From 82e85a7a0deb5ec221ec297b3ec6f99a156ad7ee Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Mon, 25 Sep 2023 21:36:31 +0900 Subject: [PATCH 01/21] Add empty rule. --- .../test/fixtures/pycodestyle/E12.py | 289 ++++++++++++++++++ .../ruff_linter/src/checkers/logical_lines.rs | 16 +- crates/ruff_linter/src/codes.rs | 2 + crates/ruff_linter/src/registry.rs | 1 + .../ruff_linter/src/rules/pycodestyle/mod.rs | 1 + ...n_line_missing_indentation_or_outdented.rs | 40 +++ .../pycodestyle/rules/logical_lines/mod.rs | 2 + 7 files changed, 347 insertions(+), 4 deletions(-) create mode 100644 crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py create mode 100644 crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py new file mode 100644 index 0000000000000..1becd795329e2 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py @@ -0,0 +1,289 @@ +#: E122 +print("E122", ( +"dent")) + +#: E122:6:5 E122:7:5 E122:8:1 +print(dedent( + ''' + mkdir -p ./{build}/ + mv ./build/ ./{build}/%(revision)s/ + '''.format( + build='build', + # more stuff +) +)) + +#: E122 +if True: + result = some_function_that_takes_arguments( + 'a', 'b', 'c', + 'd', 'e', 'f', +) + +#: E122 +if some_very_very_very_long_variable_name or var \ +or another_very_long_variable_name: + raise Exception() + +#: E122 +if some_very_very_very_long_variable_name or var[0] \ +or another_very_long_variable_name: + raise Exception() + +#: E122 +if True: + if some_very_very_very_long_variable_name or var \ + or another_very_long_variable_name: + raise Exception() + +#: E122 +if True: + if some_very_very_very_long_variable_name or var[0] \ + or another_very_long_variable_name: + raise Exception() + +#: E122 +dictionary = { + "is": { + "nested": yes(), + }, +} + +#: E122 +setup('', + scripts=[''], + classifiers=[ + 'Development Status :: 4 - Beta', + 'Environment :: Console', + 'Intended Audience :: Developers', + ]) + +#: E701:1:8 E122:2:1 E203:4:8 E128:5:1 +if True:\ +print(True) + +print(a +, end=' ') + +#: E124 +print ("E124", ("visual", + "indent_two" + )) + +#: E124 +print ("E124", ("visual", + "indent_five" +)) + +#: E124 +a = (123, +) + +#: E124 +my_list = [1, 2, 3, + 4, 5, 6, +] + +#: E124 +my_list = [1, 2, 3, + 4, 5, 6, + ] +#: E124 +result = some_function_that_takes_arguments('a', 'b', 'c', + 'd', 'e', 'f', +) + +#: E124 +fooff(aaaa, + cca( + vvv, + dadd + ), fff, +) + +#: E124 +fooff(aaaa, + ccaaa( + vvv, + dadd + ), + fff, +) + +#: E124 +d = dict('foo', + help="exclude files or directories which match these " + "comma separated patterns (default: %s)" % DEFAULT_EXCLUDE + ) + +#: E124 E128 E128 +if line_removed: + self.event(cr, uid, + name="Removing the option for contract", + description="contract line has been removed", + ) + +#: E124 E127 E127 +if line_removed: + self.event(cr, uid, + name="Removing the option for contract", + description="contract line has been removed", + ) + +#: E125 +if foo is None and bar is "frop" and \ + blah == 'yeah': + blah = 'yeahnah' + +#: E125 +# Further indentation required as indentation is not distinguishable +def long_function_name( + var_one, var_two, var_three, + var_four): + print(var_one) + +#: E125 +def qualify_by_address( + self, cr, uid, ids, context=None, + params_to_check=frozenset(QUALIF_BY_ADDRESS_PARAM)): + """ This gets called by the web server """ + +#: E125:2:5 E125:8:5 +if (""" + """): + pass + +for foo in """ + abc + 123 + """.strip().split(): + print(foo) + +#: E127 +print ("E127", ("over-", + "over-indent")) + +#: E127 +foo(1, 2, 3, + 4, 5, 6) +#: E127 +foo(1, 2, 3, + 4, 5, 6) +#: E127 +foo(1, 2, 3, + 4, 5, 6) +#: E127 +foo(1, 2, 3, + 4, 5, 6) +#: E127 +foo(1, 2, 3, + 4, 5, 6) +#: E127 +foo(1, 2, 3, + 4, 5, 6) +#: E127 +foo(1, 2, 3, + 4, 5, 6) +#: E127 +foo(1, 2, 3, + 4, 5, 6) +#: E127 +foo(1, 2, 3, + 4, 5, 6) + +#: E127 +rv.update(d=('a', 'b', 'c'), + e=42) +# +#: E127 W503 +rv.update(d=('a' + 'b', 'c'), + e=42, f=42 + + 42) +#: E127 W503 +input1 = {'a': {'calc': 1 + 2}, 'b': 1 + + 42} + +#: E127:4:12 +def foo(): + pass + raise 123 + \ + 123 + +#: E127:4:13 +class Eggs: + pass + assert 123456 == \ + 123456 + +#: E127:4:11 +def f1(): + print('foo') + with open('/path/to/some/file/you/want/to/read') as file_1, \ + open('/path/to/some/file/being/written', 'w') as file_2: + file_2.write(file_1.read()) + +#: E127:5:11 +def f1(): + print('foo') + with open('/path/to/some/file/you/want/to/read') as file_1, \ + open('/path/to/some/file/being/written', 'w') as file_2, \ + open('later-misindent'): + file_2.write(file_1.read()) + +#: E128 E128 +if line_removed: + self.event(cr, uid, + name="Removing the option for contract", + description="contract line has been removed", + ) + +#: E128 +print ("E128", ("visual", + "hanging")) + +#: E128 +print ("E128", ("under-", + "under-indent")) + +#: E128 +# Arguments on first line forbidden when not using vertical alignment +foo = long_function_name(var_one, var_two, + var_three, var_four) + +#: E128 +print('l.%s\t%s\t%s\t%r' % + (token[2][0], pos, tokenize.tok_name[token[0]], token[1])) + +#: E128 +def qualify_by_address(self, cr, uid, ids, context=None, + params_to_check=frozenset(QUALIF_BY_ADDRESS_PARAM)): + """ This gets called by the web server """ + +#: E128 +foo(1, 2, 3, +4, 5, 6) +#: E128 +foo(1, 2, 3, + 4, 5, 6) +#: E128 +foo(1, 2, 3, + 4, 5, 6) +#: E128 +foo(1, 2, 3, + 4, 5, 6) + +#: E128 W503 +rv.update(d=('a' + 'b', 'c'), + e=42, f=(42 + + 42)) + +#: E129 W503 +if (row < 0 or self.moduleCount <= row + or col < 0 or self.moduleCount <= col): + raise Exception("%s,%s - %s" % (row, col, self.moduleCount)) + +#: E129 +if (a == 2 + or b == "abc def ghi" + "jkl mno"): + return True diff --git a/crates/ruff_linter/src/checkers/logical_lines.rs b/crates/ruff_linter/src/checkers/logical_lines.rs index c5585c4b93181..024efa6175d03 100644 --- a/crates/ruff_linter/src/checkers/logical_lines.rs +++ b/crates/ruff_linter/src/checkers/logical_lines.rs @@ -7,10 +7,11 @@ use ruff_text_size::{Ranged, TextRange}; use crate::registry::{AsRule, Rule}; use crate::rules::pycodestyle::rules::logical_lines::{ - extraneous_whitespace, indentation, missing_whitespace, missing_whitespace_after_keyword, - missing_whitespace_around_operator, space_after_comma, space_around_operator, - whitespace_around_keywords, whitespace_around_named_parameter_equals, - whitespace_before_comment, whitespace_before_parameters, LogicalLines, TokenFlags, + continuation_line_missing_indentation_or_outdented, extraneous_whitespace, indentation, + missing_whitespace, missing_whitespace_after_keyword, missing_whitespace_around_operator, + space_after_comma, space_around_operator, whitespace_around_keywords, + whitespace_around_named_parameter_equals, whitespace_before_comment, + whitespace_before_parameters, LogicalLines, TokenFlags, }; use crate::settings::LinterSettings; @@ -109,6 +110,13 @@ pub(crate) fn check_logical_lines( let indent_size = 4; + continuation_line_missing_indentation_or_outdented( + &mut context, + &line, + indent_char, + indent_size, + ); + for kind in indentation( &line, prev_line.as_ref(), diff --git a/crates/ruff_linter/src/codes.rs b/crates/ruff_linter/src/codes.rs index 5de943cd83a6b..cb8df0b1dca35 100644 --- a/crates/ruff_linter/src/codes.rs +++ b/crates/ruff_linter/src/codes.rs @@ -83,6 +83,8 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { #[allow(deprecated)] (Pycodestyle, "E117") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::OverIndented), #[allow(deprecated)] + (Pycodestyle, "E122") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingOrOutdentedIndentation), + #[allow(deprecated)] (Pycodestyle, "E201") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::WhitespaceAfterOpenBracket), #[allow(deprecated)] (Pycodestyle, "E202") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::WhitespaceBeforeCloseBracket), diff --git a/crates/ruff_linter/src/registry.rs b/crates/ruff_linter/src/registry.rs index a7a571e82baf7..bf83186c1aaba 100644 --- a/crates/ruff_linter/src/registry.rs +++ b/crates/ruff_linter/src/registry.rs @@ -301,6 +301,7 @@ impl Rule { Rule::ImplicitNamespacePackage | Rule::InvalidModuleName => LintSource::Filesystem, Rule::IndentationWithInvalidMultiple | Rule::IndentationWithInvalidMultipleComment + | Rule::MissingOrOutdentedIndentation | Rule::MissingWhitespace | Rule::MissingWhitespaceAfterKeyword | Rule::MissingWhitespaceAroundArithmeticOperator diff --git a/crates/ruff_linter/src/rules/pycodestyle/mod.rs b/crates/ruff_linter/src/rules/pycodestyle/mod.rs index d5fb9eb9e3f2b..7ee1bdc3e32e3 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/mod.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/mod.rs @@ -99,6 +99,7 @@ mod tests { #[test_case(Rule::TooFewSpacesBeforeInlineComment, Path::new("E26.py"))] #[test_case(Rule::UnexpectedIndentation, Path::new("E11.py"))] #[test_case(Rule::UnexpectedIndentationComment, Path::new("E11.py"))] + #[test_case(Rule::MissingOrOutdentedIndentation, Path::new("E12.py"))] #[test_case(Rule::WhitespaceAfterOpenBracket, Path::new("E20.py"))] #[test_case(Rule::WhitespaceBeforeCloseBracket, Path::new("E20.py"))] #[test_case(Rule::WhitespaceBeforePunctuation, Path::new("E20.py"))] diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs new file mode 100644 index 0000000000000..d593078f5a28c --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs @@ -0,0 +1,40 @@ +use super::{LogicalLine, LogicalLineToken}; +use crate::checkers::logical_lines::LogicalLinesContext; +use ruff_diagnostics::Violation; +use ruff_macros::{derive_message_formats, violation}; + +/// ## What it does +/// Checks for continuation lines not indented as far as they should be or indented too far. +/// +/// ## Why is this bad? +/// This makes reading code harder. +/// +/// ## Example +/// ```python +/// print("Python", ( +/// "Rules")) +/// ``` +/// +/// Use instead: +/// ```python +/// print("Python", ( +/// "Rules")) +/// ``` +#[violation] +pub struct MissingOrOutdentedIndentation; + +impl Violation for MissingOrOutdentedIndentation { + #[derive_message_formats] + fn message(&self) -> String { + format!("Continuation line missing indentation or outdented.") + } +} + +/// E122 +pub(crate) fn continuation_line_missing_indentation_or_outdented( + context: &mut LogicalLinesContext, + logical_line: &LogicalLine, + indent_char: char, + indent_size: usize, +) { +} diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/mod.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/mod.rs index f736d6cb2fadd..c99589f56c953 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/mod.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/mod.rs @@ -1,3 +1,4 @@ +pub(crate) use continuation_line_missing_indentation_or_outdented::*; pub(crate) use extraneous_whitespace::*; pub(crate) use indentation::*; pub(crate) use missing_whitespace::*; @@ -20,6 +21,7 @@ use ruff_python_parser::TokenKind; use ruff_python_trivia::is_python_whitespace; use ruff_source_file::Locator; +mod continuation_line_missing_indentation_or_outdented; mod extraneous_whitespace; mod indentation; mod missing_whitespace; From 8a9c8dde65122fb2580609f184dd7e2e3604e73e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ho=C3=ABl=20Bagard?= <34478245+hoel-bagard@users.noreply.github.com> Date: Sat, 28 Oct 2023 21:07:47 +0900 Subject: [PATCH 02/21] Add E122 rule. Add E122 rule and base for adding the other E12 rules, based on the pycodestyle implementation. Autofix and configuration are not included. --- .github/dependabot.yml | 2 +- .github/release.yml | 5 +- .github/workflows/ci.yaml | 140 +- .github/workflows/docs.yaml | 2 +- .github/workflows/playground.yaml | 5 +- .github/workflows/pr-comment.yaml | 1 + .markdownlint.yaml | 5 + .pre-commit-config.yaml | 5 + BREAKING_CHANGES.md | 30 + CHANGELOG.md | 274 + CONTRIBUTING.md | 5 +- Cargo.lock | 268 +- Cargo.toml | 33 +- README.md | 105 +- assets/badge/format.json | 8 + crates/flake8_to_ruff/Cargo.toml | 4 +- crates/flake8_to_ruff/src/converter.rs | 140 +- crates/flake8_to_ruff/src/parser.rs | 2 +- crates/flake8_to_ruff/src/plugin.rs | 4 +- crates/ruff_benchmark/Cargo.toml | 4 +- crates/ruff_benchmark/benches/formatter.rs | 9 +- crates/ruff_cli/Cargo.toml | 6 +- crates/ruff_cli/build.rs | 80 + .../resources/test/fixtures/formatted.py | 1 + .../resources/test/fixtures/unformatted.ipynb | 72 + .../resources/test/fixtures/unformatted.py | 3 + crates/ruff_cli/src/args.rs | 120 +- crates/ruff_cli/src/cache.rs | 639 +- crates/ruff_cli/src/commands/add_noqa.rs | 19 +- crates/ruff_cli/src/commands/check.rs | 245 +- crates/ruff_cli/src/commands/check_stdin.rs | 14 +- crates/ruff_cli/src/commands/format.rs | 648 +- crates/ruff_cli/src/commands/format_stdin.rs | 117 +- crates/ruff_cli/src/commands/mod.rs | 1 + crates/ruff_cli/src/commands/rule.rs | 21 +- crates/ruff_cli/src/commands/show_files.rs | 11 +- crates/ruff_cli/src/commands/show_settings.rs | 13 +- crates/ruff_cli/src/commands/version.rs | 21 + crates/ruff_cli/src/diagnostics.rs | 400 +- crates/ruff_cli/src/lib.rs | 121 +- crates/ruff_cli/src/printer.rs | 185 +- ...i__version__tests__version_formatting.snap | 5 + ...__version_formatting_with_commit_info.snap | 5 + ...ormatting_with_commits_since_last_tag.snap | 5 + ..._version__tests__version_serializable.snap | 14 + crates/ruff_cli/src/version.rs | 130 + .../tests/black_compatibility_test.rs | 204 - crates/ruff_cli/tests/format.rs | 592 +- crates/ruff_cli/tests/integration_test.rs | 865 +- crates/ruff_cli/tests/lint.rs | 310 + ...ation_test__explain_status_codes_f401.snap | 2 +- .../integration_test__stdin_json.snap | 5 +- crates/ruff_dev/src/format_dev.rs | 40 +- crates/ruff_dev/src/generate_cli_help.rs | 38 +- crates/ruff_dev/src/generate_docs.rs | 38 +- crates/ruff_dev/src/generate_options.rs | 63 +- crates/ruff_dev/src/generate_rules_table.rs | 18 +- crates/ruff_diagnostics/Cargo.toml | 1 + crates/ruff_diagnostics/src/fix.rs | 107 +- crates/ruff_diagnostics/src/lib.rs | 2 +- crates/ruff_diagnostics/src/source_map.rs | 23 +- crates/ruff_diagnostics/src/violation.rs | 48 +- crates/ruff_formatter/Cargo.toml | 2 +- crates/ruff_formatter/src/builders.rs | 4 +- crates/ruff_formatter/src/lib.rs | 6 +- crates/ruff_formatter/src/printer/mod.rs | 2 +- crates/ruff_linter/Cargo.toml | 11 +- .../flake8_annotations/annotation_presence.py | 6 + .../test/fixtures/flake8_bandit/S103.py | 1 + .../test/fixtures/flake8_bandit/S310.py | 19 + .../test/fixtures/flake8_bandit/S505.py | 54 + .../test/fixtures/flake8_bandit/S507.py | 4 + .../test/fixtures/flake8_blind_except/BLE.py | 32 + .../test/fixtures/flake8_boolean_trap/FBT.py | 2 + .../test/fixtures/flake8_bugbear/B006_5.py | 74 + .../test/fixtures/flake8_bugbear/B006_6.py | 5 + .../test/fixtures/flake8_bugbear/B006_7.py | 5 + .../test/fixtures/flake8_bugbear/B009_B010.py | 4 + .../test/fixtures/flake8_bugbear/B014.py | 9 +- .../test/fixtures/flake8_commas/COM81.py | 2 +- .../fixtures/flake8_comprehensions/C414.py | 13 + .../flake8_implicit_str_concat/ISC.py | 20 + .../test/fixtures/flake8_logging/LOG007.py | 6 + .../fixtures/flake8_logging_format/G001.py | 9 + .../fixtures/flake8_logging_format/G002.py | 5 + .../fixtures/flake8_logging_format/G003.py | 5 + .../fixtures/flake8_logging_format/G004.py | 4 + .../fixtures/flake8_logging_format/G010.py | 5 + .../fixtures/flake8_logging_format/G101_1.py | 9 + .../fixtures/flake8_logging_format/G101_2.py | 9 + .../fixtures/flake8_logging_format/G201.py | 21 + .../fixtures/flake8_logging_format/G202.py | 20 + .../test/fixtures/flake8_pie/PIE790.py | 25 + .../test/fixtures/flake8_pie/PIE804.py | 2 + .../test/fixtures/flake8_pyi/PYI055.py | 10 +- .../test/fixtures/flake8_pyi/PYI055.pyi | 3 +- .../fixtures/flake8_pytest_style/PT018.py | 4 +- .../fixtures/flake8_quotes/doubles_escaped.py | 30 + .../fixtures/flake8_quotes/singles_escaped.py | 29 + .../test/fixtures/flake8_raise/RSE102.py | 3 + .../test/fixtures/flake8_return/RET504.py | 2 +- .../test/fixtures/flake8_simplify/SIM101.py | 9 + .../test/fixtures/flake8_simplify/SIM108.py | 9 + .../test/fixtures/flake8_simplify/SIM110.py | 21 + .../test/fixtures/flake8_simplify/SIM112.py | 4 + .../test/fixtures/flake8_simplify/SIM115.py | 4 + .../test/fixtures/flake8_simplify/SIM117.py | 13 + .../test/fixtures/flake8_simplify/SIM401.py | 13 + .../flake8_type_checking/TCH004_15.py | 19 + .../runtime_evaluated_base_classes_3.py | 7 + .../fixtures/flake8_use_pathlib/full_name.py | 13 + .../test/fixtures/pycodestyle/E20.py | 5 + .../test/fixtures/pycodestyle/E23.py | 11 + .../test/fixtures/pycodestyle/E25.py | 11 + .../test/fixtures/pycodestyle/E501_1.py | 2 + .../test/fixtures/pycodestyle/E501_3.py | 11 + .../test/fixtures/pycodestyle/E721.py | 71 +- .../test/fixtures/pycodestyle/W19.py | 8 + .../test/fixtures/pycodestyle/W605_2.py | 54 + .../test/fixtures/pydocstyle/D300.py | 10 + .../test/fixtures/pydocstyle/D301.py | 4 + .../test/fixtures/pyflakes/F401_19.py | 17 + .../resources/test/fixtures/pyflakes/F541.py | 6 +- .../resources/test/fixtures/pyflakes/F632.py | 4 + .../test/fixtures/pyflakes/F821_18.py | 19 + .../test/fixtures/pyflakes/F821_19.py | 21 + .../test/fixtures/pyflakes/F821_20.py | 5 + .../test/fixtures/pyflakes/F841_3.py | 2 +- .../test/fixtures/pygrep_hooks/PGH002_0.py | 3 + .../test/fixtures/pygrep_hooks/PGH002_1.py | 3 + .../test/fixtures/pylint/and_or_ternary.py | 73 + .../fixtures/pylint/bad_dunder_method_name.py | 20 + .../fixtures/pylint/global_at_module_level.py | 10 + .../fixtures/pylint/invalid_all_format.py | 6 + .../fixtures/pylint/invalid_characters.py | Bin 1106 -> 1639 bytes .../fixtures/pylint/iteration_over_set.py | 11 + .../fixtures/pylint/literal_membership.py | 10 + .../fixtures/pylint/logging_too_few_args.py | 26 + .../fixtures/pylint/logging_too_many_args.py | 22 + .../fixtures/pylint/misplaced_bare_raise.py | 71 + .../test/fixtures/pylint/no_self_use.py | 23 + .../pylint/non_ascii_module_import.py | 17 + .../test/fixtures/pylint/non_ascii_name.py | 31 + .../pylint/too_many_boolean_expressions.py | 54 + .../fixtures/pylint/unnecessary_lambda.py | 59 + .../fixtures/pylint/unspecified_encoding.py | 44 + .../test/fixtures/pyupgrade/UP015.py | 16 +- .../test/fixtures/pyupgrade/UP032_0.py | 5 + .../test/fixtures/pyupgrade/UP032_3.py | 9 + .../test/fixtures/pyupgrade/UP035.py | 9 +- .../test/fixtures/pyupgrade/UP036_0.py | 31 + .../test/fixtures/pyupgrade/UP040.pyi | 7 + .../resources/test/fixtures/refurb/FURB101.py | 126 + .../resources/test/fixtures/refurb/FURB105.py | 1 + .../resources/test/fixtures/refurb/FURB140.py | 12 + .../resources/test/fixtures/refurb/FURB148.py | 34 + .../resources/test/fixtures/refurb/FURB171.py | 45 + .../resources/test/fixtures/refurb/FURB177.py | 31 + .../resources/test/fixtures/ruff/RUF012.py | 11 + .../resources/test/fixtures/ruff/RUF015.py | 16 + .../fixtures/ruff/{RUF017.py => RUF017_0.py} | 5 + .../resources/test/fixtures/ruff/RUF017_1.py | 1 + .../resources/test/fixtures/ruff/RUF018.py | 7 + .../resources/test/fixtures/ruff/RUF019.py | 20 + .../resources/test/fixtures/ruff/RUF100_0.py | 3 + .../test/fixtures/ruff/confusables.py | 16 + .../test/fixtures/tryceratops/TRY400.py | 34 + .../test/fixtures/tryceratops/TRY401.py | 64 + .../src/checkers/ast/analyze/bindings.rs | 19 +- .../checkers/ast/analyze/deferred_lambdas.rs | 26 + .../checkers/ast/analyze/deferred_scopes.rs | 2 +- .../src/checkers/ast/analyze/expression.rs | 70 +- .../src/checkers/ast/analyze/mod.rs | 2 + .../src/checkers/ast/analyze/statement.rs | 33 +- .../ruff_linter/src/checkers/ast/deferred.rs | 6 +- crates/ruff_linter/src/checkers/ast/mod.rs | 96 +- .../ruff_linter/src/checkers/logical_lines.rs | 30 +- crates/ruff_linter/src/checkers/noqa.rs | 39 +- .../src/checkers/physical_lines.rs | 16 +- crates/ruff_linter/src/checkers/tokens.rs | 81 +- crates/ruff_linter/src/codes.rs | 1325 +- crates/ruff_linter/src/cst/matchers.rs | 2 +- crates/ruff_linter/src/directives.rs | 149 +- .../src/{autofix => fix}/codemods.rs | 0 .../ruff_linter/src/{autofix => fix}/edits.rs | 79 +- .../ruff_linter/src/{autofix => fix}/mod.rs | 22 +- .../src/{autofix => fix}/snippet.rs | 0 crates/ruff_linter/src/importer/mod.rs | 8 +- crates/ruff_linter/src/lib.rs | 2 +- crates/ruff_linter/src/line_width.rs | 34 +- crates/ruff_linter/src/linter.rs | 60 +- crates/ruff_linter/src/logging.rs | 13 +- crates/ruff_linter/src/message/diff.rs | 9 +- crates/ruff_linter/src/message/grouped.rs | 37 +- crates/ruff_linter/src/message/json.rs | 100 +- crates/ruff_linter/src/message/json_lines.rs | 18 +- crates/ruff_linter/src/message/mod.rs | 126 +- ...__message__grouped__tests__fix_status.snap | 4 +- ...ge__grouped__tests__fix_status_unsafe.snap | 31 + ...message__json__tests__notebook_output.snap | 105 + ..._linter__message__json__tests__output.snap | 7 +- ...e__json_lines__tests__notebook_output.snap | 8 + ...r__message__json_lines__tests__output.snap | 6 +- ...ter__message__text__tests__fix_status.snap | 4 +- ...ssage__text__tests__fix_status_unsafe.snap | 29 + ...message__text__tests__notebook_output.snap | 32 + crates/ruff_linter/src/message/text.rs | 113 +- crates/ruff_linter/src/noqa.rs | 2 +- crates/ruff_linter/src/registry.rs | 15 +- crates/ruff_linter/src/registry/rule_set.rs | 2 +- crates/ruff_linter/src/rule_selector.rs | 19 +- .../src/rules/eradicate/detection.rs | 152 +- .../eradicate/rules/commented_out_code.rs | 23 +- ...s__eradicate__tests__ERA001_ERA001.py.snap | 16 +- .../src/rules/flake8_2020/rules/compare.rs | 10 +- .../src/rules/flake8_2020/rules/subscript.rs | 12 +- .../flake8_annotations/rules/definition.rs | 32 +- ...__flake8_annotations__tests__defaults.snap | 29 + .../flake8_async/rules/blocking_http_call.rs | 27 +- .../flake8_async/rules/blocking_os_call.rs | 26 +- .../rules/open_sleep_or_subprocess_call.rs | 27 +- .../src/rules/flake8_bandit/mod.rs | 2 + .../rules/bad_file_permissions.rs | 68 +- .../src/rules/flake8_bandit/rules/mod.rs | 2 + .../flake8_bandit/rules/shell_injection.rs | 82 + .../rules/snmp_insecure_version.rs | 24 +- .../rules/ssh_no_host_key_verification.rs | 10 +- .../rules/suspicious_function_call.rs | 34 +- .../rules/weak_cryptographic_key.rs | 162 + ...s__flake8_bandit__tests__S103_S103.py.snap | 9 + ...s__flake8_bandit__tests__S310_S310.py.snap | 107 + ...s__flake8_bandit__tests__S505_S505.py.snap | 142 + ...s__flake8_bandit__tests__S507_S507.py.snap | 88 +- .../flake8_blind_except/rules/blind_except.rs | 53 +- ...e8_blind_except__tests__BLE001_BLE.py.snap | 27 + .../src/rules/flake8_boolean_trap/helpers.rs | 4 + ...e8_boolean_trap__tests__FBT001_FBT.py.snap | 8 +- .../src/rules/flake8_bugbear/mod.rs | 3 + .../flake8_bugbear/rules/assert_false.rs | 17 +- .../rules/duplicate_exceptions.rs | 39 +- .../rules/getattr_with_constant.rs | 46 +- .../rules/mutable_argument_default.rs | 106 +- .../redundant_tuple_in_exception_handler.rs | 39 +- .../rules/setattr_with_constant.rs | 17 +- .../rules/strip_with_multi_characters.rs | 2 +- .../rules/unreliable_callable_check.rs | 21 +- .../rules/unused_loop_control_variable.rs | 39 +- .../rules/useless_comparison.rs | 9 +- .../rules/useless_expression.rs | 7 +- ...flake8_bugbear__tests__B006_B006_1.py.snap | 2 +- ...flake8_bugbear__tests__B006_B006_2.py.snap | 2 +- ...flake8_bugbear__tests__B006_B006_3.py.snap | 2 +- ...flake8_bugbear__tests__B006_B006_4.py.snap | 2 +- ...flake8_bugbear__tests__B006_B006_5.py.snap | 313 + ...flake8_bugbear__tests__B006_B006_6.py.snap | 25 + ...flake8_bugbear__tests__B006_B006_7.py.snap | 25 + ...ke8_bugbear__tests__B006_B006_B008.py.snap | 70 +- ...ke8_bugbear__tests__B009_B009_B010.py.snap | 50 +- ...ke8_bugbear__tests__B010_B009_B010.py.snap | 12 +- ...__flake8_bugbear__tests__B014_B014.py.snap | 22 +- ...__flake8_bugbear__tests__B015_B015.py.snap | 8 +- ...extend_immutable_calls_arg_annotation.snap | 2 +- .../flake8_commas/rules/trailing_commas.rs | 38 +- ...rules__flake8_commas__tests__COM81.py.snap | 6 +- .../src/rules/flake8_comprehensions/fixes.rs | 25 +- .../rules/unnecessary_call_around_sorted.rs | 31 +- .../rules/unnecessary_collection_call.rs | 16 +- .../rules/unnecessary_comprehension.rs | 18 +- .../unnecessary_comprehension_any_all.rs | 16 +- .../unnecessary_double_cast_or_process.rs | 26 +- .../rules/unnecessary_generator_dict.rs | 15 +- .../rules/unnecessary_generator_list.rs | 18 +- .../rules/unnecessary_generator_set.rs | 16 +- .../rules/unnecessary_list_call.rs | 18 +- .../unnecessary_list_comprehension_dict.rs | 16 +- .../unnecessary_list_comprehension_set.rs | 16 +- .../rules/unnecessary_literal_dict.rs | 14 +- .../rules/unnecessary_literal_set.rs | 14 +- .../unnecessary_literal_within_dict_call.rs | 22 +- .../unnecessary_literal_within_list_call.rs | 22 +- .../unnecessary_literal_within_tuple_call.rs | 22 +- .../rules/unnecessary_map.rs | 30 +- .../rules/unnecessary_subscript_reversal.rs | 25 +- ...8_comprehensions__tests__C414_C414.py.snap | 55 +- .../rules/string_in_exception.rs | 85 +- .../src/rules/flake8_executable/rules/mod.rs | 4 +- .../rules/shebang_leading_whitespace.rs | 14 +- .../rules/implicit.rs | 81 +- ...icit_str_concat__tests__ISC001_ISC.py.snap | 143 + ...icit_str_concat__tests__ISC002_ISC.py.snap | 12 + ...icit_str_concat__tests__ISC003_ISC.py.snap | 21 + ...oncat__tests__multiline_ISC001_ISC.py.snap | 143 + ...oncat__tests__multiline_ISC002_ISC.py.snap | 23 + ...oncat__tests__multiline_ISC003_ISC.py.snap | 21 + .../rules/banned_import_alias.rs | 3 + .../rules/banned_import_from.rs | 3 + .../rules/unconventional_import_alias.rs | 30 +- .../rules/direct_logger_instantiation.rs | 27 +- .../rules/exception_without_exc_info.rs | 57 +- .../rules/invalid_get_logger_argument.rs | 19 +- .../flake8_logging/rules/undocumented_warn.rs | 27 +- ...ake8_logging__tests__LOG007_LOG007.py.snap | 9 + ...ake8_logging__tests__LOG009_LOG009.py.snap | 4 +- .../rules/logging_call.rs | 58 +- ...flake8_logging_format__tests__G001.py.snap | 58 + ...flake8_logging_format__tests__G002.py.snap | 18 + ...flake8_logging_format__tests__G003.py.snap | 18 + ...flake8_logging_format__tests__G004.py.snap | 28 +- ...flake8_logging_format__tests__G010.py.snap | 25 + ...ake8_logging_format__tests__G101_1.py.snap | 10 + ...ake8_logging_format__tests__G101_2.py.snap | 10 + ...flake8_logging_format__tests__G201.py.snap | 20 + ...flake8_logging_format__tests__G202.py.snap | 20 + .../rules/flake8_logging_format/violations.rs | 6 +- .../rules/duplicate_class_field_definition.rs | 25 +- .../src/rules/flake8_pie/rules/mod.rs | 4 +- .../rules/multiple_starts_ends_with.rs | 171 +- .../flake8_pie/rules/no_unnecessary_pass.rs | 78 - .../rules/reimplemented_list_builtin.rs | 19 +- .../rules/unnecessary_dict_kwargs.rs | 80 +- .../flake8_pie/rules/unnecessary_pass.rs | 75 + .../rules/unnecessary_range_start.rs | 33 +- ...__flake8_pie__tests__PIE790_PIE790.py.snap | 145 + ...__flake8_pie__tests__PIE804_PIE804.py.snap | 94 +- .../flake8_pyi/rules/any_eq_ne_annotation.rs | 23 +- .../rules/collections_named_tuple.rs | 2 +- .../flake8_pyi/rules/docstring_in_stubs.rs | 19 + .../rules/duplicate_union_member.rs | 30 +- .../rules/ellipsis_in_non_empty_class_body.rs | 25 +- .../flake8_pyi/rules/exit_annotations.rs | 19 +- .../rules/future_annotations_in_stub.rs | 11 + .../rules/no_return_argument_annotation.rs | 14 +- .../flake8_pyi/rules/non_empty_stub_body.rs | 17 +- .../flake8_pyi/rules/non_self_return_type.rs | 2 +- .../rules/numeric_literal_too_long.rs | 29 +- .../flake8_pyi/rules/pass_in_class_body.rs | 46 +- .../rules/pass_statement_stub_body.rs | 17 +- .../rules/quoted_annotation_in_stub.rs | 37 +- .../rules/redundant_literal_union.rs | 2 +- .../rules/flake8_pyi/rules/simple_defaults.rs | 194 +- .../rules/str_or_repr_defined_in_stub.rs | 23 +- .../rules/string_or_bytes_too_long.rs | 32 +- .../rules/stub_body_multiple_statements.rs | 22 + .../flake8_pyi/rules/type_alias_naming.rs | 35 + .../unaliased_collections_abc_set_import.rs | 22 +- .../rules/unnecessary_type_union.rs | 121 +- .../rules/unrecognized_version_info.rs | 13 +- ..._flake8_pyi__tests__PYI010_PYI010.pyi.snap | 6 +- ..._flake8_pyi__tests__PYI011_PYI011.pyi.snap | 36 +- ..._flake8_pyi__tests__PYI014_PYI014.pyi.snap | 26 +- ..._flake8_pyi__tests__PYI015_PYI015.pyi.snap | 22 +- ..._flake8_pyi__tests__PYI026_PYI026.pyi.snap | 10 +- ..._flake8_pyi__tests__PYI053_PYI053.pyi.snap | 10 +- ..._flake8_pyi__tests__PYI054_PYI054.pyi.snap | 16 +- ...__flake8_pyi__tests__PYI055_PYI055.py.snap | 52 +- ..._flake8_pyi__tests__PYI055_PYI055.pyi.snap | 123 +- ...e8_pyi__tests__py38_PYI026_PYI026.pyi.snap | 10 +- .../flake8_pytest_style/rules/assertion.rs | 83 +- .../flake8_pytest_style/rules/fixture.rs | 119 +- .../flake8_pytest_style/rules/helpers.rs | 13 +- .../rules/flake8_pytest_style/rules/marks.rs | 72 +- .../flake8_pytest_style/rules/parametrize.rs | 187 +- .../rules/unittest_assert.rs | 2 +- ...es__flake8_pytest_style__tests__PT018.snap | 16 +- .../src/rules/flake8_quotes/mod.rs | 39 + .../rules/avoidable_escaped_quote.rs | 256 + ...{from_tokens.rs => check_string_quotes.rs} | 371 +- .../src/rules/flake8_quotes/rules/mod.rs | 6 +- .../src/rules/flake8_quotes/settings.rs | 18 + ...quire_doubles_over_singles_escaped.py.snap | 179 + ...re_doubles_over_singles_escaped_py311.snap | 80 + ...quire_singles_over_doubles_escaped.py.snap | 200 + ...re_singles_over_doubles_escaped_py311.snap | 119 + .../unnecessary_paren_on_raise_exception.rs | 95 +- ...ry-paren-on-raise-exception_RSE102.py.snap | 21 + .../src/rules/flake8_return/rules/function.rs | 180 +- ...lake8_return__tests__RET504_RET504.py.snap | 2 +- .../src/rules/flake8_simplify/mod.rs | 19 + .../flake8_simplify/rules/ast_bool_op.rs | 332 +- .../rules/flake8_simplify/rules/ast_expr.rs | 69 +- .../src/rules/flake8_simplify/rules/ast_if.rs | 990 - .../rules/flake8_simplify/rules/ast_ifexp.rs | 143 +- .../flake8_simplify/rules/ast_unary_op.rs | 107 +- .../rules/flake8_simplify/rules/ast_with.rs | 56 +- .../flake8_simplify/rules/collapsible_if.rs | 400 + .../src/rules/flake8_simplify/rules/fix_if.rs | 132 - .../rules/flake8_simplify/rules/fix_with.rs | 2 +- .../if_else_block_instead_of_dict_get.rs | 305 + .../if_else_block_instead_of_dict_lookup.rs | 162 + .../rules/if_else_block_instead_of_if_exp.rs | 167 + .../rules/if_with_same_arms.rs | 93 + .../flake8_simplify/rules/key_in_dict.rs | 57 +- .../src/rules/flake8_simplify/rules/mod.rs | 15 +- .../flake8_simplify/rules/needless_bool.rs | 186 + .../rules/open_file_with_context_handler.rs | 29 + .../rules/reimplemented_builtin.rs | 57 +- .../rules/suppressible_exception.rs | 46 +- .../flake8_simplify/rules/yoda_conditions.rs | 21 +- ...ke8_simplify__tests__SIM101_SIM101.py.snap | 62 +- ...ke8_simplify__tests__SIM110_SIM110.py.snap | 33 + ...ke8_simplify__tests__SIM117_SIM117.py.snap | 33 + ...ke8_simplify__tests__SIM202_SIM202.py.snap | 6 +- ...ke8_simplify__tests__SIM208_SIM208.py.snap | 10 +- ...ify__tests__preview__SIM401_SIM401.py.snap | 202 + .../rules/relative_imports.rs | 22 +- .../src/rules/flake8_todos/rules/todos.rs | 31 +- .../src/rules/flake8_type_checking/helpers.rs | 14 +- .../src/rules/flake8_type_checking/mod.rs | 1 + .../rules/empty_type_checking_block.rs | 25 +- .../runtime_import_in_type_checking_block.rs | 18 +- .../rules/typing_only_runtime_import.rs | 26 +- ...t-in-type-checking-block_TCH004_15.py.snap | 4 + .../path_constructor_current_directory.rs | 11 +- .../rules/replaceable_by_pathlib.rs | 66 +- ...ake8_use_pathlib__tests__full_name.py.snap | 41 + .../rules/flake8_use_pathlib/violations.rs | 24 +- .../flynt/rules/static_join_to_fstring.rs | 22 +- crates/ruff_linter/src/rules/isort/mod.rs | 109 +- .../ruff_linter/src/rules/isort/normalize.rs | 23 +- crates/ruff_linter/src/rules/isort/order.rs | 61 +- .../rules/isort/rules/add_required_imports.rs | 21 +- .../src/rules/isort/rules/organize_imports.rs | 39 +- crates/ruff_linter/src/rules/isort/sorting.rs | 96 +- .../rules/numpy/rules/deprecated_function.rs | 27 +- .../numpy/rules/deprecated_type_alias.rs | 29 +- ...__numpy-deprecated-function_NPY003.py.snap | 20 +- ...numpy-deprecated-type-alias_NPY001.py.snap | 14 +- .../src/rules/pandas_vet/rules/attr.rs | 13 +- .../pandas_vet/rules/inplace_argument.rs | 49 +- .../rules/nunique_constant_series_check.rs | 23 +- ...id_first_argument_name_for_class_method.rs | 6 + .../invalid_first_argument_name_for_method.rs | 6 + .../rules/invalid_function_name.rs | 6 + .../non_lowercase_variable_in_function.rs | 1 + .../perflint/rules/incorrect_dict_iterator.rs | 49 +- .../perflint/rules/unnecessary_list_cast.rs | 17 +- .../src/rules/pycodestyle/helpers.rs | 140 - .../ruff_linter/src/rules/pycodestyle/mod.rs | 28 +- .../src/rules/pycodestyle/overlong.rs | 165 + .../pycodestyle/rules/compound_statements.rs | 24 +- .../pycodestyle/rules/doc_line_too_long.rs | 38 +- .../rules/invalid_escape_sequence.rs | 179 +- .../pycodestyle/rules/lambda_assignment.rs | 104 +- .../rules/pycodestyle/rules/line_too_long.rs | 41 +- .../pycodestyle/rules/literal_comparisons.rs | 48 +- ...n_line_missing_indentation_or_outdented.rs | 365 +- .../logical_lines/extraneous_whitespace.rs | 62 +- .../rules/logical_lines/indentation.rs | 17 + .../rules/logical_lines/missing_whitespace.rs | 44 +- .../missing_whitespace_after_keyword.rs | 12 +- .../missing_whitespace_around_operator.rs | 64 +- .../logical_lines/space_around_operator.rs | 43 +- .../whitespace_around_keywords.rs | 32 +- ...hitespace_around_named_parameter_equals.rs | 33 +- .../whitespace_before_comment.rs | 15 +- .../whitespace_before_parameters.rs | 17 +- .../rules/missing_newline_at_end_of_file.rs | 17 +- .../src/rules/pycodestyle/rules/not_tests.rs | 68 +- .../pycodestyle/rules/tab_indentation.rs | 8 + .../pycodestyle/rules/trailing_whitespace.rs | 32 +- .../pycodestyle/rules/type_comparison.rs | 115 +- .../src/rules/pycodestyle/settings.rs | 1 + ...ules__pycodestyle__tests__E122_E12.py.snap | 119 + ...ules__pycodestyle__tests__E201_E20.py.snap | 18 + ...ules__pycodestyle__tests__E202_E20.py.snap | 18 + ...ules__pycodestyle__tests__E223_E22.py.snap | 13 +- ...ules__pycodestyle__tests__E224_E22.py.snap | 13 +- ...ules__pycodestyle__tests__E225_E22.py.snap | 297 +- ...ules__pycodestyle__tests__E226_E22.py.snap | 433 +- ...ules__pycodestyle__tests__E227_E22.py.snap | 128 +- ...ules__pycodestyle__tests__E228_E22.py.snap | 39 +- ...ules__pycodestyle__tests__E231_E23.py.snap | 32 +- ...ules__pycodestyle__tests__E242_E24.py.snap | 13 +- ...ules__pycodestyle__tests__E252_E25.py.snap | 52 +- ...ules__pycodestyle__tests__E261_E26.py.snap | 11 +- ...ules__pycodestyle__tests__E273_E27.py.snap | 65 +- ...ules__pycodestyle__tests__E274_E27.py.snap | 26 +- ...ules__pycodestyle__tests__E275_E27.py.snap | 65 +- ...les__pycodestyle__tests__E501_E501.py.snap | 12 +- ...s__pycodestyle__tests__E501_E501_3.py.snap | 11 + ...les__pycodestyle__tests__E721_E721.py.snap | 115 +- ...les__pycodestyle__tests__E731_E731.py.snap | 12 +- ...ules__pycodestyle__tests__W191_W19.py.snap | 16 + ...s__pycodestyle__tests__W605_W605_0.py.snap | 10 +- ...s__pycodestyle__tests__W605_W605_1.py.snap | 10 +- ...s__pycodestyle__tests__W605_W605_2.py.snap | 227 + ...s__pycodestyle__tests__max_doc_length.snap | 14 +- ...yle__tests__max_doc_length_with_utf_8.snap | 14 +- ...destyle__tests__preview__E721_E721.py.snap | 112 + ...rules__pycodestyle__tests__tab_size_1.snap | 10 +- ...rules__pycodestyle__tests__tab_size_2.snap | 18 +- ...rules__pycodestyle__tests__tab_size_4.snap | 22 +- ...rules__pycodestyle__tests__tab_size_8.snap | 22 +- ...__pycodestyle__tests__task_tags_false.snap | 76 +- .../ruff_linter/src/rules/pydocstyle/mod.rs | 29 + .../src/rules/pydocstyle/rules/backslashes.rs | 23 +- .../pydocstyle/rules/blank_after_summary.rs | 53 +- .../rules/blank_before_after_class.rs | 84 +- .../rules/blank_before_after_function.rs | 36 +- .../src/rules/pydocstyle/rules/capitalized.rs | 17 +- .../pydocstyle/rules/ends_with_period.rs | 14 +- .../pydocstyle/rules/ends_with_punctuation.rs | 14 +- .../src/rules/pydocstyle/rules/indent.rs | 79 +- .../rules/multi_line_summary_start.rs | 100 +- .../rules/newline_after_last_paragraph.rs | 47 +- .../rules/no_surrounding_whitespace.rs | 27 +- .../src/rules/pydocstyle/rules/one_liner.rs | 41 +- .../src/rules/pydocstyle/rules/sections.rs | 300 +- .../rules/pydocstyle/rules/triple_quotes.rs | 53 +- ...__rules__pydocstyle__tests__D300_D.py.snap | 10 + ...ules__pydocstyle__tests__D300_D300.py.snap | 20 + ...__rules__pydocstyle__tests__D301_D.py.snap | 27 +- ...ules__pydocstyle__tests__D301_D301.py.snap | 16 +- ...linter__rules__pydocstyle__tests__bom.snap | 1 + ...pydocstyle__tests__preview__D300_D.py.snap | 200 + ...ocstyle__tests__preview__D300_D300.py.snap | 27 + crates/ruff_linter/src/rules/pyflakes/mod.rs | 4 + .../rules/f_string_missing_placeholders.rs | 83 +- .../rules/invalid_literal_comparisons.rs | 47 +- .../pyflakes/rules/raise_not_implemented.rs | 19 +- .../src/rules/pyflakes/rules/repeated_keys.rs | 96 +- .../src/rules/pyflakes/rules/strings.rs | 131 +- .../src/rules/pyflakes/rules/unused_import.rs | 14 +- .../rules/pyflakes/rules/unused_variable.rs | 25 +- ...les__pyflakes__tests__F401_F401_19.py.snap | 4 + ..._rules__pyflakes__tests__F541_F541.py.snap | 50 +- ..._rules__pyflakes__tests__F632_F632.py.snap | 39 + ...les__pyflakes__tests__F821_F821_18.py.snap | 4 + ...les__pyflakes__tests__F821_F821_19.py.snap | 12 + ...les__pyflakes__tests__F821_F821_20.py.snap | 14 + .../pygrep_hooks/rules/deprecated_log_warn.rs | 44 +- ...grep_hooks__tests__PGH002_PGH002_1.py.snap | 9 + .../ruff_linter/src/rules/pylint/helpers.rs | 8 +- crates/ruff_linter/src/rules/pylint/mod.rs | 24 + .../src/rules/pylint/rules/and_or_ternary.rs | 133 + .../pylint/rules/bad_dunder_method_name.rs | 13 +- .../pylint/rules/comparison_with_itself.rs | 2 +- .../pylint/rules/global_at_module_level.rs | 34 + .../pylint/rules/invalid_string_characters.rs | 33 +- .../rules/pylint/rules/iteration_over_set.rs | 26 +- .../rules/pylint/rules/literal_membership.rs | 68 + .../src/rules/pylint/rules/logging.rs | 39 +- .../pylint/rules/magic_value_comparison.rs | 20 +- .../rules/pylint/rules/manual_import_from.rs | 37 +- .../pylint/rules/misplaced_bare_raise.rs | 70 + .../ruff_linter/src/rules/pylint/rules/mod.rs | 18 + .../src/rules/pylint/rules/nested_min_max.rs | 36 +- .../src/rules/pylint/rules/no_self_use.rs | 46 +- .../pylint/rules/non_ascii_module_import.rs | 92 + .../src/rules/pylint/rules/non_ascii_name.rs | 116 + .../rules/repeated_equality_comparison.rs | 36 +- .../pylint/rules/repeated_isinstance_calls.rs | 22 +- .../src/rules/pylint/rules/return_in_init.rs | 4 +- .../src/rules/pylint/rules/sys_exit_alias.rs | 27 +- .../rules/pylint/rules/too_many_arguments.rs | 2 +- .../rules/too_many_boolean_expressions.rs | 89 + .../rules/pylint/rules/unnecessary_lambda.rs | 209 + .../pylint/rules/unspecified_encoding.rs | 157 + .../pylint/rules/useless_import_alias.rs | 17 +- .../src/rules/pylint/rules/useless_return.rs | 24 +- .../src/rules/pylint/rules/yield_in_init.rs | 4 +- .../ruff_linter/src/rules/pylint/settings.rs | 3 +- ..._tests__PLC0208_iteration_over_set.py.snap | 176 +- ...int__tests__PLC2401_non_ascii_name.py.snap | 79 + ...s__PLC2403_non_ascii_module_import.py.snap | 38 + ..._tests__PLE0605_invalid_all_format.py.snap | 22 +- ...ests__PLE0704_misplaced_bare_raise.py.snap | 90 + ...sts__PLE1205_logging_too_many_args.py.snap | 20 + ...ests__PLE1206_logging_too_few_args.py.snap | 10 + ..._tests__PLE2510_invalid_characters.py.snap | 51 +- ..._tests__PLE2512_invalid_characters.py.snap | 87 +- ..._tests__PLE2513_invalid_characters.py.snap | 84 +- ..._tests__PLE2514_invalid_characters.py.snap | Bin 408 -> 799 bytes ..._tests__PLE2515_invalid_characters.py.snap | 180 +- ..._tests__PLR0913_too_many_arguments.py.snap | 10 +- ...int__tests__PLR1706_and_or_ternary.py.snap | 229 + ...R1714_repeated_equality_comparison.py.snap | 180 +- ..._tests__PLR6201_literal_membership.py.snap | 69 + ...pylint__tests__PLR6301_no_self_use.py.snap | 39 +- ..._tests__PLW0108_unnecessary_lambda.py.snap | 76 + ...ts__PLW0604_global_at_module_level.py.snap | 21 + ...ests__PLW1514_unspecified_encoding.py.snap | 72 + ...inter__rules__pylint__tests__max_args.snap | 4 +- ..._tests__max_args_with_dummy_variables.snap | 2 +- ...ylint__tests__max_boolean_expressions.snap | 214 + .../ruff_linter/src/rules/pyupgrade/fixes.rs | 2 +- .../src/rules/pyupgrade/helpers.rs | 23 +- crates/ruff_linter/src/rules/pyupgrade/mod.rs | 2 + ...convert_named_tuple_functional_to_class.rs | 29 +- .../convert_typed_dict_functional_to_class.rs | 31 +- .../pyupgrade/rules/datetime_utc_alias.rs | 27 +- .../rules/deprecated_c_element_tree.rs | 19 +- .../pyupgrade/rules/deprecated_import.rs | 35 +- .../pyupgrade/rules/deprecated_mock_import.rs | 51 +- .../rules/deprecated_unittest_alias.rs | 17 +- .../pyupgrade/rules/extraneous_parentheses.rs | 25 +- .../src/rules/pyupgrade/rules/f_strings.rs | 72 +- .../rules/pyupgrade/rules/format_literals.rs | 20 +- .../rules/lru_cache_with_maxsize_none.rs | 29 +- .../rules/lru_cache_without_parameters.rs | 11 +- .../rules/pyupgrade/rules/native_literals.rs | 45 +- .../src/rules/pyupgrade/rules/open_alias.rs | 19 +- .../rules/pyupgrade/rules/os_error_alias.rs | 101 +- .../pyupgrade/rules/outdated_version_block.rs | 264 +- .../rules/printf_string_formatting.rs | 79 +- .../pyupgrade/rules/quoted_annotation.rs | 17 +- .../pyupgrade/rules/redundant_open_modes.rs | 32 +- .../pyupgrade/rules/replace_stdout_stderr.rs | 20 +- .../rules/replace_universal_newlines.rs | 41 +- .../rules/super_call_with_parameters.rs | 17 +- .../pyupgrade/rules/type_of_primitive.rs | 23 +- .../pyupgrade/rules/typing_text_str_alias.rs | 19 +- .../pyupgrade/rules/unicode_kind_prefix.rs | 17 +- .../rules/unnecessary_builtin_import.rs | 47 +- .../rules/unnecessary_class_parentheses.rs | 17 +- .../rules/unnecessary_coding_comment.rs | 20 +- .../rules/unnecessary_encode_utf8.rs | 115 +- .../rules/unnecessary_future_import.rs | 47 +- .../rules/unpacked_list_comprehension.rs | 27 +- .../pyupgrade/rules/use_pep585_annotation.rs | 51 +- .../pyupgrade/rules/use_pep604_annotation.rs | 19 +- .../pyupgrade/rules/use_pep604_isinstance.rs | 23 +- .../pyupgrade/rules/use_pep695_type_alias.rs | 108 +- .../pyupgrade/rules/useless_metaclass_type.rs | 23 +- .../rules/useless_object_inheritance.rs | 29 +- .../pyupgrade/rules/yield_in_for_loop.rs | 37 +- ...er__rules__pyupgrade__tests__UP005.py.snap | 8 +- ...er__rules__pyupgrade__tests__UP010.py.snap | 20 +- ...er__rules__pyupgrade__tests__UP013.py.snap | 24 +- ...er__rules__pyupgrade__tests__UP014.py.snap | 10 +- ...er__rules__pyupgrade__tests__UP015.py.snap | 170 +- ...er__rules__pyupgrade__tests__UP018.py.snap | 30 +- ...er__rules__pyupgrade__tests__UP020.py.snap | 2 +- ...er__rules__pyupgrade__tests__UP021.py.snap | 6 +- ...er__rules__pyupgrade__tests__UP023.py.snap | 20 +- ...er__rules__pyupgrade__tests__UP026.py.snap | 52 +- ...er__rules__pyupgrade__tests__UP027.py.snap | 10 +- ...__rules__pyupgrade__tests__UP032_0.py.snap | 102 +- ...__rules__pyupgrade__tests__UP032_1.py.snap | 2 +- ...__rules__pyupgrade__tests__UP032_2.py.snap | 44 +- ...__rules__pyupgrade__tests__UP032_3.py.snap | 4 + ...er__rules__pyupgrade__tests__UP035.py.snap | 124 +- ...__rules__pyupgrade__tests__UP036_0.py.snap | 89 + ...er__rules__pyupgrade__tests__UP040.py.snap | 22 +- ...r__rules__pyupgrade__tests__UP040.pyi.snap | 38 + ...rade__tests__datetime_utc_alias_py311.snap | 8 +- crates/ruff_linter/src/rules/refurb/mod.rs | 3 + .../refurb/rules/check_and_remove_from_set.rs | 21 +- .../rules/refurb/rules/delete_full_slice.rs | 12 +- .../src/rules/refurb/rules/implicit_cwd.rs | 106 + .../ruff_linter/src/rules/refurb/rules/mod.rs | 6 + .../rules/refurb/rules/print_empty_string.rs | 58 +- .../src/rules/refurb/rules/read_whole_file.rs | 336 + .../refurb/rules/reimplemented_starmap.rs | 120 +- .../src/rules/refurb/rules/repeated_append.rs | 13 +- .../rules/single_item_membership_test.rs | 129 + .../src/rules/refurb/rules/slice_copy.rs | 22 +- .../refurb/rules/unnecessary_enumerate.rs | 88 +- ...es__refurb__tests__FURB101_FURB101.py.snap | 96 + ...es__refurb__tests__FURB105_FURB105.py.snap | 34 +- ...es__refurb__tests__FURB140_FURB140.py.snap | 80 +- ...es__refurb__tests__FURB145_FURB145.py.snap | 12 +- ...es__refurb__tests__FURB148_FURB148.py.snap | 588 +- ...es__refurb__tests__FURB171_FURB171.py.snap | 123 + ...es__refurb__tests__FURB177_FURB177.py.snap | 94 + crates/ruff_linter/src/rules/ruff/mod.rs | 26 +- .../ruff/rules/ambiguous_unicode_character.rs | 1 + .../rules/ruff/rules/assignment_in_assert.rs | 53 + .../rules/collection_literal_concatenation.rs | 25 +- .../explicit_f_string_type_conversion.rs | 17 +- .../src/rules/ruff/rules/helpers.rs | 12 +- .../src/rules/ruff/rules/implicit_optional.rs | 22 +- .../ruff/rules/invalid_pyproject_toml.rs | 4 +- .../ruff_linter/src/rules/ruff/rules/mod.rs | 4 + .../rules/ruff/rules/mutable_class_default.rs | 10 +- .../rules/ruff/rules/pairwise_over_zipped.rs | 102 +- .../ruff/rules/quadratic_list_summation.rs | 28 +- .../rules/static_key_dict_comprehension.rs | 2 +- ...y_iterable_allocation_for_first_element.rs | 68 +- .../rules/ruff/rules/unnecessary_key_check.rs | 131 + .../src/rules/ruff/rules/unused_noqa.rs | 11 +- ..._rules__ruff__tests__RUF015_RUF015.py.snap | 219 +- ...les__ruff__tests__RUF017_RUF017_0.py.snap} | 37 +- ...ules__ruff__tests__RUF017_RUF017_1.py.snap | 17 + ..._rules__ruff__tests__RUF018_RUF018.py.snap | 22 + ..._rules__ruff__tests__RUF019_RUF019.py.snap | 82 + ...nter__rules__ruff__tests__confusables.snap | 96 + ..._linter__rules__ruff__tests__ruf100_0.snap | 250 +- ...__rules__ruff__tests__ruf100_0_prefix.snap | 267 + ..._linter__rules__ruff__tests__ruf100_1.snap | 10 +- ..._linter__rules__ruff__tests__ruf100_2.snap | 2 +- ..._linter__rules__ruff__tests__ruf100_3.snap | 38 +- ..._linter__rules__ruff__tests__ruf100_5.snap | 6 +- .../src/rules/tryceratops/helpers.rs | 29 +- .../rules/error_instead_of_exception.rs | 18 +- .../tryceratops/rules/verbose_log_message.rs | 37 +- .../rules/tryceratops/rules/verbose_raise.rs | 17 +- ..._error-instead-of-exception_TRY400.py.snap | 17 + ..._tests__verbose-log-message_TRY401.py.snap | 88 + crates/ruff_linter/src/settings/defaults.rs | 1 - crates/ruff_linter/src/settings/mod.rs | 47 +- crates/ruff_linter/src/settings/rule_table.rs | 6 +- crates/ruff_linter/src/settings/types.rs | 36 +- crates/ruff_linter/src/source_kind.rs | 144 +- crates/ruff_linter/src/test.rs | 36 +- crates/ruff_macros/src/cache_key.rs | 1 + crates/ruff_macros/src/combine_options.rs | 2 + crates/ruff_macros/src/config.rs | 221 +- crates/ruff_macros/src/lib.rs | 4 +- crates/ruff_macros/src/map_codes.rs | 16 +- crates/ruff_macros/src/rule_namespace.rs | 1 + crates/ruff_macros/src/violation.rs | 6 +- crates/ruff_notebook/Cargo.toml | 4 +- crates/ruff_notebook/src/index.rs | 34 +- crates/ruff_notebook/src/notebook.rs | 79 +- crates/ruff_python_ast/Cargo.toml | 2 - crates/ruff_python_ast/src/all.rs | 12 +- crates/ruff_python_ast/src/comparable.rs | 19 +- crates/ruff_python_ast/src/expression.rs | 2 +- crates/ruff_python_ast/src/helpers.rs | 66 +- crates/ruff_python_ast/src/int.rs | 235 + crates/ruff_python_ast/src/lib.rs | 19 +- crates/ruff_python_ast/src/node.rs | 66 +- crates/ruff_python_ast/src/nodes.rs | 39 +- crates/ruff_python_ast/src/parenthesize.rs | 75 +- .../ruff_python_ast/src/visitor/preorder.rs | 2 +- crates/ruff_python_ast/tests/preorder.rs | 4 +- crates/ruff_python_ast/tests/visitor.rs | 4 +- crates/ruff_python_codegen/src/stylist.rs | 54 + crates/ruff_python_formatter/Cargo.toml | 4 +- crates/ruff_python_formatter/README.md | 403 +- crates/ruff_python_formatter/generate.py | 2 +- .../fixtures/black/miscellaneous/force_pyi.py | 1 + .../black/miscellaneous/string_quotes.py | 1 + .../miscellaneous/string_quotes.py.expect | 1 + .../test/fixtures/black/raw_docstring.py | 16 + .../fixtures/black/raw_docstring.py.expect | 14 + .../test/fixtures/ruff/expression/binary.py | 24 +- .../ruff/expression/binary_pow_spacing.py | 10 + .../ruff/expression/boolean_operation.py | 8 +- .../test/fixtures/ruff/expression/fstring.py | 5 + .../fixtures/ruff/expression/list_comp.py | 10 + .../test/fixtures/ruff/expression/number.py | 7 + .../test/fixtures/ruff/expression/slice.py | 2 +- .../test/fixtures/ruff/expression/unary.py | 40 +- .../fixtures/ruff/expression/unsplittable.py | 2 +- ...f_unclosed_deep_nested_trailing_comment.py | 8 + .../fmt_off_unclosed_trailing_comment.py | 8 + .../test/fixtures/ruff/fmt_skip/decorators.py | 13 + .../resources/test/fixtures/ruff/form_feed.py | 6 + .../resources/test/fixtures/ruff/newlines.py | 95 + .../expression_parentheses_comments.py | 113 + ...king.options.json => preview.options.json} | 0 .../assign_breaking.py => preview.py} | 38 +- .../fixtures/ruff/statement/ann_assign.py | 15 + .../ruff/statement/class_definition.py | 2 + .../test/fixtures/ruff/statement/for.py | 8 +- .../test/fixtures/ruff/statement/function.py | 26 + .../test/fixtures/ruff/statement/if.py | 35 +- .../test/fixtures/ruff/statement/import.py | 20 + .../fixtures/ruff/statement/import_from.py | 2 + .../test/fixtures/ruff/statement/match.py | 109 +- .../test/fixtures/ruff/statement/try.py | 48 +- .../fixtures/ruff/statement/type_alias.py | 4 + .../test/fixtures/ruff/statement/while.py | 2 +- .../test/fixtures/ruff/statement/with.py | 105 +- .../test/fixtures/ruff/trailing_comments.py | 2 + .../resources/test/fixtures/ruff/trivia.py | 4 +- crates/ruff_python_formatter/src/builders.rs | 4 +- crates/ruff_python_formatter/src/cli.rs | 58 +- .../src/comments/debug.rs | 2 +- .../src/comments/format.rs | 143 +- .../ruff_python_formatter/src/comments/mod.rs | 29 +- .../src/comments/node_key.rs | 4 +- .../src/comments/placement.rs | 119 +- .../src/comments/visitor.rs | 2 +- .../src/expression/binary_like.rs | 7 +- .../src/expression/expr_attribute.rs | 37 +- .../src/expression/expr_await.rs | 2 +- .../src/expression/expr_bin_op.rs | 2 +- .../src/expression/expr_bool_op.rs | 2 +- .../src/expression/expr_call.rs | 2 +- .../src/expression/expr_compare.rs | 5 +- .../src/expression/expr_constant.rs | 2 +- .../src/expression/expr_dict.rs | 2 +- .../src/expression/expr_dict_comp.rs | 13 +- .../src/expression/expr_f_string.rs | 12 +- .../src/expression/expr_formatted_value.rs | 2 +- .../src/expression/expr_generator_exp.rs | 2 +- .../src/expression/expr_if_exp.rs | 2 +- .../src/expression/expr_ipy_escape_command.rs | 11 + .../src/expression/expr_lambda.rs | 2 +- .../src/expression/expr_list.rs | 2 +- .../src/expression/expr_list_comp.rs | 2 +- .../src/expression/expr_name.rs | 5 +- .../src/expression/expr_named_expr.rs | 2 +- .../src/expression/expr_set.rs | 2 +- .../src/expression/expr_set_comp.rs | 2 +- .../src/expression/expr_slice.rs | 11 +- .../src/expression/expr_starred.rs | 2 +- .../src/expression/expr_subscript.rs | 2 +- .../src/expression/expr_tuple.rs | 4 +- .../src/expression/expr_unary_op.rs | 13 +- .../src/expression/expr_yield.rs | 2 +- .../src/expression/expr_yield_from.rs | 2 +- .../src/expression/mod.rs | 361 +- .../src/expression/number.rs | 13 +- .../src/expression/parentheses.rs | 2 +- .../src/expression/string.rs | 224 +- crates/ruff_python_formatter/src/lib.rs | 94 +- crates/ruff_python_formatter/src/main.rs | 10 +- .../src/module/mod_module.rs | 5 +- crates/ruff_python_formatter/src/options.rs | 4 + .../ruff_python_formatter/src/other/alias.rs | 3 +- .../src/other/comprehension.rs | 41 +- .../src/other/identifier.rs | 53 + .../src/other/match_case.rs | 2 +- .../src/other/parameter_with_default.rs | 48 +- .../src/other/parameters.rs | 2 +- .../src/other/with_item.rs | 19 +- .../ruff_python_formatter/src/pattern/mod.rs | 2 +- .../src/pattern/pattern_arguments.rs | 2 +- .../src/pattern/pattern_match_as.rs | 2 +- .../src/pattern/pattern_match_class.rs | 2 +- .../src/pattern/pattern_match_mapping.rs | 2 +- .../src/pattern/pattern_match_or.rs | 2 +- .../src/pattern/pattern_match_sequence.rs | 40 +- .../src/pattern/pattern_match_singleton.rs | 2 +- .../src/pattern/pattern_match_star.rs | 2 +- .../src/pattern/pattern_match_value.rs | 2 +- .../src/statement/clause.rs | 18 +- .../src/statement/stmt_ann_assign.rs | 7 +- .../src/statement/stmt_class_def.rs | 45 +- .../src/statement/stmt_function_def.rs | 27 +- .../src/statement/stmt_global.rs | 2 +- .../src/statement/stmt_if.rs | 2 +- .../src/statement/stmt_import_from.rs | 16 +- .../src/statement/stmt_nonlocal.rs | 2 +- .../src/statement/stmt_while.rs | 2 +- .../src/statement/stmt_with.rs | 8 +- .../src/statement/suite.rs | 138 +- .../src/type_param/type_params.rs | 10 +- crates/ruff_python_formatter/src/verbatim.rs | 16 +- .../ruff_python_formatter/tests/fixtures.rs | 56 +- ...tibility@miscellaneous__decorators.py.snap | 96 +- ...atibility@miscellaneous__force_pyi.py.snap | 13 +- ...aneous__long_strings_flag_disabled.py.snap | 15 +- ...ility@miscellaneous__string_quotes.py.snap | 5 +- ...lack_compatibility@py_39__python39.py.snap | 86 - .../black_compatibility@raw_docstring.py.snap | 92 + ...ttribute_access_on_number_literals.py.snap | 108 - ...atibility@simple_cases__expression.py.snap | 11 +- ...patibility@simple_cases__function2.py.snap | 8 +- .../format@expression__binary.py.snap | 53 +- ...mat@expression__binary_pow_spacing.py.snap | 34 + ...rmat@expression__boolean_operation.py.snap | 16 +- .../format@expression__bytes.py.snap | 16 +- .../snapshots/format@expression__call.py.snap | 5 +- .../format@expression__fstring.py.snap | 10 + .../format@expression__list_comp.py.snap | 20 + .../format@expression__number.py.snap | 28 + .../format@expression__slice.py.snap | 4 +- .../format@expression__string.py.snap | 28 +- .../format@expression__unary.py.snap | 127 +- .../format@expression__unsplittable.py.snap | 4 +- ...losed_deep_nested_trailing_comment.py.snap | 30 + ..._fmt_off_unclosed_trailing_comment.py.snap | 30 + .../format@fmt_on_off__form_feed.py.snap | 1 + ...rmat@fmt_on_off__trailing_comments.py.snap | 17 + .../format@fmt_skip__decorators.py.snap | 27 + .../tests/snapshots/format@form_feed.py.snap | 26 + .../tests/snapshots/format@newlines.py.snap | 232 +- ...s__expression_parentheses_comments.py.snap | 225 + ..._opening_parentheses_comment_value.py.snap | 4 +- ...reaking.py.snap => format@preview.py.snap} | 114 +- .../format@statement__ann_assign.py.snap | 44 +- ...format@statement__class_definition.py.snap | 46 + .../snapshots/format@statement__for.py.snap | 16 +- .../format@statement__function.py.snap | 216 + .../snapshots/format@statement__if.py.snap | 74 +- .../format@statement__import.py.snap | 37 + .../format@statement__import_from.py.snap | 4 + .../snapshots/format@statement__match.py.snap | 236 +- ...ormat@statement__return_annotation.py.snap | 294 + .../format@statement__top_level.py.snap | 53 + .../snapshots/format@statement__try.py.snap | 97 +- .../format@statement__type_alias.py.snap | 8 + .../snapshots/format@statement__while.py.snap | 4 +- .../snapshots/format@statement__with.py.snap | 239 +- .../format@trailing_comments.py.snap | 4 + .../tests/snapshots/format@trivia.py.snap | 8 +- .../ruff_python_index/src/comment_ranges.rs | 23 +- .../ruff_python_index/src/fstring_ranges.rs | 97 + crates/ruff_python_index/src/indexer.rs | 250 +- crates/ruff_python_index/src/lib.rs | 3 +- crates/ruff_python_literal/Cargo.toml | 1 - crates/ruff_python_literal/src/float.rs | 44 +- crates/ruff_python_parser/Cargo.toml | 6 +- crates/ruff_python_parser/src/lexer.rs | 561 +- crates/ruff_python_parser/src/lexer/cursor.rs | 29 + .../ruff_python_parser/src/lexer/fstring.rs | 161 + crates/ruff_python_parser/src/lib.rs | 132 +- crates/ruff_python_parser/src/parser.rs | 138 +- crates/ruff_python_parser/src/python.lalrpop | 146 +- crates/ruff_python_parser/src/python.rs | 36531 ++++++++++------ ..._parser__lexer__tests__empty_fstrings.snap | 66 + ..._python_parser__lexer__tests__fstring.snap | 88 + ...arser__lexer__tests__fstring_comments.snap | 60 + ...ser__lexer__tests__fstring_conversion.snap | 116 + ..._parser__lexer__tests__fstring_escape.snap | 71 + ...__lexer__tests__fstring_escape_braces.snap | 98 + ...ser__lexer__tests__fstring_escape_raw.snap | 71 + ...__tests__fstring_expression_multiline.snap | 72 + ...rser__lexer__tests__fstring_multiline.snap | 99 + ...__lexer__tests__fstring_named_unicode.snap | 25 + ...xer__tests__fstring_named_unicode_raw.snap | 46 + ..._parser__lexer__tests__fstring_nested.snap | 163 + ...er__lexer__tests__fstring_parentheses.snap | 154 + ..._parser__lexer__tests__fstring_prefix.snap | 90 + ...__fstring_single_quote_escape_mac_eol.snap | 25 + ..._fstring_single_quote_escape_unix_eol.snap | 25 + ...tring_single_quote_escape_windows_eol.snap | 25 + ...exer__tests__fstring_with_format_spec.snap | 266 + ...ests__fstring_with_ipy_escape_command.snap | 50 + ...tests__fstring_with_lambda_expression.snap | 110 + ...s__fstring_with_multiline_format_spec.snap | 244 + ..._tests__fstring_with_named_expression.snap | 170 + ...__lexer__tests__fstring_with_nul_char.snap | 25 + ...exer__tests__invalid_leading_zero_big.snap | 12 + ...er__tests__invalid_leading_zero_small.snap | 12 + ..._python_parser__lexer__tests__numbers.snap | 14 +- ...ython_parser__parser__tests__fstrings.snap | 877 + ..._parser__tests__fstrings_with_unicode.snap | 214 + ...f_python_parser__parser__tests__match.snap | 149 + ...f_python_parser__parser__tests__patma.snap | 60 +- ...arser__parser__tests__unicode_aliases.snap | 32 + ...__fstring_parse_self_documenting_base.snap | 45 +- ...ring_parse_self_documenting_base_more.snap | 131 +- ...fstring_parse_self_documenting_format.snap | 83 +- ...r__string__tests__parse_empty_fstring.snap | 17 +- ..._parser__string__tests__parse_fstring.snap | 87 +- ...__string__tests__parse_fstring_equals.snap | 65 +- ...ring_nested_concatenation_string_spec.snap | 91 +- ...ing__tests__parse_fstring_nested_spec.snap | 81 +- ...sts__parse_fstring_nested_string_spec.snap | 91 +- ...ring__tests__parse_fstring_not_equals.snap | 65 +- ..._tests__parse_fstring_not_nested_spec.snap | 73 +- ...ts__parse_fstring_self_doc_prec_space.snap | 45 +- ...parse_fstring_self_doc_trailing_space.snap | 45 +- ...ring__tests__parse_fstring_yield_expr.snap | 33 +- ..._tests__string_parser_escaped_mac_eol.snap | 23 + ...tests__string_parser_escaped_unix_eol.snap | 23 + ...ts__string_parser_escaped_windows_eol.snap | 23 + crates/ruff_python_parser/src/string.rs | 827 +- crates/ruff_python_parser/src/token.rs | 91 +- crates/ruff_python_semantic/Cargo.toml | 1 - .../src/analyze/typing.rs | 57 +- crates/ruff_python_semantic/src/model.rs | 27 +- crates/ruff_python_semantic/src/nodes.rs | 6 +- crates/ruff_python_stdlib/src/builtins.rs | 8 + crates/ruff_python_trivia/src/lib.rs | 2 + crates/ruff_python_trivia/src/pragmas.rs | 30 + crates/ruff_python_trivia/src/tokenizer.rs | 42 +- crates/ruff_shrinking/Cargo.toml | 2 +- crates/ruff_shrinking/src/main.rs | 2 +- crates/ruff_source_file/src/lib.rs | 4 + crates/ruff_source_file/src/line_index.rs | 14 + crates/ruff_wasm/src/lib.rs | 75 +- crates/ruff_workspace/Cargo.toml | 3 +- crates/ruff_workspace/src/configuration.rs | 763 +- crates/ruff_workspace/src/options.rs | 1001 +- crates/ruff_workspace/src/options_base.rs | 42 +- crates/ruff_workspace/src/pyproject.rs | 26 +- crates/ruff_workspace/src/resolver.rs | 195 +- crates/ruff_workspace/src/settings.rs | 28 +- docs/configuration.md | 448 +- docs/faq.md | 80 +- docs/formatter.md | 274 + docs/formatter/black.md | 510 + docs/installation.md | 7 + ...editor-integrations.md => integrations.md} | 106 +- docs/linter.md | 295 + docs/preview.md | 43 +- docs/requirements-insiders.txt | 2 +- docs/requirements.txt | 2 +- docs/tutorial.md | 189 +- docs/usage.md | 109 - docs/versioning.md | 64 + mkdocs.template.yml | 15 +- playground/src/Editor/SourceEditor.tsx | 5 +- pyproject.toml | 7 +- python/ruff-ecosystem/README.md | 46 + python/ruff-ecosystem/pyproject.toml | 15 + .../ruff-ecosystem/ruff_ecosystem/__init__.py | 3 + .../ruff-ecosystem/ruff_ecosystem/__main__.py | 8 + python/ruff-ecosystem/ruff_ecosystem/check.py | 563 + python/ruff-ecosystem/ruff_ecosystem/cli.py | 166 + .../ruff-ecosystem/ruff_ecosystem/defaults.py | 73 + .../ruff-ecosystem/ruff_ecosystem/format.py | 195 + python/ruff-ecosystem/ruff_ecosystem/main.py | 144 + .../ruff-ecosystem/ruff_ecosystem/markdown.py | 44 + .../ruff-ecosystem/ruff_ecosystem/projects.py | 168 + python/ruff-ecosystem/ruff_ecosystem/types.py | 93 + ruff.schema.json | 727 +- rust-toolchain.toml | 2 +- scripts/add_rule.py | 3 +- scripts/benchmarks/pyproject.toml | 2 +- scripts/benchmarks/run_formatter.sh | 4 +- scripts/check_docs_formatted.py | 2 + scripts/check_ecosystem.py | 6 +- scripts/ecosystem_all_check.py | 2 +- scripts/ecosystem_all_check.sh | 6 +- scripts/formatter_ecosystem_checks.sh | 36 +- scripts/generate_mkdocs.py | 13 +- 1014 files changed, 66231 insertions(+), 29105 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 assets/badge/format.json create mode 100644 crates/ruff_cli/build.rs create mode 100644 crates/ruff_cli/resources/test/fixtures/formatted.py create mode 100644 crates/ruff_cli/resources/test/fixtures/unformatted.ipynb create mode 100644 crates/ruff_cli/resources/test/fixtures/unformatted.py create mode 100644 crates/ruff_cli/src/commands/version.rs create mode 100644 crates/ruff_cli/src/snapshots/ruff_cli__version__tests__version_formatting.snap create mode 100644 crates/ruff_cli/src/snapshots/ruff_cli__version__tests__version_formatting_with_commit_info.snap create mode 100644 crates/ruff_cli/src/snapshots/ruff_cli__version__tests__version_formatting_with_commits_since_last_tag.snap create mode 100644 crates/ruff_cli/src/snapshots/ruff_cli__version__tests__version_serializable.snap create mode 100644 crates/ruff_cli/src/version.rs delete mode 100644 crates/ruff_cli/tests/black_compatibility_test.rs create mode 100644 crates/ruff_cli/tests/lint.rs create mode 100644 crates/ruff_linter/resources/test/fixtures/flake8_bandit/S310.py create mode 100644 crates/ruff_linter/resources/test/fixtures/flake8_bandit/S505.py create mode 100644 crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B006_5.py create mode 100644 crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B006_6.py create mode 100644 crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B006_7.py create mode 100644 crates/ruff_linter/resources/test/fixtures/flake8_type_checking/TCH004_15.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pycodestyle/E501_3.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_2.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pydocstyle/D300.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pyflakes/F401_19.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pyflakes/F821_18.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pyflakes/F821_19.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pyflakes/F821_20.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pylint/and_or_ternary.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pylint/global_at_module_level.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pylint/literal_membership.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pylint/misplaced_bare_raise.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pylint/non_ascii_module_import.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pylint/non_ascii_name.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pylint/too_many_boolean_expressions.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pylint/unnecessary_lambda.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pylint/unspecified_encoding.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pyupgrade/UP032_3.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pyupgrade/UP040.pyi create mode 100644 crates/ruff_linter/resources/test/fixtures/refurb/FURB101.py create mode 100644 crates/ruff_linter/resources/test/fixtures/refurb/FURB171.py create mode 100644 crates/ruff_linter/resources/test/fixtures/refurb/FURB177.py rename crates/ruff_linter/resources/test/fixtures/ruff/{RUF017.py => RUF017_0.py} (73%) create mode 100644 crates/ruff_linter/resources/test/fixtures/ruff/RUF017_1.py create mode 100644 crates/ruff_linter/resources/test/fixtures/ruff/RUF018.py create mode 100644 crates/ruff_linter/resources/test/fixtures/ruff/RUF019.py create mode 100644 crates/ruff_linter/src/checkers/ast/analyze/deferred_lambdas.rs rename crates/ruff_linter/src/{autofix => fix}/codemods.rs (100%) rename crates/ruff_linter/src/{autofix => fix}/edits.rs (82%) rename crates/ruff_linter/src/{autofix => fix}/mod.rs (94%) rename crates/ruff_linter/src/{autofix => fix}/snippet.rs (100%) create mode 100644 crates/ruff_linter/src/message/snapshots/ruff_linter__message__grouped__tests__fix_status_unsafe.snap create mode 100644 crates/ruff_linter/src/message/snapshots/ruff_linter__message__json__tests__notebook_output.snap create mode 100644 crates/ruff_linter/src/message/snapshots/ruff_linter__message__json_lines__tests__notebook_output.snap create mode 100644 crates/ruff_linter/src/message/snapshots/ruff_linter__message__text__tests__fix_status_unsafe.snap create mode 100644 crates/ruff_linter/src/message/snapshots/ruff_linter__message__text__tests__notebook_output.snap create mode 100644 crates/ruff_linter/src/rules/flake8_bandit/rules/weak_cryptographic_key.rs create mode 100644 crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S310_S310.py.snap create mode 100644 crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S505_S505.py.snap create mode 100644 crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_5.py.snap create mode 100644 crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_6.py.snap create mode 100644 crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_7.py.snap delete mode 100644 crates/ruff_linter/src/rules/flake8_pie/rules/no_unnecessary_pass.rs create mode 100644 crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_pass.rs create mode 100644 crates/ruff_linter/src/rules/flake8_quotes/rules/avoidable_escaped_quote.rs rename crates/ruff_linter/src/rules/flake8_quotes/rules/{from_tokens.rs => check_string_quotes.rs} (50%) create mode 100644 crates/ruff_linter/src/rules/flake8_quotes/snapshots/ruff_linter__rules__flake8_quotes__tests__require_doubles_over_singles_escaped_py311.snap create mode 100644 crates/ruff_linter/src/rules/flake8_quotes/snapshots/ruff_linter__rules__flake8_quotes__tests__require_singles_over_doubles_escaped_py311.snap delete mode 100644 crates/ruff_linter/src/rules/flake8_simplify/rules/ast_if.rs create mode 100644 crates/ruff_linter/src/rules/flake8_simplify/rules/collapsible_if.rs delete mode 100644 crates/ruff_linter/src/rules/flake8_simplify/rules/fix_if.rs create mode 100644 crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_dict_get.rs create mode 100644 crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_dict_lookup.rs create mode 100644 crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_if_exp.rs create mode 100644 crates/ruff_linter/src/rules/flake8_simplify/rules/if_with_same_arms.rs create mode 100644 crates/ruff_linter/src/rules/flake8_simplify/rules/needless_bool.rs create mode 100644 crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__preview__SIM401_SIM401.py.snap create mode 100644 crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__runtime-import-in-type-checking-block_TCH004_15.py.snap create mode 100644 crates/ruff_linter/src/rules/pycodestyle/overlong.rs create mode 100644 crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E122_E12.py.snap create mode 100644 crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E501_E501_3.py.snap create mode 100644 crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_2.py.snap create mode 100644 crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__preview__E721_E721.py.snap create mode 100644 crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D300_D300.py.snap create mode 100644 crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__preview__D300_D.py.snap create mode 100644 crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__preview__D300_D300.py.snap create mode 100644 crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F401_F401_19.py.snap create mode 100644 crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F821_F821_18.py.snap create mode 100644 crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F821_F821_19.py.snap create mode 100644 crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F821_F821_20.py.snap create mode 100644 crates/ruff_linter/src/rules/pylint/rules/and_or_ternary.rs create mode 100644 crates/ruff_linter/src/rules/pylint/rules/global_at_module_level.rs create mode 100644 crates/ruff_linter/src/rules/pylint/rules/literal_membership.rs create mode 100644 crates/ruff_linter/src/rules/pylint/rules/misplaced_bare_raise.rs create mode 100644 crates/ruff_linter/src/rules/pylint/rules/non_ascii_module_import.rs create mode 100644 crates/ruff_linter/src/rules/pylint/rules/non_ascii_name.rs create mode 100644 crates/ruff_linter/src/rules/pylint/rules/too_many_boolean_expressions.rs create mode 100644 crates/ruff_linter/src/rules/pylint/rules/unnecessary_lambda.rs create mode 100644 crates/ruff_linter/src/rules/pylint/rules/unspecified_encoding.rs create mode 100644 crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLC2401_non_ascii_name.py.snap create mode 100644 crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLC2403_non_ascii_module_import.py.snap create mode 100644 crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE0704_misplaced_bare_raise.py.snap create mode 100644 crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1706_and_or_ternary.py.snap create mode 100644 crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR6201_literal_membership.py.snap create mode 100644 crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW0108_unnecessary_lambda.py.snap create mode 100644 crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW0604_global_at_module_level.py.snap create mode 100644 crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW1514_unspecified_encoding.py.snap create mode 100644 crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_boolean_expressions.snap create mode 100644 crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_3.py.snap create mode 100644 crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP040.pyi.snap create mode 100644 crates/ruff_linter/src/rules/refurb/rules/implicit_cwd.rs create mode 100644 crates/ruff_linter/src/rules/refurb/rules/read_whole_file.rs create mode 100644 crates/ruff_linter/src/rules/refurb/rules/single_item_membership_test.rs create mode 100644 crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB101_FURB101.py.snap create mode 100644 crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB171_FURB171.py.snap create mode 100644 crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB177_FURB177.py.snap create mode 100644 crates/ruff_linter/src/rules/ruff/rules/assignment_in_assert.rs create mode 100644 crates/ruff_linter/src/rules/ruff/rules/unnecessary_key_check.rs rename crates/ruff_linter/src/rules/ruff/snapshots/{ruff_linter__rules__ruff__tests__RUF017_RUF017.py.snap => ruff_linter__rules__ruff__tests__RUF017_RUF017_0.py.snap} (74%) create mode 100644 crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF017_RUF017_1.py.snap create mode 100644 crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF018_RUF018.py.snap create mode 100644 crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF019_RUF019.py.snap create mode 100644 crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_0_prefix.snap delete mode 100644 crates/ruff_linter/src/settings/defaults.rs create mode 100644 crates/ruff_python_ast/src/int.rs create mode 100644 crates/ruff_python_formatter/resources/test/fixtures/black/raw_docstring.py create mode 100644 crates/ruff_python_formatter/resources/test/fixtures/black/raw_docstring.py.expect create mode 100644 crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/binary_pow_spacing.py create mode 100644 crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/number.py create mode 100644 crates/ruff_python_formatter/resources/test/fixtures/ruff/fmt_on_off/fmt_off_unclosed_deep_nested_trailing_comment.py create mode 100644 crates/ruff_python_formatter/resources/test/fixtures/ruff/fmt_on_off/fmt_off_unclosed_trailing_comment.py create mode 100644 crates/ruff_python_formatter/resources/test/fixtures/ruff/form_feed.py create mode 100644 crates/ruff_python_formatter/resources/test/fixtures/ruff/parentheses/expression_parentheses_comments.py rename crates/ruff_python_formatter/resources/test/fixtures/ruff/{statement/assign_breaking.options.json => preview.options.json} (100%) rename crates/ruff_python_formatter/resources/test/fixtures/ruff/{statement/assign_breaking.py => preview.py} (62%) delete mode 100644 crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_39__python39.py.snap create mode 100644 crates/ruff_python_formatter/tests/snapshots/black_compatibility@raw_docstring.py.snap delete mode 100644 crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__attribute_access_on_number_literals.py.snap create mode 100644 crates/ruff_python_formatter/tests/snapshots/format@expression__binary_pow_spacing.py.snap create mode 100644 crates/ruff_python_formatter/tests/snapshots/format@expression__number.py.snap create mode 100644 crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_unclosed_deep_nested_trailing_comment.py.snap create mode 100644 crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_unclosed_trailing_comment.py.snap create mode 100644 crates/ruff_python_formatter/tests/snapshots/format@form_feed.py.snap create mode 100644 crates/ruff_python_formatter/tests/snapshots/format@parentheses__expression_parentheses_comments.py.snap rename crates/ruff_python_formatter/tests/snapshots/{format@statement__assign_breaking.py.snap => format@preview.py.snap} (66%) create mode 100644 crates/ruff_python_index/src/fstring_ranges.rs create mode 100644 crates/ruff_python_parser/src/lexer/fstring.rs create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__empty_fstrings.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_comments.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_conversion.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_escape.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_escape_braces.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_escape_raw.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_expression_multiline.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_multiline.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_named_unicode.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_named_unicode_raw.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_nested.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_parentheses.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_prefix.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_single_quote_escape_mac_eol.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_single_quote_escape_unix_eol.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_single_quote_escape_windows_eol.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_format_spec.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_ipy_escape_command.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_lambda_expression.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_multiline_format_spec.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_named_expression.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_nul_char.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__invalid_leading_zero_big.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__invalid_leading_zero_small.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__fstrings.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__fstrings_with_unicode.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__unicode_aliases.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_mac_eol.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_unix_eol.snap create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_windows_eol.snap create mode 100644 crates/ruff_python_trivia/src/pragmas.rs create mode 100644 docs/formatter.md create mode 100644 docs/formatter/black.md rename docs/{editor-integrations.md => integrations.md} (76%) create mode 100644 docs/linter.md delete mode 100644 docs/usage.md create mode 100644 docs/versioning.md create mode 100644 python/ruff-ecosystem/README.md create mode 100644 python/ruff-ecosystem/pyproject.toml create mode 100644 python/ruff-ecosystem/ruff_ecosystem/__init__.py create mode 100644 python/ruff-ecosystem/ruff_ecosystem/__main__.py create mode 100644 python/ruff-ecosystem/ruff_ecosystem/check.py create mode 100644 python/ruff-ecosystem/ruff_ecosystem/cli.py create mode 100644 python/ruff-ecosystem/ruff_ecosystem/defaults.py create mode 100644 python/ruff-ecosystem/ruff_ecosystem/format.py create mode 100644 python/ruff-ecosystem/ruff_ecosystem/main.py create mode 100644 python/ruff-ecosystem/ruff_ecosystem/markdown.py create mode 100644 python/ruff-ecosystem/ruff_ecosystem/projects.py create mode 100644 python/ruff-ecosystem/ruff_ecosystem/types.py diff --git a/.github/dependabot.yml b/.github/dependabot.yml index eea20ebbe8620..8b9fb3c7d141c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,5 +9,5 @@ updates: - package-ecosystem: "cargo" directory: "/" schedule: - interval: "daily" + interval: "weekly" labels: ["internal"] diff --git a/.github/release.yml b/.github/release.yml index 7b7737791d36d..5ae908bbe3cf8 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -4,7 +4,6 @@ changelog: labels: - internal - documentation - - formatter categories: - title: Breaking Changes labels: @@ -12,7 +11,6 @@ changelog: - title: Rules labels: - rule - - autofix - title: Settings labels: - configuration @@ -20,6 +18,9 @@ changelog: - title: Bug Fixes labels: - bug + - title: Formatter + labels: + - formatter - title: Preview labels: - preview diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ef17f2df333bc..effcd8b0c94df 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -43,6 +43,7 @@ jobs: - "!crates/ruff_dev/**" - "!crates/ruff_shrinking/**" - scripts/* + - .github/workflows/ci.yaml formatter: - Cargo.toml @@ -57,6 +58,7 @@ jobs: - crates/ruff_python_parser/** - crates/ruff_dev/** - scripts/* + - .github/workflows/ci.yaml cargo-fmt: name: "cargo fmt" @@ -82,12 +84,9 @@ jobs: - name: "Clippy (wasm)" run: cargo clippy -p ruff_wasm --target wasm32-unknown-unknown --all-features -- -D warnings - cargo-test: - strategy: - matrix: - os: [ubuntu-latest, windows-latest] - runs-on: ${{ matrix.os }} - name: "cargo test | ${{ matrix.os }}" + cargo-test-linux: + runs-on: ubuntu-latest + name: "cargo test (linux)" steps: - uses: actions/checkout@v4 - name: "Install Rust toolchain" @@ -96,46 +95,35 @@ jobs: uses: taiki-e/install-action@v2 with: tool: cargo-insta - - run: pip install black[d]==23.1.0 - uses: Swatinem/rust-cache@v2 - - name: "Run tests (Ubuntu)" - if: ${{ matrix.os == 'ubuntu-latest' }} + - name: "Run tests" run: cargo insta test --all --all-features --unreferenced reject - - name: "Run tests (Windows)" - if: ${{ matrix.os == 'windows-latest' }} - shell: bash - # We can't reject unreferenced snapshots on windows because flake8_executable can't run on windows - run: cargo insta test --all --all-features - - run: cargo test --package ruff_cli --test black_compatibility_test -- --ignored - # TODO: Skipped as it's currently broken. The resource were moved from the - # ruff_cli to ruff crate, but this test was not updated. - if: false # Check for broken links in the documentation. - run: cargo doc --all --no-deps env: # Setting RUSTDOCFLAGS because `cargo doc --check` isn't yet implemented (https://github.com/rust-lang/cargo/issues/10025). RUSTDOCFLAGS: "-D warnings" - uses: actions/upload-artifact@v3 - if: ${{ matrix.os == 'ubuntu-latest' }} with: name: ruff path: target/debug/ruff - cargo-fuzz: - runs-on: ubuntu-latest - name: "cargo fuzz" + cargo-test-windows: + runs-on: windows-latest + name: "cargo test (windows)" steps: - uses: actions/checkout@v4 - name: "Install Rust toolchain" run: rustup show - - uses: Swatinem/rust-cache@v2 - with: - workspaces: "fuzz -> target" - - name: "Install cargo-fuzz" + - name: "Install cargo insta" uses: taiki-e/install-action@v2 with: - tool: cargo-fuzz@0.11 - - run: cargo fuzz build -s none + tool: cargo-insta + - uses: Swatinem/rust-cache@v2 + - name: "Run tests" + shell: bash + # We can't reject unreferenced snapshots on windows because flake8_executable can't run on windows + run: cargo insta test --all --all-features cargo-test-wasm: runs-on: ubuntu-latest @@ -156,6 +144,22 @@ jobs: cd crates/ruff_wasm wasm-pack test --node + cargo-fuzz: + runs-on: ubuntu-latest + name: "cargo fuzz" + steps: + - uses: actions/checkout@v4 + - name: "Install Rust toolchain" + run: rustup show + - uses: Swatinem/rust-cache@v2 + with: + workspaces: "fuzz -> target" + - name: "Install cargo-fuzz" + uses: taiki-e/install-action@v2 + with: + tool: cargo-fuzz@0.11 + - run: cargo fuzz build -s none + scripts: name: "test scripts" runs-on: ubuntu-latest @@ -177,10 +181,10 @@ jobs: name: "ecosystem" runs-on: ubuntu-latest needs: - - cargo-test + - cargo-test-linux - determine_changes # Only runs on pull requests, since that is the only we way we can find the base version for comparison. - if: github.event_name == 'pull_request' && needs.determine_changes.outputs.linter == 'true' + if: github.event_name == 'pull_request' steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 @@ -188,27 +192,48 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} - uses: actions/download-artifact@v3 - name: Download Ruff binary + name: Download comparison Ruff binary id: ruff-target with: name: ruff path: target/debug - uses: dawidd6/action-download-artifact@v2 - name: Download base results + name: Download baseline Ruff binary with: name: ruff branch: ${{ github.event.pull_request.base.ref }} check_artifacts: true - - name: Run ecosystem check + - name: Install ruff-ecosystem + run: | + pip install ./python/ruff-ecosystem + + - name: Run `ruff check` ecosystem check + if: ${{ needs.determine_changes.outputs.linter == 'true' }} + run: | + # Make executable, since artifact download doesn't preserve this + chmod +x ./ruff ${{ steps.ruff-target.outputs.download-path }}/ruff + + ruff-ecosystem check ./ruff ${{ steps.ruff-target.outputs.download-path }}/ruff --cache ./checkouts --output-format markdown | tee ecosystem-result-check + + cat ecosystem-result-check > $GITHUB_STEP_SUMMARY + cat ecosystem-result-check > ecosystem-result + echo "" >> ecosystem-result + + - name: Run `ruff format` ecosystem check + if: ${{ needs.determine_changes.outputs.formatter == 'true' }} run: | # Make executable, since artifact download doesn't preserve this - chmod +x ruff ${{ steps.ruff-target.outputs.download-path }}/ruff + chmod +x ./ruff ${{ steps.ruff-target.outputs.download-path }}/ruff - scripts/check_ecosystem.py ruff ${{ steps.ruff-target.outputs.download-path }}/ruff | tee ecosystem-result - cat ecosystem-result > $GITHUB_STEP_SUMMARY + ruff-ecosystem format ./ruff ${{ steps.ruff-target.outputs.download-path }}/ruff --cache ./checkouts --output-format markdown | tee ecosystem-result-format + cat ecosystem-result-format > $GITHUB_STEP_SUMMARY + cat ecosystem-result-format >> ecosystem-result + + - name: Export pull request number + run: | echo ${{ github.event.number }} > pr-number - uses: actions/upload-artifact@v3 @@ -230,12 +255,12 @@ jobs: - uses: actions/checkout@v4 - name: "Install nightly Rust toolchain" # Only pinned to make caching work, update freely - run: rustup toolchain install nightly-2023-06-08 + run: rustup toolchain install nightly-2023-10-15 - uses: Swatinem/rust-cache@v2 - name: "Install cargo-udeps" uses: taiki-e/install-action@cargo-udeps - name: "Run cargo-udeps" - run: cargo +nightly-2023-06-08 udeps + run: cargo +nightly-2023-10-15 udeps python-package: name: "python package" @@ -342,6 +367,45 @@ jobs: - name: "Remove checkouts from cache" run: rm -r target/progress_projects + check-ruff-lsp: + name: "test ruff-lsp" + runs-on: ubuntu-latest + needs: cargo-test-linux + steps: + - uses: extractions/setup-just@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/checkout@v4 + name: "Download ruff-lsp source" + with: + repository: "astral-sh/ruff-lsp" + + - uses: actions/setup-python@v4 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - uses: actions/download-artifact@v3 + name: Download development ruff binary + id: ruff-target + with: + name: ruff + path: target/debug + + - name: Install ruff-lsp dependencies + run: | + just install + + - name: Run ruff-lsp tests + run: | + # Setup development binary + pip uninstall --yes ruff + chmod +x ${{ steps.ruff-target.outputs.download-path }}/ruff + export PATH=${{ steps.ruff-target.outputs.download-path }}:$PATH + ruff version + + just test + benchmarks: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index df2973ae48472..e23a8c218db00 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -47,7 +47,7 @@ jobs: run: mkdocs build --strict -f mkdocs.generated.yml - name: "Deploy to Cloudflare Pages" if: ${{ env.CF_API_TOKEN_EXISTS == 'true' }} - uses: cloudflare/wrangler-action@v3.1.1 + uses: cloudflare/wrangler-action@v3.3.1 with: apiToken: ${{ secrets.CF_API_TOKEN }} accountId: ${{ secrets.CF_ACCOUNT_ID }} diff --git a/.github/workflows/playground.yaml b/.github/workflows/playground.yaml index 1442a98f6cb5f..6daf0a89fbcd8 100644 --- a/.github/workflows/playground.yaml +++ b/.github/workflows/playground.yaml @@ -40,8 +40,9 @@ jobs: working-directory: playground - name: "Deploy to Cloudflare Pages" if: ${{ env.CF_API_TOKEN_EXISTS == 'true' }} - uses: cloudflare/wrangler-action@v3.1.1 + uses: cloudflare/wrangler-action@v3.3.1 with: apiToken: ${{ secrets.CF_API_TOKEN }} accountId: ${{ secrets.CF_ACCOUNT_ID }} - command: pages deploy playground/dist --project-name=ruff-playground --branch ${GITHUB_HEAD_REF} --commit-hash ${GITHUB_SHA} + # `github.head_ref` is only set during pull requests and for manual runs or tags we use `main` to deploy to production + command: pages deploy playground/dist --project-name=ruff-playground --branch ${{ github.head_ref || 'main' }} --commit-hash ${GITHUB_SHA} diff --git a/.github/workflows/pr-comment.yaml b/.github/workflows/pr-comment.yaml index a556d5a941d5e..f6ac19dcb0ed8 100644 --- a/.github/workflows/pr-comment.yaml +++ b/.github/workflows/pr-comment.yaml @@ -41,6 +41,7 @@ jobs: workflow: ci.yaml pr: ${{ steps.pr-number.outputs.pr-number }} path: pr/ecosystem + workflow_conclusion: completed if_no_artifact_found: ignore - name: Generate Comment diff --git a/.markdownlint.yaml b/.markdownlint.yaml index 1ae5cc49553f2..637134b0f9373 100644 --- a/.markdownlint.yaml +++ b/.markdownlint.yaml @@ -13,3 +13,8 @@ MD041: false # MD013/line-length MD013: false + +# MD024/no-duplicate-heading +MD024: + # Allow when nested under different parents e.g. CHANGELOG.md + allow_different_nesting: true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5da5eb203726a..f4c0a71f698af 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,6 +23,11 @@ repos: - id: mdformat additional_dependencies: - mdformat-mkdocs + - mdformat-admon + exclude: | + (?x)^( + docs/formatter/black.md + )$ - repo: https://github.com/igorshubovych/markdownlint-cli rev: v0.33.0 diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md index d46f3498ed66d..3fcc2337d1a3c 100644 --- a/BREAKING_CHANGES.md +++ b/BREAKING_CHANGES.md @@ -1,5 +1,35 @@ # Breaking Changes +## 0.1.0 + +### The deprecated `format` setting has been removed + +Ruff previously used the `format` setting, `--format` CLI option, and `RUFF_FORMAT` environment variable to +configure the output format of the CLI. This usage was deprecated in `v0.0.291` — the `format` setting is now used +to control Ruff's code formatting. As of this release: + +- The `format` setting cannot be used to configure the output format, use `output-format` instead +- The `RUFF_FORMAT` environment variable is ignored, use `RUFF_OUTPUT_FORMAT` instead +- The `--format` option has been removed from `ruff check`, use `--output-format` instead + +### Unsafe fixes are not applied by default ([#7769](https://github.com/astral-sh/ruff/pull/7769)) + +Ruff labels fixes as "safe" and "unsafe". The meaning and intent of your code will be retained when applying safe +fixes, but the meaning could be changed when applying unsafe fixes. Previously, unsafe fixes were always displayed +and applied when fixing was enabled. Now, unsafe fixes are hidden by default and not applied. The `--unsafe-fixes` +flag or `unsafe-fixes` configuration option can be used to enable unsafe fixes. + +See the [docs](https://docs.astral.sh/ruff/configuration/#fix-safety) for details. + +### Remove formatter-conflicting rules from the default rule set ([#7900](https://github.com/astral-sh/ruff/pull/7900)) + +Previously, Ruff enabled all implemented rules in Pycodestyle (`E`) by default. Ruff now only includes the +Pycodestyle prefixes `E4`, `E7`, and `E9` to exclude rules that conflict with automatic formatters. Consequently, +the stable rule set no longer includes `line-too-long` (`E501`) and `mixed-spaces-and-tabs` (`E101`). Other +excluded Pycodestyle rules include whitespace enforcement in `E1` and `E2`; these rules are currently in preview, and are already omitted by default. + +This change only affects those using Ruff under its default rule set. Users that include `E` in their `select` will experience no change in behavior. + ## 0.0.288 ### Remove support for emoji identifiers ([#7212](https://github.com/astral-sh/ruff/pull/7212)) diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000000..ee2a8cf4ce3b1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,274 @@ +# Changelog + +## 0.1.3 + +This release includes a variety of improvements to the Ruff formatter, removing several known and +unintentional deviations from Black. + +### Formatter + +- Avoid space around pow for `None`, `True` and `False` ([#8189](https://github.com/astral-sh/ruff/pull/8189)) +- Avoid sorting all paths in the format command ([#8181](https://github.com/astral-sh/ruff/pull/8181)) +- Insert necessary blank line between class and leading comments ([#8224](https://github.com/astral-sh/ruff/pull/8224)) +- Avoid introducing new parentheses in annotated assignments ([#8233](https://github.com/astral-sh/ruff/pull/8233)) +- Refine the warnings about incompatible linter options ([#8196](https://github.com/astral-sh/ruff/pull/8196)) +- Add test and basic implementation for formatter preview mode ([#8044](https://github.com/astral-sh/ruff/pull/8044)) +- Refine warning about incompatible `isort` settings ([#8192](https://github.com/astral-sh/ruff/pull/8192)) +- Only omit optional parentheses for starting or ending with parentheses ([#8238](https://github.com/astral-sh/ruff/pull/8238)) +- Use source type to determine parser mode for formatting ([#8205](https://github.com/astral-sh/ruff/pull/8205)) +- Don't warn about magic trailing comma when `isort.force-single-line` is true ([#8244](https://github.com/astral-sh/ruff/pull/8244)) +- Use `SourceKind::diff` for formatter ([#8240](https://github.com/astral-sh/ruff/pull/8240)) +- Fix `fmt:off` with trailing child comment ([#8234](https://github.com/astral-sh/ruff/pull/8234)) +- Formatter parentheses support for `IpyEscapeCommand` ([#8207](https://github.com/astral-sh/ruff/pull/8207)) + +### Linter + +- \[`pylint`\] Add buffer methods to `bad-dunder-method-name` (`PLW3201`) exclusions ([#8190](https://github.com/astral-sh/ruff/pull/8190)) +- Match rule prefixes from `external` codes setting in `unused-noqa` ([#8177](https://github.com/astral-sh/ruff/pull/8177)) +- Use `line-length` setting for isort in lieu of `pycodestyle.max-line-length` ([#8235](https://github.com/astral-sh/ruff/pull/8235)) +- Update fix for `unnecessary-paren-on-raise-exception` to unsafe for unknown types ([#8231](https://github.com/astral-sh/ruff/pull/8231)) +- Correct quick fix message for `W605` ([#8255](https://github.com/astral-sh/ruff/pull/8255)) + +### Documentation + +- Fix typo in max-doc-length documentation ([#8201](https://github.com/astral-sh/ruff/pull/8201)) +- Improve documentation around linter-formatter conflicts ([#8257](https://github.com/astral-sh/ruff/pull/8257)) +- Fix link to error suppression documentation in `unused-noqa` ([#8172](https://github.com/astral-sh/ruff/pull/8172)) +- Add `external` option to `unused-noqa` documentation ([#8171](https://github.com/astral-sh/ruff/pull/8171)) +- Add title attribute to icons ([#8060](https://github.com/astral-sh/ruff/pull/8060)) +- Clarify unsafe case in RSE102 ([#8256](https://github.com/astral-sh/ruff/pull/8256)) +- Fix skipping formatting examples ([#8210](https://github.com/astral-sh/ruff/pull/8210)) +- docs: fix name of `magic-trailing-comma` option in README ([#8200](https://github.com/astral-sh/ruff/pull/8200)) +- Add note about scope of rule changing in versioning policy ([#8169](https://github.com/astral-sh/ruff/pull/8169)) +- Document: Fix default lint rules ([#8218](https://github.com/astral-sh/ruff/pull/8218)) +- Fix a wrong setting in configuration.md ([#8186](https://github.com/astral-sh/ruff/pull/8186)) +- Fix misspelled TOML headers in the tutorial ([#8209](https://github.com/astral-sh/ruff/pull/8209)) + +## 0.1.2 + +This release includes the Beta version of the Ruff formatter — an extremely fast, Black-compatible Python formatter. +Try it today with `ruff format`! [Check out the blog post](https://astral.sh/blog/the-ruff-formatter) and [read the docs](https://docs.astral.sh/ruff/formatter/). + +### Preview features + +- \[`pylint`\] Implement `non-ascii-module-import` (`C2403`) ([#8056](https://github.com/astral-sh/ruff/pull/8056)) +- \[`pylint`\] implement `non-ascii-name` (`C2401`) ([#8038](https://github.com/astral-sh/ruff/pull/8038)) +- \[`pylint`\] Implement unnecessary-lambda (W0108) ([#7953](https://github.com/astral-sh/ruff/pull/7953)) +- \[`refurb`\] Implement `read-whole-file` (`FURB101`) ([#7682](https://github.com/astral-sh/ruff/pull/7682)) +- Add fix for `E223`, `E224`, and `E242` ([#8143](https://github.com/astral-sh/ruff/pull/8143)) +- Add fix for `E225`, `E226`, `E227`, and `E228` ([#8136](https://github.com/astral-sh/ruff/pull/8136)) +- Add fix for `E252` ([#8142](https://github.com/astral-sh/ruff/pull/8142)) +- Add fix for `E261` ([#8114](https://github.com/astral-sh/ruff/pull/8114)) +- Add fix for `E273` and `E274` ([#8144](https://github.com/astral-sh/ruff/pull/8144)) +- Add fix for `E275` ([#8133](https://github.com/astral-sh/ruff/pull/8133)) +- Update `SIM401` to catch ternary operations ([#7415](https://github.com/astral-sh/ruff/pull/7415)) +- Update `E721` to allow `is` and `is` not for direct type comparisons ([#7905](https://github.com/astral-sh/ruff/pull/7905)) + +### Rule changes + +- Add `backports.strenum` to `deprecated-imports` ([#8113](https://github.com/astral-sh/ruff/pull/8113)) +- Update `SIM112` to ignore `https_proxy`, `http_proxy`, and `no_proxy` ([#8140](https://github.com/astral-sh/ruff/pull/8140)) +- Update fix for `literal-membership` (`PLR6201`) to be unsafe ([#8097](https://github.com/astral-sh/ruff/pull/8097)) +- Update fix for `mutable-argument-defaults` (`B006`) to be unsafe ([#8108](https://github.com/astral-sh/ruff/pull/8108)) + +### Formatter + +- Change `line-ending` default to `auto` ([#8057](https://github.com/astral-sh/ruff/pull/8057)) +- Respect parenthesized generators in `has_own_parentheses` ([#8100](https://github.com/astral-sh/ruff/pull/8100)) +- Add caching to formatter ([#8089](https://github.com/astral-sh/ruff/pull/8089)) +- Remove `--line-length` option from `format` command ([#8131](https://github.com/astral-sh/ruff/pull/8131)) +- Add formatter to `line-length` documentation ([#8150](https://github.com/astral-sh/ruff/pull/8150)) +- Warn about incompatible formatter options ([#8088](https://github.com/astral-sh/ruff/pull/8088)) +- Fix range of unparenthesized tuple subject in match statement ([#8101](https://github.com/astral-sh/ruff/pull/8101)) +- Remove experimental formatter warning ([#8148](https://github.com/astral-sh/ruff/pull/8148)) +- Don't move type param opening parenthesis comment ([#8163](https://github.com/astral-sh/ruff/pull/8163)) +- Update versions in format benchmark script ([#8110](https://github.com/astral-sh/ruff/pull/8110)) +- Avoid loading files for cached format results ([#8134](https://github.com/astral-sh/ruff/pull/8134)) + +### CLI + +- Show the `ruff format` command in help menus ([#8167](https://github.com/astral-sh/ruff/pull/8167)) +- Add `ruff version` command with long version display ([#8034](https://github.com/astral-sh/ruff/pull/8034)) + +### Configuration + +- New `pycodestyle.max-line-length` option ([#8039](https://github.com/astral-sh/ruff/pull/8039)) + +### Bug fixes + +- Detect `sys.version_info` slices in `outdated-version-block` ([#8112](https://github.com/astral-sh/ruff/pull/8112)) +- Avoid if-else simplification for `TYPE_CHECKING` blocks ([#8072](https://github.com/astral-sh/ruff/pull/8072)) +- Avoid false-positive print separator diagnostic with starred argument ([#8079](https://github.com/astral-sh/ruff/pull/8079)) + +### Documentation + +- Fix message for `too-many-arguments` lint ([#8092](https://github.com/astral-sh/ruff/pull/8092)) +- Fix `extend-unsafe-fixes` and `extend-safe-fixes` example ([#8139](https://github.com/astral-sh/ruff/pull/8139)) +- Add links to `flake8-import-conventions` options ([#8115](https://github.com/astral-sh/ruff/pull/8115)) +- Rework the documentation to incorporate the Ruff formatter ([#7732](https://github.com/astral-sh/ruff/pull/7732)) +- Fix `Options` JSON schema description ([#8081](https://github.com/astral-sh/ruff/pull/8081)) +- Fix typo (`pytext` -> `pytest`) ([#8117](https://github.com/astral-sh/ruff/pull/8117)) +- Improve `magic-value-comparison` example in docs ([#8111](https://github.com/astral-sh/ruff/pull/8111)) + +## 0.1.1 + +### Rule changes + +- Add unsafe fix for `escape-sequence-in-docstring` (`D301`) ([#7970](https://github.com/astral-sh/ruff/pull/7970)) + +### Configuration + +- Respect `#(deprecated)` attribute in configuration options ([#8035](https://github.com/astral-sh/ruff/pull/8035)) +- Add `[format|lint].exclude` options ([#8000](https://github.com/astral-sh/ruff/pull/8000)) +- Respect `tab-size` setting in formatter ([#8006](https://github.com/astral-sh/ruff/pull/8006)) +- Add `lint.preview` ([#8002](https://github.com/astral-sh/ruff/pull/8002)) + +### Preview features + +- \[`pylint`\] Implement `literal-membership` (`PLR6201`) ([#7973](https://github.com/astral-sh/ruff/pull/7973)) +- \[`pylint`\] Implement `too-many-boolean-expressions` (`PLR0916`) ([#7975](https://github.com/astral-sh/ruff/pull/7975)) +- \[`pylint`\] Implement `misplaced-bare-raise` (`E0704`) ([#7961](https://github.com/astral-sh/ruff/pull/7961)) +- \[`pylint`\] Implement `global-at-module-level` (`W0604`) ([#8058](https://github.com/astral-sh/ruff/pull/8058)) +- \[`pylint`\] Implement `unspecified-encoding` (`PLW1514`) ([#7939](https://github.com/astral-sh/ruff/pull/7939)) +- Add fix for `triple-single-quotes` (`D300`) ([#7967](https://github.com/astral-sh/ruff/pull/7967)) + +### Formatter + +- New code style badge for `ruff format` ([#7878](https://github.com/astral-sh/ruff/pull/7878)) +- Fix comments outside expression parentheses ([#7873](https://github.com/astral-sh/ruff/pull/7873)) +- Add `--target-version` to `ruff format` ([#8055](https://github.com/astral-sh/ruff/pull/8055)) +- Skip over parentheses when detecting `in` keyword ([#8054](https://github.com/astral-sh/ruff/pull/8054)) +- Add `--diff` option to `ruff format` ([#7937](https://github.com/astral-sh/ruff/pull/7937)) +- Insert newline after nested function or class statements ([#7946](https://github.com/astral-sh/ruff/pull/7946)) +- Use `pass` over ellipsis in non-function/class contexts ([#8049](https://github.com/astral-sh/ruff/pull/8049)) + +### Bug fixes + +- Lazily evaluate all PEP 695 type alias values ([#8033](https://github.com/astral-sh/ruff/pull/8033)) +- Avoid failed assertion when showing fixes from stdin ([#8029](https://github.com/astral-sh/ruff/pull/8029)) +- Avoid flagging HTTP and HTTPS literals in urllib-open ([#8046](https://github.com/astral-sh/ruff/pull/8046)) +- Avoid flagging `bad-dunder-method-name` for `_` ([#8015](https://github.com/astral-sh/ruff/pull/8015)) +- Remove Python 2-only methods from `URLOpen` audit ([#8047](https://github.com/astral-sh/ruff/pull/8047)) +- Use set bracket replacement for `iteration-over-set` to preserve whitespace and comments ([#8001](https://github.com/astral-sh/ruff/pull/8001)) + +### Documentation + +- Update tutorial to match revised Ruff defaults ([#8066](https://github.com/astral-sh/ruff/pull/8066)) +- Update rule `B005` docs ([#8028](https://github.com/astral-sh/ruff/pull/8028)) +- Update GitHub actions example in docs to use `--output-format` ([#8014](https://github.com/astral-sh/ruff/pull/8014)) +- Document `lint.preview` and `format.preview` ([#8032](https://github.com/astral-sh/ruff/pull/8032)) +- Clarify that new rules should be added to `RuleGroup::Preview`. ([#7989](https://github.com/astral-sh/ruff/pull/7989)) + +## 0.1.0 + +This is the first release which uses the `CHANGELOG` file. See [GitHub Releases](https://github.com/astral-sh/ruff/releases) for prior changelog entries. + +Read Ruff's new [versioning policy](https://docs.astral.sh/ruff/versioning/). + +### Breaking changes + +- Unsafe fixes are no longer displayed or applied without opt-in ([#7769](https://github.com/astral-sh/ruff/pull/7769)) +- Drop formatting specific rules from the default set ([#7900](https://github.com/astral-sh/ruff/pull/7900)) +- The deprecated `format` setting has been removed ([#7984](https://github.com/astral-sh/ruff/pull/7984)) + - The `format` setting cannot be used to configure the output format, use `output-format` instead + - The `RUFF_FORMAT` environment variable is ignored, use `RUFF_OUTPUT_FORMAT` instead + - The `--format` option has been removed from `ruff check`, use `--output-format` instead + +### Rule changes + +- Extend `reimplemented-starmap` (`FURB140`) to catch calls with a single and starred argument ([#7768](https://github.com/astral-sh/ruff/pull/7768)) +- Improve cases covered by `RUF015` ([#7848](https://github.com/astral-sh/ruff/pull/7848)) +- Update `SIM15` to allow `open` followed by `close` ([#7916](https://github.com/astral-sh/ruff/pull/7916)) +- Respect `msgspec.Struct` default-copy semantics in `RUF012` ([#7786](https://github.com/astral-sh/ruff/pull/7786)) +- Add `sqlalchemy` methods to \`flake8-boolean-trap\`\` exclusion list ([#7874](https://github.com/astral-sh/ruff/pull/7874)) +- Add fix for `PLR1714` ([#7910](https://github.com/astral-sh/ruff/pull/7910)) +- Add fix for `PIE804` ([#7884](https://github.com/astral-sh/ruff/pull/7884)) +- Add fix for `PLC0208` ([#7887](https://github.com/astral-sh/ruff/pull/7887)) +- Add fix for `PYI055` ([#7886](https://github.com/astral-sh/ruff/pull/7886)) +- Update `non-pep695-type-alias` to require `--unsafe-fixes` outside of stub files ([#7836](https://github.com/astral-sh/ruff/pull/7836)) +- Improve fix message for `UP018` ([#7913](https://github.com/astral-sh/ruff/pull/7913)) +- Update `PLW3201` to support `Enum` [sunder names](https://docs.python.org/3/library/enum.html#supported-sunder-names) ([#7987](https://github.com/astral-sh/ruff/pull/7987)) + +### Preview features + +- Only show warnings for empty preview selectors when enabling rules ([#7842](https://github.com/astral-sh/ruff/pull/7842)) +- Add `unnecessary-key-check` to simplify `key in dct and dct[key]` to `dct.get(key)` ([#7895](https://github.com/astral-sh/ruff/pull/7895)) +- Add `assignment-in-assert` to prevent walrus expressions in assert statements ([#7856](https://github.com/astral-sh/ruff/pull/7856)) +- \[`refurb`\] Add `single-item-membership-test` (`FURB171`) ([#7815](https://github.com/astral-sh/ruff/pull/7815)) +- \[`pylint`\] Add `and-or-ternary` (`R1706`) ([#7811](https://github.com/astral-sh/ruff/pull/7811)) + +_New rules are added in [preview](https://docs.astral.sh/ruff/preview/)._ + +### Configuration + +- Add `unsafe-fixes` setting ([#7769](https://github.com/astral-sh/ruff/pull/7769)) +- Add `extend-safe-fixes` and `extend-unsafe-fixes` for promoting and demoting fixes ([#7841](https://github.com/astral-sh/ruff/pull/7841)) + +### CLI + +- Added `--unsafe-fixes` option for opt-in to display and apply unsafe fixes ([#7769](https://github.com/astral-sh/ruff/pull/7769)) +- Fix use of deprecated `--format` option in warning ([#7837](https://github.com/astral-sh/ruff/pull/7837)) +- Show changed files when running under `--check` ([#7788](https://github.com/astral-sh/ruff/pull/7788)) +- Write summary messages to stderr when fixing via stdin instead of omitting them ([#7838](https://github.com/astral-sh/ruff/pull/7838)) +- Update fix summary message in `check --diff` to include unsafe fix hints ([#7790](https://github.com/astral-sh/ruff/pull/7790)) +- Add notebook `cell` field to JSON output format ([#7664](https://github.com/astral-sh/ruff/pull/7664)) +- Rename applicability levels to `Safe`, `Unsafe`, and `Display` ([#7843](https://github.com/astral-sh/ruff/pull/7843)) + +### Bug fixes + +- Fix bug where f-strings were allowed in match pattern literal ([#7857](https://github.com/astral-sh/ruff/pull/7857)) +- Fix `SIM110` with a yield in the condition ([#7801](https://github.com/astral-sh/ruff/pull/7801)) +- Preserve trailing comments in `C414` fixes ([#7775](https://github.com/astral-sh/ruff/pull/7775)) +- Check sequence type before triggering `unnecessary-enumerate` `len` suggestion ([#7781](https://github.com/astral-sh/ruff/pull/7781)) +- Use correct start location for class/function clause header ([#7802](https://github.com/astral-sh/ruff/pull/7802)) +- Fix incorrect fixes for `SIM101` ([#7798](https://github.com/astral-sh/ruff/pull/7798)) +- Format comment before parameter default correctly ([#7870](https://github.com/astral-sh/ruff/pull/7870)) +- Fix `E251` false positive inside f-strings ([#7894](https://github.com/astral-sh/ruff/pull/7894)) +- Allow bindings to be created and referenced within annotations ([#7885](https://github.com/astral-sh/ruff/pull/7885)) +- Show per-cell diffs when analyzing notebooks over `stdin` ([#7789](https://github.com/astral-sh/ruff/pull/7789)) +- Avoid curly brace escape in f-string format spec ([#7780](https://github.com/astral-sh/ruff/pull/7780)) +- Fix lexing single-quoted f-string with multi-line format spec ([#7787](https://github.com/astral-sh/ruff/pull/7787)) +- Consider nursery rules to be in-preview for `ruff rule` ([#7812](https://github.com/astral-sh/ruff/pull/7812)) +- Report precise location for invalid conversion flag ([#7809](https://github.com/astral-sh/ruff/pull/7809)) +- Visit pattern match guard as a boolean test ([#7911](https://github.com/astral-sh/ruff/pull/7911)) +- Respect `--unfixable` in `ISC` rules ([#7917](https://github.com/astral-sh/ruff/pull/7917)) +- Fix edge case with `PIE804` ([#7922](https://github.com/astral-sh/ruff/pull/7922)) +- Show custom message in `PTH118` for `Path.joinpath` with starred arguments ([#7852](https://github.com/astral-sh/ruff/pull/7852)) +- Fix false negative in `outdated-version-block` when using greater than comparisons ([#7920](https://github.com/astral-sh/ruff/pull/7920)) +- Avoid converting f-strings within Django `gettext` calls ([#7898](https://github.com/astral-sh/ruff/pull/7898)) +- Fix false positive in `PLR6301` ([#7933](https://github.com/astral-sh/ruff/pull/7933)) +- Treat type aliases as typing-only expressions e.g. resolves false positive in `TCH004` ([#7968](https://github.com/astral-sh/ruff/pull/7968)) +- Resolve `cache-dir` relative to project root ([#7962](https://github.com/astral-sh/ruff/pull/7962)) +- Respect subscripted base classes in type-checking rules e.g. resolves false positive in `TCH003` ([#7954](https://github.com/astral-sh/ruff/pull/7954)) +- Fix JSON schema limit for `line-length` ([#7883](https://github.com/astral-sh/ruff/pull/7883)) +- Fix commented-out `coalesce` keyword ([#7876](https://github.com/astral-sh/ruff/pull/7876)) + +### Documentation + +- Document `reimplemented-starmap` performance effects ([#7846](https://github.com/astral-sh/ruff/pull/7846)) +- Default to following the system dark/light mode ([#7888](https://github.com/astral-sh/ruff/pull/7888)) +- Add documentation for fixes ([#7901](https://github.com/astral-sh/ruff/pull/7901)) +- Fix typo in docs of `PLR6301` ([#7831](https://github.com/astral-sh/ruff/pull/7831)) +- Update `UP038` docs to note that it results in slower code ([#7872](https://github.com/astral-sh/ruff/pull/7872)) +- crlf -> cr-lf ([#7766](https://github.com/astral-sh/ruff/pull/7766)) +- Add an example of an unsafe fix ([#7924](https://github.com/astral-sh/ruff/pull/7924)) +- Fix documented examples for `unnecessary-subscript-reversal` ([#7774](https://github.com/astral-sh/ruff/pull/7774)) +- Correct error in tuple example in ruff formatter docs ([#7822](https://github.com/astral-sh/ruff/pull/7822)) +- Add versioning policy to documentation ([#7923](https://github.com/astral-sh/ruff/pull/7923)) +- Fix invalid code in `FURB177` example ([#7832](https://github.com/astral-sh/ruff/pull/7832)) + +### Formatter + +- Less scary `ruff format` message ([#7867](https://github.com/astral-sh/ruff/pull/7867)) +- Remove spaces from import statements ([#7859](https://github.com/astral-sh/ruff/pull/7859)) +- Formatter quoting for f-strings with triple quotes ([#7826](https://github.com/astral-sh/ruff/pull/7826)) +- Update `ruff_python_formatter` generate.py comment ([#7850](https://github.com/astral-sh/ruff/pull/7850)) +- Document one-call chaining deviation ([#7767](https://github.com/astral-sh/ruff/pull/7767)) +- Allow f-string modifications in line-shrinking cases ([#7818](https://github.com/astral-sh/ruff/pull/7818)) +- Add trailing comment deviation to README ([#7827](https://github.com/astral-sh/ruff/pull/7827)) +- Add trailing zero between dot and exponential ([#7956](https://github.com/astral-sh/ruff/pull/7956)) +- Force parentheses for power operations in unary expressions ([#7955](https://github.com/astral-sh/ruff/pull/7955)) + +### Playground + +- Fix playground `Quick Fix` action ([#7824](https://github.com/astral-sh/ruff/pull/7824)) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cf239242294f1..35562266b948c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -170,7 +170,8 @@ At a high level, the steps involved in adding a new lint rule are as follows: statements, like imports) or `analyze/expression.rs` (if your rule is based on analyzing expressions, like function calls). -1. Map the violation struct to a rule code in `crates/ruff_linter/src/codes.rs` (e.g., `B011`). +1. Map the violation struct to a rule code in `crates/ruff_linter/src/codes.rs` (e.g., `B011`). New rules + should be added in `RuleGroup::Preview`. 1. Add proper [testing](#rule-testing-fixtures-and-snapshots) for your rule. @@ -204,7 +205,7 @@ As such, rule names should... For example, `AssertFalse` guards against `assert False` statements. - _Not_ contain instructions on how to fix the violation, which instead belong in the rule - documentation and the `autofix_title`. + documentation and the `fix_title`. - _Not_ contain a redundant prefix, like `Disallow` or `Banned`, which are already implied by the convention. diff --git a/Cargo.lock b/Cargo.lock index d00e468feeefb..18699b6ddeabf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.5" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] @@ -74,9 +74,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.5.0" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" dependencies = [ "anstyle", "anstyle-parse", @@ -112,9 +112,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "2.1.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -221,7 +221,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a" dependencies = [ "memchr", - "regex-automata 0.3.8", + "regex-automata 0.3.9", "serde", ] @@ -313,9 +313,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.4" +version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" +checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" dependencies = [ "clap_builder", "clap_derive", @@ -323,9 +323,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.4" +version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" +checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" dependencies = [ "anstream", "anstyle", @@ -383,7 +383,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -407,9 +407,9 @@ dependencies = [ [[package]] name = "codspeed" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3238416c10f19985b52a937c5b3efc3ed7efe8f7ae263d2aab29a09bca9f57" +checksum = "d680ccd1eedd2dd7c7a3649a78c7d06e0f16b191b30d81cc58e7bc906488d344" dependencies = [ "colored", "libc", @@ -418,9 +418,9 @@ dependencies = [ [[package]] name = "codspeed-criterion-compat" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecc18f65b942d2b033545bb3bd8430a23eecbbe53fad3b1342fb0e5514bca7b" +checksum = "58b48b6c8e890d7d4ad0ed85e9ab4949bf7023198c006000ef6338ba84cf5b71" dependencies = [ "codspeed", "colored", @@ -608,7 +608,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -619,7 +619,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -810,7 +810,7 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flake8-to-ruff" -version = "0.0.291" +version = "0.1.3" dependencies = [ "anyhow", "clap", @@ -872,6 +872,15 @@ dependencies = [ "libc", ] +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + [[package]] name = "getrandom" version = "0.2.10" @@ -1075,9 +1084,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.32.0" +version = "1.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e02c584f4595792d09509a94cdb92a3cef7592b1eb2d9877ee6f527062d0ea" +checksum = "5d64600be34b2fcfc267740a243fa7744441bb4947a619ac4e5bb6507f35fbfc" dependencies = [ "console", "globset", @@ -1120,7 +1129,7 @@ dependencies = [ "pmutil 0.6.1", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -1259,9 +1268,9 @@ checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libcst" -version = "0.1.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7773d520d4292e200ab1838f2daabe2feed7549f93b0a3c7582160a09e79ffde" +checksum = "bd5c2ff400caac657bf794181d885491bb97cc37c376f8cb4fa3a0cc2176a053" dependencies = [ "chic", "libcst_derive", @@ -1274,9 +1283,9 @@ dependencies = [ [[package]] name = "libcst_derive" -version = "0.1.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520197c50ba477f258cd7005ec5ed3a7393693ae6bec664990c7c8d9306a7c0d" +checksum = "6d7f252282b20bfec6fae65d351ab1df7e4552a6270dd7bb779ca9d6135aabe9" dependencies = [ "quote", "syn 1.0.109", @@ -1337,9 +1346,9 @@ checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "memchr" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memoffset" @@ -1454,27 +1463,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "num-bigint" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.16" @@ -1605,9 +1593,9 @@ checksum = "9fa00462b37ead6d11a82c9d568b26682d78e0477dc02d1966c013af80969739" [[package]] name = "pep440_rs" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05bf2c44c4cd12f03b2c3ca095f3aa21f44e43c16021c332e511884719705be" +checksum = "887f66cc62717ea72caac4f1eb4e6f392224da3ffff3f40ec13ab427802746d6" dependencies = [ "lazy_static", "regex", @@ -1719,7 +1707,7 @@ checksum = "52a40bc70c2c58040d2d8b167ba9a5ff59fc9dab7ad44771cfde3dcfde7a09c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -1804,9 +1792,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -1937,14 +1925,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.5" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.8", - "regex-syntax 0.7.5", + "regex-automata 0.4.3", + "regex-syntax 0.8.2", ] [[package]] @@ -1958,13 +1946,19 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.8" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" + +[[package]] +name = "regex-automata" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.5", + "regex-syntax 0.8.2", ] [[package]] @@ -1979,6 +1973,12 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + [[package]] name = "result-like" version = "0.4.6" @@ -2051,7 +2051,7 @@ dependencies = [ [[package]] name = "ruff_cli" -version = "0.0.291" +version = "0.1.3" dependencies = [ "annotate-snippets 0.9.1", "anyhow", @@ -2155,6 +2155,7 @@ name = "ruff_diagnostics" version = "0.0.0" dependencies = [ "anyhow", + "is-macro", "log", "ruff_text_size", "serde", @@ -2187,8 +2188,9 @@ dependencies = [ [[package]] name = "ruff_linter" -version = "0.0.291" +version = "0.1.3" dependencies = [ + "aho-corasick", "annotate-snippets 0.9.1", "anyhow", "bitflags 2.4.0", @@ -2206,8 +2208,6 @@ dependencies = [ "log", "memchr", "natord", - "num-bigint", - "num-traits", "once_cell", "path-absolutize", "pathdiff", @@ -2259,7 +2259,7 @@ dependencies = [ "proc-macro2", "quote", "ruff_python_trivia", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -2290,8 +2290,6 @@ dependencies = [ "is-macro", "itertools 0.11.0", "memchr", - "num-bigint", - "num-traits", "once_cell", "ruff_python_parser", "ruff_python_trivia", @@ -2368,7 +2366,6 @@ dependencies = [ "is-macro", "itertools 0.11.0", "lexical-parse-float", - "num-traits", "rand", "unic-ucd-category", ] @@ -2378,13 +2375,13 @@ name = "ruff_python_parser" version = "0.0.0" dependencies = [ "anyhow", + "bitflags 2.4.0", "insta", "is-macro", "itertools 0.11.0", "lalrpop", "lalrpop-util", - "num-bigint", - "num-traits", + "memchr", "ruff_python_ast", "ruff_text_size", "rustc-hash", @@ -2410,7 +2407,6 @@ version = "0.0.0" dependencies = [ "bitflags 2.4.0", "is-macro", - "num-traits", "ruff_index", "ruff_python_ast", "ruff_python_parser", @@ -2443,7 +2439,7 @@ dependencies = [ [[package]] name = "ruff_shrinking" -version = "0.1.0" +version = "0.1.3" dependencies = [ "anyhow", "clap", @@ -2514,6 +2510,7 @@ dependencies = [ "glob", "globset", "ignore", + "is-macro", "itertools 0.11.0", "log", "once_cell", @@ -2573,20 +2570,10 @@ checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", "ring", - "rustls-webpki 0.101.4", + "rustls-webpki", "sct", ] -[[package]] -name = "rustls-webpki" -version = "0.100.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e98ff011474fa39949b7e5c0428f9b4937eda7da7848bbb947786b7be0b27dab" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "rustls-webpki" version = "0.101.4" @@ -2672,9 +2659,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "semver" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" @@ -2704,7 +2691,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -2749,9 +2736,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca3b16a3d82c4088f343b7480a93550b3eabe1a358569c2dfe38bbcead07237" +checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" dependencies = [ "serde", "serde_with_macros", @@ -2759,14 +2746,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e6be15c453eb305019bfa438b1593c731f36a289a7853f7707ee29e870b3b3c" +checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -2795,9 +2782,9 @@ checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" [[package]] name = "similar" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf" +checksum = "2aeaf503862c419d66959f5d7ca015337d864e9c49485d771b732e2a20453597" [[package]] name = "siphasher" @@ -2853,15 +2840,15 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.25.2" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" dependencies = [ "heck", "proc-macro2", "quote", "rustversion", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -2877,9 +2864,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.37" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", @@ -2966,7 +2953,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -2978,28 +2965,28 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", "test-case-core", ] [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -3032,6 +3019,22 @@ dependencies = [ "tikv-jemalloc-sys", ] +[[package]] +name = "time" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +dependencies = [ + "serde", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -3102,11 +3105,10 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "log", "pin-project-lite", "tracing-attributes", @@ -3115,20 +3117,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", "valuable", @@ -3258,10 +3260,25 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "unicode_names2" -version = "0.6.0" -source = "git+https://github.com/youknowone/unicode_names2.git?rev=4ce16aa85cbcdd9cc830410f1a72ef9a235f2fde#4ce16aa85cbcdd9cc830410f1a72ef9a235f2fde" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5506ae2c3c1ccbdf468e52fc5ef536c2ccd981f01273a4cb81aa61021f3a5f" dependencies = [ "phf", + "unicode_names2_generator", +] + +[[package]] +name = "unicode_names2_generator" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6dfc680313e95bc6637fa278cd7a22390c3c2cd7b8b2bd28755bc6c0fc811e7" +dependencies = [ + "getopts", + "log", + "phf_codegen", + "rand", + "time", ] [[package]] @@ -3272,16 +3289,16 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "ureq" -version = "2.7.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b11c96ac7ee530603dcdf68ed1557050f374ce55a5a07193ebf8cbc9f8927e9" +checksum = "f5ccd538d4a604753ebc2f17cd9946e89b77bf87f6a8e2309667c6f2e87855e3" dependencies = [ "base64", "flate2", "log", "once_cell", "rustls", - "rustls-webpki 0.100.2", + "rustls-webpki", "url", "webpki-roots", ] @@ -3324,7 +3341,7 @@ checksum = "f7e1ba1f333bd65ce3c9f27de592fcbc256dafe3af2717f56d7c87761fbaccf4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -3418,7 +3435,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", "wasm-bindgen-shared", ] @@ -3452,7 +3469,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3499,12 +3516,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.23.1" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" -dependencies = [ - "rustls-webpki 0.100.2", -] +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "which" diff --git a/Cargo.toml b/Cargo.toml index 89113963db7fd..80630fc0452f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,49 +15,46 @@ license = "MIT" anyhow = { version = "1.0.69" } bitflags = { version = "2.3.1" } chrono = { version = "0.4.31", default-features = false, features = ["clock"] } -clap = { version = "4.4.4", features = ["derive"] } +clap = { version = "4.4.6", features = ["derive"] } colored = { version = "2.0.0" } filetime = { version = "0.2.20" } glob = { version = "0.3.1" } globset = { version = "0.4.10" } ignore = { version = "0.4.20" } -insta = { version = "1.32.0", feature = ["filters", "glob"] } +insta = { version = "1.34.0", feature = ["filters", "glob"] } is-macro = { version = "0.3.0" } itertools = { version = "0.11.0" } +libcst = { version = "1.1.0", default-features = false } log = { version = "0.4.17" } -memchr = "2.6.3" -num-bigint = { version = "0.4.3" } -num-traits = { version = "0.2.15" } +memchr = { version = "2.6.4" } once_cell = { version = "1.17.1" } path-absolutize = { version = "3.1.1" } -proc-macro2 = { version = "1.0.67" } +proc-macro2 = { version = "1.0.69" } quote = { version = "1.0.23" } -regex = { version = "1.9.5" } +regex = { version = "1.10.2" } rustc-hash = { version = "1.1.0" } schemars = { version = "0.8.15" } serde = { version = "1.0.152", features = ["derive"] } serde_json = { version = "1.0.107" } shellexpand = { version = "3.0.0" } -similar = { version = "2.2.1", features = ["inline"] } +similar = { version = "2.3.0", features = ["inline"] } smallvec = { version = "1.11.1" } static_assertions = "1.1.0" strum = { version = "0.25.0", features = ["strum_macros"] } -strum_macros = { version = "0.25.2" } -syn = { version = "2.0.37" } +strum_macros = { version = "0.25.3" } +syn = { version = "2.0.38" } test-case = { version = "3.2.1" } -thiserror = { version = "1.0.48" } +thiserror = { version = "1.0.50" } toml = { version = "0.7.8" } -tracing = "0.1.37" -tracing-indicatif = "0.3.4" +tracing = { version = "0.1.40" } +tracing-indicatif = { version = "0.3.4" } tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } -unicode-ident = "1.0.12" -unicode-width = "0.1.11" +unicode-ident = { version = "1.0.12" } +unicode_names2 = { version = "1.2.0" } +unicode-width = { version = "0.1.11" } uuid = { version = "1.4.1", features = ["v4", "fast-rng", "macro-diagnostics", "js"] } wsl = { version = "0.1.0" } -# v1.0.1 -libcst = { version = "0.1.0", default-features = false } - [profile.release] lto = "fat" codegen-units = 1 diff --git a/README.md b/README.md index 19f4ab17f27f3..0ddd1da460cc3 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ [**Discord**](https://discord.gg/c9MhzV8aU5) | [**Docs**](https://docs.astral.sh/ruff/) | [**Playground**](https://play.ruff.rs/) -An extremely fast Python linter, written in Rust. +An extremely fast Python linter and code formatter, written in Rust.

@@ -24,16 +24,15 @@ An extremely fast Python linter, written in Rust. Linting the CPython codebase from scratch.

-- ⚡️ 10-100x faster than existing linters +- ⚡️ 10-100x faster than existing linters (like Flake8) and formatters (like Black) - 🐍 Installable via `pip` - 🛠️ `pyproject.toml` support -- 🤝 Python 3.11 compatibility +- 🤝 Python 3.12 compatibility +- ⚖️ Drop-in parity with [Flake8](https://docs.astral.sh/ruff/faq/#how-does-ruff-compare-to-flake8), isort, and Black - 📦 Built-in caching, to avoid re-analyzing unchanged files -- 🔧 Autofix support, for automatic error correction (e.g., automatically remove unused imports) -- 📏 Over [700 built-in rules](https://docs.astral.sh/ruff/rules/) -- ⚖️ [Near-parity](https://docs.astral.sh/ruff/faq/#how-does-ruff-compare-to-flake8) with the - built-in Flake8 rule set -- 🔌 Native re-implementations of dozens of Flake8 plugins, like flake8-bugbear +- 🔧 Fix support, for automatic error correction (e.g., automatically remove unused imports) +- 📏 Over [700 built-in rules](https://docs.astral.sh/ruff/rules/), with native re-implementations + of popular Flake8 plugins, like flake8-bugbear - ⌨️ First-party [editor integrations](https://docs.astral.sh/ruff/editor-integrations/) for [VS Code](https://github.com/astral-sh/ruff-vscode) and [more](https://github.com/astral-sh/ruff-lsp) - 🌎 Monorepo-friendly, with [hierarchical and cascading configuration](https://docs.astral.sh/ruff/configuration/#pyprojecttoml-discovery) @@ -42,10 +41,10 @@ Ruff aims to be orders of magnitude faster than alternative tools while integrat functionality behind a single, common interface. Ruff can be used to replace [Flake8](https://pypi.org/project/flake8/) (plus dozens of plugins), -[isort](https://pypi.org/project/isort/), [pydocstyle](https://pypi.org/project/pydocstyle/), -[yesqa](https://github.com/asottile/yesqa), [eradicate](https://pypi.org/project/eradicate/), -[pyupgrade](https://pypi.org/project/pyupgrade/), and [autoflake](https://pypi.org/project/autoflake/), -all while executing tens or hundreds of times faster than any individual tool. +[Black](https://github.com/psf/black), [isort](https://pypi.org/project/isort/), +[pydocstyle](https://pypi.org/project/pydocstyle/), [pyupgrade](https://pypi.org/project/pyupgrade/), +[autoflake](https://pypi.org/project/autoflake/), and more, all while executing tens or hundreds of +times faster than any individual tool. Ruff is extremely actively developed and used in major open-source projects like: @@ -126,23 +125,38 @@ and with [a variety of other package managers](https://docs.astral.sh/ruff/insta ### Usage -To run Ruff, try any of the following: +To run Ruff as a linter, try any of the following: ```shell -ruff check . # Lint all files in the current directory (and any subdirectories) -ruff check path/to/code/ # Lint all files in `/path/to/code` (and any subdirectories) -ruff check path/to/code/*.py # Lint all `.py` files in `/path/to/code` -ruff check path/to/code/to/file.py # Lint `file.py` +ruff check . # Lint all files in the current directory (and any subdirectories). +ruff check path/to/code/ # Lint all files in `/path/to/code` (and any subdirectories). +ruff check path/to/code/*.py # Lint all `.py` files in `/path/to/code`. +ruff check path/to/code/to/file.py # Lint `file.py`. +ruff check @arguments.txt # Lint using an input file, treating its contents as newline-delimited command-line arguments. ``` -Ruff can also be used as a [pre-commit](https://pre-commit.com) hook: +Or, to run Ruff as a formatter: + +```shell +ruff format . # Format all files in the current directory (and any subdirectories). +ruff format path/to/code/ # Format all files in `/path/to/code` (and any subdirectories). +ruff format path/to/code/*.py # Format all `.py` files in `/path/to/code`. +ruff format path/to/code/to/file.py # Format `file.py`. +ruff format @arguments.txt # Format using an input file, treating its contents as newline-delimited command-line arguments. +``` + +Ruff can also be used as a [pre-commit](https://pre-commit.com/) hook via [`ruff-pre-commit`](https://github.com/astral-sh/ruff-pre-commit): ```yaml +# Run the Ruff linter. - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.0.291 + rev: v0.1.3 hooks: + # Run the Ruff linter. - id: ruff + # Run the Ruff formatter. + - id: ruff-format ``` Ruff can also be used as a [VS Code extension](https://github.com/astral-sh/ruff-vscode) or @@ -168,18 +182,10 @@ Ruff can be configured through a `pyproject.toml`, `ruff.toml`, or `.ruff.toml` [_Configuration_](https://docs.astral.sh/ruff/configuration/), or [_Settings_](https://docs.astral.sh/ruff/settings/) for a complete list of all configuration options). -If left unspecified, the default configuration is equivalent to: +If left unspecified, Ruff's default configuration is equivalent to: ```toml [tool.ruff] -# Enable pycodestyle (`E`) and Pyflakes (`F`) codes by default. -select = ["E", "F"] -ignore = [] - -# Allow autofix for all enabled rules (when `--fix`) is provided. -fixable = ["A", "B", "C", "D", "E", "F", "G", "I", "N", "Q", "S", "T", "W", "ANN", "ARG", "BLE", "COM", "DJ", "DTZ", "EM", "ERA", "EXE", "FBT", "ICN", "INP", "ISC", "NPY", "PD", "PGH", "PIE", "PL", "PT", "PTH", "PYI", "RET", "RSE", "RUF", "SIM", "SLF", "TCH", "TID", "TRY", "UP", "YTT"] -unfixable = [] - # Exclude a variety of commonly ignored directories. exclude = [ ".bzr", @@ -207,27 +213,46 @@ exclude = [ # Same as Black. line-length = 88 +indent-width = 4 + +# Assume Python 3.8 +target-version = "py38" + +[tool.ruff.lint] +# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. +select = ["E4", "E7", "E9", "F"] +ignore = [] + +# Allow fix for all enabled rules (when `--fix`) is provided. +fixable = ["ALL"] +unfixable = [] # Allow unused variables when underscore-prefixed. dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" -# Assume Python 3.8 -target-version = "py38" +[tool.ruff.format] +# Like Black, use double quotes for strings. +quote-style = "double" + +# Like Black, indent with spaces, rather than tabs. +indent-style = "space" + +# Like Black, respect magic trailing commas. +skip-magic-trailing-comma = false -[tool.ruff.mccabe] -# Unlike Flake8, default to a complexity level of 10. -max-complexity = 10 +# Like Black, automatically detect the appropriate line ending. +line-ending = "auto" ``` Some configuration options can be provided via the command-line, such as those related to -rule enablement and disablement, file discovery, logging level, and more: +rule enablement and disablement, file discovery, and logging level: ```shell ruff check path/to/code/ --select F401 --select F403 --quiet ``` -See `ruff help` for more on Ruff's top-level commands, or `ruff help check` for more on the -linting command. +See `ruff help` for more on Ruff's top-level commands, or `ruff help check` and `ruff help format` +for more on the linting and formatting commands, respectively. ## Rules @@ -237,9 +262,8 @@ linting command. isort, pyupgrade, and others. Regardless of the rule's origin, Ruff re-implements every rule in Rust as a first-party feature. -By default, Ruff enables Flake8's `E` and `F` rules. Ruff supports all rules from the `F` category, -and a [subset](https://docs.astral.sh/ruff/rules/#error-e) of the `E` category, omitting those -stylistic rules made obsolete by the use of an autoformatter, like +By default, Ruff enables Flake8's `F` rules, along with a subset of the `E` rules, omitting any +stylistic rules that overlap with the use of a formatter, like `ruff format` or [Black](https://github.com/psf/black). If you're just getting started with Ruff, **the default rule set is a great place to start**: it @@ -331,7 +355,7 @@ In some cases, Ruff includes a "direct" Rust port of the corresponding tool. We're grateful to the maintainers of these tools for their work, and for all the value they've provided to the Python community. -Ruff's autoformatter is built on a fork of Rome's [`rome_formatter`](https://github.com/rome/tools/tree/main/crates/rome_formatter), +Ruff's formatter is built on a fork of Rome's [`rome_formatter`](https://github.com/rome/tools/tree/main/crates/rome_formatter), and again draws on both API and implementation details from [Rome](https://github.com/rome/tools), [Prettier](https://github.com/prettier/prettier), and [Black](https://github.com/psf/black). @@ -385,6 +409,7 @@ Ruff is used by a number of major open-source projects and companies, including: - [Mypy](https://github.com/python/mypy) - Netflix ([Dispatch](https://github.com/Netflix/dispatch)) - [Neon](https://github.com/neondatabase/neon) +- [NoneBot](https://github.com/nonebot/nonebot2) - [ONNX](https://github.com/onnx/onnx) - [OpenBB](https://github.com/OpenBB-finance/OpenBBTerminal) - [PDM](https://github.com/pdm-project/pdm) diff --git a/assets/badge/format.json b/assets/badge/format.json new file mode 100644 index 0000000000000..cd9f73cbdb999 --- /dev/null +++ b/assets/badge/format.json @@ -0,0 +1,8 @@ +{ + "label": "code style", + "message": "Ruff", + "logoSvg": "", + "logoWidth": 10, + "labelColor": "grey", + "color": "#261230" +} diff --git a/crates/flake8_to_ruff/Cargo.toml b/crates/flake8_to_ruff/Cargo.toml index df18c510185a8..2d9ba8551c754 100644 --- a/crates/flake8_to_ruff/Cargo.toml +++ b/crates/flake8_to_ruff/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "flake8-to-ruff" -version = "0.0.291" +version = "0.1.3" description = """ Convert Flake8 configuration files to Ruff configuration files. """ @@ -23,7 +23,7 @@ configparser = { version = "3.0.2" } itertools = { workspace = true } log = { workspace = true } once_cell = { workspace = true } -pep440_rs = { version = "0.3.1", features = ["serde"] } +pep440_rs = { version = "0.3.12", features = ["serde"] } regex = { workspace = true } rustc-hash = { workspace = true } serde = { workspace = true } diff --git a/crates/flake8_to_ruff/src/converter.rs b/crates/flake8_to_ruff/src/converter.rs index 0caafa0b54df5..af1fd3c4373b3 100644 --- a/crates/flake8_to_ruff/src/converter.rs +++ b/crates/flake8_to_ruff/src/converter.rs @@ -13,11 +13,12 @@ use ruff_linter::rules::flake8_quotes::settings::Quote; use ruff_linter::rules::flake8_tidy_imports::settings::Strictness; use ruff_linter::rules::pydocstyle::settings::Convention; use ruff_linter::settings::types::PythonVersion; +use ruff_linter::settings::DEFAULT_SELECTORS; use ruff_linter::warn_user; use ruff_workspace::options::{ Flake8AnnotationsOptions, Flake8BugbearOptions, Flake8BuiltinsOptions, Flake8ErrMsgOptions, - Flake8PytestStyleOptions, Flake8QuotesOptions, Flake8TidyImportsOptions, McCabeOptions, - Options, Pep8NamingOptions, PydocstyleOptions, + Flake8PytestStyleOptions, Flake8QuotesOptions, Flake8TidyImportsOptions, LintCommonOptions, + LintOptions, McCabeOptions, Options, Pep8NamingOptions, PydocstyleOptions, }; use ruff_workspace::pyproject::Pyproject; @@ -25,11 +26,6 @@ use super::external_config::ExternalConfig; use super::plugin::Plugin; use super::{parser, plugin}; -const DEFAULT_SELECTORS: &[RuleSelector] = &[ - RuleSelector::Linter(Linter::Pyflakes), - RuleSelector::Linter(Linter::Pycodestyle), -]; - pub(crate) fn convert( config: &HashMap>>, external_config: &ExternalConfig, @@ -103,6 +99,7 @@ pub(crate) fn convert( // Parse each supported option. let mut options = Options::default(); + let mut lint_options = LintCommonOptions::default(); let mut flake8_annotations = Flake8AnnotationsOptions::default(); let mut flake8_bugbear = Flake8BugbearOptions::default(); let mut flake8_builtins = Flake8BuiltinsOptions::default(); @@ -150,7 +147,7 @@ pub(crate) fn convert( "per-file-ignores" | "per_file_ignores" => { match parser::parse_files_to_codes_mapping(value.as_ref()) { Ok(per_file_ignores) => { - options.per_file_ignores = + lint_options.per_file_ignores = Some(parser::collect_per_file_ignores(per_file_ignores)); } Err(e) => { @@ -358,47 +355,47 @@ pub(crate) fn convert( } // Deduplicate and sort. - options.select = Some( + lint_options.select = Some( select .into_iter() .sorted_by_key(RuleSelector::prefix_and_code) .collect(), ); - options.ignore = Some( + lint_options.ignore = Some( ignore .into_iter() .sorted_by_key(RuleSelector::prefix_and_code) .collect(), ); if flake8_annotations != Flake8AnnotationsOptions::default() { - options.flake8_annotations = Some(flake8_annotations); + lint_options.flake8_annotations = Some(flake8_annotations); } if flake8_bugbear != Flake8BugbearOptions::default() { - options.flake8_bugbear = Some(flake8_bugbear); + lint_options.flake8_bugbear = Some(flake8_bugbear); } if flake8_builtins != Flake8BuiltinsOptions::default() { - options.flake8_builtins = Some(flake8_builtins); + lint_options.flake8_builtins = Some(flake8_builtins); } if flake8_errmsg != Flake8ErrMsgOptions::default() { - options.flake8_errmsg = Some(flake8_errmsg); + lint_options.flake8_errmsg = Some(flake8_errmsg); } if flake8_pytest_style != Flake8PytestStyleOptions::default() { - options.flake8_pytest_style = Some(flake8_pytest_style); + lint_options.flake8_pytest_style = Some(flake8_pytest_style); } if flake8_quotes != Flake8QuotesOptions::default() { - options.flake8_quotes = Some(flake8_quotes); + lint_options.flake8_quotes = Some(flake8_quotes); } if flake8_tidy_imports != Flake8TidyImportsOptions::default() { - options.flake8_tidy_imports = Some(flake8_tidy_imports); + lint_options.flake8_tidy_imports = Some(flake8_tidy_imports); } if mccabe != McCabeOptions::default() { - options.mccabe = Some(mccabe); + lint_options.mccabe = Some(mccabe); } if pep8_naming != Pep8NamingOptions::default() { - options.pep8_naming = Some(pep8_naming); + lint_options.pep8_naming = Some(pep8_naming); } if pydocstyle != PydocstyleOptions::default() { - options.pydocstyle = Some(pydocstyle); + lint_options.pydocstyle = Some(pydocstyle); } // Extract any settings from the existing `pyproject.toml`. @@ -436,6 +433,13 @@ pub(crate) fn convert( } } + if lint_options != LintCommonOptions::default() { + options.lint = Some(LintOptions { + common: lint_options, + ..LintOptions::default() + }); + } + // Create the pyproject.toml. Pyproject::new(options) } @@ -464,7 +468,9 @@ mod tests { use ruff_linter::rules::flake8_quotes; use ruff_linter::rules::pydocstyle::settings::Convention; use ruff_linter::settings::types::PythonVersion; - use ruff_workspace::options::{Flake8QuotesOptions, Options, PydocstyleOptions}; + use ruff_workspace::options::{ + Flake8QuotesOptions, LintCommonOptions, LintOptions, Options, PydocstyleOptions, + }; use ruff_workspace::pyproject::Pyproject; use crate::converter::DEFAULT_SELECTORS; @@ -474,8 +480,8 @@ mod tests { use super::super::plugin::Plugin; use super::convert; - fn default_options(plugins: impl IntoIterator) -> Options { - Options { + fn lint_default_options(plugins: impl IntoIterator) -> LintCommonOptions { + LintCommonOptions { ignore: Some(vec![]), select: Some( DEFAULT_SELECTORS @@ -485,7 +491,7 @@ mod tests { .sorted_by_key(RuleSelector::prefix_and_code) .collect(), ), - ..Options::default() + ..LintCommonOptions::default() } } @@ -496,7 +502,13 @@ mod tests { &ExternalConfig::default(), None, ); - let expected = Pyproject::new(default_options([])); + let expected = Pyproject::new(Options { + lint: Some(LintOptions { + common: lint_default_options([]), + ..LintOptions::default() + }), + ..Options::default() + }); assert_eq!(actual, expected); } @@ -512,7 +524,11 @@ mod tests { ); let expected = Pyproject::new(Options { line_length: Some(LineLength::try_from(100).unwrap()), - ..default_options([]) + lint: Some(LintOptions { + common: lint_default_options([]), + ..LintOptions::default() + }), + ..Options::default() }); assert_eq!(actual, expected); } @@ -529,7 +545,11 @@ mod tests { ); let expected = Pyproject::new(Options { line_length: Some(LineLength::try_from(100).unwrap()), - ..default_options([]) + lint: Some(LintOptions { + common: lint_default_options([]), + ..LintOptions::default() + }), + ..Options::default() }); assert_eq!(actual, expected); } @@ -544,7 +564,13 @@ mod tests { &ExternalConfig::default(), Some(vec![]), ); - let expected = Pyproject::new(default_options([])); + let expected = Pyproject::new(Options { + lint: Some(LintOptions { + common: lint_default_options([]), + ..LintOptions::default() + }), + ..Options::default() + }); assert_eq!(actual, expected); } @@ -559,13 +585,19 @@ mod tests { Some(vec![]), ); let expected = Pyproject::new(Options { - flake8_quotes: Some(Flake8QuotesOptions { - inline_quotes: Some(flake8_quotes::settings::Quote::Single), - multiline_quotes: None, - docstring_quotes: None, - avoid_escape: None, + lint: Some(LintOptions { + common: LintCommonOptions { + flake8_quotes: Some(Flake8QuotesOptions { + inline_quotes: Some(flake8_quotes::settings::Quote::Single), + multiline_quotes: None, + docstring_quotes: None, + avoid_escape: None, + }), + ..lint_default_options([]) + }, + ..LintOptions::default() }), - ..default_options([]) + ..Options::default() }); assert_eq!(actual, expected); } @@ -584,12 +616,18 @@ mod tests { Some(vec![Plugin::Flake8Docstrings]), ); let expected = Pyproject::new(Options { - pydocstyle: Some(PydocstyleOptions { - convention: Some(Convention::Numpy), - ignore_decorators: None, - property_decorators: None, + lint: Some(LintOptions { + common: LintCommonOptions { + pydocstyle: Some(PydocstyleOptions { + convention: Some(Convention::Numpy), + ignore_decorators: None, + property_decorators: None, + }), + ..lint_default_options([Linter::Pydocstyle.into()]) + }, + ..LintOptions::default() }), - ..default_options([Linter::Pydocstyle.into()]) + ..Options::default() }); assert_eq!(actual, expected); } @@ -605,13 +643,19 @@ mod tests { None, ); let expected = Pyproject::new(Options { - flake8_quotes: Some(Flake8QuotesOptions { - inline_quotes: Some(flake8_quotes::settings::Quote::Single), - multiline_quotes: None, - docstring_quotes: None, - avoid_escape: None, + lint: Some(LintOptions { + common: LintCommonOptions { + flake8_quotes: Some(Flake8QuotesOptions { + inline_quotes: Some(flake8_quotes::settings::Quote::Single), + multiline_quotes: None, + docstring_quotes: None, + avoid_escape: None, + }), + ..lint_default_options([Linter::Flake8Quotes.into()]) + }, + ..LintOptions::default() }), - ..default_options([Linter::Flake8Quotes.into()]) + ..Options::default() }); assert_eq!(actual, expected); } @@ -630,7 +674,11 @@ mod tests { ); let expected = Pyproject::new(Options { target_version: Some(PythonVersion::Py38), - ..default_options([]) + lint: Some(LintOptions { + common: lint_default_options([]), + ..LintOptions::default() + }), + ..Options::default() }); assert_eq!(actual, expected); diff --git a/crates/flake8_to_ruff/src/parser.rs b/crates/flake8_to_ruff/src/parser.rs index 468992ddf96d1..63ab9b68008b7 100644 --- a/crates/flake8_to_ruff/src/parser.rs +++ b/crates/flake8_to_ruff/src/parser.rs @@ -184,7 +184,7 @@ pub(crate) fn collect_per_file_ignores( for pair in pairs { per_file_ignores .entry(pair.pattern) - .or_insert_with(Vec::new) + .or_default() .push(pair.prefix); } per_file_ignores diff --git a/crates/flake8_to_ruff/src/plugin.rs b/crates/flake8_to_ruff/src/plugin.rs index 37c8795f57989..5b2fc585dc850 100644 --- a/crates/flake8_to_ruff/src/plugin.rs +++ b/crates/flake8_to_ruff/src/plugin.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use anyhow::anyhow; use ruff_linter::registry::Linter; -use ruff_linter::settings::types::PreviewMode; +use ruff_linter::rule_selector::PreviewOptions; use ruff_linter::RuleSelector; #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] @@ -332,7 +332,7 @@ pub(crate) fn infer_plugins_from_codes(selectors: &HashSet) -> Vec .filter(|plugin| { for selector in selectors { if selector - .rules(PreviewMode::Disabled) + .rules(&PreviewOptions::default()) .any(|rule| Linter::from(plugin).rules().any(|r| r == rule)) { return true; diff --git a/crates/ruff_benchmark/Cargo.toml b/crates/ruff_benchmark/Cargo.toml index 97f1e8607fd66..1a26242f61b2b 100644 --- a/crates/ruff_benchmark/Cargo.toml +++ b/crates/ruff_benchmark/Cargo.toml @@ -35,9 +35,9 @@ once_cell.workspace = true serde.workspace = true serde_json.workspace = true url = "2.3.1" -ureq = "2.6.2" +ureq = "2.8.0" criterion = { version = "0.5.1", default-features = false } -codspeed-criterion-compat = { version="2.2.0", default-features = false, optional = true} +codspeed-criterion-compat = { version="2.3.0", default-features = false, optional = true} [dev-dependencies] ruff_linter.path = "../ruff_linter" diff --git a/crates/ruff_benchmark/benches/formatter.rs b/crates/ruff_benchmark/benches/formatter.rs index 603f13555ca0d..e89b47a102aee 100644 --- a/crates/ruff_benchmark/benches/formatter.rs +++ b/crates/ruff_benchmark/benches/formatter.rs @@ -4,7 +4,7 @@ use ruff_benchmark::criterion::{ criterion_group, criterion_main, BenchmarkId, Criterion, Throughput, }; use ruff_benchmark::{TestCase, TestFile, TestFileDownloadError}; -use ruff_python_formatter::{format_node, PyFormatOptions}; +use ruff_python_formatter::{format_module_ast, PyFormatOptions}; use ruff_python_index::CommentRangesBuilder; use ruff_python_parser::lexer::lex; use ruff_python_parser::{parse_tokens, Mode}; @@ -65,13 +65,14 @@ fn benchmark_formatter(criterion: &mut Criterion) { let comment_ranges = comment_ranges.finish(); // Parse the AST. - let python_ast = parse_tokens(tokens, Mode::Module, "") + let module = parse_tokens(tokens, case.code(), Mode::Module, "") .expect("Input to be a valid python program"); b.iter(|| { let options = PyFormatOptions::from_extension(Path::new(case.name())); - let formatted = format_node(&python_ast, &comment_ranges, case.code(), options) - .expect("Formatting to succeed"); + let formatted = + format_module_ast(&module, &comment_ranges, case.code(), options) + .expect("Formatting to succeed"); formatted.print().expect("Printing to succeed") }); diff --git a/crates/ruff_cli/Cargo.toml b/crates/ruff_cli/Cargo.toml index d0942e2e45e52..6805f4861dfac 100644 --- a/crates/ruff_cli/Cargo.toml +++ b/crates/ruff_cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ruff_cli" -version = "0.0.291" +version = "0.1.3" publish = false authors = { workspace = true } edition = { workspace = true } @@ -66,11 +66,11 @@ wild = { version = "2" } assert_cmd = { version = "2.0.8" } # Avoid writing colored snapshots when running tests from the terminal colored = { workspace = true, features = ["no-color"]} -insta = { workspace = true, features = ["filters"] } +insta = { workspace = true, features = ["filters", "json"] } insta-cmd = { version = "0.4.0" } tempfile = "3.6.0" test-case = { workspace = true } -ureq = { version = "2.6.2", features = [] } +ureq = { version = "2.8.0", features = [] } [target.'cfg(target_os = "windows")'.dependencies] mimalloc = "0.1.39" diff --git a/crates/ruff_cli/build.rs b/crates/ruff_cli/build.rs new file mode 100644 index 0000000000000..c50a033d6df2b --- /dev/null +++ b/crates/ruff_cli/build.rs @@ -0,0 +1,80 @@ +use std::{fs, path::Path, process::Command}; + +fn main() { + // The workspace root directory is not available without walking up the tree + // https://github.com/rust-lang/cargo/issues/3946 + let workspace_root = Path::new(&std::env::var("CARGO_MANIFEST_DIR").unwrap()) + .join("..") + .join(".."); + + commit_info(&workspace_root); + + #[allow(clippy::disallowed_methods)] + let target = std::env::var("TARGET").unwrap(); + println!("cargo:rustc-env=RUST_HOST_TARGET={target}"); +} + +fn commit_info(workspace_root: &Path) { + // If not in a git repository, do not attempt to retrieve commit information + let git_dir = workspace_root.join(".git"); + if !git_dir.exists() { + return; + } + + let git_head_path = git_dir.join("HEAD"); + println!( + "cargo:rerun-if-changed={}", + git_head_path.as_path().display() + ); + + let git_head_contents = fs::read_to_string(git_head_path); + if let Ok(git_head_contents) = git_head_contents { + // The contents are either a commit or a reference in the following formats + // - "" when the head is detached + // - "ref " when working on a branch + // If a commit, checking if the HEAD file has changed is sufficient + // If a ref, we need to add the head file for that ref to rebuild on commit + let mut git_ref_parts = git_head_contents.split_whitespace(); + git_ref_parts.next(); + if let Some(git_ref) = git_ref_parts.next() { + let git_ref_path = git_dir.join(git_ref); + println!( + "cargo:rerun-if-changed={}", + git_ref_path.as_path().display() + ); + } + } + + let output = match Command::new("git") + .arg("log") + .arg("-1") + .arg("--date=short") + .arg("--abbrev=9") + .arg("--format=%H %h %cd %(describe)") + .output() + { + Ok(output) if output.status.success() => output, + _ => return, + }; + let stdout = String::from_utf8(output.stdout).unwrap(); + let mut parts = stdout.split_whitespace(); + let mut next = || parts.next().unwrap(); + println!("cargo:rustc-env=RUFF_COMMIT_HASH={}", next()); + println!("cargo:rustc-env=RUFF_COMMIT_SHORT_HASH={}", next()); + println!("cargo:rustc-env=RUFF_COMMIT_DATE={}", next()); + + // Describe can fail for some commits + // https://git-scm.com/docs/pretty-formats#Documentation/pretty-formats.txt-emdescribeoptionsem + if let Some(describe) = parts.next() { + let mut describe_parts = describe.split('-'); + println!( + "cargo:rustc-env=RUFF_LAST_TAG={}", + describe_parts.next().unwrap() + ); + // If this is the tagged commit, this component will be missing + println!( + "cargo:rustc-env=RUFF_LAST_TAG_DISTANCE={}", + describe_parts.next().unwrap_or("0") + ); + } +} diff --git a/crates/ruff_cli/resources/test/fixtures/formatted.py b/crates/ruff_cli/resources/test/fixtures/formatted.py new file mode 100644 index 0000000000000..a205c715fb474 --- /dev/null +++ b/crates/ruff_cli/resources/test/fixtures/formatted.py @@ -0,0 +1 @@ +print("All formatted!") diff --git a/crates/ruff_cli/resources/test/fixtures/unformatted.ipynb b/crates/ruff_cli/resources/test/fixtures/unformatted.ipynb new file mode 100644 index 0000000000000..c13f24a142928 --- /dev/null +++ b/crates/ruff_cli/resources/test/fixtures/unformatted.ipynb @@ -0,0 +1,72 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "98e1dd71-14a2-454d-9be0-061dde560b07", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy\n", + "maths = (numpy.arange(100)**2).sum()\n", + "stats= numpy.asarray([1,2,3,4]).median()" + ] + }, + { + "cell_type": "markdown", + "id": "83a0b1b8", + "metadata": {}, + "source": [ + "A markdown cell" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ae12f012", + "metadata": {}, + "outputs": [], + "source": [ + "# A cell with IPython escape command\n", + "def some_function(foo, bar):\n", + " pass\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10f3bbf9", + "metadata": {}, + "outputs": [], + "source": [ + "foo = %pwd\n", + "def some_function(foo,bar,):\n", + " # Another cell with IPython escape command\n", + " foo = %pwd\n", + " print(foo)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/crates/ruff_cli/resources/test/fixtures/unformatted.py b/crates/ruff_cli/resources/test/fixtures/unformatted.py new file mode 100644 index 0000000000000..31bf5480ca982 --- /dev/null +++ b/crates/ruff_cli/resources/test/fixtures/unformatted.py @@ -0,0 +1,3 @@ +x = 1 +y=2 +z = 3 diff --git a/crates/ruff_cli/src/args.rs b/crates/ruff_cli/src/args.rs index b3159f4eb6ab5..ba2cca1b16558 100644 --- a/crates/ruff_cli/src/args.rs +++ b/crates/ruff_cli/src/args.rs @@ -9,9 +9,11 @@ use ruff_linter::logging::LogLevel; use ruff_linter::registry::Rule; use ruff_linter::settings::types::{ FilePattern, PatternPrefixPair, PerFileIgnore, PreviewMode, PythonVersion, SerializationFormat, + UnsafeFixes, }; use ruff_linter::{RuleParser, RuleSelector, RuleSelectorParser}; use ruff_workspace::configuration::{Configuration, RuleSelection}; +use ruff_workspace::options::PycodestyleOptions; use ruff_workspace::resolver::ConfigurationTransformer; #[derive(Debug, Parser)] @@ -48,7 +50,11 @@ pub enum Command { /// Output format #[arg(long, value_enum, default_value = "text")] - format: HelpFormat, + output_format: HelpFormat, + + /// Output format (Deprecated: Use `--output-format` instead). + #[arg(long, value_enum, conflicts_with = "output_format", hide = true)] + format: Option, }, /// List or describe the available configuration options. Config { option: Option }, @@ -56,7 +62,11 @@ pub enum Command { Linter { /// Output format #[arg(long, value_enum, default_value = "text")] - format: HelpFormat, + output_format: HelpFormat, + + /// Output format (Deprecated: Use `--output-format` instead). + #[arg(long, value_enum, conflicts_with = "output_format", hide = true)] + format: Option, }, /// Clear any caches in the current directory and any subdirectories. #[clap(alias = "--clean")] @@ -65,9 +75,12 @@ pub enum Command { #[clap(alias = "--generate-shell-completion", hide = true)] GenerateShellCompletion { shell: clap_complete_command::Shell }, /// Run the Ruff formatter on the given files or directories. - #[doc(hidden)] - #[clap(hide = true)] Format(FormatCommand), + /// Display Ruff's version + Version { + #[arg(long, value_enum, default_value = "text")] + output_format: HelpFormat, + }, } // The `Parser` derive is for ruff_dev, for ruff_cli `Args` would be sufficient @@ -76,19 +89,25 @@ pub enum Command { pub struct CheckCommand { /// List of files or directories to check. pub files: Vec, - /// Attempt to automatically fix lint violations. - /// Use `--no-fix` to disable. + /// Apply fixes to resolve lint violations. + /// Use `--no-fix` to disable or `--unsafe-fixes` to include unsafe fixes. #[arg(long, overrides_with("no_fix"))] fix: bool, #[clap(long, overrides_with("fix"), hide = true)] no_fix: bool, + /// Include fixes that may not retain the original intent of the code. + /// Use `--no-unsafe-fixes` to disable. + #[arg(long, overrides_with("no_unsafe_fixes"))] + unsafe_fixes: bool, + #[arg(long, overrides_with("unsafe_fixes"), hide = true)] + no_unsafe_fixes: bool, /// Show violations with source code. /// Use `--no-show-source` to disable. #[arg(long, overrides_with("no_show_source"))] show_source: bool, #[clap(long, overrides_with("show_source"), hide = true)] no_show_source: bool, - /// Show an enumeration of all autofixed lint violations. + /// Show an enumeration of all fixed lint violations. /// Use `--no-show-fixes` to disable. #[arg(long, overrides_with("no_show_fixes"))] show_fixes: bool, @@ -100,8 +119,8 @@ pub struct CheckCommand { /// Run in watch mode by re-running whenever files change. #[arg(short, long)] pub watch: bool, - /// Fix any fixable lint violations, but don't report on leftover violations. Implies `--fix`. - /// Use `--no-fix-only` to disable. + /// Apply fixes to resolve lint violations, but don't report on leftover violations. Implies `--fix`. + /// Use `--no-fix-only` to disable or `--unsafe-fixes` to include unsafe fixes. #[arg(long, overrides_with("no_fix_only"))] fix_only: bool, #[clap(long, overrides_with("fix_only"), hide = true)] @@ -110,16 +129,6 @@ pub struct CheckCommand { #[arg(long)] ignore_noqa: bool, - /// Output serialization format for violations. (Deprecated: Use `--output-format` instead). - #[arg( - long, - value_enum, - env = "RUFF_FORMAT", - conflicts_with = "output_format", - hide = true - )] - pub format: Option, - /// Output serialization format for violations. #[arg(long, value_enum, env = "RUFF_OUTPUT_FORMAT")] pub output_format: Option, @@ -202,7 +211,7 @@ pub struct CheckCommand { help_heading = "File selection" )] pub extend_exclude: Option>, - /// List of rule codes to treat as eligible for autofix. Only applicable when autofix itself is enabled (e.g., via `--fix`). + /// List of rule codes to treat as eligible for fix. Only applicable when fix itself is enabled (e.g., via `--fix`). #[arg( long, value_delimiter = ',', @@ -212,7 +221,7 @@ pub struct CheckCommand { hide_possible_values = true )] pub fixable: Option>, - /// List of rule codes to treat as ineligible for autofix. Only applicable when autofix itself is enabled (e.g., via `--fix`). + /// List of rule codes to treat as ineligible for fix. Only applicable when fix itself is enabled (e.g., via `--fix`). #[arg( long, value_delimiter = ',', @@ -288,7 +297,7 @@ pub struct CheckCommand { conflicts_with = "exit_non_zero_on_fix" )] pub exit_zero: bool, - /// Exit with a non-zero status code if any files were modified via autofix, even if no lint violations remain. + /// Exit with a non-zero status code if any files were modified via fix, even if no lint violations remain. #[arg(long, help_heading = "Miscellaneous", conflicts_with = "exit_zero")] pub exit_non_zero_on_fix: bool, /// Show counts for every rule with at least one violation. @@ -356,9 +365,21 @@ pub struct FormatCommand { /// files would have been modified, and zero otherwise. #[arg(long)] pub check: bool, + /// Avoid writing any formatted files back; instead, exit with a non-zero status code and the + /// difference between the current file and how the formatted file would look like. + #[arg(long)] + pub diff: bool, /// Path to the `pyproject.toml` or `ruff.toml` file to use for configuration. #[arg(long, conflicts_with = "isolated")] pub config: Option, + + /// Disable cache reads. + #[arg(short, long, help_heading = "Miscellaneous")] + pub no_cache: bool, + /// Path to the cache directory. + #[arg(long, env = "RUFF_CACHE_DIR", help_heading = "Miscellaneous")] + pub cache_dir: Option, + /// Respect file exclusions via `.gitignore` and other standard ignore files. /// Use `--no-respect-gitignore` to disable. #[arg( @@ -369,6 +390,15 @@ pub struct FormatCommand { respect_gitignore: bool, #[clap(long, overrides_with("respect_gitignore"), hide = true)] no_respect_gitignore: bool, + /// List of paths, used to omit files and/or directories from analysis. + #[arg( + long, + value_delimiter = ',', + value_name = "FILE_PATTERN", + help_heading = "File selection" + )] + pub exclude: Option>, + /// Enforce exclusions, even for paths passed to Ruff directly on the command-line. /// Use `--no-force-exclude` to disable. #[arg( @@ -379,19 +409,18 @@ pub struct FormatCommand { force_exclude: bool, #[clap(long, overrides_with("force_exclude"), hide = true)] no_force_exclude: bool, - /// Set the line-length. - #[arg(long, help_heading = "Rule configuration", hide = true)] - pub line_length: Option, /// Ignore all configuration files. #[arg(long, conflicts_with = "config", help_heading = "Miscellaneous")] pub isolated: bool, /// The name of the file when passing it through stdin. #[arg(long, help_heading = "Miscellaneous")] pub stdin_filename: Option, - - /// Enable preview mode; checks will include unstable rules and fixes. + /// The minimum Python version that should be supported. + #[arg(long, value_enum)] + pub target_version: Option, + /// Enable preview mode; enables unstable formatting. /// Use `--no-preview` to disable. - #[arg(long, overrides_with("no_preview"), hide = true)] + #[arg(long, overrides_with("no_preview"))] preview: bool, #[clap(long, overrides_with("preview"), hide = true)] no_preview: bool, @@ -497,8 +526,10 @@ impl CheckCommand { cache_dir: self.cache_dir, fix: resolve_bool_arg(self.fix, self.no_fix), fix_only: resolve_bool_arg(self.fix_only, self.no_fix_only), + unsafe_fixes: resolve_bool_arg(self.unsafe_fixes, self.no_unsafe_fixes) + .map(UnsafeFixes::from), force_exclude: resolve_bool_arg(self.force_exclude, self.no_force_exclude), - output_format: self.output_format.or(self.format), + output_format: self.output_format, show_fixes: resolve_bool_arg(self.show_fixes, self.no_show_fixes), }, ) @@ -512,19 +543,24 @@ impl FormatCommand { ( FormatArguments { check: self.check, + diff: self.diff, config: self.config, files: self.files, isolated: self.isolated, + no_cache: self.no_cache, stdin_filename: self.stdin_filename, }, CliOverrides { - line_length: self.line_length, respect_gitignore: resolve_bool_arg( self.respect_gitignore, self.no_respect_gitignore, ), + exclude: self.exclude, preview: resolve_bool_arg(self.preview, self.no_preview).map(PreviewMode::from), force_exclude: resolve_bool_arg(self.force_exclude, self.no_force_exclude), + target_version: self.target_version, + cache_dir: self.cache_dir, + // Unsupported on the formatter CLI, but required on `Overrides`. ..CliOverrides::default() }, @@ -568,6 +604,8 @@ pub struct CheckArguments { #[allow(clippy::struct_excessive_bools)] pub struct FormatArguments { pub check: bool, + pub no_cache: bool, + pub diff: bool, pub config: Option, pub files: Vec, pub isolated: bool, @@ -599,6 +637,7 @@ pub struct CliOverrides { pub cache_dir: Option, pub fix: Option, pub fix_only: Option, + pub unsafe_fixes: Option, pub force_exclude: Option, pub output_format: Option, pub show_fixes: Option, @@ -610,7 +649,7 @@ impl ConfigurationTransformer for CliOverrides { config.cache_dir = Some(cache_dir.clone()); } if let Some(dummy_variable_rgx) = &self.dummy_variable_rgx { - config.dummy_variable_rgx = Some(dummy_variable_rgx.clone()); + config.lint.dummy_variable_rgx = Some(dummy_variable_rgx.clone()); } if let Some(exclude) = &self.exclude { config.exclude = Some(exclude.clone()); @@ -624,7 +663,10 @@ impl ConfigurationTransformer for CliOverrides { if let Some(fix_only) = &self.fix_only { config.fix_only = Some(*fix_only); } - config.rule_selections.push(RuleSelection { + if self.unsafe_fixes.is_some() { + config.unsafe_fixes = self.unsafe_fixes; + } + config.lint.rule_selections.push(RuleSelection { select: self.select.clone(), ignore: self .ignore @@ -650,14 +692,20 @@ impl ConfigurationTransformer for CliOverrides { if let Some(force_exclude) = &self.force_exclude { config.force_exclude = Some(*force_exclude); } - if let Some(line_length) = &self.line_length { - config.line_length = Some(*line_length); + if let Some(line_length) = self.line_length { + config.line_length = Some(line_length); + config.lint.pycodestyle = Some(PycodestyleOptions { + max_line_length: Some(line_length), + ..config.lint.pycodestyle.unwrap_or_default() + }); } if let Some(preview) = &self.preview { config.preview = Some(*preview); + config.lint.preview = Some(*preview); + config.format.preview = Some(*preview); } if let Some(per_file_ignores) = &self.per_file_ignores { - config.per_file_ignores = Some(collect_per_file_ignores(per_file_ignores.clone())); + config.lint.per_file_ignores = Some(collect_per_file_ignores(per_file_ignores.clone())); } if let Some(respect_gitignore) = &self.respect_gitignore { config.respect_gitignore = Some(*respect_gitignore); @@ -682,7 +730,7 @@ pub fn collect_per_file_ignores(pairs: Vec) -> Vec io::Result { + // Construct a cache key for the file + let metadata = path.metadata()?; + + #[cfg(unix)] + let permissions = { + use std::os::unix::fs::PermissionsExt; + metadata.permissions().mode() + }; + #[cfg(windows)] + let permissions: u32 = metadata.permissions().readonly().into(); + + Ok(FileCacheKey { + file_last_modified: FileTime::from_last_modification_time(&metadata), + file_permissions_mode: permissions, + }) + } +} + /// Cache. /// /// `Cache` holds everything required to display the diagnostics for a single @@ -50,7 +84,7 @@ pub(crate) struct Cache { /// Files that are linted, but are not in `package.files` or are in /// `package.files` but are outdated. This gets merged with `package.files` /// when the cache is written back to disk in [`Cache::store`]. - new_files: Mutex>, + changes: Mutex>, /// The "current" timestamp used as cache for the updates of /// [`FileCache::last_seen`] last_seen_cache: u64, @@ -65,7 +99,7 @@ impl Cache { /// /// Finally `settings` is used to ensure we don't open a cache for different /// settings. It also defines the directory where to store the cache. - pub(crate) fn open(package_root: PathBuf, settings: &Settings) -> Cache { + pub(crate) fn open(package_root: PathBuf, settings: &Settings) -> Self { debug_assert!(package_root.is_absolute(), "package root not canonicalized"); let mut buf = itoa::Buffer::new(); @@ -105,7 +139,7 @@ impl Cache { } /// Create an empty `Cache`. - fn empty(path: PathBuf, package_root: PathBuf) -> Cache { + fn empty(path: PathBuf, package_root: PathBuf) -> Self { let package = PackageCache { package_root, files: HashMap::new(), @@ -114,37 +148,25 @@ impl Cache { } #[allow(clippy::cast_possible_truncation)] - fn new(path: PathBuf, package: PackageCache) -> Cache { + fn new(path: PathBuf, package: PackageCache) -> Self { Cache { path, package, - new_files: Mutex::new(HashMap::new()), + changes: Mutex::new(Vec::new()), // SAFETY: this will be truncated to the year ~2554 (so don't use // this code after that!). last_seen_cache: SystemTime::UNIX_EPOCH.elapsed().unwrap().as_millis() as u64, } } - /// Store the cache to disk, if it has been changed. - #[allow(clippy::cast_possible_truncation)] - pub(crate) fn store(mut self) -> Result<()> { - let new_files = self.new_files.into_inner().unwrap(); - if new_files.is_empty() { + /// Applies the pending changes and persists the cache to disk, if it has been changed. + pub(crate) fn persist(mut self) -> Result<()> { + if !self.save() { // No changes made, no need to write the same cache file back to // disk. return Ok(()); } - // Remove cached files that we haven't seen in a while. - let now = self.last_seen_cache; - self.package.files.retain(|_, file| { - // SAFETY: this will be truncated to the year ~2554. - (now - *file.last_seen.get_mut()) <= MAX_LAST_SEEN.as_millis() as u64 - }); - - // Apply any changes made and keep track of when we last saw files. - self.package.files.extend(new_files); - let file = File::create(&self.path) .with_context(|| format!("Failed to create cache file '{}'", self.path.display()))?; let writer = BufWriter::new(file); @@ -156,6 +178,53 @@ impl Cache { }) } + /// Applies the pending changes without storing the cache to disk. + #[allow(clippy::cast_possible_truncation)] + pub(crate) fn save(&mut self) -> bool { + /// Maximum duration for which we keep a file in cache that hasn't been seen. + const MAX_LAST_SEEN: Duration = Duration::from_secs(30 * 24 * 60 * 60); // 30 days. + + let changes = std::mem::take(self.changes.get_mut().unwrap()); + if changes.is_empty() { + return false; + } + + // Remove cached files that we haven't seen in a while. + let now = self.last_seen_cache; + self.package.files.retain(|_, file| { + // SAFETY: this will be truncated to the year ~2554. + (now - *file.last_seen.get_mut()) <= MAX_LAST_SEEN.as_millis() as u64 + }); + + // Apply any changes made and keep track of when we last saw files. + for change in changes { + let entry = self + .package + .files + .entry(change.path) + .and_modify(|existing| { + if existing.key != change.new_key { + // Reset the data if the key change. + existing.data = FileCacheData::default(); + } + + existing.key = change.new_key; + existing + .last_seen + .store(self.last_seen_cache, Ordering::Relaxed); + }) + .or_insert_with(|| FileCache { + key: change.new_key, + last_seen: AtomicU64::new(self.last_seen_cache), + data: FileCacheData::default(), + }); + + change.new_data.apply(&mut entry.data); + } + + true + } + /// Returns the relative path based on `path` and the package root. /// /// Returns `None` if `path` is not within the package. @@ -169,7 +238,7 @@ impl Cache { /// /// This returns `None` if `key` differs from the cached key or if the /// cache doesn't contain results for the file. - pub(crate) fn get(&self, path: &RelativePath, key: &T) -> Option<&FileCache> { + pub(crate) fn get(&self, path: &RelativePath, key: &FileCacheKey) -> Option<&FileCache> { let file = self.package.files.get(path)?; let mut hasher = CacheKeyHasher::new(); @@ -185,50 +254,34 @@ impl Cache { Some(file) } + pub(crate) fn is_formatted(&self, path: &RelativePath, key: &FileCacheKey) -> bool { + self.get(path, key) + .is_some_and(|entry| entry.data.formatted) + } + /// Add or update a file cache at `path` relative to the package root. - pub(crate) fn update( + fn update(&self, path: RelativePathBuf, key: &FileCacheKey, data: ChangeData) { + let mut hasher = CacheKeyHasher::new(); + key.cache_key(&mut hasher); + + self.changes.lock().unwrap().push(Change { + path, + new_key: hasher.finish(), + new_data: data, + }); + } + + pub(crate) fn update_lint( &self, path: RelativePathBuf, - key: T, - messages: &[Message], - imports: &ImportMap, - notebook_index: Option<&NotebookIndex>, + key: &FileCacheKey, + data: LintCacheData, ) { - let source = if let Some(msg) = messages.first() { - msg.file.source_text().to_owned() - } else { - String::new() // No messages, no need to keep the source! - }; - - let messages = messages - .iter() - .map(|msg| { - // Make sure that all message use the same source file. - assert!( - msg.file == messages.first().unwrap().file, - "message uses a different source file" - ); - CacheMessage { - kind: msg.kind.clone(), - range: msg.range, - fix: msg.fix.clone(), - noqa_offset: msg.noqa_offset, - } - }) - .collect(); - - let mut hasher = CacheKeyHasher::new(); - key.cache_key(&mut hasher); + self.update(path, key, ChangeData::Lint(data)); + } - let file = FileCache { - key: hasher.finish(), - last_seen: AtomicU64::new(self.last_seen_cache), - imports: imports.clone(), - messages, - source, - notebook_index: notebook_index.cloned(), - }; - self.new_files.lock().unwrap().insert(path, file); + pub(crate) fn set_formatted(&self, path: RelativePathBuf, key: &FileCacheKey) { + self.update(path, key, ChangeData::Formatted); } } @@ -254,55 +307,43 @@ pub(crate) struct FileCache { /// Represented as the number of milliseconds since Unix epoch. This will /// break in 1970 + ~584 years (~2554). last_seen: AtomicU64, - /// Imports made. - imports: ImportMap, - /// Diagnostic messages. - messages: Vec, - /// Source code of the file. - /// - /// # Notes - /// - /// This will be empty if `messages` is empty. - source: String, - /// Notebook index if this file is a Jupyter Notebook. - notebook_index: Option, + + data: FileCacheData, } impl FileCache { /// Convert the file cache into `Diagnostics`, using `path` as file name. - pub(crate) fn as_diagnostics(&self, path: &Path) -> Diagnostics { - let messages = if self.messages.is_empty() { - Vec::new() - } else { - let file = SourceFileBuilder::new(path.to_string_lossy(), &*self.source).finish(); - self.messages - .iter() - .map(|msg| Message { - kind: msg.kind.clone(), - range: msg.range, - fix: msg.fix.clone(), - file: file.clone(), - noqa_offset: msg.noqa_offset, - }) - .collect() - }; - let notebook_indexes = if let Some(notebook_index) = self.notebook_index.as_ref() { - FxHashMap::from_iter([(path.to_string_lossy().to_string(), notebook_index.clone())]) - } else { - FxHashMap::default() - }; - Diagnostics::new(messages, self.imports.clone(), notebook_indexes) + pub(crate) fn to_diagnostics(&self, path: &Path) -> Option { + self.data.lint.as_ref().map(|lint| { + let messages = if lint.messages.is_empty() { + Vec::new() + } else { + let file = SourceFileBuilder::new(path.to_string_lossy(), &*lint.source).finish(); + lint.messages + .iter() + .map(|msg| Message { + kind: msg.kind.clone(), + range: msg.range, + fix: msg.fix.clone(), + file: file.clone(), + noqa_offset: msg.noqa_offset, + }) + .collect() + }; + let notebook_indexes = if let Some(notebook_index) = lint.notebook_index.as_ref() { + FxHashMap::from_iter([(path.to_string_lossy().to_string(), notebook_index.clone())]) + } else { + FxHashMap::default() + }; + Diagnostics::new(messages, lint.imports.clone(), notebook_indexes) + }) } } -/// On disk representation of a diagnostic message. -#[derive(Deserialize, Debug, Serialize)] -struct CacheMessage { - kind: DiagnosticKind, - /// Range into the message's [`FileCache::source`]. - range: TextRange, - fix: Option, - noqa_offset: TextSize, +#[derive(Debug, Default, Deserialize, Serialize)] +struct FileCacheData { + lint: Option, + formatted: bool, } /// Returns a hash key based on the `package_root`, `settings` and the crate @@ -335,32 +376,209 @@ pub(crate) fn init(path: &Path) -> Result<()> { Ok(()) } +#[derive(Deserialize, Debug, Serialize, PartialEq)] +pub(crate) struct LintCacheData { + /// Imports made. + pub(super) imports: ImportMap, + /// Diagnostic messages. + pub(super) messages: Vec, + /// Source code of the file. + /// + /// # Notes + /// + /// This will be empty if `messages` is empty. + pub(super) source: String, + /// Notebook index if this file is a Jupyter Notebook. + pub(super) notebook_index: Option, +} + +impl LintCacheData { + pub(crate) fn from_messages( + messages: &[Message], + imports: ImportMap, + notebook_index: Option, + ) -> Self { + let source = if let Some(msg) = messages.first() { + msg.file.source_text().to_owned() + } else { + String::new() // No messages, no need to keep the source! + }; + + let messages = messages + .iter() + .map(|msg| { + // Make sure that all message use the same source file. + assert_eq!( + msg.file, + messages.first().unwrap().file, + "message uses a different source file" + ); + CacheMessage { + kind: msg.kind.clone(), + range: msg.range, + fix: msg.fix.clone(), + noqa_offset: msg.noqa_offset, + } + }) + .collect(); + + Self { + imports, + messages, + source, + notebook_index, + } + } +} + +/// On disk representation of a diagnostic message. +#[derive(Deserialize, Debug, Serialize, PartialEq)] +pub(super) struct CacheMessage { + kind: DiagnosticKind, + /// Range into the message's [`FileCache::source`]. + range: TextRange, + fix: Option, + noqa_offset: TextSize, +} + +pub(crate) trait PackageCaches { + fn get(&self, package_root: &Path) -> Option<&Cache>; + + fn persist(self) -> anyhow::Result<()>; +} + +impl PackageCaches for Option +where + T: PackageCaches, +{ + fn get(&self, package_root: &Path) -> Option<&Cache> { + match self { + None => None, + Some(caches) => caches.get(package_root), + } + } + + fn persist(self) -> Result<()> { + match self { + None => Ok(()), + Some(caches) => caches.persist(), + } + } +} + +pub(crate) struct PackageCacheMap<'a>(FxHashMap<&'a Path, Cache>); + +impl<'a> PackageCacheMap<'a> { + pub(crate) fn init( + pyproject_config: &PyprojectConfig, + package_roots: &FxHashMap<&'a Path, Option<&'a Path>>, + resolver: &Resolver, + ) -> Self { + fn init_cache(path: &Path) { + if let Err(e) = cache::init(path) { + error!("Failed to initialize cache at {}: {e:?}", path.display()); + } + } + + match pyproject_config.strategy { + PyprojectDiscoveryStrategy::Fixed => { + init_cache(&pyproject_config.settings.cache_dir); + } + PyprojectDiscoveryStrategy::Hierarchical => { + for settings in + std::iter::once(&pyproject_config.settings).chain(resolver.settings()) + { + init_cache(&settings.cache_dir); + } + } + } + + Self( + package_roots + .iter() + .map(|(package, package_root)| package_root.unwrap_or(package)) + .unique() + .par_bridge() + .map(|cache_root| { + let settings = resolver.resolve(cache_root, pyproject_config); + let cache = Cache::open(cache_root.to_path_buf(), settings); + (cache_root, cache) + }) + .collect(), + ) + } +} + +impl PackageCaches for PackageCacheMap<'_> { + fn get(&self, package_root: &Path) -> Option<&Cache> { + let cache = self.0.get(package_root); + + if cache.is_none() { + debug!("No cache found for {}", package_root.display()); + } + + cache + } + + fn persist(self) -> Result<()> { + self.0 + .into_par_iter() + .try_for_each(|(_, cache)| cache.persist()) + } +} + +#[derive(Debug)] +struct Change { + path: PathBuf, + new_key: u64, + new_data: ChangeData, +} + +#[derive(Debug)] +enum ChangeData { + Lint(LintCacheData), + Formatted, +} + +impl ChangeData { + fn apply(self, data: &mut FileCacheData) { + match self { + ChangeData::Lint(new_lint) => { + data.lint = Some(new_lint); + } + ChangeData::Formatted => { + data.formatted = true; + } + } + } +} + #[cfg(test)] mod tests { - use filetime::{set_file_mtime, FileTime}; use std::env::temp_dir; use std::fs; use std::io; use std::io::Write; use std::path::{Path, PathBuf}; + use std::sync::atomic::AtomicU64; use std::time::SystemTime; + use anyhow::Result; + use filetime::{set_file_mtime, FileTime}; use itertools::Itertools; + use test_case::test_case; + use ruff_cache::CACHE_DIR_NAME; use ruff_linter::settings::flags; + use ruff_linter::settings::types::UnsafeFixes; + use ruff_python_ast::PySourceType; + use ruff_workspace::Settings; - use crate::cache::RelativePathBuf; - use crate::cache::{self, Cache, FileCache}; + use crate::cache::{self, FileCache, FileCacheData, FileCacheKey}; + use crate::cache::{Cache, RelativePathBuf}; + use crate::commands::format::{format_path, FormatCommandError, FormatMode, FormatResult}; use crate::diagnostics::{lint_path, Diagnostics}; - use std::sync::atomic::AtomicU64; - - use anyhow::Result; - use ruff_python_ast::imports::ImportMap; - - use ruff_workspace::Settings; - use test_case::test_case; - #[test_case("../ruff_linter/resources/test/fixtures", "ruff_tests/cache_same_results_ruff_linter"; "ruff_linter_fixtures")] #[test_case("../ruff_notebook/resources/test/fixtures", "ruff_tests/cache_same_results_ruff_notebook"; "ruff_notebook_fixtures")] fn same_results(package_root: &str, cache_dir_path: &str) { @@ -376,7 +594,7 @@ mod tests { let package_root = fs::canonicalize(package_root).unwrap(); let cache = Cache::open(package_root.clone(), &settings); - assert_eq!(cache.new_files.lock().unwrap().len(), 0); + assert_eq!(cache.changes.lock().unwrap().len(), 0); let mut paths = Vec::new(); let mut parse_errors = Vec::new(); @@ -410,6 +628,7 @@ mod tests { Some(&cache), flags::Noqa::Enabled, flags::FixMode::Generate, + UnsafeFixes::Enabled, ) .unwrap(); if diagnostics @@ -425,7 +644,7 @@ mod tests { } assert_ne!(paths, &[] as &[std::path::PathBuf], "no files checked"); - cache.store().unwrap(); + cache.persist().unwrap(); let cache = Cache::open(package_root.clone(), &settings); assert_ne!(cache.package.files.len(), 0); @@ -455,6 +674,7 @@ mod tests { Some(&cache), flags::Noqa::Enabled, flags::FixMode::Generate, + UnsafeFixes::Enabled, ) .unwrap(); } @@ -469,21 +689,21 @@ mod tests { let test_cache = TestCache::new("cache_adds_file_on_lint"); let cache = test_cache.open(); test_cache.write_source_file("source.py", source); - assert_eq!(cache.new_files.lock().unwrap().len(), 0); + assert_eq!(cache.changes.lock().unwrap().len(), 0); - cache.store().unwrap(); + cache.persist().unwrap(); let cache = test_cache.open(); test_cache .lint_file_with_cache("source.py", &cache) .expect("Failed to lint test file"); assert_eq!( - cache.new_files.lock().unwrap().len(), + cache.changes.lock().unwrap().len(), 1, "A single new file should be added to the cache" ); - cache.store().unwrap(); + cache.persist().unwrap(); } #[test] @@ -494,9 +714,9 @@ mod tests { let cache = test_cache.open(); test_cache.write_source_file("source_1.py", source); test_cache.write_source_file("source_2.py", source); - assert_eq!(cache.new_files.lock().unwrap().len(), 0); + assert_eq!(cache.changes.lock().unwrap().len(), 0); - cache.store().unwrap(); + cache.persist().unwrap(); let cache = test_cache.open(); test_cache @@ -506,12 +726,39 @@ mod tests { .lint_file_with_cache("source_2.py", &cache) .expect("Failed to lint test file"); assert_eq!( - cache.new_files.lock().unwrap().len(), + cache.changes.lock().unwrap().len(), 2, "Both files should be added to the cache" ); + cache.persist().unwrap(); + } + + #[test] + fn cache_adds_files_on_format() { + let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\", \"b\"])\n"; - cache.store().unwrap(); + let test_cache = TestCache::new("cache_adds_files_on_format"); + let cache = test_cache.open(); + test_cache.write_source_file("source_1.py", source); + test_cache.write_source_file("source_2.py", source); + assert_eq!(cache.changes.lock().unwrap().len(), 0); + + cache.persist().unwrap(); + let cache = test_cache.open(); + + test_cache + .format_file_with_cache("source_1.py", &cache) + .expect("Failed to format test file"); + test_cache + .format_file_with_cache("source_2.py", &cache) + .expect("Failed to format test file"); + assert_eq!( + cache.changes.lock().unwrap().len(), + 2, + "Both files should be added to the cache" + ); + + cache.persist().unwrap(); } #[test] @@ -521,13 +768,13 @@ mod tests { let test_cache = TestCache::new("cache_invalidated_on_file_modified_time"); let cache = test_cache.open(); let source_path = test_cache.write_source_file("source.py", source); - assert_eq!(cache.new_files.lock().unwrap().len(), 0); + assert_eq!(cache.changes.lock().unwrap().len(), 0); let expected_diagnostics = test_cache .lint_file_with_cache("source.py", &cache) .expect("Failed to lint test file"); - cache.store().unwrap(); + cache.persist().unwrap(); let cache = test_cache.open(); // Update the modified time of the file to a time in the future @@ -542,7 +789,7 @@ mod tests { .expect("Failed to lint test file"); assert_eq!( - cache.new_files.lock().unwrap().len(), + cache.changes.lock().unwrap().len(), 1, "Cache should not be used, the file should be treated as new and added to the cache" ); @@ -580,13 +827,13 @@ mod tests { let test_cache = TestCache::new("cache_invalidated_on_permission_change"); let cache = test_cache.open(); let path = test_cache.write_source_file("source.py", source); - assert_eq!(cache.new_files.lock().unwrap().len(), 0); + assert_eq!(cache.changes.lock().unwrap().len(), 0); let expected_diagnostics = test_cache .lint_file_with_cache("source.py", &cache) .unwrap(); - cache.store().unwrap(); + cache.persist().unwrap(); let cache = test_cache.open(); // Flip the permissions on the file @@ -600,7 +847,7 @@ mod tests { .unwrap(); assert_eq!( - cache.new_files.lock().unwrap().len(), + cache.changes.lock().unwrap().len(), 1, "Cache should not be used, the file should be treated as new and added to the cache" ); @@ -612,8 +859,8 @@ mod tests { } #[test] - fn cache_removes_stale_files_on_store() { - let test_cache = TestCache::new("cache_removes_stale_files_on_store"); + fn cache_removes_stale_files_on_persist() { + let test_cache = TestCache::new("cache_removes_stale_files_on_persist"); let mut cache = test_cache.open(); // Add a file to the cache that hasn't been linted or seen since the '70s! @@ -623,10 +870,7 @@ mod tests { FileCache { key: 123, last_seen: AtomicU64::new(123), - imports: ImportMap::new(), - messages: Vec::new(), - source: String::new(), - notebook_index: None, + data: FileCacheData::default(), }, ); @@ -634,34 +878,125 @@ mod tests { let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\", \"b\"])\n"; test_cache.write_source_file("new.py", source); let new_path_key = RelativePathBuf::from("new.py"); - assert_eq!(cache.new_files.lock().unwrap().len(), 0); + assert_eq!(cache.changes.lock().unwrap().len(), 0); test_cache .lint_file_with_cache("new.py", &cache) .expect("Failed to lint test file"); // Storing the cache should remove the old (`old.py`) file. - cache.store().unwrap(); + cache.persist().unwrap(); // So we when we open the cache again it shouldn't contain `old.py`. let cache = test_cache.open(); - assert!( - cache.package.files.keys().collect_vec() == vec![&new_path_key], + assert_eq!( + cache.package.files.keys().collect_vec(), + vec![&new_path_key], "Only the new file should be present" ); } + #[test] + fn format_updates_cache_entry() { + let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\", \"b\"])\n"; + + let test_cache = TestCache::new("format_updates_cache_entry"); + let cache = test_cache.open(); + test_cache.write_source_file("source.py", source); + assert_eq!(cache.changes.lock().unwrap().len(), 0); + + cache.persist().unwrap(); + let cache = test_cache.open(); + + // Cache the lint results + test_cache + .lint_file_with_cache("source.py", &cache) + .expect("Failed to lint test file"); + cache.persist().unwrap(); + + let mut cache = test_cache.open(); + + // Now lint the file + test_cache + .format_file_with_cache("source.py", &cache) + .expect("Failed to format test file"); + + cache.save(); + + assert_eq!(cache.package.files.len(), 1); + + let Some(file_cache) = cache.get( + Path::new("source.py"), + &FileCacheKey::from_path(&test_cache.package_root.join("source.py")).unwrap(), + ) else { + panic!("Cache entry for `source.py` is missing."); + }; + + assert!(file_cache.data.lint.is_some()); + assert!(file_cache.data.formatted); + } + + #[test] + fn file_changes_invalidate_file_cache() { + let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\", \"b\"])\n"; + + let test_cache = TestCache::new("file_changes_invalidate_file_cache"); + let cache = test_cache.open(); + let source_path = test_cache.write_source_file("source.py", source); + assert_eq!(cache.changes.lock().unwrap().len(), 0); + + cache.persist().unwrap(); + let cache = test_cache.open(); + + // Cache the format and lint results + test_cache + .lint_file_with_cache("source.py", &cache) + .expect("Failed to lint test file"); + test_cache + .format_file_with_cache("source.py", &cache) + .expect("Failed to format test file"); + + cache.persist().unwrap(); + + let mut cache = test_cache.open(); + assert_eq!(cache.package.files.len(), 1); + + set_file_mtime( + &source_path, + FileTime::from_system_time(SystemTime::now() + std::time::Duration::from_secs(1)), + ) + .unwrap(); + + test_cache + .format_file_with_cache("source.py", &cache) + .expect("Failed to format test file"); + + cache.save(); + + assert_eq!(cache.package.files.len(), 1); + + let Some(file_cache) = cache.get( + Path::new("source.py"), + &FileCacheKey::from_path(&source_path).unwrap(), + ) else { + panic!("Cache entry for `source.py` is missing."); + }; + + assert_eq!(file_cache.data.lint, None); + assert!(file_cache.data.formatted); + } + struct TestCache { package_root: PathBuf, settings: Settings, } impl TestCache { - fn new(name: &str) -> Self { + fn new(test_case: &str) -> Self { // Build a new cache directory and clear it let mut test_dir = temp_dir(); test_dir.push("ruff_tests/cache"); - test_dir.push(name); + test_dir.push(test_case); let _ = fs::remove_dir_all(&test_dir); @@ -712,6 +1047,22 @@ mod tests { Some(cache), flags::Noqa::Enabled, flags::FixMode::Generate, + UnsafeFixes::Enabled, + ) + } + + fn format_file_with_cache( + &self, + path: &str, + cache: &Cache, + ) -> Result { + let file_path = self.package_root.join(path); + format_path( + &file_path, + &self.settings.formatter, + PySourceType::Python, + FormatMode::Write, + Some(cache), ) } } diff --git a/crates/ruff_cli/src/commands/add_noqa.rs b/crates/ruff_cli/src/commands/add_noqa.rs index 513f4ba2487ca..541e40f2b78cf 100644 --- a/crates/ruff_cli/src/commands/add_noqa.rs +++ b/crates/ruff_cli/src/commands/add_noqa.rs @@ -7,12 +7,12 @@ use log::{debug, error}; use rayon::prelude::*; use ruff_linter::linter::add_noqa_to_path; +use ruff_linter::source_kind::SourceKind; use ruff_linter::warn_user_once; use ruff_python_ast::{PySourceType, SourceType}; -use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig}; +use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig, ResolvedFile}; use crate::args::CliOverrides; -use crate::diagnostics::LintSource; /// Add `noqa` directives to a collection of files. pub(crate) fn add_noqa( @@ -36,7 +36,7 @@ pub(crate) fn add_noqa( &paths .iter() .flatten() - .map(ignore::DirEntry::path) + .map(ResolvedFile::path) .collect::>(), pyproject_config, ); @@ -45,20 +45,21 @@ pub(crate) fn add_noqa( let modifications: usize = paths .par_iter() .flatten() - .filter_map(|entry| { - let path = entry.path(); + .filter_map(|resolved_file| { let SourceType::Python(source_type @ (PySourceType::Python | PySourceType::Stub)) = - SourceType::from(path) + SourceType::from(resolved_file.path()) else { return None; }; - let package = path + let path = resolved_file.path(); + let package = resolved_file + .path() .parent() .and_then(|parent| package_roots.get(parent)) .and_then(|package| *package); let settings = resolver.resolve(path, pyproject_config); - let LintSource(source_kind) = match LintSource::try_from_path(path, source_type) { - Ok(Some(source)) => source, + let source_kind = match SourceKind::from_path(path, source_type) { + Ok(Some(source_kind)) => source_kind, Ok(None) => return None, Err(e) => { error!("Failed to extract source from {}: {e}", path.display()); diff --git a/crates/ruff_cli/src/commands/check.rs b/crates/ruff_cli/src/commands/check.rs index a16f9fef9ae5d..001cb0ae8449d 100644 --- a/crates/ruff_cli/src/commands/check.rs +++ b/crates/ruff_cli/src/commands/check.rs @@ -1,4 +1,3 @@ -use std::collections::HashMap; use std::fmt::Write; use std::io; use std::path::{Path, PathBuf}; @@ -7,7 +6,6 @@ use std::time::Instant; use anyhow::Result; use colored::Colorize; use ignore::Error; -use itertools::Itertools; use log::{debug, error, warn}; #[cfg(not(target_family = "wasm"))] use rayon::prelude::*; @@ -16,15 +14,18 @@ use rustc_hash::FxHashMap; use ruff_diagnostics::Diagnostic; use ruff_linter::message::Message; use ruff_linter::registry::Rule; +use ruff_linter::settings::types::UnsafeFixes; use ruff_linter::settings::{flags, LinterSettings}; use ruff_linter::{fs, warn_user_once, IOError}; use ruff_python_ast::imports::ImportMap; use ruff_source_file::SourceFileBuilder; use ruff_text_size::{TextRange, TextSize}; -use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig, PyprojectDiscoveryStrategy}; +use ruff_workspace::resolver::{ + match_exclusion, python_files_in_path, PyprojectConfig, ResolvedFile, +}; use crate::args::CliOverrides; -use crate::cache::{self, Cache}; +use crate::cache::{Cache, PackageCacheMap, PackageCaches}; use crate::diagnostics::Diagnostics; use crate::panic::catch_unwind; @@ -35,159 +36,150 @@ pub(crate) fn check( overrides: &CliOverrides, cache: flags::Cache, noqa: flags::Noqa, - autofix: flags::FixMode, + fix_mode: flags::FixMode, + unsafe_fixes: UnsafeFixes, ) -> Result { // Collect all the Python files to check. let start = Instant::now(); let (paths, resolver) = python_files_in_path(files, pyproject_config, overrides)?; - let duration = start.elapsed(); - debug!("Identified files to lint in: {:?}", duration); + debug!("Identified files to lint in: {:?}", start.elapsed()); if paths.is_empty() { warn_user_once!("No Python files found under the given path(s)"); return Ok(Diagnostics::default()); } - // Initialize the cache. - if cache.into() { - fn init_cache(path: &Path) { - if let Err(e) = cache::init(path) { - error!("Failed to initialize cache at {}: {e:?}", path.display()); - } - } - - match pyproject_config.strategy { - PyprojectDiscoveryStrategy::Fixed => { - init_cache(&pyproject_config.settings.cache_dir); - } - PyprojectDiscoveryStrategy::Hierarchical => { - for settings in - std::iter::once(&pyproject_config.settings).chain(resolver.settings()) - { - init_cache(&settings.cache_dir); - } - } - } - }; - // Discover the package root for each Python file. let package_roots = resolver.package_roots( &paths .iter() .flatten() - .map(ignore::DirEntry::path) + .map(ResolvedFile::path) .collect::>(), pyproject_config, ); // Load the caches. - let caches = bool::from(cache).then(|| { - package_roots - .iter() - .map(|(package, package_root)| package_root.unwrap_or(package)) - .unique() - .par_bridge() - .map(|cache_root| { - let settings = resolver.resolve(cache_root, pyproject_config); - let cache = Cache::open(cache_root.to_path_buf(), settings); - (cache_root, cache) - }) - .collect::>() - }); + let caches = if bool::from(cache) { + Some(PackageCacheMap::init( + pyproject_config, + &package_roots, + &resolver, + )) + } else { + None + }; let start = Instant::now(); - let mut diagnostics: Diagnostics = paths - .par_iter() - .map(|entry| { - match entry { - Ok(entry) => { - let path = entry.path(); - let package = path - .parent() - .and_then(|parent| package_roots.get(parent)) - .and_then(|package| *package); - - let settings = resolver.resolve(path, pyproject_config); - - let cache_root = package.unwrap_or_else(|| path.parent().unwrap_or(path)); - let cache = caches.as_ref().and_then(|caches| { - if let Some(cache) = caches.get(&cache_root) { - Some(cache) - } else { - debug!("No cache found for {}", cache_root.display()); - None + let diagnostics_per_file = paths.par_iter().filter_map(|resolved_file| { + let result = match resolved_file { + Ok(resolved_file) => { + let path = resolved_file.path(); + let package = path + .parent() + .and_then(|parent| package_roots.get(parent)) + .and_then(|package| *package); + + let settings = resolver.resolve(path, pyproject_config); + + if !resolved_file.is_root() + && match_exclusion( + resolved_file.path(), + resolved_file.file_name(), + &settings.linter.exclude, + ) + { + return None; + } + + let cache_root = package.unwrap_or_else(|| path.parent().unwrap_or(path)); + let cache = caches.get(cache_root); + + lint_path( + path, + package, + &settings.linter, + cache, + noqa, + fix_mode, + unsafe_fixes, + ) + .map_err(|e| { + (Some(path.to_path_buf()), { + let mut error = e.to_string(); + for cause in e.chain() { + write!(&mut error, "\n Cause: {cause}").unwrap(); } - }); - - lint_path(path, package, &settings.linter, cache, noqa, autofix).map_err(|e| { - (Some(path.to_owned()), { - let mut error = e.to_string(); - for cause in e.chain() { - write!(&mut error, "\n Cause: {cause}").unwrap(); - } - error - }) + error }) - } - Err(e) => Err(( - if let Error::WithPath { path, .. } = e { - Some(path.clone()) - } else { - None - }, - e.io_error() - .map_or_else(|| e.to_string(), io::Error::to_string), - )), + }) } - .unwrap_or_else(|(path, message)| { - if let Some(path) = &path { - let settings = resolver.resolve(path, pyproject_config); - if settings.linter.rules.enabled(Rule::IOError) { - let dummy = - SourceFileBuilder::new(path.to_string_lossy().as_ref(), "").finish(); - - Diagnostics::new( - vec![Message::from_diagnostic( - Diagnostic::new(IOError { message }, TextRange::default()), - dummy, - TextSize::default(), - )], - ImportMap::default(), - FxHashMap::default(), - ) - } else { - warn!( - "{}{}{} {message}", - "Failed to lint ".bold(), - fs::relativize_path(path).bold(), - ":".bold() - ); - Diagnostics::default() - } + Err(e) => Err(( + if let Error::WithPath { path, .. } = e { + Some(path.clone()) + } else { + None + }, + e.io_error() + .map_or_else(|| e.to_string(), io::Error::to_string), + )), + }; + + Some(result.unwrap_or_else(|(path, message)| { + if let Some(path) = &path { + let settings = resolver.resolve(path, pyproject_config); + if settings.linter.rules.enabled(Rule::IOError) { + let dummy = + SourceFileBuilder::new(path.to_string_lossy().as_ref(), "").finish(); + + Diagnostics::new( + vec![Message::from_diagnostic( + Diagnostic::new(IOError { message }, TextRange::default()), + dummy, + TextSize::default(), + )], + ImportMap::default(), + FxHashMap::default(), + ) } else { - warn!("{} {message}", "Encountered error:".bold()); + warn!( + "{}{}{} {message}", + "Failed to lint ".bold(), + fs::relativize_path(path).bold(), + ":".bold() + ); Diagnostics::default() } - }) - }) - .reduce(Diagnostics::default, |mut acc, item| { - acc += item; - acc - }); + } else { + warn!("{} {message}", "Encountered error:".bold()); + Diagnostics::default() + } + })) + }); - diagnostics.messages.sort(); + // Aggregate the diagnostics of all checked files and count the checked files. + // This can't be a regular for loop because we use `par_iter`. + let (mut all_diagnostics, checked_files) = diagnostics_per_file + .fold( + || (Diagnostics::default(), 0u64), + |(all_diagnostics, checked_files), file_diagnostics| { + (all_diagnostics + file_diagnostics, checked_files + 1) + }, + ) + .reduce( + || (Diagnostics::default(), 0u64), + |a, b| (a.0 + b.0, a.1 + b.1), + ); + + all_diagnostics.messages.sort(); // Store the caches. - if let Some(caches) = caches { - caches - .into_par_iter() - .try_for_each(|(_, cache)| cache.store())?; - } + caches.persist()?; let duration = start.elapsed(); - debug!("Checked {:?} files in: {:?}", paths.len(), duration); + debug!("Checked {:?} files in: {:?}", checked_files, duration); - Ok(diagnostics) + Ok(all_diagnostics) } /// Wraps [`lint_path`](crate::diagnostics::lint_path) in a [`catch_unwind`](std::panic::catch_unwind) and emits @@ -198,10 +190,11 @@ fn lint_path( settings: &LinterSettings, cache: Option<&Cache>, noqa: flags::Noqa, - autofix: flags::FixMode, + fix_mode: flags::FixMode, + unsafe_fixes: UnsafeFixes, ) -> Result { let result = catch_unwind(|| { - crate::diagnostics::lint_path(path, package, settings, cache, noqa, autofix) + crate::diagnostics::lint_path(path, package, settings, cache, noqa, fix_mode, unsafe_fixes) }); match result { @@ -238,6 +231,7 @@ mod test { use ruff_linter::message::{Emitter, EmitterContext, TextEmitter}; use ruff_linter::registry::Rule; + use ruff_linter::settings::types::UnsafeFixes; use ruff_linter::settings::{flags, LinterSettings}; use ruff_workspace::resolver::{PyprojectConfig, PyprojectDiscoveryStrategy}; use ruff_workspace::Settings; @@ -285,6 +279,7 @@ mod test { flags::Cache::Disabled, flags::Noqa::Disabled, flags::FixMode::Generate, + UnsafeFixes::Enabled, ) .unwrap(); let mut output = Vec::new(); diff --git a/crates/ruff_cli/src/commands/check_stdin.rs b/crates/ruff_cli/src/commands/check_stdin.rs index 9b391fb384e40..67f01cd0e8d3a 100644 --- a/crates/ruff_cli/src/commands/check_stdin.rs +++ b/crates/ruff_cli/src/commands/check_stdin.rs @@ -4,7 +4,7 @@ use anyhow::Result; use ruff_linter::packaging; use ruff_linter::settings::flags; -use ruff_workspace::resolver::{python_file_at_path, PyprojectConfig}; +use ruff_workspace::resolver::{match_exclusion, python_file_at_path, PyprojectConfig}; use crate::args::CliOverrides; use crate::diagnostics::{lint_stdin, Diagnostics}; @@ -16,12 +16,20 @@ pub(crate) fn check_stdin( pyproject_config: &PyprojectConfig, overrides: &CliOverrides, noqa: flags::Noqa, - autofix: flags::FixMode, + fix_mode: flags::FixMode, ) -> Result { if let Some(filename) = filename { if !python_file_at_path(filename, pyproject_config, overrides)? { return Ok(Diagnostics::default()); } + + let lint_settings = &pyproject_config.settings.linter; + if filename + .file_name() + .is_some_and(|name| match_exclusion(filename, name, &lint_settings.exclude)) + { + return Ok(Diagnostics::default()); + } } let package_root = filename.and_then(Path::parent).and_then(|path| { packaging::detect_package_root(path, &pyproject_config.settings.linter.namespace_packages) @@ -33,7 +41,7 @@ pub(crate) fn check_stdin( stdin, &pyproject_config.settings, noqa, - autofix, + fix_mode, )?; diagnostics.messages.sort_unstable(); Ok(diagnostics) diff --git a/crates/ruff_cli/src/commands/format.rs b/crates/ruff_cli/src/commands/format.rs index a8a353e670d6c..1947c74169551 100644 --- a/crates/ruff_cli/src/commands/format.rs +++ b/crates/ruff_cli/src/commands/format.rs @@ -1,25 +1,36 @@ use std::fmt::{Display, Formatter}; +use std::fs::File; use std::io; +use std::io::{stderr, stdout, Write}; use std::path::{Path, PathBuf}; use std::time::Instant; use anyhow::Result; use colored::Colorize; -use log::error; +use itertools::Itertools; +use log::{error, warn}; use rayon::iter::Either::{Left, Right}; -use rayon::iter::{IntoParallelIterator, ParallelIterator}; +use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use thiserror::Error; use tracing::debug; +use ruff_diagnostics::SourceMap; use ruff_linter::fs; use ruff_linter::logging::LogLevel; +use ruff_linter::registry::Rule; +use ruff_linter::rules::flake8_quotes::settings::Quote; +use ruff_linter::source_kind::{SourceError, SourceKind}; use ruff_linter::warn_user_once; use ruff_python_ast::{PySourceType, SourceType}; -use ruff_python_formatter::{format_module, FormatModuleError}; -use ruff_workspace::resolver::python_files_in_path; +use ruff_python_formatter::{format_module_source, FormatModuleError, QuoteStyle}; +use ruff_text_size::{TextLen, TextRange, TextSize}; +use ruff_workspace::resolver::{ + match_exclusion, python_files_in_path, PyprojectConfig, ResolvedFile, Resolver, +}; use ruff_workspace::FormatterSettings; use crate::args::{CliOverrides, FormatArguments}; +use crate::cache::{Cache, FileCacheKey, PackageCacheMap, PackageCaches}; use crate::panic::{catch_unwind, PanicError}; use crate::resolve::resolve; use crate::ExitStatus; @@ -30,6 +41,20 @@ pub(crate) enum FormatMode { Write, /// Check if the file is formatted, but do not write the formatted contents back. Check, + /// Check if the file is formatted, show a diff if not. + Diff, +} + +impl FormatMode { + pub(crate) fn from_cli(cli: &FormatArguments) -> Self { + if cli.diff { + FormatMode::Diff + } else if cli.check { + FormatMode::Check + } else { + FormatMode::Write + } + } } /// Format a set of files, and return the exit status. @@ -44,11 +69,7 @@ pub(crate) fn format( overrides, cli.stdin_filename.as_deref(), )?; - let mode = if cli.check { - FormatMode::Check - } else { - FormatMode::Write - }; + let mode = FormatMode::from_cli(cli); let (paths, resolver) = python_files_in_path(&cli.files, &pyproject_config, overrides)?; if paths.is_empty() { @@ -56,36 +77,87 @@ pub(crate) fn format( return Ok(ExitStatus::Success); } + warn_incompatible_formatter_settings(&pyproject_config, Some(&resolver)); + + // Discover the package root for each Python file. + let package_roots = resolver.package_roots( + &paths + .iter() + .flatten() + .map(ResolvedFile::path) + .collect::>(), + &pyproject_config, + ); + + let caches = if cli.no_cache { + None + } else { + // `--no-cache` doesn't respect code changes, and so is often confusing during + // development. + #[cfg(debug_assertions)] + crate::warn_user!("Detected debug build without --no-cache."); + + Some(PackageCacheMap::init( + &pyproject_config, + &package_roots, + &resolver, + )) + }; + let start = Instant::now(); - let (results, errors): (Vec<_>, Vec<_>) = paths - .into_par_iter() + let (results, mut errors): (Vec<_>, Vec<_>) = paths + .par_iter() .filter_map(|entry| { match entry { - Ok(entry) => { - let path = entry.path(); - - let SourceType::Python( - source_type @ (PySourceType::Python | PySourceType::Stub), - ) = SourceType::from(path) - else { + Ok(resolved_file) => { + let path = resolved_file.path(); + let SourceType::Python(source_type) = SourceType::from(&path) else { // Ignore any non-Python files. return None; }; let resolved_settings = resolver.resolve(path, &pyproject_config); + // Ignore files that are excluded from formatting + if !resolved_file.is_root() + && match_exclusion( + path, + resolved_file.file_name(), + &resolved_settings.formatter.exclude, + ) + { + return None; + } + + let package = path + .parent() + .and_then(|parent| package_roots.get(parent).copied()) + .flatten(); + let cache_root = package.unwrap_or_else(|| path.parent().unwrap_or(path)); + let cache = caches.get(cache_root); + Some( match catch_unwind(|| { - format_path(path, &resolved_settings.formatter, source_type, mode) + format_path( + path, + &resolved_settings.formatter, + source_type, + mode, + cache, + ) }) { - Ok(inner) => inner, - Err(error) => { - Err(FormatCommandError::Panic(Some(path.to_path_buf()), error)) - } + Ok(inner) => inner.map(|result| FormatPathResult { + path: resolved_file.path().to_path_buf(), + result, + }), + Err(error) => Err(FormatCommandError::Panic( + Some(resolved_file.path().to_path_buf()), + error, + )), }, ) } - Err(err) => Some(Err(FormatCommandError::Ignore(err))), + Err(err) => Some(Err(FormatCommandError::Ignore(err.clone()))), } }) .partition_map(|result| match result { @@ -100,18 +172,33 @@ pub(crate) fn format( duration ); + caches.persist()?; + // Report on any errors. + errors.sort_unstable_by(|a, b| a.path().cmp(&b.path())); + for error in &errors { error!("{error}"); } - let summary = FormatResultSummary::new(results, mode); + let results = FormatResults::new(results.as_slice(), mode); + match mode { + FormatMode::Write => {} + FormatMode::Check => { + results.write_changed(&mut stdout().lock())?; + } + FormatMode::Diff => { + results.write_diff(&mut stdout().lock())?; + } + } // Report on the formatting changes. if log_level >= LogLevel::Default { - #[allow(clippy::print_stdout)] - { - println!("{summary}"); + if mode.is_diff() { + // Allow piping the diff to e.g. a file by writing the summary to stderr + results.write_summary(&mut stderr().lock())?; + } else { + results.write_summary(&mut stdout().lock())?; } } @@ -123,9 +210,9 @@ pub(crate) fn format( Ok(ExitStatus::Error) } } - FormatMode::Check => { + FormatMode::Check | FormatMode::Diff => { if errors.is_empty() { - if summary.formatted > 0 { + if results.any_formatted() { Ok(ExitStatus::Failure) } else { Ok(ExitStatus::Success) @@ -138,101 +225,327 @@ pub(crate) fn format( } /// Format the file at the given [`Path`]. -#[tracing::instrument(skip_all, fields(path = %path.display()))] -fn format_path( +#[tracing::instrument(level="debug", skip_all, fields(path = %path.display()))] +pub(crate) fn format_path( path: &Path, settings: &FormatterSettings, source_type: PySourceType, mode: FormatMode, -) -> Result { - let unformatted = std::fs::read_to_string(path) - .map_err(|err| FormatCommandError::Read(Some(path.to_path_buf()), err))?; + cache: Option<&Cache>, +) -> Result { + if let Some(cache) = cache { + let relative_path = cache + .relative_path(path) + .expect("wrong package cache for file"); - let options = settings.to_format_options(source_type, &unformatted); - debug!("Formatting {} with {:?}", path.display(), options); + if let Ok(cache_key) = FileCacheKey::from_path(path) { + if cache.is_formatted(relative_path, &cache_key) { + return Ok(FormatResult::Unchanged); + } + } + } - let formatted = format_module(&unformatted, options) - .map_err(|err| FormatCommandError::FormatModule(Some(path.to_path_buf()), err))?; + // Extract the sources from the file. + let unformatted = match SourceKind::from_path(path, source_type) { + Ok(Some(source_kind)) => source_kind, + // Non Python Jupyter notebook + Ok(None) => return Ok(FormatResult::Skipped), + Err(err) => { + return Err(FormatCommandError::Read(Some(path.to_path_buf()), err)); + } + }; - let formatted = formatted.as_code(); - if formatted.len() == unformatted.len() && formatted == unformatted { - Ok(FormatCommandResult::Unchanged) - } else { - if mode.is_write() { - std::fs::write(path, formatted.as_bytes()) - .map_err(|err| FormatCommandError::Write(Some(path.to_path_buf()), err))?; + // Format the source. + let format_result = match format_source(&unformatted, source_type, Some(path), settings)? { + FormattedSource::Formatted(formatted) => match mode { + FormatMode::Write => { + let mut writer = File::create(path).map_err(|err| { + FormatCommandError::Write(Some(path.to_path_buf()), err.into()) + })?; + formatted + .write(&mut writer) + .map_err(|err| FormatCommandError::Write(Some(path.to_path_buf()), err))?; + + if let Some(cache) = cache { + if let Ok(cache_key) = FileCacheKey::from_path(path) { + let relative_path = cache + .relative_path(path) + .expect("wrong package cache for file"); + cache.set_formatted(relative_path.to_path_buf(), &cache_key); + } + } + + FormatResult::Formatted + } + FormatMode::Check => FormatResult::Formatted, + FormatMode::Diff => FormatResult::Diff { + unformatted, + formatted, + }, + }, + FormattedSource::Unchanged => { + if let Some(cache) = cache { + if let Ok(cache_key) = FileCacheKey::from_path(path) { + let relative_path = cache + .relative_path(path) + .expect("wrong package cache for file"); + cache.set_formatted(relative_path.to_path_buf(), &cache_key); + } + } + + FormatResult::Unchanged + } + }; + + Ok(format_result) +} + +#[derive(Debug)] +pub(crate) enum FormattedSource { + /// The source was formatted, and the [`SourceKind`] contains the transformed source code. + Formatted(SourceKind), + /// The source was unchanged. + Unchanged, +} + +impl From for FormatResult { + fn from(value: FormattedSource) -> Self { + match value { + FormattedSource::Formatted(_) => FormatResult::Formatted, + FormattedSource::Unchanged => FormatResult::Unchanged, + } + } +} + +/// Format a [`SourceKind`], returning the transformed [`SourceKind`], or `None` if the source was +/// unchanged. +pub(crate) fn format_source( + source_kind: &SourceKind, + source_type: PySourceType, + path: Option<&Path>, + settings: &FormatterSettings, +) -> Result { + match source_kind { + SourceKind::Python(unformatted) => { + let options = settings.to_format_options(source_type, unformatted); + + let formatted = format_module_source(unformatted, options) + .map_err(|err| FormatCommandError::Format(path.map(Path::to_path_buf), err))?; + + let formatted = formatted.into_code(); + if formatted.len() == unformatted.len() && formatted == *unformatted { + Ok(FormattedSource::Unchanged) + } else { + Ok(FormattedSource::Formatted(SourceKind::Python(formatted))) + } + } + SourceKind::IpyNotebook(notebook) => { + if !notebook.is_python_notebook() { + return Ok(FormattedSource::Unchanged); + } + + let options = settings.to_format_options(source_type, notebook.source_code()); + + let mut output: Option = None; + let mut last: Option = None; + let mut source_map = SourceMap::default(); + + // Format each cell individually. + for (start, end) in notebook.cell_offsets().iter().tuple_windows::<(_, _)>() { + let range = TextRange::new(*start, *end); + let unformatted = ¬ebook.source_code()[range]; + + // Format the cell. + let formatted = format_module_source(unformatted, options.clone()) + .map_err(|err| FormatCommandError::Format(path.map(Path::to_path_buf), err))?; + + // If the cell is unchanged, skip it. + let formatted = formatted.as_code(); + if formatted.len() == unformatted.len() && formatted == unformatted { + continue; + } + + // If this is the first newly-formatted cell, initialize the output. + let output = output + .get_or_insert_with(|| String::with_capacity(notebook.source_code().len())); + + // Add all contents from `last` to the current cell. + let slice = ¬ebook.source_code() + [TextRange::new(last.unwrap_or_default(), range.start())]; + output.push_str(slice); + + // Add the start source marker for the cell. + source_map.push_marker(*start, output.text_len()); + + // Add the cell itself. + output.push_str(formatted); + + // Add the end source marker for the added cell. + source_map.push_marker(*end, output.text_len()); + + // Track that the cell was formatted. + last = Some(*end); + } + + // If the file was unchanged, return `None`. + let (Some(mut output), Some(last)) = (output, last) else { + return Ok(FormattedSource::Unchanged); + }; + + // Add the remaining content. + let slice = ¬ebook.source_code()[usize::from(last)..]; + output.push_str(slice); + + // Update the notebook. + let mut formatted = notebook.clone(); + formatted.update(&source_map, output); + + Ok(FormattedSource::Formatted(SourceKind::IpyNotebook( + formatted, + ))) } - Ok(FormatCommandResult::Formatted) } } -#[derive(Debug, Clone, Copy, is_macro::Is)] -pub(crate) enum FormatCommandResult { +/// The result of an individual formatting operation. +#[derive(Debug, Clone, is_macro::Is)] +pub(crate) enum FormatResult { /// The file was formatted. Formatted, + /// The file was formatted, [`SourceKind`] contains the formatted code + Diff { + unformatted: SourceKind, + formatted: SourceKind, + }, /// The file was unchanged, as the formatted contents matched the existing contents. Unchanged, + + /// Skipped formatting because its an unsupported file format + Skipped, } +/// The coupling of a [`FormatResult`] with the path of the file that was analyzed. #[derive(Debug)] -struct FormatResultSummary { +struct FormatPathResult { + path: PathBuf, + result: FormatResult, +} + +/// The results of formatting a set of files +#[derive(Debug)] +struct FormatResults<'a> { + /// The individual formatting results. + results: &'a [FormatPathResult], /// The format mode that was used. mode: FormatMode, - /// The number of files that were formatted. - formatted: usize, - /// The number of files that were unchanged. - unchanged: usize, } -impl FormatResultSummary { - fn new(diagnostics: Vec, mode: FormatMode) -> Self { - let mut summary = Self { - mode, - formatted: 0, - unchanged: 0, - }; - for diagnostic in diagnostics { - match diagnostic { - FormatCommandResult::Formatted => summary.formatted += 1, - FormatCommandResult::Unchanged => summary.unchanged += 1, - } +impl<'a> FormatResults<'a> { + fn new(results: &'a [FormatPathResult], mode: FormatMode) -> Self { + Self { results, mode } + } + + /// Returns `true` if any of the files require formatting. + fn any_formatted(&self) -> bool { + self.results.iter().any(|result| match result.result { + FormatResult::Formatted | FormatResult::Diff { .. } => true, + FormatResult::Unchanged | FormatResult::Skipped => false, + }) + } + + /// Write a diff of the formatting changes to the given writer. + fn write_diff(&self, f: &mut impl Write) -> io::Result<()> { + for (path, unformatted, formatted) in self + .results + .iter() + .filter_map(|result| { + if let FormatResult::Diff { + unformatted, + formatted, + } = &result.result + { + Some((result.path.as_path(), unformatted, formatted)) + } else { + None + } + }) + .sorted_unstable_by_key(|(path, _, _)| *path) + { + unformatted.diff(formatted, Some(path), f)?; } - summary + + Ok(()) } -} -impl Display for FormatResultSummary { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - if self.formatted > 0 && self.unchanged > 0 { - write!( + /// Write a list of the files that would be changed to the given writer. + fn write_changed(&self, f: &mut impl Write) -> io::Result<()> { + for path in self + .results + .iter() + .filter_map(|result| { + if result.result.is_formatted() { + Some(result.path.as_path()) + } else { + None + } + }) + .sorted_unstable() + { + writeln!(f, "Would reformat: {}", fs::relativize_path(path).bold())?; + } + + Ok(()) + } + + /// Write a summary of the formatting results to the given writer. + fn write_summary(&self, f: &mut impl Write) -> io::Result<()> { + // Compute the number of changed and unchanged files. + let mut changed = 0u32; + let mut unchanged = 0u32; + for result in self.results { + match &result.result { + FormatResult::Formatted => { + changed += 1; + } + FormatResult::Unchanged => unchanged += 1, + FormatResult::Diff { .. } => { + changed += 1; + } + FormatResult::Skipped => {} + } + } + + // Write out a summary of the formatting results. + if changed > 0 && unchanged > 0 { + writeln!( f, "{} file{} {}, {} file{} left unchanged", - self.formatted, - if self.formatted == 1 { "" } else { "s" }, + changed, + if changed == 1 { "" } else { "s" }, match self.mode { FormatMode::Write => "reformatted", - FormatMode::Check => "would be reformatted", + FormatMode::Check | FormatMode::Diff => "would be reformatted", }, - self.unchanged, - if self.unchanged == 1 { "" } else { "s" }, + unchanged, + if unchanged == 1 { "" } else { "s" }, ) - } else if self.formatted > 0 { - write!( + } else if changed > 0 { + writeln!( f, "{} file{} {}", - self.formatted, - if self.formatted == 1 { "" } else { "s" }, + changed, + if changed == 1 { "" } else { "s" }, match self.mode { FormatMode::Write => "reformatted", - FormatMode::Check => "would be reformatted", + FormatMode::Check | FormatMode::Diff => "would be reformatted", } ) - } else if self.unchanged > 0 { - write!( + } else if unchanged > 0 { + writeln!( f, "{} file{} left unchanged", - self.unchanged, - if self.unchanged == 1 { "" } else { "s" }, + unchanged, + if unchanged == 1 { "" } else { "s" }, ) } else { Ok(()) @@ -244,10 +557,30 @@ impl Display for FormatResultSummary { #[derive(Error, Debug)] pub(crate) enum FormatCommandError { Ignore(#[from] ignore::Error), - Read(Option, io::Error), - Write(Option, io::Error), - FormatModule(Option, FormatModuleError), Panic(Option, PanicError), + Read(Option, SourceError), + Format(Option, FormatModuleError), + Write(Option, SourceError), + Diff(Option, io::Error), +} + +impl FormatCommandError { + fn path(&self) -> Option<&Path> { + match self { + Self::Ignore(err) => { + if let ignore::Error::WithPath { path, .. } = err { + Some(path.as_path()) + } else { + None + } + } + Self::Panic(path, _) + | Self::Read(path, _) + | Self::Format(path, _) + | Self::Write(path, _) + | Self::Diff(path, _) => path.as_deref(), + } + } } impl Display for FormatCommandError { @@ -300,7 +633,7 @@ impl Display for FormatCommandError { write!(f, "{}{} {err}", "Failed to write".bold(), ":".bold()) } } - Self::FormatModule(path, err) => { + Self::Format(path, err) => { if let Some(path) = path { write!( f, @@ -313,6 +646,24 @@ impl Display for FormatCommandError { write!(f, "{}{} {err}", "Failed to format".bold(), ":".bold()) } } + Self::Diff(path, err) => { + if let Some(path) = path { + write!( + f, + "{}{}{} {err}", + "Failed to generate diff for ".bold(), + fs::relativize_path(path).bold(), + ":".bold() + ) + } else { + write!( + f, + "{}{} {err}", + "Failed to generate diff".bold(), + ":".bold() + ) + } + } Self::Panic(path, err) => { let message = r#"This indicates a bug in Ruff. If you could open an issue at: @@ -339,3 +690,120 @@ impl Display for FormatCommandError { } } } + +pub(super) fn warn_incompatible_formatter_settings( + pyproject_config: &PyprojectConfig, + resolver: Option<&Resolver>, +) { + for setting in std::iter::once(&pyproject_config.settings) + .chain(resolver.iter().flat_map(|resolver| resolver.settings())) + { + let mut incompatible_rules = Vec::new(); + + for rule in [ + // The formatter might collapse implicit string concatenation on a single line. + Rule::SingleLineImplicitStringConcatenation, + // Flags missing trailing commas when all arguments are on its own line: + // ```python + // def args( + // aaaaaaaa, bbbbbbbbb, cccccccccc, ddddddddd, eeeeeeee, ffffff, gggggggggggg, hhhh + // ): + // pass + // ``` + Rule::MissingTrailingComma, + ] { + if setting.linter.rules.enabled(rule) { + incompatible_rules.push(rule); + } + } + + // Rules asserting for space indentation + if setting.formatter.indent_style.is_tab() { + for rule in [Rule::TabIndentation, Rule::IndentWithSpaces] { + if setting.linter.rules.enabled(rule) { + incompatible_rules.push(rule); + } + } + } + + // Rules asserting for indent-width=4 + if setting.formatter.indent_width.value() != 4 { + for rule in [ + Rule::IndentationWithInvalidMultiple, + Rule::IndentationWithInvalidMultipleComment, + ] { + if setting.linter.rules.enabled(rule) { + incompatible_rules.push(rule); + } + } + } + + if !incompatible_rules.is_empty() { + let mut rule_names: Vec<_> = incompatible_rules + .into_iter() + .map(|rule| format!("`{}`", rule.noqa_code())) + .collect(); + rule_names.sort(); + warn!("The following rules may cause conflicts when used with the formatter: {}. To avoid unexpected behavior, we recommend disabling these rules, either by removing them from the `select` or `extend-select` configuration, or adding then to the `ignore` configuration.", rule_names.join(", ")); + } + + // Rules with different quote styles. + if setting + .linter + .rules + .any_enabled(&[Rule::BadQuotesInlineString, Rule::AvoidableEscapedQuote]) + { + match ( + setting.linter.flake8_quotes.inline_quotes, + setting.formatter.quote_style, + ) { + (Quote::Double, QuoteStyle::Single) => { + warn!("The `flake8-quotes.inline-quotes=\"double\"` option is incompatible with the formatter's `format.quote-style=\"single\"`. We recommend disabling `Q000` and `Q003` when using the formatter, which enforces a consistent quote style. Alternatively, set both options to either `\"single\"` or `\"double\"`."); + } + (Quote::Single, QuoteStyle::Double) => { + warn!("The `flake8-quotes.inline-quotes=\"single\"` option is incompatible with the formatter's `format.quote-style=\"double\"`. We recommend disabling `Q000` and `Q003` when using the formatter, which enforces a consistent quote style. Alternatively, set both options to either `\"single\"` or `\"double\"`."); + } + _ => {} + } + } + + if setting.linter.rules.enabled(Rule::BadQuotesMultilineString) + && setting.linter.flake8_quotes.multiline_quotes == Quote::Single + { + warn!("The `flake8-quotes.multiline-quotes=\"single\"` option is incompatible with the formatter. We recommend disabling `Q001` when using the formatter, which enforces double quotes for multiline strings. Alternatively, set the `flake8-quotes.multiline-quotes` option to `\"double\"`.`"); + } + + if setting.linter.rules.enabled(Rule::BadQuotesDocstring) + && setting.linter.flake8_quotes.docstring_quotes == Quote::Single + { + warn!("The `flake8-quotes.multiline-quotes=\"single\"` option is incompatible with the formatter. We recommend disabling `Q002` when using the formatter, which enforces double quotes for docstrings. Alternatively, set the `flake8-quotes.docstring-quotes` option to `\"double\"`.`"); + } + + if setting.linter.rules.enabled(Rule::UnsortedImports) { + // The formatter removes empty lines if the value is larger than 2 but always inserts a empty line after imports. + // Two empty lines are okay because `isort` only uses this setting for top-level imports (not in nested blocks). + if !matches!(setting.linter.isort.lines_after_imports, 1 | 2 | -1) { + warn!("The isort option `isort.lines-after-imports` with a value other than `-1`, `1` or `2` is incompatible with the formatter. To avoid unexpected behavior, we recommend setting the option to one of: `2`, `1`, or `-1` (default)."); + } + + // Values larger than two get reduced to one line by the formatter if the import is in a nested block. + if setting.linter.isort.lines_between_types > 1 { + warn!("The isort option `isort.lines-between-types` with a value greater than 1 is incompatible with the formatter. To avoid unexpected behavior, we recommend setting the option to one of: `1` or `0` (default)."); + } + + // isort inserts a trailing comma which the formatter preserves, but only if `skip-magic-trailing-comma` isn't false. + // This isn't relevant when using `force-single-line`, since isort will never include a trailing comma in that case. + if setting.formatter.magic_trailing_comma.is_ignore() + && !setting.linter.isort.force_single_line + { + if setting.linter.isort.force_wrap_aliases { + warn!("The isort option `isort.force-wrap-aliases` is incompatible with the formatter `format.skip-magic-trailing-comma=true` option. To avoid unexpected behavior, we recommend either setting `isort.force-wrap-aliases=false` or `format.skip-magic-trailing-comma=false`."); + } + + if setting.linter.isort.split_on_trailing_comma { + warn!("The isort option `isort.split-on-trailing-comma` is incompatible with the formatter `format.skip-magic-trailing-comma=true` option. To avoid unexpected behavior, we recommend either setting `isort.split-on-trailing-comma=false` or `format.skip-magic-trailing-comma=false`."); + } + } + } + } +} diff --git a/crates/ruff_cli/src/commands/format_stdin.rs b/crates/ruff_cli/src/commands/format_stdin.rs index ed897a3111e20..082dfedfb00da 100644 --- a/crates/ruff_cli/src/commands/format_stdin.rs +++ b/crates/ruff_cli/src/commands/format_stdin.rs @@ -1,16 +1,19 @@ -use std::io::{stdout, Write}; +use std::io::stdout; use std::path::Path; use anyhow::Result; -use log::warn; +use log::error; -use ruff_python_ast::PySourceType; -use ruff_python_formatter::format_module; -use ruff_workspace::resolver::python_file_at_path; +use ruff_linter::source_kind::SourceKind; +use ruff_python_ast::{PySourceType, SourceType}; +use ruff_workspace::resolver::{match_exclusion, python_file_at_path}; use ruff_workspace::FormatterSettings; use crate::args::{CliOverrides, FormatArguments}; -use crate::commands::format::{FormatCommandError, FormatCommandResult, FormatMode}; +use crate::commands::format::{ + format_source, warn_incompatible_formatter_settings, FormatCommandError, FormatMode, + FormatResult, FormattedSource, +}; use crate::resolve::resolve; use crate::stdin::read_from_stdin; use crate::ExitStatus; @@ -23,25 +26,41 @@ pub(crate) fn format_stdin(cli: &FormatArguments, overrides: &CliOverrides) -> R overrides, cli.stdin_filename.as_deref(), )?; - let mode = if cli.check { - FormatMode::Check - } else { - FormatMode::Write - }; + + warn_incompatible_formatter_settings(&pyproject_config, None); + + let mode = FormatMode::from_cli(cli); if let Some(filename) = cli.stdin_filename.as_deref() { if !python_file_at_path(filename, &pyproject_config, overrides)? { return Ok(ExitStatus::Success); } + + let format_settings = &pyproject_config.settings.formatter; + if filename + .file_name() + .is_some_and(|name| match_exclusion(filename, name, &format_settings.exclude)) + { + return Ok(ExitStatus::Success); + } } - // Format the file. let path = cli.stdin_filename.as_deref(); - match format_source(path, &pyproject_config.settings.formatter, mode) { + let SourceType::Python(source_type) = path.map(SourceType::from).unwrap_or_default() else { + return Ok(ExitStatus::Success); + }; + + // Format the file. + match format_source_code( + path, + &pyproject_config.settings.formatter, + source_type, + mode, + ) { Ok(result) => match mode { FormatMode::Write => Ok(ExitStatus::Success), - FormatMode::Check => { + FormatMode::Check | FormatMode::Diff => { if result.is_formatted() { Ok(ExitStatus::Failure) } else { @@ -50,39 +69,59 @@ pub(crate) fn format_stdin(cli: &FormatArguments, overrides: &CliOverrides) -> R } }, Err(err) => { - warn!("{err}"); + error!("{err}"); Ok(ExitStatus::Error) } } } /// Format source code read from `stdin`. -fn format_source( +fn format_source_code( path: Option<&Path>, settings: &FormatterSettings, + source_type: PySourceType, mode: FormatMode, -) -> Result { - let unformatted = read_from_stdin() - .map_err(|err| FormatCommandError::Read(path.map(Path::to_path_buf), err))?; - - let options = settings.to_format_options( - path.map(PySourceType::from).unwrap_or_default(), - &unformatted, - ); - - let formatted = format_module(&unformatted, options) - .map_err(|err| FormatCommandError::FormatModule(path.map(Path::to_path_buf), err))?; - let formatted = formatted.as_code(); - - if mode.is_write() { - stdout() - .lock() - .write_all(formatted.as_bytes()) - .map_err(|err| FormatCommandError::Write(path.map(Path::to_path_buf), err))?; - } - if formatted.len() == unformatted.len() && formatted == unformatted { - Ok(FormatCommandResult::Unchanged) - } else { - Ok(FormatCommandResult::Formatted) +) -> Result { + // Read the source from stdin. + let source_code = read_from_stdin() + .map_err(|err| FormatCommandError::Read(path.map(Path::to_path_buf), err.into()))?; + + let source_kind = match SourceKind::from_source_code(source_code, source_type) { + Ok(Some(source_kind)) => source_kind, + Ok(None) => return Ok(FormatResult::Unchanged), + Err(err) => { + return Err(FormatCommandError::Read(path.map(Path::to_path_buf), err)); + } + }; + + // Format the source. + let formatted = format_source(&source_kind, source_type, path, settings)?; + + match &formatted { + FormattedSource::Formatted(formatted) => match mode { + FormatMode::Write => { + let mut writer = stdout().lock(); + formatted + .write(&mut writer) + .map_err(|err| FormatCommandError::Write(path.map(Path::to_path_buf), err))?; + } + FormatMode::Check => {} + FormatMode::Diff => { + source_kind + .diff(formatted, path, &mut stdout().lock()) + .map_err(|err| FormatCommandError::Diff(path.map(Path::to_path_buf), err))?; + } + }, + FormattedSource::Unchanged => { + // Write to stdout regardless of whether the source was formatted + if mode.is_write() { + let mut writer = stdout().lock(); + source_kind + .write(&mut writer) + .map_err(|err| FormatCommandError::Write(path.map(Path::to_path_buf), err))?; + } + } } + + Ok(FormatResult::from(formatted)) } diff --git a/crates/ruff_cli/src/commands/mod.rs b/crates/ruff_cli/src/commands/mod.rs index 794a58788b352..554a7a454add2 100644 --- a/crates/ruff_cli/src/commands/mod.rs +++ b/crates/ruff_cli/src/commands/mod.rs @@ -9,3 +9,4 @@ pub(crate) mod linter; pub(crate) mod rule; pub(crate) mod show_files; pub(crate) mod show_settings; +pub(crate) mod version; diff --git a/crates/ruff_cli/src/commands/rule.rs b/crates/ruff_cli/src/commands/rule.rs index f9b9f86c957dc..8df1eacb1ec2f 100644 --- a/crates/ruff_cli/src/commands/rule.rs +++ b/crates/ruff_cli/src/commands/rule.rs @@ -5,7 +5,7 @@ use serde::ser::SerializeSeq; use serde::{Serialize, Serializer}; use strum::IntoEnumIterator; -use ruff_diagnostics::AutofixKind; +use ruff_diagnostics::FixAvailability; use ruff_linter::registry::{Linter, Rule, RuleNamespace}; use crate::args::HelpFormat; @@ -17,7 +17,7 @@ struct Explanation<'a> { linter: &'a str, summary: &'a str, message_formats: &'a [&'a str], - autofix: String, + fix: String, explanation: Option<&'a str>, preview: bool, } @@ -26,16 +26,16 @@ impl<'a> Explanation<'a> { fn from_rule(rule: &'a Rule) -> Self { let code = rule.noqa_code().to_string(); let (linter, _) = Linter::parse_code(&code).unwrap(); - let autofix = rule.autofixable().to_string(); + let fix = rule.fixable().to_string(); Self { name: rule.as_ref(), code, linter: linter.name(), summary: rule.message_formats()[0], message_formats: rule.message_formats(), - autofix, + fix, explanation: rule.explanation(), - preview: rule.is_preview(), + preview: rule.is_preview() || rule.is_nursery(), } } } @@ -51,14 +51,17 @@ fn format_rule_text(rule: Rule) -> String { output.push('\n'); output.push('\n'); - let autofix = rule.autofixable(); - if matches!(autofix, AutofixKind::Always | AutofixKind::Sometimes) { - output.push_str(&autofix.to_string()); + let fix_availability = rule.fixable(); + if matches!( + fix_availability, + FixAvailability::Always | FixAvailability::Sometimes + ) { + output.push_str(&fix_availability.to_string()); output.push('\n'); output.push('\n'); } - if rule.is_preview() { + if rule.is_preview() || rule.is_nursery() { output.push_str( r#"This rule is in preview and is not stable. The `--preview` flag is required for use."#, ); diff --git a/crates/ruff_cli/src/commands/show_files.rs b/crates/ruff_cli/src/commands/show_files.rs index f92998e57a855..201c97f75de20 100644 --- a/crates/ruff_cli/src/commands/show_files.rs +++ b/crates/ruff_cli/src/commands/show_files.rs @@ -5,7 +5,7 @@ use anyhow::Result; use itertools::Itertools; use ruff_linter::warn_user_once; -use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig}; +use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig, ResolvedFile}; use crate::args::CliOverrides; @@ -25,12 +25,13 @@ pub(crate) fn show_files( } // Print the list of files. - for entry in paths - .iter() + for path in paths + .into_iter() .flatten() - .sorted_by(|a, b| a.path().cmp(b.path())) + .map(ResolvedFile::into_path) + .sorted_unstable() { - writeln!(writer, "{}", entry.path().to_string_lossy())?; + writeln!(writer, "{}", path.to_string_lossy())?; } Ok(()) diff --git a/crates/ruff_cli/src/commands/show_settings.rs b/crates/ruff_cli/src/commands/show_settings.rs index 163981a523150..baeed55a08f36 100644 --- a/crates/ruff_cli/src/commands/show_settings.rs +++ b/crates/ruff_cli/src/commands/show_settings.rs @@ -4,7 +4,7 @@ use std::path::PathBuf; use anyhow::{bail, Result}; use itertools::Itertools; -use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig}; +use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig, ResolvedFile}; use crate::args::CliOverrides; @@ -19,16 +19,17 @@ pub(crate) fn show_settings( let (paths, resolver) = python_files_in_path(files, pyproject_config, overrides)?; // Print the list of files. - let Some(entry) = paths - .iter() + let Some(path) = paths + .into_iter() .flatten() - .sorted_by(|a, b| a.path().cmp(b.path())) + .map(ResolvedFile::into_path) + .sorted_unstable() .next() else { bail!("No files found under the given path"); }; - let path = entry.path(); - let settings = resolver.resolve(path, pyproject_config); + + let settings = resolver.resolve(&path, pyproject_config); writeln!(writer, "Resolved settings for: {path:?}")?; if let Some(settings_path) = pyproject_config.path.as_ref() { diff --git a/crates/ruff_cli/src/commands/version.rs b/crates/ruff_cli/src/commands/version.rs new file mode 100644 index 0000000000000..729d0f15d5e9e --- /dev/null +++ b/crates/ruff_cli/src/commands/version.rs @@ -0,0 +1,21 @@ +use std::io::{self, BufWriter, Write}; + +use anyhow::Result; + +use crate::args::HelpFormat; + +/// Display version information +pub(crate) fn version(output_format: HelpFormat) -> Result<()> { + let mut stdout = BufWriter::new(io::stdout().lock()); + let version_info = crate::version::version(); + + match output_format { + HelpFormat::Text => { + writeln!(stdout, "ruff {}", &version_info)?; + } + HelpFormat::Json => { + serde_json::to_writer_pretty(stdout, &version_info)?; + } + }; + Ok(()) +} diff --git a/crates/ruff_cli/src/diagnostics.rs b/crates/ruff_cli/src/diagnostics.rs index 13de795a86b8b..b2cf812e09bff 100644 --- a/crates/ruff_cli/src/diagnostics.rs +++ b/crates/ruff_cli/src/diagnostics.rs @@ -1,69 +1,37 @@ #![cfg_attr(target_family = "wasm", allow(dead_code))] -use std::fs::{write, File}; +use std::fs::File; use std::io; -use std::io::{BufWriter, Write}; -use std::ops::AddAssign; -#[cfg(unix)] -use std::os::unix::fs::PermissionsExt; +use std::ops::{Add, AddAssign}; use std::path::Path; -use anyhow::{anyhow, Context, Result}; +use anyhow::{Context, Result}; use colored::Colorize; -use filetime::FileTime; use log::{debug, error, warn}; use rustc_hash::FxHashMap; -use similar::TextDiff; -use thiserror::Error; +use crate::cache::{Cache, FileCacheKey, LintCacheData}; use ruff_diagnostics::Diagnostic; use ruff_linter::linter::{lint_fix, lint_only, FixTable, FixerResult, LinterResult}; use ruff_linter::logging::DisplayParseError; use ruff_linter::message::Message; use ruff_linter::pyproject_toml::lint_pyproject_toml; use ruff_linter::registry::AsRule; +use ruff_linter::settings::types::UnsafeFixes; use ruff_linter::settings::{flags, LinterSettings}; -use ruff_linter::source_kind::SourceKind; +use ruff_linter::source_kind::{SourceError, SourceKind}; use ruff_linter::{fs, IOError, SyntaxError}; -use ruff_macros::CacheKey; -use ruff_notebook::{Cell, Notebook, NotebookError, NotebookIndex}; +use ruff_notebook::{Notebook, NotebookError, NotebookIndex}; use ruff_python_ast::imports::ImportMap; -use ruff_python_ast::{PySourceType, SourceType, TomlSourceType}; +use ruff_python_ast::{SourceType, TomlSourceType}; use ruff_source_file::{LineIndex, SourceCode, SourceFileBuilder}; use ruff_text_size::{TextRange, TextSize}; use ruff_workspace::Settings; -use crate::cache::Cache; - -#[derive(CacheKey)] -pub(crate) struct FileCacheKey { - /// Timestamp when the file was last modified before the (cached) check. - file_last_modified: FileTime, - /// Permissions of the file before the (cached) check. - file_permissions_mode: u32, -} - -impl FileCacheKey { - fn from_path(path: &Path) -> io::Result { - // Construct a cache key for the file - let metadata = path.metadata()?; - - #[cfg(unix)] - let permissions = metadata.permissions().mode(); - #[cfg(windows)] - let permissions: u32 = metadata.permissions().readonly().into(); - - Ok(FileCacheKey { - file_last_modified: FileTime::from_last_modification_time(&metadata), - file_permissions_mode: permissions, - }) - } -} - #[derive(Debug, Default, PartialEq)] pub(crate) struct Diagnostics { pub(crate) messages: Vec, - pub(crate) fixed: FxHashMap, + pub(crate) fixed: FixMap, pub(crate) imports: ImportMap, pub(crate) notebook_indexes: FxHashMap, } @@ -76,21 +44,44 @@ impl Diagnostics { ) -> Self { Self { messages, - fixed: FxHashMap::default(), + fixed: FixMap::default(), imports, notebook_indexes, } } - /// Generate [`Diagnostics`] based on a [`SourceExtractionError`]. + /// Generate [`Diagnostics`] based on a [`SourceError`]. pub(crate) fn from_source_error( - err: &SourceExtractionError, + err: &SourceError, path: Option<&Path>, settings: &LinterSettings, ) -> Self { - let diagnostic = Diagnostic::from(err); + let diagnostic = match err { + // IO errors. + SourceError::Io(_) + | SourceError::Notebook(NotebookError::Io(_) | NotebookError::Json(_)) => { + Diagnostic::new( + IOError { + message: err.to_string(), + }, + TextRange::default(), + ) + } + // Syntax errors. + SourceError::Notebook( + NotebookError::InvalidJson(_) + | NotebookError::InvalidSchema(_) + | NotebookError::InvalidFormat(_), + ) => Diagnostic::new( + SyntaxError { + message: err.to_string(), + }, + TextRange::default(), + ), + }; + if settings.rules.enabled(diagnostic.kind.rule()) { - let name = path.map_or_else(|| "-".into(), std::path::Path::to_string_lossy); + let name = path.map_or_else(|| "-".into(), Path::to_string_lossy); let dummy = SourceFileBuilder::new(name, "").finish(); Self::new( vec![Message::from_diagnostic( @@ -121,22 +112,68 @@ impl Diagnostics { } } +impl Add for Diagnostics { + type Output = Diagnostics; + + fn add(mut self, other: Self) -> Self::Output { + self += other; + self + } +} + impl AddAssign for Diagnostics { fn add_assign(&mut self, other: Self) { self.messages.extend(other.messages); self.imports.extend(other.imports); - for (filename, fixed) in other.fixed { + self.fixed += other.fixed; + self.notebook_indexes.extend(other.notebook_indexes); + } +} + +/// A collection of fixes indexed by file path. +#[derive(Debug, Default, PartialEq)] +pub(crate) struct FixMap(FxHashMap); + +impl FixMap { + /// Returns `true` if there are no fixes in the map. + pub(crate) fn is_empty(&self) -> bool { + self.0.is_empty() + } + + /// Returns an iterator over the fixes in the map, along with the file path. + pub(crate) fn iter(&self) -> impl Iterator { + self.0.iter() + } + + /// Returns an iterator over the fixes in the map. + pub(crate) fn values(&self) -> impl Iterator { + self.0.values() + } +} + +impl FromIterator<(String, FixTable)> for FixMap { + fn from_iter>(iter: T) -> Self { + Self( + iter.into_iter() + .filter(|(_, fixes)| !fixes.is_empty()) + .collect(), + ) + } +} + +impl AddAssign for FixMap { + fn add_assign(&mut self, rhs: Self) { + for (filename, fixed) in rhs.0 { if fixed.is_empty() { continue; } - let fixed_in_file = self.fixed.entry(filename).or_default(); + let fixed_in_file = self.0.entry(filename).or_default(); for (rule, count) in fixed { if count > 0 { *fixed_in_file.entry(rule).or_default() += count; } } } - self.notebook_indexes.extend(other.notebook_indexes); } } @@ -147,7 +184,8 @@ pub(crate) fn lint_path( settings: &LinterSettings, cache: Option<&Cache>, noqa: flags::Noqa, - autofix: flags::FixMode, + fix_mode: flags::FixMode, + unsafe_fixes: UnsafeFixes, ) -> Result { // Check the cache. // TODO(charlie): `fixer::Mode::Apply` and `fixer::Mode::Diff` both have @@ -156,15 +194,17 @@ pub(crate) fn lint_path( // write the fixes to disk, thus invalidating the cache. But it's a bit hard // to reason about. We need to come up with a better solution here.) let caching = match cache { - Some(cache) if noqa.into() && autofix.is_generate() => { + Some(cache) if noqa.into() && fix_mode.is_generate() => { let relative_path = cache .relative_path(path) .expect("wrong package cache for file"); let cache_key = FileCacheKey::from_path(path).context("Failed to create cache key")?; - - if let Some(cache) = cache.get(relative_path, &cache_key) { - return Ok(cache.as_diagnostics(path)); + let cached_diagnostics = cache + .get(relative_path, &cache_key) + .and_then(|entry| entry.to_diagnostics(path)); + if let Some(diagnostics) = cached_diagnostics { + return Ok(diagnostics); } // Stash the file metadata for later so when we update the cache it reflects the prerun @@ -183,13 +223,12 @@ pub(crate) fn lint_path( .iter_enabled() .any(|rule_code| rule_code.lint_source().is_pyproject_toml()) { - let contents = - match std::fs::read_to_string(path).map_err(SourceExtractionError::Io) { - Ok(contents) => contents, - Err(err) => { - return Ok(Diagnostics::from_source_error(&err, Some(path), settings)); - } - }; + let contents = match std::fs::read_to_string(path).map_err(SourceError::from) { + Ok(contents) => contents, + Err(err) => { + return Ok(Diagnostics::from_source_error(&err, Some(path), settings)); + } + }; let source_file = SourceFileBuilder::new(path.to_string_lossy(), contents).finish(); lint_pyproject_toml(source_file, settings) } else { @@ -205,8 +244,8 @@ pub(crate) fn lint_path( }; // Extract the sources from the file. - let LintSource(source_kind) = match LintSource::try_from_path(path, source_type) { - Ok(Some(sources)) => sources, + let source_kind = match SourceKind::from_path(path, source_type) { + Ok(Some(source_kind)) => source_kind, Ok(None) => return Ok(Diagnostics::default()), Err(err) => { return Ok(Diagnostics::from_source_error(&err, Some(path), settings)); @@ -220,89 +259,36 @@ pub(crate) fn lint_path( error: parse_error, }, fixed, - ) = if matches!(autofix, flags::FixMode::Apply | flags::FixMode::Diff) { + ) = if matches!(fix_mode, flags::FixMode::Apply | flags::FixMode::Diff) { if let Ok(FixerResult { result, transformed, fixed, - }) = lint_fix(path, package, noqa, settings, &source_kind, source_type) - { + }) = lint_fix( + path, + package, + noqa, + unsafe_fixes, + settings, + &source_kind, + source_type, + ) { if !fixed.is_empty() { - match autofix { - flags::FixMode::Apply => match transformed.as_ref() { - SourceKind::Python(transformed) => { - write(path, transformed.as_bytes())?; - } - SourceKind::IpyNotebook(notebook) => { - let mut writer = BufWriter::new(File::create(path)?); - notebook.write(&mut writer)?; - } - }, + match fix_mode { + flags::FixMode::Apply => transformed.write(&mut File::create(path)?)?, flags::FixMode::Diff => { - match transformed.as_ref() { - SourceKind::Python(transformed) => { - let mut stdout = io::stdout().lock(); - TextDiff::from_lines(source_kind.source_code(), transformed) - .unified_diff() - .header(&fs::relativize_path(path), &fs::relativize_path(path)) - .to_writer(&mut stdout)?; - stdout.write_all(b"\n")?; - stdout.flush()?; - } - SourceKind::IpyNotebook(dest_notebook) => { - // We need to load the notebook again, since we might've - // mutated it. - let src_notebook = source_kind.as_ipy_notebook().unwrap(); - let mut stdout = io::stdout().lock(); - for ((idx, src_cell), dest_cell) in src_notebook - .cells() - .iter() - .enumerate() - .zip(dest_notebook.cells().iter()) - { - let (Cell::Code(src_code_cell), Cell::Code(dest_code_cell)) = - (src_cell, dest_cell) - else { - continue; - }; - TextDiff::from_lines( - &src_code_cell.source.to_string(), - &dest_code_cell.source.to_string(), - ) - .unified_diff() - // Jupyter notebook cells don't necessarily have a newline - // at the end. For example, - // - // ```python - // print("hello") - // ``` - // - // For a cell containing the above code, there'll only be one line, - // and it won't have a newline at the end. If it did, there'd be - // two lines, and the second line would be empty: - // - // ```python - // print("hello") - // - // ``` - .missing_newline_hint(false) - .header( - &format!("{}:cell {}", &fs::relativize_path(path), idx), - &format!("{}:cell {}", &fs::relativize_path(path), idx), - ) - .to_writer(&mut stdout)?; - } - stdout.write_all(b"\n")?; - stdout.flush()?; - } - } + source_kind.diff( + transformed.as_ref(), + Some(path), + &mut io::stdout().lock(), + )?; } flags::FixMode::Generate => {} } } (result, fixed) } else { - // If we fail to autofix, lint the original source code. + // If we fail to fix, lint the original source code. let result = lint_only(path, package, settings, noqa, &source_kind, source_type); let fixed = FxHashMap::default(); (result, fixed) @@ -318,12 +304,14 @@ pub(crate) fn lint_path( if let Some((cache, relative_path, key)) = caching { // We don't cache parsing errors. if parse_error.is_none() { - cache.update( + cache.update_lint( relative_path.to_owned(), - key, - &messages, - &imports, - source_kind.as_ipy_notebook().map(Notebook::index), + &key, + LintCacheData::from_messages( + &messages, + imports.clone(), + source_kind.as_ipy_notebook().map(Notebook::index).cloned(), + ), ); } } @@ -343,20 +331,14 @@ pub(crate) fn lint_path( } let notebook_indexes = if let SourceKind::IpyNotebook(notebook) = source_kind { - FxHashMap::from_iter([( - path.to_str() - .ok_or_else(|| anyhow!("Unable to parse filename: {:?}", path))? - .to_string(), - // Index needs to be computed always to store in cache. - notebook.index().clone(), - )]) + FxHashMap::from_iter([(path.to_string_lossy().to_string(), notebook.into_index())]) } else { FxHashMap::default() }; Ok(Diagnostics { messages, - fixed: FxHashMap::from_iter([(fs::relativize_path(path), fixed)]), + fixed: FixMap::from_iter([(fs::relativize_path(path), fixed)]), imports, notebook_indexes, }) @@ -370,7 +352,7 @@ pub(crate) fn lint_stdin( contents: String, settings: &Settings, noqa: flags::Noqa, - autofix: flags::FixMode, + fix_mode: flags::FixMode, ) -> Result { // TODO(charlie): Support `pyproject.toml`. let SourceType::Python(source_type) = path.map(SourceType::from).unwrap_or_default() else { @@ -378,8 +360,8 @@ pub(crate) fn lint_stdin( }; // Extract the sources from the file. - let LintSource(source_kind) = match LintSource::try_from_source_code(contents, source_type) { - Ok(Some(sources)) => sources, + let source_kind = match SourceKind::from_source_code(contents, source_type) { + Ok(Some(source_kind)) => source_kind, Ok(None) => return Ok(Diagnostics::default()), Err(err) => { return Ok(Diagnostics::from_source_error(&err, path, &settings.linter)); @@ -393,7 +375,7 @@ pub(crate) fn lint_stdin( error: parse_error, }, fixed, - ) = if matches!(autofix, flags::FixMode::Apply | flags::FixMode::Diff) { + ) = if matches!(fix_mode, flags::FixMode::Apply | flags::FixMode::Diff) { if let Ok(FixerResult { result, transformed, @@ -402,32 +384,20 @@ pub(crate) fn lint_stdin( path.unwrap_or_else(|| Path::new("-")), package, noqa, + settings.unsafe_fixes, &settings.linter, &source_kind, source_type, ) { - match autofix { + match fix_mode { flags::FixMode::Apply => { // Write the contents to stdout, regardless of whether any errors were fixed. - io::stdout().write_all(transformed.source_code().as_bytes())?; + transformed.write(&mut io::stdout().lock())?; } flags::FixMode::Diff => { // But only write a diff if it's non-empty. if !fixed.is_empty() { - let text_diff = TextDiff::from_lines( - source_kind.source_code(), - transformed.source_code(), - ); - let mut unified_diff = text_diff.unified_diff(); - if let Some(path) = path { - unified_diff - .header(&fs::relativize_path(path), &fs::relativize_path(path)); - } - - let mut stdout = io::stdout().lock(); - unified_diff.to_writer(&mut stdout)?; - stdout.write_all(b"\n")?; - stdout.flush()?; + source_kind.diff(transformed.as_ref(), path, &mut io::stdout().lock())?; } } flags::FixMode::Generate => {} @@ -435,7 +405,7 @@ pub(crate) fn lint_stdin( (result, fixed) } else { - // If we fail to autofix, lint the original source code. + // If we fail to fix, lint the original source code. let result = lint_only( path.unwrap_or_else(|| Path::new("-")), package, @@ -447,8 +417,8 @@ pub(crate) fn lint_stdin( let fixed = FxHashMap::default(); // Write the contents to stdout anyway. - if autofix.is_apply() { - io::stdout().write_all(source_kind.source_code().as_bytes())?; + if fix_mode.is_apply() { + source_kind.write(&mut io::stdout().lock())?; } (result, fixed) @@ -475,90 +445,22 @@ pub(crate) fn lint_stdin( ); } + let notebook_indexes = if let SourceKind::IpyNotebook(notebook) = source_kind { + FxHashMap::from_iter([( + path.map_or_else(|| "-".into(), |path| path.to_string_lossy().to_string()), + notebook.into_index(), + )]) + } else { + FxHashMap::default() + }; + Ok(Diagnostics { messages, - fixed: FxHashMap::from_iter([( + fixed: FixMap::from_iter([( fs::relativize_path(path.unwrap_or_else(|| Path::new("-"))), fixed, )]), imports, - notebook_indexes: FxHashMap::default(), + notebook_indexes, }) } - -#[derive(Debug)] -pub(crate) struct LintSource(pub(crate) SourceKind); - -impl LintSource { - /// Extract the lint [`LintSource`] from the given file path. - pub(crate) fn try_from_path( - path: &Path, - source_type: PySourceType, - ) -> Result, SourceExtractionError> { - if source_type.is_ipynb() { - let notebook = Notebook::from_path(path)?; - Ok(notebook - .is_python_notebook() - .then_some(LintSource(SourceKind::IpyNotebook(notebook)))) - } else { - // This is tested by ruff_cli integration test `unreadable_file` - let contents = std::fs::read_to_string(path)?; - Ok(Some(LintSource(SourceKind::Python(contents)))) - } - } - - /// Extract the lint [`LintSource`] from the raw string contents, optionally accompanied by a - /// file path indicating the path to the file from which the contents were read. If provided, - /// the file path should be used for diagnostics, but not for reading the file from disk. - pub(crate) fn try_from_source_code( - source_code: String, - source_type: PySourceType, - ) -> Result, SourceExtractionError> { - if source_type.is_ipynb() { - let notebook = Notebook::from_source_code(&source_code)?; - Ok(notebook - .is_python_notebook() - .then_some(LintSource(SourceKind::IpyNotebook(notebook)))) - } else { - Ok(Some(LintSource(SourceKind::Python(source_code)))) - } - } -} - -#[derive(Error, Debug)] -pub(crate) enum SourceExtractionError { - /// The extraction failed due to an [`io::Error`]. - #[error(transparent)] - Io(#[from] io::Error), - /// The extraction failed due to a [`NotebookError`]. - #[error(transparent)] - Notebook(#[from] NotebookError), -} - -impl From<&SourceExtractionError> for Diagnostic { - fn from(err: &SourceExtractionError) -> Self { - match err { - // IO errors. - SourceExtractionError::Io(_) - | SourceExtractionError::Notebook(NotebookError::Io(_) | NotebookError::Json(_)) => { - Diagnostic::new( - IOError { - message: err.to_string(), - }, - TextRange::default(), - ) - } - // Syntax errors. - SourceExtractionError::Notebook( - NotebookError::InvalidJson(_) - | NotebookError::InvalidSchema(_) - | NotebookError::InvalidFormat(_), - ) => Diagnostic::new( - SyntaxError { - message: err.to_string(), - }, - TextRange::default(), - ), - } - } -} diff --git a/crates/ruff_cli/src/lib.rs b/crates/ruff_cli/src/lib.rs index c7f0c34729322..4cb0db0c8bb9e 100644 --- a/crates/ruff_cli/src/lib.rs +++ b/crates/ruff_cli/src/lib.rs @@ -1,3 +1,5 @@ +#![allow(clippy::print_stdout)] + use std::fs::File; use std::io::{self, stdout, BufWriter, Write}; use std::path::{Path, PathBuf}; @@ -6,16 +8,17 @@ use std::sync::mpsc::channel; use anyhow::Result; use clap::CommandFactory; +use colored::Colorize; use log::warn; use notify::{recommended_watcher, RecursiveMode, Watcher}; use ruff_linter::logging::{set_up_logging, LogLevel}; -use ruff_linter::settings::flags; +use ruff_linter::settings::flags::FixMode; use ruff_linter::settings::types::SerializationFormat; use ruff_linter::{fs, warn_user, warn_user_once}; use ruff_workspace::Settings; -use crate::args::{Args, CheckCommand, Command, FormatCommand}; +use crate::args::{Args, CheckCommand, Command, FormatCommand, HelpFormat}; use crate::printer::{Flags as PrinterFlags, Printer}; pub mod args; @@ -26,6 +29,7 @@ mod panic; mod printer; pub mod resolve; mod stdin; +mod version; #[derive(Copy, Clone)] pub enum ExitStatus { @@ -97,6 +101,15 @@ fn is_stdin(files: &[PathBuf], stdin_filename: Option<&Path>) -> bool { file == Path::new("-") } +/// Get the actual value of the `format` desired from either `output_format` +/// or `format`, and warn the user if they're using the deprecated form. +fn resolve_help_output_format(output_format: HelpFormat, format: Option) -> HelpFormat { + if format.is_some() { + warn_user!("The `--format` argument is deprecated. Use `--output-format` instead."); + } + format.unwrap_or(output_format) +} + pub fn run( Args { command, @@ -104,8 +117,6 @@ pub fn run( }: Args, ) -> Result { { - use colored::Colorize; - let default_panic_hook = std::panic::take_hook(); std::panic::set_hook(Box::new(move |info| { #[allow(clippy::print_stderr)] @@ -135,12 +146,22 @@ pub fn run( set_up_logging(&log_level)?; match command { - Command::Rule { rule, all, format } => { + Command::Version { output_format } => { + commands::version::version(output_format)?; + Ok(ExitStatus::Success) + } + Command::Rule { + rule, + all, + format, + mut output_format, + } => { + output_format = resolve_help_output_format(output_format, format); if all { - commands::rule::rules(format)?; + commands::rule::rules(output_format)?; } if let Some(rule) = rule { - commands::rule::rule(rule, format)?; + commands::rule::rule(rule, output_format)?; } Ok(ExitStatus::Success) } @@ -148,8 +169,12 @@ pub fn run( commands::config::config(option.as_deref())?; Ok(ExitStatus::Success) } - Command::Linter { format } => { - commands::linter::linter(format)?; + Command::Linter { + format, + mut output_format, + } => { + output_format = resolve_help_output_format(output_format, format); + commands::linter::linter(output_format)?; Ok(ExitStatus::Success) } Command::Clean => { @@ -166,11 +191,6 @@ pub fn run( } fn format(args: FormatCommand, log_level: LogLevel) -> Result { - warn_user_once!( - "`ruff format` is a work-in-progress, subject to change at any time, and intended only for \ - experimentation." - ); - let (cli, overrides) = args.partition(); if is_stdin(&cli.files, cli.stdin_filename.as_deref()) { @@ -181,14 +201,6 @@ fn format(args: FormatCommand, log_level: LogLevel) -> Result { } pub fn check(args: CheckCommand, log_level: LogLevel) -> Result { - if args.format.is_some() { - if std::env::var("RUFF_FORMAT").is_ok() { - warn_user!("The environment variable `RUFF_FORMAT` is deprecated. Use `RUFF_OUTPUT_FORMAT` instead."); - } else { - warn_user!("The argument `--format=` is deprecated. Use `--output-format=` instead."); - } - } - let (cli, overrides) = args.partition(); // Construct the "default" settings. These are used when no `pyproject.toml` @@ -208,6 +220,7 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result { } _ => Box::new(BufWriter::new(io::stdout())), }; + let stderr_writer = Box::new(BufWriter::new(io::stderr())); if cli.show_settings { commands::show_settings::show_settings( @@ -228,25 +241,29 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result { let Settings { fix, fix_only, + unsafe_fixes, output_format, show_fixes, show_source, .. } = pyproject_config.settings; - // Autofix rules are as follows: + // Fix rules are as follows: // - By default, generate all fixes, but don't apply them to the filesystem. - // - If `--fix` or `--fix-only` is set, always apply fixes to the filesystem (or + // - If `--fix` or `--fix-only` is set, apply applicable fixes to the filesystem (or // print them to stdout, if we're reading from stdin). - // - If `--diff` or `--fix-only` are set, don't print any violations (only - // fixes). - let autofix = if cli.diff { - flags::FixMode::Diff + // - If `--diff` or `--fix-only` are set, don't print any violations (only applicable fixes) + // - By default, applicable fixes only include [`Applicablility::Automatic`], but if + // `--unsafe-fixes` is set, then [`Applicablility::Suggested`] fixes are included. + + let fix_mode = if cli.diff { + FixMode::Diff } else if fix || fix_only { - flags::FixMode::Apply + FixMode::Apply } else { - flags::FixMode::Generate + FixMode::Generate }; + let cache = !cli.no_cache; let noqa = !cli.ignore_noqa; let mut printer_flags = PrinterFlags::empty(); @@ -275,7 +292,7 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result { } if cli.add_noqa { - if !autofix.is_generate() { + if !fix_mode.is_generate() { warn_user!("--fix is incompatible with --add-noqa."); } let modifications = @@ -290,11 +307,17 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result { return Ok(ExitStatus::Success); } - let printer = Printer::new(output_format, log_level, autofix, printer_flags); + let printer = Printer::new( + output_format, + log_level, + fix_mode, + unsafe_fixes, + printer_flags, + ); if cli.watch { if output_format != SerializationFormat::Text { - warn_user!("--format 'text' is used in watch mode."); + warn_user!("`--output-format text` is always used in watch mode."); } // Configure the file watcher. @@ -317,7 +340,8 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result { &overrides, cache.into(), noqa.into(), - autofix, + fix_mode, + unsafe_fixes, )?; printer.write_continuously(&mut writer, &messages)?; @@ -349,7 +373,8 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result { &overrides, cache.into(), noqa.into(), - autofix, + fix_mode, + unsafe_fixes, )?; printer.write_continuously(&mut writer, &messages)?; } @@ -366,7 +391,7 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result { &pyproject_config, &overrides, noqa.into(), - autofix, + fix_mode, )? } else { commands::check::check( @@ -375,19 +400,23 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result { &overrides, cache.into(), noqa.into(), - autofix, + fix_mode, + unsafe_fixes, )? }; - // Always try to print violations (the printer itself may suppress output), - // unless we're writing fixes via stdin (in which case, the transformed - // source code goes to stdout). - if !(is_stdin && matches!(autofix, flags::FixMode::Apply | flags::FixMode::Diff)) { - if cli.statistics { - printer.write_statistics(&diagnostics, &mut writer)?; - } else { - printer.write_once(&diagnostics, &mut writer)?; - } + // Always try to print violations (though the printer itself may suppress output) + // If we're writing fixes via stdin, the transformed source code goes to the writer + // so send the summary to stderr instead + let mut summary_writer = if is_stdin && matches!(fix_mode, FixMode::Apply | FixMode::Diff) { + stderr_writer + } else { + writer + }; + if cli.statistics { + printer.write_statistics(&diagnostics, &mut summary_writer)?; + } else { + printer.write_once(&diagnostics, &mut summary_writer)?; } if !cli.exit_zero { diff --git a/crates/ruff_cli/src/printer.rs b/crates/ruff_cli/src/printer.rs index 07757fed83860..6f22f37d1608e 100644 --- a/crates/ruff_cli/src/printer.rs +++ b/crates/ruff_cli/src/printer.rs @@ -7,11 +7,9 @@ use anyhow::Result; use bitflags::bitflags; use colored::Colorize; use itertools::{iterate, Itertools}; -use rustc_hash::FxHashMap; use serde::Serialize; use ruff_linter::fs::relativize_path; -use ruff_linter::linter::FixTable; use ruff_linter::logging::LogLevel; use ruff_linter::message::{ AzureEmitter, Emitter, EmitterContext, GithubEmitter, GitlabEmitter, GroupedEmitter, @@ -19,10 +17,10 @@ use ruff_linter::message::{ }; use ruff_linter::notify_user; use ruff_linter::registry::{AsRule, Rule}; -use ruff_linter::settings::flags; -use ruff_linter::settings::types::SerializationFormat; +use ruff_linter::settings::flags::{self}; +use ruff_linter::settings::types::{SerializationFormat, UnsafeFixes}; -use crate::diagnostics::Diagnostics; +use crate::diagnostics::{Diagnostics, FixMap}; bitflags! { #[derive(Default, Debug, Copy, Clone)] @@ -72,7 +70,8 @@ impl From for SerializeRuleAsCode { pub(crate) struct Printer { format: SerializationFormat, log_level: LogLevel, - autofix_level: flags::FixMode, + fix_mode: flags::FixMode, + unsafe_fixes: UnsafeFixes, flags: Flags, } @@ -80,13 +79,15 @@ impl Printer { pub(crate) const fn new( format: SerializationFormat, log_level: LogLevel, - autofix_level: flags::FixMode, + fix_mode: flags::FixMode, + unsafe_fixes: UnsafeFixes, flags: Flags, ) -> Self { Self { format, log_level, - autofix_level, + fix_mode, + unsafe_fixes, flags, } } @@ -99,12 +100,15 @@ impl Printer { fn write_summary_text(&self, writer: &mut dyn Write, diagnostics: &Diagnostics) -> Result<()> { if self.log_level >= LogLevel::Default { + let fixables = FixableStatistics::try_from(diagnostics, self.unsafe_fixes); + + let fixed = diagnostics + .fixed + .values() + .flat_map(std::collections::HashMap::values) + .sum::(); + if self.flags.intersects(Flags::SHOW_VIOLATIONS) { - let fixed = diagnostics - .fixed - .values() - .flat_map(std::collections::HashMap::values) - .sum::(); let remaining = diagnostics.messages.len(); let total = fixed + remaining; if fixed > 0 { @@ -118,32 +122,83 @@ impl Printer { writeln!(writer, "Found {remaining} error{s}.")?; } - if show_fix_status(self.autofix_level) { - let num_fixable = diagnostics - .messages - .iter() - .filter(|message| message.fix.is_some()) - .count(); - if num_fixable > 0 { - writeln!( - writer, - "[{}] {num_fixable} potentially fixable with the --fix option.", - "*".cyan(), - )?; + if let Some(fixables) = fixables { + let fix_prefix = format!("[{}]", "*".cyan()); + + if self.unsafe_fixes.is_enabled() { + if fixables.applicable > 0 { + writeln!( + writer, + "{fix_prefix} {} fixable with the --fix option.", + fixables.applicable + )?; + } + } else { + if fixables.applicable > 0 && fixables.unapplicable_unsafe > 0 { + let es = if fixables.unapplicable_unsafe == 1 { + "" + } else { + "es" + }; + writeln!(writer, + "{fix_prefix} {} fixable with the `--fix` option ({} hidden fix{es} can be enabled with the `--unsafe-fixes` option).", + fixables.applicable, fixables.unapplicable_unsafe + )?; + } else if fixables.applicable > 0 { + // Only applicable fixes + writeln!( + writer, + "{fix_prefix} {} fixable with the `--fix` option.", + fixables.applicable, + )?; + } else { + // Only unapplicable fixes + let es = if fixables.unapplicable_unsafe == 1 { + "" + } else { + "es" + }; + writeln!(writer, + "No fixes available ({} hidden fix{es} can be enabled with the `--unsafe-fixes` option).", + fixables.unapplicable_unsafe + )?; + } } } } else { - let fixed = diagnostics - .fixed - .values() - .flat_map(std::collections::HashMap::values) - .sum::(); - if fixed > 0 { - let s = if fixed == 1 { "" } else { "s" }; - if self.autofix_level.is_apply() { - writeln!(writer, "Fixed {fixed} error{s}.")?; + // Check if there are unapplied fixes + let unapplied = { + if let Some(fixables) = fixables { + fixables.unapplicable_unsafe } else { - writeln!(writer, "Would fix {fixed} error{s}.")?; + 0 + } + }; + + if unapplied > 0 { + let es = if unapplied == 1 { "" } else { "es" }; + if fixed > 0 { + let s = if fixed == 1 { "" } else { "s" }; + if self.fix_mode.is_apply() { + writeln!(writer, "Fixed {fixed} error{s} ({unapplied} additional fix{es} available with `--unsafe-fixes`).")?; + } else { + writeln!(writer, "Would fix {fixed} error{s} ({unapplied} additional fix{es} available with `--unsafe-fixes`).")?; + } + } else { + if self.fix_mode.is_apply() { + writeln!(writer, "No errors fixed ({unapplied} fix{es} available with `--unsafe-fixes`).")?; + } else { + writeln!(writer, "No errors would be fixed ({unapplied} fix{es} available with `--unsafe-fixes`).")?; + } + } + } else { + if fixed > 0 { + let s = if fixed == 1 { "" } else { "s" }; + if self.fix_mode.is_apply() { + writeln!(writer, "Fixed {fixed} error{s}.")?; + } else { + writeln!(writer, "Would fix {fixed} error{s}.")?; + } } } } @@ -178,6 +233,7 @@ impl Printer { } let context = EmitterContext::new(&diagnostics.notebook_indexes); + let fixables = FixableStatistics::try_from(diagnostics, self.unsafe_fixes); match self.format { SerializationFormat::Json => { @@ -191,9 +247,10 @@ impl Printer { } SerializationFormat::Text => { TextEmitter::default() - .with_show_fix_status(show_fix_status(self.autofix_level)) + .with_show_fix_status(show_fix_status(self.fix_mode, fixables.as_ref())) .with_show_fix_diff(self.flags.intersects(Flags::SHOW_FIX_DIFF)) .with_show_source(self.flags.intersects(Flags::SHOW_SOURCE)) + .with_unsafe_fixes(self.unsafe_fixes) .emit(writer, &diagnostics.messages, &context)?; if self.flags.intersects(Flags::SHOW_FIX_SUMMARY) { @@ -209,7 +266,8 @@ impl Printer { SerializationFormat::Grouped => { GroupedEmitter::default() .with_show_source(self.flags.intersects(Flags::SHOW_SOURCE)) - .with_show_fix_status(show_fix_status(self.autofix_level)) + .with_show_fix_status(show_fix_status(self.fix_mode, fixables.as_ref())) + .with_unsafe_fixes(self.unsafe_fixes) .emit(writer, &diagnostics.messages, &context)?; if self.flags.intersects(Flags::SHOW_FIX_SUMMARY) { @@ -359,6 +417,8 @@ impl Printer { ); } + let fixables = FixableStatistics::try_from(diagnostics, self.unsafe_fixes); + if !diagnostics.messages.is_empty() { if self.log_level >= LogLevel::Default { writeln!(writer)?; @@ -366,8 +426,9 @@ impl Printer { let context = EmitterContext::new(&diagnostics.notebook_indexes); TextEmitter::default() - .with_show_fix_status(show_fix_status(self.autofix_level)) + .with_show_fix_status(show_fix_status(self.fix_mode, fixables.as_ref())) .with_show_source(self.flags.intersects(Flags::SHOW_SOURCE)) + .with_unsafe_fixes(self.unsafe_fixes) .emit(writer, &diagnostics.messages, &context)?; } writer.flush()?; @@ -390,16 +451,16 @@ fn num_digits(n: usize) -> usize { } /// Return `true` if the [`Printer`] should indicate that a rule is fixable. -const fn show_fix_status(autofix_level: flags::FixMode) -> bool { +fn show_fix_status(fix_mode: flags::FixMode, fixables: Option<&FixableStatistics>) -> bool { // If we're in application mode, avoid indicating that a rule is fixable. // If the specific violation were truly fixable, it would've been fixed in // this pass! (We're occasionally unable to determine whether a specific - // violation is fixable without trying to fix it, so if autofix is not + // violation is fixable without trying to fix it, so if fix is not // enabled, we may inadvertently indicate that a rule is fixable.) - !autofix_level.is_apply() + (!fix_mode.is_apply()) && fixables.is_some_and(FixableStatistics::any_applicable_fixes) } -fn print_fix_summary(writer: &mut dyn Write, fixed: &FxHashMap) -> Result<()> { +fn print_fix_summary(writer: &mut dyn Write, fixed: &FixMap) -> Result<()> { let total = fixed .values() .map(|table| table.values().sum::()) @@ -439,3 +500,43 @@ fn print_fix_summary(writer: &mut dyn Write, fixed: &FxHashMap } Ok(()) } + +/// Statistics for [applicable][ruff_diagnostics::Applicability] fixes. +#[derive(Debug)] +struct FixableStatistics { + applicable: u32, + unapplicable_unsafe: u32, +} + +impl FixableStatistics { + fn try_from(diagnostics: &Diagnostics, unsafe_fixes: UnsafeFixes) -> Option { + let mut applicable = 0; + let mut unapplicable_unsafe = 0; + + for message in &diagnostics.messages { + if let Some(fix) = &message.fix { + if fix.applies(unsafe_fixes.required_applicability()) { + applicable += 1; + } else { + // Do not include unapplicable fixes at other levels that do not provide an opt-in + if fix.applicability().is_unsafe() { + unapplicable_unsafe += 1; + } + } + } + } + + if applicable == 0 && unapplicable_unsafe == 0 { + None + } else { + Some(Self { + applicable, + unapplicable_unsafe, + }) + } + } + + fn any_applicable_fixes(&self) -> bool { + self.applicable > 0 + } +} diff --git a/crates/ruff_cli/src/snapshots/ruff_cli__version__tests__version_formatting.snap b/crates/ruff_cli/src/snapshots/ruff_cli__version__tests__version_formatting.snap new file mode 100644 index 0000000000000..7bd9a393de87c --- /dev/null +++ b/crates/ruff_cli/src/snapshots/ruff_cli__version__tests__version_formatting.snap @@ -0,0 +1,5 @@ +--- +source: crates/ruff_cli/src/version.rs +expression: version +--- +0.0.0 diff --git a/crates/ruff_cli/src/snapshots/ruff_cli__version__tests__version_formatting_with_commit_info.snap b/crates/ruff_cli/src/snapshots/ruff_cli__version__tests__version_formatting_with_commit_info.snap new file mode 100644 index 0000000000000..cdda49684aad8 --- /dev/null +++ b/crates/ruff_cli/src/snapshots/ruff_cli__version__tests__version_formatting_with_commit_info.snap @@ -0,0 +1,5 @@ +--- +source: crates/ruff_cli/src/version.rs +expression: version +--- +0.0.0 (53b0f5d92 2023-10-19) diff --git a/crates/ruff_cli/src/snapshots/ruff_cli__version__tests__version_formatting_with_commits_since_last_tag.snap b/crates/ruff_cli/src/snapshots/ruff_cli__version__tests__version_formatting_with_commits_since_last_tag.snap new file mode 100644 index 0000000000000..6330751c8a006 --- /dev/null +++ b/crates/ruff_cli/src/snapshots/ruff_cli__version__tests__version_formatting_with_commits_since_last_tag.snap @@ -0,0 +1,5 @@ +--- +source: crates/ruff_cli/src/version.rs +expression: version +--- +0.0.0+24 (53b0f5d92 2023-10-19) diff --git a/crates/ruff_cli/src/snapshots/ruff_cli__version__tests__version_serializable.snap b/crates/ruff_cli/src/snapshots/ruff_cli__version__tests__version_serializable.snap new file mode 100644 index 0000000000000..0a63628659679 --- /dev/null +++ b/crates/ruff_cli/src/snapshots/ruff_cli__version__tests__version_serializable.snap @@ -0,0 +1,14 @@ +--- +source: crates/ruff_cli/src/version.rs +expression: version +--- +{ + "version": "0.0.0", + "commit_info": { + "short_commit_hash": "53b0f5d92", + "commit_hash": "53b0f5d924110e5b26fbf09f6fd3a03d67b475b7", + "commit_date": "2023-10-19", + "last_tag": "v0.0.1", + "commits_since_last_tag": 0 + } +} diff --git a/crates/ruff_cli/src/version.rs b/crates/ruff_cli/src/version.rs new file mode 100644 index 0000000000000..f79b938f653c4 --- /dev/null +++ b/crates/ruff_cli/src/version.rs @@ -0,0 +1,130 @@ +//! Code for representing Ruff's release version number. +use serde::Serialize; +use std::fmt; + +/// Information about the git repository where Ruff was built from. +#[derive(Serialize)] +pub(crate) struct CommitInfo { + short_commit_hash: String, + commit_hash: String, + commit_date: String, + last_tag: Option, + commits_since_last_tag: u32, +} + +/// Ruff's version. +#[derive(Serialize)] +pub(crate) struct VersionInfo { + /// Ruff's version, such as "0.5.1" + version: String, + /// Information about the git commit we may have been built from. + /// + /// `None` if not built from a git repo or if retrieval failed. + commit_info: Option, +} + +impl fmt::Display for VersionInfo { + /// Formatted version information: "[+] ( )" + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.version)?; + + if let Some(ref ci) = self.commit_info { + if ci.commits_since_last_tag > 0 { + write!(f, "+{}", ci.commits_since_last_tag)?; + } + write!(f, " ({} {})", ci.short_commit_hash, ci.commit_date)?; + } + + Ok(()) + } +} + +/// Returns information about Ruff's version. +pub(crate) fn version() -> VersionInfo { + // Environment variables are only read at compile-time + macro_rules! option_env_str { + ($name:expr) => { + option_env!($name).map(|s| s.to_string()) + }; + } + + // This version is pulled from Cargo.toml and set by Cargo + let version = option_env_str!("CARGO_PKG_VERSION").unwrap(); + + // Commit info is pulled from git and set by `build.rs` + let commit_info = option_env_str!("RUFF_COMMIT_HASH").map(|commit_hash| CommitInfo { + short_commit_hash: option_env_str!("RUFF_COMMIT_SHORT_HASH").unwrap(), + commit_hash, + commit_date: option_env_str!("RUFF_COMMIT_DATE").unwrap(), + last_tag: option_env_str!("RUFF_LAST_TAG"), + commits_since_last_tag: option_env_str!("RUFF_LAST_TAG_DISTANCE") + .as_deref() + .map_or(0, |value| value.parse::().unwrap_or(0)), + }); + + VersionInfo { + version, + commit_info, + } +} + +#[cfg(test)] +mod tests { + use insta::{assert_display_snapshot, assert_json_snapshot}; + + use super::{CommitInfo, VersionInfo}; + + #[test] + fn version_formatting() { + let version = VersionInfo { + version: "0.0.0".to_string(), + commit_info: None, + }; + assert_display_snapshot!(version); + } + + #[test] + fn version_formatting_with_commit_info() { + let version = VersionInfo { + version: "0.0.0".to_string(), + commit_info: Some(CommitInfo { + short_commit_hash: "53b0f5d92".to_string(), + commit_hash: "53b0f5d924110e5b26fbf09f6fd3a03d67b475b7".to_string(), + last_tag: Some("v0.0.1".to_string()), + commit_date: "2023-10-19".to_string(), + commits_since_last_tag: 0, + }), + }; + assert_display_snapshot!(version); + } + + #[test] + fn version_formatting_with_commits_since_last_tag() { + let version = VersionInfo { + version: "0.0.0".to_string(), + commit_info: Some(CommitInfo { + short_commit_hash: "53b0f5d92".to_string(), + commit_hash: "53b0f5d924110e5b26fbf09f6fd3a03d67b475b7".to_string(), + last_tag: Some("v0.0.1".to_string()), + commit_date: "2023-10-19".to_string(), + commits_since_last_tag: 24, + }), + }; + assert_display_snapshot!(version); + } + + #[test] + fn version_serializable() { + let version = VersionInfo { + version: "0.0.0".to_string(), + commit_info: Some(CommitInfo { + short_commit_hash: "53b0f5d92".to_string(), + commit_hash: "53b0f5d924110e5b26fbf09f6fd3a03d67b475b7".to_string(), + last_tag: Some("v0.0.1".to_string()), + commit_date: "2023-10-19".to_string(), + commits_since_last_tag: 0, + }), + }; + assert_json_snapshot!(version); + } +} diff --git a/crates/ruff_cli/tests/black_compatibility_test.rs b/crates/ruff_cli/tests/black_compatibility_test.rs deleted file mode 100644 index 53159716e75b6..0000000000000 --- a/crates/ruff_cli/tests/black_compatibility_test.rs +++ /dev/null @@ -1,204 +0,0 @@ -#![cfg(not(target_family = "wasm"))] - -use std::io::{ErrorKind, Read, Write}; -use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpListener, TcpStream}; -use std::path::{Path, PathBuf}; -use std::process::{Command, Stdio}; -use std::thread::sleep; -use std::time::Duration; -use std::{fs, process, str}; - -use anyhow::{anyhow, bail, Context, Result}; -use insta_cmd::get_cargo_bin; -use log::info; -use walkdir::WalkDir; - -use ruff_linter::logging::{set_up_logging, LogLevel}; - -/// Handles `blackd` process and allows submitting code to it for formatting. -struct Blackd { - address: SocketAddr, - server: process::Child, - client: ureq::Agent, -} - -const BIN_NAME: &str = "ruff"; - -impl Blackd { - pub(crate) fn new() -> Result { - // Get free TCP port to run on - let address = TcpListener::bind(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0))?.local_addr()?; - - let args = [ - "--bind-host", - &address.ip().to_string(), - "--bind-port", - &address.port().to_string(), - ]; - let server = Command::new("blackd") - .args(args) - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .spawn() - .context("Starting blackd")?; - - // Wait up to four seconds for `blackd` to be ready. - for _ in 0..20 { - match TcpStream::connect(address) { - Err(e) if e.kind() == ErrorKind::ConnectionRefused => { - info!("`blackd` not ready yet; retrying..."); - sleep(Duration::from_millis(200)); - } - Err(e) => return Err(e.into()), - Ok(_) => { - info!("`blackd` ready"); - return Ok(Self { - address, - server, - client: ureq::agent(), - }); - } - } - } - - bail!("blackd {:?} failed to start", args) - } - - /// Format given code with blackd. - pub(crate) fn check(&self, code: &[u8]) -> Result> { - match self - .client - .post(&format!("http://{}/", self.address)) - .set("X-Line-Length", "88") - .send_bytes(code) - { - // 204 indicates the input wasn't changed during formatting, so - // we return the original. - Ok(response) => { - if response.status() == 204 { - Ok(code.to_vec()) - } else { - let mut buf = vec![]; - response - .into_reader() - .take((1024 * 1024) as u64) - .read_to_end(&mut buf)?; - Ok(buf) - } - } - Err(ureq::Error::Status(_, response)) => Err(anyhow::anyhow!( - "Formatting with `black` failed: {}", - response.into_string()? - )), - Err(e) => Err(e.into()), - } - } -} - -impl Drop for Blackd { - fn drop(&mut self) { - self.server.kill().expect("Couldn't end `blackd` process"); - } -} - -fn run_test(path: &Path, blackd: &Blackd, ruff_args: &[&str]) -> Result<()> { - let input = fs::read(path)?; - - // Step 1: Run `ruff` on the input. - let mut step_1 = Command::new(get_cargo_bin(BIN_NAME)) - .args(ruff_args) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn()?; - if let Some(mut stdin) = step_1.stdin.take() { - stdin.write_all(input.as_ref())?; - } - let step_1_output = step_1.wait_with_output()?; - if !step_1_output.status.success() { - return Err(anyhow!( - "Running input through ruff failed:\n{}", - str::from_utf8(&step_1_output.stderr)? - )); - } - - // Step 2: Run `blackd` on the input. - let step_2_output = blackd.check(&step_1_output.stdout.clone())?; - - // Step 3: Re-run `ruff` on the input. - let mut step_3 = Command::new(get_cargo_bin(BIN_NAME)) - .args(ruff_args) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn()?; - if let Some(mut stdin) = step_3.stdin.take() { - stdin.write_all(step_2_output.as_ref())?; - } - let step_3_output = step_3.wait_with_output()?; - if !step_3_output.status.success() { - return Err(anyhow!( - "Running input through ruff after black failed:\n{}", - str::from_utf8(&step_3_output.stderr)? - )); - } - let step_3_output = step_3_output.stdout.clone(); - - assert_eq!( - str::from_utf8(&step_2_output), - str::from_utf8(&step_3_output), - "Mismatch found for {}", - path.display() - ); - - Ok(()) -} - -#[test] -#[ignore] -fn test_ruff_black_compatibility() -> Result<()> { - set_up_logging(&LogLevel::Default)?; - - let blackd = Blackd::new()?; - - let fixtures_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) - .join("resources") - .join("test") - .join("fixtures"); - - // Ignore some fixtures that currently trigger errors. `E999.py` especially, as - // that is triggering a syntax error on purpose. - let excludes = ["E999.py", "W605_1.py"]; - - let paths = WalkDir::new(fixtures_dir) - .into_iter() - .flatten() - .filter(|entry| { - entry - .path() - .extension() - .is_some_and(|ext| ext == "py" || ext == "pyi") - && !excludes.contains(&entry.path().file_name().unwrap().to_str().unwrap()) - }); - - let ruff_args = [ - "-", - "--silent", - "--exit-zero", - "--fix", - "--line-length", - "88", - "--select", - "ALL", - // Exclude ruff codes, specifically RUF100, because it causes differences that are not a - // problem. Ruff would add a `# noqa: W292` after the first run, black introduces a - // newline, and ruff removes the `# noqa: W292` again. - "--ignore", - "RUF", - ]; - - for entry in paths { - let path = entry.path(); - run_test(path, &blackd, &ruff_args).context(format!("Testing {}", path.display()))?; - } - - Ok(()) -} diff --git a/crates/ruff_cli/tests/format.rs b/crates/ruff_cli/tests/format.rs index c51a521816f1b..56efebcc64b4a 100644 --- a/crates/ruff_cli/tests/format.rs +++ b/crates/ruff_cli/tests/format.rs @@ -1,6 +1,7 @@ #![cfg(not(target_family = "wasm"))] use std::fs; +use std::path::Path; use std::process::Command; use std::str; @@ -13,7 +14,7 @@ const BIN_NAME: &str = "ruff"; #[test] fn default_options() { assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(["format", "--isolated"]) + .args(["format", "--isolated", "--stdin-filename", "test.py"]) .arg("-") .pass_stdin(r#" def foo(arg1, arg2,): @@ -39,7 +40,6 @@ if condition: print('Hy "Micha"') # Should not change quotes ----- stderr ----- - warning: `ruff format` is a work-in-progress, subject to change at any time, and intended only for experimentation. "###); } @@ -50,6 +50,9 @@ fn format_options() -> Result<()> { fs::write( &ruff_toml, r#" +indent-width = 8 +line-length = 84 + [format] indent-style = "tab" quote-style = "single" @@ -64,7 +67,7 @@ line-ending = "cr-lf" .arg("-") .pass_stdin(r#" def foo(arg1, arg2,): - print("Shouldn't change quotes") + print("Shouldn't change quotes. It exceeds the line width with the tab size 8") if condition: @@ -76,14 +79,144 @@ if condition: exit_code: 0 ----- stdout ----- def foo(arg1, arg2): - print("Shouldn't change quotes") + print( + "Shouldn't change quotes. It exceeds the line width with the tab size 8" + ) if condition: print('Should change quotes') ----- stderr ----- - warning: `ruff format` is a work-in-progress, subject to change at any time, and intended only for experimentation. + "###); + Ok(()) +} + +#[test] +fn mixed_line_endings() -> Result<()> { + let tempdir = TempDir::new()?; + + fs::write( + tempdir.path().join("main.py"), + "from test import say_hy\n\nif __name__ == \"__main__\":\n say_hy(\"dear Ruff contributor\")\n", + )?; + + fs::write( + tempdir.path().join("test.py"), + "def say_hy(name: str):\r\n print(f\"Hy {name}\")\r\n", + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .current_dir(tempdir.path()) + .args(["format", "--no-cache", "--diff", "--isolated"]) + .arg("."), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + 2 files left unchanged + "###); + Ok(()) +} + +#[test] +fn exclude() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +extend-exclude = ["out"] + +[format] +exclude = ["test.py", "generated.py"] +"#, + )?; + + fs::write( + tempdir.path().join("main.py"), + r#" +from test import say_hy + +if __name__ == "__main__": + say_hy("dear Ruff contributor") +"#, + )?; + + // Excluded file but passed to the CLI directly, should be formatted + let test_path = tempdir.path().join("test.py"); + fs::write( + &test_path, + r#" +def say_hy(name: str): + print(f"Hy {name}")"#, + )?; + + fs::write( + tempdir.path().join("generated.py"), + r#"NUMBERS = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 +] +OTHER = "OTHER" +"#, + )?; + + let out_dir = tempdir.path().join("out"); + fs::create_dir(&out_dir)?; + + fs::write(out_dir.join("a.py"), "a = a")?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .current_dir(tempdir.path()) + .args(["format", "--no-cache", "--check", "--config"]) + .arg(ruff_toml.file_name().unwrap()) + // Explicitly pass test.py, should be formatted regardless of it being excluded by format.exclude + .arg(test_path.file_name().unwrap()) + // Format all other files in the directory, should respect the `exclude` and `format.exclude` options + .arg("."), @r###" + success: false + exit_code: 1 + ----- stdout ----- + Would reformat: main.py + Would reformat: test.py + 2 files would be reformatted + + ----- stderr ----- + "###); + Ok(()) +} + +#[test] +fn exclude_stdin() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +extend-select = ["B", "Q"] +ignore = ["Q000", "Q001", "Q002", "Q003"] + +[format] +exclude = ["generated.py"] +"#, + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .current_dir(tempdir.path()) + .args(["format", "--config", &ruff_toml.file_name().unwrap().to_string_lossy(), "--stdin-filename", "generated.py", "-"]) + .pass_stdin(r#" +from test import say_hy + +if __name__ == '__main__': + say_hy("dear Ruff contributor") +"#), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- "###); Ok(()) } @@ -98,6 +231,9 @@ fn format_option_inheritance() -> Result<()> { r#" extend = "base.toml" +[lint] +extend-select = ["COM812"] + [format] quote-style = "single" "#, @@ -139,12 +275,47 @@ if condition: print('Should change quotes') ----- stderr ----- - warning: `ruff format` is a work-in-progress, subject to change at any time, and intended only for experimentation. + warning: The following rules may cause conflicts when used with the formatter: `COM812`. To avoid unexpected behavior, we recommend disabling these rules, either by removing them from the `select` or `extend-select` configuration, or adding then to the `ignore` configuration. "###); Ok(()) } -/// Tests that the legacy `format` option continues to work but emits a warning. +#[test] +fn deprecated_options() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +tab-size = 2 +"#, + )?; + + insta::with_settings!({filters => vec![ + (&*regex::escape(ruff_toml.to_str().unwrap()), "[RUFF-TOML-PATH]"), + ]}, { + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(["format", "--config"]) + .arg(&ruff_toml) + .arg("-") + .pass_stdin(r#" +if True: + pass + "#), @r###" + success: true + exit_code: 0 + ----- stdout ----- + if True: + pass + + ----- stderr ----- + warning: The `tab-size` option has been renamed to `indent-width` to emphasize that it configures the indentation used by the formatter as well as the tab width. Please update your configuration to use `indent-width = ` instead. + "###); + }); + Ok(()) +} + +/// Since 0.1.0 the legacy format option is no longer supported #[test] fn legacy_format_option() -> Result<()> { let tempdir = TempDir::new()?; @@ -156,52 +327,381 @@ format = "json" "#, )?; + insta::with_settings!({filters => vec![ + (&*regex::escape(ruff_toml.to_str().unwrap()), "[RUFF-TOML-PATH]"), + ]}, { + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(["check", "--select", "F401", "--no-cache", "--config"]) + .arg(&ruff_toml) + .arg("-") + .pass_stdin(r#" + import os + "#), @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + ruff failed + Cause: Failed to parse `[RUFF-TOML-PATH]`: TOML parse error at line 2, column 10 + | + 2 | format = "json" + | ^^^^^^ + invalid type: string "json", expected struct FormatOptions + + "###); + }); + Ok(()) +} + +#[test] +fn conflicting_options() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +indent-width = 2 + +[lint] +select = ["ALL"] +ignore = ["D203", "D212"] + +[lint.isort] +lines-after-imports = 3 +lines-between-types = 2 +force-wrap-aliases = true +combine-as-imports = true +split-on-trailing-comma = true + +[lint.flake8-quotes] +inline-quotes = "single" +docstring-quotes = "single" +multiline-quotes = "single" + +[format] +skip-magic-trailing-comma = true +indent-style = "tab" +"#, + )?; + + let test_path = tempdir.path().join("test.py"); + fs::write( + &test_path, + r#" +def say_hy(name: str): + print(f"Hy {name}")"#, + )?; + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) - .args(["check", "--select", "F401", "--no-cache", "--config"]) + .args(["format", "--no-cache", "--config"]) + .arg(&ruff_toml) + .arg(test_path), @r###" + success: true + exit_code: 0 + ----- stdout ----- + 1 file reformatted + + ----- stderr ----- + warning: The following rules may cause conflicts when used with the formatter: `COM812`, `D206`, `ISC001`, `W191`. To avoid unexpected behavior, we recommend disabling these rules, either by removing them from the `select` or `extend-select` configuration, or adding then to the `ignore` configuration. + warning: The `flake8-quotes.inline-quotes="single"` option is incompatible with the formatter's `format.quote-style="double"`. We recommend disabling `Q000` and `Q003` when using the formatter, which enforces a consistent quote style. Alternatively, set both options to either `"single"` or `"double"`. + warning: The `flake8-quotes.multiline-quotes="single"` option is incompatible with the formatter. We recommend disabling `Q001` when using the formatter, which enforces double quotes for multiline strings. Alternatively, set the `flake8-quotes.multiline-quotes` option to `"double"`.` + warning: The `flake8-quotes.multiline-quotes="single"` option is incompatible with the formatter. We recommend disabling `Q002` when using the formatter, which enforces double quotes for docstrings. Alternatively, set the `flake8-quotes.docstring-quotes` option to `"double"`.` + warning: The isort option `isort.lines-after-imports` with a value other than `-1`, `1` or `2` is incompatible with the formatter. To avoid unexpected behavior, we recommend setting the option to one of: `2`, `1`, or `-1` (default). + warning: The isort option `isort.lines-between-types` with a value greater than 1 is incompatible with the formatter. To avoid unexpected behavior, we recommend setting the option to one of: `1` or `0` (default). + warning: The isort option `isort.force-wrap-aliases` is incompatible with the formatter `format.skip-magic-trailing-comma=true` option. To avoid unexpected behavior, we recommend either setting `isort.force-wrap-aliases=false` or `format.skip-magic-trailing-comma=false`. + warning: The isort option `isort.split-on-trailing-comma` is incompatible with the formatter `format.skip-magic-trailing-comma=true` option. To avoid unexpected behavior, we recommend either setting `isort.split-on-trailing-comma=false` or `format.skip-magic-trailing-comma=false`. + "###); + Ok(()) +} + +#[test] +fn conflicting_options_stdin() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +indent-width = 2 + +[lint] +select = ["ALL"] +ignore = ["D203", "D212"] + +[lint.isort] +lines-after-imports = 3 +lines-between-types = 2 +force-wrap-aliases = true +combine-as-imports = true +split-on-trailing-comma = true + +[lint.flake8-quotes] +inline-quotes = "single" +docstring-quotes = "single" +multiline-quotes = "single" + +[format] +skip-magic-trailing-comma = true +indent-style = "tab" +"#, + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(["format", "--config"]) .arg(&ruff_toml) .arg("-") .pass_stdin(r#" -import os -"#), @r###" +def say_hy(name: str): + print(f"Hy {name}")"#), @r###" + success: true + exit_code: 0 + ----- stdout ----- + def say_hy(name: str): + print(f"Hy {name}") + + ----- stderr ----- + warning: The following rules may cause conflicts when used with the formatter: `COM812`, `D206`, `ISC001`, `W191`. To avoid unexpected behavior, we recommend disabling these rules, either by removing them from the `select` or `extend-select` configuration, or adding then to the `ignore` configuration. + warning: The `flake8-quotes.inline-quotes="single"` option is incompatible with the formatter's `format.quote-style="double"`. We recommend disabling `Q000` and `Q003` when using the formatter, which enforces a consistent quote style. Alternatively, set both options to either `"single"` or `"double"`. + warning: The `flake8-quotes.multiline-quotes="single"` option is incompatible with the formatter. We recommend disabling `Q001` when using the formatter, which enforces double quotes for multiline strings. Alternatively, set the `flake8-quotes.multiline-quotes` option to `"double"`.` + warning: The `flake8-quotes.multiline-quotes="single"` option is incompatible with the formatter. We recommend disabling `Q002` when using the formatter, which enforces double quotes for docstrings. Alternatively, set the `flake8-quotes.docstring-quotes` option to `"double"`.` + warning: The isort option `isort.lines-after-imports` with a value other than `-1`, `1` or `2` is incompatible with the formatter. To avoid unexpected behavior, we recommend setting the option to one of: `2`, `1`, or `-1` (default). + warning: The isort option `isort.lines-between-types` with a value greater than 1 is incompatible with the formatter. To avoid unexpected behavior, we recommend setting the option to one of: `1` or `0` (default). + warning: The isort option `isort.force-wrap-aliases` is incompatible with the formatter `format.skip-magic-trailing-comma=true` option. To avoid unexpected behavior, we recommend either setting `isort.force-wrap-aliases=false` or `format.skip-magic-trailing-comma=false`. + warning: The isort option `isort.split-on-trailing-comma` is incompatible with the formatter `format.skip-magic-trailing-comma=true` option. To avoid unexpected behavior, we recommend either setting `isort.split-on-trailing-comma=false` or `format.skip-magic-trailing-comma=false`. + "###); + Ok(()) +} + +#[test] +fn valid_linter_options() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +[lint] +select = ["ALL"] +ignore = ["D203", "D212", "COM812", "ISC001"] + +[lint.isort] +lines-after-imports = 2 +lines-between-types = 1 +force-wrap-aliases = true +combine-as-imports = true +split-on-trailing-comma = true + +[lint.flake8-quotes] +inline-quotes = "single" +docstring-quotes = "double" +multiline-quotes = "double" + +[format] +skip-magic-trailing-comma = false +quote-style = "single" +"#, + )?; + + let test_path = tempdir.path().join("test.py"); + fs::write( + &test_path, + r#" +def say_hy(name: str): + print(f"Hy {name}")"#, + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(["format", "--no-cache", "--config"]) + .arg(&ruff_toml) + .arg(test_path), @r###" + success: true + exit_code: 0 + ----- stdout ----- + 1 file reformatted + + ----- stderr ----- + "###); + Ok(()) +} + +#[test] +fn all_rules_default_options() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + + fs::write( + &ruff_toml, + r#" +[lint] +select = ["ALL"] +"#, + )?; + + let test_path = tempdir.path().join("test.py"); + fs::write( + &test_path, + r#" +def say_hy(name: str): + print(f"Hy {name}")"#, + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(["format", "--no-cache", "--config"]) + .arg(&ruff_toml) + .arg(test_path), @r###" + success: true + exit_code: 0 + ----- stdout ----- + 1 file reformatted + + ----- stderr ----- + warning: `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. Ignoring `one-blank-line-before-class`. + warning: `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible. Ignoring `multi-line-summary-second-line`. + warning: The following rules may cause conflicts when used with the formatter: `COM812`, `ISC001`. To avoid unexpected behavior, we recommend disabling these rules, either by removing them from the `select` or `extend-select` configuration, or adding then to the `ignore` configuration. + "###); + Ok(()) +} + +#[test] +fn test_diff() { + let args = ["format", "--no-cache", "--isolated", "--diff"]; + let fixtures = Path::new("resources").join("test").join("fixtures"); + let paths = [ + fixtures.join("unformatted.py"), + fixtures.join("formatted.py"), + fixtures.join("unformatted.ipynb"), + ]; + insta::with_settings!({filters => vec![ + // Replace windows paths + (r"\\", "/"), + ]}, { + assert_cmd_snapshot!( + Command::new(get_cargo_bin(BIN_NAME)).args(args).args(paths), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + --- resources/test/fixtures/unformatted.ipynb:cell 1 + +++ resources/test/fixtures/unformatted.ipynb:cell 1 + @@ -1,3 +1,4 @@ + import numpy + -maths = (numpy.arange(100)**2).sum() + -stats= numpy.asarray([1,2,3,4]).median() + + + +maths = (numpy.arange(100) ** 2).sum() + +stats = numpy.asarray([1, 2, 3, 4]).median() + --- resources/test/fixtures/unformatted.ipynb:cell 3 + +++ resources/test/fixtures/unformatted.ipynb:cell 3 + @@ -1,4 +1,6 @@ + # A cell with IPython escape command + def some_function(foo, bar): + pass + + + + + %matplotlib inline + --- resources/test/fixtures/unformatted.ipynb:cell 4 + +++ resources/test/fixtures/unformatted.ipynb:cell 4 + @@ -1,5 +1,10 @@ + foo = %pwd + -def some_function(foo,bar,): + + + + + +def some_function( + + foo, + + bar, + +): + # Another cell with IPython escape command + foo = %pwd + print(foo) + + --- resources/test/fixtures/unformatted.py + +++ resources/test/fixtures/unformatted.py + @@ -1,3 +1,3 @@ + x = 1 + -y=2 + +y = 2 + z = 3 + + + ----- stderr ----- + 2 files would be reformatted, 1 file left unchanged + "###); + }); +} + +#[test] +fn test_diff_no_change() { + let args = ["format", "--no-cache", "--isolated", "--diff"]; + let fixtures = Path::new("resources").join("test").join("fixtures"); + let paths = [fixtures.join("unformatted.py")]; + insta::with_settings!({filters => vec![ + // Replace windows paths + (r"\\", "/"), + ]}, { + assert_cmd_snapshot!( + Command::new(get_cargo_bin(BIN_NAME)).args(args).args(paths), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + --- resources/test/fixtures/unformatted.py + +++ resources/test/fixtures/unformatted.py + @@ -1,3 +1,3 @@ + x = 1 + -y=2 + +y = 2 + z = 3 + + + ----- stderr ----- + 1 file would be reformatted + "### + ); + }); +} + +#[test] +fn test_diff_stdin_unformatted() { + let args = [ + "format", + "--isolated", + "--diff", + "-", + "--stdin-filename", + "unformatted.py", + ]; + let fixtures = Path::new("resources").join("test").join("fixtures"); + let unformatted = fs::read(fixtures.join("unformatted.py")).unwrap(); + assert_cmd_snapshot!( + Command::new(get_cargo_bin(BIN_NAME)).args(args).pass_stdin(unformatted), + @r###" success: false exit_code: 1 ----- stdout ----- - [ - { - "code": "F401", - "end_location": { - "column": 10, - "row": 2 - }, - "filename": "-", - "fix": { - "applicability": "Automatic", - "edits": [ - { - "content": "", - "end_location": { - "column": 1, - "row": 3 - }, - "location": { - "column": 1, - "row": 2 - } - } - ], - "message": "Remove unused import: `os`" - }, - "location": { - "column": 8, - "row": 2 - }, - "message": "`os` imported but unused", - "noqa_row": 2, - "url": "https://docs.astral.sh/ruff/rules/unused-import" - } - ] + --- unformatted.py + +++ unformatted.py + @@ -1,3 +1,3 @@ + x = 1 + -y=2 + +y = 2 + z = 3 + + + ----- stderr ----- + "###); +} + +#[test] +fn test_diff_stdin_formatted() { + let args = ["format", "--isolated", "--diff", "-"]; + let fixtures = Path::new("resources").join("test").join("fixtures"); + let unformatted = fs::read(fixtures.join("formatted.py")).unwrap(); + assert_cmd_snapshot!( + Command::new(get_cargo_bin(BIN_NAME)).args(args).pass_stdin(unformatted), + @r###" + success: true + exit_code: 0 + ----- stdout ----- + ----- stderr ----- - warning: The option `format` has been deprecated to avoid ambiguity with Ruff's upcoming formatter. Use `output-format` instead. "###); - Ok(()) } diff --git a/crates/ruff_cli/tests/integration_test.rs b/crates/ruff_cli/tests/integration_test.rs index 1a4e538bd2ff8..27a1336c3ff63 100644 --- a/crates/ruff_cli/tests/integration_test.rs +++ b/crates/ruff_cli/tests/integration_test.rs @@ -1,6 +1,5 @@ #![cfg(not(target_family = "wasm"))] -#[cfg(unix)] use std::fs; #[cfg(unix)] use std::fs::Permissions; @@ -19,7 +18,6 @@ use clap::Parser; use insta_cmd::{assert_cmd_snapshot, get_cargo_bin}; #[cfg(unix)] use path_absolutize::path_dedot; -#[cfg(unix)] use tempfile::TempDir; #[cfg(unix)] @@ -47,16 +45,16 @@ fn stdin_success() { fn stdin_error() { assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) .args(STDIN_BASE_OPTIONS) - .pass_stdin("import os\n"), @r#" + .pass_stdin("import os\n"), @r###" success: false exit_code: 1 ----- stdout ----- -:1:8: F401 [*] `os` imported but unused Found 1 error. - [*] 1 potentially fixable with the --fix option. + [*] 1 fixable with the `--fix` option. ----- stderr ----- - "#); + "###); } #[test] @@ -70,14 +68,14 @@ fn stdin_filename() { ----- stdout ----- F401.py:1:8: F401 [*] `os` imported but unused Found 1 error. - [*] 1 potentially fixable with the --fix option. + [*] 1 fixable with the `--fix` option. ----- stderr ----- "###); } -#[test] /// Raise `TCH` errors in `.py` files ... +#[test] fn stdin_source_type_py() { assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) .args(STDIN_BASE_OPTIONS) @@ -88,7 +86,7 @@ fn stdin_source_type_py() { ----- stdout ----- TCH.py:1:8: F401 [*] `os` imported but unused Found 1 error. - [*] 1 potentially fixable with the --fix option. + [*] 1 fixable with the `--fix` option. ----- stderr ----- "###); @@ -137,7 +135,7 @@ fn stdin_json() { } #[test] -fn stdin_autofix() { +fn stdin_fix_py() { let args = ["--fix"]; assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) .args(STDIN_BASE_OPTIONS) @@ -151,11 +149,180 @@ fn stdin_autofix() { print(sys.version) ----- stderr ----- + Found 1 error (1 fixed, 0 remaining). + "###); +} + +#[test] +fn stdin_fix_jupyter() { + let args = ["--fix", "--stdin-filename", "Jupyter.ipynb"]; + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(STDIN_BASE_OPTIONS) + .args(args) + .pass_stdin(r#"{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "dccc687c-96e2-4604-b957-a8a89b5bec06", + "metadata": {}, + "outputs": [], + "source": [ + "import os" + ] + }, + { + "cell_type": "markdown", + "id": "19e1b029-f516-4662-a9b9-623b93edac1a", + "metadata": {}, + "source": [ + "Foo" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "cdce7b92-b0fb-4c02-86f6-e233b26fa84f", + "metadata": {}, + "outputs": [], + "source": [ + "import sys" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "e40b33d2-7fe4-46c5-bdf0-8802f3052565", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n" + ] + } + ], + "source": [ + "print(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a1899bc8-d46f-4ec0-b1d1-e1ca0f04bf60", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}"#), @r###" + success: true + exit_code: 0 + ----- stdout ----- + { + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "dccc687c-96e2-4604-b957-a8a89b5bec06", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "19e1b029-f516-4662-a9b9-623b93edac1a", + "metadata": {}, + "source": [ + "Foo" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "cdce7b92-b0fb-4c02-86f6-e233b26fa84f", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "e40b33d2-7fe4-46c5-bdf0-8802f3052565", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n" + ] + } + ], + "source": [ + "print(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a1899bc8-d46f-4ec0-b1d1-e1ca0f04bf60", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 + } + ----- stderr ----- + Found 2 errors (2 fixed, 0 remaining). "###); } #[test] -fn stdin_autofix_when_not_fixable_should_still_print_contents() { +fn stdin_fix_when_not_fixable_should_still_print_contents() { let args = ["--fix"]; assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) .args(STDIN_BASE_OPTIONS) @@ -170,11 +337,13 @@ fn stdin_autofix_when_not_fixable_should_still_print_contents() { print(sys.version) ----- stderr ----- + -:3:4: F634 If test is a tuple, which is always `True` + Found 2 errors (1 fixed, 1 remaining). "###); } #[test] -fn stdin_autofix_when_no_issues_should_still_print_contents() { +fn stdin_fix_when_no_issues_should_still_print_contents() { let args = ["--fix"]; assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) .args(STDIN_BASE_OPTIONS) @@ -191,6 +360,134 @@ fn stdin_autofix_when_no_issues_should_still_print_contents() { "###); } +#[test] +fn stdin_format_jupyter() { + let args = ["format", "--stdin-filename", "Jupyter.ipynb", "--isolated"]; + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(args) + .pass_stdin(r#"{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "dccc687c-96e2-4604-b957-a8a89b5bec06", + "metadata": {}, + "outputs": [], + "source": [ + "x=1" + ] + }, + { + "cell_type": "markdown", + "id": "19e1b029-f516-4662-a9b9-623b93edac1a", + "metadata": {}, + "source": [ + "Foo" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cdce7b92-b0fb-4c02-86f6-e233b26fa84f", + "metadata": {}, + "outputs": [], + "source": [ + "def func():\n", + " pass\n", + "print(1)\n", + "import os" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} +"#), @r###" + success: true + exit_code: 0 + ----- stdout ----- + { + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "dccc687c-96e2-4604-b957-a8a89b5bec06", + "metadata": {}, + "outputs": [], + "source": [ + "x = 1" + ] + }, + { + "cell_type": "markdown", + "id": "19e1b029-f516-4662-a9b9-623b93edac1a", + "metadata": {}, + "source": [ + "Foo" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cdce7b92-b0fb-4c02-86f6-e233b26fa84f", + "metadata": {}, + "outputs": [], + "source": [ + "def func():\n", + " pass\n", + "\n", + "\n", + "print(1)\n", + "import os" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 + } + + ----- stderr ----- + "###); +} + #[test] fn show_source() { let args = ["--show-source"]; @@ -337,8 +634,9 @@ fn nursery_group_selector_preview_enabled() { exit_code: 1 ----- stdout ----- -:1:1: CPY001 Missing copyright notice at top of file - -:1:2: E225 Missing whitespace around operator + -:1:2: E225 [*] Missing whitespace around operator Found 2 errors. + [*] 1 fixable with the `--fix` option. ----- stderr ----- warning: The `NURSERY` selector has been deprecated. @@ -357,8 +655,9 @@ fn preview_enabled_prefix() { exit_code: 1 ----- stdout ----- -:1:1: E741 Ambiguous variable name: `I` - -:1:2: E225 Missing whitespace around operator + -:1:2: E225 [*] Missing whitespace around operator Found 2 errors. + [*] 1 fixable with the `--fix` option. ----- stderr ----- "###); @@ -377,8 +676,9 @@ fn preview_enabled_all() { -:1:1: E741 Ambiguous variable name: `I` -:1:1: D100 Missing docstring in public module -:1:1: CPY001 Missing copyright notice at top of file - -:1:2: E225 Missing whitespace around operator + -:1:2: E225 [*] Missing whitespace around operator Found 4 errors. + [*] 1 fixable with the `--fix` option. ----- stderr ----- warning: `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. Ignoring `one-blank-line-before-class`. @@ -397,8 +697,9 @@ fn preview_enabled_direct() { success: false exit_code: 1 ----- stdout ----- - -:1:2: E225 Missing whitespace around operator + -:1:2: E225 [*] Missing whitespace around operator Found 1 error. + [*] 1 fixable with the `--fix` option. ----- stderr ----- "###); @@ -438,6 +739,42 @@ fn preview_disabled_prefix_empty() { "###); } +#[test] +fn preview_disabled_does_not_warn_for_empty_ignore_selections() { + // Does not warn that the selection is empty since the user is not trying to enable the rule + let args = ["--ignore", "CPY"]; + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(STDIN_BASE_OPTIONS) + .args(args) + .pass_stdin("I=42\n"), @r###" + success: false + exit_code: 1 + ----- stdout ----- + -:1:1: E741 Ambiguous variable name: `I` + Found 1 error. + + ----- stderr ----- + "###); +} + +#[test] +fn preview_disabled_does_not_warn_for_empty_fixable_selections() { + // Does not warn that the selection is empty since the user is not trying to enable the rule + let args = ["--fixable", "CPY"]; + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(STDIN_BASE_OPTIONS) + .args(args) + .pass_stdin("I=42\n"), @r###" + success: false + exit_code: 1 + ----- stdout ----- + -:1:1: E741 Ambiguous variable name: `I` + Found 1 error. + + ----- stderr ----- + "###); +} + #[test] fn preview_group_selector() { // `--select PREVIEW` should error (selector was removed) @@ -566,7 +903,7 @@ fn check_input_from_argfile() -> Result<()> { ----- stdout ----- /path/to/a.py:1:8: F401 [*] `os` imported but unused Found 1 error. - [*] 1 potentially fixable with the --fix option. + [*] 1 fixable with the `--fix` option. ----- stderr ----- "###); @@ -574,3 +911,499 @@ fn check_input_from_argfile() -> Result<()> { Ok(()) } + +#[test] +fn check_hints_hidden_unsafe_fixes() { + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args([ + "-", + "--output-format=text", + "--isolated", + "--select", + "F601,UP034", + "--no-cache", + ]) + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + -:1:14: F601 Dictionary key literal `'a'` repeated + -:2:7: UP034 [*] Avoid extraneous parentheses + Found 2 errors. + [*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option). + + ----- stderr ----- + "###); +} + +#[test] +fn check_hints_hidden_unsafe_fixes_with_no_safe_fixes() { + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(["-", "--output-format", "text", "--no-cache", "--isolated", "--select", "F601"]) + .pass_stdin("x = {'a': 1, 'a': 1}\n"), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + -:1:14: F601 Dictionary key literal `'a'` repeated + Found 1 error. + No fixes available (1 hidden fix can be enabled with the `--unsafe-fixes` option). + + ----- stderr ----- + "###); +} + +#[test] +fn check_shows_unsafe_fixes_with_opt_in() { + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args([ + "-", + "--output-format=text", + "--isolated", + "--select", + "F601,UP034", + "--no-cache", + "--unsafe-fixes", + ]) + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + -:1:14: F601 [*] Dictionary key literal `'a'` repeated + -:2:7: UP034 [*] Avoid extraneous parentheses + Found 2 errors. + [*] 2 fixable with the --fix option. + + ----- stderr ----- + "###); +} + +#[test] +fn fix_applies_safe_fixes_by_default() { + assert_cmd_snapshot!( + Command::new(get_cargo_bin(BIN_NAME)) + .args([ + "-", + "--output-format", + "text", + "--isolated", + "--no-cache", + "--select", + "F601,UP034", + "--fix", + ]) + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + x = {'a': 1, 'a': 1} + print('foo') + + ----- stderr ----- + -:1:14: F601 Dictionary key literal `'a'` repeated + Found 2 errors (1 fixed, 1 remaining). + No fixes available (1 hidden fix can be enabled with the `--unsafe-fixes` option). + "###); +} + +#[test] +fn fix_applies_unsafe_fixes_with_opt_in() { + assert_cmd_snapshot!( + Command::new(get_cargo_bin(BIN_NAME)) + .args([ + "-", + "--output-format", + "text", + "--isolated", + "--no-cache", + "--select", + "F601,UP034", + "--fix", + "--unsafe-fixes", + ]) + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" + success: true + exit_code: 0 + ----- stdout ----- + x = {'a': 1} + print('foo') + + ----- stderr ----- + Found 2 errors (2 fixed, 0 remaining). + "###); +} + +#[test] +fn fix_does_not_apply_display_only_fixes() { + assert_cmd_snapshot!( + Command::new(get_cargo_bin(BIN_NAME)) + .args([ + "-", + "--output-format", + "text", + "--isolated", + "--no-cache", + "--select", + "B006", + "--fix", + ]) + .pass_stdin("def add_to_list(item, some_list=[]): ..."), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + def add_to_list(item, some_list=[]): ... + ----- stderr ----- + -:1:33: B006 Do not use mutable data structures for argument defaults + Found 1 error. + "###); +} + +#[test] +fn fix_does_not_apply_display_only_fixes_with_unsafe_fixes_enabled() { + assert_cmd_snapshot!( + Command::new(get_cargo_bin(BIN_NAME)) + .args([ + "-", + "--output-format", + "text", + "--isolated", + "--no-cache", + "--select", + "B006", + "--fix", + "--unsafe-fixes", + ]) + .pass_stdin("def add_to_list(item, some_list=[]): ..."), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + def add_to_list(item, some_list=[]): ... + ----- stderr ----- + -:1:33: B006 Do not use mutable data structures for argument defaults + Found 1 error. + "###); +} + +#[test] +fn fix_only_unsafe_fixes_available() { + assert_cmd_snapshot!( + Command::new(get_cargo_bin(BIN_NAME)) + .args([ + "-", + "--output-format", + "text", + "--isolated", + "--no-cache", + "--select", + "F601", + "--fix", + ]) + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + x = {'a': 1, 'a': 1} + print(('foo')) + + ----- stderr ----- + -:1:14: F601 Dictionary key literal `'a'` repeated + Found 1 error. + No fixes available (1 hidden fix can be enabled with the `--unsafe-fixes` option). + "###); +} + +#[test] +fn fix_only_flag_applies_safe_fixes_by_default() { + assert_cmd_snapshot!( + Command::new(get_cargo_bin(BIN_NAME)) + .args([ + "-", + "--output-format", + "text", + "--isolated", + "--no-cache", + "--select", + "F601,UP034", + "--fix-only", + ]) + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" + success: true + exit_code: 0 + ----- stdout ----- + x = {'a': 1, 'a': 1} + print('foo') + + ----- stderr ----- + Fixed 1 error (1 additional fix available with `--unsafe-fixes`). + "###); +} + +#[test] +fn fix_only_flag_applies_unsafe_fixes_with_opt_in() { + assert_cmd_snapshot!( + Command::new(get_cargo_bin(BIN_NAME)) + .args([ + "-", + "--output-format", + "text", + "--isolated", + "--no-cache", + "--select", + "F601,UP034", + "--fix-only", + "--unsafe-fixes", + ]) + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" + success: true + exit_code: 0 + ----- stdout ----- + x = {'a': 1} + print('foo') + + ----- stderr ----- + Fixed 2 errors. + "###); +} + +#[test] +fn diff_shows_safe_fixes_by_default() { + assert_cmd_snapshot!( + Command::new(get_cargo_bin(BIN_NAME)) + .args([ + "-", + "--output-format", + "text", + "--isolated", + "--no-cache", + "--select", + "F601,UP034", + "--diff", + ]) + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + @@ -1,2 +1,2 @@ + x = {'a': 1, 'a': 1} + -print(('foo')) + +print('foo') + + + ----- stderr ----- + Would fix 1 error (1 additional fix available with `--unsafe-fixes`). + "### + ); +} + +#[test] +fn diff_shows_unsafe_fixes_with_opt_in() { + assert_cmd_snapshot!( + Command::new(get_cargo_bin(BIN_NAME)) + .args([ + "-", + "--output-format", + "text", + "--isolated", + "--no-cache", + "--select", + "F601,UP034", + "--diff", + "--unsafe-fixes", + ]) + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + @@ -1,2 +1,2 @@ + -x = {'a': 1, 'a': 1} + -print(('foo')) + +x = {'a': 1} + +print('foo') + + + ----- stderr ----- + Would fix 2 errors. + "### + ); +} + +#[test] +fn diff_does_not_show_display_only_fixes_with_unsafe_fixes_enabled() { + assert_cmd_snapshot!( + Command::new(get_cargo_bin(BIN_NAME)) + .args([ + "-", + "--output-format", + "text", + "--isolated", + "--no-cache", + "--select", + "B006", + "--diff", + "--unsafe-fixes", + ]) + .pass_stdin("def add_to_list(item, some_list=[]): ..."), + @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + "###); +} + +#[test] +fn diff_only_unsafe_fixes_available() { + assert_cmd_snapshot!( + Command::new(get_cargo_bin(BIN_NAME)) + .args([ + "-", + "--output-format", + "text", + "--isolated", + "--no-cache", + "--select", + "F601", + "--diff", + ]) + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + No errors would be fixed (1 fix available with `--unsafe-fixes`). + "### + ); +} + +#[test] +fn check_extend_unsafe_fixes() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +[lint] +extend-unsafe-fixes = ["UP034"] +"#, + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(["check", "--config"]) + .arg(&ruff_toml) + .arg("-") + .args([ + "--output-format", + "text", + "--no-cache", + "--select", + "F601,UP034", + ]) + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + -:1:14: F601 Dictionary key literal `'a'` repeated + -:2:7: UP034 Avoid extraneous parentheses + Found 2 errors. + No fixes available (2 hidden fixes can be enabled with the `--unsafe-fixes` option). + + ----- stderr ----- + "###); + + Ok(()) +} + +#[test] +fn check_extend_safe_fixes() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +[lint] +extend-safe-fixes = ["F601"] +"#, + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(["check", "--config"]) + .arg(&ruff_toml) + .arg("-") + .args([ + "--output-format", + "text", + "--no-cache", + "--select", + "F601,UP034", + ]) + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + -:1:14: F601 [*] Dictionary key literal `'a'` repeated + -:2:7: UP034 [*] Avoid extraneous parentheses + Found 2 errors. + [*] 2 fixable with the `--fix` option. + + ----- stderr ----- + "###); + + Ok(()) +} + +#[test] +fn check_extend_unsafe_fixes_conflict_with_extend_safe_fixes() -> Result<()> { + // Adding a rule to both options should result in it being treated as unsafe + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +[lint] +extend-unsafe-fixes = ["UP034"] +extend-safe-fixes = ["UP034"] +"#, + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(["check", "--config"]) + .arg(&ruff_toml) + .arg("-") + .args([ + "--output-format", + "text", + "--no-cache", + "--select", + "F601,UP034", + ]) + .pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\n"), + @r###" + success: false + exit_code: 1 + ----- stdout ----- + -:1:14: F601 Dictionary key literal `'a'` repeated + -:2:7: UP034 Avoid extraneous parentheses + Found 2 errors. + No fixes available (2 hidden fixes can be enabled with the `--unsafe-fixes` option). + + ----- stderr ----- + "###); + + Ok(()) +} diff --git a/crates/ruff_cli/tests/lint.rs b/crates/ruff_cli/tests/lint.rs new file mode 100644 index 0000000000000..f6a7a2a99f60f --- /dev/null +++ b/crates/ruff_cli/tests/lint.rs @@ -0,0 +1,310 @@ +//! Tests the interaction of the `lint` configuration section + +#![cfg(not(target_family = "wasm"))] + +use std::fs; +use std::process::Command; +use std::str; + +use anyhow::Result; +use insta_cmd::{assert_cmd_snapshot, get_cargo_bin}; +use tempfile::TempDir; + +const BIN_NAME: &str = "ruff"; +const STDIN_BASE_OPTIONS: &[&str] = &["--no-cache", "--output-format", "text"]; + +#[test] +fn top_level_options() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +extend-select = ["B", "Q"] + +[flake8-quotes] +inline-quotes = "single" +"#, + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(STDIN_BASE_OPTIONS) + .arg("--config") + .arg(&ruff_toml) + .args(["--stdin-filename", "test.py"]) + .arg("-") + .pass_stdin(r#"a = "abcba".strip("aba")"#), @r###" + success: false + exit_code: 1 + ----- stdout ----- + test.py:1:5: Q000 [*] Double quotes found but single quotes preferred + test.py:1:5: B005 Using `.strip()` with multi-character strings is misleading + test.py:1:19: Q000 [*] Double quotes found but single quotes preferred + Found 3 errors. + [*] 2 fixable with the `--fix` option. + + ----- stderr ----- + "###); + Ok(()) +} + +#[test] +fn lint_options() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +[lint] +extend-select = ["B", "Q"] + +[lint.flake8-quotes] +inline-quotes = "single" +"#, + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(STDIN_BASE_OPTIONS) + .arg("--config") + .arg(&ruff_toml) + .arg("-") + .pass_stdin(r#"a = "abcba".strip("aba")"#), @r###" + success: false + exit_code: 1 + ----- stdout ----- + -:1:5: Q000 [*] Double quotes found but single quotes preferred + -:1:5: B005 Using `.strip()` with multi-character strings is misleading + -:1:19: Q000 [*] Double quotes found but single quotes preferred + Found 3 errors. + [*] 2 fixable with the `--fix` option. + + ----- stderr ----- + "###); + Ok(()) +} + +/// Tests that configurations from the top-level and `lint` section are merged together. +#[test] +fn mixed_levels() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +extend-select = ["B", "Q"] + +[lint.flake8-quotes] +inline-quotes = "single" +"#, + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(STDIN_BASE_OPTIONS) + .arg("--config") + .arg(&ruff_toml) + .arg("-") + .pass_stdin(r#"a = "abcba".strip("aba")"#), @r###" + success: false + exit_code: 1 + ----- stdout ----- + -:1:5: Q000 [*] Double quotes found but single quotes preferred + -:1:5: B005 Using `.strip()` with multi-character strings is misleading + -:1:19: Q000 [*] Double quotes found but single quotes preferred + Found 3 errors. + [*] 2 fixable with the `--fix` option. + + ----- stderr ----- + "###); + Ok(()) +} + +/// Tests that options in the `lint` section have higher precedence than top-level options (because they are more specific). +#[test] +fn precedence() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +[lint] +extend-select = ["B", "Q"] + +[flake8-quotes] +inline-quotes = "double" + +[lint.flake8-quotes] +inline-quotes = "single" +"#, + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(STDIN_BASE_OPTIONS) + .arg("--config") + .arg(&ruff_toml) + .arg("-") + .pass_stdin(r#"a = "abcba".strip("aba")"#), @r###" + success: false + exit_code: 1 + ----- stdout ----- + -:1:5: Q000 [*] Double quotes found but single quotes preferred + -:1:5: B005 Using `.strip()` with multi-character strings is misleading + -:1:19: Q000 [*] Double quotes found but single quotes preferred + Found 3 errors. + [*] 2 fixable with the `--fix` option. + + ----- stderr ----- + "###); + Ok(()) +} + +#[test] +fn exclude() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +extend-select = ["B", "Q"] +extend-exclude = ["out"] + +[lint] +exclude = ["test.py", "generated.py"] + +[lint.flake8-quotes] +inline-quotes = "single" +"#, + )?; + + fs::write( + tempdir.path().join("main.py"), + r#" +from test import say_hy + +if __name__ == "__main__": + say_hy("dear Ruff contributor") +"#, + )?; + + // Excluded file but passed to the CLI directly, should be linted + let test_path = tempdir.path().join("test.py"); + fs::write( + &test_path, + r#" +def say_hy(name: str): + print(f"Hy {name}")"#, + )?; + + fs::write( + tempdir.path().join("generated.py"), + r#"NUMBERS = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 +] +OTHER = "OTHER" +"#, + )?; + + let out_dir = tempdir.path().join("out"); + fs::create_dir(&out_dir)?; + + fs::write(out_dir.join("a.py"), r#"a = "a""#)?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .current_dir(tempdir.path()) + .arg("check") + .args(STDIN_BASE_OPTIONS) + .args(["--config", &ruff_toml.file_name().unwrap().to_string_lossy()]) + // Explicitly pass test.py, should be linted regardless of it being excluded by lint.exclude + .arg(test_path.file_name().unwrap()) + // Lint all other files in the directory, should respect the `exclude` and `lint.exclude` options + .arg("."), @r###" + success: false + exit_code: 1 + ----- stdout ----- + main.py:4:16: Q000 [*] Double quotes found but single quotes preferred + main.py:5:12: Q000 [*] Double quotes found but single quotes preferred + test.py:3:15: Q000 [*] Double quotes found but single quotes preferred + Found 3 errors. + [*] 3 fixable with the `--fix` option. + + ----- stderr ----- + "###); + Ok(()) +} + +#[test] +fn exclude_stdin() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +extend-select = ["B", "Q"] + +[lint] +exclude = ["generated.py"] + +[lint.flake8-quotes] +inline-quotes = "single" +"#, + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .current_dir(tempdir.path()) + .arg("check") + .args(STDIN_BASE_OPTIONS) + .args(["--config", &ruff_toml.file_name().unwrap().to_string_lossy()]) + .args(["--stdin-filename", "generated.py"]) + .arg("-") + .pass_stdin(r#" +from test import say_hy + +if __name__ == "__main__": + say_hy("dear Ruff contributor") +"#), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + "###); + Ok(()) +} + +#[test] +fn line_too_long_width_override() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +line-length = 80 +select = ["E501"] + +[pycodestyle] +max-line-length = 100 +"#, + )?; + + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .args(STDIN_BASE_OPTIONS) + .arg("--config") + .arg(&ruff_toml) + .args(["--stdin-filename", "test.py"]) + .arg("-") + .pass_stdin(r#" +# longer than 80, but less than 100 +_ = "---------------------------------------------------------------------------亜亜亜亜亜亜" +# longer than 100 +_ = "---------------------------------------------------------------------------亜亜亜亜亜亜亜亜亜亜亜亜亜亜" +"#), @r###" + success: false + exit_code: 1 + ----- stdout ----- + test.py:5:91: E501 Line too long (109 > 100) + Found 1 error. + + ----- stderr ----- + "###); + Ok(()) +} diff --git a/crates/ruff_cli/tests/snapshots/integration_test__explain_status_codes_f401.snap b/crates/ruff_cli/tests/snapshots/integration_test__explain_status_codes_f401.snap index 17615bf57049e..f8e0c12dc7021 100644 --- a/crates/ruff_cli/tests/snapshots/integration_test__explain_status_codes_f401.snap +++ b/crates/ruff_cli/tests/snapshots/integration_test__explain_status_codes_f401.snap @@ -13,7 +13,7 @@ exit_code: 0 Derived from the **Pyflakes** linter. -Autofix is sometimes available. +Fix is sometimes available. ## What it does Checks for unused imports. diff --git a/crates/ruff_cli/tests/snapshots/integration_test__stdin_json.snap b/crates/ruff_cli/tests/snapshots/integration_test__stdin_json.snap index 01a422aa42629..c374117787954 100644 --- a/crates/ruff_cli/tests/snapshots/integration_test__stdin_json.snap +++ b/crates/ruff_cli/tests/snapshots/integration_test__stdin_json.snap @@ -6,7 +6,7 @@ info: - "-" - "--isolated" - "--no-cache" - - "--format" + - "--output-format" - json - "--stdin-filename" - F401.py @@ -17,6 +17,7 @@ exit_code: 1 ----- stdout ----- [ { + "cell": null, "code": "F401", "end_location": { "column": 10, @@ -24,7 +25,7 @@ exit_code: 1 }, "filename": "/path/to/F401.py", "fix": { - "applicability": "Automatic", + "applicability": "safe", "edits": [ { "content": "", diff --git a/crates/ruff_dev/src/format_dev.rs b/crates/ruff_dev/src/format_dev.rs index 00f0e610b8524..5589254b05284 100644 --- a/crates/ruff_dev/src/format_dev.rs +++ b/crates/ruff_dev/src/format_dev.rs @@ -11,7 +11,6 @@ use std::{fmt, fs, io, iter}; use anyhow::{bail, format_err, Context, Error}; use clap::{CommandFactory, FromArgMatches}; -use ignore::DirEntry; use imara_diff::intern::InternedInput; use imara_diff::sink::Counter; use imara_diff::{diff, Algorithm}; @@ -34,16 +33,16 @@ use ruff_formatter::{FormatError, LineWidth, PrintError}; use ruff_linter::logging::LogLevel; use ruff_linter::settings::types::{FilePattern, FilePatternSet}; use ruff_python_formatter::{ - format_module, FormatModuleError, MagicTrailingComma, PyFormatOptions, + format_module_source, FormatModuleError, MagicTrailingComma, PreviewMode, PyFormatOptions, }; -use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig, Resolver}; +use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig, ResolvedFile, Resolver}; /// Find files that ruff would check so we can format them. Adapted from `ruff_cli`. #[allow(clippy::type_complexity)] fn ruff_check_paths( dirs: &[PathBuf], ) -> anyhow::Result<( - Vec>, + Vec>, Resolver, PyprojectConfig, )> { @@ -467,9 +466,9 @@ fn format_dev_project( let iter = { paths.into_par_iter() }; #[cfg(feature = "singlethreaded")] let iter = { paths.into_iter() }; - iter.map(|dir_entry| { + iter.map(|path| { let result = format_dir_entry( - dir_entry, + path, stability_check, write, &black_options, @@ -527,24 +526,20 @@ fn format_dev_project( /// Error handling in between walkdir and `format_dev_file` fn format_dir_entry( - dir_entry: Result, + resolved_file: Result, stability_check: bool, write: bool, options: &BlackOptions, resolver: &Resolver, pyproject_config: &PyprojectConfig, ) -> anyhow::Result<(Result, PathBuf), Error> { - let dir_entry = match dir_entry.context("Iterating the files in the repository failed") { - Ok(dir_entry) => dir_entry, - Err(err) => return Err(err), - }; - let file = dir_entry.path().to_path_buf(); + let resolved_file = resolved_file.context("Iterating the files in the repository failed")?; // For some reason it does not filter in the beginning - if dir_entry.file_name() == "pyproject.toml" { - return Ok((Ok(Statistics::default()), file)); + if resolved_file.file_name() == "pyproject.toml" { + return Ok((Ok(Statistics::default()), resolved_file.into_path())); } - let path = dir_entry.path().to_path_buf(); + let path = resolved_file.into_path(); let mut options = options.to_py_format_options(&path); let settings = resolver.resolve(&path, pyproject_config); @@ -799,7 +794,7 @@ fn format_dev_file( let content = fs::read_to_string(input_path)?; #[cfg(not(debug_assertions))] let start = Instant::now(); - let printed = match format_module(&content, options.clone()) { + let printed = match format_module_source(&content, options.clone()) { Ok(printed) => printed, Err(err @ (FormatModuleError::LexError(_) | FormatModuleError::ParseError(_))) => { return Err(CheckFileError::SyntaxErrorInInput(err)); @@ -826,7 +821,7 @@ fn format_dev_file( } if stability_check { - let reformatted = match format_module(formatted, options) { + let reformatted = match format_module_source(formatted, options) { Ok(reformatted) => reformatted, Err(err @ (FormatModuleError::LexError(_) | FormatModuleError::ParseError(_))) => { return Err(CheckFileError::SyntaxErrorInOutput { @@ -876,9 +871,7 @@ struct BlackOptions { line_length: NonZeroU16, #[serde(alias = "skip-magic-trailing-comma")] skip_magic_trailing_comma: bool, - #[allow(unused)] - #[serde(alias = "force-exclude")] - force_exclude: Option, + preview: bool, } impl Default for BlackOptions { @@ -886,7 +879,7 @@ impl Default for BlackOptions { Self { line_length: NonZeroU16::new(88).unwrap(), skip_magic_trailing_comma: false, - force_exclude: None, + preview: false, } } } @@ -934,6 +927,11 @@ impl BlackOptions { } else { MagicTrailingComma::Respect }) + .with_preview(if self.preview { + PreviewMode::Enabled + } else { + PreviewMode::Disabled + }) } } diff --git a/crates/ruff_dev/src/generate_cli_help.rs b/crates/ruff_dev/src/generate_cli_help.rs index 420927495ffbd..1493a3814023b 100644 --- a/crates/ruff_dev/src/generate_cli_help.rs +++ b/crates/ruff_dev/src/generate_cli_help.rs @@ -16,8 +16,11 @@ use crate::ROOT_DIR; const COMMAND_HELP_BEGIN_PRAGMA: &str = "\n"; const COMMAND_HELP_END_PRAGMA: &str = ""; -const SUBCOMMAND_HELP_BEGIN_PRAGMA: &str = "\n"; -const SUBCOMMAND_HELP_END_PRAGMA: &str = ""; +const CHECK_HELP_BEGIN_PRAGMA: &str = "\n"; +const CHECK_HELP_END_PRAGMA: &str = ""; + +const FORMAT_HELP_BEGIN_PRAGMA: &str = "\n"; +const FORMAT_HELP_END_PRAGMA: &str = ""; #[derive(clap::Args)] pub(crate) struct Args { @@ -56,11 +59,15 @@ pub(super) fn main(args: &Args) -> Result<()> { let command_help = trim_lines(&help_text()); // Generate `ruff help check`. - let subcommand_help = trim_lines(&check_help_text()); + let check_help = trim_lines(&subcommand_help_text("check")?); + + // Generate `ruff help format`. + let format_help = trim_lines(&subcommand_help_text("format")?); if args.mode.is_dry_run() { print!("{command_help}"); - print!("{subcommand_help}"); + print!("{check_help}"); + print!("{format_help}"); return Ok(()); } @@ -77,9 +84,15 @@ pub(super) fn main(args: &Args) -> Result<()> { )?; let new = replace_docs_section( &new, - &format!("```text\n{subcommand_help}\n```\n\n"), - SUBCOMMAND_HELP_BEGIN_PRAGMA, - SUBCOMMAND_HELP_END_PRAGMA, + &format!("```text\n{check_help}\n```\n\n"), + CHECK_HELP_BEGIN_PRAGMA, + CHECK_HELP_END_PRAGMA, + )?; + let new = replace_docs_section( + &new, + &format!("```text\n{format_help}\n```\n\n"), + FORMAT_HELP_BEGIN_PRAGMA, + FORMAT_HELP_END_PRAGMA, )?; match args.mode { @@ -104,18 +117,19 @@ fn help_text() -> String { args::Args::command().render_help().to_string() } -/// Returns the output of `ruff help check`. -fn check_help_text() -> String { +/// Returns the output of a given subcommand (e.g., `ruff help check`). +fn subcommand_help_text(subcommand: &str) -> Result { let mut cmd = args::Args::command(); // The build call is necessary for the help output to contain `Usage: ruff // check` instead of `Usage: check` see https://github.com/clap-rs/clap/issues/4685 cmd.build(); - cmd.find_subcommand_mut("check") - .expect("`check` subcommand not found") + Ok(cmd + .find_subcommand_mut(subcommand) + .with_context(|| format!("Unable to find subcommand `{subcommand}`"))? .render_help() - .to_string() + .to_string()) } #[cfg(test)] diff --git a/crates/ruff_dev/src/generate_docs.rs b/crates/ruff_dev/src/generate_docs.rs index b6b70c7f4e324..1b557b68bcccb 100644 --- a/crates/ruff_dev/src/generate_docs.rs +++ b/crates/ruff_dev/src/generate_docs.rs @@ -8,10 +8,10 @@ use anyhow::Result; use regex::{Captures, Regex}; use strum::IntoEnumIterator; -use ruff_diagnostics::AutofixKind; +use ruff_diagnostics::FixAvailability; use ruff_linter::registry::{Linter, Rule, RuleNamespace}; use ruff_workspace::options::Options; -use ruff_workspace::options_base::OptionsMetadata; +use ruff_workspace::options_base::{OptionEntry, OptionsMetadata}; use crate::ROOT_DIR; @@ -37,22 +37,29 @@ pub(crate) fn main(args: &Args) -> Result<()> { output.push('\n'); } - let autofix = rule.autofixable(); - if matches!(autofix, AutofixKind::Always | AutofixKind::Sometimes) { - output.push_str(&autofix.to_string()); + let fix_availability = rule.fixable(); + if matches!( + fix_availability, + FixAvailability::Always | FixAvailability::Sometimes + ) { + output.push_str(&fix_availability.to_string()); output.push('\n'); output.push('\n'); } - if rule.is_preview() { + if rule.is_preview() || rule.is_nursery() { output.push_str( - r#"This rule is in preview and is not stable. The `--preview` flag is required for use."#, + r#"This rule is unstable and in [preview](../preview.md). The `--preview` flag is required for use."#, ); output.push('\n'); output.push('\n'); } - process_documentation(explanation.trim(), &mut output); + process_documentation( + explanation.trim(), + &mut output, + &rule.noqa_code().to_string(), + ); let filename = PathBuf::from(ROOT_DIR) .join("docs") @@ -71,7 +78,7 @@ pub(crate) fn main(args: &Args) -> Result<()> { Ok(()) } -fn process_documentation(documentation: &str, out: &mut String) { +fn process_documentation(documentation: &str, out: &mut String, rule_name: &str) { let mut in_options = false; let mut after = String::new(); @@ -97,7 +104,17 @@ fn process_documentation(documentation: &str, out: &mut String) { if let Some(rest) = line.strip_prefix("- `") { let option = rest.trim_end().trim_end_matches('`'); - assert!(Options::metadata().has(option), "unknown option {option}"); + match Options::metadata().find(option) { + Some(OptionEntry::Field(field)) => { + if field.deprecated.is_some() { + eprintln!("Rule {rule_name} references deprecated option {option}."); + } + } + Some(_) => {} + None => { + panic!("Unknown option {option} referenced by rule {rule_name}"); + } + } let anchor = option.replace('.', "-"); out.push_str(&format!("- [`{option}`][{option}]\n")); @@ -135,6 +152,7 @@ Something [`else`][other]. [other]: http://example.com.", &mut output, + "example", ); assert_eq!( output, diff --git a/crates/ruff_dev/src/generate_options.rs b/crates/ruff_dev/src/generate_options.rs index ea135d5ba44de..38737fb439d69 100644 --- a/crates/ruff_dev/src/generate_options.rs +++ b/crates/ruff_dev/src/generate_options.rs @@ -14,7 +14,11 @@ pub(crate) fn generate() -> String { } fn generate_set(output: &mut String, set: &Set) { - writeln!(output, "### {title}\n", title = set.title()).unwrap(); + if set.level() < 2 { + writeln!(output, "### {title}\n", title = set.title()).unwrap(); + } else { + writeln!(output, "#### {title}\n", title = set.title()).unwrap(); + } if let Some(documentation) = set.metadata().documentation() { output.push_str(documentation); @@ -32,58 +36,89 @@ fn generate_set(output: &mut String, set: &Set) { // Generate the fields. for (name, field) in &fields { - emit_field(output, name, field, set.name()); + emit_field(output, name, field, set); output.push_str("---\n\n"); } // Generate all the sub-sets. for (set_name, sub_set) in &sets { - generate_set(output, &Set::Named(set_name, *sub_set)); + generate_set(output, &Set::Named(set_name, *sub_set, set.level() + 1)); } } enum Set<'a> { Toplevel(OptionSet), - Named(&'a str, OptionSet), + Named(&'a str, OptionSet, u32), } impl<'a> Set<'a> { fn name(&self) -> Option<&'a str> { match self { Set::Toplevel(_) => None, - Set::Named(name, _) => Some(name), + Set::Named(name, _, _) => Some(name), } } fn title(&self) -> &'a str { match self { Set::Toplevel(_) => "Top-level", - Set::Named(name, _) => name, + Set::Named(name, _, _) => name, } } fn metadata(&self) -> &OptionSet { match self { Set::Toplevel(set) => set, - Set::Named(_, set) => set, + Set::Named(_, set, _) => set, + } + } + + fn level(&self) -> u32 { + match self { + Set::Toplevel(_) => 0, + Set::Named(_, _, level) => *level, } } } -fn emit_field(output: &mut String, name: &str, field: &OptionField, group_name: Option<&str>) { - // if there's a group name, we need to add it to the anchor - if let Some(group_name) = group_name { +fn emit_field(output: &mut String, name: &str, field: &OptionField, parent_set: &Set) { + let header_level = if parent_set.level() < 2 { + "####" + } else { + "#####" + }; + + // if there's a set name, we need to add it to the anchor + if let Some(set_name) = parent_set.name() { // the anchor used to just be the name, but now it's the group name // for backwards compatibility, we need to keep the old anchor output.push_str(&format!("\n")); output.push_str(&format!( - "#### [`{name}`](#{group_name}-{name}) {{: #{group_name}-{name} }}\n" + "{header_level} [`{name}`](#{set_name}-{name}) {{: #{set_name}-{name} }}\n" )); } else { - output.push_str(&format!("#### [`{name}`](#{name})\n")); + output.push_str(&format!("{header_level} [`{name}`](#{name})\n")); } output.push('\n'); + + if let Some(deprecated) = &field.deprecated { + output.push_str("!!! warning \"Deprecated\"\n"); + output.push_str(" This option has been deprecated"); + + if let Some(since) = deprecated.since { + write!(output, " in {since}").unwrap(); + } + + output.push('.'); + + if let Some(message) = deprecated.message { + writeln!(output, " {message}").unwrap(); + } + + output.push('\n'); + } + output.push_str(field.doc); output.push_str("\n\n"); output.push_str(&format!("**Default value**: `{}`\n", field.default)); @@ -92,8 +127,8 @@ fn emit_field(output: &mut String, name: &str, field: &OptionField, group_name: output.push('\n'); output.push_str(&format!( "**Example usage**:\n\n```toml\n[tool.ruff{}]\n{}\n```\n", - if group_name.is_some() { - format!(".{}", group_name.unwrap()) + if let Some(set_name) = parent_set.name() { + format!(".{set_name}") } else { String::new() }, diff --git a/crates/ruff_dev/src/generate_rules_table.rs b/crates/ruff_dev/src/generate_rules_table.rs index 82addce497d4d..8959796c4f967 100644 --- a/crates/ruff_dev/src/generate_rules_table.rs +++ b/crates/ruff_dev/src/generate_rules_table.rs @@ -5,7 +5,7 @@ use itertools::Itertools; use strum::IntoEnumIterator; -use ruff_diagnostics::AutofixKind; +use ruff_diagnostics::FixAvailability; use ruff_linter::registry::{Linter, Rule, RuleNamespace}; use ruff_linter::upstream_categories::UpstreamCategoryAndPrefix; use ruff_workspace::options::Options; @@ -20,16 +20,18 @@ fn generate_table(table_out: &mut String, rules: impl IntoIterator, table_out.push_str("| ---- | ---- | ------- | ------: |"); table_out.push('\n'); for rule in rules { - let fix_token = match rule.autofixable() { - AutofixKind::Always | AutofixKind::Sometimes => { - format!("{FIX_SYMBOL}") + let fix_token = match rule.fixable() { + FixAvailability::Always | FixAvailability::Sometimes => { + format!("{FIX_SYMBOL}") + } + FixAvailability::None => { + format!("") } - AutofixKind::None => format!("{FIX_SYMBOL}"), }; let preview_token = if rule.is_preview() || rule.is_nursery() { - format!("{PREVIEW_SYMBOL}") + format!("{PREVIEW_SYMBOL}") } else { - format!("{PREVIEW_SYMBOL}") + format!("") }; let status_token = format!("{fix_token} {preview_token}"); @@ -62,7 +64,7 @@ pub(crate) fn generate() -> String { table_out.push('\n'); table_out.push_str(&format!( - "The {PREVIEW_SYMBOL} emoji indicates that a rule in [\"preview\"](faq.md#what-is-preview)." + "The {PREVIEW_SYMBOL} emoji indicates that a rule is in [\"preview\"](faq.md#what-is-preview)." )); table_out.push('\n'); table_out.push('\n'); diff --git a/crates/ruff_diagnostics/Cargo.toml b/crates/ruff_diagnostics/Cargo.toml index 4d548f41b6292..9a2e22e2340fb 100644 --- a/crates/ruff_diagnostics/Cargo.toml +++ b/crates/ruff_diagnostics/Cargo.toml @@ -17,4 +17,5 @@ ruff_text_size = { path = "../ruff_text_size" } anyhow = { workspace = true } log = { workspace = true } +is-macro = { workspace = true } serde = { workspace = true, optional = true, features = [] } diff --git a/crates/ruff_diagnostics/src/fix.rs b/crates/ruff_diagnostics/src/fix.rs index d553e83d6696f..befb5c1c5650d 100644 --- a/crates/ruff_diagnostics/src/fix.rs +++ b/crates/ruff_diagnostics/src/fix.rs @@ -5,27 +5,22 @@ use ruff_text_size::{Ranged, TextSize}; use crate::edit::Edit; -/// Indicates confidence in the correctness of a suggested fix. -#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +/// Indicates if a fix can be applied. +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, is_macro::Is)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))] pub enum Applicability { - /// The fix is definitely what the user intended, or maintains the exact meaning of the code. - /// This fix should be automatically applied. - Automatic, - - /// The fix may be what the user intended, but it is uncertain. - /// The fix should result in valid code if it is applied. - /// The fix can be applied with user opt-in. - Suggested, + /// The fix is unsafe and should only be displayed for manual application by the user. + /// The fix is likely to be incorrect or the resulting code may have invalid syntax. + Display, - /// The fix has a good chance of being incorrect or the code be incomplete. - /// The fix may result in invalid code if it is applied. - /// The fix should only be manually applied by the user. - Manual, + /// The fix is unsafe and should only be applied with user opt-in. + /// The fix may be what the user intended, but it is uncertain; the resulting code will have valid syntax. + Unsafe, - /// The applicability of the fix is unknown. - #[default] - Unspecified, + /// The fix is safe and can always be applied. + /// The fix is definitely what the user intended, or it maintains the exact meaning of the code. + Safe, } /// Indicates the level of isolation required to apply a fix. @@ -52,86 +47,62 @@ pub struct Fix { } impl Fix { - /// Create a new [`Fix`] with an unspecified applicability from an [`Edit`] element. - #[deprecated( - note = "Use `Fix::automatic`, `Fix::suggested`, or `Fix::manual` instead to specify an applicability." - )] - pub fn unspecified(edit: Edit) -> Self { - Self { - edits: vec![edit], - applicability: Applicability::Unspecified, - isolation_level: IsolationLevel::default(), - } - } - - /// Create a new [`Fix`] with an unspecified applicability from multiple [`Edit`] elements. - #[deprecated( - note = "Use `Fix::automatic_edits`, `Fix::suggested_edits`, or `Fix::manual_edits` instead to specify an applicability." - )] - pub fn unspecified_edits(edit: Edit, rest: impl IntoIterator) -> Self { - Self { - edits: std::iter::once(edit).chain(rest).collect(), - applicability: Applicability::Unspecified, - isolation_level: IsolationLevel::default(), - } - } - - /// Create a new [`Fix`] with [automatic applicability](Applicability::Automatic) from an [`Edit`] element. - pub fn automatic(edit: Edit) -> Self { + /// Create a new [`Fix`] that is [safe](Applicability::Safe) to apply from an [`Edit`] element. + pub fn safe_edit(edit: Edit) -> Self { Self { edits: vec![edit], - applicability: Applicability::Automatic, + applicability: Applicability::Safe, isolation_level: IsolationLevel::default(), } } - /// Create a new [`Fix`] with [automatic applicability](Applicability::Automatic) from multiple [`Edit`] elements. - pub fn automatic_edits(edit: Edit, rest: impl IntoIterator) -> Self { + /// Create a new [`Fix`] that is [safe](Applicability::Safe) to apply from multiple [`Edit`] elements. + pub fn safe_edits(edit: Edit, rest: impl IntoIterator) -> Self { let mut edits: Vec = std::iter::once(edit).chain(rest).collect(); - edits.sort_by_key(Ranged::start); + edits.sort_by_key(|edit| (edit.start(), edit.end())); Self { edits, - applicability: Applicability::Automatic, + applicability: Applicability::Safe, isolation_level: IsolationLevel::default(), } } - /// Create a new [`Fix`] with [suggested applicability](Applicability::Suggested) from an [`Edit`] element. - pub fn suggested(edit: Edit) -> Self { + /// Create a new [`Fix`] that is [unsafe](Applicability::Unsafe) to apply from an [`Edit`] element. + pub fn unsafe_edit(edit: Edit) -> Self { Self { edits: vec![edit], - applicability: Applicability::Suggested, + applicability: Applicability::Unsafe, isolation_level: IsolationLevel::default(), } } - /// Create a new [`Fix`] with [suggested applicability](Applicability::Suggested) from multiple [`Edit`] elements. - pub fn suggested_edits(edit: Edit, rest: impl IntoIterator) -> Self { + /// Create a new [`Fix`] that is [unsafe](Applicability::Unsafe) to apply from multiple [`Edit`] elements. + pub fn unsafe_edits(edit: Edit, rest: impl IntoIterator) -> Self { let mut edits: Vec = std::iter::once(edit).chain(rest).collect(); - edits.sort_by_key(Ranged::start); + edits.sort_by_key(|edit| (edit.start(), edit.end())); Self { edits, - applicability: Applicability::Suggested, + applicability: Applicability::Unsafe, isolation_level: IsolationLevel::default(), } } - /// Create a new [`Fix`] with [manual applicability](Applicability::Manual) from an [`Edit`] element. - pub fn manual(edit: Edit) -> Self { + /// Create a new [`Fix`] that should only [display](Applicability::Display) and not apply from an [`Edit`] element . + pub fn display_edit(edit: Edit) -> Self { Self { edits: vec![edit], - applicability: Applicability::Manual, + applicability: Applicability::Display, isolation_level: IsolationLevel::default(), } } - /// Create a new [`Fix`] with [manual applicability](Applicability::Manual) from multiple [`Edit`] elements. - pub fn manual_edits(edit: Edit, rest: impl IntoIterator) -> Self { + /// Create a new [`Fix`] that should only [display](Applicability::Display) and not apply from multiple [`Edit`] elements. + pub fn display_edits(edit: Edit, rest: impl IntoIterator) -> Self { let mut edits: Vec = std::iter::once(edit).chain(rest).collect(); - edits.sort_by_key(Ranged::start); + edits.sort_by_key(|edit| (edit.start(), edit.end())); Self { edits, - applicability: Applicability::Manual, + applicability: Applicability::Display, isolation_level: IsolationLevel::default(), } } @@ -162,4 +133,16 @@ impl Fix { self.isolation_level = isolation; self } + + /// Return [`true`] if this [`Fix`] should be applied with at a given [`Applicability`]. + pub fn applies(&self, applicability: Applicability) -> bool { + self.applicability >= applicability + } + + /// Create a new [`Fix`] with the given [`Applicability`]. + #[must_use] + pub fn with_applicability(mut self, applicability: Applicability) -> Self { + self.applicability = applicability; + self + } } diff --git a/crates/ruff_diagnostics/src/lib.rs b/crates/ruff_diagnostics/src/lib.rs index f093861de7fbf..f21419abe9cd4 100644 --- a/crates/ruff_diagnostics/src/lib.rs +++ b/crates/ruff_diagnostics/src/lib.rs @@ -2,7 +2,7 @@ pub use diagnostic::{Diagnostic, DiagnosticKind}; pub use edit::Edit; pub use fix::{Applicability, Fix, IsolationLevel}; pub use source_map::{SourceMap, SourceMarker}; -pub use violation::{AlwaysAutofixableViolation, AutofixKind, Violation}; +pub use violation::{AlwaysFixableViolation, FixAvailability, Violation}; mod diagnostic; mod edit; diff --git a/crates/ruff_diagnostics/src/source_map.rs b/crates/ruff_diagnostics/src/source_map.rs index 161496eadc50d..5a3e2e8c6f9a9 100644 --- a/crates/ruff_diagnostics/src/source_map.rs +++ b/crates/ruff_diagnostics/src/source_map.rs @@ -46,10 +46,7 @@ impl SourceMap { /// The `output_length` is the length of the transformed string before the /// edit is applied. pub fn push_start_marker(&mut self, edit: &Edit, output_length: TextSize) { - self.0.push(SourceMarker { - source: edit.start(), - dest: output_length, - }); + self.push_marker(edit.start(), output_length); } /// Push the end marker for an [`Edit`]. @@ -58,16 +55,18 @@ impl SourceMap { /// edit has been applied. pub fn push_end_marker(&mut self, edit: &Edit, output_length: TextSize) { if edit.is_insertion() { - self.0.push(SourceMarker { - source: edit.start(), - dest: output_length, - }); + self.push_marker(edit.start(), output_length); } else { // Deletion or replacement - self.0.push(SourceMarker { - source: edit.end(), - dest: output_length, - }); + self.push_marker(edit.end(), output_length); } } + + /// Push a new marker to the sourcemap. + pub fn push_marker(&mut self, offset: TextSize, output_length: TextSize) { + self.0.push(SourceMarker { + source: offset, + dest: output_length, + }); + } } diff --git a/crates/ruff_diagnostics/src/violation.rs b/crates/ruff_diagnostics/src/violation.rs index d57a1b4e38b1b..b61ccfb85a436 100644 --- a/crates/ruff_diagnostics/src/violation.rs +++ b/crates/ruff_diagnostics/src/violation.rs @@ -1,26 +1,26 @@ use std::fmt::{Debug, Display}; #[derive(Debug, Copy, Clone)] -pub enum AutofixKind { +pub enum FixAvailability { Sometimes, Always, None, } -impl Display for AutofixKind { +impl Display for FixAvailability { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - AutofixKind::Sometimes => write!(f, "Autofix is sometimes available."), - AutofixKind::Always => write!(f, "Autofix is always available."), - AutofixKind::None => write!(f, "Autofix is not available."), + FixAvailability::Sometimes => write!(f, "Fix is sometimes available."), + FixAvailability::Always => write!(f, "Fix is always available."), + FixAvailability::None => write!(f, "Fix is not available."), } } } pub trait Violation: Debug + PartialEq + Eq { - /// `None` in the case an autofix is never available or otherwise Some - /// [`AutofixKind`] describing the available autofix. - const AUTOFIX: AutofixKind = AutofixKind::None; + /// `None` in the case an fix is never available or otherwise Some + /// [`FixAvailability`] describing the available fix. + const FIX_AVAILABILITY: FixAvailability = FixAvailability::None; /// The message used to describe the violation. fn message(&self) -> String; @@ -30,13 +30,13 @@ pub trait Violation: Debug + PartialEq + Eq { None } - // TODO(micha): Move `autofix_title` to `Fix`, add new `advice` method that is shown as an advice. + // TODO(micha): Move `fix_title` to `Fix`, add new `advice` method that is shown as an advice. // Change the `Diagnostic` renderer to show the advice, and render the fix message after the `Suggested fix: ` - /// Returns the title for the autofix. The message is also shown as an advice as part of the diagnostics. + /// Returns the title for the fix. The message is also shown as an advice as part of the diagnostics. /// - /// Required for rules that have autofixes. - fn autofix_title(&self) -> Option { + /// Required for rules that have fixes. + fn fix_title(&self) -> Option { None } @@ -45,8 +45,8 @@ pub trait Violation: Debug + PartialEq + Eq { } /// This trait exists just to make implementing the [`Violation`] trait more -/// convenient for violations that can always be autofixed. -pub trait AlwaysAutofixableViolation: Debug + PartialEq + Eq { +/// convenient for violations that can always be fixed. +pub trait AlwaysFixableViolation: Debug + PartialEq + Eq { /// The message used to describe the violation. fn message(&self) -> String; @@ -55,31 +55,31 @@ pub trait AlwaysAutofixableViolation: Debug + PartialEq + Eq { None } - /// The title displayed for the available autofix. - fn autofix_title(&self) -> String; + /// The title displayed for the available fix. + fn fix_title(&self) -> String; /// Returns the format strings used by - /// [`message`](AlwaysAutofixableViolation::message). + /// [`message`](AlwaysFixableViolation::message). fn message_formats() -> &'static [&'static str]; } /// A blanket implementation. -impl Violation for VA { - const AUTOFIX: AutofixKind = AutofixKind::Always; +impl Violation for V { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Always; fn message(&self) -> String { - ::message(self) + ::message(self) } fn explanation() -> Option<&'static str> { - ::explanation() + ::explanation() } - fn autofix_title(&self) -> Option { - Some(::autofix_title(self)) + fn fix_title(&self) -> Option { + Some(::fix_title(self)) } fn message_formats() -> &'static [&'static str] { - ::message_formats() + ::message_formats() } } diff --git a/crates/ruff_formatter/Cargo.toml b/crates/ruff_formatter/Cargo.toml index 8e8a433294123..fc28b2fd0f23c 100644 --- a/crates/ruff_formatter/Cargo.toml +++ b/crates/ruff_formatter/Cargo.toml @@ -20,7 +20,7 @@ rustc-hash = { workspace = true } schemars = { workspace = true, optional = true } serde = { workspace = true, optional = true } static_assertions = { workspace = true } -tracing = { version = "0.1.37", default-features = false, features = ["std"] } +tracing = { workspace = true } unicode-width = { workspace = true } [dev-dependencies] diff --git a/crates/ruff_formatter/src/builders.rs b/crates/ruff_formatter/src/builders.rs index f5d81eb726862..7eadba123a207 100644 --- a/crates/ruff_formatter/src/builders.rs +++ b/crates/ruff_formatter/src/builders.rs @@ -2448,7 +2448,7 @@ where /// Adds a new entry to the join output. pub fn entry(&mut self, entry: &dyn Format) -> &mut Self { - self.result = self.result.and_then(|_| { + self.result = self.result.and_then(|()| { if let Some(with) = &self.with { if self.has_elements { with.fmt(self.fmt)?; @@ -2519,7 +2519,7 @@ impl<'a, 'buf, Context> FillBuilder<'a, 'buf, Context> { separator: &dyn Format, entry: &dyn Format, ) -> &mut Self { - self.result = self.result.and_then(|_| { + self.result = self.result.and_then(|()| { if self.empty { self.empty = false; } else { diff --git a/crates/ruff_formatter/src/lib.rs b/crates/ruff_formatter/src/lib.rs index 6cd63f3e7c387..dfac3df3fc345 100644 --- a/crates/ruff_formatter/src/lib.rs +++ b/crates/ruff_formatter/src/lib.rs @@ -95,7 +95,7 @@ impl std::fmt::Display for IndentStyle { /// /// Determines the visual width of a tab character (`\t`) and the number of /// spaces per indent when using [`IndentStyle::Space`]. -#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, CacheKey)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct IndentWidth(NonZeroU8); @@ -575,6 +575,10 @@ where context: PhantomData, } } + + pub fn rule(&self) -> &R { + &self.rule + } } impl FormatRefWithRule<'_, T, R, C> diff --git a/crates/ruff_formatter/src/printer/mod.rs b/crates/ruff_formatter/src/printer/mod.rs index 4535234fa3c4b..eda85658e3d0d 100644 --- a/crates/ruff_formatter/src/printer/mod.rs +++ b/crates/ruff_formatter/src/printer/mod.rs @@ -54,7 +54,7 @@ impl<'a> Printer<'a> { /// Prints the passed in element as well as all its content, /// starting at the specified indentation level - #[tracing::instrument(name = "Printer::print", skip_all)] + #[tracing::instrument(level = "debug", name = "Printer::print", skip_all)] pub fn print_with_indent( mut self, document: &'a Document, diff --git a/crates/ruff_linter/Cargo.toml b/crates/ruff_linter/Cargo.toml index cb7016aeca40d..a1d87ef4e61fd 100644 --- a/crates/ruff_linter/Cargo.toml +++ b/crates/ruff_linter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ruff_linter" -version = "0.0.291" +version = "0.1.3" publish = false authors = { workspace = true } edition = { workspace = true } @@ -29,6 +29,7 @@ ruff_python_parser = { path = "../ruff_python_parser" } ruff_source_file = { path = "../ruff_source_file", features = ["serde"] } ruff_text_size = { path = "../ruff_text_size" } +aho-corasick = { version = "1.1.2" } annotate-snippets = { version = "0.9.1", features = ["color"] } anyhow = { workspace = true } bitflags = { workspace = true } @@ -45,22 +46,20 @@ libcst = { workspace = true } log = { workspace = true } memchr = { workspace = true } natord = { version = "1.0.9" } -num-bigint = { workspace = true } -num-traits = { workspace = true } once_cell = { workspace = true } path-absolutize = { workspace = true, features = [ "once_cell_cache", "use_unix_paths_on_wasm", ] } pathdiff = { version = "0.2.1" } -pep440_rs = { version = "0.3.1", features = ["serde"] } +pep440_rs = { version = "0.3.12", features = ["serde"] } pyproject-toml = { version = "0.7.0" } quick-junit = { version = "0.3.2" } regex = { workspace = true } result-like = { version = "0.4.6" } rustc-hash = { workspace = true } schemars = { workspace = true, optional = true } -semver = { version = "1.0.19" } +semver = { version = "1.0.20" } serde = { workspace = true } serde_json = { workspace = true } similar = { workspace = true } @@ -71,7 +70,7 @@ thiserror = { workspace = true } toml = { workspace = true } typed-arena = { version = "2.0.2" } unicode-width = { workspace = true } -unicode_names2 = { version = "0.6.0", git = "https://github.com/youknowone/unicode_names2.git", rev = "4ce16aa85cbcdd9cc830410f1a72ef9a235f2fde" } +unicode_names2 = { workspace = true } wsl = { version = "0.1.0" } [dev-dependencies] diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_annotations/annotation_presence.py b/crates/ruff_linter/resources/test/fixtures/flake8_annotations/annotation_presence.py index 36c5155b83e79..b84ec16576854 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_annotations/annotation_presence.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_annotations/annotation_presence.py @@ -158,3 +158,9 @@ class Foo: @decorator() def __init__(self: "Foo", foo: int): ... + + +# Regression test for: https://github.com/astral-sh/ruff/issues/7711 +class Class: + def __init__(self): + print(f"{self.attr=}") diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S103.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S103.py index 8f95808bb61c2..30c800d9fd032 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S103.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S103.py @@ -20,3 +20,4 @@ os.chmod("~/hidden_exec", stat.S_IXGRP) # Error os.chmod("~/hidden_exec", stat.S_IXOTH) # OK os.chmod("/etc/passwd", stat.S_IWOTH) # Error +os.chmod("/etc/passwd", 0o100000000) # Error diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S310.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S310.py new file mode 100644 index 0000000000000..c69c5a15d6a89 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S310.py @@ -0,0 +1,19 @@ +import urllib.request + +urllib.request.urlopen(url='http://www.google.com') +urllib.request.urlopen(url='http://www.google.com', **kwargs) +urllib.request.urlopen('http://www.google.com') +urllib.request.urlopen('file:///foo/bar/baz') +urllib.request.urlopen(url) + +urllib.request.Request(url='http://www.google.com', **kwargs) +urllib.request.Request(url='http://www.google.com') +urllib.request.Request('http://www.google.com') +urllib.request.Request('file:///foo/bar/baz') +urllib.request.Request(url) + +urllib.request.URLopener().open(fullurl='http://www.google.com', **kwargs) +urllib.request.URLopener().open(fullurl='http://www.google.com') +urllib.request.URLopener().open('http://www.google.com') +urllib.request.URLopener().open('file:///foo/bar/baz') +urllib.request.URLopener().open(url) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S505.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S505.py new file mode 100644 index 0000000000000..a21b28c9077f8 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S505.py @@ -0,0 +1,54 @@ +from cryptography.hazmat import backends +from cryptography.hazmat.primitives.asymmetric import dsa +from cryptography.hazmat.primitives.asymmetric import ec +from cryptography.hazmat.primitives.asymmetric import rsa +from Crypto.PublicKey import DSA as pycrypto_dsa +from Crypto.PublicKey import RSA as pycrypto_rsa +from Cryptodome.PublicKey import DSA as pycryptodomex_dsa +from Cryptodome.PublicKey import RSA as pycryptodomex_rsa + +# OK +dsa.generate_private_key(key_size=2048, backend=backends.default_backend()) +ec.generate_private_key(curve=ec.SECP384R1, backend=backends.default_backend()) +rsa.generate_private_key( + public_exponent=65537, key_size=2048, backend=backends.default_backend() +) +pycrypto_dsa.generate(bits=2048) +pycrypto_rsa.generate(bits=2048) +pycryptodomex_dsa.generate(bits=2048) +pycryptodomex_rsa.generate(bits=2048) +dsa.generate_private_key(2048, backends.default_backend()) +ec.generate_private_key(ec.SECP256K1, backends.default_backend()) +rsa.generate_private_key(3, 2048, backends.default_backend()) +pycrypto_dsa.generate(2048) +pycrypto_rsa.generate(2048) +pycryptodomex_dsa.generate(2048) +pycryptodomex_rsa.generate(2048) + +# Errors +dsa.generate_private_key(key_size=2047, backend=backends.default_backend()) +ec.generate_private_key(curve=ec.SECT163R2, backend=backends.default_backend()) +rsa.generate_private_key( + public_exponent=65537, key_size=2047, backend=backends.default_backend() +) +pycrypto_dsa.generate(bits=2047) +pycrypto_rsa.generate(bits=2047) +pycryptodomex_dsa.generate(bits=2047) +pycryptodomex_rsa.generate(bits=2047) +dsa.generate_private_key(2047, backends.default_backend()) +ec.generate_private_key(ec.SECT163R2, backends.default_backend()) +rsa.generate_private_key(3, 2047, backends.default_backend()) +pycrypto_dsa.generate(2047) +pycrypto_rsa.generate(2047) +pycryptodomex_dsa.generate(2047) +pycryptodomex_rsa.generate(2047) + +# Don't crash when the size is variable. +rsa.generate_private_key( + public_exponent=65537, key_size=some_key_size, backend=backends.default_backend() +) + +# Can't reliably know which curve was passed, in some cases like below. +ec.generate_private_key( + curve=curves[self.curve]["create"](self.size), backend=backends.default_backend() +) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S507.py b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S507.py index 9aeb24a1bdc6d..e5e94d183965f 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S507.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bandit/S507.py @@ -1,7 +1,9 @@ +import paramiko from paramiko import client from paramiko.client import AutoAddPolicy, WarningPolicy ssh_client = client.SSHClient() +ssh_client_from_paramiko = paramiko.SSHClient() # OK ssh_client.set_missing_host_key_policy(policy=foo) @@ -12,10 +14,12 @@ # Errors ssh_client.set_missing_host_key_policy(client.AutoAddPolicy) ssh_client.set_missing_host_key_policy(client.WarningPolicy) +ssh_client.set_missing_host_key_policy(client.AutoAddPolicy()) ssh_client.set_missing_host_key_policy(AutoAddPolicy) ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) ssh_client.set_missing_host_key_policy(policy=WarningPolicy) +ssh_client_from_paramiko.set_missing_host_key_policy(paramiko.AutoAddPolicy) # Unrelated set_missing_host_key_policy(client.AutoAddPolicy) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_blind_except/BLE.py b/crates/ruff_linter/resources/test/fixtures/flake8_blind_except/BLE.py index 6ce4ab3dcefbc..b2272b8ab591e 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_blind_except/BLE.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_blind_except/BLE.py @@ -92,3 +92,35 @@ pass except Exception: logging.error("...", exc_info=True) + + +from logging import error, exception + +try: + pass +except Exception: + error("...") + + +try: + pass +except Exception: + error("...", exc_info=False) + + +try: + pass +except Exception: + error("...", exc_info=None) + + +try: + pass +except Exception: + exception("...") + + +try: + pass +except Exception: + error("...", exc_info=True) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_boolean_trap/FBT.py b/crates/ruff_linter/resources/test/fixtures/flake8_boolean_trap/FBT.py index eba1a03097ddf..88e5468692e10 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_boolean_trap/FBT.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_boolean_trap/FBT.py @@ -70,6 +70,8 @@ def used(do): foo.is_(True) bar.is_not(False) next(iter([]), False) +sa.func.coalesce(tbl.c.valid, False) + class Registry: def __init__(self) -> None: diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B006_5.py b/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B006_5.py new file mode 100644 index 0000000000000..b2bde5afa118d --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B006_5.py @@ -0,0 +1,74 @@ +# Move mutable arguments below imports and docstrings +# https://github.com/astral-sh/ruff/issues/7616 + + +def import_module_wrong(value: dict[str, str] = {}): + import os + + +def import_module_with_values_wrong(value: dict[str, str] = {}): + import os + + return 2 + + +def import_modules_wrong(value: dict[str, str] = {}): + import os + import sys + import itertools + + +def from_import_module_wrong(value: dict[str, str] = {}): + from os import path + + +def from_imports_module_wrong(value: dict[str, str] = {}): + from os import path + from sys import version_info + + +def import_and_from_imports_module_wrong(value: dict[str, str] = {}): + import os + from sys import version_info + + +def import_docstring_module_wrong(value: dict[str, str] = {}): + """Docstring""" + import os + + +def import_module_wrong(value: dict[str, str] = {}): + """Docstring""" + import os; import sys + + +def import_module_wrong(value: dict[str, str] = {}): + """Docstring""" + import os; import sys; x = 1 + + +def import_module_wrong(value: dict[str, str] = {}): + """Docstring""" + import os; import sys + + +def import_module_wrong(value: dict[str, str] = {}): + import os; import sys + + +def import_module_wrong(value: dict[str, str] = {}): + import os; import sys; x = 1 + + +def import_module_wrong(value: dict[str, str] = {}): + import os; import sys + + +def import_module_wrong(value: dict[str, str] = {}): import os + + +def import_module_wrong(value: dict[str, str] = {}): import os; import sys + + +def import_module_wrong(value: dict[str, str] = {}): \ + import os diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B006_6.py b/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B006_6.py new file mode 100644 index 0000000000000..b651380f0def1 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B006_6.py @@ -0,0 +1,5 @@ +# Import followed by whitespace with no newline +# Same as B006_2.py, but import instead of docstring + +def foobar(foor, bar={}): + import os \ No newline at end of file diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B006_7.py b/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B006_7.py new file mode 100644 index 0000000000000..0b382b5fbfcf9 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B006_7.py @@ -0,0 +1,5 @@ +# Import with no newline +# Same as B006_3.py, but import instead of docstring + +def foobar(foor, bar={}): + import os \ No newline at end of file diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B009_B010.py b/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B009_B010.py index 18c819a7f951a..a889e7ef2f95c 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B009_B010.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B009_B010.py @@ -60,3 +60,7 @@ # Regression test for: https://github.com/astral-sh/ruff/issues/7455#issuecomment-1732387247 getattr(*foo, "bar") setattr(*foo, "bar", None) + +# Regression test for: https://github.com/astral-sh/ruff/issues/7455#issuecomment-1739800901 +getattr(self. + registration.registry, '__name__') diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B014.py b/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B014.py index 8a03e75121c01..99cbd2a2499c5 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B014.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B014.py @@ -76,8 +76,15 @@ class MyError(Exception): pass -# https://github.com/astral-sh/ruff/issues/6412 +# Regression test for: https://github.com/astral-sh/ruff/issues/6412 try: pass except (ValueError, ValueError, TypeError): pass + + +# Regression test for: https://github.com/astral-sh/ruff/issues/7455#issuecomment-1739801758 +try: + pas +except(re.error, re.error): + p diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_commas/COM81.py b/crates/ruff_linter/resources/test/fixtures/flake8_commas/COM81.py index f76059e98d095..8bc53dcd34760 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_commas/COM81.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_commas/COM81.py @@ -627,7 +627,7 @@ def foo( **{'ham': spam} ) -# Make sure the COM812 and UP034 rules don't autofix simultaneously and cause a syntax error. +# Make sure the COM812 and UP034 rules don't fix simultaneously and cause a syntax error. the_first_one = next( (i for i in range(10) if i // 2 == 0) # COM812 fix should include the final bracket ) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C414.py b/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C414.py index ad61eec08a6fd..7db605fecbe64 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C414.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C414.py @@ -32,3 +32,16 @@ sorted(sorted(x, key=lambda y: y), key=lambda x: x) sorted(sorted(x), reverse=True) sorted(sorted(x, reverse=False), reverse=True) + +# Preserve trailing comments. +xxxxxxxxxxx_xxxxx_xxxxx = sorted( + list(x_xxxx_xxxxxxxxxxx_xxxxx.xxxx()), + # xxxxxxxxxxx xxxxx xxxx xxx xx Nxxx, xxx xxxxxx3 xxxxxxxxx xx + # xx xxxx xxxxxxx xxxx xxx xxxxxxxx Nxxx + key=lambda xxxxx: xxxxx or "", +) + +xxxxxxxxxxx_xxxxx_xxxxx = sorted( + list(x_xxxx_xxxxxxxxxxx_xxxxx.xxxx()), # xxxxxxxxxxx xxxxx xxxx xxx xx Nxxx + key=lambda xxxxx: xxxxx or "", +) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_implicit_str_concat/ISC.py b/crates/ruff_linter/resources/test/fixtures/flake8_implicit_str_concat/ISC.py index ef4517b5b1129..5abfd1a2f1e5b 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_implicit_str_concat/ISC.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_implicit_str_concat/ISC.py @@ -59,3 +59,23 @@ _ = foo + bar + "abc" _ = "abc" + foo + bar _ = foo + "abc" + bar + +# Multiple strings nested inside a f-string +_ = f"a {'b' 'c' 'd'} e" +_ = f"""abc {"def" "ghi"} jkl""" +_ = f"""abc { + "def" + "ghi" +} jkl""" + +# Nested f-strings +_ = "a" f"b {f"c" f"d"} e" "f" +_ = f"b {f"c" f"d {f"e" f"f"} g"} h" +_ = f"b {f"abc" \ + f"def"} g" + +# Explicitly concatenated nested f-strings +_ = f"a {f"first" + + f"second"} d" +_ = f"a {f"first {f"middle"}" + + f"second"} d" diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_logging/LOG007.py b/crates/ruff_linter/resources/test/fixtures/flake8_logging/LOG007.py index 00fe85bf9159a..24a4cff872bf7 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_logging/LOG007.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_logging/LOG007.py @@ -16,3 +16,9 @@ exception("foo", exc_info=False) # LOG007 exception("foo", exc_info=True) # OK + + +exception = lambda *args, **kwargs: None + +exception("foo", exc_info=False) # OK +exception("foo", exc_info=True) # OK diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G001.py b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G001.py index 7a3a49a6a7d10..f100eae9a4d6c 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G001.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G001.py @@ -16,3 +16,12 @@ flask.current_app.logger.info("Hello {}".format("World!")) current_app.logger.info("Hello {}".format("World!")) app.logger.log(logging.INFO, "Hello {}".format("World!")) + +from logging import info, log + +info("Hello {}".format("World!")) +log(logging.INFO, "Hello {}".format("World!")) +info("Hello {}".format("World!")) +log(logging.INFO, msg="Hello {}".format("World!")) +log(level=logging.INFO, msg="Hello {}".format("World!")) +log(msg="Hello {}".format("World!"), level=logging.INFO) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G002.py b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G002.py index 11b61a1cb8e7a..6c01eb8819e19 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G002.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G002.py @@ -2,3 +2,8 @@ logging.info("Hello %s" % "World!") logging.log(logging.INFO, "Hello %s" % "World!") + +from logging import info, log + +info("Hello %s" % "World!") +log(logging.INFO, "Hello %s" % "World!") diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G003.py b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G003.py index 4e20dc6d9b285..1f52dbe3df615 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G003.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G003.py @@ -2,3 +2,8 @@ logging.info("Hello" + " " + "World!") logging.log(logging.INFO, "Hello" + " " + "World!") + +from logging import info, log + +info("Hello" + " " + "World!") +log(logging.INFO, "Hello" + " " + "World!") diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G004.py b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G004.py index 56e005293a62a..ffc9ed7dd2c03 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G004.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G004.py @@ -6,3 +6,7 @@ _LOGGER = logging.getLogger() _LOGGER.info(f"{__name__}") + +from logging import info +info(f"{name}") +info(f"{__name__}") diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G010.py b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G010.py index fc0029c40987a..3c1294069b06e 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G010.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G010.py @@ -8,3 +8,8 @@ logger.warn("Hello world!") logging . warn("Hello World!") + +from logging import warn, warning, exception +warn("foo") +warning("foo") +exception("foo") diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G101_1.py b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G101_1.py index 3386f5e480c88..08131551a2f7c 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G101_1.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G101_1.py @@ -6,3 +6,12 @@ "name": "foobar", }, ) + +from logging import info + +info( + "Hello world!", + extra={ + "name": "foobar", + }, +) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G101_2.py b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G101_2.py index c73c54e4c67e0..c21e3c37cffc0 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G101_2.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G101_2.py @@ -6,3 +6,12 @@ name="foobar", ), ) + +from logging import info + +info( + "Hello world!", + extra=dict( + name="foobar", + ), +) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G201.py b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G201.py index e85490752028e..d8610e0e26789 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G201.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G201.py @@ -19,3 +19,24 @@ logging.error("Hello World", exc_info=False) logging.error("Hello World", exc_info=sys.exc_info()) + +# G201 +from logging import error +try: + pass +except: + error("Hello World", exc_info=True) + +try: + pass +except: + error("Hello World", exc_info=sys.exc_info()) + +# OK +try: + pass +except: + error("Hello World", exc_info=False) + +error("Hello World", exc_info=sys.exc_info()) + diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G202.py b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G202.py index 6af630930ca1b..aca5f3a45baa1 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G202.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_logging_format/G202.py @@ -19,3 +19,23 @@ logging.exception("Hello World", exc_info=False) logging.exception("Hello World", exc_info=True) + +# G202 +from logging import exception +try: + pass +except: + exception("Hello World", exc_info=True) + +try: + pass +except: + exception("Hello World", exc_info=sys.exc_info()) + +# OK +try: + pass +except: + exception("Hello World", exc_info=False) + +exception("Hello World", exc_info=True) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE790.py b/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE790.py index 5f35fd443a108..976b15dbd52ef 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE790.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE790.py @@ -123,3 +123,28 @@ class Error(Exception): def foo() -> None: pass + + +def foo(): + print("foo") + pass + + +def foo(): + """A docstring.""" + print("foo") + pass + + +for i in range(10): + pass + pass + +for i in range(10): + pass + + pass + +for i in range(10): + pass # comment + pass diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE804.py b/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE804.py index de112a074e1f9..84274c853a8aa 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE804.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pie/PIE804.py @@ -8,6 +8,8 @@ Foo.objects.create(**{**bar}) # PIE804 +foo(**{}) + foo(**{**data, "foo": "buzz"}) foo(**buzz) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI055.py b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI055.py index adbc1f737a814..6471613f9838c 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI055.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI055.py @@ -28,4 +28,12 @@ def func(arg: type[int, float] | str) -> None: def func(): # PYI055 - item: type[requests_mock.Mocker] | type[httpretty] = requests_mock.Mocker + x: type[requests_mock.Mocker] | type[httpretty] | type[str] = requests_mock.Mocker + y: Union[type[requests_mock.Mocker], type[httpretty], type[str]] = requests_mock.Mocker + + +def func(): + from typing import Union as U + + # PYI055 + x: Union[type[requests_mock.Mocker], type[httpretty], type[str]] = requests_mock.Mocker diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI055.pyi b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI055.pyi index 3cc530f770517..530f395dfa359 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI055.pyi +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI055.pyi @@ -21,4 +21,5 @@ item: type[requests_mock.Mocker] | type[httpretty] = requests_mock.Mocker def func(): # PYI055 - item: type[requests_mock.Mocker] | type[httpretty] = requests_mock.Mocker + item: type[requests_mock.Mocker] | type[httpretty] | type[str] = requests_mock.Mocker + item2: Union[type[requests_mock.Mocker], type[httpretty], type[str]] = requests_mock.Mocker diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_pytest_style/PT018.py b/crates/ruff_linter/resources/test/fixtures/flake8_pytest_style/PT018.py index 0eafac016e681..0ccec6f7596ab 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_pytest_style/PT018.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_pytest_style/PT018.py @@ -33,10 +33,10 @@ def test_error(): assert not (a or not (b or c)) assert not (a or not (b and c)) - # detected, but no autofix for messages + # detected, but no fix for messages assert something and something_else, "error message" assert not (something or something_else and something_third), "with message" - # detected, but no autofix for mixed conditions (e.g. `a or b and c`) + # detected, but no fix for mixed conditions (e.g. `a or b and c`) assert not (something or something_else and something_third) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_quotes/doubles_escaped.py b/crates/ruff_linter/resources/test/fixtures/flake8_quotes/doubles_escaped.py index c55ba00cd8fc3..7f789a22fbad9 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_quotes/doubles_escaped.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_quotes/doubles_escaped.py @@ -9,3 +9,33 @@ 'This is a' '\'string\'' ) + +# Same as above, but with f-strings +f'This is a \'string\'' # Q003 +f'This is \\ a \\\'string\'' # Q003 +f'"This" is a \'string\'' +f"This is a 'string'" +f"\"This\" is a 'string'" +fr'This is a \'string\'' +fR'This is a \'string\'' +foo = ( + f'This is a' + f'\'string\'' # Q003 +) + +# Nested f-strings (Python 3.12+) +# +# The first one is interesting because the fix for it is valid pre 3.12: +# +# f"'foo' {'nested'}" +# +# but as the actual string itself is invalid pre 3.12, we don't catch it. +f'\'foo\' {'nested'}' # Q003 +f'\'foo\' {f'nested'}' # Q003 +f'\'foo\' {f'\'nested\''} \'\'' # Q003 + +f'normal {f'nested'} normal' +f'\'normal\' {f'nested'} normal' # Q003 +f'\'normal\' {f'nested'} "double quotes"' +f'\'normal\' {f'\'nested\' {'other'} normal'} "double quotes"' # Q003 +f'\'normal\' {f'\'nested\' {'other'} "double quotes"'} normal' # Q00l diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_quotes/singles_escaped.py b/crates/ruff_linter/resources/test/fixtures/flake8_quotes/singles_escaped.py index f011c5f90c5bd..815db5bdb7af9 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_quotes/singles_escaped.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_quotes/singles_escaped.py @@ -8,3 +8,32 @@ "This is a" "\"string\"" ) + +# Same as above, but with f-strings +f"This is a \"string\"" +f"'This' is a \"string\"" +f'This is a "string"' +f'\'This\' is a "string"' +fr"This is a \"string\"" +fR"This is a \"string\"" +foo = ( + f"This is a" + f"\"string\"" +) + +# Nested f-strings (Python 3.12+) +# +# The first one is interesting because the fix for it is valid pre 3.12: +# +# f'"foo" {"nested"}' +# +# but as the actual string itself is invalid pre 3.12, we don't catch it. +f"\"foo\" {"foo"}" # Q003 +f"\"foo\" {f"foo"}" # Q003 +f"\"foo\" {f"\"foo\""} \"\"" # Q003 + +f"normal {f"nested"} normal" +f"\"normal\" {f"nested"} normal" # Q003 +f"\"normal\" {f"nested"} 'single quotes'" +f"\"normal\" {f"\"nested\" {"other"} normal"} 'single quotes'" # Q003 +f"\"normal\" {f"\"nested\" {"other"} 'single quotes'"} normal" # Q003 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_raise/RSE102.py b/crates/ruff_linter/resources/test/fixtures/flake8_raise/RSE102.py index bdf30e0a51cd5..0a750b97cb190 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_raise/RSE102.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_raise/RSE102.py @@ -79,3 +79,6 @@ def error(): raise IndexError() from ZeroDivisionError raise IndexError(); + +# RSE102 +raise Foo() diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_return/RET504.py b/crates/ruff_linter/resources/test/fixtures/flake8_return/RET504.py index ef71d178ad75b..9899fa15ed6bc 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_return/RET504.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_return/RET504.py @@ -335,7 +335,7 @@ def foo(): return x -# Autofix cases +# Fix cases def foo(): a = 1 b=a diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM101.py b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM101.py index 1d9066f5ce896..12e26c4c76c7d 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM101.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM101.py @@ -31,6 +31,15 @@ if isinstance(a, int) or isinstance(a.b, float): pass +# OK +if isinstance(a, int) or unrelated_condition or isinstance(a, float): + pass + +if x or isinstance(a, int) or isinstance(a, float): + pass + +if x or y or isinstance(a, int) or isinstance(a, float) or z: + pass def f(): # OK diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM108.py b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM108.py index 956caff2b3f53..e31cc0af02e34 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM108.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM108.py @@ -126,3 +126,12 @@ def f(): x = yield 3 else: x = yield 5 + + +from typing import TYPE_CHECKING + +# OK +if TYPE_CHECKING: + x = 3 +else: + x = 5 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM110.py b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM110.py index cc2527e0922f8..2ac86dca61b10 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM110.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM110.py @@ -185,3 +185,24 @@ async def f(): if check(x): return True return False + +async def f(): + # SIM110 + for x in await iterable: + if check(x): + return True + return False + +def f(): + # OK (can't turn this into any() because the yield would end up inside a genexp) + for x in iterable: + if (yield check(x)): + return True + return False + +def f(): + # OK (same) + for x in iterable: + if (yield from check(x)): + return True + return False diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM112.py b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM112.py index 74b44d63325dc..937a2555c98e5 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM112.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM112.py @@ -38,3 +38,7 @@ if env := os.environ['FOO']: pass + +os.environ['https_proxy'] +os.environ.get['http_proxy'] +os.getenv('no_proxy') diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM115.py b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM115.py index 388b1fd670986..6a6925c45a603 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM115.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM115.py @@ -42,3 +42,7 @@ with contextlib.ExitStack() as exit_stack: exit_stack_ = exit_stack f = exit_stack_.enter_context(open("filename")) + +# OK (quick one-liner to clear file contents) +open("filename", "w").close() +pathlib.Path("filename").open("w").close() diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM117.py b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM117.py index 4053754f025a2..c3c64044a2aac 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM117.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM117.py @@ -121,3 +121,16 @@ async def main(): with c as c2: async with d as d2: f(b2, c2, d2) + +# SIM117 +with A() as a: + with B() as b: + type ListOrSet[T] = list[T] | set[T] + + class ClassA[T: str]: + def method1(self) -> T: + ... + + f" something { my_dict["key"] } something else " + + f"foo {f"bar {x}"} baz" diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM401.py b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM401.py index 79b48a57dd1c5..26bc35ee63209 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM401.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_simplify/SIM401.py @@ -114,3 +114,16 @@ vars[idx] = a_dict[key] else: vars[idx] = "default" + +### +# Positive cases (preview) +### + +# SIM401 +var = a_dict[key] if key in a_dict else "default3" + +# SIM401 +var = "default-1" if key not in a_dict else a_dict[key] + +# OK (default contains effect) +var = a_dict[key] if key in a_dict else val1 + val2 diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_type_checking/TCH004_15.py b/crates/ruff_linter/resources/test/fixtures/flake8_type_checking/TCH004_15.py new file mode 100644 index 0000000000000..6cf57e2f83780 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/flake8_type_checking/TCH004_15.py @@ -0,0 +1,19 @@ +from __future__ import annotations + +from collections.abc import Callable +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from .foo import Record + +type RecordOrThings = Record | int | str +type RecordCallback[R: Record] = Callable[[R], None] + + +def process_record[R: Record](record: R) -> None: + ... + + +class RecordContainer[R: Record]: + def add_record(self, record: R) -> None: + ... diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_3.py b/crates/ruff_linter/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_3.py index 1bd948a83f655..98527b019dee0 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_3.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_3.py @@ -22,3 +22,10 @@ class C: class D(C): x: UUID + + +import collections + + +class E(BaseModel[int]): + x: collections.Awaitable diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_use_pathlib/full_name.py b/crates/ruff_linter/resources/test/fixtures/flake8_use_pathlib/full_name.py index 9d15fb8cb43b4..5d2fca01873df 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_use_pathlib/full_name.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_use_pathlib/full_name.py @@ -33,3 +33,16 @@ fp.read() open(p).close() os.getcwdb(p) +os.path.join(p, *q) +os.sep.join(p, *q) + +# https://github.com/astral-sh/ruff/issues/7620 +def opener(path, flags): + return os.open(path, flags, dir_fd=os.open('somedir', os.O_RDONLY)) + + +open(p, closefd=False) +open(p, opener=opener) +open(p, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +open(p, 'r', - 1, None, None, None, True, None) +open(p, 'r', - 1, None, None, None, False, opener) diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E20.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E20.py index 2e8f5f7d90ce0..d91cfe96a87d7 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E20.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E20.py @@ -84,3 +84,8 @@ x = [ # 'some value', ] + +# F-strings +f"{ {'a': 1} }" +f"{[ { {'a': 1} } ]}" +f"normal { {f"{ { [1, 2] } }" } } normal" diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E23.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E23.py index d2bb50b05d023..4d0089bb451ab 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E23.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E23.py @@ -29,5 +29,16 @@ def foo() -> None: 'tag_smalldata':[('byte_count_mdtype', 'u4'), ('data', 'S4')], } +# E231 +f"{(a,b)}" + +# Okay because it's hard to differentiate between the usages of a colon in a f-string +f"{a:=1}" +f"{ {'a':1} }" +f"{a:.3f}" +f"{(a:=1)}" +f"{(lambda x:x)}" +f"normal{f"{a:.3f}"}normal" + #: Okay a = (1, diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E25.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E25.py index 88981576efc62..9d8bddac4234c 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E25.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E25.py @@ -48,3 +48,14 @@ def add(a: int=0, b: int =0, c: int= 0) -> int: #: Okay def add(a: int = _default(name='f')): return a + +# F-strings +f"{a=}" +f"{a:=1}" +f"{foo(a=1)}" +f"normal {f"{a=}"} normal" + +# Okay as the `=` is used inside a f-string... +print(f"{foo = }") +# ...but then it creates false negatives for now +print(f"{foo(a = 1)}") diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E501_1.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E501_1.py index 6c9e62fa81a0d..7656422387050 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E501_1.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E501_1.py @@ -1,6 +1,8 @@ # TODO: comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +# TODO(charlie): comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` # FIXME: comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +# FIXME(charlie): comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E501_3.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E501_3.py new file mode 100644 index 0000000000000..b4d693460eec1 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E501_3.py @@ -0,0 +1,11 @@ +# OK (88 characters) +"shape:" + "shape:" + "shape:" + "shape:" + "shape:" + "shape:" + "shape:" + "shape:aaa" # type: ignore + +# OK (88 characters) +"shape:" + "shape:" + "shape:" + "shape:" + "shape:" + "shape:" + "shape:" + "shape:aaa"# type: ignore + +# OK (88 characters) +"shape:" + "shape:" + "shape:" + "shape:" + "shape:" + "shape:" + "shape:" + "shape:aaa" # type: ignore + +# Error (89 characters) +"shape:" + "shape:" + "shape:" + "shape:" + "shape:" + "shape:" + "shape:" + "shape:aaaa" # type: ignore diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E721.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E721.py index 6eacc0cb0c9ab..26776e816b73e 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E721.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E721.py @@ -4,18 +4,18 @@ #: E721 if type(res) != type(""): pass -#: E721 +#: Okay import types if res == types.IntType: pass -#: E721 +#: Okay import types if type(res) is not types.ListType: pass #: E721 -assert type(res) == type(False) +assert type(res) == type(False) or type(res) == type(None) #: E721 assert type(res) == type([]) #: E721 @@ -25,21 +25,18 @@ #: E721 assert type(res) == type((0)) #: E721 -assert type(res) != type((1,)) -#: E721 -assert type(res) is type((1,)) -#: E721 -assert type(res) is not type((1,)) +assert type(res) != type((1, )) +#: Okay +assert type(res) is type((1, )) +#: Okay +assert type(res) is not type((1, )) #: E211 E721 -assert type(res) == type( - [ - 2, - ] -) +assert type(res) == type ([2, ]) #: E201 E201 E202 E721 -assert type(res) == type(()) +assert type(res) == type( ( ) ) #: E201 E202 E721 -assert type(res) == type((0,)) +assert type(res) == type( (0, ) ) +#: #: Okay import types @@ -50,18 +47,48 @@ pass if isinstance(res, types.MethodType): pass -if type(a) != type(b) or type(a) == type(ccc): +#: Okay +def func_histype(a, b, c): + pass +#: E722 +try: + pass +except: pass +#: E722 +try: + pass +except Exception: + pass +except: + pass +#: E722 E203 E271 +try: + pass +except : + pass +#: Okay +fake_code = """" +try: + do_something() +except: + pass +""" +try: + pass +except Exception: + pass +#: Okay +from . import custom_types as types -assert type(res) == type(None) +red = types.ColorTypeRED +red is types.ColorType.RED +#: Okay +from . import compute_type -types = StrEnum -if x == types.X: +if compute_type(foo) == 5: pass -#: E721 -assert type(res) is int - class Foo: def asdf(self, value: str | None): diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/W19.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/W19.py index 2fdcb6f65ee57..6bb8fb430c9d1 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/W19.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/W19.py @@ -152,3 +152,11 @@ def test_keys(self): multiline string with tab in it, different lines ''' " single line string with tab in it" + +f"test{ + tab_indented_should_be_flagged +} <- this tab is fine" + +f"""test{ + tab_indented_should_be_flagged +} <- this tab is fine""" diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_2.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_2.py new file mode 100644 index 0000000000000..b34ad587c46d5 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_2.py @@ -0,0 +1,54 @@ +# Same as `W605_0.py` but using f-strings instead. + +#: W605:1:10 +regex = f'\.png$' + +#: W605:2:1 +regex = f''' +\.png$ +''' + +#: W605:2:6 +f( + f'\_' +) + +#: W605:4:6 +f""" +multi-line +literal +with \_ somewhere +in the middle +""" + +#: W605:1:38 +value = f'new line\nand invalid escape \_ here' + + +#: Okay +regex = fr'\.png$' +regex = f'\\.png$' +regex = fr''' +\.png$ +''' +regex = fr''' +\\.png$ +''' +s = f'\\' +regex = f'\w' # noqa +regex = f''' +\w +''' # noqa + +regex = f'\\\_' +value = f'\{{1}}' +value = f'\{1}' +value = f'{1:\}' +value = f"{f"\{1}"}" +value = rf"{f"\{1}"}" + +# Okay +value = rf'\{{1}}' +value = rf'\{1}' +value = rf'{1:\}' +value = f"{rf"\{1}"}" diff --git a/crates/ruff_linter/resources/test/fixtures/pydocstyle/D300.py b/crates/ruff_linter/resources/test/fixtures/pydocstyle/D300.py new file mode 100644 index 0000000000000..eb9b4c57307da --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pydocstyle/D300.py @@ -0,0 +1,10 @@ +def with_backslash(): + """Sum\\mary.""" + + +def ends_in_quote(): + 'Sum\\mary."' + + +def contains_quote(): + 'Sum"\\mary.' diff --git a/crates/ruff_linter/resources/test/fixtures/pydocstyle/D301.py b/crates/ruff_linter/resources/test/fixtures/pydocstyle/D301.py index 1e6c8eef078ae..6af8362ad8dcf 100644 --- a/crates/ruff_linter/resources/test/fixtures/pydocstyle/D301.py +++ b/crates/ruff_linter/resources/test/fixtures/pydocstyle/D301.py @@ -10,6 +10,10 @@ def double_quotes_backslash_uppercase(): R"""Sum\\mary.""" +def shouldnt_add_raw_here(): + "Ruff \U000026a1" + + def make_unique_pod_id(pod_id: str) -> str | None: r""" Generate a unique Pod name. diff --git a/crates/ruff_linter/resources/test/fixtures/pyflakes/F401_19.py b/crates/ruff_linter/resources/test/fixtures/pyflakes/F401_19.py new file mode 100644 index 0000000000000..ea2f5fe8a8031 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pyflakes/F401_19.py @@ -0,0 +1,17 @@ +"""Test that type parameters are considered used.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from collections.abc import Callable + + from .foo import Record as Record1 + from .bar import Record as Record2 + +type RecordCallback[R: Record1] = Callable[[R], None] + + +def process_record[R: Record2](record: R) -> None: + ... diff --git a/crates/ruff_linter/resources/test/fixtures/pyflakes/F541.py b/crates/ruff_linter/resources/test/fixtures/pyflakes/F541.py index 09c10216eb337..1e59967fdb4f8 100644 --- a/crates/ruff_linter/resources/test/fixtures/pyflakes/F541.py +++ b/crates/ruff_linter/resources/test/fixtures/pyflakes/F541.py @@ -40,7 +40,5 @@ ""f"" ''f"" (""f""r"") - -# To be fixed -# Error: f-string: single '}' is not allowed at line 41 column 8 -# f"\{{x}}" +f"{v:{f"0.2f"}}" +f"\{{x}}" diff --git a/crates/ruff_linter/resources/test/fixtures/pyflakes/F632.py b/crates/ruff_linter/resources/test/fixtures/pyflakes/F632.py index 9f40368ad8b95..6e18123898565 100644 --- a/crates/ruff_linter/resources/test/fixtures/pyflakes/F632.py +++ b/crates/ruff_linter/resources/test/fixtures/pyflakes/F632.py @@ -25,3 +25,7 @@ {2 is not ''} + +# Regression test for +if values[1is not None ] is not '-': + pass diff --git a/crates/ruff_linter/resources/test/fixtures/pyflakes/F821_18.py b/crates/ruff_linter/resources/test/fixtures/pyflakes/F821_18.py new file mode 100644 index 0000000000000..8576a1d403d38 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pyflakes/F821_18.py @@ -0,0 +1,19 @@ +"""Test bindings created within annotations.""" + +from typing import Annotated + +foo = [1, 2, 3, 4, 5] + + +class Bar: + # OK: Allow list comprehensions in annotations (i.e., treat `qux` as a valid + # load in the scope of the annotation). + baz: Annotated[ + str, + [qux for qux in foo], + ] + + +# OK: Allow named expressions in annotations. +x: (y := 1) +print(y) diff --git a/crates/ruff_linter/resources/test/fixtures/pyflakes/F821_19.py b/crates/ruff_linter/resources/test/fixtures/pyflakes/F821_19.py new file mode 100644 index 0000000000000..660f75ec1c336 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pyflakes/F821_19.py @@ -0,0 +1,21 @@ +"""Test bindings created within annotations under `__future__` annotations.""" + +from __future__ import annotations + +from typing import Annotated + +foo = [1, 2, 3, 4, 5] + + +class Bar: + # OK: Allow list comprehensions in annotations (i.e., treat `qux` as a valid + # load in the scope of the annotation). + baz: Annotated[ + str, + [qux for qux in foo], + ] + + +# Error: `y` is not defined. +x: (y := 1) +print(y) diff --git a/crates/ruff_linter/resources/test/fixtures/pyflakes/F821_20.py b/crates/ruff_linter/resources/test/fixtures/pyflakes/F821_20.py new file mode 100644 index 0000000000000..1954bec533c2f --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pyflakes/F821_20.py @@ -0,0 +1,5 @@ +"""Test lazy evaluation of type alias values.""" + +type RecordCallback[R: Record] = Callable[[R], None] + +from collections.abc import Callable diff --git a/crates/ruff_linter/resources/test/fixtures/pyflakes/F841_3.py b/crates/ruff_linter/resources/test/fixtures/pyflakes/F841_3.py index 00c2962223d60..a9aa20d035a99 100644 --- a/crates/ruff_linter/resources/test/fixtures/pyflakes/F841_3.py +++ b/crates/ruff_linter/resources/test/fixtures/pyflakes/F841_3.py @@ -1,4 +1,4 @@ -"""Test case for autofixing F841 violations.""" +"""Test case for fixing F841 violations.""" def f(): diff --git a/crates/ruff_linter/resources/test/fixtures/pygrep_hooks/PGH002_0.py b/crates/ruff_linter/resources/test/fixtures/pygrep_hooks/PGH002_0.py index 523b65bf41c56..d1bc313fc821d 100644 --- a/crates/ruff_linter/resources/test/fixtures/pygrep_hooks/PGH002_0.py +++ b/crates/ruff_linter/resources/test/fixtures/pygrep_hooks/PGH002_0.py @@ -5,3 +5,6 @@ warnings.warn("this is ok") warn("by itself is also ok") logging.warning("this is fine") + +logger = logging.getLogger(__name__) +logger.warning("this is fine") diff --git a/crates/ruff_linter/resources/test/fixtures/pygrep_hooks/PGH002_1.py b/crates/ruff_linter/resources/test/fixtures/pygrep_hooks/PGH002_1.py index c2866d0969fd9..8ff160407c6fa 100644 --- a/crates/ruff_linter/resources/test/fixtures/pygrep_hooks/PGH002_1.py +++ b/crates/ruff_linter/resources/test/fixtures/pygrep_hooks/PGH002_1.py @@ -3,3 +3,6 @@ logging.warn("this is not ok") warn("not ok") + +logger = logging.getLogger(__name__) +logger.warn("this is not ok") diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/and_or_ternary.py b/crates/ruff_linter/resources/test/fixtures/pylint/and_or_ternary.py new file mode 100644 index 0000000000000..a65f0b02a0dc1 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pylint/and_or_ternary.py @@ -0,0 +1,73 @@ +# OK + +1<2 and 'b' and 'c' + +1<2 or 'a' and 'b' + +1<2 and 'a' + +1<2 or 'a' + +2>1 + +1<2 and 'a' or 'b' and 'c' + +1<2 and 'a' or 'b' or 'c' + +1<2 and 'a' or 'b' or 'c' or (lambda x: x+1) + +1<2 and 'a' or 'b' or (lambda x: x+1) or 'c' + +default = 'default' +if (not isinstance(default, bool) and isinstance(default, int)) \ + or (isinstance(default, str) and default): + pass + +docid, token = None, None +(docid is None and token is None) or (docid is not None and token is not None) + +vendor, os_version = 'darwin', '14' +vendor == "debian" and os_version in ["12"] or vendor == "ubuntu" and os_version in [] + +# Don't emit if the parent is an `if` statement. +if (task_id in task_dict and task_dict[task_id] is not task) \ + or task_id in used_group_ids: + pass + +no_target, is_x64, target = True, False, 'target' +if (no_target and not is_x64) or target == 'ARM_APPL_RUST_TARGET': + pass + +# Don't emit if the parent is a `bool_op` expression. +isinstance(val, str) and ((len(val) == 7 and val[0] == "#") or val in enums.NamedColor) + +# Errors + +1<2 and 'a' or 'b' + +(lambda x: x+1) and 'a' or 'b' + +'a' and (lambda x: x+1) or 'orange' + +val = '#0000FF' +(len(val) == 7 and val[0] == "#") or val in {'green'} + +marker = 'marker' +isinstance(marker, dict) and 'field' in marker or marker in {} + +def has_oranges(oranges, apples=None) -> bool: + return apples and False or oranges + +[x for x in l if a and b or c] + +{x: y for x in l if a and b or c} + +{x for x in l if a and b or c} + +new_list = [ + x + for sublist in all_lists + if a and b or c + for x in sublist + if (isinstance(operator, list) and x in operator) or x != operator +] diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/bad_dunder_method_name.py b/crates/ruff_linter/resources/test/fixtures/pylint/bad_dunder_method_name.py index be1cf65702e81..760951260e24c 100644 --- a/crates/ruff_linter/resources/test/fixtures/pylint/bad_dunder_method_name.py +++ b/crates/ruff_linter/resources/test/fixtures/pylint/bad_dunder_method_name.py @@ -49,6 +49,13 @@ def __private_method(self): def __doc__(self): return "Docstring" + # Added in Python 3.12 + def __buffer__(self): + return memoryview(b'') + + def __release_buffer__(self, buf): + pass + # Allow dunder methods recommended by attrs. def __attrs_post_init__(self): pass @@ -63,6 +70,19 @@ def __attrs_init__(self): def __html__(self): pass + # Allow Python's __index__ + def __index__(self): + pass + + # Allow _missing_, used by enum.Enum. + @classmethod + def _missing_(cls, value): + pass + + # Allow anonymous functions. + def _(self): + pass + def __foo_bar__(): # this is not checked by the [bad-dunder-name] rule ... diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/global_at_module_level.py b/crates/ruff_linter/resources/test/fixtures/pylint/global_at_module_level.py new file mode 100644 index 0000000000000..83ca8a93911fb --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pylint/global_at_module_level.py @@ -0,0 +1,10 @@ +global price # W0604 + +price = 25 + +if True: + global X # W0604 + +def no_error(): + global price + price = 30 diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/invalid_all_format.py b/crates/ruff_linter/resources/test/fixtures/pylint/invalid_all_format.py index fc7a3f8e154fa..f3b0eb1de133b 100644 --- a/crates/ruff_linter/resources/test/fixtures/pylint/invalid_all_format.py +++ b/crates/ruff_linter/resources/test/fixtures/pylint/invalid_all_format.py @@ -20,6 +20,8 @@ __all__ = foo["bar"] # [invalid-all-format] +__all__ = (foo := bar) # [invalid-all-format] + __all__ = ["Hello"] __all__ = ("Hello",) @@ -41,3 +43,7 @@ __all__ = __all__ + multiprocessing.__all__ __all__ = list[str](["Hello", "world"]) + +__all__ = list[str](foo()) + +__all__ = (foo := ["Hello", "world"]) diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/invalid_characters.py b/crates/ruff_linter/resources/test/fixtures/pylint/invalid_characters.py index 6233ed9353308d93ea948e16755fa23d395c9552..79c9307695a9153b9945e2976c45335259630bfa 100644 GIT binary patch delta 501 zcmb_Wy-LGS6jrW7xVku+SSX2b21(OMW3AvI_yjH@6iSljHo-P6xd|3a@FDK%3%L0X zzJa^5o2#qmq)Dl}TrTJPJ0Ism`#N}QvHPHX)fS)u=fP64X72NeAc=}X)BL+@U)mx9-u-y4WOg9 zHFBF1yH&RCQ7`ORdwP@$Y!T{}S^Gp9^PSzOPjG?IBV9toLe zNjj0V4BAS7j^BV1ALmv(&hv%5beu_&$3@Ty=QGF04S#CO*vSeZoJ7hZl1{(pc~*rn nGmFyPcKbbdFt~8L=X^=+rfHU?uLn4}b@va=XWpM?gPMN".format(self.internal_ids, self.external_ids, self.properties, self.tags, self.others) diff --git a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP032_3.py b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP032_3.py new file mode 100644 index 0000000000000..9c32a1a3e27a3 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP032_3.py @@ -0,0 +1,9 @@ +from django.utils.translation import gettext + +long = 'long' +split_to = 'split_to' +gettext( + 'some super {} and complicated string so that the error code ' + 'E501 Triggers when this is not {} multi-line'.format( + long, split_to) +) diff --git a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP035.py b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP035.py index d0da69d47f323..48d6929653f32 100644 --- a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP035.py +++ b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP035.py @@ -80,11 +80,14 @@ # OK from a import b -# Ok: `typing_extensions` contains backported improvements. +# OK: `typing_extensions` contains backported improvements. from typing_extensions import SupportsIndex -# Ok: `typing_extensions` contains backported improvements. +# OK: `typing_extensions` contains backported improvements. from typing_extensions import NamedTuple -# Ok: `typing_extensions` supports `frozen_default` (backported from 3.12). +# OK: `typing_extensions` supports `frozen_default` (backported from 3.12). from typing_extensions import dataclass_transform + +# UP035 +from backports.strenum import StrEnum diff --git a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP036_0.py b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP036_0.py index fc4ad3ccd78cc..eba76a594f487 100644 --- a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP036_0.py +++ b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP036_0.py @@ -184,3 +184,34 @@ def g(): if sys.version_info <= (3,12): print("py3") + +if sys.version_info <= (3,12): + print("py3") + +if sys.version_info == 10000000: + print("py3") + +if sys.version_info < (3,10000000): + print("py3") + +if sys.version_info <= (3,10000000): + print("py3") + +if sys.version_info > (3,12): + print("py3") + +if sys.version_info >= (3,12): + print("py3") + +# Slices on `sys.version_info` should be treated equivalently. +if sys.version_info[:2] >= (3,0): + print("py3") + +if sys.version_info[:3] >= (3,0): + print("py3") + +if sys.version_info[:2] > (3,13): + print("py3") + +if sys.version_info[:3] > (3,13): + print("py3") diff --git a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP040.pyi b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP040.pyi new file mode 100644 index 0000000000000..e2a18694bd86e --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP040.pyi @@ -0,0 +1,7 @@ +import typing +from typing import TypeAlias + +# UP040 +# Fixes in type stub files should be safe to apply unlike in regular code where runtime behavior could change +x: typing.TypeAlias = int +x: TypeAlias = int diff --git a/crates/ruff_linter/resources/test/fixtures/refurb/FURB101.py b/crates/ruff_linter/resources/test/fixtures/refurb/FURB101.py new file mode 100644 index 0000000000000..2f0276a09a826 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/refurb/FURB101.py @@ -0,0 +1,126 @@ +def foo(): + ... + + +def bar(x): + ... + + +# Errors. + +# FURB101 +with open("file.txt") as f: + x = f.read() + +# FURB101 +with open("file.txt", "rb") as f: + x = f.read() + +# FURB101 +with open("file.txt", mode="rb") as f: + x = f.read() + +# FURB101 +with open("file.txt", encoding="utf8") as f: + x = f.read() + +# FURB101 +with open("file.txt", errors="ignore") as f: + x = f.read() + +# FURB101 +with open("file.txt", errors="ignore", mode="rb") as f: + x = f.read() + +# FURB101 +with open("file.txt", mode="r") as f: # noqa: FURB120 + x = f.read() + +# FURB101 +with open(foo(), "rb") as f: + # The body of `with` is non-trivial, but the recommendation holds. + bar("pre") + bar(f.read()) + bar("post") + print("Done") + +# FURB101 +with open("a.txt") as a, open("b.txt", "rb") as b: + x = a.read() + y = b.read() + +# FURB101 +with foo() as a, open("file.txt") as b, foo() as c: + # We have other things in here, multiple with items, but + # the user reads the whole file and that bit they can replace. + bar(a) + bar(bar(a + b.read())) + bar(c) + + +# Non-errors. + +f2 = open("file2.txt") +with open("file.txt") as f: + x = f2.read() + +with open("file.txt") as f: + # Path.read_text() does not support size, so ignore this + x = f.read(100) + +# mode is dynamic +with open("file.txt", foo()) as f: + x = f.read() + +# keyword mode is incorrect +with open("file.txt", mode="a+") as f: + x = f.read() + +# enables line buffering, not supported in read_text() +with open("file.txt", buffering=1) as f: + x = f.read() + +# force CRLF, not supported in read_text() +with open("file.txt", newline="\r\n") as f: + x = f.read() + +# dont mistake "newline" for "mode" +with open("file.txt", newline="b") as f: + x = f.read() + +# I guess we can possibly also report this case, but the question +# is why the user would put "r+" here in the first place. +with open("file.txt", "r+") as f: + x = f.read() + +# Even though we read the whole file, we do other things. +with open("file.txt") as f: + x = f.read() + f.seek(0) + x += f.read(100) + +# This shouldn't error, since it could contain unsupported arguments, like `buffering`. +with open(*filename) as f: + x = f.read() + +# This shouldn't error, since it could contain unsupported arguments, like `buffering`. +with open(**kwargs) as f: + x = f.read() + +# This shouldn't error, since it could contain unsupported arguments, like `buffering`. +with open("file.txt", **kwargs) as f: + x = f.read() + +# This shouldn't error, since it could contain unsupported arguments, like `buffering`. +with open("file.txt", mode="r", **kwargs) as f: + x = f.read() + +# This could error (but doesn't), since it can't contain unsupported arguments, like +# `buffering`. +with open(*filename, mode="r") as f: + x = f.read() + +# This could error (but doesn't), since it can't contain unsupported arguments, like +# `buffering`. +with open(*filename, file="file.txt", mode="r") as f: + x = f.read() diff --git a/crates/ruff_linter/resources/test/fixtures/refurb/FURB105.py b/crates/ruff_linter/resources/test/fixtures/refurb/FURB105.py index 167ee675b8c61..2e58dc46b1766 100644 --- a/crates/ruff_linter/resources/test/fixtures/refurb/FURB105.py +++ b/crates/ruff_linter/resources/test/fixtures/refurb/FURB105.py @@ -31,3 +31,4 @@ print("foo", "", sep=",") print("foo", "", "bar", "", sep=",") print("", "", **kwargs) +print(*args, sep=",") diff --git a/crates/ruff_linter/resources/test/fixtures/refurb/FURB140.py b/crates/ruff_linter/resources/test/fixtures/refurb/FURB140.py index fd0bc8461316b..e4de0667c76ea 100644 --- a/crates/ruff_linter/resources/test/fixtures/refurb/FURB140.py +++ b/crates/ruff_linter/resources/test/fixtures/refurb/FURB140.py @@ -24,6 +24,12 @@ def zipped(): # FURB140 {print(x, y) for x, y in zipped()} +# FURB140 (check it still flags starred arguments). +# See https://github.com/astral-sh/ruff/issues/7636 +[foo(*t) for t in [(85, 60), (100, 80)]] +(foo(*t) for t in [(85, 60), (100, 80)]) +{foo(*t) for t in [(85, 60), (100, 80)]} + # Non-errors. [print(x, int) for x, _ in zipped()] @@ -41,3 +47,9 @@ def zipped(): [print() for x, y in zipped()] [print(x, end=y) for x, y in zipped()] + +[print(*x, y) for x, y in zipped()] + +[print(x, *y) for x, y in zipped()] + +[print(*x, *y) for x, y in zipped()] diff --git a/crates/ruff_linter/resources/test/fixtures/refurb/FURB148.py b/crates/ruff_linter/resources/test/fixtures/refurb/FURB148.py index 75f2c8a900603..5302dffbefabb 100644 --- a/crates/ruff_linter/resources/test/fixtures/refurb/FURB148.py +++ b/crates/ruff_linter/resources/test/fixtures/refurb/FURB148.py @@ -1,5 +1,15 @@ books = ["Dune", "Foundation", "Neuromancer"] +books_and_authors = { + "Dune": "Frank Herbert", + "Foundation": "Isaac Asimov", + "Neuromancer": "William Gibson", +} + +books_set = {"Dune", "Foundation", "Neuromancer"} + +books_tuple = ("Dune", "Foundation", "Neuromancer") + # Errors for index, _ in enumerate(books): print(index) @@ -55,6 +65,24 @@ for(index), _ in enumerate(books): print(index) +for index, _ in enumerate(books_and_authors): + print(index) + +for _, book in enumerate(books_and_authors): + print(book) + +for index, _ in enumerate(books_set): + print(index) + +for _, book in enumerate(books_set): + print(book) + +for index, _ in enumerate(books_tuple): + print(index) + +for _, book in enumerate(books_tuple): + print(book) + # OK for index, book in enumerate(books): print(index, book) @@ -64,3 +92,9 @@ for book in books: print(book) + +# Generators don't support the len() function. +# https://github.com/astral-sh/ruff/issues/7656 +a = (b for b in range(1, 100)) +for i, _ in enumerate(a): + print(i) diff --git a/crates/ruff_linter/resources/test/fixtures/refurb/FURB171.py b/crates/ruff_linter/resources/test/fixtures/refurb/FURB171.py new file mode 100644 index 0000000000000..4596ffe4edaf0 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/refurb/FURB171.py @@ -0,0 +1,45 @@ +# Errors. + +if 1 in (1,): + print("Single-element tuple") + +if 1 in [1]: + print("Single-element list") + +if 1 in {1}: + print("Single-element set") + +if "a" in "a": + print("Single-element string") + +if 1 not in (1,): + print("Check `not in` membership test") + +if not 1 in (1,): + print("Check the negated membership test") + +# Non-errors. + +if 1 in (1, 2): + pass + +if 1 in [1, 2]: + pass + +if 1 in {1, 2}: + pass + +if "a" in "ab": + pass + +if 1 == (1,): + pass + +if 1 > [1]: + pass + +if 1 is {1}: + pass + +if "a" == "a": + pass diff --git a/crates/ruff_linter/resources/test/fixtures/refurb/FURB177.py b/crates/ruff_linter/resources/test/fixtures/refurb/FURB177.py new file mode 100644 index 0000000000000..48823dfb054a9 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/refurb/FURB177.py @@ -0,0 +1,31 @@ +import pathlib +from pathlib import Path + +# Errors +_ = Path().resolve() +_ = pathlib.Path().resolve() + +_ = Path("").resolve() +_ = pathlib.Path("").resolve() + +_ = Path(".").resolve() +_ = pathlib.Path(".").resolve() + +_ = Path("", **kwargs).resolve() +_ = pathlib.Path("", **kwargs).resolve() + +_ = Path(".", **kwargs).resolve() +_ = pathlib.Path(".", **kwargs).resolve() + +# OK +_ = Path.cwd() +_ = pathlib.Path.cwd() + +_ = Path("foo").resolve() +_ = pathlib.Path("foo").resolve() + +_ = Path(".", "foo").resolve() +_ = pathlib.Path(".", "foo").resolve() + +_ = Path(*args).resolve() +_ = pathlib.Path(*args).resolve() diff --git a/crates/ruff_linter/resources/test/fixtures/ruff/RUF012.py b/crates/ruff_linter/resources/test/fixtures/ruff/RUF012.py index 9f7349f740ae4..ef58e45df1cb4 100644 --- a/crates/ruff_linter/resources/test/fixtures/ruff/RUF012.py +++ b/crates/ruff_linter/resources/test/fixtures/ruff/RUF012.py @@ -37,3 +37,14 @@ class D(BaseModel): without_annotation = [] class_variable: ClassVar[list[int]] = [] final_variable: Final[list[int]] = [] + + +from msgspec import Struct + + +class E(Struct): + mutable_default: list[int] = [] + immutable_annotation: Sequence[int] = [] + without_annotation = [] + class_variable: ClassVar[list[int]] = [] + final_variable: Final[list[int]] = [] diff --git a/crates/ruff_linter/resources/test/fixtures/ruff/RUF015.py b/crates/ruff_linter/resources/test/fixtures/ruff/RUF015.py index 2aa92f467cfe8..9ce388f6ceaba 100644 --- a/crates/ruff_linter/resources/test/fixtures/ruff/RUF015.py +++ b/crates/ruff_linter/resources/test/fixtures/ruff/RUF015.py @@ -38,6 +38,13 @@ list(range(10))[0] list(x.y)[0] list(x["y"])[0] +[*range(10)][0] +[*x["y"]][0] +[*x.y][0] +[* x.y][0] +[ + *x.y +][0] # RUF015 (multi-line) revision_heads_map_ast = [ @@ -45,3 +52,12 @@ for a in revision_heads_map_ast_obj.body if isinstance(a, ast.Assign) and a.targets[0].id == "REVISION_HEADS_MAP" ][0] + +# RUF015 (zip) +list(zip(x, y))[0] +[*zip(x, y)][0] + + +def test(): + zip = list # Overwrite the builtin zip + list(zip(x, y))[0] diff --git a/crates/ruff_linter/resources/test/fixtures/ruff/RUF017.py b/crates/ruff_linter/resources/test/fixtures/ruff/RUF017_0.py similarity index 73% rename from crates/ruff_linter/resources/test/fixtures/ruff/RUF017.py rename to crates/ruff_linter/resources/test/fixtures/ruff/RUF017_0.py index 546d08be57b59..6c20232032cd2 100644 --- a/crates/ruff_linter/resources/test/fixtures/ruff/RUF017.py +++ b/crates/ruff_linter/resources/test/fixtures/ruff/RUF017_0.py @@ -19,3 +19,8 @@ def func(): import functools, operator sum([x, y], []) + + +# Regression test for: https://github.com/astral-sh/ruff/issues/7718 +def func(): + sum((factor.dims for factor in bases), []) diff --git a/crates/ruff_linter/resources/test/fixtures/ruff/RUF017_1.py b/crates/ruff_linter/resources/test/fixtures/ruff/RUF017_1.py new file mode 100644 index 0000000000000..13a1e0be940c8 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/ruff/RUF017_1.py @@ -0,0 +1 @@ +sum((factor.dims for factor in bases), []) diff --git a/crates/ruff_linter/resources/test/fixtures/ruff/RUF018.py b/crates/ruff_linter/resources/test/fixtures/ruff/RUF018.py new file mode 100644 index 0000000000000..f7d4e24c6ea3b --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/ruff/RUF018.py @@ -0,0 +1,7 @@ +# RUF018 +assert (x := 0) == 0 +assert x, (y := "error") + +# OK +if z := 0: + pass diff --git a/crates/ruff_linter/resources/test/fixtures/ruff/RUF019.py b/crates/ruff_linter/resources/test/fixtures/ruff/RUF019.py new file mode 100644 index 0000000000000..ffcdb032e2237 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/ruff/RUF019.py @@ -0,0 +1,20 @@ +d = {} +# RUF019 +if "k" in d and d["k"]: + pass + +k = "k" +if k in d and d[k]: + pass + +if (k) in d and d[k]: + pass + +if k in d and d[(k)]: + pass + +# OK +v = "k" in d and d["k"] + +if f() in d and d[f()]: + pass diff --git a/crates/ruff_linter/resources/test/fixtures/ruff/RUF100_0.py b/crates/ruff_linter/resources/test/fixtures/ruff/RUF100_0.py index 5e51807ef90c9..25c8854b5434c 100644 --- a/crates/ruff_linter/resources/test/fixtures/ruff/RUF100_0.py +++ b/crates/ruff_linter/resources/test/fixtures/ruff/RUF100_0.py @@ -21,6 +21,9 @@ def f() -> None: # Invalid (but external) d = 1 # noqa: F841, V101 + # Invalid (but external) + d = 1 # noqa: V500 + # fmt: off # Invalid - no space before # d = 1# noqa: E501 diff --git a/crates/ruff_linter/resources/test/fixtures/ruff/confusables.py b/crates/ruff_linter/resources/test/fixtures/ruff/confusables.py index 3ae350887fa3f..7e88914110631 100644 --- a/crates/ruff_linter/resources/test/fixtures/ruff/confusables.py +++ b/crates/ruff_linter/resources/test/fixtures/ruff/confusables.py @@ -29,3 +29,19 @@ def f(): # consisting of a single ambiguous character, while the second character is a "word # boundary" (whitespace) that it itself ambiguous. x = "Р усский" + +# Same test cases as above but using f-strings instead: +x = f"𝐁ad string" +x = f"−" +x = f"Русский" +x = f"βα Bαd" +x = f"Р усский" + +# Nested f-strings +x = f"𝐁ad string {f" {f"Р усский"}"}" + +# Comments inside f-strings +x = f"string { # And here's a comment with an unusual parenthesis: ) +# And here's a comment with a greek alpha: ∗ +foo # And here's a comment with an unusual punctuation mark: ᜵ +}" diff --git a/crates/ruff_linter/resources/test/fixtures/tryceratops/TRY400.py b/crates/ruff_linter/resources/test/fixtures/tryceratops/TRY400.py index 1c31197c26754..987c321907880 100644 --- a/crates/ruff_linter/resources/test/fixtures/tryceratops/TRY400.py +++ b/crates/ruff_linter/resources/test/fixtures/tryceratops/TRY400.py @@ -75,3 +75,37 @@ def fine(): a = 1 except Exception: logger.error("Context message here", exc_info=sys.exc_info()) + + +from logging import error, exception + + +def bad(): + try: + a = 1 + except Exception: + error("Context message here") + + if True: + error("Context message here") + + +def good(): + try: + a = 1 + except Exception: + exception("Context message here") + + +def fine(): + try: + a = 1 + except Exception: + error("Context message here", exc_info=True) + + +def fine(): + try: + a = 1 + except Exception: + error("Context message here", exc_info=sys.exc_info()) diff --git a/crates/ruff_linter/resources/test/fixtures/tryceratops/TRY401.py b/crates/ruff_linter/resources/test/fixtures/tryceratops/TRY401.py index b96661a68ba5c..0aa58677837fd 100644 --- a/crates/ruff_linter/resources/test/fixtures/tryceratops/TRY401.py +++ b/crates/ruff_linter/resources/test/fixtures/tryceratops/TRY401.py @@ -62,3 +62,67 @@ def main_function(): except Exception as ex: logger.exception(f"Found an error: {er}") logger.exception(f"Found an error: {ex.field}") + + + +from logging import error, exception + + +def main_function(): + try: + process() + handle() + finish() + except Exception as ex: + exception(f"Found an error: {ex}") # TRY401 + + +def main_function(): + try: + process() + handle() + finish() + except ValueError as bad: + if True is False: + for i in range(10): + exception(f"Found an error: {bad} {good}") # TRY401 + except IndexError as bad: + exception(f"Found an error: {bad} {bad}") # TRY401 + except Exception as bad: + exception(f"Found an error: {bad}") # TRY401 + exception(f"Found an error: {bad}") # TRY401 + + if True: + exception(f"Found an error: {bad}") # TRY401 + + +def func_fstr(): + try: + ... + except Exception as ex: + exception(f"Logging an error: {ex}") # TRY401 + + +def func_concat(): + try: + ... + except Exception as ex: + exception("Logging an error: " + str(ex)) # TRY401 + + +def func_comma(): + try: + ... + except Exception as ex: + exception("Logging an error:", ex) # TRY401 + + +# OK +def main_function(): + try: + process() + handle() + finish() + except Exception as ex: + exception(f"Found an error: {er}") + exception(f"Found an error: {ex.field}") diff --git a/crates/ruff_linter/src/checkers/ast/analyze/bindings.rs b/crates/ruff_linter/src/checkers/ast/analyze/bindings.rs index fca537a63cea7..0fbc85f5552fa 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/bindings.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/bindings.rs @@ -10,6 +10,7 @@ pub(crate) fn bindings(checker: &mut Checker) { if !checker.any_enabled(&[ Rule::InvalidAllFormat, Rule::InvalidAllObject, + Rule::NonAsciiName, Rule::UnaliasedCollectionsAbcSetImport, Rule::UnconventionalImportAlias, Rule::UnusedVariable, @@ -32,15 +33,10 @@ pub(crate) fn bindings(checker: &mut Checker) { }, binding.range(), ); - if checker.patch(Rule::UnusedVariable) { - diagnostic.try_set_fix(|| { - pyflakes::fixes::remove_exception_handler_assignment( - binding, - checker.locator, - ) - .map(Fix::automatic) - }); - } + diagnostic.try_set_fix(|| { + pyflakes::fixes::remove_exception_handler_assignment(binding, checker.locator) + .map(Fix::safe_edit) + }); checker.diagnostics.push(diagnostic); } } @@ -54,6 +50,11 @@ pub(crate) fn bindings(checker: &mut Checker) { checker.diagnostics.push(diagnostic); } } + if checker.enabled(Rule::NonAsciiName) { + if let Some(diagnostic) = pylint::rules::non_ascii_name(binding, checker.locator) { + checker.diagnostics.push(diagnostic); + } + } if checker.enabled(Rule::UnconventionalImportAlias) { if let Some(diagnostic) = flake8_import_conventions::rules::unconventional_import_alias( checker, diff --git a/crates/ruff_linter/src/checkers/ast/analyze/deferred_lambdas.rs b/crates/ruff_linter/src/checkers/ast/analyze/deferred_lambdas.rs new file mode 100644 index 0000000000000..e3dffc3ad3874 --- /dev/null +++ b/crates/ruff_linter/src/checkers/ast/analyze/deferred_lambdas.rs @@ -0,0 +1,26 @@ +use ruff_python_ast::Expr; + +use crate::checkers::ast::Checker; +use crate::codes::Rule; +use crate::rules::{flake8_pie, pylint}; + +/// Run lint rules over all deferred lambdas in the [`SemanticModel`]. +pub(crate) fn deferred_lambdas(checker: &mut Checker) { + while !checker.deferred.lambdas.is_empty() { + let lambdas = std::mem::take(&mut checker.deferred.lambdas); + for snapshot in lambdas { + checker.semantic.restore(snapshot); + + let Some(Expr::Lambda(lambda)) = checker.semantic.current_expression() else { + unreachable!("Expected Expr::Lambda"); + }; + + if checker.enabled(Rule::UnnecessaryLambda) { + pylint::rules::unnecessary_lambda(checker, lambda); + } + if checker.enabled(Rule::ReimplementedListBuiltin) { + flake8_pie::rules::reimplemented_list_builtin(checker, lambda); + } + } + } +} diff --git a/crates/ruff_linter/src/checkers/ast/analyze/deferred_scopes.rs b/crates/ruff_linter/src/checkers/ast/analyze/deferred_scopes.rs index 493186ec444ec..e3b18d0685a27 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/deferred_scopes.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/deferred_scopes.rs @@ -306,7 +306,7 @@ pub(crate) fn deferred_scopes(checker: &mut Checker) { if scope.kind.is_function() { if checker.enabled(Rule::NoSelfUse) { - pylint::rules::no_self_use(checker, scope, &mut diagnostics); + pylint::rules::no_self_use(checker, scope_id, scope, &mut diagnostics); } } } diff --git a/crates/ruff_linter/src/checkers/ast/analyze/expression.rs b/crates/ruff_linter/src/checkers/ast/analyze/expression.rs index 6725ce15234bf..13ad26bed7933 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/expression.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/expression.rs @@ -414,13 +414,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { pyupgrade::rules::format_literals(checker, call, &summary); } if checker.enabled(Rule::FString) { - pyupgrade::rules::f_strings( - checker, - call, - &summary, - value, - checker.settings.line_length, - ); + pyupgrade::rules::f_strings(checker, call, &summary, value); } } } @@ -474,13 +468,13 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { } } if checker.enabled(Rule::BlockingHttpCallInAsyncFunction) { - flake8_async::rules::blocking_http_call(checker, expr); + flake8_async::rules::blocking_http_call(checker, call); } if checker.enabled(Rule::OpenSleepOrSubprocessInAsyncFunction) { - flake8_async::rules::open_sleep_or_subprocess_call(checker, expr); + flake8_async::rules::open_sleep_or_subprocess_call(checker, call); } if checker.enabled(Rule::BlockingOsCallInAsyncFunction) { - flake8_async::rules::blocking_os_call(checker, expr); + flake8_async::rules::blocking_os_call(checker, call); } if checker.any_enabled(&[Rule::Print, Rule::PPrint]) { flake8_print::rules::print_call(checker, call); @@ -508,7 +502,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { Rule::SuspiciousTelnetUsage, Rule::SuspiciousFTPLibUsage, ]) { - flake8_bandit::rules::suspicious_function_call(checker, expr); + flake8_bandit::rules::suspicious_function_call(checker, call); } if checker.enabled(Rule::ReSubPositionalArgs) { flake8_bugbear::rules::re_sub_positional_args(checker, call); @@ -592,6 +586,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { if checker.enabled(Rule::FlaskDebugTrue) { flake8_bandit::rules::flask_debug_true(checker, call); } + if checker.enabled(Rule::WeakCryptographicKey) { + flake8_bandit::rules::weak_cryptographic_key(checker, call); + } if checker.any_enabled(&[ Rule::SubprocessWithoutShellEqualsTrue, Rule::SubprocessPopenWithShellEqualsTrue, @@ -677,9 +674,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { ); } if checker.enabled(Rule::UnnecessarySubscriptReversal) { - flake8_comprehensions::rules::unnecessary_subscript_reversal( - checker, expr, func, args, - ); + flake8_comprehensions::rules::unnecessary_subscript_reversal(checker, call); } if checker.enabled(Rule::UnnecessaryMap) { flake8_comprehensions::rules::unnecessary_map( @@ -746,7 +741,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { pygrep_hooks::rules::no_eval(checker, func); } if checker.enabled(Rule::DeprecatedLogWarn) { - pygrep_hooks::rules::deprecated_log_warn(checker, func); + pygrep_hooks::rules::deprecated_log_warn(checker, call); } if checker.enabled(Rule::UnnecessaryDirectLambdaCall) { pylint::rules::unnecessary_direct_lambda_call(checker, expr, func); @@ -791,6 +786,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { if checker.enabled(Rule::SubprocessRunWithoutCheck) { pylint::rules::subprocess_run_without_check(checker, call); } + if checker.enabled(Rule::UnspecifiedEncoding) { + pylint::rules::unspecified_encoding(checker, call); + } if checker.any_enabled(&[ Rule::PytestRaisesWithoutException, Rule::PytestRaisesTooBroad, @@ -863,7 +861,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { Rule::OsPathGetctime, Rule::Glob, ]) { - flake8_use_pathlib::rules::replaceable_by_pathlib(checker, func); + flake8_use_pathlib::rules::replaceable_by_pathlib(checker, call); } if checker.enabled(Rule::PathConstructorCurrentDirectory) { flake8_use_pathlib::rules::path_constructor_current_directory(checker, expr, func); @@ -910,6 +908,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { if checker.enabled(Rule::ExceptionWithoutExcInfo) { flake8_logging::rules::exception_without_exc_info(checker, call); } + if checker.enabled(Rule::ImplicitCwd) { + refurb::rules::no_implicit_cwd(checker, call); + } } Expr::Dict( dict @ ast::ExprDict { @@ -960,9 +961,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { pylint::rules::await_outside_async(checker, expr); } } - Expr::FString(ast::ExprFString { values, .. }) => { + Expr::FString(fstring @ ast::ExprFString { values, .. }) => { if checker.enabled(Rule::FStringMissingPlaceholders) { - pyflakes::rules::f_string_missing_placeholders(expr, values, checker); + pyflakes::rules::f_string_missing_placeholders(fstring, checker); } if checker.enabled(Rule::HardcodedSQLExpression) { flake8_bandit::rules::hardcoded_sql_expression(checker, expr); @@ -1196,6 +1197,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { if checker.enabled(Rule::ComparisonWithItself) { pylint::rules::comparison_with_itself(checker, left, ops, comparators); } + if checker.enabled(Rule::LiteralMembership) { + pylint::rules::literal_membership(checker, compare); + } if checker.enabled(Rule::ComparisonOfConstant) { pylint::rules::comparison_of_constant(checker, left, ops, comparators); } @@ -1220,6 +1224,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { comparators, ); } + if checker.enabled(Rule::SingleItemMembershipTest) { + refurb::rules::single_item_membership_test(checker, expr, left, ops, comparators); + } } Expr::Constant(ast::ExprConstant { value: Constant::Int(_) | Constant::Float(_) | Constant::Complex { .. }, @@ -1260,23 +1267,17 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { } } } - Expr::Lambda( - lambda @ ast::ExprLambda { - parameters: _, - body: _, - range: _, - }, - ) => { - if checker.enabled(Rule::ReimplementedListBuiltin) { - flake8_pie::rules::reimplemented_list_builtin(checker, lambda); - } - } Expr::IfExp(ast::ExprIfExp { test, body, orelse, range: _, }) => { + if checker.enabled(Rule::IfElseBlockInsteadOfDictGet) { + flake8_simplify::rules::if_exp_instead_of_dict_get( + checker, expr, test, body, orelse, + ); + } if checker.enabled(Rule::IfExprWithTrueFalse) { flake8_simplify::rules::if_expr_with_true_false(checker, expr, test, body, orelse); } @@ -1411,6 +1412,17 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { if checker.enabled(Rule::RepeatedEqualityComparison) { pylint::rules::repeated_equality_comparison(checker, bool_op); } + if checker.enabled(Rule::AndOrTernary) { + pylint::rules::and_or_ternary(checker, bool_op); + } + if checker.enabled(Rule::UnnecessaryKeyCheck) { + ruff::rules::unnecessary_key_check(checker, expr); + } + } + Expr::NamedExpr(..) => { + if checker.enabled(Rule::AssignmentInAssert) { + ruff::rules::assignment_in_assert(checker, expr); + } } _ => {} }; diff --git a/crates/ruff_linter/src/checkers/ast/analyze/mod.rs b/crates/ruff_linter/src/checkers/ast/analyze/mod.rs index ed623b1abfdc6..dd9ec2fbfd2ce 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/mod.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/mod.rs @@ -1,6 +1,7 @@ pub(super) use bindings::bindings; pub(super) use comprehension::comprehension; pub(super) use deferred_for_loops::deferred_for_loops; +pub(super) use deferred_lambdas::deferred_lambdas; pub(super) use deferred_scopes::deferred_scopes; pub(super) use definitions::definitions; pub(super) use except_handler::except_handler; @@ -15,6 +16,7 @@ pub(super) use unresolved_references::unresolved_references; mod bindings; mod comprehension; mod deferred_for_loops; +mod deferred_lambdas; mod deferred_scopes; mod definitions; mod except_handler; diff --git a/crates/ruff_linter/src/checkers/ast/analyze/statement.rs b/crates/ruff_linter/src/checkers/ast/analyze/statement.rs index a39fd0734355c..29e5a72173440 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/statement.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/statement.rs @@ -21,6 +21,9 @@ use crate::settings::types::PythonVersion; pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { match stmt { Stmt::Global(ast::StmtGlobal { names, range: _ }) => { + if checker.enabled(Rule::GlobalAtModuleLevel) { + pylint::rules::global_at_module_level(checker, stmt); + } if checker.enabled(Rule::AmbiguousVariableName) { checker.diagnostics.extend(names.iter().filter_map(|name| { pycodestyle::rules::ambiguous_variable_name(name, name.range()) @@ -544,6 +547,9 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { } for alias in names { + if checker.enabled(Rule::NonAsciiImportName) { + pylint::rules::non_ascii_module_import(checker, alias); + } if let Some(asname) = &alias.asname { if checker.enabled(Rule::BuiltinVariableShadowing) { flake8_builtins::rules::builtin_variable_shadowing( @@ -695,8 +701,8 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { range: _, }, ) => { - let module = module.as_deref(); let level = *level; + let module = module.as_deref(); if checker.enabled(Rule::ModuleImportNotAtTopOfFile) { pycodestyle::rules::module_import_not_at_top_of_file(checker, stmt); } @@ -709,6 +715,11 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { } } } + if checker.enabled(Rule::NonAsciiImportName) { + for alias in names { + pylint::rules::non_ascii_module_import(checker, alias); + } + } if checker.enabled(Rule::UnnecessaryFutureImport) { if checker.settings.target_version >= PythonVersion::Py37 { if let Some("__future__") = module { @@ -964,7 +975,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { } } } - Stmt::Raise(ast::StmtRaise { exc, .. }) => { + Stmt::Raise(raise @ ast::StmtRaise { exc, .. }) => { if checker.enabled(Rule::RaiseNotImplemented) { if let Some(expr) = exc { pyflakes::rules::raise_not_implemented(checker, expr); @@ -1004,6 +1015,9 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { flake8_raise::rules::unnecessary_paren_on_raise_exception(checker, expr); } } + if checker.enabled(Rule::MisplacedBareRaise) { + pylint::rules::misplaced_bare_raise(checker, raise); + } } Stmt::AugAssign(ast::StmtAugAssign { target, .. }) => { if checker.enabled(Rule::GlobalStatement) { @@ -1038,16 +1052,16 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { flake8_simplify::rules::if_with_same_arms(checker, checker.locator, if_); } if checker.enabled(Rule::NeedlessBool) { - flake8_simplify::rules::needless_bool(checker, stmt); + flake8_simplify::rules::needless_bool(checker, if_); } if checker.enabled(Rule::IfElseBlockInsteadOfDictLookup) { - flake8_simplify::rules::manual_dict_lookup(checker, if_); + flake8_simplify::rules::if_else_block_instead_of_dict_lookup(checker, if_); } if checker.enabled(Rule::IfElseBlockInsteadOfIfExp) { - flake8_simplify::rules::use_ternary_operator(checker, stmt); + flake8_simplify::rules::if_else_block_instead_of_if_exp(checker, if_); } if checker.enabled(Rule::IfElseBlockInsteadOfDictGet) { - flake8_simplify::rules::use_dict_get_with_default(checker, if_); + flake8_simplify::rules::if_else_block_instead_of_dict_get(checker, if_); } if checker.enabled(Rule::TypeCheckWithoutTypeError) { tryceratops::rules::type_check_without_type_error( @@ -1067,6 +1081,9 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { if checker.enabled(Rule::CheckAndRemoveFromSet) { refurb::rules::check_and_remove_from_set(checker, if_); } + if checker.enabled(Rule::TooManyBooleanExpressions) { + pylint::rules::too_many_boolean_expressions(checker, if_); + } if checker.source_type.is_stub() { if checker.any_enabled(&[ Rule::UnrecognizedVersionInfoCheck, @@ -1166,6 +1183,9 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { if checker.enabled(Rule::RedefinedLoopName) { pylint::rules::redefined_loop_name(checker, stmt); } + if checker.enabled(Rule::ReadWholeFile) { + refurb::rules::read_whole_file(checker, with_stmt); + } } Stmt::While(ast::StmtWhile { body, orelse, .. }) => { if checker.enabled(Rule::FunctionUsesLoopVariable) { @@ -1305,6 +1325,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { } } Stmt::Assign(assign @ ast::StmtAssign { targets, value, .. }) => { + checker.enabled(Rule::NonAsciiName); if checker.enabled(Rule::LambdaAssignment) { if let [target] = &targets[..] { pycodestyle::rules::lambda_assignment(checker, target, value, None, stmt); diff --git a/crates/ruff_linter/src/checkers/ast/deferred.rs b/crates/ruff_linter/src/checkers/ast/deferred.rs index 85c900d1b004d..829621545241e 100644 --- a/crates/ruff_linter/src/checkers/ast/deferred.rs +++ b/crates/ruff_linter/src/checkers/ast/deferred.rs @@ -1,4 +1,4 @@ -use ruff_python_ast::{Expr, TypeParam}; +use ruff_python_ast::Expr; use ruff_python_semantic::{ScopeId, Snapshot}; use ruff_text_size::TextRange; @@ -10,8 +10,8 @@ pub(crate) struct Deferred<'a> { pub(crate) scopes: Vec, pub(crate) string_type_definitions: Vec<(TextRange, &'a str, Snapshot)>, pub(crate) future_type_definitions: Vec<(&'a Expr, Snapshot)>, - pub(crate) type_param_definitions: Vec<(&'a TypeParam, Snapshot)>, + pub(crate) type_param_definitions: Vec<(&'a Expr, Snapshot)>, pub(crate) functions: Vec, - pub(crate) lambdas: Vec<(&'a Expr, Snapshot)>, + pub(crate) lambdas: Vec, pub(crate) for_loops: Vec, } diff --git a/crates/ruff_linter/src/checkers/ast/mod.rs b/crates/ruff_linter/src/checkers/ast/mod.rs index 19663bbeff139..2905820fa6590 100644 --- a/crates/ruff_linter/src/checkers/ast/mod.rs +++ b/crates/ruff_linter/src/checkers/ast/mod.rs @@ -29,7 +29,7 @@ use std::path::Path; use itertools::Itertools; -use log::error; +use log::debug; use ruff_python_ast::{ self as ast, Arguments, Comprehension, Constant, ElifElseClause, ExceptHandler, Expr, ExprContext, Keyword, MatchCase, Parameter, ParameterWithDefault, Parameters, Pattern, Stmt, @@ -52,8 +52,8 @@ use ruff_python_parser::typing::{parse_type_annotation, AnnotationKind}; use ruff_python_semantic::analyze::{typing, visibility}; use ruff_python_semantic::{ BindingFlags, BindingId, BindingKind, Exceptions, Export, FromImport, Globals, Import, Module, - ModuleKind, NodeId, ScopeId, ScopeKind, SemanticModel, SemanticModelFlags, StarImport, - SubmoduleImport, + ModuleKind, NodeId, ScopeId, ScopeKind, SemanticModel, SemanticModelFlags, Snapshot, + StarImport, SubmoduleImport, }; use ruff_python_stdlib::builtins::{BUILTINS, MAGIC_GLOBALS}; use ruff_source_file::Locator; @@ -143,11 +143,6 @@ impl<'a> Checker<'a> { } impl<'a> Checker<'a> { - /// Return `true` if a patch should be generated for a given [`Rule`]. - pub(crate) fn patch(&self, code: Rule) -> bool { - self.settings.rules.should_fix(code) - } - /// Return `true` if a [`Rule`] is disabled by a `noqa` directive. pub(crate) fn rule_is_ignored(&self, code: Rule, offset: TextSize) -> bool { // TODO(charlie): `noqa` directives are mostly enforced in `check_lines.rs`. @@ -183,7 +178,7 @@ impl<'a> Checker<'a> { // Find the quote character used to start the containing f-string. let expr = self.semantic.current_expression()?; - let string_range = self.indexer.f_string_range(expr.start())?; + let string_range = self.indexer.fstring_ranges().innermost(expr.start())?; let trailing_quote = trailing_quote(self.locator.slice(string_range))?; // Invert the quote character, if it's a single quote. @@ -529,6 +524,7 @@ where ); self.semantic.push_definition(definition); self.semantic.push_scope(ScopeKind::Function(function_def)); + self.semantic.flags -= SemanticModelFlags::EXCEPTION_HANDLER; self.deferred.functions.push(self.semantic.snapshot()); @@ -567,6 +563,7 @@ where ); self.semantic.push_definition(definition); self.semantic.push_scope(ScopeKind::Class(class_def)); + self.semantic.flags -= SemanticModelFlags::EXCEPTION_HANDLER; // Extract any global bindings from the class body. if let Some(globals) = Globals::from_body(body) { @@ -585,7 +582,9 @@ where if let Some(type_params) = type_params { self.visit_type_params(type_params); } - self.visit_expr(value); + self.deferred + .type_param_definitions + .push((value, self.semantic.snapshot())); self.semantic.pop_scope(); self.visit_expr(name); } @@ -903,7 +902,7 @@ where } self.semantic.push_scope(ScopeKind::Lambda(lambda)); - self.deferred.lambdas.push((expr, self.semantic.snapshot())); + self.deferred.lambdas.push(self.semantic.snapshot()); } Expr::IfExp(ast::ExprIfExp { test, @@ -1168,15 +1167,16 @@ where range: _, }) = slice.as_ref() { - if let Some(expr) = elts.first() { + let mut iter = elts.iter(); + if let Some(expr) = iter.next() { self.visit_expr(expr); - for expr in elts.iter().skip(1) { - self.visit_non_type_definition(expr); - } - self.visit_expr_context(ctx); } + for expr in iter { + self.visit_non_type_definition(expr); + } + self.visit_expr_context(ctx); } else { - error!("Found non-Expr::Tuple argument to PEP 593 Annotation."); + debug!("Found non-Expr::Tuple argument to PEP 593 Annotation."); } } None => { @@ -1366,7 +1366,7 @@ where fn visit_match_case(&mut self, match_case: &'b MatchCase) { self.visit_pattern(&match_case.pattern); if let Some(expr) = &match_case.guard { - self.visit_expr(expr); + self.visit_boolean_test(expr); } self.semantic.push_branch(); @@ -1389,9 +1389,14 @@ where } } // Step 2: Traversal - self.deferred - .type_param_definitions - .push((type_param, self.semantic.snapshot())); + if let ast::TypeParam::TypeVar(ast::TypeParamTypeVar { + bound: Some(bound), .. + }) = type_param + { + self.deferred + .type_param_definitions + .push((bound, self.semantic.snapshot())); + } } } @@ -1618,10 +1623,12 @@ impl<'a> Checker<'a> { fn handle_node_store(&mut self, id: &'a str, expr: &Expr) { let parent = self.semantic.current_statement(); + // Match the left-hand side of an annotated assignment, like `x` in `x: int`. if matches!( parent, Stmt::AnnAssign(ast::StmtAnnAssign { value: None, .. }) - ) { + ) && !self.semantic.in_annotation() + { self.add_binding( id, expr.range(), @@ -1764,12 +1771,9 @@ impl<'a> Checker<'a> { for (type_param, snapshot) in type_params { self.semantic.restore(snapshot); - if let ast::TypeParam::TypeVar(ast::TypeParamTypeVar { - bound: Some(bound), .. - }) = type_param - { - self.visit_expr(bound); - } + self.semantic.flags |= + SemanticModelFlags::TYPE_PARAM_DEFINITION | SemanticModelFlags::TYPE_DEFINITION; + self.visit_expr(type_param); } } self.semantic.restore(snapshot); @@ -1830,15 +1834,15 @@ impl<'a> Checker<'a> { for snapshot in deferred_functions { self.semantic.restore(snapshot); - if let Stmt::FunctionDef(ast::StmtFunctionDef { + let Stmt::FunctionDef(ast::StmtFunctionDef { body, parameters, .. }) = self.semantic.current_statement() - { - self.visit_parameters(parameters); - self.visit_body(body); - } else { + else { unreachable!("Expected Stmt::FunctionDef") - } + }; + + self.visit_parameters(parameters); + self.visit_body(body); } } self.semantic.restore(snapshot); @@ -1846,26 +1850,31 @@ impl<'a> Checker<'a> { fn visit_deferred_lambdas(&mut self) { let snapshot = self.semantic.snapshot(); + let mut deferred: Vec = Vec::with_capacity(self.deferred.lambdas.len()); while !self.deferred.lambdas.is_empty() { let lambdas = std::mem::take(&mut self.deferred.lambdas); - for (expr, snapshot) in lambdas { + for snapshot in lambdas { self.semantic.restore(snapshot); - if let Expr::Lambda(ast::ExprLambda { + let Some(Expr::Lambda(ast::ExprLambda { parameters, body, range: _, - }) = expr - { - if let Some(parameters) = parameters { - self.visit_parameters(parameters); - } - self.visit_expr(body); - } else { + })) = self.semantic.current_expression() + else { unreachable!("Expected Expr::Lambda"); + }; + + if let Some(parameters) = parameters { + self.visit_parameters(parameters); } + self.visit_expr(body); + + deferred.push(snapshot); } } + // Reset the deferred lambdas, so we can analyze them later on. + self.deferred.lambdas = deferred; self.semantic.restore(snapshot); } @@ -1985,6 +1994,7 @@ pub(crate) fn check_ast( checker.visit_exports(); // Check docstrings, bindings, and unresolved references. + analyze::deferred_lambdas(&mut checker); analyze::deferred_for_loops(&mut checker); analyze::definitions(&mut checker); analyze::bindings(&mut checker); diff --git a/crates/ruff_linter/src/checkers/logical_lines.rs b/crates/ruff_linter/src/checkers/logical_lines.rs index 024efa6175d03..28382971e5f24 100644 --- a/crates/ruff_linter/src/checkers/logical_lines.rs +++ b/crates/ruff_linter/src/checkers/logical_lines.rs @@ -5,7 +5,7 @@ use ruff_python_parser::TokenKind; use ruff_source_file::Locator; use ruff_text_size::{Ranged, TextRange}; -use crate::registry::{AsRule, Rule}; +use crate::registry::AsRule; use crate::rules::pycodestyle::rules::logical_lines::{ continuation_line_missing_indentation_or_outdented, extraneous_whitespace, indentation, missing_whitespace, missing_whitespace_after_keyword, missing_whitespace_around_operator, @@ -39,17 +39,6 @@ pub(crate) fn check_logical_lines( ) -> Vec { let mut context = LogicalLinesContext::new(settings); - let should_fix_missing_whitespace = settings.rules.should_fix(Rule::MissingWhitespace); - let should_fix_whitespace_before_parameters = - settings.rules.should_fix(Rule::WhitespaceBeforeParameters); - let should_fix_whitespace_after_open_bracket = - settings.rules.should_fix(Rule::WhitespaceAfterOpenBracket); - let should_fix_whitespace_before_close_bracket = settings - .rules - .should_fix(Rule::WhitespaceBeforeCloseBracket); - let should_fix_whitespace_before_punctuation = - settings.rules.should_fix(Rule::WhitespaceBeforePunctuation); - let mut prev_line = None; let mut prev_indent_level = None; let indent_char = stylist.indentation().as_char(); @@ -59,7 +48,7 @@ pub(crate) fn check_logical_lines( space_around_operator(&line, &mut context); whitespace_around_named_parameter_equals(&line, &mut context); missing_whitespace_around_operator(&line, &mut context); - missing_whitespace(&line, should_fix_missing_whitespace, &mut context); + missing_whitespace(&line, &mut context); } if line.flags().contains(TokenFlags::PUNCTUATION) { space_after_comma(&line, &mut context); @@ -69,13 +58,7 @@ pub(crate) fn check_logical_lines( .flags() .intersects(TokenFlags::OPERATOR | TokenFlags::BRACKET | TokenFlags::PUNCTUATION) { - extraneous_whitespace( - &line, - &mut context, - should_fix_whitespace_after_open_bracket, - should_fix_whitespace_before_close_bracket, - should_fix_whitespace_before_punctuation, - ); + extraneous_whitespace(&line, &mut context); } if line.flags().contains(TokenFlags::KEYWORD) { @@ -88,11 +71,7 @@ pub(crate) fn check_logical_lines( } if line.flags().contains(TokenFlags::BRACKET) { - whitespace_before_parameters( - &line, - should_fix_whitespace_before_parameters, - &mut context, - ); + whitespace_before_parameters(&line, &mut context); } // Extract the indentation level. @@ -113,6 +92,7 @@ pub(crate) fn check_logical_lines( continuation_line_missing_indentation_or_outdented( &mut context, &line, + locator, indent_char, indent_size, ); diff --git a/crates/ruff_linter/src/checkers/noqa.rs b/crates/ruff_linter/src/checkers/noqa.rs index 9a762c6cab5cd..7b4224c4e1e99 100644 --- a/crates/ruff_linter/src/checkers/noqa.rs +++ b/crates/ruff_linter/src/checkers/noqa.rs @@ -109,10 +109,8 @@ pub(crate) fn check_noqa( if line.matches.is_empty() { let mut diagnostic = Diagnostic::new(UnusedNOQA { codes: None }, directive.range()); - if settings.rules.should_fix(diagnostic.kind.rule()) { - diagnostic - .set_fix(Fix::suggested(delete_noqa(directive.range(), locator))); - } + diagnostic.set_fix(Fix::safe_edit(delete_noqa(directive.range(), locator))); + diagnostics.push(diagnostic); } } @@ -130,7 +128,10 @@ pub(crate) fn check_noqa( } if line.matches.iter().any(|match_| *match_ == code) - || settings.external.contains(code) + || settings + .external + .iter() + .any(|external| code.starts_with(external)) { valid_codes.push(code); } else { @@ -173,18 +174,14 @@ pub(crate) fn check_noqa( }, directive.range(), ); - if settings.rules.should_fix(diagnostic.kind.rule()) { - if valid_codes.is_empty() { - diagnostic.set_fix(Fix::suggested(delete_noqa( - directive.range(), - locator, - ))); - } else { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - format!("# noqa: {}", valid_codes.join(", ")), - directive.range(), - ))); - } + if valid_codes.is_empty() { + diagnostic + .set_fix(Fix::safe_edit(delete_noqa(directive.range(), locator))); + } else { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + format!("# noqa: {}", valid_codes.join(", ")), + directive.range(), + ))); } diagnostics.push(diagnostic); } @@ -230,7 +227,13 @@ fn delete_noqa(range: TextRange, locator: &Locator) -> Edit { Edit::deletion(range.start() - leading_space_len, line_range.end()) } // Ex) `x = 1 # noqa # type: ignore` - else if locator.contents()[usize::from(range.end() + trailing_space_len)..].starts_with('#') { + else if locator + .slice(TextRange::new( + range.end() + trailing_space_len, + line_range.end(), + )) + .starts_with('#') + { Edit::deletion(range.start(), range.end() + trailing_space_len) } // Ex) `x = 1 # noqa here` diff --git a/crates/ruff_linter/src/checkers/physical_lines.rs b/crates/ruff_linter/src/checkers/physical_lines.rs index 1f5cec0a7c707..a2b8b98b85c34 100644 --- a/crates/ruff_linter/src/checkers/physical_lines.rs +++ b/crates/ruff_linter/src/checkers/physical_lines.rs @@ -41,7 +41,7 @@ pub(crate) fn check_physical_lines( .is_some() { if enforce_doc_line_too_long { - if let Some(diagnostic) = doc_line_too_long(&line, settings) { + if let Some(diagnostic) = doc_line_too_long(&line, indexer, settings) { diagnostics.push(diagnostic); } } @@ -54,7 +54,7 @@ pub(crate) fn check_physical_lines( } if enforce_line_too_long { - if let Some(diagnostic) = line_too_long(&line, settings) { + if let Some(diagnostic) = line_too_long(&line, indexer, settings) { diagnostics.push(diagnostic); } } @@ -71,11 +71,7 @@ pub(crate) fn check_physical_lines( } if enforce_no_newline_at_end_of_file { - if let Some(diagnostic) = no_newline_at_end_of_file( - locator, - stylist, - settings.rules.should_fix(Rule::MissingNewlineAtEndOfFile), - ) { + if let Some(diagnostic) = no_newline_at_end_of_file(locator, stylist) { diagnostics.push(diagnostic); } } @@ -99,6 +95,7 @@ mod tests { use crate::line_width::LineLength; use crate::registry::Rule; + use crate::rules::pycodestyle; use crate::settings::LinterSettings; use super::check_physical_lines; @@ -118,7 +115,10 @@ mod tests { &indexer, &[], &LinterSettings { - line_length, + pycodestyle: pycodestyle::settings::Settings { + max_line_length: line_length, + ..pycodestyle::settings::Settings::default() + }, ..LinterSettings::for_rule(Rule::LineTooLong) }, ) diff --git a/crates/ruff_linter/src/checkers/tokens.rs b/crates/ruff_linter/src/checkers/tokens.rs index 98ecbc2898363..ad623b9e5ba4c 100644 --- a/crates/ruff_linter/src/checkers/tokens.rs +++ b/crates/ruff_linter/src/checkers/tokens.rs @@ -45,23 +45,25 @@ pub(crate) fn check_tokens( let mut state_machine = StateMachine::default(); for &(ref tok, range) in tokens.iter().flatten() { let is_docstring = state_machine.consume(tok); - if matches!(tok, Tok::String { .. } | Tok::Comment(_)) { - ruff::rules::ambiguous_unicode_character( - &mut diagnostics, - locator, - range, - if tok.is_string() { - if is_docstring { - Context::Docstring - } else { - Context::String - } + let context = match tok { + Tok::String { .. } => { + if is_docstring { + Context::Docstring } else { - Context::Comment - }, - settings, - ); - } + Context::String + } + } + Tok::FStringMiddle { .. } => Context::String, + Tok::Comment(_) => Context::Comment, + _ => continue, + }; + ruff::rules::ambiguous_unicode_character( + &mut diagnostics, + locator, + range, + context, + settings, + ); } } @@ -70,19 +72,18 @@ pub(crate) fn check_tokens( } if settings.rules.enabled(Rule::UTF8EncodingDeclaration) { - pyupgrade::rules::unnecessary_coding_comment(&mut diagnostics, locator, indexer, settings); + pyupgrade::rules::unnecessary_coding_comment(&mut diagnostics, locator, indexer); } if settings.rules.enabled(Rule::InvalidEscapeSequence) { for (tok, range) in tokens.iter().flatten() { - if tok.is_string() { - pycodestyle::rules::invalid_escape_sequence( - &mut diagnostics, - locator, - *range, - settings.rules.should_fix(Rule::InvalidEscapeSequence), - ); - } + pycodestyle::rules::invalid_escape_sequence( + &mut diagnostics, + locator, + indexer, + tok, + *range, + ); } } @@ -98,9 +99,7 @@ pub(crate) fn check_tokens( Rule::InvalidCharacterZeroWidthSpace, ]) { for (tok, range) in tokens.iter().flatten() { - if tok.is_string() { - pylint::rules::invalid_string_characters(&mut diagnostics, *range, locator); - } + pylint::rules::invalid_string_characters(&mut diagnostics, tok, *range, locator); } } @@ -109,22 +108,19 @@ pub(crate) fn check_tokens( Rule::MultipleStatementsOnOneLineSemicolon, Rule::UselessSemicolon, ]) { - pycodestyle::rules::compound_statements( - &mut diagnostics, - tokens, - locator, - indexer, - settings, - ); + pycodestyle::rules::compound_statements(&mut diagnostics, tokens, locator, indexer); + } + + if settings.rules.enabled(Rule::AvoidableEscapedQuote) && settings.flake8_quotes.avoid_escape { + flake8_quotes::rules::avoidable_escaped_quote(&mut diagnostics, tokens, locator, settings); } if settings.rules.any_enabled(&[ Rule::BadQuotesInlineString, Rule::BadQuotesMultilineString, Rule::BadQuotesDocstring, - Rule::AvoidableEscapedQuote, ]) { - flake8_quotes::rules::from_tokens(&mut diagnostics, tokens, locator, settings); + flake8_quotes::rules::check_string_quotes(&mut diagnostics, tokens, locator, settings); } if settings.rules.any_enabled(&[ @@ -134,8 +130,9 @@ pub(crate) fn check_tokens( flake8_implicit_str_concat::rules::implicit( &mut diagnostics, tokens, - &settings.flake8_implicit_str_concat, + settings, locator, + indexer, ); } @@ -144,11 +141,11 @@ pub(crate) fn check_tokens( Rule::TrailingCommaOnBareTuple, Rule::ProhibitedTrailingComma, ]) { - flake8_commas::rules::trailing_commas(&mut diagnostics, tokens, locator, settings); + flake8_commas::rules::trailing_commas(&mut diagnostics, tokens, locator); } if settings.rules.enabled(Rule::ExtraneousParentheses) { - pyupgrade::rules::extraneous_parentheses(&mut diagnostics, tokens, locator, settings); + pyupgrade::rules::extraneous_parentheses(&mut diagnostics, tokens, locator); } if is_stub && settings.rules.enabled(Rule::TypeCommentInStub) { @@ -162,7 +159,7 @@ pub(crate) fn check_tokens( Rule::ShebangNotFirstLine, Rule::ShebangMissingPython, ]) { - flake8_executable::rules::from_tokens(tokens, path, locator, settings, &mut diagnostics); + flake8_executable::rules::from_tokens(tokens, path, locator, &mut diagnostics); } if settings.rules.any_enabled(&[ @@ -187,7 +184,7 @@ pub(crate) fn check_tokens( TodoComment::from_comment(comment, *comment_range, i) }) .collect(); - flake8_todos::rules::todos(&mut diagnostics, &todo_comments, locator, indexer, settings); + flake8_todos::rules::todos(&mut diagnostics, &todo_comments, locator, indexer); flake8_fixme::rules::todos(&mut diagnostics, &todo_comments); } diff --git a/crates/ruff_linter/src/codes.rs b/crates/ruff_linter/src/codes.rs index cb8df0b1dca35..a325f7cb832a8 100644 --- a/crates/ruff_linter/src/codes.rs +++ b/crates/ruff_linter/src/codes.rs @@ -4,14 +4,12 @@ /// `--select`. For pylint this is e.g. C0414 and E0118 but also C and E01. use std::fmt::Formatter; -use strum_macros::{AsRefStr, EnumIter}; - -use ruff_diagnostics::Violation; - use crate::registry::{AsRule, Linter}; use crate::rule_selector::is_single_rule_selector; use crate::rules; +use strum_macros::{AsRefStr, EnumIter}; + #[derive(PartialEq, Eq, PartialOrd, Ord)] pub struct NoqaCode(&'static str, &'static str); @@ -50,8 +48,8 @@ impl PartialEq<&str> for NoqaCode { #[derive(Debug, Copy, Clone)] pub enum RuleGroup { - /// The rule has not been assigned to any specific group. - Unspecified, + /// The rule is stable. + Stable, /// The rule is unstable, and preview mode must be enabled for usage. Preview, /// Legacy category for unstable rules, supports backwards compatible selection. @@ -67,7 +65,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { #[rustfmt::skip] Some(match (linter, code) { // pycodestyle errors - (Pycodestyle, "E101") => (RuleGroup::Unspecified, rules::pycodestyle::rules::MixedSpacesAndTabs), + (Pycodestyle, "E101") => (RuleGroup::Stable, rules::pycodestyle::rules::MixedSpacesAndTabs), #[allow(deprecated)] (Pycodestyle, "E111") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::IndentationWithInvalidMultiple), #[allow(deprecated)] @@ -136,786 +134,799 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Pycodestyle, "E274") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::TabBeforeKeyword), #[allow(deprecated)] (Pycodestyle, "E275") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAfterKeyword), - (Pycodestyle, "E401") => (RuleGroup::Unspecified, rules::pycodestyle::rules::MultipleImportsOnOneLine), - (Pycodestyle, "E402") => (RuleGroup::Unspecified, rules::pycodestyle::rules::ModuleImportNotAtTopOfFile), - (Pycodestyle, "E501") => (RuleGroup::Unspecified, rules::pycodestyle::rules::LineTooLong), - (Pycodestyle, "E701") => (RuleGroup::Unspecified, rules::pycodestyle::rules::MultipleStatementsOnOneLineColon), - (Pycodestyle, "E702") => (RuleGroup::Unspecified, rules::pycodestyle::rules::MultipleStatementsOnOneLineSemicolon), - (Pycodestyle, "E703") => (RuleGroup::Unspecified, rules::pycodestyle::rules::UselessSemicolon), - (Pycodestyle, "E711") => (RuleGroup::Unspecified, rules::pycodestyle::rules::NoneComparison), - (Pycodestyle, "E712") => (RuleGroup::Unspecified, rules::pycodestyle::rules::TrueFalseComparison), - (Pycodestyle, "E713") => (RuleGroup::Unspecified, rules::pycodestyle::rules::NotInTest), - (Pycodestyle, "E714") => (RuleGroup::Unspecified, rules::pycodestyle::rules::NotIsTest), - (Pycodestyle, "E721") => (RuleGroup::Unspecified, rules::pycodestyle::rules::TypeComparison), - (Pycodestyle, "E722") => (RuleGroup::Unspecified, rules::pycodestyle::rules::BareExcept), - (Pycodestyle, "E731") => (RuleGroup::Unspecified, rules::pycodestyle::rules::LambdaAssignment), - (Pycodestyle, "E741") => (RuleGroup::Unspecified, rules::pycodestyle::rules::AmbiguousVariableName), - (Pycodestyle, "E742") => (RuleGroup::Unspecified, rules::pycodestyle::rules::AmbiguousClassName), - (Pycodestyle, "E743") => (RuleGroup::Unspecified, rules::pycodestyle::rules::AmbiguousFunctionName), - (Pycodestyle, "E902") => (RuleGroup::Unspecified, rules::pycodestyle::rules::IOError), - (Pycodestyle, "E999") => (RuleGroup::Unspecified, rules::pycodestyle::rules::SyntaxError), + (Pycodestyle, "E401") => (RuleGroup::Stable, rules::pycodestyle::rules::MultipleImportsOnOneLine), + (Pycodestyle, "E402") => (RuleGroup::Stable, rules::pycodestyle::rules::ModuleImportNotAtTopOfFile), + (Pycodestyle, "E501") => (RuleGroup::Stable, rules::pycodestyle::rules::LineTooLong), + (Pycodestyle, "E701") => (RuleGroup::Stable, rules::pycodestyle::rules::MultipleStatementsOnOneLineColon), + (Pycodestyle, "E702") => (RuleGroup::Stable, rules::pycodestyle::rules::MultipleStatementsOnOneLineSemicolon), + (Pycodestyle, "E703") => (RuleGroup::Stable, rules::pycodestyle::rules::UselessSemicolon), + (Pycodestyle, "E711") => (RuleGroup::Stable, rules::pycodestyle::rules::NoneComparison), + (Pycodestyle, "E712") => (RuleGroup::Stable, rules::pycodestyle::rules::TrueFalseComparison), + (Pycodestyle, "E713") => (RuleGroup::Stable, rules::pycodestyle::rules::NotInTest), + (Pycodestyle, "E714") => (RuleGroup::Stable, rules::pycodestyle::rules::NotIsTest), + (Pycodestyle, "E721") => (RuleGroup::Stable, rules::pycodestyle::rules::TypeComparison), + (Pycodestyle, "E722") => (RuleGroup::Stable, rules::pycodestyle::rules::BareExcept), + (Pycodestyle, "E731") => (RuleGroup::Stable, rules::pycodestyle::rules::LambdaAssignment), + (Pycodestyle, "E741") => (RuleGroup::Stable, rules::pycodestyle::rules::AmbiguousVariableName), + (Pycodestyle, "E742") => (RuleGroup::Stable, rules::pycodestyle::rules::AmbiguousClassName), + (Pycodestyle, "E743") => (RuleGroup::Stable, rules::pycodestyle::rules::AmbiguousFunctionName), + (Pycodestyle, "E902") => (RuleGroup::Stable, rules::pycodestyle::rules::IOError), + (Pycodestyle, "E999") => (RuleGroup::Stable, rules::pycodestyle::rules::SyntaxError), // pycodestyle warnings - (Pycodestyle, "W191") => (RuleGroup::Unspecified, rules::pycodestyle::rules::TabIndentation), - (Pycodestyle, "W291") => (RuleGroup::Unspecified, rules::pycodestyle::rules::TrailingWhitespace), - (Pycodestyle, "W292") => (RuleGroup::Unspecified, rules::pycodestyle::rules::MissingNewlineAtEndOfFile), - (Pycodestyle, "W293") => (RuleGroup::Unspecified, rules::pycodestyle::rules::BlankLineWithWhitespace), - (Pycodestyle, "W505") => (RuleGroup::Unspecified, rules::pycodestyle::rules::DocLineTooLong), - (Pycodestyle, "W605") => (RuleGroup::Unspecified, rules::pycodestyle::rules::InvalidEscapeSequence), + (Pycodestyle, "W191") => (RuleGroup::Stable, rules::pycodestyle::rules::TabIndentation), + (Pycodestyle, "W291") => (RuleGroup::Stable, rules::pycodestyle::rules::TrailingWhitespace), + (Pycodestyle, "W292") => (RuleGroup::Stable, rules::pycodestyle::rules::MissingNewlineAtEndOfFile), + (Pycodestyle, "W293") => (RuleGroup::Stable, rules::pycodestyle::rules::BlankLineWithWhitespace), + (Pycodestyle, "W505") => (RuleGroup::Stable, rules::pycodestyle::rules::DocLineTooLong), + (Pycodestyle, "W605") => (RuleGroup::Stable, rules::pycodestyle::rules::InvalidEscapeSequence), // pyflakes - (Pyflakes, "401") => (RuleGroup::Unspecified, rules::pyflakes::rules::UnusedImport), - (Pyflakes, "402") => (RuleGroup::Unspecified, rules::pyflakes::rules::ImportShadowedByLoopVar), - (Pyflakes, "403") => (RuleGroup::Unspecified, rules::pyflakes::rules::UndefinedLocalWithImportStar), - (Pyflakes, "404") => (RuleGroup::Unspecified, rules::pyflakes::rules::LateFutureImport), - (Pyflakes, "405") => (RuleGroup::Unspecified, rules::pyflakes::rules::UndefinedLocalWithImportStarUsage), - (Pyflakes, "406") => (RuleGroup::Unspecified, rules::pyflakes::rules::UndefinedLocalWithNestedImportStarUsage), - (Pyflakes, "407") => (RuleGroup::Unspecified, rules::pyflakes::rules::FutureFeatureNotDefined), - (Pyflakes, "501") => (RuleGroup::Unspecified, rules::pyflakes::rules::PercentFormatInvalidFormat), - (Pyflakes, "502") => (RuleGroup::Unspecified, rules::pyflakes::rules::PercentFormatExpectedMapping), - (Pyflakes, "503") => (RuleGroup::Unspecified, rules::pyflakes::rules::PercentFormatExpectedSequence), - (Pyflakes, "504") => (RuleGroup::Unspecified, rules::pyflakes::rules::PercentFormatExtraNamedArguments), - (Pyflakes, "505") => (RuleGroup::Unspecified, rules::pyflakes::rules::PercentFormatMissingArgument), - (Pyflakes, "506") => (RuleGroup::Unspecified, rules::pyflakes::rules::PercentFormatMixedPositionalAndNamed), - (Pyflakes, "507") => (RuleGroup::Unspecified, rules::pyflakes::rules::PercentFormatPositionalCountMismatch), - (Pyflakes, "508") => (RuleGroup::Unspecified, rules::pyflakes::rules::PercentFormatStarRequiresSequence), - (Pyflakes, "509") => (RuleGroup::Unspecified, rules::pyflakes::rules::PercentFormatUnsupportedFormatCharacter), - (Pyflakes, "521") => (RuleGroup::Unspecified, rules::pyflakes::rules::StringDotFormatInvalidFormat), - (Pyflakes, "522") => (RuleGroup::Unspecified, rules::pyflakes::rules::StringDotFormatExtraNamedArguments), - (Pyflakes, "523") => (RuleGroup::Unspecified, rules::pyflakes::rules::StringDotFormatExtraPositionalArguments), - (Pyflakes, "524") => (RuleGroup::Unspecified, rules::pyflakes::rules::StringDotFormatMissingArguments), - (Pyflakes, "525") => (RuleGroup::Unspecified, rules::pyflakes::rules::StringDotFormatMixingAutomatic), - (Pyflakes, "541") => (RuleGroup::Unspecified, rules::pyflakes::rules::FStringMissingPlaceholders), - (Pyflakes, "601") => (RuleGroup::Unspecified, rules::pyflakes::rules::MultiValueRepeatedKeyLiteral), - (Pyflakes, "602") => (RuleGroup::Unspecified, rules::pyflakes::rules::MultiValueRepeatedKeyVariable), - (Pyflakes, "621") => (RuleGroup::Unspecified, rules::pyflakes::rules::ExpressionsInStarAssignment), - (Pyflakes, "622") => (RuleGroup::Unspecified, rules::pyflakes::rules::MultipleStarredExpressions), - (Pyflakes, "631") => (RuleGroup::Unspecified, rules::pyflakes::rules::AssertTuple), - (Pyflakes, "632") => (RuleGroup::Unspecified, rules::pyflakes::rules::IsLiteral), - (Pyflakes, "633") => (RuleGroup::Unspecified, rules::pyflakes::rules::InvalidPrintSyntax), - (Pyflakes, "634") => (RuleGroup::Unspecified, rules::pyflakes::rules::IfTuple), - (Pyflakes, "701") => (RuleGroup::Unspecified, rules::pyflakes::rules::BreakOutsideLoop), - (Pyflakes, "702") => (RuleGroup::Unspecified, rules::pyflakes::rules::ContinueOutsideLoop), - (Pyflakes, "704") => (RuleGroup::Unspecified, rules::pyflakes::rules::YieldOutsideFunction), - (Pyflakes, "706") => (RuleGroup::Unspecified, rules::pyflakes::rules::ReturnOutsideFunction), - (Pyflakes, "707") => (RuleGroup::Unspecified, rules::pyflakes::rules::DefaultExceptNotLast), - (Pyflakes, "722") => (RuleGroup::Unspecified, rules::pyflakes::rules::ForwardAnnotationSyntaxError), - (Pyflakes, "811") => (RuleGroup::Unspecified, rules::pyflakes::rules::RedefinedWhileUnused), - (Pyflakes, "821") => (RuleGroup::Unspecified, rules::pyflakes::rules::UndefinedName), - (Pyflakes, "822") => (RuleGroup::Unspecified, rules::pyflakes::rules::UndefinedExport), - (Pyflakes, "823") => (RuleGroup::Unspecified, rules::pyflakes::rules::UndefinedLocal), - (Pyflakes, "841") => (RuleGroup::Unspecified, rules::pyflakes::rules::UnusedVariable), - (Pyflakes, "842") => (RuleGroup::Unspecified, rules::pyflakes::rules::UnusedAnnotation), - (Pyflakes, "901") => (RuleGroup::Unspecified, rules::pyflakes::rules::RaiseNotImplemented), + (Pyflakes, "401") => (RuleGroup::Stable, rules::pyflakes::rules::UnusedImport), + (Pyflakes, "402") => (RuleGroup::Stable, rules::pyflakes::rules::ImportShadowedByLoopVar), + (Pyflakes, "403") => (RuleGroup::Stable, rules::pyflakes::rules::UndefinedLocalWithImportStar), + (Pyflakes, "404") => (RuleGroup::Stable, rules::pyflakes::rules::LateFutureImport), + (Pyflakes, "405") => (RuleGroup::Stable, rules::pyflakes::rules::UndefinedLocalWithImportStarUsage), + (Pyflakes, "406") => (RuleGroup::Stable, rules::pyflakes::rules::UndefinedLocalWithNestedImportStarUsage), + (Pyflakes, "407") => (RuleGroup::Stable, rules::pyflakes::rules::FutureFeatureNotDefined), + (Pyflakes, "501") => (RuleGroup::Stable, rules::pyflakes::rules::PercentFormatInvalidFormat), + (Pyflakes, "502") => (RuleGroup::Stable, rules::pyflakes::rules::PercentFormatExpectedMapping), + (Pyflakes, "503") => (RuleGroup::Stable, rules::pyflakes::rules::PercentFormatExpectedSequence), + (Pyflakes, "504") => (RuleGroup::Stable, rules::pyflakes::rules::PercentFormatExtraNamedArguments), + (Pyflakes, "505") => (RuleGroup::Stable, rules::pyflakes::rules::PercentFormatMissingArgument), + (Pyflakes, "506") => (RuleGroup::Stable, rules::pyflakes::rules::PercentFormatMixedPositionalAndNamed), + (Pyflakes, "507") => (RuleGroup::Stable, rules::pyflakes::rules::PercentFormatPositionalCountMismatch), + (Pyflakes, "508") => (RuleGroup::Stable, rules::pyflakes::rules::PercentFormatStarRequiresSequence), + (Pyflakes, "509") => (RuleGroup::Stable, rules::pyflakes::rules::PercentFormatUnsupportedFormatCharacter), + (Pyflakes, "521") => (RuleGroup::Stable, rules::pyflakes::rules::StringDotFormatInvalidFormat), + (Pyflakes, "522") => (RuleGroup::Stable, rules::pyflakes::rules::StringDotFormatExtraNamedArguments), + (Pyflakes, "523") => (RuleGroup::Stable, rules::pyflakes::rules::StringDotFormatExtraPositionalArguments), + (Pyflakes, "524") => (RuleGroup::Stable, rules::pyflakes::rules::StringDotFormatMissingArguments), + (Pyflakes, "525") => (RuleGroup::Stable, rules::pyflakes::rules::StringDotFormatMixingAutomatic), + (Pyflakes, "541") => (RuleGroup::Stable, rules::pyflakes::rules::FStringMissingPlaceholders), + (Pyflakes, "601") => (RuleGroup::Stable, rules::pyflakes::rules::MultiValueRepeatedKeyLiteral), + (Pyflakes, "602") => (RuleGroup::Stable, rules::pyflakes::rules::MultiValueRepeatedKeyVariable), + (Pyflakes, "621") => (RuleGroup::Stable, rules::pyflakes::rules::ExpressionsInStarAssignment), + (Pyflakes, "622") => (RuleGroup::Stable, rules::pyflakes::rules::MultipleStarredExpressions), + (Pyflakes, "631") => (RuleGroup::Stable, rules::pyflakes::rules::AssertTuple), + (Pyflakes, "632") => (RuleGroup::Stable, rules::pyflakes::rules::IsLiteral), + (Pyflakes, "633") => (RuleGroup::Stable, rules::pyflakes::rules::InvalidPrintSyntax), + (Pyflakes, "634") => (RuleGroup::Stable, rules::pyflakes::rules::IfTuple), + (Pyflakes, "701") => (RuleGroup::Stable, rules::pyflakes::rules::BreakOutsideLoop), + (Pyflakes, "702") => (RuleGroup::Stable, rules::pyflakes::rules::ContinueOutsideLoop), + (Pyflakes, "704") => (RuleGroup::Stable, rules::pyflakes::rules::YieldOutsideFunction), + (Pyflakes, "706") => (RuleGroup::Stable, rules::pyflakes::rules::ReturnOutsideFunction), + (Pyflakes, "707") => (RuleGroup::Stable, rules::pyflakes::rules::DefaultExceptNotLast), + (Pyflakes, "722") => (RuleGroup::Stable, rules::pyflakes::rules::ForwardAnnotationSyntaxError), + (Pyflakes, "811") => (RuleGroup::Stable, rules::pyflakes::rules::RedefinedWhileUnused), + (Pyflakes, "821") => (RuleGroup::Stable, rules::pyflakes::rules::UndefinedName), + (Pyflakes, "822") => (RuleGroup::Stable, rules::pyflakes::rules::UndefinedExport), + (Pyflakes, "823") => (RuleGroup::Stable, rules::pyflakes::rules::UndefinedLocal), + (Pyflakes, "841") => (RuleGroup::Stable, rules::pyflakes::rules::UnusedVariable), + (Pyflakes, "842") => (RuleGroup::Stable, rules::pyflakes::rules::UnusedAnnotation), + (Pyflakes, "901") => (RuleGroup::Stable, rules::pyflakes::rules::RaiseNotImplemented), // pylint - (Pylint, "C0105") => (RuleGroup::Unspecified, rules::pylint::rules::TypeNameIncorrectVariance), - (Pylint, "C0131") => (RuleGroup::Unspecified, rules::pylint::rules::TypeBivariance), - (Pylint, "C0132") => (RuleGroup::Unspecified, rules::pylint::rules::TypeParamNameMismatch), - (Pylint, "C0205") => (RuleGroup::Unspecified, rules::pylint::rules::SingleStringSlots), - (Pylint, "C0208") => (RuleGroup::Unspecified, rules::pylint::rules::IterationOverSet), - (Pylint, "C0414") => (RuleGroup::Unspecified, rules::pylint::rules::UselessImportAlias), + (Pylint, "C0105") => (RuleGroup::Stable, rules::pylint::rules::TypeNameIncorrectVariance), + (Pylint, "C0131") => (RuleGroup::Stable, rules::pylint::rules::TypeBivariance), + (Pylint, "C0132") => (RuleGroup::Stable, rules::pylint::rules::TypeParamNameMismatch), + (Pylint, "C0205") => (RuleGroup::Stable, rules::pylint::rules::SingleStringSlots), + (Pylint, "C0208") => (RuleGroup::Stable, rules::pylint::rules::IterationOverSet), + (Pylint, "C0414") => (RuleGroup::Stable, rules::pylint::rules::UselessImportAlias), + (Pylint, "C2401") => (RuleGroup::Preview, rules::pylint::rules::NonAsciiName), + (Pylint, "C2403") => (RuleGroup::Preview, rules::pylint::rules::NonAsciiImportName), #[allow(deprecated)] (Pylint, "C1901") => (RuleGroup::Nursery, rules::pylint::rules::CompareToEmptyString), - (Pylint, "C3002") => (RuleGroup::Unspecified, rules::pylint::rules::UnnecessaryDirectLambdaCall), - (Pylint, "E0100") => (RuleGroup::Unspecified, rules::pylint::rules::YieldInInit), - (Pylint, "E0101") => (RuleGroup::Unspecified, rules::pylint::rules::ReturnInInit), - (Pylint, "E0116") => (RuleGroup::Unspecified, rules::pylint::rules::ContinueInFinally), - (Pylint, "E0117") => (RuleGroup::Unspecified, rules::pylint::rules::NonlocalWithoutBinding), - (Pylint, "E0118") => (RuleGroup::Unspecified, rules::pylint::rules::LoadBeforeGlobalDeclaration), - (Pylint, "E0241") => (RuleGroup::Unspecified, rules::pylint::rules::DuplicateBases), - (Pylint, "E0302") => (RuleGroup::Unspecified, rules::pylint::rules::UnexpectedSpecialMethodSignature), - (Pylint, "E0307") => (RuleGroup::Unspecified, rules::pylint::rules::InvalidStrReturnType), - (Pylint, "E0604") => (RuleGroup::Unspecified, rules::pylint::rules::InvalidAllObject), - (Pylint, "E0605") => (RuleGroup::Unspecified, rules::pylint::rules::InvalidAllFormat), - (Pylint, "E1142") => (RuleGroup::Unspecified, rules::pylint::rules::AwaitOutsideAsync), - (Pylint, "E1205") => (RuleGroup::Unspecified, rules::pylint::rules::LoggingTooManyArgs), - (Pylint, "E1206") => (RuleGroup::Unspecified, rules::pylint::rules::LoggingTooFewArgs), - (Pylint, "E1300") => (RuleGroup::Unspecified, rules::pylint::rules::BadStringFormatCharacter), - (Pylint, "E1307") => (RuleGroup::Unspecified, rules::pylint::rules::BadStringFormatType), - (Pylint, "E1310") => (RuleGroup::Unspecified, rules::pylint::rules::BadStrStripCall), - (Pylint, "E1507") => (RuleGroup::Unspecified, rules::pylint::rules::InvalidEnvvarValue), - (Pylint, "E1700") => (RuleGroup::Unspecified, rules::pylint::rules::YieldFromInAsyncFunction), - (Pylint, "E2502") => (RuleGroup::Unspecified, rules::pylint::rules::BidirectionalUnicode), - (Pylint, "E2510") => (RuleGroup::Unspecified, rules::pylint::rules::InvalidCharacterBackspace), - (Pylint, "E2512") => (RuleGroup::Unspecified, rules::pylint::rules::InvalidCharacterSub), - (Pylint, "E2513") => (RuleGroup::Unspecified, rules::pylint::rules::InvalidCharacterEsc), - (Pylint, "E2514") => (RuleGroup::Unspecified, rules::pylint::rules::InvalidCharacterNul), - (Pylint, "E2515") => (RuleGroup::Unspecified, rules::pylint::rules::InvalidCharacterZeroWidthSpace), - (Pylint, "R0124") => (RuleGroup::Unspecified, rules::pylint::rules::ComparisonWithItself), - (Pylint, "R0133") => (RuleGroup::Unspecified, rules::pylint::rules::ComparisonOfConstant), - (Pylint, "R0206") => (RuleGroup::Unspecified, rules::pylint::rules::PropertyWithParameters), - (Pylint, "R0402") => (RuleGroup::Unspecified, rules::pylint::rules::ManualFromImport), - (Pylint, "R0911") => (RuleGroup::Unspecified, rules::pylint::rules::TooManyReturnStatements), - (Pylint, "R0912") => (RuleGroup::Unspecified, rules::pylint::rules::TooManyBranches), - (Pylint, "R0913") => (RuleGroup::Unspecified, rules::pylint::rules::TooManyArguments), - (Pylint, "R0915") => (RuleGroup::Unspecified, rules::pylint::rules::TooManyStatements), - (Pylint, "R1701") => (RuleGroup::Unspecified, rules::pylint::rules::RepeatedIsinstanceCalls), - (Pylint, "R1711") => (RuleGroup::Unspecified, rules::pylint::rules::UselessReturn), - (Pylint, "R1714") => (RuleGroup::Unspecified, rules::pylint::rules::RepeatedEqualityComparison), - (Pylint, "R1722") => (RuleGroup::Unspecified, rules::pylint::rules::SysExitAlias), - (Pylint, "R2004") => (RuleGroup::Unspecified, rules::pylint::rules::MagicValueComparison), - (Pylint, "R5501") => (RuleGroup::Unspecified, rules::pylint::rules::CollapsibleElseIf), + (Pylint, "C3002") => (RuleGroup::Stable, rules::pylint::rules::UnnecessaryDirectLambdaCall), + (Pylint, "E0100") => (RuleGroup::Stable, rules::pylint::rules::YieldInInit), + (Pylint, "E0101") => (RuleGroup::Stable, rules::pylint::rules::ReturnInInit), + (Pylint, "E0116") => (RuleGroup::Stable, rules::pylint::rules::ContinueInFinally), + (Pylint, "E0117") => (RuleGroup::Stable, rules::pylint::rules::NonlocalWithoutBinding), + (Pylint, "E0118") => (RuleGroup::Stable, rules::pylint::rules::LoadBeforeGlobalDeclaration), + (Pylint, "E0241") => (RuleGroup::Stable, rules::pylint::rules::DuplicateBases), + (Pylint, "E0302") => (RuleGroup::Stable, rules::pylint::rules::UnexpectedSpecialMethodSignature), + (Pylint, "E0307") => (RuleGroup::Stable, rules::pylint::rules::InvalidStrReturnType), + (Pylint, "E0604") => (RuleGroup::Stable, rules::pylint::rules::InvalidAllObject), + (Pylint, "E0605") => (RuleGroup::Stable, rules::pylint::rules::InvalidAllFormat), + (Pylint, "E0704") => (RuleGroup::Preview, rules::pylint::rules::MisplacedBareRaise), + (Pylint, "E1142") => (RuleGroup::Stable, rules::pylint::rules::AwaitOutsideAsync), + (Pylint, "E1205") => (RuleGroup::Stable, rules::pylint::rules::LoggingTooManyArgs), + (Pylint, "E1206") => (RuleGroup::Stable, rules::pylint::rules::LoggingTooFewArgs), + (Pylint, "E1300") => (RuleGroup::Stable, rules::pylint::rules::BadStringFormatCharacter), + (Pylint, "E1307") => (RuleGroup::Stable, rules::pylint::rules::BadStringFormatType), + (Pylint, "E1310") => (RuleGroup::Stable, rules::pylint::rules::BadStrStripCall), + (Pylint, "E1507") => (RuleGroup::Stable, rules::pylint::rules::InvalidEnvvarValue), + (Pylint, "E1700") => (RuleGroup::Stable, rules::pylint::rules::YieldFromInAsyncFunction), + (Pylint, "E2502") => (RuleGroup::Stable, rules::pylint::rules::BidirectionalUnicode), + (Pylint, "E2510") => (RuleGroup::Stable, rules::pylint::rules::InvalidCharacterBackspace), + (Pylint, "E2512") => (RuleGroup::Stable, rules::pylint::rules::InvalidCharacterSub), + (Pylint, "E2513") => (RuleGroup::Stable, rules::pylint::rules::InvalidCharacterEsc), + (Pylint, "E2514") => (RuleGroup::Stable, rules::pylint::rules::InvalidCharacterNul), + (Pylint, "E2515") => (RuleGroup::Stable, rules::pylint::rules::InvalidCharacterZeroWidthSpace), + (Pylint, "R0124") => (RuleGroup::Stable, rules::pylint::rules::ComparisonWithItself), + (Pylint, "R0133") => (RuleGroup::Stable, rules::pylint::rules::ComparisonOfConstant), + (Pylint, "R0206") => (RuleGroup::Stable, rules::pylint::rules::PropertyWithParameters), + (Pylint, "R0402") => (RuleGroup::Stable, rules::pylint::rules::ManualFromImport), + (Pylint, "R0911") => (RuleGroup::Stable, rules::pylint::rules::TooManyReturnStatements), + (Pylint, "R0912") => (RuleGroup::Stable, rules::pylint::rules::TooManyBranches), + (Pylint, "R0913") => (RuleGroup::Stable, rules::pylint::rules::TooManyArguments), + (Pylint, "R0915") => (RuleGroup::Stable, rules::pylint::rules::TooManyStatements), + (Pylint, "R0916") => (RuleGroup::Preview, rules::pylint::rules::TooManyBooleanExpressions), + (Pylint, "R1701") => (RuleGroup::Stable, rules::pylint::rules::RepeatedIsinstanceCalls), + (Pylint, "R1711") => (RuleGroup::Stable, rules::pylint::rules::UselessReturn), + (Pylint, "R1714") => (RuleGroup::Stable, rules::pylint::rules::RepeatedEqualityComparison), + (Pylint, "R1706") => (RuleGroup::Preview, rules::pylint::rules::AndOrTernary), + (Pylint, "R1722") => (RuleGroup::Stable, rules::pylint::rules::SysExitAlias), + (Pylint, "R2004") => (RuleGroup::Stable, rules::pylint::rules::MagicValueComparison), + (Pylint, "R5501") => (RuleGroup::Stable, rules::pylint::rules::CollapsibleElseIf), + (Pylint, "R6201") => (RuleGroup::Preview, rules::pylint::rules::LiteralMembership), #[allow(deprecated)] (Pylint, "R6301") => (RuleGroup::Nursery, rules::pylint::rules::NoSelfUse), - (Pylint, "W0120") => (RuleGroup::Unspecified, rules::pylint::rules::UselessElseOnLoop), - (Pylint, "W0127") => (RuleGroup::Unspecified, rules::pylint::rules::SelfAssigningVariable), - (Pylint, "W0129") => (RuleGroup::Unspecified, rules::pylint::rules::AssertOnStringLiteral), - (Pylint, "W0131") => (RuleGroup::Unspecified, rules::pylint::rules::NamedExprWithoutContext), - (Pylint, "W0406") => (RuleGroup::Unspecified, rules::pylint::rules::ImportSelf), - (Pylint, "W0602") => (RuleGroup::Unspecified, rules::pylint::rules::GlobalVariableNotAssigned), - (Pylint, "W0603") => (RuleGroup::Unspecified, rules::pylint::rules::GlobalStatement), - (Pylint, "W0711") => (RuleGroup::Unspecified, rules::pylint::rules::BinaryOpException), - (Pylint, "W1508") => (RuleGroup::Unspecified, rules::pylint::rules::InvalidEnvvarDefault), - (Pylint, "W1509") => (RuleGroup::Unspecified, rules::pylint::rules::SubprocessPopenPreexecFn), - (Pylint, "W1510") => (RuleGroup::Unspecified, rules::pylint::rules::SubprocessRunWithoutCheck), + (Pylint, "W0108") => (RuleGroup::Preview, rules::pylint::rules::UnnecessaryLambda), + (Pylint, "W0120") => (RuleGroup::Stable, rules::pylint::rules::UselessElseOnLoop), + (Pylint, "W0127") => (RuleGroup::Stable, rules::pylint::rules::SelfAssigningVariable), + (Pylint, "W0129") => (RuleGroup::Stable, rules::pylint::rules::AssertOnStringLiteral), + (Pylint, "W0131") => (RuleGroup::Stable, rules::pylint::rules::NamedExprWithoutContext), + (Pylint, "W0406") => (RuleGroup::Stable, rules::pylint::rules::ImportSelf), + (Pylint, "W0602") => (RuleGroup::Stable, rules::pylint::rules::GlobalVariableNotAssigned), + (Pylint, "W0604") => (RuleGroup::Preview, rules::pylint::rules::GlobalAtModuleLevel), + (Pylint, "W0603") => (RuleGroup::Stable, rules::pylint::rules::GlobalStatement), + (Pylint, "W0711") => (RuleGroup::Stable, rules::pylint::rules::BinaryOpException), + (Pylint, "W1508") => (RuleGroup::Stable, rules::pylint::rules::InvalidEnvvarDefault), + (Pylint, "W1509") => (RuleGroup::Stable, rules::pylint::rules::SubprocessPopenPreexecFn), + (Pylint, "W1510") => (RuleGroup::Stable, rules::pylint::rules::SubprocessRunWithoutCheck), + (Pylint, "W1514") => (RuleGroup::Preview, rules::pylint::rules::UnspecifiedEncoding), #[allow(deprecated)] (Pylint, "W1641") => (RuleGroup::Nursery, rules::pylint::rules::EqWithoutHash), (Pylint, "R0904") => (RuleGroup::Preview, rules::pylint::rules::TooManyPublicMethods), - (Pylint, "W2901") => (RuleGroup::Unspecified, rules::pylint::rules::RedefinedLoopName), + (Pylint, "W2901") => (RuleGroup::Stable, rules::pylint::rules::RedefinedLoopName), #[allow(deprecated)] (Pylint, "W3201") => (RuleGroup::Nursery, rules::pylint::rules::BadDunderMethodName), - (Pylint, "W3301") => (RuleGroup::Unspecified, rules::pylint::rules::NestedMinMax), + (Pylint, "W3301") => (RuleGroup::Stable, rules::pylint::rules::NestedMinMax), // flake8-async - (Flake8Async, "100") => (RuleGroup::Unspecified, rules::flake8_async::rules::BlockingHttpCallInAsyncFunction), - (Flake8Async, "101") => (RuleGroup::Unspecified, rules::flake8_async::rules::OpenSleepOrSubprocessInAsyncFunction), - (Flake8Async, "102") => (RuleGroup::Unspecified, rules::flake8_async::rules::BlockingOsCallInAsyncFunction), + (Flake8Async, "100") => (RuleGroup::Stable, rules::flake8_async::rules::BlockingHttpCallInAsyncFunction), + (Flake8Async, "101") => (RuleGroup::Stable, rules::flake8_async::rules::OpenSleepOrSubprocessInAsyncFunction), + (Flake8Async, "102") => (RuleGroup::Stable, rules::flake8_async::rules::BlockingOsCallInAsyncFunction), // flake8-builtins - (Flake8Builtins, "001") => (RuleGroup::Unspecified, rules::flake8_builtins::rules::BuiltinVariableShadowing), - (Flake8Builtins, "002") => (RuleGroup::Unspecified, rules::flake8_builtins::rules::BuiltinArgumentShadowing), - (Flake8Builtins, "003") => (RuleGroup::Unspecified, rules::flake8_builtins::rules::BuiltinAttributeShadowing), + (Flake8Builtins, "001") => (RuleGroup::Stable, rules::flake8_builtins::rules::BuiltinVariableShadowing), + (Flake8Builtins, "002") => (RuleGroup::Stable, rules::flake8_builtins::rules::BuiltinArgumentShadowing), + (Flake8Builtins, "003") => (RuleGroup::Stable, rules::flake8_builtins::rules::BuiltinAttributeShadowing), // flake8-bugbear - (Flake8Bugbear, "002") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::UnaryPrefixIncrementDecrement), - (Flake8Bugbear, "003") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::AssignmentToOsEnviron), - (Flake8Bugbear, "004") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::UnreliableCallableCheck), - (Flake8Bugbear, "005") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::StripWithMultiCharacters), - (Flake8Bugbear, "006") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::MutableArgumentDefault), - (Flake8Bugbear, "007") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::UnusedLoopControlVariable), - (Flake8Bugbear, "008") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::FunctionCallInDefaultArgument), - (Flake8Bugbear, "009") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::GetAttrWithConstant), - (Flake8Bugbear, "010") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::SetAttrWithConstant), - (Flake8Bugbear, "011") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::AssertFalse), - (Flake8Bugbear, "012") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::JumpStatementInFinally), - (Flake8Bugbear, "013") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::RedundantTupleInExceptionHandler), - (Flake8Bugbear, "014") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::DuplicateHandlerException), - (Flake8Bugbear, "015") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::UselessComparison), - (Flake8Bugbear, "016") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::RaiseLiteral), - (Flake8Bugbear, "017") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::AssertRaisesException), - (Flake8Bugbear, "018") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::UselessExpression), - (Flake8Bugbear, "019") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::CachedInstanceMethod), - (Flake8Bugbear, "020") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::LoopVariableOverridesIterator), - (Flake8Bugbear, "021") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::FStringDocstring), - (Flake8Bugbear, "022") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::UselessContextlibSuppress), - (Flake8Bugbear, "023") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::FunctionUsesLoopVariable), - (Flake8Bugbear, "024") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::AbstractBaseClassWithoutAbstractMethod), - (Flake8Bugbear, "025") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::DuplicateTryBlockException), - (Flake8Bugbear, "026") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::StarArgUnpackingAfterKeywordArg), - (Flake8Bugbear, "027") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::EmptyMethodWithoutAbstractDecorator), - (Flake8Bugbear, "028") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::NoExplicitStacklevel), - (Flake8Bugbear, "029") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::ExceptWithEmptyTuple), - (Flake8Bugbear, "030") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::ExceptWithNonExceptionClasses), - (Flake8Bugbear, "031") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::ReuseOfGroupbyGenerator), - (Flake8Bugbear, "032") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::UnintentionalTypeAnnotation), - (Flake8Bugbear, "033") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::DuplicateValue), - (Flake8Bugbear, "034") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::ReSubPositionalArgs), - (Flake8Bugbear, "904") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::RaiseWithoutFromInsideExcept), - (Flake8Bugbear, "905") => (RuleGroup::Unspecified, rules::flake8_bugbear::rules::ZipWithoutExplicitStrict), + (Flake8Bugbear, "002") => (RuleGroup::Stable, rules::flake8_bugbear::rules::UnaryPrefixIncrementDecrement), + (Flake8Bugbear, "003") => (RuleGroup::Stable, rules::flake8_bugbear::rules::AssignmentToOsEnviron), + (Flake8Bugbear, "004") => (RuleGroup::Stable, rules::flake8_bugbear::rules::UnreliableCallableCheck), + (Flake8Bugbear, "005") => (RuleGroup::Stable, rules::flake8_bugbear::rules::StripWithMultiCharacters), + (Flake8Bugbear, "006") => (RuleGroup::Stable, rules::flake8_bugbear::rules::MutableArgumentDefault), + (Flake8Bugbear, "007") => (RuleGroup::Stable, rules::flake8_bugbear::rules::UnusedLoopControlVariable), + (Flake8Bugbear, "008") => (RuleGroup::Stable, rules::flake8_bugbear::rules::FunctionCallInDefaultArgument), + (Flake8Bugbear, "009") => (RuleGroup::Stable, rules::flake8_bugbear::rules::GetAttrWithConstant), + (Flake8Bugbear, "010") => (RuleGroup::Stable, rules::flake8_bugbear::rules::SetAttrWithConstant), + (Flake8Bugbear, "011") => (RuleGroup::Stable, rules::flake8_bugbear::rules::AssertFalse), + (Flake8Bugbear, "012") => (RuleGroup::Stable, rules::flake8_bugbear::rules::JumpStatementInFinally), + (Flake8Bugbear, "013") => (RuleGroup::Stable, rules::flake8_bugbear::rules::RedundantTupleInExceptionHandler), + (Flake8Bugbear, "014") => (RuleGroup::Stable, rules::flake8_bugbear::rules::DuplicateHandlerException), + (Flake8Bugbear, "015") => (RuleGroup::Stable, rules::flake8_bugbear::rules::UselessComparison), + (Flake8Bugbear, "016") => (RuleGroup::Stable, rules::flake8_bugbear::rules::RaiseLiteral), + (Flake8Bugbear, "017") => (RuleGroup::Stable, rules::flake8_bugbear::rules::AssertRaisesException), + (Flake8Bugbear, "018") => (RuleGroup::Stable, rules::flake8_bugbear::rules::UselessExpression), + (Flake8Bugbear, "019") => (RuleGroup::Stable, rules::flake8_bugbear::rules::CachedInstanceMethod), + (Flake8Bugbear, "020") => (RuleGroup::Stable, rules::flake8_bugbear::rules::LoopVariableOverridesIterator), + (Flake8Bugbear, "021") => (RuleGroup::Stable, rules::flake8_bugbear::rules::FStringDocstring), + (Flake8Bugbear, "022") => (RuleGroup::Stable, rules::flake8_bugbear::rules::UselessContextlibSuppress), + (Flake8Bugbear, "023") => (RuleGroup::Stable, rules::flake8_bugbear::rules::FunctionUsesLoopVariable), + (Flake8Bugbear, "024") => (RuleGroup::Stable, rules::flake8_bugbear::rules::AbstractBaseClassWithoutAbstractMethod), + (Flake8Bugbear, "025") => (RuleGroup::Stable, rules::flake8_bugbear::rules::DuplicateTryBlockException), + (Flake8Bugbear, "026") => (RuleGroup::Stable, rules::flake8_bugbear::rules::StarArgUnpackingAfterKeywordArg), + (Flake8Bugbear, "027") => (RuleGroup::Stable, rules::flake8_bugbear::rules::EmptyMethodWithoutAbstractDecorator), + (Flake8Bugbear, "028") => (RuleGroup::Stable, rules::flake8_bugbear::rules::NoExplicitStacklevel), + (Flake8Bugbear, "029") => (RuleGroup::Stable, rules::flake8_bugbear::rules::ExceptWithEmptyTuple), + (Flake8Bugbear, "030") => (RuleGroup::Stable, rules::flake8_bugbear::rules::ExceptWithNonExceptionClasses), + (Flake8Bugbear, "031") => (RuleGroup::Stable, rules::flake8_bugbear::rules::ReuseOfGroupbyGenerator), + (Flake8Bugbear, "032") => (RuleGroup::Stable, rules::flake8_bugbear::rules::UnintentionalTypeAnnotation), + (Flake8Bugbear, "033") => (RuleGroup::Stable, rules::flake8_bugbear::rules::DuplicateValue), + (Flake8Bugbear, "034") => (RuleGroup::Stable, rules::flake8_bugbear::rules::ReSubPositionalArgs), + (Flake8Bugbear, "904") => (RuleGroup::Stable, rules::flake8_bugbear::rules::RaiseWithoutFromInsideExcept), + (Flake8Bugbear, "905") => (RuleGroup::Stable, rules::flake8_bugbear::rules::ZipWithoutExplicitStrict), // flake8-blind-except - (Flake8BlindExcept, "001") => (RuleGroup::Unspecified, rules::flake8_blind_except::rules::BlindExcept), + (Flake8BlindExcept, "001") => (RuleGroup::Stable, rules::flake8_blind_except::rules::BlindExcept), // flake8-comprehensions - (Flake8Comprehensions, "00") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessaryGeneratorList), - (Flake8Comprehensions, "01") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessaryGeneratorSet), - (Flake8Comprehensions, "02") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessaryGeneratorDict), - (Flake8Comprehensions, "03") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessaryListComprehensionSet), - (Flake8Comprehensions, "04") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessaryListComprehensionDict), - (Flake8Comprehensions, "05") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessaryLiteralSet), - (Flake8Comprehensions, "06") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessaryLiteralDict), - (Flake8Comprehensions, "08") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessaryCollectionCall), - (Flake8Comprehensions, "09") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessaryLiteralWithinTupleCall), - (Flake8Comprehensions, "10") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessaryLiteralWithinListCall), - (Flake8Comprehensions, "11") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessaryListCall), - (Flake8Comprehensions, "13") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessaryCallAroundSorted), - (Flake8Comprehensions, "14") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessaryDoubleCastOrProcess), - (Flake8Comprehensions, "15") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessarySubscriptReversal), - (Flake8Comprehensions, "16") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessaryComprehension), - (Flake8Comprehensions, "17") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessaryMap), - (Flake8Comprehensions, "18") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessaryLiteralWithinDictCall), - (Flake8Comprehensions, "19") => (RuleGroup::Unspecified, rules::flake8_comprehensions::rules::UnnecessaryComprehensionAnyAll), + (Flake8Comprehensions, "00") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryGeneratorList), + (Flake8Comprehensions, "01") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryGeneratorSet), + (Flake8Comprehensions, "02") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryGeneratorDict), + (Flake8Comprehensions, "03") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryListComprehensionSet), + (Flake8Comprehensions, "04") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryListComprehensionDict), + (Flake8Comprehensions, "05") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryLiteralSet), + (Flake8Comprehensions, "06") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryLiteralDict), + (Flake8Comprehensions, "08") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryCollectionCall), + (Flake8Comprehensions, "09") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryLiteralWithinTupleCall), + (Flake8Comprehensions, "10") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryLiteralWithinListCall), + (Flake8Comprehensions, "11") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryListCall), + (Flake8Comprehensions, "13") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryCallAroundSorted), + (Flake8Comprehensions, "14") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryDoubleCastOrProcess), + (Flake8Comprehensions, "15") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessarySubscriptReversal), + (Flake8Comprehensions, "16") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryComprehension), + (Flake8Comprehensions, "17") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryMap), + (Flake8Comprehensions, "18") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryLiteralWithinDictCall), + (Flake8Comprehensions, "19") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryComprehensionAnyAll), // flake8-debugger - (Flake8Debugger, "0") => (RuleGroup::Unspecified, rules::flake8_debugger::rules::Debugger), + (Flake8Debugger, "0") => (RuleGroup::Stable, rules::flake8_debugger::rules::Debugger), // mccabe - (McCabe, "1") => (RuleGroup::Unspecified, rules::mccabe::rules::ComplexStructure), + (McCabe, "1") => (RuleGroup::Stable, rules::mccabe::rules::ComplexStructure), // flake8-tidy-imports - (Flake8TidyImports, "251") => (RuleGroup::Unspecified, rules::flake8_tidy_imports::rules::BannedApi), - (Flake8TidyImports, "252") => (RuleGroup::Unspecified, rules::flake8_tidy_imports::rules::RelativeImports), - (Flake8TidyImports, "253") => (RuleGroup::Unspecified, rules::flake8_tidy_imports::rules::BannedModuleLevelImports), + (Flake8TidyImports, "251") => (RuleGroup::Stable, rules::flake8_tidy_imports::rules::BannedApi), + (Flake8TidyImports, "252") => (RuleGroup::Stable, rules::flake8_tidy_imports::rules::RelativeImports), + (Flake8TidyImports, "253") => (RuleGroup::Stable, rules::flake8_tidy_imports::rules::BannedModuleLevelImports), // flake8-return - (Flake8Return, "501") => (RuleGroup::Unspecified, rules::flake8_return::rules::UnnecessaryReturnNone), - (Flake8Return, "502") => (RuleGroup::Unspecified, rules::flake8_return::rules::ImplicitReturnValue), - (Flake8Return, "503") => (RuleGroup::Unspecified, rules::flake8_return::rules::ImplicitReturn), - (Flake8Return, "504") => (RuleGroup::Unspecified, rules::flake8_return::rules::UnnecessaryAssign), - (Flake8Return, "505") => (RuleGroup::Unspecified, rules::flake8_return::rules::SuperfluousElseReturn), - (Flake8Return, "506") => (RuleGroup::Unspecified, rules::flake8_return::rules::SuperfluousElseRaise), - (Flake8Return, "507") => (RuleGroup::Unspecified, rules::flake8_return::rules::SuperfluousElseContinue), - (Flake8Return, "508") => (RuleGroup::Unspecified, rules::flake8_return::rules::SuperfluousElseBreak), + (Flake8Return, "501") => (RuleGroup::Stable, rules::flake8_return::rules::UnnecessaryReturnNone), + (Flake8Return, "502") => (RuleGroup::Stable, rules::flake8_return::rules::ImplicitReturnValue), + (Flake8Return, "503") => (RuleGroup::Stable, rules::flake8_return::rules::ImplicitReturn), + (Flake8Return, "504") => (RuleGroup::Stable, rules::flake8_return::rules::UnnecessaryAssign), + (Flake8Return, "505") => (RuleGroup::Stable, rules::flake8_return::rules::SuperfluousElseReturn), + (Flake8Return, "506") => (RuleGroup::Stable, rules::flake8_return::rules::SuperfluousElseRaise), + (Flake8Return, "507") => (RuleGroup::Stable, rules::flake8_return::rules::SuperfluousElseContinue), + (Flake8Return, "508") => (RuleGroup::Stable, rules::flake8_return::rules::SuperfluousElseBreak), // flake8-gettext - (Flake8GetText, "001") => (RuleGroup::Unspecified, rules::flake8_gettext::rules::FStringInGetTextFuncCall), - (Flake8GetText, "002") => (RuleGroup::Unspecified, rules::flake8_gettext::rules::FormatInGetTextFuncCall), - (Flake8GetText, "003") => (RuleGroup::Unspecified, rules::flake8_gettext::rules::PrintfInGetTextFuncCall), + (Flake8GetText, "001") => (RuleGroup::Stable, rules::flake8_gettext::rules::FStringInGetTextFuncCall), + (Flake8GetText, "002") => (RuleGroup::Stable, rules::flake8_gettext::rules::FormatInGetTextFuncCall), + (Flake8GetText, "003") => (RuleGroup::Stable, rules::flake8_gettext::rules::PrintfInGetTextFuncCall), // flake8-implicit-str-concat - (Flake8ImplicitStrConcat, "001") => (RuleGroup::Unspecified, rules::flake8_implicit_str_concat::rules::SingleLineImplicitStringConcatenation), - (Flake8ImplicitStrConcat, "002") => (RuleGroup::Unspecified, rules::flake8_implicit_str_concat::rules::MultiLineImplicitStringConcatenation), - (Flake8ImplicitStrConcat, "003") => (RuleGroup::Unspecified, rules::flake8_implicit_str_concat::rules::ExplicitStringConcatenation), + (Flake8ImplicitStrConcat, "001") => (RuleGroup::Stable, rules::flake8_implicit_str_concat::rules::SingleLineImplicitStringConcatenation), + (Flake8ImplicitStrConcat, "002") => (RuleGroup::Stable, rules::flake8_implicit_str_concat::rules::MultiLineImplicitStringConcatenation), + (Flake8ImplicitStrConcat, "003") => (RuleGroup::Stable, rules::flake8_implicit_str_concat::rules::ExplicitStringConcatenation), // flake8-print - (Flake8Print, "1") => (RuleGroup::Unspecified, rules::flake8_print::rules::Print), - (Flake8Print, "3") => (RuleGroup::Unspecified, rules::flake8_print::rules::PPrint), + (Flake8Print, "1") => (RuleGroup::Stable, rules::flake8_print::rules::Print), + (Flake8Print, "3") => (RuleGroup::Stable, rules::flake8_print::rules::PPrint), // flake8-quotes - (Flake8Quotes, "000") => (RuleGroup::Unspecified, rules::flake8_quotes::rules::BadQuotesInlineString), - (Flake8Quotes, "001") => (RuleGroup::Unspecified, rules::flake8_quotes::rules::BadQuotesMultilineString), - (Flake8Quotes, "002") => (RuleGroup::Unspecified, rules::flake8_quotes::rules::BadQuotesDocstring), - (Flake8Quotes, "003") => (RuleGroup::Unspecified, rules::flake8_quotes::rules::AvoidableEscapedQuote), + (Flake8Quotes, "000") => (RuleGroup::Stable, rules::flake8_quotes::rules::BadQuotesInlineString), + (Flake8Quotes, "001") => (RuleGroup::Stable, rules::flake8_quotes::rules::BadQuotesMultilineString), + (Flake8Quotes, "002") => (RuleGroup::Stable, rules::flake8_quotes::rules::BadQuotesDocstring), + (Flake8Quotes, "003") => (RuleGroup::Stable, rules::flake8_quotes::rules::AvoidableEscapedQuote), // flake8-annotations - (Flake8Annotations, "001") => (RuleGroup::Unspecified, rules::flake8_annotations::rules::MissingTypeFunctionArgument), - (Flake8Annotations, "002") => (RuleGroup::Unspecified, rules::flake8_annotations::rules::MissingTypeArgs), - (Flake8Annotations, "003") => (RuleGroup::Unspecified, rules::flake8_annotations::rules::MissingTypeKwargs), - (Flake8Annotations, "101") => (RuleGroup::Unspecified, rules::flake8_annotations::rules::MissingTypeSelf), - (Flake8Annotations, "102") => (RuleGroup::Unspecified, rules::flake8_annotations::rules::MissingTypeCls), - (Flake8Annotations, "201") => (RuleGroup::Unspecified, rules::flake8_annotations::rules::MissingReturnTypeUndocumentedPublicFunction), - (Flake8Annotations, "202") => (RuleGroup::Unspecified, rules::flake8_annotations::rules::MissingReturnTypePrivateFunction), - (Flake8Annotations, "204") => (RuleGroup::Unspecified, rules::flake8_annotations::rules::MissingReturnTypeSpecialMethod), - (Flake8Annotations, "205") => (RuleGroup::Unspecified, rules::flake8_annotations::rules::MissingReturnTypeStaticMethod), - (Flake8Annotations, "206") => (RuleGroup::Unspecified, rules::flake8_annotations::rules::MissingReturnTypeClassMethod), - (Flake8Annotations, "401") => (RuleGroup::Unspecified, rules::flake8_annotations::rules::AnyType), + (Flake8Annotations, "001") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingTypeFunctionArgument), + (Flake8Annotations, "002") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingTypeArgs), + (Flake8Annotations, "003") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingTypeKwargs), + (Flake8Annotations, "101") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingTypeSelf), + (Flake8Annotations, "102") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingTypeCls), + (Flake8Annotations, "201") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingReturnTypeUndocumentedPublicFunction), + (Flake8Annotations, "202") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingReturnTypePrivateFunction), + (Flake8Annotations, "204") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingReturnTypeSpecialMethod), + (Flake8Annotations, "205") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingReturnTypeStaticMethod), + (Flake8Annotations, "206") => (RuleGroup::Stable, rules::flake8_annotations::rules::MissingReturnTypeClassMethod), + (Flake8Annotations, "401") => (RuleGroup::Stable, rules::flake8_annotations::rules::AnyType), // flake8-future-annotations - (Flake8FutureAnnotations, "100") => (RuleGroup::Unspecified, rules::flake8_future_annotations::rules::FutureRewritableTypeAnnotation), - (Flake8FutureAnnotations, "102") => (RuleGroup::Unspecified, rules::flake8_future_annotations::rules::FutureRequiredTypeAnnotation), + (Flake8FutureAnnotations, "100") => (RuleGroup::Stable, rules::flake8_future_annotations::rules::FutureRewritableTypeAnnotation), + (Flake8FutureAnnotations, "102") => (RuleGroup::Stable, rules::flake8_future_annotations::rules::FutureRequiredTypeAnnotation), // flake8-2020 - (Flake82020, "101") => (RuleGroup::Unspecified, rules::flake8_2020::rules::SysVersionSlice3), - (Flake82020, "102") => (RuleGroup::Unspecified, rules::flake8_2020::rules::SysVersion2), - (Flake82020, "103") => (RuleGroup::Unspecified, rules::flake8_2020::rules::SysVersionCmpStr3), - (Flake82020, "201") => (RuleGroup::Unspecified, rules::flake8_2020::rules::SysVersionInfo0Eq3), - (Flake82020, "202") => (RuleGroup::Unspecified, rules::flake8_2020::rules::SixPY3), - (Flake82020, "203") => (RuleGroup::Unspecified, rules::flake8_2020::rules::SysVersionInfo1CmpInt), - (Flake82020, "204") => (RuleGroup::Unspecified, rules::flake8_2020::rules::SysVersionInfoMinorCmpInt), - (Flake82020, "301") => (RuleGroup::Unspecified, rules::flake8_2020::rules::SysVersion0), - (Flake82020, "302") => (RuleGroup::Unspecified, rules::flake8_2020::rules::SysVersionCmpStr10), - (Flake82020, "303") => (RuleGroup::Unspecified, rules::flake8_2020::rules::SysVersionSlice1), + (Flake82020, "101") => (RuleGroup::Stable, rules::flake8_2020::rules::SysVersionSlice3), + (Flake82020, "102") => (RuleGroup::Stable, rules::flake8_2020::rules::SysVersion2), + (Flake82020, "103") => (RuleGroup::Stable, rules::flake8_2020::rules::SysVersionCmpStr3), + (Flake82020, "201") => (RuleGroup::Stable, rules::flake8_2020::rules::SysVersionInfo0Eq3), + (Flake82020, "202") => (RuleGroup::Stable, rules::flake8_2020::rules::SixPY3), + (Flake82020, "203") => (RuleGroup::Stable, rules::flake8_2020::rules::SysVersionInfo1CmpInt), + (Flake82020, "204") => (RuleGroup::Stable, rules::flake8_2020::rules::SysVersionInfoMinorCmpInt), + (Flake82020, "301") => (RuleGroup::Stable, rules::flake8_2020::rules::SysVersion0), + (Flake82020, "302") => (RuleGroup::Stable, rules::flake8_2020::rules::SysVersionCmpStr10), + (Flake82020, "303") => (RuleGroup::Stable, rules::flake8_2020::rules::SysVersionSlice1), // flake8-simplify - (Flake8Simplify, "101") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::DuplicateIsinstanceCall), - (Flake8Simplify, "102") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::CollapsibleIf), - (Flake8Simplify, "103") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::NeedlessBool), - (Flake8Simplify, "105") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::SuppressibleException), - (Flake8Simplify, "107") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::ReturnInTryExceptFinally), - (Flake8Simplify, "108") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::IfElseBlockInsteadOfIfExp), - (Flake8Simplify, "109") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::CompareWithTuple), - (Flake8Simplify, "110") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::ReimplementedBuiltin), - (Flake8Simplify, "112") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::UncapitalizedEnvironmentVariables), - (Flake8Simplify, "114") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::IfWithSameArms), - (Flake8Simplify, "115") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::OpenFileWithContextHandler), - (Flake8Simplify, "116") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::IfElseBlockInsteadOfDictLookup), - (Flake8Simplify, "117") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::MultipleWithStatements), - (Flake8Simplify, "118") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::InDictKeys), - (Flake8Simplify, "201") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::NegateEqualOp), - (Flake8Simplify, "202") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::NegateNotEqualOp), - (Flake8Simplify, "208") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::DoubleNegation), - (Flake8Simplify, "210") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::IfExprWithTrueFalse), - (Flake8Simplify, "211") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::IfExprWithFalseTrue), - (Flake8Simplify, "212") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::IfExprWithTwistedArms), - (Flake8Simplify, "220") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::ExprAndNotExpr), - (Flake8Simplify, "221") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::ExprOrNotExpr), - (Flake8Simplify, "222") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::ExprOrTrue), - (Flake8Simplify, "223") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::ExprAndFalse), - (Flake8Simplify, "300") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::YodaConditions), - (Flake8Simplify, "401") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::IfElseBlockInsteadOfDictGet), - (Flake8Simplify, "910") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::DictGetWithNoneDefault), + (Flake8Simplify, "101") => (RuleGroup::Stable, rules::flake8_simplify::rules::DuplicateIsinstanceCall), + (Flake8Simplify, "102") => (RuleGroup::Stable, rules::flake8_simplify::rules::CollapsibleIf), + (Flake8Simplify, "103") => (RuleGroup::Stable, rules::flake8_simplify::rules::NeedlessBool), + (Flake8Simplify, "105") => (RuleGroup::Stable, rules::flake8_simplify::rules::SuppressibleException), + (Flake8Simplify, "107") => (RuleGroup::Stable, rules::flake8_simplify::rules::ReturnInTryExceptFinally), + (Flake8Simplify, "108") => (RuleGroup::Stable, rules::flake8_simplify::rules::IfElseBlockInsteadOfIfExp), + (Flake8Simplify, "109") => (RuleGroup::Stable, rules::flake8_simplify::rules::CompareWithTuple), + (Flake8Simplify, "110") => (RuleGroup::Stable, rules::flake8_simplify::rules::ReimplementedBuiltin), + (Flake8Simplify, "112") => (RuleGroup::Stable, rules::flake8_simplify::rules::UncapitalizedEnvironmentVariables), + (Flake8Simplify, "114") => (RuleGroup::Stable, rules::flake8_simplify::rules::IfWithSameArms), + (Flake8Simplify, "115") => (RuleGroup::Stable, rules::flake8_simplify::rules::OpenFileWithContextHandler), + (Flake8Simplify, "116") => (RuleGroup::Stable, rules::flake8_simplify::rules::IfElseBlockInsteadOfDictLookup), + (Flake8Simplify, "117") => (RuleGroup::Stable, rules::flake8_simplify::rules::MultipleWithStatements), + (Flake8Simplify, "118") => (RuleGroup::Stable, rules::flake8_simplify::rules::InDictKeys), + (Flake8Simplify, "201") => (RuleGroup::Stable, rules::flake8_simplify::rules::NegateEqualOp), + (Flake8Simplify, "202") => (RuleGroup::Stable, rules::flake8_simplify::rules::NegateNotEqualOp), + (Flake8Simplify, "208") => (RuleGroup::Stable, rules::flake8_simplify::rules::DoubleNegation), + (Flake8Simplify, "210") => (RuleGroup::Stable, rules::flake8_simplify::rules::IfExprWithTrueFalse), + (Flake8Simplify, "211") => (RuleGroup::Stable, rules::flake8_simplify::rules::IfExprWithFalseTrue), + (Flake8Simplify, "212") => (RuleGroup::Stable, rules::flake8_simplify::rules::IfExprWithTwistedArms), + (Flake8Simplify, "220") => (RuleGroup::Stable, rules::flake8_simplify::rules::ExprAndNotExpr), + (Flake8Simplify, "221") => (RuleGroup::Stable, rules::flake8_simplify::rules::ExprOrNotExpr), + (Flake8Simplify, "222") => (RuleGroup::Stable, rules::flake8_simplify::rules::ExprOrTrue), + (Flake8Simplify, "223") => (RuleGroup::Stable, rules::flake8_simplify::rules::ExprAndFalse), + (Flake8Simplify, "300") => (RuleGroup::Stable, rules::flake8_simplify::rules::YodaConditions), + (Flake8Simplify, "401") => (RuleGroup::Stable, rules::flake8_simplify::rules::IfElseBlockInsteadOfDictGet), + (Flake8Simplify, "910") => (RuleGroup::Stable, rules::flake8_simplify::rules::DictGetWithNoneDefault), // flake8-copyright #[allow(deprecated)] (Flake8Copyright, "001") => (RuleGroup::Nursery, rules::flake8_copyright::rules::MissingCopyrightNotice), // pyupgrade - (Pyupgrade, "001") => (RuleGroup::Unspecified, rules::pyupgrade::rules::UselessMetaclassType), - (Pyupgrade, "003") => (RuleGroup::Unspecified, rules::pyupgrade::rules::TypeOfPrimitive), - (Pyupgrade, "004") => (RuleGroup::Unspecified, rules::pyupgrade::rules::UselessObjectInheritance), - (Pyupgrade, "005") => (RuleGroup::Unspecified, rules::pyupgrade::rules::DeprecatedUnittestAlias), - (Pyupgrade, "006") => (RuleGroup::Unspecified, rules::pyupgrade::rules::NonPEP585Annotation), - (Pyupgrade, "007") => (RuleGroup::Unspecified, rules::pyupgrade::rules::NonPEP604Annotation), - (Pyupgrade, "008") => (RuleGroup::Unspecified, rules::pyupgrade::rules::SuperCallWithParameters), - (Pyupgrade, "009") => (RuleGroup::Unspecified, rules::pyupgrade::rules::UTF8EncodingDeclaration), - (Pyupgrade, "010") => (RuleGroup::Unspecified, rules::pyupgrade::rules::UnnecessaryFutureImport), - (Pyupgrade, "011") => (RuleGroup::Unspecified, rules::pyupgrade::rules::LRUCacheWithoutParameters), - (Pyupgrade, "012") => (RuleGroup::Unspecified, rules::pyupgrade::rules::UnnecessaryEncodeUTF8), - (Pyupgrade, "013") => (RuleGroup::Unspecified, rules::pyupgrade::rules::ConvertTypedDictFunctionalToClass), - (Pyupgrade, "014") => (RuleGroup::Unspecified, rules::pyupgrade::rules::ConvertNamedTupleFunctionalToClass), - (Pyupgrade, "015") => (RuleGroup::Unspecified, rules::pyupgrade::rules::RedundantOpenModes), - (Pyupgrade, "017") => (RuleGroup::Unspecified, rules::pyupgrade::rules::DatetimeTimezoneUTC), - (Pyupgrade, "018") => (RuleGroup::Unspecified, rules::pyupgrade::rules::NativeLiterals), - (Pyupgrade, "019") => (RuleGroup::Unspecified, rules::pyupgrade::rules::TypingTextStrAlias), - (Pyupgrade, "020") => (RuleGroup::Unspecified, rules::pyupgrade::rules::OpenAlias), - (Pyupgrade, "021") => (RuleGroup::Unspecified, rules::pyupgrade::rules::ReplaceUniversalNewlines), - (Pyupgrade, "022") => (RuleGroup::Unspecified, rules::pyupgrade::rules::ReplaceStdoutStderr), - (Pyupgrade, "023") => (RuleGroup::Unspecified, rules::pyupgrade::rules::DeprecatedCElementTree), - (Pyupgrade, "024") => (RuleGroup::Unspecified, rules::pyupgrade::rules::OSErrorAlias), - (Pyupgrade, "025") => (RuleGroup::Unspecified, rules::pyupgrade::rules::UnicodeKindPrefix), - (Pyupgrade, "026") => (RuleGroup::Unspecified, rules::pyupgrade::rules::DeprecatedMockImport), - (Pyupgrade, "027") => (RuleGroup::Unspecified, rules::pyupgrade::rules::UnpackedListComprehension), - (Pyupgrade, "028") => (RuleGroup::Unspecified, rules::pyupgrade::rules::YieldInForLoop), - (Pyupgrade, "029") => (RuleGroup::Unspecified, rules::pyupgrade::rules::UnnecessaryBuiltinImport), - (Pyupgrade, "030") => (RuleGroup::Unspecified, rules::pyupgrade::rules::FormatLiterals), - (Pyupgrade, "031") => (RuleGroup::Unspecified, rules::pyupgrade::rules::PrintfStringFormatting), - (Pyupgrade, "032") => (RuleGroup::Unspecified, rules::pyupgrade::rules::FString), - (Pyupgrade, "033") => (RuleGroup::Unspecified, rules::pyupgrade::rules::LRUCacheWithMaxsizeNone), - (Pyupgrade, "034") => (RuleGroup::Unspecified, rules::pyupgrade::rules::ExtraneousParentheses), - (Pyupgrade, "035") => (RuleGroup::Unspecified, rules::pyupgrade::rules::DeprecatedImport), - (Pyupgrade, "036") => (RuleGroup::Unspecified, rules::pyupgrade::rules::OutdatedVersionBlock), - (Pyupgrade, "037") => (RuleGroup::Unspecified, rules::pyupgrade::rules::QuotedAnnotation), - (Pyupgrade, "038") => (RuleGroup::Unspecified, rules::pyupgrade::rules::NonPEP604Isinstance), - (Pyupgrade, "039") => (RuleGroup::Unspecified, rules::pyupgrade::rules::UnnecessaryClassParentheses), - (Pyupgrade, "040") => (RuleGroup::Unspecified, rules::pyupgrade::rules::NonPEP695TypeAlias), + (Pyupgrade, "001") => (RuleGroup::Stable, rules::pyupgrade::rules::UselessMetaclassType), + (Pyupgrade, "003") => (RuleGroup::Stable, rules::pyupgrade::rules::TypeOfPrimitive), + (Pyupgrade, "004") => (RuleGroup::Stable, rules::pyupgrade::rules::UselessObjectInheritance), + (Pyupgrade, "005") => (RuleGroup::Stable, rules::pyupgrade::rules::DeprecatedUnittestAlias), + (Pyupgrade, "006") => (RuleGroup::Stable, rules::pyupgrade::rules::NonPEP585Annotation), + (Pyupgrade, "007") => (RuleGroup::Stable, rules::pyupgrade::rules::NonPEP604Annotation), + (Pyupgrade, "008") => (RuleGroup::Stable, rules::pyupgrade::rules::SuperCallWithParameters), + (Pyupgrade, "009") => (RuleGroup::Stable, rules::pyupgrade::rules::UTF8EncodingDeclaration), + (Pyupgrade, "010") => (RuleGroup::Stable, rules::pyupgrade::rules::UnnecessaryFutureImport), + (Pyupgrade, "011") => (RuleGroup::Stable, rules::pyupgrade::rules::LRUCacheWithoutParameters), + (Pyupgrade, "012") => (RuleGroup::Stable, rules::pyupgrade::rules::UnnecessaryEncodeUTF8), + (Pyupgrade, "013") => (RuleGroup::Stable, rules::pyupgrade::rules::ConvertTypedDictFunctionalToClass), + (Pyupgrade, "014") => (RuleGroup::Stable, rules::pyupgrade::rules::ConvertNamedTupleFunctionalToClass), + (Pyupgrade, "015") => (RuleGroup::Stable, rules::pyupgrade::rules::RedundantOpenModes), + (Pyupgrade, "017") => (RuleGroup::Stable, rules::pyupgrade::rules::DatetimeTimezoneUTC), + (Pyupgrade, "018") => (RuleGroup::Stable, rules::pyupgrade::rules::NativeLiterals), + (Pyupgrade, "019") => (RuleGroup::Stable, rules::pyupgrade::rules::TypingTextStrAlias), + (Pyupgrade, "020") => (RuleGroup::Stable, rules::pyupgrade::rules::OpenAlias), + (Pyupgrade, "021") => (RuleGroup::Stable, rules::pyupgrade::rules::ReplaceUniversalNewlines), + (Pyupgrade, "022") => (RuleGroup::Stable, rules::pyupgrade::rules::ReplaceStdoutStderr), + (Pyupgrade, "023") => (RuleGroup::Stable, rules::pyupgrade::rules::DeprecatedCElementTree), + (Pyupgrade, "024") => (RuleGroup::Stable, rules::pyupgrade::rules::OSErrorAlias), + (Pyupgrade, "025") => (RuleGroup::Stable, rules::pyupgrade::rules::UnicodeKindPrefix), + (Pyupgrade, "026") => (RuleGroup::Stable, rules::pyupgrade::rules::DeprecatedMockImport), + (Pyupgrade, "027") => (RuleGroup::Stable, rules::pyupgrade::rules::UnpackedListComprehension), + (Pyupgrade, "028") => (RuleGroup::Stable, rules::pyupgrade::rules::YieldInForLoop), + (Pyupgrade, "029") => (RuleGroup::Stable, rules::pyupgrade::rules::UnnecessaryBuiltinImport), + (Pyupgrade, "030") => (RuleGroup::Stable, rules::pyupgrade::rules::FormatLiterals), + (Pyupgrade, "031") => (RuleGroup::Stable, rules::pyupgrade::rules::PrintfStringFormatting), + (Pyupgrade, "032") => (RuleGroup::Stable, rules::pyupgrade::rules::FString), + (Pyupgrade, "033") => (RuleGroup::Stable, rules::pyupgrade::rules::LRUCacheWithMaxsizeNone), + (Pyupgrade, "034") => (RuleGroup::Stable, rules::pyupgrade::rules::ExtraneousParentheses), + (Pyupgrade, "035") => (RuleGroup::Stable, rules::pyupgrade::rules::DeprecatedImport), + (Pyupgrade, "036") => (RuleGroup::Stable, rules::pyupgrade::rules::OutdatedVersionBlock), + (Pyupgrade, "037") => (RuleGroup::Stable, rules::pyupgrade::rules::QuotedAnnotation), + (Pyupgrade, "038") => (RuleGroup::Stable, rules::pyupgrade::rules::NonPEP604Isinstance), + (Pyupgrade, "039") => (RuleGroup::Stable, rules::pyupgrade::rules::UnnecessaryClassParentheses), + (Pyupgrade, "040") => (RuleGroup::Stable, rules::pyupgrade::rules::NonPEP695TypeAlias), // pydocstyle - (Pydocstyle, "100") => (RuleGroup::Unspecified, rules::pydocstyle::rules::UndocumentedPublicModule), - (Pydocstyle, "101") => (RuleGroup::Unspecified, rules::pydocstyle::rules::UndocumentedPublicClass), - (Pydocstyle, "102") => (RuleGroup::Unspecified, rules::pydocstyle::rules::UndocumentedPublicMethod), - (Pydocstyle, "103") => (RuleGroup::Unspecified, rules::pydocstyle::rules::UndocumentedPublicFunction), - (Pydocstyle, "104") => (RuleGroup::Unspecified, rules::pydocstyle::rules::UndocumentedPublicPackage), - (Pydocstyle, "105") => (RuleGroup::Unspecified, rules::pydocstyle::rules::UndocumentedMagicMethod), - (Pydocstyle, "106") => (RuleGroup::Unspecified, rules::pydocstyle::rules::UndocumentedPublicNestedClass), - (Pydocstyle, "107") => (RuleGroup::Unspecified, rules::pydocstyle::rules::UndocumentedPublicInit), - (Pydocstyle, "200") => (RuleGroup::Unspecified, rules::pydocstyle::rules::FitsOnOneLine), - (Pydocstyle, "201") => (RuleGroup::Unspecified, rules::pydocstyle::rules::NoBlankLineBeforeFunction), - (Pydocstyle, "202") => (RuleGroup::Unspecified, rules::pydocstyle::rules::NoBlankLineAfterFunction), - (Pydocstyle, "203") => (RuleGroup::Unspecified, rules::pydocstyle::rules::OneBlankLineBeforeClass), - (Pydocstyle, "204") => (RuleGroup::Unspecified, rules::pydocstyle::rules::OneBlankLineAfterClass), - (Pydocstyle, "205") => (RuleGroup::Unspecified, rules::pydocstyle::rules::BlankLineAfterSummary), - (Pydocstyle, "206") => (RuleGroup::Unspecified, rules::pydocstyle::rules::IndentWithSpaces), - (Pydocstyle, "207") => (RuleGroup::Unspecified, rules::pydocstyle::rules::UnderIndentation), - (Pydocstyle, "208") => (RuleGroup::Unspecified, rules::pydocstyle::rules::OverIndentation), - (Pydocstyle, "209") => (RuleGroup::Unspecified, rules::pydocstyle::rules::NewLineAfterLastParagraph), - (Pydocstyle, "210") => (RuleGroup::Unspecified, rules::pydocstyle::rules::SurroundingWhitespace), - (Pydocstyle, "211") => (RuleGroup::Unspecified, rules::pydocstyle::rules::BlankLineBeforeClass), - (Pydocstyle, "212") => (RuleGroup::Unspecified, rules::pydocstyle::rules::MultiLineSummaryFirstLine), - (Pydocstyle, "213") => (RuleGroup::Unspecified, rules::pydocstyle::rules::MultiLineSummarySecondLine), - (Pydocstyle, "214") => (RuleGroup::Unspecified, rules::pydocstyle::rules::SectionNotOverIndented), - (Pydocstyle, "215") => (RuleGroup::Unspecified, rules::pydocstyle::rules::SectionUnderlineNotOverIndented), - (Pydocstyle, "300") => (RuleGroup::Unspecified, rules::pydocstyle::rules::TripleSingleQuotes), - (Pydocstyle, "301") => (RuleGroup::Unspecified, rules::pydocstyle::rules::EscapeSequenceInDocstring), - (Pydocstyle, "400") => (RuleGroup::Unspecified, rules::pydocstyle::rules::EndsInPeriod), - (Pydocstyle, "401") => (RuleGroup::Unspecified, rules::pydocstyle::rules::NonImperativeMood), - (Pydocstyle, "402") => (RuleGroup::Unspecified, rules::pydocstyle::rules::NoSignature), - (Pydocstyle, "403") => (RuleGroup::Unspecified, rules::pydocstyle::rules::FirstLineCapitalized), - (Pydocstyle, "404") => (RuleGroup::Unspecified, rules::pydocstyle::rules::DocstringStartsWithThis), - (Pydocstyle, "405") => (RuleGroup::Unspecified, rules::pydocstyle::rules::CapitalizeSectionName), - (Pydocstyle, "406") => (RuleGroup::Unspecified, rules::pydocstyle::rules::NewLineAfterSectionName), - (Pydocstyle, "407") => (RuleGroup::Unspecified, rules::pydocstyle::rules::DashedUnderlineAfterSection), - (Pydocstyle, "408") => (RuleGroup::Unspecified, rules::pydocstyle::rules::SectionUnderlineAfterName), - (Pydocstyle, "409") => (RuleGroup::Unspecified, rules::pydocstyle::rules::SectionUnderlineMatchesSectionLength), - (Pydocstyle, "410") => (RuleGroup::Unspecified, rules::pydocstyle::rules::NoBlankLineAfterSection), - (Pydocstyle, "411") => (RuleGroup::Unspecified, rules::pydocstyle::rules::NoBlankLineBeforeSection), - (Pydocstyle, "412") => (RuleGroup::Unspecified, rules::pydocstyle::rules::BlankLinesBetweenHeaderAndContent), - (Pydocstyle, "413") => (RuleGroup::Unspecified, rules::pydocstyle::rules::BlankLineAfterLastSection), - (Pydocstyle, "414") => (RuleGroup::Unspecified, rules::pydocstyle::rules::EmptyDocstringSection), - (Pydocstyle, "415") => (RuleGroup::Unspecified, rules::pydocstyle::rules::EndsInPunctuation), - (Pydocstyle, "416") => (RuleGroup::Unspecified, rules::pydocstyle::rules::SectionNameEndsInColon), - (Pydocstyle, "417") => (RuleGroup::Unspecified, rules::pydocstyle::rules::UndocumentedParam), - (Pydocstyle, "418") => (RuleGroup::Unspecified, rules::pydocstyle::rules::OverloadWithDocstring), - (Pydocstyle, "419") => (RuleGroup::Unspecified, rules::pydocstyle::rules::EmptyDocstring), + (Pydocstyle, "100") => (RuleGroup::Stable, rules::pydocstyle::rules::UndocumentedPublicModule), + (Pydocstyle, "101") => (RuleGroup::Stable, rules::pydocstyle::rules::UndocumentedPublicClass), + (Pydocstyle, "102") => (RuleGroup::Stable, rules::pydocstyle::rules::UndocumentedPublicMethod), + (Pydocstyle, "103") => (RuleGroup::Stable, rules::pydocstyle::rules::UndocumentedPublicFunction), + (Pydocstyle, "104") => (RuleGroup::Stable, rules::pydocstyle::rules::UndocumentedPublicPackage), + (Pydocstyle, "105") => (RuleGroup::Stable, rules::pydocstyle::rules::UndocumentedMagicMethod), + (Pydocstyle, "106") => (RuleGroup::Stable, rules::pydocstyle::rules::UndocumentedPublicNestedClass), + (Pydocstyle, "107") => (RuleGroup::Stable, rules::pydocstyle::rules::UndocumentedPublicInit), + (Pydocstyle, "200") => (RuleGroup::Stable, rules::pydocstyle::rules::FitsOnOneLine), + (Pydocstyle, "201") => (RuleGroup::Stable, rules::pydocstyle::rules::NoBlankLineBeforeFunction), + (Pydocstyle, "202") => (RuleGroup::Stable, rules::pydocstyle::rules::NoBlankLineAfterFunction), + (Pydocstyle, "203") => (RuleGroup::Stable, rules::pydocstyle::rules::OneBlankLineBeforeClass), + (Pydocstyle, "204") => (RuleGroup::Stable, rules::pydocstyle::rules::OneBlankLineAfterClass), + (Pydocstyle, "205") => (RuleGroup::Stable, rules::pydocstyle::rules::BlankLineAfterSummary), + (Pydocstyle, "206") => (RuleGroup::Stable, rules::pydocstyle::rules::IndentWithSpaces), + (Pydocstyle, "207") => (RuleGroup::Stable, rules::pydocstyle::rules::UnderIndentation), + (Pydocstyle, "208") => (RuleGroup::Stable, rules::pydocstyle::rules::OverIndentation), + (Pydocstyle, "209") => (RuleGroup::Stable, rules::pydocstyle::rules::NewLineAfterLastParagraph), + (Pydocstyle, "210") => (RuleGroup::Stable, rules::pydocstyle::rules::SurroundingWhitespace), + (Pydocstyle, "211") => (RuleGroup::Stable, rules::pydocstyle::rules::BlankLineBeforeClass), + (Pydocstyle, "212") => (RuleGroup::Stable, rules::pydocstyle::rules::MultiLineSummaryFirstLine), + (Pydocstyle, "213") => (RuleGroup::Stable, rules::pydocstyle::rules::MultiLineSummarySecondLine), + (Pydocstyle, "214") => (RuleGroup::Stable, rules::pydocstyle::rules::SectionNotOverIndented), + (Pydocstyle, "215") => (RuleGroup::Stable, rules::pydocstyle::rules::SectionUnderlineNotOverIndented), + (Pydocstyle, "300") => (RuleGroup::Stable, rules::pydocstyle::rules::TripleSingleQuotes), + (Pydocstyle, "301") => (RuleGroup::Stable, rules::pydocstyle::rules::EscapeSequenceInDocstring), + (Pydocstyle, "400") => (RuleGroup::Stable, rules::pydocstyle::rules::EndsInPeriod), + (Pydocstyle, "401") => (RuleGroup::Stable, rules::pydocstyle::rules::NonImperativeMood), + (Pydocstyle, "402") => (RuleGroup::Stable, rules::pydocstyle::rules::NoSignature), + (Pydocstyle, "403") => (RuleGroup::Stable, rules::pydocstyle::rules::FirstLineCapitalized), + (Pydocstyle, "404") => (RuleGroup::Stable, rules::pydocstyle::rules::DocstringStartsWithThis), + (Pydocstyle, "405") => (RuleGroup::Stable, rules::pydocstyle::rules::CapitalizeSectionName), + (Pydocstyle, "406") => (RuleGroup::Stable, rules::pydocstyle::rules::NewLineAfterSectionName), + (Pydocstyle, "407") => (RuleGroup::Stable, rules::pydocstyle::rules::DashedUnderlineAfterSection), + (Pydocstyle, "408") => (RuleGroup::Stable, rules::pydocstyle::rules::SectionUnderlineAfterName), + (Pydocstyle, "409") => (RuleGroup::Stable, rules::pydocstyle::rules::SectionUnderlineMatchesSectionLength), + (Pydocstyle, "410") => (RuleGroup::Stable, rules::pydocstyle::rules::NoBlankLineAfterSection), + (Pydocstyle, "411") => (RuleGroup::Stable, rules::pydocstyle::rules::NoBlankLineBeforeSection), + (Pydocstyle, "412") => (RuleGroup::Stable, rules::pydocstyle::rules::BlankLinesBetweenHeaderAndContent), + (Pydocstyle, "413") => (RuleGroup::Stable, rules::pydocstyle::rules::BlankLineAfterLastSection), + (Pydocstyle, "414") => (RuleGroup::Stable, rules::pydocstyle::rules::EmptyDocstringSection), + (Pydocstyle, "415") => (RuleGroup::Stable, rules::pydocstyle::rules::EndsInPunctuation), + (Pydocstyle, "416") => (RuleGroup::Stable, rules::pydocstyle::rules::SectionNameEndsInColon), + (Pydocstyle, "417") => (RuleGroup::Stable, rules::pydocstyle::rules::UndocumentedParam), + (Pydocstyle, "418") => (RuleGroup::Stable, rules::pydocstyle::rules::OverloadWithDocstring), + (Pydocstyle, "419") => (RuleGroup::Stable, rules::pydocstyle::rules::EmptyDocstring), // pep8-naming - (PEP8Naming, "801") => (RuleGroup::Unspecified, rules::pep8_naming::rules::InvalidClassName), - (PEP8Naming, "802") => (RuleGroup::Unspecified, rules::pep8_naming::rules::InvalidFunctionName), - (PEP8Naming, "803") => (RuleGroup::Unspecified, rules::pep8_naming::rules::InvalidArgumentName), - (PEP8Naming, "804") => (RuleGroup::Unspecified, rules::pep8_naming::rules::InvalidFirstArgumentNameForClassMethod), - (PEP8Naming, "805") => (RuleGroup::Unspecified, rules::pep8_naming::rules::InvalidFirstArgumentNameForMethod), - (PEP8Naming, "806") => (RuleGroup::Unspecified, rules::pep8_naming::rules::NonLowercaseVariableInFunction), - (PEP8Naming, "807") => (RuleGroup::Unspecified, rules::pep8_naming::rules::DunderFunctionName), - (PEP8Naming, "811") => (RuleGroup::Unspecified, rules::pep8_naming::rules::ConstantImportedAsNonConstant), - (PEP8Naming, "812") => (RuleGroup::Unspecified, rules::pep8_naming::rules::LowercaseImportedAsNonLowercase), - (PEP8Naming, "813") => (RuleGroup::Unspecified, rules::pep8_naming::rules::CamelcaseImportedAsLowercase), - (PEP8Naming, "814") => (RuleGroup::Unspecified, rules::pep8_naming::rules::CamelcaseImportedAsConstant), - (PEP8Naming, "815") => (RuleGroup::Unspecified, rules::pep8_naming::rules::MixedCaseVariableInClassScope), - (PEP8Naming, "816") => (RuleGroup::Unspecified, rules::pep8_naming::rules::MixedCaseVariableInGlobalScope), - (PEP8Naming, "817") => (RuleGroup::Unspecified, rules::pep8_naming::rules::CamelcaseImportedAsAcronym), - (PEP8Naming, "818") => (RuleGroup::Unspecified, rules::pep8_naming::rules::ErrorSuffixOnExceptionName), - (PEP8Naming, "999") => (RuleGroup::Unspecified, rules::pep8_naming::rules::InvalidModuleName), + (PEP8Naming, "801") => (RuleGroup::Stable, rules::pep8_naming::rules::InvalidClassName), + (PEP8Naming, "802") => (RuleGroup::Stable, rules::pep8_naming::rules::InvalidFunctionName), + (PEP8Naming, "803") => (RuleGroup::Stable, rules::pep8_naming::rules::InvalidArgumentName), + (PEP8Naming, "804") => (RuleGroup::Stable, rules::pep8_naming::rules::InvalidFirstArgumentNameForClassMethod), + (PEP8Naming, "805") => (RuleGroup::Stable, rules::pep8_naming::rules::InvalidFirstArgumentNameForMethod), + (PEP8Naming, "806") => (RuleGroup::Stable, rules::pep8_naming::rules::NonLowercaseVariableInFunction), + (PEP8Naming, "807") => (RuleGroup::Stable, rules::pep8_naming::rules::DunderFunctionName), + (PEP8Naming, "811") => (RuleGroup::Stable, rules::pep8_naming::rules::ConstantImportedAsNonConstant), + (PEP8Naming, "812") => (RuleGroup::Stable, rules::pep8_naming::rules::LowercaseImportedAsNonLowercase), + (PEP8Naming, "813") => (RuleGroup::Stable, rules::pep8_naming::rules::CamelcaseImportedAsLowercase), + (PEP8Naming, "814") => (RuleGroup::Stable, rules::pep8_naming::rules::CamelcaseImportedAsConstant), + (PEP8Naming, "815") => (RuleGroup::Stable, rules::pep8_naming::rules::MixedCaseVariableInClassScope), + (PEP8Naming, "816") => (RuleGroup::Stable, rules::pep8_naming::rules::MixedCaseVariableInGlobalScope), + (PEP8Naming, "817") => (RuleGroup::Stable, rules::pep8_naming::rules::CamelcaseImportedAsAcronym), + (PEP8Naming, "818") => (RuleGroup::Stable, rules::pep8_naming::rules::ErrorSuffixOnExceptionName), + (PEP8Naming, "999") => (RuleGroup::Stable, rules::pep8_naming::rules::InvalidModuleName), // isort - (Isort, "001") => (RuleGroup::Unspecified, rules::isort::rules::UnsortedImports), - (Isort, "002") => (RuleGroup::Unspecified, rules::isort::rules::MissingRequiredImport), + (Isort, "001") => (RuleGroup::Stable, rules::isort::rules::UnsortedImports), + (Isort, "002") => (RuleGroup::Stable, rules::isort::rules::MissingRequiredImport), // eradicate - (Eradicate, "001") => (RuleGroup::Unspecified, rules::eradicate::rules::CommentedOutCode), + (Eradicate, "001") => (RuleGroup::Stable, rules::eradicate::rules::CommentedOutCode), // flake8-bandit - (Flake8Bandit, "101") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::Assert), - (Flake8Bandit, "102") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::ExecBuiltin), - (Flake8Bandit, "103") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::BadFilePermissions), - (Flake8Bandit, "104") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::HardcodedBindAllInterfaces), - (Flake8Bandit, "105") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::HardcodedPasswordString), - (Flake8Bandit, "106") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::HardcodedPasswordFuncArg), - (Flake8Bandit, "107") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::HardcodedPasswordDefault), - (Flake8Bandit, "108") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::HardcodedTempFile), - (Flake8Bandit, "110") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::TryExceptPass), - (Flake8Bandit, "112") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::TryExceptContinue), - (Flake8Bandit, "113") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::RequestWithoutTimeout), + (Flake8Bandit, "101") => (RuleGroup::Stable, rules::flake8_bandit::rules::Assert), + (Flake8Bandit, "102") => (RuleGroup::Stable, rules::flake8_bandit::rules::ExecBuiltin), + (Flake8Bandit, "103") => (RuleGroup::Stable, rules::flake8_bandit::rules::BadFilePermissions), + (Flake8Bandit, "104") => (RuleGroup::Stable, rules::flake8_bandit::rules::HardcodedBindAllInterfaces), + (Flake8Bandit, "105") => (RuleGroup::Stable, rules::flake8_bandit::rules::HardcodedPasswordString), + (Flake8Bandit, "106") => (RuleGroup::Stable, rules::flake8_bandit::rules::HardcodedPasswordFuncArg), + (Flake8Bandit, "107") => (RuleGroup::Stable, rules::flake8_bandit::rules::HardcodedPasswordDefault), + (Flake8Bandit, "108") => (RuleGroup::Stable, rules::flake8_bandit::rules::HardcodedTempFile), + (Flake8Bandit, "110") => (RuleGroup::Stable, rules::flake8_bandit::rules::TryExceptPass), + (Flake8Bandit, "112") => (RuleGroup::Stable, rules::flake8_bandit::rules::TryExceptContinue), + (Flake8Bandit, "113") => (RuleGroup::Stable, rules::flake8_bandit::rules::RequestWithoutTimeout), (Flake8Bandit, "201") => (RuleGroup::Preview, rules::flake8_bandit::rules::FlaskDebugTrue), - (Flake8Bandit, "301") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousPickleUsage), - (Flake8Bandit, "302") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousMarshalUsage), - (Flake8Bandit, "303") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousInsecureHashUsage), - (Flake8Bandit, "304") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousInsecureCipherUsage), - (Flake8Bandit, "305") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousInsecureCipherModeUsage), - (Flake8Bandit, "306") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousMktempUsage), - (Flake8Bandit, "307") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousEvalUsage), - (Flake8Bandit, "308") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousMarkSafeUsage), - (Flake8Bandit, "310") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousURLOpenUsage), - (Flake8Bandit, "311") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousNonCryptographicRandomUsage), - (Flake8Bandit, "312") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousTelnetUsage), - (Flake8Bandit, "313") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousXMLCElementTreeUsage), - (Flake8Bandit, "314") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousXMLElementTreeUsage), - (Flake8Bandit, "315") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousXMLExpatReaderUsage), - (Flake8Bandit, "316") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousXMLExpatBuilderUsage), - (Flake8Bandit, "317") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousXMLSaxUsage), - (Flake8Bandit, "318") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousXMLMiniDOMUsage), - (Flake8Bandit, "319") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousXMLPullDOMUsage), - (Flake8Bandit, "320") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousXMLETreeUsage), - (Flake8Bandit, "321") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousFTPLibUsage), - (Flake8Bandit, "323") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SuspiciousUnverifiedContextUsage), - (Flake8Bandit, "324") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::HashlibInsecureHashFunction), - (Flake8Bandit, "501") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::RequestWithNoCertValidation), - (Flake8Bandit, "506") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::UnsafeYAMLLoad), + (Flake8Bandit, "301") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousPickleUsage), + (Flake8Bandit, "302") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousMarshalUsage), + (Flake8Bandit, "303") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousInsecureHashUsage), + (Flake8Bandit, "304") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousInsecureCipherUsage), + (Flake8Bandit, "305") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousInsecureCipherModeUsage), + (Flake8Bandit, "306") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousMktempUsage), + (Flake8Bandit, "307") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousEvalUsage), + (Flake8Bandit, "308") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousMarkSafeUsage), + (Flake8Bandit, "310") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousURLOpenUsage), + (Flake8Bandit, "311") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousNonCryptographicRandomUsage), + (Flake8Bandit, "312") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousTelnetUsage), + (Flake8Bandit, "313") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousXMLCElementTreeUsage), + (Flake8Bandit, "314") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousXMLElementTreeUsage), + (Flake8Bandit, "315") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousXMLExpatReaderUsage), + (Flake8Bandit, "316") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousXMLExpatBuilderUsage), + (Flake8Bandit, "317") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousXMLSaxUsage), + (Flake8Bandit, "318") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousXMLMiniDOMUsage), + (Flake8Bandit, "319") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousXMLPullDOMUsage), + (Flake8Bandit, "320") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousXMLETreeUsage), + (Flake8Bandit, "321") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousFTPLibUsage), + (Flake8Bandit, "323") => (RuleGroup::Stable, rules::flake8_bandit::rules::SuspiciousUnverifiedContextUsage), + (Flake8Bandit, "324") => (RuleGroup::Stable, rules::flake8_bandit::rules::HashlibInsecureHashFunction), + (Flake8Bandit, "501") => (RuleGroup::Stable, rules::flake8_bandit::rules::RequestWithNoCertValidation), + (Flake8Bandit, "505") => (RuleGroup::Preview, rules::flake8_bandit::rules::WeakCryptographicKey), + (Flake8Bandit, "506") => (RuleGroup::Stable, rules::flake8_bandit::rules::UnsafeYAMLLoad), (Flake8Bandit, "507") => (RuleGroup::Preview, rules::flake8_bandit::rules::SSHNoHostKeyVerification), - (Flake8Bandit, "508") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SnmpInsecureVersion), - (Flake8Bandit, "509") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SnmpWeakCryptography), - (Flake8Bandit, "601") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::ParamikoCall), - (Flake8Bandit, "602") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SubprocessPopenWithShellEqualsTrue), - (Flake8Bandit, "603") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::SubprocessWithoutShellEqualsTrue), - (Flake8Bandit, "604") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::CallWithShellEqualsTrue), - (Flake8Bandit, "605") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::StartProcessWithAShell), - (Flake8Bandit, "606") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::StartProcessWithNoShell), - (Flake8Bandit, "607") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::StartProcessWithPartialPath), - (Flake8Bandit, "608") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::HardcodedSQLExpression), - (Flake8Bandit, "609") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::UnixCommandWildcardInjection), - (Flake8Bandit, "612") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::LoggingConfigInsecureListen), - (Flake8Bandit, "701") => (RuleGroup::Unspecified, rules::flake8_bandit::rules::Jinja2AutoescapeFalse), + (Flake8Bandit, "508") => (RuleGroup::Stable, rules::flake8_bandit::rules::SnmpInsecureVersion), + (Flake8Bandit, "509") => (RuleGroup::Stable, rules::flake8_bandit::rules::SnmpWeakCryptography), + (Flake8Bandit, "601") => (RuleGroup::Stable, rules::flake8_bandit::rules::ParamikoCall), + (Flake8Bandit, "602") => (RuleGroup::Stable, rules::flake8_bandit::rules::SubprocessPopenWithShellEqualsTrue), + (Flake8Bandit, "603") => (RuleGroup::Stable, rules::flake8_bandit::rules::SubprocessWithoutShellEqualsTrue), + (Flake8Bandit, "604") => (RuleGroup::Stable, rules::flake8_bandit::rules::CallWithShellEqualsTrue), + (Flake8Bandit, "605") => (RuleGroup::Stable, rules::flake8_bandit::rules::StartProcessWithAShell), + (Flake8Bandit, "606") => (RuleGroup::Stable, rules::flake8_bandit::rules::StartProcessWithNoShell), + (Flake8Bandit, "607") => (RuleGroup::Stable, rules::flake8_bandit::rules::StartProcessWithPartialPath), + (Flake8Bandit, "608") => (RuleGroup::Stable, rules::flake8_bandit::rules::HardcodedSQLExpression), + (Flake8Bandit, "609") => (RuleGroup::Stable, rules::flake8_bandit::rules::UnixCommandWildcardInjection), + (Flake8Bandit, "612") => (RuleGroup::Stable, rules::flake8_bandit::rules::LoggingConfigInsecureListen), + (Flake8Bandit, "701") => (RuleGroup::Stable, rules::flake8_bandit::rules::Jinja2AutoescapeFalse), // flake8-boolean-trap - (Flake8BooleanTrap, "001") => (RuleGroup::Unspecified, rules::flake8_boolean_trap::rules::BooleanTypeHintPositionalArgument), - (Flake8BooleanTrap, "002") => (RuleGroup::Unspecified, rules::flake8_boolean_trap::rules::BooleanDefaultValuePositionalArgument), - (Flake8BooleanTrap, "003") => (RuleGroup::Unspecified, rules::flake8_boolean_trap::rules::BooleanPositionalValueInCall), + (Flake8BooleanTrap, "001") => (RuleGroup::Stable, rules::flake8_boolean_trap::rules::BooleanTypeHintPositionalArgument), + (Flake8BooleanTrap, "002") => (RuleGroup::Stable, rules::flake8_boolean_trap::rules::BooleanDefaultValuePositionalArgument), + (Flake8BooleanTrap, "003") => (RuleGroup::Stable, rules::flake8_boolean_trap::rules::BooleanPositionalValueInCall), // flake8-unused-arguments - (Flake8UnusedArguments, "001") => (RuleGroup::Unspecified, rules::flake8_unused_arguments::rules::UnusedFunctionArgument), - (Flake8UnusedArguments, "002") => (RuleGroup::Unspecified, rules::flake8_unused_arguments::rules::UnusedMethodArgument), - (Flake8UnusedArguments, "003") => (RuleGroup::Unspecified, rules::flake8_unused_arguments::rules::UnusedClassMethodArgument), - (Flake8UnusedArguments, "004") => (RuleGroup::Unspecified, rules::flake8_unused_arguments::rules::UnusedStaticMethodArgument), - (Flake8UnusedArguments, "005") => (RuleGroup::Unspecified, rules::flake8_unused_arguments::rules::UnusedLambdaArgument), + (Flake8UnusedArguments, "001") => (RuleGroup::Stable, rules::flake8_unused_arguments::rules::UnusedFunctionArgument), + (Flake8UnusedArguments, "002") => (RuleGroup::Stable, rules::flake8_unused_arguments::rules::UnusedMethodArgument), + (Flake8UnusedArguments, "003") => (RuleGroup::Stable, rules::flake8_unused_arguments::rules::UnusedClassMethodArgument), + (Flake8UnusedArguments, "004") => (RuleGroup::Stable, rules::flake8_unused_arguments::rules::UnusedStaticMethodArgument), + (Flake8UnusedArguments, "005") => (RuleGroup::Stable, rules::flake8_unused_arguments::rules::UnusedLambdaArgument), // flake8-import-conventions - (Flake8ImportConventions, "001") => (RuleGroup::Unspecified, rules::flake8_import_conventions::rules::UnconventionalImportAlias), - (Flake8ImportConventions, "002") => (RuleGroup::Unspecified, rules::flake8_import_conventions::rules::BannedImportAlias), - (Flake8ImportConventions, "003") => (RuleGroup::Unspecified, rules::flake8_import_conventions::rules::BannedImportFrom), + (Flake8ImportConventions, "001") => (RuleGroup::Stable, rules::flake8_import_conventions::rules::UnconventionalImportAlias), + (Flake8ImportConventions, "002") => (RuleGroup::Stable, rules::flake8_import_conventions::rules::BannedImportAlias), + (Flake8ImportConventions, "003") => (RuleGroup::Stable, rules::flake8_import_conventions::rules::BannedImportFrom), // flake8-datetimez - (Flake8Datetimez, "001") => (RuleGroup::Unspecified, rules::flake8_datetimez::rules::CallDatetimeWithoutTzinfo), - (Flake8Datetimez, "002") => (RuleGroup::Unspecified, rules::flake8_datetimez::rules::CallDatetimeToday), - (Flake8Datetimez, "003") => (RuleGroup::Unspecified, rules::flake8_datetimez::rules::CallDatetimeUtcnow), - (Flake8Datetimez, "004") => (RuleGroup::Unspecified, rules::flake8_datetimez::rules::CallDatetimeUtcfromtimestamp), - (Flake8Datetimez, "005") => (RuleGroup::Unspecified, rules::flake8_datetimez::rules::CallDatetimeNowWithoutTzinfo), - (Flake8Datetimez, "006") => (RuleGroup::Unspecified, rules::flake8_datetimez::rules::CallDatetimeFromtimestamp), - (Flake8Datetimez, "007") => (RuleGroup::Unspecified, rules::flake8_datetimez::rules::CallDatetimeStrptimeWithoutZone), - (Flake8Datetimez, "011") => (RuleGroup::Unspecified, rules::flake8_datetimez::rules::CallDateToday), - (Flake8Datetimez, "012") => (RuleGroup::Unspecified, rules::flake8_datetimez::rules::CallDateFromtimestamp), + (Flake8Datetimez, "001") => (RuleGroup::Stable, rules::flake8_datetimez::rules::CallDatetimeWithoutTzinfo), + (Flake8Datetimez, "002") => (RuleGroup::Stable, rules::flake8_datetimez::rules::CallDatetimeToday), + (Flake8Datetimez, "003") => (RuleGroup::Stable, rules::flake8_datetimez::rules::CallDatetimeUtcnow), + (Flake8Datetimez, "004") => (RuleGroup::Stable, rules::flake8_datetimez::rules::CallDatetimeUtcfromtimestamp), + (Flake8Datetimez, "005") => (RuleGroup::Stable, rules::flake8_datetimez::rules::CallDatetimeNowWithoutTzinfo), + (Flake8Datetimez, "006") => (RuleGroup::Stable, rules::flake8_datetimez::rules::CallDatetimeFromtimestamp), + (Flake8Datetimez, "007") => (RuleGroup::Stable, rules::flake8_datetimez::rules::CallDatetimeStrptimeWithoutZone), + (Flake8Datetimez, "011") => (RuleGroup::Stable, rules::flake8_datetimez::rules::CallDateToday), + (Flake8Datetimez, "012") => (RuleGroup::Stable, rules::flake8_datetimez::rules::CallDateFromtimestamp), // pygrep-hooks - (PygrepHooks, "001") => (RuleGroup::Unspecified, rules::pygrep_hooks::rules::Eval), - (PygrepHooks, "002") => (RuleGroup::Unspecified, rules::pygrep_hooks::rules::DeprecatedLogWarn), - (PygrepHooks, "003") => (RuleGroup::Unspecified, rules::pygrep_hooks::rules::BlanketTypeIgnore), - (PygrepHooks, "004") => (RuleGroup::Unspecified, rules::pygrep_hooks::rules::BlanketNOQA), - (PygrepHooks, "005") => (RuleGroup::Unspecified, rules::pygrep_hooks::rules::InvalidMockAccess), + (PygrepHooks, "001") => (RuleGroup::Stable, rules::pygrep_hooks::rules::Eval), + (PygrepHooks, "002") => (RuleGroup::Stable, rules::pygrep_hooks::rules::DeprecatedLogWarn), + (PygrepHooks, "003") => (RuleGroup::Stable, rules::pygrep_hooks::rules::BlanketTypeIgnore), + (PygrepHooks, "004") => (RuleGroup::Stable, rules::pygrep_hooks::rules::BlanketNOQA), + (PygrepHooks, "005") => (RuleGroup::Stable, rules::pygrep_hooks::rules::InvalidMockAccess), // pandas-vet - (PandasVet, "002") => (RuleGroup::Unspecified, rules::pandas_vet::rules::PandasUseOfInplaceArgument), - (PandasVet, "003") => (RuleGroup::Unspecified, rules::pandas_vet::rules::PandasUseOfDotIsNull), - (PandasVet, "004") => (RuleGroup::Unspecified, rules::pandas_vet::rules::PandasUseOfDotNotNull), - (PandasVet, "007") => (RuleGroup::Unspecified, rules::pandas_vet::rules::PandasUseOfDotIx), - (PandasVet, "008") => (RuleGroup::Unspecified, rules::pandas_vet::rules::PandasUseOfDotAt), - (PandasVet, "009") => (RuleGroup::Unspecified, rules::pandas_vet::rules::PandasUseOfDotIat), - (PandasVet, "010") => (RuleGroup::Unspecified, rules::pandas_vet::rules::PandasUseOfDotPivotOrUnstack), - (PandasVet, "011") => (RuleGroup::Unspecified, rules::pandas_vet::rules::PandasUseOfDotValues), - (PandasVet, "012") => (RuleGroup::Unspecified, rules::pandas_vet::rules::PandasUseOfDotReadTable), - (PandasVet, "013") => (RuleGroup::Unspecified, rules::pandas_vet::rules::PandasUseOfDotStack), - (PandasVet, "015") => (RuleGroup::Unspecified, rules::pandas_vet::rules::PandasUseOfPdMerge), - (PandasVet, "101") => (RuleGroup::Unspecified, rules::pandas_vet::rules::PandasNuniqueConstantSeriesCheck), - (PandasVet, "901") => (RuleGroup::Unspecified, rules::pandas_vet::rules::PandasDfVariableName), + (PandasVet, "002") => (RuleGroup::Stable, rules::pandas_vet::rules::PandasUseOfInplaceArgument), + (PandasVet, "003") => (RuleGroup::Stable, rules::pandas_vet::rules::PandasUseOfDotIsNull), + (PandasVet, "004") => (RuleGroup::Stable, rules::pandas_vet::rules::PandasUseOfDotNotNull), + (PandasVet, "007") => (RuleGroup::Stable, rules::pandas_vet::rules::PandasUseOfDotIx), + (PandasVet, "008") => (RuleGroup::Stable, rules::pandas_vet::rules::PandasUseOfDotAt), + (PandasVet, "009") => (RuleGroup::Stable, rules::pandas_vet::rules::PandasUseOfDotIat), + (PandasVet, "010") => (RuleGroup::Stable, rules::pandas_vet::rules::PandasUseOfDotPivotOrUnstack), + (PandasVet, "011") => (RuleGroup::Stable, rules::pandas_vet::rules::PandasUseOfDotValues), + (PandasVet, "012") => (RuleGroup::Stable, rules::pandas_vet::rules::PandasUseOfDotReadTable), + (PandasVet, "013") => (RuleGroup::Stable, rules::pandas_vet::rules::PandasUseOfDotStack), + (PandasVet, "015") => (RuleGroup::Stable, rules::pandas_vet::rules::PandasUseOfPdMerge), + (PandasVet, "101") => (RuleGroup::Stable, rules::pandas_vet::rules::PandasNuniqueConstantSeriesCheck), + (PandasVet, "901") => (RuleGroup::Stable, rules::pandas_vet::rules::PandasDfVariableName), // flake8-errmsg - (Flake8ErrMsg, "101") => (RuleGroup::Unspecified, rules::flake8_errmsg::rules::RawStringInException), - (Flake8ErrMsg, "102") => (RuleGroup::Unspecified, rules::flake8_errmsg::rules::FStringInException), - (Flake8ErrMsg, "103") => (RuleGroup::Unspecified, rules::flake8_errmsg::rules::DotFormatInException), + (Flake8ErrMsg, "101") => (RuleGroup::Stable, rules::flake8_errmsg::rules::RawStringInException), + (Flake8ErrMsg, "102") => (RuleGroup::Stable, rules::flake8_errmsg::rules::FStringInException), + (Flake8ErrMsg, "103") => (RuleGroup::Stable, rules::flake8_errmsg::rules::DotFormatInException), // flake8-pyi - (Flake8Pyi, "001") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::UnprefixedTypeParam), - (Flake8Pyi, "002") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::ComplexIfStatementInStub), - (Flake8Pyi, "003") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::UnrecognizedVersionInfoCheck), - (Flake8Pyi, "004") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::PatchVersionComparison), - (Flake8Pyi, "005") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::WrongTupleLengthVersionComparison), - (Flake8Pyi, "006") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::BadVersionInfoComparison), - (Flake8Pyi, "007") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::UnrecognizedPlatformCheck), - (Flake8Pyi, "008") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::UnrecognizedPlatformName), - (Flake8Pyi, "009") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::PassStatementStubBody), - (Flake8Pyi, "010") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::NonEmptyStubBody), - (Flake8Pyi, "011") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::TypedArgumentDefaultInStub), - (Flake8Pyi, "012") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::PassInClassBody), - (Flake8Pyi, "013") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::EllipsisInNonEmptyClassBody), - (Flake8Pyi, "014") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::ArgumentDefaultInStub), - (Flake8Pyi, "015") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::AssignmentDefaultInStub), - (Flake8Pyi, "016") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::DuplicateUnionMember), - (Flake8Pyi, "017") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::ComplexAssignmentInStub), - (Flake8Pyi, "018") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::UnusedPrivateTypeVar), - (Flake8Pyi, "019") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::CustomTypeVarReturnType), - (Flake8Pyi, "020") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::QuotedAnnotationInStub), - (Flake8Pyi, "021") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::DocstringInStub), - (Flake8Pyi, "024") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::CollectionsNamedTuple), - (Flake8Pyi, "025") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::UnaliasedCollectionsAbcSetImport), - (Flake8Pyi, "026") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::TypeAliasWithoutAnnotation), - (Flake8Pyi, "029") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::StrOrReprDefinedInStub), - (Flake8Pyi, "030") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::UnnecessaryLiteralUnion), - (Flake8Pyi, "032") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::AnyEqNeAnnotation), - (Flake8Pyi, "033") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::TypeCommentInStub), - (Flake8Pyi, "034") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::NonSelfReturnType), - (Flake8Pyi, "035") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::UnassignedSpecialVariableInStub), - (Flake8Pyi, "036") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::BadExitAnnotation), - (Flake8Pyi, "041") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::RedundantNumericUnion), - (Flake8Pyi, "042") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::SnakeCaseTypeAlias), - (Flake8Pyi, "043") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::TSuffixedTypeAlias), - (Flake8Pyi, "044") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::FutureAnnotationsInStub), - (Flake8Pyi, "045") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::IterMethodReturnIterable), - (Flake8Pyi, "046") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::UnusedPrivateProtocol), - (Flake8Pyi, "047") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::UnusedPrivateTypeAlias), - (Flake8Pyi, "048") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::StubBodyMultipleStatements), - (Flake8Pyi, "049") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::UnusedPrivateTypedDict), - (Flake8Pyi, "050") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::NoReturnArgumentAnnotationInStub), - (Flake8Pyi, "051") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::RedundantLiteralUnion), - (Flake8Pyi, "052") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::UnannotatedAssignmentInStub), - (Flake8Pyi, "054") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::NumericLiteralTooLong), - (Flake8Pyi, "053") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::StringOrBytesTooLong), - (Flake8Pyi, "055") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::UnnecessaryTypeUnion), - (Flake8Pyi, "056") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::UnsupportedMethodCallOnAll), + (Flake8Pyi, "001") => (RuleGroup::Stable, rules::flake8_pyi::rules::UnprefixedTypeParam), + (Flake8Pyi, "002") => (RuleGroup::Stable, rules::flake8_pyi::rules::ComplexIfStatementInStub), + (Flake8Pyi, "003") => (RuleGroup::Stable, rules::flake8_pyi::rules::UnrecognizedVersionInfoCheck), + (Flake8Pyi, "004") => (RuleGroup::Stable, rules::flake8_pyi::rules::PatchVersionComparison), + (Flake8Pyi, "005") => (RuleGroup::Stable, rules::flake8_pyi::rules::WrongTupleLengthVersionComparison), + (Flake8Pyi, "006") => (RuleGroup::Stable, rules::flake8_pyi::rules::BadVersionInfoComparison), + (Flake8Pyi, "007") => (RuleGroup::Stable, rules::flake8_pyi::rules::UnrecognizedPlatformCheck), + (Flake8Pyi, "008") => (RuleGroup::Stable, rules::flake8_pyi::rules::UnrecognizedPlatformName), + (Flake8Pyi, "009") => (RuleGroup::Stable, rules::flake8_pyi::rules::PassStatementStubBody), + (Flake8Pyi, "010") => (RuleGroup::Stable, rules::flake8_pyi::rules::NonEmptyStubBody), + (Flake8Pyi, "011") => (RuleGroup::Stable, rules::flake8_pyi::rules::TypedArgumentDefaultInStub), + (Flake8Pyi, "012") => (RuleGroup::Stable, rules::flake8_pyi::rules::PassInClassBody), + (Flake8Pyi, "013") => (RuleGroup::Stable, rules::flake8_pyi::rules::EllipsisInNonEmptyClassBody), + (Flake8Pyi, "014") => (RuleGroup::Stable, rules::flake8_pyi::rules::ArgumentDefaultInStub), + (Flake8Pyi, "015") => (RuleGroup::Stable, rules::flake8_pyi::rules::AssignmentDefaultInStub), + (Flake8Pyi, "016") => (RuleGroup::Stable, rules::flake8_pyi::rules::DuplicateUnionMember), + (Flake8Pyi, "017") => (RuleGroup::Stable, rules::flake8_pyi::rules::ComplexAssignmentInStub), + (Flake8Pyi, "018") => (RuleGroup::Stable, rules::flake8_pyi::rules::UnusedPrivateTypeVar), + (Flake8Pyi, "019") => (RuleGroup::Stable, rules::flake8_pyi::rules::CustomTypeVarReturnType), + (Flake8Pyi, "020") => (RuleGroup::Stable, rules::flake8_pyi::rules::QuotedAnnotationInStub), + (Flake8Pyi, "021") => (RuleGroup::Stable, rules::flake8_pyi::rules::DocstringInStub), + (Flake8Pyi, "024") => (RuleGroup::Stable, rules::flake8_pyi::rules::CollectionsNamedTuple), + (Flake8Pyi, "025") => (RuleGroup::Stable, rules::flake8_pyi::rules::UnaliasedCollectionsAbcSetImport), + (Flake8Pyi, "026") => (RuleGroup::Stable, rules::flake8_pyi::rules::TypeAliasWithoutAnnotation), + (Flake8Pyi, "029") => (RuleGroup::Stable, rules::flake8_pyi::rules::StrOrReprDefinedInStub), + (Flake8Pyi, "030") => (RuleGroup::Stable, rules::flake8_pyi::rules::UnnecessaryLiteralUnion), + (Flake8Pyi, "032") => (RuleGroup::Stable, rules::flake8_pyi::rules::AnyEqNeAnnotation), + (Flake8Pyi, "033") => (RuleGroup::Stable, rules::flake8_pyi::rules::TypeCommentInStub), + (Flake8Pyi, "034") => (RuleGroup::Stable, rules::flake8_pyi::rules::NonSelfReturnType), + (Flake8Pyi, "035") => (RuleGroup::Stable, rules::flake8_pyi::rules::UnassignedSpecialVariableInStub), + (Flake8Pyi, "036") => (RuleGroup::Stable, rules::flake8_pyi::rules::BadExitAnnotation), + (Flake8Pyi, "041") => (RuleGroup::Stable, rules::flake8_pyi::rules::RedundantNumericUnion), + (Flake8Pyi, "042") => (RuleGroup::Stable, rules::flake8_pyi::rules::SnakeCaseTypeAlias), + (Flake8Pyi, "043") => (RuleGroup::Stable, rules::flake8_pyi::rules::TSuffixedTypeAlias), + (Flake8Pyi, "044") => (RuleGroup::Stable, rules::flake8_pyi::rules::FutureAnnotationsInStub), + (Flake8Pyi, "045") => (RuleGroup::Stable, rules::flake8_pyi::rules::IterMethodReturnIterable), + (Flake8Pyi, "046") => (RuleGroup::Stable, rules::flake8_pyi::rules::UnusedPrivateProtocol), + (Flake8Pyi, "047") => (RuleGroup::Stable, rules::flake8_pyi::rules::UnusedPrivateTypeAlias), + (Flake8Pyi, "048") => (RuleGroup::Stable, rules::flake8_pyi::rules::StubBodyMultipleStatements), + (Flake8Pyi, "049") => (RuleGroup::Stable, rules::flake8_pyi::rules::UnusedPrivateTypedDict), + (Flake8Pyi, "050") => (RuleGroup::Stable, rules::flake8_pyi::rules::NoReturnArgumentAnnotationInStub), + (Flake8Pyi, "051") => (RuleGroup::Stable, rules::flake8_pyi::rules::RedundantLiteralUnion), + (Flake8Pyi, "052") => (RuleGroup::Stable, rules::flake8_pyi::rules::UnannotatedAssignmentInStub), + (Flake8Pyi, "054") => (RuleGroup::Stable, rules::flake8_pyi::rules::NumericLiteralTooLong), + (Flake8Pyi, "053") => (RuleGroup::Stable, rules::flake8_pyi::rules::StringOrBytesTooLong), + (Flake8Pyi, "055") => (RuleGroup::Stable, rules::flake8_pyi::rules::UnnecessaryTypeUnion), + (Flake8Pyi, "056") => (RuleGroup::Stable, rules::flake8_pyi::rules::UnsupportedMethodCallOnAll), // flake8-pytest-style - (Flake8PytestStyle, "001") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestFixtureIncorrectParenthesesStyle), - (Flake8PytestStyle, "002") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestFixturePositionalArgs), - (Flake8PytestStyle, "003") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestExtraneousScopeFunction), - (Flake8PytestStyle, "004") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestMissingFixtureNameUnderscore), - (Flake8PytestStyle, "005") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestIncorrectFixtureNameUnderscore), - (Flake8PytestStyle, "006") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestParametrizeNamesWrongType), - (Flake8PytestStyle, "007") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestParametrizeValuesWrongType), - (Flake8PytestStyle, "008") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestPatchWithLambda), - (Flake8PytestStyle, "009") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestUnittestAssertion), - (Flake8PytestStyle, "010") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestRaisesWithoutException), - (Flake8PytestStyle, "011") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestRaisesTooBroad), - (Flake8PytestStyle, "012") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestRaisesWithMultipleStatements), - (Flake8PytestStyle, "013") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestIncorrectPytestImport), - (Flake8PytestStyle, "014") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestDuplicateParametrizeTestCases), - (Flake8PytestStyle, "015") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestAssertAlwaysFalse), - (Flake8PytestStyle, "016") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestFailWithoutMessage), - (Flake8PytestStyle, "017") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestAssertInExcept), - (Flake8PytestStyle, "018") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestCompositeAssertion), - (Flake8PytestStyle, "019") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestFixtureParamWithoutValue), - (Flake8PytestStyle, "020") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestDeprecatedYieldFixture), - (Flake8PytestStyle, "021") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestFixtureFinalizerCallback), - (Flake8PytestStyle, "022") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestUselessYieldFixture), - (Flake8PytestStyle, "023") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestIncorrectMarkParenthesesStyle), - (Flake8PytestStyle, "024") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestUnnecessaryAsyncioMarkOnFixture), - (Flake8PytestStyle, "025") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestErroneousUseFixturesOnFixture), - (Flake8PytestStyle, "026") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestUseFixturesWithoutParameters), - (Flake8PytestStyle, "027") => (RuleGroup::Unspecified, rules::flake8_pytest_style::rules::PytestUnittestRaisesAssertion), + (Flake8PytestStyle, "001") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestFixtureIncorrectParenthesesStyle), + (Flake8PytestStyle, "002") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestFixturePositionalArgs), + (Flake8PytestStyle, "003") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestExtraneousScopeFunction), + (Flake8PytestStyle, "004") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestMissingFixtureNameUnderscore), + (Flake8PytestStyle, "005") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestIncorrectFixtureNameUnderscore), + (Flake8PytestStyle, "006") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestParametrizeNamesWrongType), + (Flake8PytestStyle, "007") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestParametrizeValuesWrongType), + (Flake8PytestStyle, "008") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestPatchWithLambda), + (Flake8PytestStyle, "009") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestUnittestAssertion), + (Flake8PytestStyle, "010") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestRaisesWithoutException), + (Flake8PytestStyle, "011") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestRaisesTooBroad), + (Flake8PytestStyle, "012") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestRaisesWithMultipleStatements), + (Flake8PytestStyle, "013") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestIncorrectPytestImport), + (Flake8PytestStyle, "014") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestDuplicateParametrizeTestCases), + (Flake8PytestStyle, "015") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestAssertAlwaysFalse), + (Flake8PytestStyle, "016") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestFailWithoutMessage), + (Flake8PytestStyle, "017") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestAssertInExcept), + (Flake8PytestStyle, "018") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestCompositeAssertion), + (Flake8PytestStyle, "019") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestFixtureParamWithoutValue), + (Flake8PytestStyle, "020") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestDeprecatedYieldFixture), + (Flake8PytestStyle, "021") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestFixtureFinalizerCallback), + (Flake8PytestStyle, "022") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestUselessYieldFixture), + (Flake8PytestStyle, "023") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestIncorrectMarkParenthesesStyle), + (Flake8PytestStyle, "024") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestUnnecessaryAsyncioMarkOnFixture), + (Flake8PytestStyle, "025") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestErroneousUseFixturesOnFixture), + (Flake8PytestStyle, "026") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestUseFixturesWithoutParameters), + (Flake8PytestStyle, "027") => (RuleGroup::Stable, rules::flake8_pytest_style::rules::PytestUnittestRaisesAssertion), // flake8-pie - (Flake8Pie, "790") => (RuleGroup::Unspecified, rules::flake8_pie::rules::UnnecessaryPass), - (Flake8Pie, "794") => (RuleGroup::Unspecified, rules::flake8_pie::rules::DuplicateClassFieldDefinition), - (Flake8Pie, "796") => (RuleGroup::Unspecified, rules::flake8_pie::rules::NonUniqueEnums), - (Flake8Pie, "800") => (RuleGroup::Unspecified, rules::flake8_pie::rules::UnnecessarySpread), - (Flake8Pie, "804") => (RuleGroup::Unspecified, rules::flake8_pie::rules::UnnecessaryDictKwargs), - (Flake8Pie, "807") => (RuleGroup::Unspecified, rules::flake8_pie::rules::ReimplementedListBuiltin), - (Flake8Pie, "808") => (RuleGroup::Unspecified, rules::flake8_pie::rules::UnnecessaryRangeStart), - (Flake8Pie, "810") => (RuleGroup::Unspecified, rules::flake8_pie::rules::MultipleStartsEndsWith), + (Flake8Pie, "790") => (RuleGroup::Stable, rules::flake8_pie::rules::UnnecessaryPass), + (Flake8Pie, "794") => (RuleGroup::Stable, rules::flake8_pie::rules::DuplicateClassFieldDefinition), + (Flake8Pie, "796") => (RuleGroup::Stable, rules::flake8_pie::rules::NonUniqueEnums), + (Flake8Pie, "800") => (RuleGroup::Stable, rules::flake8_pie::rules::UnnecessarySpread), + (Flake8Pie, "804") => (RuleGroup::Stable, rules::flake8_pie::rules::UnnecessaryDictKwargs), + (Flake8Pie, "807") => (RuleGroup::Stable, rules::flake8_pie::rules::ReimplementedListBuiltin), + (Flake8Pie, "808") => (RuleGroup::Stable, rules::flake8_pie::rules::UnnecessaryRangeStart), + (Flake8Pie, "810") => (RuleGroup::Stable, rules::flake8_pie::rules::MultipleStartsEndsWith), // flake8-commas - (Flake8Commas, "812") => (RuleGroup::Unspecified, rules::flake8_commas::rules::MissingTrailingComma), - (Flake8Commas, "818") => (RuleGroup::Unspecified, rules::flake8_commas::rules::TrailingCommaOnBareTuple), - (Flake8Commas, "819") => (RuleGroup::Unspecified, rules::flake8_commas::rules::ProhibitedTrailingComma), + (Flake8Commas, "812") => (RuleGroup::Stable, rules::flake8_commas::rules::MissingTrailingComma), + (Flake8Commas, "818") => (RuleGroup::Stable, rules::flake8_commas::rules::TrailingCommaOnBareTuple), + (Flake8Commas, "819") => (RuleGroup::Stable, rules::flake8_commas::rules::ProhibitedTrailingComma), // flake8-no-pep420 - (Flake8NoPep420, "001") => (RuleGroup::Unspecified, rules::flake8_no_pep420::rules::ImplicitNamespacePackage), + (Flake8NoPep420, "001") => (RuleGroup::Stable, rules::flake8_no_pep420::rules::ImplicitNamespacePackage), // flake8-executable - (Flake8Executable, "001") => (RuleGroup::Unspecified, rules::flake8_executable::rules::ShebangNotExecutable), - (Flake8Executable, "002") => (RuleGroup::Unspecified, rules::flake8_executable::rules::ShebangMissingExecutableFile), - (Flake8Executable, "003") => (RuleGroup::Unspecified, rules::flake8_executable::rules::ShebangMissingPython), - (Flake8Executable, "004") => (RuleGroup::Unspecified, rules::flake8_executable::rules::ShebangLeadingWhitespace), - (Flake8Executable, "005") => (RuleGroup::Unspecified, rules::flake8_executable::rules::ShebangNotFirstLine), + (Flake8Executable, "001") => (RuleGroup::Stable, rules::flake8_executable::rules::ShebangNotExecutable), + (Flake8Executable, "002") => (RuleGroup::Stable, rules::flake8_executable::rules::ShebangMissingExecutableFile), + (Flake8Executable, "003") => (RuleGroup::Stable, rules::flake8_executable::rules::ShebangMissingPython), + (Flake8Executable, "004") => (RuleGroup::Stable, rules::flake8_executable::rules::ShebangLeadingWhitespace), + (Flake8Executable, "005") => (RuleGroup::Stable, rules::flake8_executable::rules::ShebangNotFirstLine), // flake8-type-checking - (Flake8TypeChecking, "001") => (RuleGroup::Unspecified, rules::flake8_type_checking::rules::TypingOnlyFirstPartyImport), - (Flake8TypeChecking, "002") => (RuleGroup::Unspecified, rules::flake8_type_checking::rules::TypingOnlyThirdPartyImport), - (Flake8TypeChecking, "003") => (RuleGroup::Unspecified, rules::flake8_type_checking::rules::TypingOnlyStandardLibraryImport), - (Flake8TypeChecking, "004") => (RuleGroup::Unspecified, rules::flake8_type_checking::rules::RuntimeImportInTypeCheckingBlock), - (Flake8TypeChecking, "005") => (RuleGroup::Unspecified, rules::flake8_type_checking::rules::EmptyTypeCheckingBlock), + (Flake8TypeChecking, "001") => (RuleGroup::Stable, rules::flake8_type_checking::rules::TypingOnlyFirstPartyImport), + (Flake8TypeChecking, "002") => (RuleGroup::Stable, rules::flake8_type_checking::rules::TypingOnlyThirdPartyImport), + (Flake8TypeChecking, "003") => (RuleGroup::Stable, rules::flake8_type_checking::rules::TypingOnlyStandardLibraryImport), + (Flake8TypeChecking, "004") => (RuleGroup::Stable, rules::flake8_type_checking::rules::RuntimeImportInTypeCheckingBlock), + (Flake8TypeChecking, "005") => (RuleGroup::Stable, rules::flake8_type_checking::rules::EmptyTypeCheckingBlock), // tryceratops - (Tryceratops, "002") => (RuleGroup::Unspecified, rules::tryceratops::rules::RaiseVanillaClass), - (Tryceratops, "003") => (RuleGroup::Unspecified, rules::tryceratops::rules::RaiseVanillaArgs), - (Tryceratops, "004") => (RuleGroup::Unspecified, rules::tryceratops::rules::TypeCheckWithoutTypeError), - (Tryceratops, "200") => (RuleGroup::Unspecified, rules::tryceratops::rules::ReraiseNoCause), - (Tryceratops, "201") => (RuleGroup::Unspecified, rules::tryceratops::rules::VerboseRaise), - (Tryceratops, "300") => (RuleGroup::Unspecified, rules::tryceratops::rules::TryConsiderElse), - (Tryceratops, "301") => (RuleGroup::Unspecified, rules::tryceratops::rules::RaiseWithinTry), - (Tryceratops, "302") => (RuleGroup::Unspecified, rules::tryceratops::rules::UselessTryExcept), - (Tryceratops, "400") => (RuleGroup::Unspecified, rules::tryceratops::rules::ErrorInsteadOfException), - (Tryceratops, "401") => (RuleGroup::Unspecified, rules::tryceratops::rules::VerboseLogMessage), + (Tryceratops, "002") => (RuleGroup::Stable, rules::tryceratops::rules::RaiseVanillaClass), + (Tryceratops, "003") => (RuleGroup::Stable, rules::tryceratops::rules::RaiseVanillaArgs), + (Tryceratops, "004") => (RuleGroup::Stable, rules::tryceratops::rules::TypeCheckWithoutTypeError), + (Tryceratops, "200") => (RuleGroup::Stable, rules::tryceratops::rules::ReraiseNoCause), + (Tryceratops, "201") => (RuleGroup::Stable, rules::tryceratops::rules::VerboseRaise), + (Tryceratops, "300") => (RuleGroup::Stable, rules::tryceratops::rules::TryConsiderElse), + (Tryceratops, "301") => (RuleGroup::Stable, rules::tryceratops::rules::RaiseWithinTry), + (Tryceratops, "302") => (RuleGroup::Stable, rules::tryceratops::rules::UselessTryExcept), + (Tryceratops, "400") => (RuleGroup::Stable, rules::tryceratops::rules::ErrorInsteadOfException), + (Tryceratops, "401") => (RuleGroup::Stable, rules::tryceratops::rules::VerboseLogMessage), // flake8-use-pathlib - (Flake8UsePathlib, "100") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsPathAbspath), - (Flake8UsePathlib, "101") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsChmod), - (Flake8UsePathlib, "102") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsMkdir), - (Flake8UsePathlib, "103") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsMakedirs), - (Flake8UsePathlib, "104") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsRename), - (Flake8UsePathlib, "105") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsReplace), - (Flake8UsePathlib, "106") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsRmdir), - (Flake8UsePathlib, "107") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsRemove), - (Flake8UsePathlib, "108") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsUnlink), - (Flake8UsePathlib, "109") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsGetcwd), - (Flake8UsePathlib, "110") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsPathExists), - (Flake8UsePathlib, "111") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsPathExpanduser), - (Flake8UsePathlib, "112") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsPathIsdir), - (Flake8UsePathlib, "113") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsPathIsfile), - (Flake8UsePathlib, "114") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsPathIslink), - (Flake8UsePathlib, "115") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsReadlink), - (Flake8UsePathlib, "116") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsStat), - (Flake8UsePathlib, "117") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsPathIsabs), - (Flake8UsePathlib, "118") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsPathJoin), - (Flake8UsePathlib, "119") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsPathBasename), - (Flake8UsePathlib, "120") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsPathDirname), - (Flake8UsePathlib, "121") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsPathSamefile), - (Flake8UsePathlib, "122") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::OsPathSplitext), - (Flake8UsePathlib, "123") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::BuiltinOpen), - (Flake8UsePathlib, "124") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::violations::PyPath), - (Flake8UsePathlib, "201") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::rules::PathConstructorCurrentDirectory), - (Flake8UsePathlib, "202") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::rules::OsPathGetsize), - (Flake8UsePathlib, "202") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::rules::OsPathGetsize), - (Flake8UsePathlib, "203") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::rules::OsPathGetatime), - (Flake8UsePathlib, "204") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::rules::OsPathGetmtime), - (Flake8UsePathlib, "205") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::rules::OsPathGetctime), - (Flake8UsePathlib, "206") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::rules::OsSepSplit), - (Flake8UsePathlib, "207") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::rules::Glob), + (Flake8UsePathlib, "100") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathAbspath), + (Flake8UsePathlib, "101") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsChmod), + (Flake8UsePathlib, "102") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsMkdir), + (Flake8UsePathlib, "103") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsMakedirs), + (Flake8UsePathlib, "104") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsRename), + (Flake8UsePathlib, "105") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsReplace), + (Flake8UsePathlib, "106") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsRmdir), + (Flake8UsePathlib, "107") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsRemove), + (Flake8UsePathlib, "108") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsUnlink), + (Flake8UsePathlib, "109") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsGetcwd), + (Flake8UsePathlib, "110") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathExists), + (Flake8UsePathlib, "111") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathExpanduser), + (Flake8UsePathlib, "112") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathIsdir), + (Flake8UsePathlib, "113") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathIsfile), + (Flake8UsePathlib, "114") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathIslink), + (Flake8UsePathlib, "115") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsReadlink), + (Flake8UsePathlib, "116") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsStat), + (Flake8UsePathlib, "117") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathIsabs), + (Flake8UsePathlib, "118") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathJoin), + (Flake8UsePathlib, "119") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathBasename), + (Flake8UsePathlib, "120") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathDirname), + (Flake8UsePathlib, "121") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathSamefile), + (Flake8UsePathlib, "122") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathSplitext), + (Flake8UsePathlib, "123") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::BuiltinOpen), + (Flake8UsePathlib, "124") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::PyPath), + (Flake8UsePathlib, "201") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::PathConstructorCurrentDirectory), + (Flake8UsePathlib, "202") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathGetsize), + (Flake8UsePathlib, "202") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathGetsize), + (Flake8UsePathlib, "203") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathGetatime), + (Flake8UsePathlib, "204") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathGetmtime), + (Flake8UsePathlib, "205") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathGetctime), + (Flake8UsePathlib, "206") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsSepSplit), + (Flake8UsePathlib, "207") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::Glob), // flake8-logging-format - (Flake8LoggingFormat, "001") => (RuleGroup::Unspecified, rules::flake8_logging_format::violations::LoggingStringFormat), - (Flake8LoggingFormat, "002") => (RuleGroup::Unspecified, rules::flake8_logging_format::violations::LoggingPercentFormat), - (Flake8LoggingFormat, "003") => (RuleGroup::Unspecified, rules::flake8_logging_format::violations::LoggingStringConcat), - (Flake8LoggingFormat, "004") => (RuleGroup::Unspecified, rules::flake8_logging_format::violations::LoggingFString), - (Flake8LoggingFormat, "010") => (RuleGroup::Unspecified, rules::flake8_logging_format::violations::LoggingWarn), - (Flake8LoggingFormat, "101") => (RuleGroup::Unspecified, rules::flake8_logging_format::violations::LoggingExtraAttrClash), - (Flake8LoggingFormat, "201") => (RuleGroup::Unspecified, rules::flake8_logging_format::violations::LoggingExcInfo), - (Flake8LoggingFormat, "202") => (RuleGroup::Unspecified, rules::flake8_logging_format::violations::LoggingRedundantExcInfo), + (Flake8LoggingFormat, "001") => (RuleGroup::Stable, rules::flake8_logging_format::violations::LoggingStringFormat), + (Flake8LoggingFormat, "002") => (RuleGroup::Stable, rules::flake8_logging_format::violations::LoggingPercentFormat), + (Flake8LoggingFormat, "003") => (RuleGroup::Stable, rules::flake8_logging_format::violations::LoggingStringConcat), + (Flake8LoggingFormat, "004") => (RuleGroup::Stable, rules::flake8_logging_format::violations::LoggingFString), + (Flake8LoggingFormat, "010") => (RuleGroup::Stable, rules::flake8_logging_format::violations::LoggingWarn), + (Flake8LoggingFormat, "101") => (RuleGroup::Stable, rules::flake8_logging_format::violations::LoggingExtraAttrClash), + (Flake8LoggingFormat, "201") => (RuleGroup::Stable, rules::flake8_logging_format::violations::LoggingExcInfo), + (Flake8LoggingFormat, "202") => (RuleGroup::Stable, rules::flake8_logging_format::violations::LoggingRedundantExcInfo), // flake8-raise - (Flake8Raise, "102") => (RuleGroup::Unspecified, rules::flake8_raise::rules::UnnecessaryParenOnRaiseException), + (Flake8Raise, "102") => (RuleGroup::Stable, rules::flake8_raise::rules::UnnecessaryParenOnRaiseException), // flake8-self - (Flake8Self, "001") => (RuleGroup::Unspecified, rules::flake8_self::rules::PrivateMemberAccess), + (Flake8Self, "001") => (RuleGroup::Stable, rules::flake8_self::rules::PrivateMemberAccess), // numpy - (Numpy, "001") => (RuleGroup::Unspecified, rules::numpy::rules::NumpyDeprecatedTypeAlias), - (Numpy, "002") => (RuleGroup::Unspecified, rules::numpy::rules::NumpyLegacyRandom), - (Numpy, "003") => (RuleGroup::Unspecified, rules::numpy::rules::NumpyDeprecatedFunction), + (Numpy, "001") => (RuleGroup::Stable, rules::numpy::rules::NumpyDeprecatedTypeAlias), + (Numpy, "002") => (RuleGroup::Stable, rules::numpy::rules::NumpyLegacyRandom), + (Numpy, "003") => (RuleGroup::Stable, rules::numpy::rules::NumpyDeprecatedFunction), // ruff - (Ruff, "001") => (RuleGroup::Unspecified, rules::ruff::rules::AmbiguousUnicodeCharacterString), - (Ruff, "002") => (RuleGroup::Unspecified, rules::ruff::rules::AmbiguousUnicodeCharacterDocstring), - (Ruff, "003") => (RuleGroup::Unspecified, rules::ruff::rules::AmbiguousUnicodeCharacterComment), - (Ruff, "005") => (RuleGroup::Unspecified, rules::ruff::rules::CollectionLiteralConcatenation), - (Ruff, "006") => (RuleGroup::Unspecified, rules::ruff::rules::AsyncioDanglingTask), - (Ruff, "007") => (RuleGroup::Unspecified, rules::ruff::rules::PairwiseOverZipped), - (Ruff, "008") => (RuleGroup::Unspecified, rules::ruff::rules::MutableDataclassDefault), - (Ruff, "009") => (RuleGroup::Unspecified, rules::ruff::rules::FunctionCallInDataclassDefaultArgument), - (Ruff, "010") => (RuleGroup::Unspecified, rules::ruff::rules::ExplicitFStringTypeConversion), - (Ruff, "011") => (RuleGroup::Unspecified, rules::ruff::rules::StaticKeyDictComprehension), - (Ruff, "012") => (RuleGroup::Unspecified, rules::ruff::rules::MutableClassDefault), - (Ruff, "013") => (RuleGroup::Unspecified, rules::ruff::rules::ImplicitOptional), + (Ruff, "001") => (RuleGroup::Stable, rules::ruff::rules::AmbiguousUnicodeCharacterString), + (Ruff, "002") => (RuleGroup::Stable, rules::ruff::rules::AmbiguousUnicodeCharacterDocstring), + (Ruff, "003") => (RuleGroup::Stable, rules::ruff::rules::AmbiguousUnicodeCharacterComment), + (Ruff, "005") => (RuleGroup::Stable, rules::ruff::rules::CollectionLiteralConcatenation), + (Ruff, "006") => (RuleGroup::Stable, rules::ruff::rules::AsyncioDanglingTask), + (Ruff, "007") => (RuleGroup::Stable, rules::ruff::rules::PairwiseOverZipped), + (Ruff, "008") => (RuleGroup::Stable, rules::ruff::rules::MutableDataclassDefault), + (Ruff, "009") => (RuleGroup::Stable, rules::ruff::rules::FunctionCallInDataclassDefaultArgument), + (Ruff, "010") => (RuleGroup::Stable, rules::ruff::rules::ExplicitFStringTypeConversion), + (Ruff, "011") => (RuleGroup::Stable, rules::ruff::rules::StaticKeyDictComprehension), + (Ruff, "012") => (RuleGroup::Stable, rules::ruff::rules::MutableClassDefault), + (Ruff, "013") => (RuleGroup::Stable, rules::ruff::rules::ImplicitOptional), #[cfg(feature = "unreachable-code")] // When removing this feature gate, also update rules_selector.rs #[allow(deprecated)] (Ruff, "014") => (RuleGroup::Nursery, rules::ruff::rules::UnreachableCode), - (Ruff, "015") => (RuleGroup::Unspecified, rules::ruff::rules::UnnecessaryIterableAllocationForFirstElement), - (Ruff, "016") => (RuleGroup::Unspecified, rules::ruff::rules::InvalidIndexType), + (Ruff, "015") => (RuleGroup::Stable, rules::ruff::rules::UnnecessaryIterableAllocationForFirstElement), + (Ruff, "016") => (RuleGroup::Stable, rules::ruff::rules::InvalidIndexType), #[allow(deprecated)] (Ruff, "017") => (RuleGroup::Nursery, rules::ruff::rules::QuadraticListSummation), - (Ruff, "100") => (RuleGroup::Unspecified, rules::ruff::rules::UnusedNOQA), - (Ruff, "200") => (RuleGroup::Unspecified, rules::ruff::rules::InvalidPyprojectToml), + (Ruff, "018") => (RuleGroup::Preview, rules::ruff::rules::AssignmentInAssert), + (Ruff, "019") => (RuleGroup::Preview, rules::ruff::rules::UnnecessaryKeyCheck), + (Ruff, "100") => (RuleGroup::Stable, rules::ruff::rules::UnusedNOQA), + (Ruff, "200") => (RuleGroup::Stable, rules::ruff::rules::InvalidPyprojectToml), // flake8-django - (Flake8Django, "001") => (RuleGroup::Unspecified, rules::flake8_django::rules::DjangoNullableModelStringField), - (Flake8Django, "003") => (RuleGroup::Unspecified, rules::flake8_django::rules::DjangoLocalsInRenderFunction), - (Flake8Django, "006") => (RuleGroup::Unspecified, rules::flake8_django::rules::DjangoExcludeWithModelForm), - (Flake8Django, "007") => (RuleGroup::Unspecified, rules::flake8_django::rules::DjangoAllWithModelForm), - (Flake8Django, "008") => (RuleGroup::Unspecified, rules::flake8_django::rules::DjangoModelWithoutDunderStr), - (Flake8Django, "012") => (RuleGroup::Unspecified, rules::flake8_django::rules::DjangoUnorderedBodyContentInModel), - (Flake8Django, "013") => (RuleGroup::Unspecified, rules::flake8_django::rules::DjangoNonLeadingReceiverDecorator), + (Flake8Django, "001") => (RuleGroup::Stable, rules::flake8_django::rules::DjangoNullableModelStringField), + (Flake8Django, "003") => (RuleGroup::Stable, rules::flake8_django::rules::DjangoLocalsInRenderFunction), + (Flake8Django, "006") => (RuleGroup::Stable, rules::flake8_django::rules::DjangoExcludeWithModelForm), + (Flake8Django, "007") => (RuleGroup::Stable, rules::flake8_django::rules::DjangoAllWithModelForm), + (Flake8Django, "008") => (RuleGroup::Stable, rules::flake8_django::rules::DjangoModelWithoutDunderStr), + (Flake8Django, "012") => (RuleGroup::Stable, rules::flake8_django::rules::DjangoUnorderedBodyContentInModel), + (Flake8Django, "013") => (RuleGroup::Stable, rules::flake8_django::rules::DjangoNonLeadingReceiverDecorator), // flynt - // Reserved: (Flynt, "001") => (RuleGroup::Unspecified, Rule: :StringConcatenationToFString), - (Flynt, "002") => (RuleGroup::Unspecified, rules::flynt::rules::StaticJoinToFString), + // Reserved: (Flynt, "001") => (RuleGroup::Stable, Rule: :StringConcatenationToFString), + (Flynt, "002") => (RuleGroup::Stable, rules::flynt::rules::StaticJoinToFString), // flake8-todos - (Flake8Todos, "001") => (RuleGroup::Unspecified, rules::flake8_todos::rules::InvalidTodoTag), - (Flake8Todos, "002") => (RuleGroup::Unspecified, rules::flake8_todos::rules::MissingTodoAuthor), - (Flake8Todos, "003") => (RuleGroup::Unspecified, rules::flake8_todos::rules::MissingTodoLink), - (Flake8Todos, "004") => (RuleGroup::Unspecified, rules::flake8_todos::rules::MissingTodoColon), - (Flake8Todos, "005") => (RuleGroup::Unspecified, rules::flake8_todos::rules::MissingTodoDescription), - (Flake8Todos, "006") => (RuleGroup::Unspecified, rules::flake8_todos::rules::InvalidTodoCapitalization), - (Flake8Todos, "007") => (RuleGroup::Unspecified, rules::flake8_todos::rules::MissingSpaceAfterTodoColon), + (Flake8Todos, "001") => (RuleGroup::Stable, rules::flake8_todos::rules::InvalidTodoTag), + (Flake8Todos, "002") => (RuleGroup::Stable, rules::flake8_todos::rules::MissingTodoAuthor), + (Flake8Todos, "003") => (RuleGroup::Stable, rules::flake8_todos::rules::MissingTodoLink), + (Flake8Todos, "004") => (RuleGroup::Stable, rules::flake8_todos::rules::MissingTodoColon), + (Flake8Todos, "005") => (RuleGroup::Stable, rules::flake8_todos::rules::MissingTodoDescription), + (Flake8Todos, "006") => (RuleGroup::Stable, rules::flake8_todos::rules::InvalidTodoCapitalization), + (Flake8Todos, "007") => (RuleGroup::Stable, rules::flake8_todos::rules::MissingSpaceAfterTodoColon), // airflow - (Airflow, "001") => (RuleGroup::Unspecified, rules::airflow::rules::AirflowVariableNameTaskIdMismatch), + (Airflow, "001") => (RuleGroup::Stable, rules::airflow::rules::AirflowVariableNameTaskIdMismatch), // perflint - (Perflint, "101") => (RuleGroup::Unspecified, rules::perflint::rules::UnnecessaryListCast), - (Perflint, "102") => (RuleGroup::Unspecified, rules::perflint::rules::IncorrectDictIterator), - (Perflint, "203") => (RuleGroup::Unspecified, rules::perflint::rules::TryExceptInLoop), - (Perflint, "401") => (RuleGroup::Unspecified, rules::perflint::rules::ManualListComprehension), - (Perflint, "402") => (RuleGroup::Unspecified, rules::perflint::rules::ManualListCopy), + (Perflint, "101") => (RuleGroup::Stable, rules::perflint::rules::UnnecessaryListCast), + (Perflint, "102") => (RuleGroup::Stable, rules::perflint::rules::IncorrectDictIterator), + (Perflint, "203") => (RuleGroup::Stable, rules::perflint::rules::TryExceptInLoop), + (Perflint, "401") => (RuleGroup::Stable, rules::perflint::rules::ManualListComprehension), + (Perflint, "402") => (RuleGroup::Stable, rules::perflint::rules::ManualListCopy), (Perflint, "403") => (RuleGroup::Preview, rules::perflint::rules::ManualDictComprehension), // flake8-fixme - (Flake8Fixme, "001") => (RuleGroup::Unspecified, rules::flake8_fixme::rules::LineContainsFixme), - (Flake8Fixme, "002") => (RuleGroup::Unspecified, rules::flake8_fixme::rules::LineContainsTodo), - (Flake8Fixme, "003") => (RuleGroup::Unspecified, rules::flake8_fixme::rules::LineContainsXxx), - (Flake8Fixme, "004") => (RuleGroup::Unspecified, rules::flake8_fixme::rules::LineContainsHack), + (Flake8Fixme, "001") => (RuleGroup::Stable, rules::flake8_fixme::rules::LineContainsFixme), + (Flake8Fixme, "002") => (RuleGroup::Stable, rules::flake8_fixme::rules::LineContainsTodo), + (Flake8Fixme, "003") => (RuleGroup::Stable, rules::flake8_fixme::rules::LineContainsXxx), + (Flake8Fixme, "004") => (RuleGroup::Stable, rules::flake8_fixme::rules::LineContainsHack), // flake8-slots - (Flake8Slots, "000") => (RuleGroup::Unspecified, rules::flake8_slots::rules::NoSlotsInStrSubclass), - (Flake8Slots, "001") => (RuleGroup::Unspecified, rules::flake8_slots::rules::NoSlotsInTupleSubclass), - (Flake8Slots, "002") => (RuleGroup::Unspecified, rules::flake8_slots::rules::NoSlotsInNamedtupleSubclass), + (Flake8Slots, "000") => (RuleGroup::Stable, rules::flake8_slots::rules::NoSlotsInStrSubclass), + (Flake8Slots, "001") => (RuleGroup::Stable, rules::flake8_slots::rules::NoSlotsInTupleSubclass), + (Flake8Slots, "002") => (RuleGroup::Stable, rules::flake8_slots::rules::NoSlotsInNamedtupleSubclass), // refurb + (Refurb, "101") => (RuleGroup::Preview, rules::refurb::rules::ReadWholeFile), (Refurb, "105") => (RuleGroup::Preview, rules::refurb::rules::PrintEmptyString), #[allow(deprecated)] (Refurb, "113") => (RuleGroup::Nursery, rules::refurb::rules::RepeatedAppend), @@ -926,6 +937,8 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Refurb, "140") => (RuleGroup::Preview, rules::refurb::rules::ReimplementedStarmap), (Refurb, "145") => (RuleGroup::Preview, rules::refurb::rules::SliceCopy), (Refurb, "148") => (RuleGroup::Preview, rules::refurb::rules::UnnecessaryEnumerate), + (Refurb, "171") => (RuleGroup::Preview, rules::refurb::rules::SingleItemMembershipTest), + (Refurb, "177") => (RuleGroup::Preview, rules::refurb::rules::ImplicitCwd), // flake8-logging (Flake8Logging, "001") => (RuleGroup::Preview, rules::flake8_logging::rules::DirectLoggerInstantiation), diff --git a/crates/ruff_linter/src/cst/matchers.rs b/crates/ruff_linter/src/cst/matchers.rs index 70cc4b3aa351d..fac3be1e41010 100644 --- a/crates/ruff_linter/src/cst/matchers.rs +++ b/crates/ruff_linter/src/cst/matchers.rs @@ -1,4 +1,4 @@ -use crate::autofix::codemods::CodegenStylist; +use crate::fix::codemods::CodegenStylist; use anyhow::{bail, Result}; use libcst_native::{ Arg, Attribute, Call, Comparison, CompoundStatement, Dict, Expression, FunctionDef, diff --git a/crates/ruff_linter/src/directives.rs b/crates/ruff_linter/src/directives.rs index 60f8c69b78651..87095f9ac65a7 100644 --- a/crates/ruff_linter/src/directives.rs +++ b/crates/ruff_linter/src/directives.rs @@ -1,5 +1,6 @@ //! Extract `# noqa`, `# isort: skip`, and `# TODO` directives from tokenized source. +use std::iter::Peekable; use std::str::FromStr; use bitflags::bitflags; @@ -85,6 +86,39 @@ pub fn extract_directives( } } +struct SortedMergeIter +where + L: Iterator, + R: Iterator, +{ + left: Peekable, + right: Peekable, +} + +impl Iterator for SortedMergeIter +where + L: Iterator, + R: Iterator, + Item: Ranged, +{ + type Item = Item; + + fn next(&mut self) -> Option { + match (self.left.peek(), self.right.peek()) { + (Some(left), Some(right)) => { + if left.start() <= right.start() { + Some(self.left.next().unwrap()) + } else { + Some(self.right.next().unwrap()) + } + } + (Some(_), None) => Some(self.left.next().unwrap()), + (None, Some(_)) => Some(self.right.next().unwrap()), + (None, None) => None, + } + } +} + /// Extract a mapping from logical line to noqa line. fn extract_noqa_line_for(lxr: &[LexResult], locator: &Locator, indexer: &Indexer) -> NoqaMapping { let mut string_mappings = Vec::new(); @@ -113,6 +147,29 @@ fn extract_noqa_line_for(lxr: &[LexResult], locator: &Locator, indexer: &Indexer } } + // The capacity allocated here might be more than we need if there are + // nested f-strings. + let mut fstring_mappings = Vec::with_capacity(indexer.fstring_ranges().len()); + + // For nested f-strings, we expect `noqa` directives on the last line of the + // outermost f-string. The last f-string range will be used to skip over + // the inner f-strings. + let mut last_fstring_range: TextRange = TextRange::default(); + for fstring_range in indexer.fstring_ranges().values() { + if !locator.contains_line_break(*fstring_range) { + continue; + } + if last_fstring_range.contains_range(*fstring_range) { + continue; + } + let new_range = TextRange::new( + locator.line_start(fstring_range.start()), + fstring_range.end(), + ); + fstring_mappings.push(new_range); + last_fstring_range = new_range; + } + let mut continuation_mappings = Vec::new(); // For continuations, we expect `noqa` directives on the last line of the @@ -137,27 +194,20 @@ fn extract_noqa_line_for(lxr: &[LexResult], locator: &Locator, indexer: &Indexer } // Merge the mappings in sorted order - let mut mappings = - NoqaMapping::with_capacity(continuation_mappings.len() + string_mappings.len()); + let mut mappings = NoqaMapping::with_capacity( + continuation_mappings.len() + string_mappings.len() + fstring_mappings.len(), + ); - let mut continuation_mappings = continuation_mappings.into_iter().peekable(); - let mut string_mappings = string_mappings.into_iter().peekable(); - - while let (Some(continuation), Some(string)) = - (continuation_mappings.peek(), string_mappings.peek()) - { - if continuation.start() <= string.start() { - mappings.push_mapping(continuation_mappings.next().unwrap()); - } else { - mappings.push_mapping(string_mappings.next().unwrap()); - } - } - - for mapping in continuation_mappings { - mappings.push_mapping(mapping); - } + let string_mappings = SortedMergeIter { + left: fstring_mappings.into_iter().peekable(), + right: string_mappings.into_iter().peekable(), + }; + let all_mappings = SortedMergeIter { + left: string_mappings.peekable(), + right: continuation_mappings.into_iter().peekable(), + }; - for mapping in string_mappings { + for mapping in all_mappings { mappings.push_mapping(mapping); } @@ -429,6 +479,67 @@ ghi NoqaMapping::from_iter([TextRange::new(TextSize::from(6), TextSize::from(28))]) ); + let contents = "x = f'abc { +a + * + b +}' +y = 2 +"; + assert_eq!( + noqa_mappings(contents), + NoqaMapping::from_iter([TextRange::new(TextSize::from(0), TextSize::from(32))]) + ); + + let contents = "x = f'''abc +def +ghi +''' +y = 2 +z = x + 1"; + assert_eq!( + noqa_mappings(contents), + NoqaMapping::from_iter([TextRange::new(TextSize::from(0), TextSize::from(23))]) + ); + + let contents = "x = 1 +y = f'''abc +def +ghi +''' +z = 2"; + assert_eq!( + noqa_mappings(contents), + NoqaMapping::from_iter([TextRange::new(TextSize::from(6), TextSize::from(29))]) + ); + + let contents = "x = 1 +y = f'''abc +def +ghi +'''"; + assert_eq!( + noqa_mappings(contents), + NoqaMapping::from_iter([TextRange::new(TextSize::from(6), TextSize::from(29))]) + ); + + let contents = "x = 1 +y = f'''abc +def {f'''nested +fstring''' f'another nested'} +end''' +"; + assert_eq!( + noqa_mappings(contents), + NoqaMapping::from_iter([TextRange::new(TextSize::from(6), TextSize::from(70))]) + ); + + let contents = "x = 1 +y = f'normal' +z = f'another but {f'nested but {f'still single line'} nested'}' +"; + assert_eq!(noqa_mappings(contents), NoqaMapping::default()); + let contents = r"x = \ 1"; assert_eq!( diff --git a/crates/ruff_linter/src/autofix/codemods.rs b/crates/ruff_linter/src/fix/codemods.rs similarity index 100% rename from crates/ruff_linter/src/autofix/codemods.rs rename to crates/ruff_linter/src/fix/codemods.rs diff --git a/crates/ruff_linter/src/autofix/edits.rs b/crates/ruff_linter/src/fix/edits.rs similarity index 82% rename from crates/ruff_linter/src/autofix/edits.rs rename to crates/ruff_linter/src/fix/edits.rs index e11d8a53e6719..76257f7f5967b 100644 --- a/crates/ruff_linter/src/autofix/edits.rs +++ b/crates/ruff_linter/src/fix/edits.rs @@ -1,18 +1,20 @@ -//! Interface for generating autofix edits from higher-level actions (e.g., "remove an argument"). +//! Interface for generating fix edits from higher-level actions (e.g., "remove an argument"). use anyhow::{Context, Result}; use ruff_diagnostics::Edit; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{self as ast, Arguments, ExceptHandler, Stmt}; use ruff_python_codegen::Stylist; use ruff_python_index::Indexer; use ruff_python_trivia::{ has_leading_content, is_python_whitespace, PythonWhitespace, SimpleTokenKind, SimpleTokenizer, }; -use ruff_source_file::{Locator, NewlineWithTrailingNewline}; +use ruff_source_file::{Locator, NewlineWithTrailingNewline, UniversalNewlines}; use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; -use crate::autofix::codemods; +use crate::fix::codemods; +use crate::line_width::{IndentWidth, LineLength, LineWidthBuilder}; /// Return the `Fix` to use when deleting a `Stmt`. /// @@ -285,6 +287,75 @@ pub(crate) fn pad(content: String, range: TextRange, locator: &Locator) -> Strin ) } +/// Returns `true` if the fix fits within the maximum configured line length. +pub(crate) fn fits( + fix: &str, + node: AnyNodeRef, + locator: &Locator, + line_length: LineLength, + tab_size: IndentWidth, +) -> bool { + all_lines_fit(fix, node, locator, line_length.value() as usize, tab_size) +} + +/// Returns `true` if the fix fits within the maximum configured line length, or produces lines that +/// are shorter than the maximum length of the existing AST node. +pub(crate) fn fits_or_shrinks( + fix: &str, + node: AnyNodeRef, + locator: &Locator, + line_length: LineLength, + tab_size: IndentWidth, +) -> bool { + // Use the larger of the line length limit, or the longest line in the existing AST node. + let line_length = std::iter::once(line_length.value() as usize) + .chain( + locator + .slice(locator.lines_range(node.range())) + .universal_newlines() + .map(|line| LineWidthBuilder::new(tab_size).add_str(&line).get()), + ) + .max() + .unwrap_or(line_length.value() as usize); + + all_lines_fit(fix, node, locator, line_length, tab_size) +} + +/// Returns `true` if all lines in the fix are shorter than the given line length. +fn all_lines_fit( + fix: &str, + node: AnyNodeRef, + locator: &Locator, + line_length: usize, + tab_size: IndentWidth, +) -> bool { + let prefix = locator.slice(TextRange::new( + locator.line_start(node.start()), + node.start(), + )); + + // Ensure that all lines are shorter than the line length limit. + fix.universal_newlines().enumerate().all(|(idx, line)| { + // If `template` is a multiline string, `col_offset` should only be applied to the first + // line: + // ``` + // a = """{} -> offset = col_offset (= 4) + // {} -> offset = 0 + // """.format(0, 1) -> offset = 0 + // ``` + let measured_length = if idx == 0 { + LineWidthBuilder::new(tab_size) + .add_str(prefix) + .add_str(&line) + .get() + } else { + LineWidthBuilder::new(tab_size).add_str(&line).get() + }; + + measured_length <= line_length + }) +} + #[cfg(test)] mod tests { use anyhow::Result; @@ -293,7 +364,7 @@ mod tests { use ruff_source_file::Locator; use ruff_text_size::{Ranged, TextSize}; - use crate::autofix::edits::{next_stmt_break, trailing_semicolon}; + use crate::fix::edits::{next_stmt_break, trailing_semicolon}; #[test] fn find_semicolon() -> Result<()> { diff --git a/crates/ruff_linter/src/autofix/mod.rs b/crates/ruff_linter/src/fix/mod.rs similarity index 94% rename from crates/ruff_linter/src/autofix/mod.rs rename to crates/ruff_linter/src/fix/mod.rs index 6e33cb99a1ed5..069bf6e8f7244 100644 --- a/crates/ruff_linter/src/autofix/mod.rs +++ b/crates/ruff_linter/src/fix/mod.rs @@ -9,6 +9,7 @@ use ruff_source_file::Locator; use crate::linter::FixTable; use crate::registry::{AsRule, Rule}; +use crate::settings::types::UnsafeFixes; pub(crate) mod codemods; pub(crate) mod edits; @@ -23,11 +24,22 @@ pub(crate) struct FixResult { pub(crate) source_map: SourceMap, } -/// Auto-fix errors in a file, and write the fixed source code to disk. -pub(crate) fn fix_file(diagnostics: &[Diagnostic], locator: &Locator) -> Option { +/// Fix errors in a file, and write the fixed source code to disk. +pub(crate) fn fix_file( + diagnostics: &[Diagnostic], + locator: &Locator, + unsafe_fixes: UnsafeFixes, +) -> Option { + let required_applicability = unsafe_fixes.required_applicability(); + let mut with_fixes = diagnostics .iter() - .filter(|diag| diag.fix.is_some()) + .filter(|diagnostic| { + diagnostic + .fix + .as_ref() + .map_or(false, |fix| fix.applies(required_applicability)) + }) .peekable(); if with_fixes.peek().is_none() { @@ -141,7 +153,7 @@ mod tests { use ruff_diagnostics::{Diagnostic, Edit, Fix, SourceMarker}; use ruff_source_file::Locator; - use crate::autofix::{apply_fixes, FixResult}; + use crate::fix::{apply_fixes, FixResult}; use crate::rules::pycodestyle::rules::MissingNewlineAtEndOfFile; #[allow(deprecated)] @@ -151,7 +163,7 @@ mod tests { // The choice of rule here is arbitrary. kind: MissingNewlineAtEndOfFile.into(), range: edit.range(), - fix: Some(Fix::unspecified(edit)), + fix: Some(Fix::safe_edit(edit)), parent: None, }) .collect() diff --git a/crates/ruff_linter/src/autofix/snippet.rs b/crates/ruff_linter/src/fix/snippet.rs similarity index 100% rename from crates/ruff_linter/src/autofix/snippet.rs rename to crates/ruff_linter/src/fix/snippet.rs diff --git a/crates/ruff_linter/src/importer/mod.rs b/crates/ruff_linter/src/importer/mod.rs index c01884db56399..5241aa4f4c8d3 100644 --- a/crates/ruff_linter/src/importer/mod.rs +++ b/crates/ruff_linter/src/importer/mod.rs @@ -17,9 +17,9 @@ use ruff_python_semantic::SemanticModel; use ruff_python_trivia::textwrap::indent; use ruff_source_file::Locator; -use crate::autofix; -use crate::autofix::codemods::CodegenStylist; use crate::cst::matchers::{match_aliases, match_import_from, match_statement}; +use crate::fix; +use crate::fix::codemods::CodegenStylist; use crate::importer::insertion::Insertion; mod insertion; @@ -91,7 +91,7 @@ impl<'a> Importer<'a> { at: TextSize, ) -> Result { // Generate the modified import statement. - let content = autofix::codemods::retain_imports( + let content = fix::codemods::retain_imports( &import.names, import.statement, self.locator, @@ -124,7 +124,7 @@ impl<'a> Importer<'a> { source_type: PySourceType, ) -> Result { // Generate the modified import statement. - let content = autofix::codemods::retain_imports( + let content = fix::codemods::retain_imports( &import.names, import.statement, self.locator, diff --git a/crates/ruff_linter/src/lib.rs b/crates/ruff_linter/src/lib.rs index ee8f238879da8..857c7fadae5fc 100644 --- a/crates/ruff_linter/src/lib.rs +++ b/crates/ruff_linter/src/lib.rs @@ -14,7 +14,6 @@ pub use rules::pycodestyle::rules::{IOError, SyntaxError}; pub const VERSION: &str = env!("CARGO_PKG_VERSION"); -mod autofix; mod checkers; pub mod codes; mod comments; @@ -22,6 +21,7 @@ mod cst; pub mod directives; mod doc_lines; mod docstrings; +mod fix; pub mod fs; mod importer; mod lex; diff --git a/crates/ruff_linter/src/line_width.rs b/crates/ruff_linter/src/line_width.rs index 5b869751fb039..06fe47c94464b 100644 --- a/crates/ruff_linter/src/line_width.rs +++ b/crates/ruff_linter/src/line_width.rs @@ -1,19 +1,23 @@ -use ruff_cache::{CacheKey, CacheKeyHasher}; -use serde::{Deserialize, Serialize}; use std::error::Error; use std::hash::Hasher; use std::num::{NonZeroU16, NonZeroU8, ParseIntError}; use std::str::FromStr; + +use serde::{Deserialize, Serialize}; use unicode_width::UnicodeWidthChar; +use ruff_cache::{CacheKey, CacheKeyHasher}; use ruff_macros::CacheKey; +use ruff_text_size::TextSize; /// The length of a line of text that is considered too long. /// /// The allowed range of values is 1..=320 #[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct LineLength(NonZeroU16); +pub struct LineLength( + #[cfg_attr(feature = "schemars", schemars(range(min = 1, max = 320)))] NonZeroU16, +); impl LineLength { /// Maximum allowed value for a valid [`LineLength`] @@ -23,6 +27,10 @@ impl LineLength { pub fn value(&self) -> u16 { self.0.get() } + + pub fn text_len(&self) -> TextSize { + TextSize::from(u32::from(self.value())) + } } impl Default for LineLength { @@ -121,12 +129,12 @@ pub struct LineWidthBuilder { /// This is used to calculate the width of tabs. column: usize, /// The tab size to use when calculating the width of tabs. - tab_size: TabSize, + tab_size: IndentWidth, } impl Default for LineWidthBuilder { fn default() -> Self { - Self::new(TabSize::default()) + Self::new(IndentWidth::default()) } } @@ -156,7 +164,7 @@ impl LineWidthBuilder { } /// Creates a new `LineWidth` with the given tab size. - pub fn new(tab_size: TabSize) -> Self { + pub fn new(tab_size: IndentWidth) -> Self { LineWidthBuilder { width: 0, column: 0, @@ -226,22 +234,28 @@ impl PartialOrd for LineWidthBuilder { /// The size of a tab. #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, CacheKey)] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct TabSize(NonZeroU8); +pub struct IndentWidth(NonZeroU8); -impl TabSize { +impl IndentWidth { pub(crate) fn as_usize(self) -> usize { self.0.get() as usize } } -impl Default for TabSize { +impl Default for IndentWidth { fn default() -> Self { Self(NonZeroU8::new(4).unwrap()) } } -impl From for TabSize { +impl From for IndentWidth { fn from(tab_size: NonZeroU8) -> Self { Self(tab_size) } } + +impl From for NonZeroU8 { + fn from(value: IndentWidth) -> Self { + value.0 + } +} diff --git a/crates/ruff_linter/src/linter.rs b/crates/ruff_linter/src/linter.rs index f07e3d3f0781a..f12690345ce8f 100644 --- a/crates/ruff_linter/src/linter.rs +++ b/crates/ruff_linter/src/linter.rs @@ -8,7 +8,7 @@ use itertools::Itertools; use log::error; use rustc_hash::FxHashMap; -use ruff_diagnostics::Diagnostic; +use ruff_diagnostics::{Applicability, Diagnostic}; use ruff_python_ast::imports::ImportMap; use ruff_python_ast::PySourceType; use ruff_python_codegen::Stylist; @@ -18,7 +18,6 @@ use ruff_python_parser::{AsMode, ParseError}; use ruff_source_file::{Locator, SourceFileBuilder}; use ruff_text_size::Ranged; -use crate::autofix::{fix_file, FixResult}; use crate::checkers::ast::check_ast; use crate::checkers::filesystem::check_file_path; use crate::checkers::imports::check_imports; @@ -27,11 +26,13 @@ use crate::checkers::physical_lines::check_physical_lines; use crate::checkers::tokens::check_tokens; use crate::directives::Directives; use crate::doc_lines::{doc_lines_from_ast, doc_lines_from_tokens}; +use crate::fix::{fix_file, FixResult}; use crate::logging::DisplayParseError; use crate::message::Message; use crate::noqa::add_noqa; use crate::registry::{AsRule, Rule}; use crate::rules::pycodestyle; +use crate::settings::types::UnsafeFixes; use crate::settings::{flags, LinterSettings}; use crate::source_kind::SourceKind; use crate::{directives, fs}; @@ -143,6 +144,7 @@ pub fn check_path( if use_ast || use_imports || use_doc_lines { match ruff_python_parser::parse_program_tokens( tokens, + source_kind.source_code(), &path.to_string_lossy(), source_type.is_ipynb(), ) { @@ -258,6 +260,36 @@ pub fn check_path( } } + // Remove fixes for any rules marked as unfixable. + for diagnostic in &mut diagnostics { + if !settings.rules.should_fix(diagnostic.kind.rule()) { + diagnostic.fix = None; + } + } + + // Update fix applicability to account for overrides + if !settings.extend_safe_fixes.is_empty() || !settings.extend_unsafe_fixes.is_empty() { + for diagnostic in &mut diagnostics { + if let Some(fix) = diagnostic.fix.take() { + // Enforce demotions over promotions so if someone puts a rule in both we are conservative + if fix.applicability().is_safe() + && settings + .extend_unsafe_fixes + .contains(diagnostic.kind.rule()) + { + diagnostic.set_fix(fix.with_applicability(Applicability::Unsafe)); + } else if fix.applicability().is_unsafe() + && settings.extend_safe_fixes.contains(diagnostic.kind.rule()) + { + diagnostic.set_fix(fix.with_applicability(Applicability::Safe)); + } else { + // Retain the existing fix (will be dropped from `.take()` otherwise) + diagnostic.set_fix(fix); + } + } + } + } + LinterResult::new((diagnostics, imports), error) } @@ -412,12 +444,14 @@ fn diagnostics_to_messages( .collect() } -/// Generate `Diagnostic`s from source code content, iteratively autofixing +/// Generate `Diagnostic`s from source code content, iteratively fixing /// until stable. +#[allow(clippy::too_many_arguments)] pub fn lint_fix<'a>( path: &Path, package: Option<&Path>, noqa: flags::Noqa, + unsafe_fixes: UnsafeFixes, settings: &LinterSettings, source_kind: &'a SourceKind, source_type: PySourceType, @@ -433,7 +467,7 @@ pub fn lint_fix<'a>( // Track whether the _initial_ source code was parseable. let mut parseable = false; - // Continuously autofix until the source code stabilizes. + // Continuously fix until the source code stabilizes. loop { // Tokenize once. let tokens: Vec = @@ -467,7 +501,7 @@ pub fn lint_fix<'a>( &directives, settings, noqa, - source_kind, + &transformed, source_type, ); @@ -478,22 +512,22 @@ pub fn lint_fix<'a>( // longer parseable on a subsequent pass, then we've introduced a // syntax error. Return the original code. if parseable && result.error.is_some() { - report_autofix_syntax_error( + report_fix_syntax_error( path, transformed.source_code(), &result.error.unwrap(), fixed.keys().copied(), ); - return Err(anyhow!("Autofix introduced a syntax error")); + return Err(anyhow!("Fix introduced a syntax error")); } } - // Apply autofix. + // Apply fix. if let Some(FixResult { code: fixed_contents, fixes: applied, source_map, - }) = fix_file(&result.data.0, &locator) + }) = fix_file(&result.data.0, &locator, unsafe_fixes) { if iterations < MAX_ITERATIONS { // Count the number of fixed errors. @@ -569,7 +603,7 @@ This indicates a bug in Ruff. If you could open an issue at: } #[allow(clippy::print_stderr)] -fn report_autofix_syntax_error( +fn report_fix_syntax_error( path: &Path, transformed: &str, error: &ParseError, @@ -578,7 +612,7 @@ fn report_autofix_syntax_error( let codes = collect_rule_codes(rules); if cfg!(debug_assertions) { eprintln!( - "{}{} Autofix introduced a syntax error in `{}` with rule codes {}: {}\n---\n{}\n---", + "{}{} Fix introduced a syntax error in `{}` with rule codes {}: {}\n---\n{}\n---", "error".red().bold(), ":".bold(), fs::relativize_path(path), @@ -589,11 +623,11 @@ fn report_autofix_syntax_error( } else { eprintln!( r#" -{}{} Autofix introduced a syntax error. Reverting all changes. +{}{} Fix introduced a syntax error. Reverting all changes. This indicates a bug in Ruff. If you could open an issue at: - https://github.com/astral-sh/ruff/issues/new?title=%5BAutofix%20error%5D + https://github.com/astral-sh/ruff/issues/new?title=%5BFix%20error%5D ...quoting the contents of `{}`, the rule codes {}, along with the `pyproject.toml` settings and executed command, we'd be very appreciative! "#, diff --git a/crates/ruff_linter/src/logging.rs b/crates/ruff_linter/src/logging.rs index 6851680cfb0a7..d65acd9ad58f3 100644 --- a/crates/ruff_linter/src/logging.rs +++ b/crates/ruff_linter/src/logging.rs @@ -177,18 +177,15 @@ impl Display for DisplayParseError<'_> { f, "cell {cell}{colon}", cell = jupyter_index - .cell(source_location.row.get()) - .unwrap_or_default(), + .cell(source_location.row) + .unwrap_or(OneIndexed::MIN), colon = ":".cyan(), )?; SourceLocation { - row: OneIndexed::new( - jupyter_index - .cell_row(source_location.row.get()) - .unwrap_or(1) as usize, - ) - .unwrap(), + row: jupyter_index + .cell_row(source_location.row) + .unwrap_or(OneIndexed::MIN), column: source_location.column, } } else { diff --git a/crates/ruff_linter/src/message/diff.rs b/crates/ruff_linter/src/message/diff.rs index 645d0797f5bdb..6bfe8750c4a36 100644 --- a/crates/ruff_linter/src/message/diff.rs +++ b/crates/ruff_linter/src/message/diff.rs @@ -35,6 +35,7 @@ impl<'a> Diff<'a> { impl Display for Diff<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + // TODO(dhruvmanila): Add support for Notebook cells once it's user-facing let mut output = String::with_capacity(self.source_code.source_text().len()); let mut last_end = TextSize::default(); @@ -52,10 +53,10 @@ impl Display for Diff<'_> { let diff = TextDiff::from_lines(self.source_code.source_text(), &output); let message = match self.fix.applicability() { - Applicability::Automatic => "Fix", - Applicability::Suggested => "Suggested fix", - Applicability::Manual => "Possible fix", - Applicability::Unspecified => "Suggested fix", /* For backwards compatibility, unspecified fixes are 'suggested' */ + // TODO(zanieb): Adjust this messaging once it's user-facing + Applicability::Safe => "Fix", + Applicability::Unsafe => "Suggested fix", + Applicability::Display => "Possible fix", }; writeln!(f, "ℹ {}", message.blue())?; diff --git a/crates/ruff_linter/src/message/grouped.rs b/crates/ruff_linter/src/message/grouped.rs index 41e3f52cd118f..0445c1746193b 100644 --- a/crates/ruff_linter/src/message/grouped.rs +++ b/crates/ruff_linter/src/message/grouped.rs @@ -13,11 +13,13 @@ use crate::message::text::{MessageCodeFrame, RuleCodeAndBody}; use crate::message::{ group_messages_by_filename, Emitter, EmitterContext, Message, MessageWithLocation, }; +use crate::settings::types::UnsafeFixes; #[derive(Default)] pub struct GroupedEmitter { show_fix_status: bool, show_source: bool, + unsafe_fixes: UnsafeFixes, } impl GroupedEmitter { @@ -32,6 +34,12 @@ impl GroupedEmitter { self.show_source = show_source; self } + + #[must_use] + pub fn with_unsafe_fixes(mut self, unsafe_fixes: UnsafeFixes) -> Self { + self.unsafe_fixes = unsafe_fixes; + self + } } impl Emitter for GroupedEmitter { @@ -68,6 +76,7 @@ impl Emitter for GroupedEmitter { notebook_index: context.notebook_index(message.filename()), message, show_fix_status: self.show_fix_status, + unsafe_fixes: self.unsafe_fixes, show_source: self.show_source, row_length, column_length, @@ -89,6 +98,7 @@ impl Emitter for GroupedEmitter { struct DisplayGroupedMessage<'a> { message: MessageWithLocation<'a>, show_fix_status: bool, + unsafe_fixes: UnsafeFixes, show_source: bool, row_length: NonZeroUsize, column_length: NonZeroUsize, @@ -115,18 +125,18 @@ impl Display for DisplayGroupedMessage<'_> { f, "cell {cell}{sep}", cell = jupyter_index - .cell(start_location.row.get()) - .unwrap_or_default(), + .cell(start_location.row) + .unwrap_or(OneIndexed::MIN), sep = ":".cyan() )?; ( jupyter_index - .cell_row(start_location.row.get()) - .unwrap_or(1) as usize, - start_location.column.get(), + .cell_row(start_location.row) + .unwrap_or(OneIndexed::MIN), + start_location.column, ) } else { - (start_location.row.get(), start_location.column.get()) + (start_location.row, start_location.column) }; writeln!( @@ -138,7 +148,8 @@ impl Display for DisplayGroupedMessage<'_> { ), code_and_body = RuleCodeAndBody { message, - show_fix_status: self.show_fix_status + show_fix_status: self.show_fix_status, + unsafe_fixes: self.unsafe_fixes }, )?; @@ -196,6 +207,7 @@ mod tests { use crate::message::tests::{capture_emitter_output, create_messages}; use crate::message::GroupedEmitter; + use crate::settings::types::UnsafeFixes; #[test] fn default() { @@ -222,4 +234,15 @@ mod tests { assert_snapshot!(content); } + + #[test] + fn fix_status_unsafe() { + let mut emitter = GroupedEmitter::default() + .with_show_fix_status(true) + .with_show_source(true) + .with_unsafe_fixes(UnsafeFixes::Enabled); + let content = capture_emitter_output(&mut emitter, &create_messages()); + + assert_snapshot!(content); + } } diff --git a/crates/ruff_linter/src/message/json.rs b/crates/ruff_linter/src/message/json.rs index e1a2e3e36df98..7c3b9764f3831 100644 --- a/crates/ruff_linter/src/message/json.rs +++ b/crates/ruff_linter/src/message/json.rs @@ -5,7 +5,8 @@ use serde::{Serialize, Serializer}; use serde_json::{json, Value}; use ruff_diagnostics::Edit; -use ruff_source_file::SourceCode; +use ruff_notebook::NotebookIndex; +use ruff_source_file::{OneIndexed, SourceCode, SourceLocation}; use ruff_text_size::Ranged; use crate::message::{Emitter, EmitterContext, Message}; @@ -19,9 +20,9 @@ impl Emitter for JsonEmitter { &mut self, writer: &mut dyn Write, messages: &[Message], - _context: &EmitterContext, + context: &EmitterContext, ) -> anyhow::Result<()> { - serde_json::to_writer_pretty(writer, &ExpandedMessages { messages })?; + serde_json::to_writer_pretty(writer, &ExpandedMessages { messages, context })?; Ok(()) } @@ -29,6 +30,7 @@ impl Emitter for JsonEmitter { struct ExpandedMessages<'a> { messages: &'a [Message], + context: &'a EmitterContext<'a>, } impl Serialize for ExpandedMessages<'_> { @@ -39,7 +41,7 @@ impl Serialize for ExpandedMessages<'_> { let mut s = serializer.serialize_seq(Some(self.messages.len()))?; for message in self.messages { - let value = message_to_json_value(message); + let value = message_to_json_value(message, self.context); s.serialize_element(&value)?; } @@ -47,26 +49,40 @@ impl Serialize for ExpandedMessages<'_> { } } -pub(crate) fn message_to_json_value(message: &Message) -> Value { +pub(crate) fn message_to_json_value(message: &Message, context: &EmitterContext) -> Value { let source_code = message.file.to_source_code(); + let notebook_index = context.notebook_index(message.filename()); let fix = message.fix.as_ref().map(|fix| { json!({ "applicability": fix.applicability(), "message": message.kind.suggestion.as_deref(), - "edits": &ExpandedEdits { edits: fix.edits(), source_code: &source_code }, + "edits": &ExpandedEdits { edits: fix.edits(), source_code: &source_code, notebook_index }, }) }); - let start_location = source_code.source_location(message.start()); - let end_location = source_code.source_location(message.end()); - let noqa_location = source_code.source_location(message.noqa_offset); + let mut start_location = source_code.source_location(message.start()); + let mut end_location = source_code.source_location(message.end()); + let mut noqa_location = source_code.source_location(message.noqa_offset); + let mut notebook_cell_index = None; + + if let Some(notebook_index) = notebook_index { + notebook_cell_index = Some( + notebook_index + .cell(start_location.row) + .unwrap_or(OneIndexed::MIN), + ); + start_location = notebook_index.translate_location(&start_location); + end_location = notebook_index.translate_location(&end_location); + noqa_location = notebook_index.translate_location(&noqa_location); + } json!({ "code": message.kind.rule().noqa_code().to_string(), "url": message.kind.rule().url(), "message": message.kind.body, "fix": fix, + "cell": notebook_cell_index, "location": start_location, "end_location": end_location, "filename": message.filename(), @@ -77,6 +93,7 @@ pub(crate) fn message_to_json_value(message: &Message) -> Value { struct ExpandedEdits<'a> { edits: &'a [Edit], source_code: &'a SourceCode<'a, 'a>, + notebook_index: Option<&'a NotebookIndex>, } impl Serialize for ExpandedEdits<'_> { @@ -87,10 +104,57 @@ impl Serialize for ExpandedEdits<'_> { let mut s = serializer.serialize_seq(Some(self.edits.len()))?; for edit in self.edits { + let mut location = self.source_code.source_location(edit.start()); + let mut end_location = self.source_code.source_location(edit.end()); + + if let Some(notebook_index) = self.notebook_index { + // There exists a newline between each cell's source code in the + // concatenated source code in Ruff. This newline doesn't actually + // exists in the JSON source field. + // + // Now, certain edits may try to remove this newline, which means + // the edit will spill over to the first character of the next cell. + // If it does, we need to translate the end location to the last + // character of the previous cell. + match ( + notebook_index.cell(location.row), + notebook_index.cell(end_location.row), + ) { + (Some(start_cell), Some(end_cell)) if start_cell != end_cell => { + debug_assert_eq!(end_location.column.get(), 1); + + let prev_row = end_location.row.saturating_sub(1); + end_location = SourceLocation { + row: notebook_index.cell_row(prev_row).unwrap_or(OneIndexed::MIN), + column: self + .source_code + .source_location(self.source_code.line_end_exclusive(prev_row)) + .column, + }; + } + (Some(_), None) => { + debug_assert_eq!(end_location.column.get(), 1); + + let prev_row = end_location.row.saturating_sub(1); + end_location = SourceLocation { + row: notebook_index.cell_row(prev_row).unwrap_or(OneIndexed::MIN), + column: self + .source_code + .source_location(self.source_code.line_end_exclusive(prev_row)) + .column, + }; + } + _ => { + end_location = notebook_index.translate_location(&end_location); + } + } + location = notebook_index.translate_location(&location); + } + let value = json!({ "content": edit.content().unwrap_or_default(), - "location": self.source_code.source_location(edit.start()), - "end_location": self.source_code.source_location(edit.end()) + "location": location, + "end_location": end_location }); s.serialize_element(&value)?; @@ -104,7 +168,10 @@ impl Serialize for ExpandedEdits<'_> { mod tests { use insta::assert_snapshot; - use crate::message::tests::{capture_emitter_output, create_messages}; + use crate::message::tests::{ + capture_emitter_notebook_output, capture_emitter_output, create_messages, + create_notebook_messages, + }; use crate::message::JsonEmitter; #[test] @@ -114,4 +181,13 @@ mod tests { assert_snapshot!(content); } + + #[test] + fn notebook_output() { + let mut emitter = JsonEmitter; + let (messages, notebook_indexes) = create_notebook_messages(); + let content = capture_emitter_notebook_output(&mut emitter, &messages, ¬ebook_indexes); + + assert_snapshot!(content); + } } diff --git a/crates/ruff_linter/src/message/json_lines.rs b/crates/ruff_linter/src/message/json_lines.rs index 360e7ec6a71a7..25b8cc1d5b32b 100644 --- a/crates/ruff_linter/src/message/json_lines.rs +++ b/crates/ruff_linter/src/message/json_lines.rs @@ -11,11 +11,11 @@ impl Emitter for JsonLinesEmitter { &mut self, writer: &mut dyn Write, messages: &[Message], - _context: &EmitterContext, + context: &EmitterContext, ) -> anyhow::Result<()> { let mut w = writer; for message in messages { - serde_json::to_writer(&mut w, &message_to_json_value(message))?; + serde_json::to_writer(&mut w, &message_to_json_value(message, context))?; w.write_all(b"\n")?; } Ok(()) @@ -27,7 +27,10 @@ mod tests { use insta::assert_snapshot; use crate::message::json_lines::JsonLinesEmitter; - use crate::message::tests::{capture_emitter_output, create_messages}; + use crate::message::tests::{ + capture_emitter_notebook_output, capture_emitter_output, create_messages, + create_notebook_messages, + }; #[test] fn output() { @@ -36,4 +39,13 @@ mod tests { assert_snapshot!(content); } + + #[test] + fn notebook_output() { + let mut emitter = JsonLinesEmitter; + let (messages, notebook_indexes) = create_notebook_messages(); + let content = capture_emitter_notebook_output(&mut emitter, &messages, ¬ebook_indexes); + + assert_snapshot!(content); + } } diff --git a/crates/ruff_linter/src/message/mod.rs b/crates/ruff_linter/src/message/mod.rs index 67ba50df4eb30..0e5520b5a75ff 100644 --- a/crates/ruff_linter/src/message/mod.rs +++ b/crates/ruff_linter/src/message/mod.rs @@ -150,7 +150,8 @@ mod tests { use rustc_hash::FxHashMap; use ruff_diagnostics::{Diagnostic, DiagnosticKind, Edit, Fix}; - use ruff_source_file::SourceFileBuilder; + use ruff_notebook::NotebookIndex; + use ruff_source_file::{OneIndexed, SourceFileBuilder}; use ruff_text_size::{Ranged, TextRange, TextSize}; use crate::message::{Emitter, EmitterContext, Message}; @@ -178,7 +179,7 @@ def fibonacci(n): }, TextRange::new(TextSize::from(7), TextSize::from(9)), ) - .with_fix(Fix::suggested(Edit::range_deletion(TextRange::new( + .with_fix(Fix::unsafe_edit(Edit::range_deletion(TextRange::new( TextSize::from(0), TextSize::from(10), )))); @@ -193,7 +194,7 @@ def fibonacci(n): }, TextRange::new(TextSize::from(94), TextSize::from(95)), ) - .with_fix(Fix::suggested(Edit::deletion( + .with_fix(Fix::unsafe_edit(Edit::deletion( TextSize::from(94), TextSize::from(99), ))); @@ -221,6 +222,113 @@ def fibonacci(n): ] } + pub(super) fn create_notebook_messages() -> (Vec, FxHashMap) { + let notebook = r"# cell 1 +import os +# cell 2 +import math + +print('hello world') +# cell 3 +def foo(): + print() + x = 1 +"; + + let unused_import_os = Diagnostic::new( + DiagnosticKind { + name: "UnusedImport".to_string(), + body: "`os` imported but unused".to_string(), + suggestion: Some("Remove unused import: `os`".to_string()), + }, + TextRange::new(TextSize::from(16), TextSize::from(18)), + ) + .with_fix(Fix::safe_edit(Edit::range_deletion(TextRange::new( + TextSize::from(9), + TextSize::from(19), + )))); + + let unused_import_math = Diagnostic::new( + DiagnosticKind { + name: "UnusedImport".to_string(), + body: "`math` imported but unused".to_string(), + suggestion: Some("Remove unused import: `math`".to_string()), + }, + TextRange::new(TextSize::from(35), TextSize::from(39)), + ) + .with_fix(Fix::safe_edit(Edit::range_deletion(TextRange::new( + TextSize::from(28), + TextSize::from(40), + )))); + + let unused_variable = Diagnostic::new( + DiagnosticKind { + name: "UnusedVariable".to_string(), + body: "Local variable `x` is assigned to but never used".to_string(), + suggestion: Some("Remove assignment to unused variable `x`".to_string()), + }, + TextRange::new(TextSize::from(98), TextSize::from(99)), + ) + .with_fix(Fix::unsafe_edit(Edit::deletion( + TextSize::from(94), + TextSize::from(104), + ))); + + let notebook_source = SourceFileBuilder::new("notebook.ipynb", notebook).finish(); + + let mut notebook_indexes = FxHashMap::default(); + notebook_indexes.insert( + "notebook.ipynb".to_string(), + NotebookIndex::new( + vec![ + OneIndexed::from_zero_indexed(0), + OneIndexed::from_zero_indexed(0), + OneIndexed::from_zero_indexed(1), + OneIndexed::from_zero_indexed(1), + OneIndexed::from_zero_indexed(1), + OneIndexed::from_zero_indexed(1), + OneIndexed::from_zero_indexed(2), + OneIndexed::from_zero_indexed(2), + OneIndexed::from_zero_indexed(2), + OneIndexed::from_zero_indexed(2), + ], + vec![ + OneIndexed::from_zero_indexed(0), + OneIndexed::from_zero_indexed(1), + OneIndexed::from_zero_indexed(0), + OneIndexed::from_zero_indexed(1), + OneIndexed::from_zero_indexed(2), + OneIndexed::from_zero_indexed(3), + OneIndexed::from_zero_indexed(0), + OneIndexed::from_zero_indexed(1), + OneIndexed::from_zero_indexed(2), + OneIndexed::from_zero_indexed(3), + ], + ), + ); + + let unused_import_os_start = unused_import_os.start(); + let unused_import_math_start = unused_import_math.start(); + let unused_variable_start = unused_variable.start(); + + ( + vec![ + Message::from_diagnostic( + unused_import_os, + notebook_source.clone(), + unused_import_os_start, + ), + Message::from_diagnostic( + unused_import_math, + notebook_source.clone(), + unused_import_math_start, + ), + Message::from_diagnostic(unused_variable, notebook_source, unused_variable_start), + ], + notebook_indexes, + ) + } + pub(super) fn capture_emitter_output( emitter: &mut dyn Emitter, messages: &[Message], @@ -232,4 +340,16 @@ def fibonacci(n): String::from_utf8(output).expect("Output to be valid UTF-8") } + + pub(super) fn capture_emitter_notebook_output( + emitter: &mut dyn Emitter, + messages: &[Message], + notebook_indexes: &FxHashMap, + ) -> String { + let context = EmitterContext::new(notebook_indexes); + let mut output: Vec = Vec::new(); + emitter.emit(&mut output, messages, &context).unwrap(); + + String::from_utf8(output).expect("Output to be valid UTF-8") + } } diff --git a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__grouped__tests__fix_status.snap b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__grouped__tests__fix_status.snap index 453cf1eda49e2..37344ef4884d3 100644 --- a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__grouped__tests__fix_status.snap +++ b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__grouped__tests__fix_status.snap @@ -3,14 +3,14 @@ source: crates/ruff_linter/src/message/grouped.rs expression: content --- fib.py: - 1:8 F401 [*] `os` imported but unused + 1:8 F401 `os` imported but unused | 1 | import os | ^^ F401 | = help: Remove unused import: `os` - 6:5 F841 [*] Local variable `x` is assigned to but never used + 6:5 F841 Local variable `x` is assigned to but never used | 4 | def fibonacci(n): 5 | """Compute the nth number in the Fibonacci sequence.""" diff --git a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__grouped__tests__fix_status_unsafe.snap b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__grouped__tests__fix_status_unsafe.snap new file mode 100644 index 0000000000000..453cf1eda49e2 --- /dev/null +++ b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__grouped__tests__fix_status_unsafe.snap @@ -0,0 +1,31 @@ +--- +source: crates/ruff_linter/src/message/grouped.rs +expression: content +--- +fib.py: + 1:8 F401 [*] `os` imported but unused + | + 1 | import os + | ^^ F401 + | + = help: Remove unused import: `os` + + 6:5 F841 [*] Local variable `x` is assigned to but never used + | + 4 | def fibonacci(n): + 5 | """Compute the nth number in the Fibonacci sequence.""" + 6 | x = 1 + | ^ F841 + 7 | if n == 0: + 8 | return 0 + | + = help: Remove assignment to unused variable `x` + +undef.py: + 1:4 F821 Undefined name `a` + | + 1 | if a == 1: pass + | ^ F821 + | + + diff --git a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__json__tests__notebook_output.snap b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__json__tests__notebook_output.snap new file mode 100644 index 0000000000000..7403245cc13aa --- /dev/null +++ b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__json__tests__notebook_output.snap @@ -0,0 +1,105 @@ +--- +source: crates/ruff_linter/src/message/json.rs +expression: content +--- +[ + { + "cell": 1, + "code": "F401", + "end_location": { + "column": 10, + "row": 2 + }, + "filename": "notebook.ipynb", + "fix": { + "applicability": "safe", + "edits": [ + { + "content": "", + "end_location": { + "column": 10, + "row": 2 + }, + "location": { + "column": 1, + "row": 2 + } + } + ], + "message": "Remove unused import: `os`" + }, + "location": { + "column": 8, + "row": 2 + }, + "message": "`os` imported but unused", + "noqa_row": 2, + "url": "https://docs.astral.sh/ruff/rules/unused-import" + }, + { + "cell": 2, + "code": "F401", + "end_location": { + "column": 12, + "row": 2 + }, + "filename": "notebook.ipynb", + "fix": { + "applicability": "safe", + "edits": [ + { + "content": "", + "end_location": { + "column": 1, + "row": 3 + }, + "location": { + "column": 1, + "row": 2 + } + } + ], + "message": "Remove unused import: `math`" + }, + "location": { + "column": 8, + "row": 2 + }, + "message": "`math` imported but unused", + "noqa_row": 2, + "url": "https://docs.astral.sh/ruff/rules/unused-import" + }, + { + "cell": 3, + "code": "F841", + "end_location": { + "column": 6, + "row": 4 + }, + "filename": "notebook.ipynb", + "fix": { + "applicability": "unsafe", + "edits": [ + { + "content": "", + "end_location": { + "column": 10, + "row": 4 + }, + "location": { + "column": 1, + "row": 4 + } + } + ], + "message": "Remove assignment to unused variable `x`" + }, + "location": { + "column": 5, + "row": 4 + }, + "message": "Local variable `x` is assigned to but never used", + "noqa_row": 4, + "url": "https://docs.astral.sh/ruff/rules/unused-variable" + } +] diff --git a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__json__tests__output.snap b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__json__tests__output.snap index d149e4ec54139..fed85f04281fe 100644 --- a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__json__tests__output.snap +++ b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__json__tests__output.snap @@ -4,6 +4,7 @@ expression: content --- [ { + "cell": null, "code": "F401", "end_location": { "column": 10, @@ -11,7 +12,7 @@ expression: content }, "filename": "fib.py", "fix": { - "applicability": "Suggested", + "applicability": "unsafe", "edits": [ { "content": "", @@ -36,6 +37,7 @@ expression: content "url": "https://docs.astral.sh/ruff/rules/unused-import" }, { + "cell": null, "code": "F841", "end_location": { "column": 6, @@ -43,7 +45,7 @@ expression: content }, "filename": "fib.py", "fix": { - "applicability": "Suggested", + "applicability": "unsafe", "edits": [ { "content": "", @@ -68,6 +70,7 @@ expression: content "url": "https://docs.astral.sh/ruff/rules/unused-variable" }, { + "cell": null, "code": "F821", "end_location": { "column": 5, diff --git a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__json_lines__tests__notebook_output.snap b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__json_lines__tests__notebook_output.snap new file mode 100644 index 0000000000000..e50520b8b9df9 --- /dev/null +++ b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__json_lines__tests__notebook_output.snap @@ -0,0 +1,8 @@ +--- +source: crates/ruff_linter/src/message/json_lines.rs +expression: content +--- +{"cell":1,"code":"F401","end_location":{"column":10,"row":2},"filename":"notebook.ipynb","fix":{"applicability":"safe","edits":[{"content":"","end_location":{"column":10,"row":2},"location":{"column":1,"row":2}}],"message":"Remove unused import: `os`"},"location":{"column":8,"row":2},"message":"`os` imported but unused","noqa_row":2,"url":"https://docs.astral.sh/ruff/rules/unused-import"} +{"cell":2,"code":"F401","end_location":{"column":12,"row":2},"filename":"notebook.ipynb","fix":{"applicability":"safe","edits":[{"content":"","end_location":{"column":1,"row":3},"location":{"column":1,"row":2}}],"message":"Remove unused import: `math`"},"location":{"column":8,"row":2},"message":"`math` imported but unused","noqa_row":2,"url":"https://docs.astral.sh/ruff/rules/unused-import"} +{"cell":3,"code":"F841","end_location":{"column":6,"row":4},"filename":"notebook.ipynb","fix":{"applicability":"unsafe","edits":[{"content":"","end_location":{"column":10,"row":4},"location":{"column":1,"row":4}}],"message":"Remove assignment to unused variable `x`"},"location":{"column":5,"row":4},"message":"Local variable `x` is assigned to but never used","noqa_row":4,"url":"https://docs.astral.sh/ruff/rules/unused-variable"} + diff --git a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__json_lines__tests__output.snap b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__json_lines__tests__output.snap index 4a4c04222def7..57cd47822ceea 100644 --- a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__json_lines__tests__output.snap +++ b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__json_lines__tests__output.snap @@ -2,7 +2,7 @@ source: crates/ruff_linter/src/message/json_lines.rs expression: content --- -{"code":"F401","end_location":{"column":10,"row":1},"filename":"fib.py","fix":{"applicability":"Suggested","edits":[{"content":"","end_location":{"column":1,"row":2},"location":{"column":1,"row":1}}],"message":"Remove unused import: `os`"},"location":{"column":8,"row":1},"message":"`os` imported but unused","noqa_row":1,"url":"https://docs.astral.sh/ruff/rules/unused-import"} -{"code":"F841","end_location":{"column":6,"row":6},"filename":"fib.py","fix":{"applicability":"Suggested","edits":[{"content":"","end_location":{"column":10,"row":6},"location":{"column":5,"row":6}}],"message":"Remove assignment to unused variable `x`"},"location":{"column":5,"row":6},"message":"Local variable `x` is assigned to but never used","noqa_row":6,"url":"https://docs.astral.sh/ruff/rules/unused-variable"} -{"code":"F821","end_location":{"column":5,"row":1},"filename":"undef.py","fix":null,"location":{"column":4,"row":1},"message":"Undefined name `a`","noqa_row":1,"url":"https://docs.astral.sh/ruff/rules/undefined-name"} +{"cell":null,"code":"F401","end_location":{"column":10,"row":1},"filename":"fib.py","fix":{"applicability":"unsafe","edits":[{"content":"","end_location":{"column":1,"row":2},"location":{"column":1,"row":1}}],"message":"Remove unused import: `os`"},"location":{"column":8,"row":1},"message":"`os` imported but unused","noqa_row":1,"url":"https://docs.astral.sh/ruff/rules/unused-import"} +{"cell":null,"code":"F841","end_location":{"column":6,"row":6},"filename":"fib.py","fix":{"applicability":"unsafe","edits":[{"content":"","end_location":{"column":10,"row":6},"location":{"column":5,"row":6}}],"message":"Remove assignment to unused variable `x`"},"location":{"column":5,"row":6},"message":"Local variable `x` is assigned to but never used","noqa_row":6,"url":"https://docs.astral.sh/ruff/rules/unused-variable"} +{"cell":null,"code":"F821","end_location":{"column":5,"row":1},"filename":"undef.py","fix":null,"location":{"column":4,"row":1},"message":"Undefined name `a`","noqa_row":1,"url":"https://docs.astral.sh/ruff/rules/undefined-name"} diff --git a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__text__tests__fix_status.snap b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__text__tests__fix_status.snap index a53420329c119..77cd92056a7de 100644 --- a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__text__tests__fix_status.snap +++ b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__text__tests__fix_status.snap @@ -2,14 +2,14 @@ source: crates/ruff_linter/src/message/text.rs expression: content --- -fib.py:1:8: F401 [*] `os` imported but unused +fib.py:1:8: F401 `os` imported but unused | 1 | import os | ^^ F401 | = help: Remove unused import: `os` -fib.py:6:5: F841 [*] Local variable `x` is assigned to but never used +fib.py:6:5: F841 Local variable `x` is assigned to but never used | 4 | def fibonacci(n): 5 | """Compute the nth number in the Fibonacci sequence.""" diff --git a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__text__tests__fix_status_unsafe.snap b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__text__tests__fix_status_unsafe.snap new file mode 100644 index 0000000000000..a53420329c119 --- /dev/null +++ b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__text__tests__fix_status_unsafe.snap @@ -0,0 +1,29 @@ +--- +source: crates/ruff_linter/src/message/text.rs +expression: content +--- +fib.py:1:8: F401 [*] `os` imported but unused + | +1 | import os + | ^^ F401 + | + = help: Remove unused import: `os` + +fib.py:6:5: F841 [*] Local variable `x` is assigned to but never used + | +4 | def fibonacci(n): +5 | """Compute the nth number in the Fibonacci sequence.""" +6 | x = 1 + | ^ F841 +7 | if n == 0: +8 | return 0 + | + = help: Remove assignment to unused variable `x` + +undef.py:1:4: F821 Undefined name `a` + | +1 | if a == 1: pass + | ^ F821 + | + + diff --git a/crates/ruff_linter/src/message/snapshots/ruff_linter__message__text__tests__notebook_output.snap b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__text__tests__notebook_output.snap new file mode 100644 index 0000000000000..5cd2f33939a8f --- /dev/null +++ b/crates/ruff_linter/src/message/snapshots/ruff_linter__message__text__tests__notebook_output.snap @@ -0,0 +1,32 @@ +--- +source: crates/ruff_linter/src/message/text.rs +expression: content +--- +notebook.ipynb:cell 1:2:8: F401 [*] `os` imported but unused + | +1 | # cell 1 +2 | import os + | ^^ F401 + | + = help: Remove unused import: `os` + +notebook.ipynb:cell 2:2:8: F401 [*] `math` imported but unused + | +1 | # cell 2 +2 | import math + | ^^^^ F401 +3 | +4 | print('hello world') + | + = help: Remove unused import: `math` + +notebook.ipynb:cell 3:4:5: F841 [*] Local variable `x` is assigned to but never used + | +2 | def foo(): +3 | print() +4 | x = 1 + | ^ F841 + | + = help: Remove assignment to unused variable `x` + + diff --git a/crates/ruff_linter/src/message/text.rs b/crates/ruff_linter/src/message/text.rs index 5abc7fd268b76..833deab46c818 100644 --- a/crates/ruff_linter/src/message/text.rs +++ b/crates/ruff_linter/src/message/text.rs @@ -12,26 +12,28 @@ use ruff_source_file::{OneIndexed, SourceLocation}; use ruff_text_size::{Ranged, TextRange, TextSize}; use crate::fs::relativize_path; -use crate::line_width::{LineWidthBuilder, TabSize}; +use crate::line_width::{IndentWidth, LineWidthBuilder}; use crate::message::diff::Diff; use crate::message::{Emitter, EmitterContext, Message}; use crate::registry::AsRule; +use crate::settings::types::UnsafeFixes; bitflags! { #[derive(Default)] struct EmitterFlags: u8 { /// Whether to show the fix status of a diagnostic. - const SHOW_FIX_STATUS = 0b0000_0001; + const SHOW_FIX_STATUS = 0b0000_0001; /// Whether to show the diff of a fix, for diagnostics that have a fix. - const SHOW_FIX_DIFF = 0b0000_0010; + const SHOW_FIX_DIFF = 0b0000_0010; /// Whether to show the source code of a diagnostic. - const SHOW_SOURCE = 0b0000_0100; + const SHOW_SOURCE = 0b0000_0100; } } #[derive(Default)] pub struct TextEmitter { flags: EmitterFlags, + unsafe_fixes: UnsafeFixes, } impl TextEmitter { @@ -53,6 +55,12 @@ impl TextEmitter { self.flags.set(EmitterFlags::SHOW_SOURCE, show_source); self } + + #[must_use] + pub fn with_unsafe_fixes(mut self, unsafe_fixes: UnsafeFixes) -> Self { + self.unsafe_fixes = unsafe_fixes; + self + } } impl Emitter for TextEmitter { @@ -79,18 +87,15 @@ impl Emitter for TextEmitter { writer, "cell {cell}{sep}", cell = notebook_index - .cell(start_location.row.get()) - .unwrap_or_default(), + .cell(start_location.row) + .unwrap_or(OneIndexed::MIN), sep = ":".cyan(), )?; SourceLocation { - row: OneIndexed::new( - notebook_index - .cell_row(start_location.row.get()) - .unwrap_or(1) as usize, - ) - .unwrap(), + row: notebook_index + .cell_row(start_location.row) + .unwrap_or(OneIndexed::MIN), column: start_location.column, } } else { @@ -105,7 +110,8 @@ impl Emitter for TextEmitter { sep = ":".cyan(), code_and_body = RuleCodeAndBody { message, - show_fix_status: self.flags.intersects(EmitterFlags::SHOW_FIX_STATUS) + show_fix_status: self.flags.intersects(EmitterFlags::SHOW_FIX_STATUS), + unsafe_fixes: self.unsafe_fixes, } )?; @@ -134,28 +140,33 @@ impl Emitter for TextEmitter { pub(super) struct RuleCodeAndBody<'a> { pub(crate) message: &'a Message, pub(crate) show_fix_status: bool, + pub(crate) unsafe_fixes: UnsafeFixes, } impl Display for RuleCodeAndBody<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { let kind = &self.message.kind; + if self.show_fix_status { + if let Some(fix) = self.message.fix.as_ref() { + // Do not display an indicator for unapplicable fixes + if fix.applies(self.unsafe_fixes.required_applicability()) { + return write!( + f, + "{code} {fix}{body}", + code = kind.rule().noqa_code().to_string().red().bold(), + fix = format_args!("[{}] ", "*".cyan()), + body = kind.body, + ); + } + } + }; - if self.show_fix_status && self.message.fix.is_some() { - write!( - f, - "{code} {autofix}{body}", - code = kind.rule().noqa_code().to_string().red().bold(), - autofix = format_args!("[{}] ", "*".cyan()), - body = kind.body, - ) - } else { - write!( - f, - "{code} {body}", - code = kind.rule().noqa_code().to_string().red().bold(), - body = kind.body, - ) - } + write!( + f, + "{code} {body}", + code = kind.rule().noqa_code().to_string().red().bold(), + body = kind.body, + ) } } @@ -189,9 +200,9 @@ impl Display for MessageCodeFrame<'_> { // If we're working with a Jupyter Notebook, skip the lines which are // outside of the cell containing the diagnostic. if let Some(index) = self.notebook_index { - let content_start_cell = index.cell(content_start_index.get()).unwrap_or_default(); + let content_start_cell = index.cell(content_start_index).unwrap_or(OneIndexed::MIN); while start_index < content_start_index { - if index.cell(start_index.get()).unwrap_or_default() == content_start_cell { + if index.cell(start_index).unwrap_or(OneIndexed::MIN) == content_start_cell { break; } start_index = start_index.saturating_add(1); @@ -214,9 +225,9 @@ impl Display for MessageCodeFrame<'_> { // If we're working with a Jupyter Notebook, skip the lines which are // outside of the cell containing the diagnostic. if let Some(index) = self.notebook_index { - let content_end_cell = index.cell(content_end_index.get()).unwrap_or_default(); + let content_end_cell = index.cell(content_end_index).unwrap_or(OneIndexed::MIN); while end_index > content_end_index { - if index.cell(end_index.get()).unwrap_or_default() == content_end_cell { + if index.cell(end_index).unwrap_or(OneIndexed::MIN) == content_end_cell { break; } end_index = end_index.saturating_sub(1); @@ -256,8 +267,9 @@ impl Display for MessageCodeFrame<'_> { || start_index.get(), |notebook_index| { notebook_index - .cell_row(start_index.get()) - .unwrap_or_default() as usize + .cell_row(start_index) + .unwrap_or(OneIndexed::MIN) + .get() }, ), annotations: vec![SourceAnnotation { @@ -288,7 +300,7 @@ fn replace_whitespace(source: &str, annotation_range: TextRange) -> SourceCode { let mut result = String::new(); let mut last_end = 0; let mut range = annotation_range; - let mut line_width = LineWidthBuilder::new(TabSize::default()); + let mut line_width = LineWidthBuilder::new(IndentWidth::default()); for (index, c) in source.char_indices() { let old_width = line_width.get(); @@ -339,8 +351,12 @@ struct SourceCode<'a> { mod tests { use insta::assert_snapshot; - use crate::message::tests::{capture_emitter_output, create_messages}; + use crate::message::tests::{ + capture_emitter_notebook_output, capture_emitter_output, create_messages, + create_notebook_messages, + }; use crate::message::TextEmitter; + use crate::settings::types::UnsafeFixes; #[test] fn default() { @@ -359,4 +375,27 @@ mod tests { assert_snapshot!(content); } + + #[test] + fn fix_status_unsafe() { + let mut emitter = TextEmitter::default() + .with_show_fix_status(true) + .with_show_source(true) + .with_unsafe_fixes(UnsafeFixes::Enabled); + let content = capture_emitter_output(&mut emitter, &create_messages()); + + assert_snapshot!(content); + } + + #[test] + fn notebook_output() { + let mut emitter = TextEmitter::default() + .with_show_fix_status(true) + .with_show_source(true) + .with_unsafe_fixes(UnsafeFixes::Enabled); + let (messages, notebook_indexes) = create_notebook_messages(); + let content = capture_emitter_notebook_output(&mut emitter, &messages, ¬ebook_indexes); + + assert_snapshot!(content); + } } diff --git a/crates/ruff_linter/src/noqa.rs b/crates/ruff_linter/src/noqa.rs index b53976dae06a9..e98f33bcf72e7 100644 --- a/crates/ruff_linter/src/noqa.rs +++ b/crates/ruff_linter/src/noqa.rs @@ -253,7 +253,7 @@ impl FileExemption { #[allow(deprecated)] let line = locator.compute_line_index(range.start()); let path_display = relativize_path(path); - warn!("Unexpected `# ruff: noqa` directive at {path_display}:{line}. File-level suppression comments must appear on their own line."); + warn!("Unexpected `# ruff: noqa` directive at {path_display}:{line}. File-level suppression comments must appear on their own line. For line-level suppression, omit the `ruff:` prefix."); continue; } diff --git a/crates/ruff_linter/src/registry.rs b/crates/ruff_linter/src/registry.rs index bf83186c1aaba..6dd7c459122bc 100644 --- a/crates/ruff_linter/src/registry.rs +++ b/crates/ruff_linter/src/registry.rs @@ -428,7 +428,18 @@ mod tests { use super::{Linter, Rule, RuleNamespace}; #[test] - fn test_rule_naming_convention() { + fn documentation() { + for rule in Rule::iter() { + assert!( + rule.explanation().is_some(), + "Rule {} is missing documentation", + rule.as_ref() + ); + } + } + + #[test] + fn rule_naming_convention() { // The disallowed rule names are defined in a separate file so that they can also be picked up by add_rule.py. let patterns: Vec<_> = include_str!("../resources/test/disallowed_rule_names.txt") .trim() @@ -460,7 +471,7 @@ mod tests { } #[test] - fn test_linter_parse_code() { + fn linter_parse_code() { for rule in Rule::iter() { let code = format!("{}", rule.noqa_code()); let (linter, rest) = diff --git a/crates/ruff_linter/src/registry/rule_set.rs b/crates/ruff_linter/src/registry/rule_set.rs index 77ce199b98b97..e5214d5e447b3 100644 --- a/crates/ruff_linter/src/registry/rule_set.rs +++ b/crates/ruff_linter/src/registry/rule_set.rs @@ -3,7 +3,7 @@ use ruff_macros::CacheKey; use std::fmt::{Debug, Formatter}; use std::iter::FusedIterator; -const RULESET_SIZE: usize = 11; +const RULESET_SIZE: usize = 12; /// A set of [`Rule`]s. /// diff --git a/crates/ruff_linter/src/rule_selector.rs b/crates/ruff_linter/src/rule_selector.rs index 910cac9cb1fa2..ea83c058ed014 100644 --- a/crates/ruff_linter/src/rule_selector.rs +++ b/crates/ruff_linter/src/rule_selector.rs @@ -198,16 +198,19 @@ impl RuleSelector { } } - /// Returns rules matching the selector, taking into account whether preview mode is enabled. - pub fn rules(&self, preview: PreviewMode) -> impl Iterator + '_ { + /// Returns rules matching the selector, taking into account preview options enabled. + pub fn rules<'a>(&'a self, preview: &PreviewOptions) -> impl Iterator + 'a { + let preview_enabled = preview.mode.is_enabled(); + let preview_require_explicit = preview.require_explicit; #[allow(deprecated)] self.all_rules().filter(move |rule| { // Always include rules that are not in preview or the nursery !(rule.is_preview() || rule.is_nursery()) // Backwards compatibility allows selection of nursery rules by exact code or dedicated group || ((matches!(self, RuleSelector::Rule { .. }) || matches!(self, RuleSelector::Nursery { .. })) && rule.is_nursery()) - // Enabling preview includes all preview or nursery rules - || preview.is_enabled() + // Enabling preview includes all preview or nursery rules unless explicit selection + // is turned on + || (preview_enabled && (matches!(self, RuleSelector::Rule { .. }) || !preview_require_explicit)) }) } } @@ -232,6 +235,14 @@ impl Iterator for RuleSelectorIter { } } +#[derive(Debug, Clone, PartialEq, Eq, Default)] +pub struct PreviewOptions { + pub mode: PreviewMode, + /// If true, preview rule selection requires explicit codes e.g. not prefixes. + /// Generally this should be derived from the user-facing `explicit-preview-rules` option. + pub require_explicit: bool, +} + #[cfg(feature = "schemars")] mod schema { use itertools::Itertools; diff --git a/crates/ruff_linter/src/rules/eradicate/detection.rs b/crates/ruff_linter/src/rules/eradicate/detection.rs index 77be87c048f1b..9d4eef33efbcc 100644 --- a/crates/ruff_linter/src/rules/eradicate/detection.rs +++ b/crates/ruff_linter/src/rules/eradicate/detection.rs @@ -1,106 +1,86 @@ /// See: [eradicate.py](https://github.com/myint/eradicate/blob/98f199940979c94447a461d50d27862b118b282d/eradicate.py) +use aho_corasick::AhoCorasick; use once_cell::sync::Lazy; -use regex::Regex; +use regex::{Regex, RegexSet}; use ruff_python_parser::parse_suite; +static CODE_INDICATORS: Lazy = Lazy::new(|| { + AhoCorasick::new([ + "(", ")", "[", "]", "{", "}", ":", "=", "%", "print", "return", "break", "continue", + "import", + ]) + .unwrap() +}); + static ALLOWLIST_REGEX: Lazy = Lazy::new(|| { Regex::new( - r"^(?i)(?:pylint|pyright|noqa|nosec|region|endregion|type:\s*ignore|fmt:\s*(on|off)|isort:\s*(on|off|skip|skip_file|split|dont-add-imports(:\s*\[.*?])?)|mypy:|SPDX-License-Identifier:)" + r"^(?i)(?:pylint|pyright|noqa|nosec|region|endregion|type:\s*ignore|fmt:\s*(on|off)|isort:\s*(on|off|skip|skip_file|split|dont-add-imports(:\s*\[.*?])?)|mypy:|SPDX-License-Identifier:|(?:en)?coding[:=][ \t]*([-_.a-zA-Z0-9]+))", ).unwrap() }); -static BRACKET_REGEX: Lazy = Lazy::new(|| Regex::new(r"^[()\[\]{}\s]+$").unwrap()); -static CODE_INDICATORS: &[&str] = &[ - "(", ")", "[", "]", "{", "}", ":", "=", "%", "print", "return", "break", "continue", "import", -]; -static CODE_KEYWORDS: Lazy> = Lazy::new(|| { - vec![ - Regex::new(r"^\s*elif\s+.*\s*:\s*$").unwrap(), - Regex::new(r"^\s*else\s*:\s*$").unwrap(), - Regex::new(r"^\s*try\s*:\s*$").unwrap(), - Regex::new(r"^\s*finally\s*:\s*$").unwrap(), - Regex::new(r"^\s*except\s+.*\s*:\s*$").unwrap(), - ] -}); -static CODING_COMMENT_REGEX: Lazy = - Lazy::new(|| Regex::new(r"^.*?coding[:=][ \t]*([-_.a-zA-Z0-9]+)").unwrap()); + static HASH_NUMBER: Lazy = Lazy::new(|| Regex::new(r"#\d").unwrap()); -static MULTILINE_ASSIGNMENT_REGEX: Lazy = - Lazy::new(|| Regex::new(r"^\s*([(\[]\s*)?(\w+\s*,\s*)*\w+\s*([)\]]\s*)?=.*[(\[{]$").unwrap()); -static PARTIAL_DICTIONARY_REGEX: Lazy = - Lazy::new(|| Regex::new(r#"^\s*['"]\w+['"]\s*:.+[,{]\s*(#.*)?$"#).unwrap()); -static PRINT_RETURN_REGEX: Lazy = Lazy::new(|| Regex::new(r"^(print|return)\b\s*").unwrap()); + +static POSITIVE_CASES: Lazy = Lazy::new(|| { + RegexSet::new([ + // Keywords + r"^(?:elif\s+.*\s*:|else\s*:|try\s*:|finally\s*:|except\s+.*\s*:)$", + // Partial dictionary + r#"^['"]\w+['"]\s*:.+[,{]\s*(#.*)?$"#, + // Multiline assignment + r"^(?:[(\[]\s*)?(?:\w+\s*,\s*)*\w+\s*([)\]]\s*)?=.*[(\[{]$", + // Brackets, + r"^[()\[\]{}\s]+$", + ]) + .unwrap() +}); /// Returns `true` if a comment contains Python code. pub(crate) fn comment_contains_code(line: &str, task_tags: &[String]) -> bool { - let line = if let Some(line) = line.trim().strip_prefix('#') { - line.trim_start_matches([' ', '#']) - } else { - return false; - }; + let line = line.trim_start_matches([' ', '#']).trim_end(); - // Ignore non-comment related hashes (e.g., "# Issue #999"). - if HASH_NUMBER.is_match(line) { + // Fast path: if none of the indicators are present, the line is not code. + if !CODE_INDICATORS.is_match(line) { return false; } - // Ignore whitelisted comments. - if ALLOWLIST_REGEX.is_match(line) { + // Ignore task tag comments (e.g., "# TODO(tom): Refactor"). + if line + .split(&[' ', ':', '(']) + .next() + .is_some_and(|first| task_tags.iter().any(|tag| tag == first)) + { return false; } - if let Some(first) = line.split(&[' ', ':']).next() { - if task_tags.iter().any(|tag| tag == first) { - return false; - } - } - - if CODING_COMMENT_REGEX.is_match(line) { + // Ignore whitelisted comments. + if ALLOWLIST_REGEX.is_match(line) { return false; } - // Check that this is possibly code. - if CODE_INDICATORS.iter().all(|symbol| !line.contains(symbol)) { + // Ignore non-comment related hashes (e.g., "# Issue #999"). + if HASH_NUMBER.is_match(line) { return false; } - if multiline_case(line) { - return true; - } - - if CODE_KEYWORDS.iter().any(|symbol| symbol.is_match(line)) { - return true; - } - - let line = PRINT_RETURN_REGEX.replace_all(line, ""); - - if PARTIAL_DICTIONARY_REGEX.is_match(&line) { - return true; - } - - // Finally, compile the source code. - parse_suite(&line, "").is_ok() -} - -/// Returns `true` if a line is probably part of some multiline code. -fn multiline_case(line: &str) -> bool { + // If the comment made it this far, and ends in a continuation, assume it's code. if line.ends_with('\\') { return true; } - if MULTILINE_ASSIGNMENT_REGEX.is_match(line) { + // If the comment matches any of the specified positive cases, assume it's code. + if POSITIVE_CASES.is_match(line) { return true; } - if BRACKET_REGEX.is_match(line) { - return true; - } - - false + // Finally, compile the source code. + parse_suite(line, "").is_ok() } #[cfg(test)] mod tests { + use crate::settings::TASK_TAGS; + use super::comment_contains_code; #[test] @@ -123,7 +103,6 @@ mod tests { assert!(!comment_contains_code("# 123", &[])); assert!(!comment_contains_code("# 123.1", &[])); assert!(!comment_contains_code("# 1, 2, 3", &[])); - assert!(!comment_contains_code("x = 1 # x = 1", &[])); assert!(!comment_contains_code( "# pylint: disable=redefined-outer-name", &[] @@ -146,7 +125,6 @@ mod tests { fn comment_contains_code_with_print() { assert!(comment_contains_code("#print", &[])); assert!(comment_contains_code("#print(1)", &[])); - assert!(comment_contains_code("#print 1", &[])); assert!(!comment_contains_code("#to print", &[])); } @@ -279,4 +257,42 @@ mod tests { &["XXX".to_string()] )); } + + #[test] + fn comment_contains_todo() { + let task_tags = TASK_TAGS + .iter() + .map(ToString::to_string) + .collect::>(); + + assert!(!comment_contains_code( + "# TODO(tom): Rewrite in Rust", + &task_tags + )); + assert!(!comment_contains_code( + "# TODO: Rewrite in Rust", + &task_tags + )); + assert!(!comment_contains_code("# TODO:Rewrite in Rust", &task_tags)); + + assert!(!comment_contains_code( + "# FIXME(tom): Rewrite in Rust", + &task_tags + )); + assert!(!comment_contains_code( + "# FIXME: Rewrite in Rust", + &task_tags + )); + assert!(!comment_contains_code( + "# FIXME:Rewrite in Rust", + &task_tags + )); + + assert!(!comment_contains_code( + "# XXX(tom): Rewrite in Rust", + &task_tags + )); + assert!(!comment_contains_code("# XXX: Rewrite in Rust", &task_tags)); + assert!(!comment_contains_code("# XXX:Rewrite in Rust", &task_tags)); + } } diff --git a/crates/ruff_linter/src/rules/eradicate/rules/commented_out_code.rs b/crates/ruff_linter/src/rules/eradicate/rules/commented_out_code.rs index 7c712f20a167e..6dbe63570f10b 100644 --- a/crates/ruff_linter/src/rules/eradicate/rules/commented_out_code.rs +++ b/crates/ruff_linter/src/rules/eradicate/rules/commented_out_code.rs @@ -1,9 +1,8 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_index::Indexer; use ruff_source_file::Locator; -use crate::registry::Rule; use crate::settings::LinterSettings; use super::super::detection::comment_contains_code; @@ -15,23 +14,29 @@ use super::super::detection::comment_contains_code; /// Commented-out code is dead code, and is often included inadvertently. /// It should be removed. /// +/// ## Known problems +/// Prone to false positives when checking comments that resemble Python code, +/// but are not actually Python code ([#4845]). +/// /// ## Example /// ```python -/// # print('foo') +/// # print("Hello, world!") /// ``` /// /// ## Options /// - `task-tags` +/// +/// [#4845]: https://github.com/astral-sh/ruff/issues/4845 #[violation] pub struct CommentedOutCode; -impl AlwaysAutofixableViolation for CommentedOutCode { +impl AlwaysFixableViolation for CommentedOutCode { #[derive_message_formats] fn message(&self) -> String { format!("Found commented-out code") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove commented-out code".to_string() } } @@ -61,11 +66,9 @@ pub(crate) fn commented_out_code( if is_standalone_comment(line) && comment_contains_code(line, &settings.task_tags[..]) { let mut diagnostic = Diagnostic::new(CommentedOutCode, *range); - if settings.rules.should_fix(Rule::CommentedOutCode) { - diagnostic.set_fix(Fix::manual(Edit::range_deletion( - locator.full_lines_range(*range), - ))); - } + diagnostic.set_fix(Fix::display_edit(Edit::range_deletion( + locator.full_lines_range(*range), + ))); diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/eradicate/snapshots/ruff_linter__rules__eradicate__tests__ERA001_ERA001.py.snap b/crates/ruff_linter/src/rules/eradicate/snapshots/ruff_linter__rules__eradicate__tests__ERA001_ERA001.py.snap index c33d3b0978978..ae9b9588724c8 100644 --- a/crates/ruff_linter/src/rules/eradicate/snapshots/ruff_linter__rules__eradicate__tests__ERA001_ERA001.py.snap +++ b/crates/ruff_linter/src/rules/eradicate/snapshots/ruff_linter__rules__eradicate__tests__ERA001_ERA001.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/eradicate/mod.rs --- -ERA001.py:1:1: ERA001 [*] Found commented-out code +ERA001.py:1:1: ERA001 Found commented-out code | 1 | #import os | ^^^^^^^^^^ ERA001 @@ -16,7 +16,7 @@ ERA001.py:1:1: ERA001 [*] Found commented-out code 3 2 | #a = 3 4 3 | a = 4 -ERA001.py:2:1: ERA001 [*] Found commented-out code +ERA001.py:2:1: ERA001 Found commented-out code | 1 | #import os 2 | # from foo import junk @@ -33,7 +33,7 @@ ERA001.py:2:1: ERA001 [*] Found commented-out code 4 3 | a = 4 5 4 | #foo(1, 2, 3) -ERA001.py:3:1: ERA001 [*] Found commented-out code +ERA001.py:3:1: ERA001 Found commented-out code | 1 | #import os 2 | # from foo import junk @@ -52,7 +52,7 @@ ERA001.py:3:1: ERA001 [*] Found commented-out code 5 4 | #foo(1, 2, 3) 6 5 | -ERA001.py:5:1: ERA001 [*] Found commented-out code +ERA001.py:5:1: ERA001 Found commented-out code | 3 | #a = 3 4 | a = 4 @@ -72,7 +72,7 @@ ERA001.py:5:1: ERA001 [*] Found commented-out code 7 6 | def foo(x, y, z): 8 7 | content = 1 # print('hello') -ERA001.py:13:5: ERA001 [*] Found commented-out code +ERA001.py:13:5: ERA001 Found commented-out code | 11 | # This is a real comment. 12 | # # This is a (nested) comment. @@ -91,7 +91,7 @@ ERA001.py:13:5: ERA001 [*] Found commented-out code 15 14 | 16 15 | #import os # noqa: ERA001 -ERA001.py:21:5: ERA001 [*] Found commented-out code +ERA001.py:21:5: ERA001 Found commented-out code | 19 | class A(): 20 | pass @@ -109,7 +109,7 @@ ERA001.py:21:5: ERA001 [*] Found commented-out code 23 22 | 24 23 | dictionary = { -ERA001.py:26:5: ERA001 [*] Found commented-out code +ERA001.py:26:5: ERA001 Found commented-out code | 24 | dictionary = { 25 | # "key1": 123, # noqa: ERA001 @@ -129,7 +129,7 @@ ERA001.py:26:5: ERA001 [*] Found commented-out code 28 27 | } 29 28 | -ERA001.py:27:5: ERA001 [*] Found commented-out code +ERA001.py:27:5: ERA001 Found commented-out code | 25 | # "key1": 123, # noqa: ERA001 26 | # "key2": 456, diff --git a/crates/ruff_linter/src/rules/flake8_2020/rules/compare.rs b/crates/ruff_linter/src/rules/flake8_2020/rules/compare.rs index 58a8f808386e9..debb88697e56a 100644 --- a/crates/ruff_linter/src/rules/flake8_2020/rules/compare.rs +++ b/crates/ruff_linter/src/rules/flake8_2020/rules/compare.rs @@ -1,8 +1,6 @@ -use num_bigint::BigInt; -use ruff_python_ast::{self as ast, CmpOp, Constant, Expr}; - use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, CmpOp, Constant, Expr}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -237,7 +235,7 @@ pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[CmpOp], compara .. }) = slice.as_ref() { - if *i == BigInt::from(0) { + if *i == 0 { if let ( [CmpOp::Eq | CmpOp::NotEq], [Expr::Constant(ast::ExprConstant { @@ -246,13 +244,13 @@ pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[CmpOp], compara })], ) = (ops, comparators) { - if *n == BigInt::from(3) && checker.enabled(Rule::SysVersionInfo0Eq3) { + if *n == 3 && checker.enabled(Rule::SysVersionInfo0Eq3) { checker .diagnostics .push(Diagnostic::new(SysVersionInfo0Eq3, left.range())); } } - } else if *i == BigInt::from(1) { + } else if *i == 1 { if let ( [CmpOp::Lt | CmpOp::LtE | CmpOp::Gt | CmpOp::GtE], [Expr::Constant(ast::ExprConstant { diff --git a/crates/ruff_linter/src/rules/flake8_2020/rules/subscript.rs b/crates/ruff_linter/src/rules/flake8_2020/rules/subscript.rs index 9c21064ce09d4..f92c0da03d57a 100644 --- a/crates/ruff_linter/src/rules/flake8_2020/rules/subscript.rs +++ b/crates/ruff_linter/src/rules/flake8_2020/rules/subscript.rs @@ -1,8 +1,6 @@ -use num_bigint::BigInt; -use ruff_python_ast::{self as ast, Constant, Expr}; - use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, Constant, Expr}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -184,11 +182,11 @@ pub(crate) fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) { .. }) = upper.as_ref() { - if *i == BigInt::from(1) && checker.enabled(Rule::SysVersionSlice1) { + if *i == 1 && checker.enabled(Rule::SysVersionSlice1) { checker .diagnostics .push(Diagnostic::new(SysVersionSlice1, value.range())); - } else if *i == BigInt::from(3) && checker.enabled(Rule::SysVersionSlice3) { + } else if *i == 3 && checker.enabled(Rule::SysVersionSlice3) { checker .diagnostics .push(Diagnostic::new(SysVersionSlice3, value.range())); @@ -200,11 +198,11 @@ pub(crate) fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) { value: Constant::Int(i), .. }) => { - if *i == BigInt::from(2) && checker.enabled(Rule::SysVersion2) { + if *i == 2 && checker.enabled(Rule::SysVersion2) { checker .diagnostics .push(Diagnostic::new(SysVersion2, value.range())); - } else if *i == BigInt::from(0) && checker.enabled(Rule::SysVersion0) { + } else if *i == 0 && checker.enabled(Rule::SysVersion0) { checker .diagnostics .push(Diagnostic::new(SysVersion0, value.range())); diff --git a/crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs b/crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs index f86e84830c8b6..1db658efef269 100644 --- a/crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs +++ b/crates/ruff_linter/src/rules/flake8_annotations/rules/definition.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::ReturnStatementVisitor; use ruff_python_ast::identifier::Identifier; @@ -11,7 +11,7 @@ use ruff_python_stdlib::typing::simple_magic_return_type; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::{AsRule, Rule}; +use crate::registry::Rule; use crate::rules::ruff::typing::type_hint_resolves_to_any; /// ## What it does @@ -287,14 +287,14 @@ pub struct MissingReturnTypeSpecialMethod { name: String, } -impl AlwaysAutofixableViolation for MissingReturnTypeSpecialMethod { +impl AlwaysFixableViolation for MissingReturnTypeSpecialMethod { #[derive_message_formats] fn message(&self) -> String { let MissingReturnTypeSpecialMethod { name } = self; format!("Missing return type annotation for special method `{name}`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Add `None` return type".to_string() } } @@ -412,7 +412,7 @@ impl Violation for MissingReturnTypeClassMethod { /// ## References /// - [PEP 484](https://www.python.org/dev/peps/pep-0484/#the-any-type) /// - [Python documentation: `typing.Any`](https://docs.python.org/3/library/typing.html#typing.Any) -/// - [Mypy: The Any type](https://mypy.readthedocs.io/en/stable/kinds_of_types.html#the-any-type) +/// - [Mypy documentation: The Any type](https://mypy.readthedocs.io/en/stable/kinds_of_types.html#the-any-type) #[violation] pub struct AnyType { name: String, @@ -702,12 +702,10 @@ pub(crate) fn definition( }, function.identifier(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::insertion( - " -> None".to_string(), - function.parameters.range().end(), - ))); - } + diagnostic.set_fix(Fix::unsafe_edit(Edit::insertion( + " -> None".to_string(), + function.parameters.range().end(), + ))); diagnostics.push(diagnostic); } } @@ -719,13 +717,11 @@ pub(crate) fn definition( }, function.identifier(), ); - if checker.patch(diagnostic.kind.rule()) { - if let Some(return_type) = simple_magic_return_type(name) { - diagnostic.set_fix(Fix::suggested(Edit::insertion( - format!(" -> {return_type}"), - function.parameters.range().end(), - ))); - } + if let Some(return_type) = simple_magic_return_type(name) { + diagnostic.set_fix(Fix::unsafe_edit(Edit::insertion( + format!(" -> {return_type}"), + function.parameters.range().end(), + ))); } diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__defaults.snap b/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__defaults.snap index 10154ea5c0eea..46f4faabe2fd8 100644 --- a/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__defaults.snap +++ b/crates/ruff_linter/src/rules/flake8_annotations/snapshots/ruff_linter__rules__flake8_annotations__tests__defaults.snap @@ -259,5 +259,34 @@ annotation_presence.py:159:9: ANN204 [*] Missing return type annotation for spec 159 |- def __init__(self: "Foo", foo: int): 159 |+ def __init__(self: "Foo", foo: int) -> None: 160 160 | ... +161 161 | +162 162 | + +annotation_presence.py:165:9: ANN204 [*] Missing return type annotation for special method `__init__` + | +163 | # Regression test for: https://github.com/astral-sh/ruff/issues/7711 +164 | class Class: +165 | def __init__(self): + | ^^^^^^^^ ANN204 +166 | print(f"{self.attr=}") + | + = help: Add `None` return type + +ℹ Suggested fix +162 162 | +163 163 | # Regression test for: https://github.com/astral-sh/ruff/issues/7711 +164 164 | class Class: +165 |- def __init__(self): + 165 |+ def __init__(self) -> None: +166 166 | print(f"{self.attr=}") + +annotation_presence.py:165:18: ANN101 Missing type annotation for `self` in method + | +163 | # Regression test for: https://github.com/astral-sh/ruff/issues/7711 +164 | class Class: +165 | def __init__(self): + | ^^^^ ANN101 +166 | print(f"{self.attr=}") + | diff --git a/crates/ruff_linter/src/rules/flake8_async/rules/blocking_http_call.rs b/crates/ruff_linter/src/rules/flake8_async/rules/blocking_http_call.rs index eabe27f54fb44..3fe925f2f1165 100644 --- a/crates/ruff_linter/src/rules/flake8_async/rules/blocking_http_call.rs +++ b/crates/ruff_linter/src/rules/flake8_async/rules/blocking_http_call.rs @@ -1,5 +1,4 @@ -use ruff_python_ast as ast; -use ruff_python_ast::Expr; +use ruff_python_ast::ExprCall; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -62,20 +61,18 @@ fn is_blocking_http_call(call_path: &CallPath) -> bool { } /// ASYNC100 -pub(crate) fn blocking_http_call(checker: &mut Checker, expr: &Expr) { +pub(crate) fn blocking_http_call(checker: &mut Checker, call: &ExprCall) { if checker.semantic().in_async_context() { - if let Expr::Call(ast::ExprCall { func, .. }) = expr { - if checker - .semantic() - .resolve_call_path(func) - .as_ref() - .is_some_and(is_blocking_http_call) - { - checker.diagnostics.push(Diagnostic::new( - BlockingHttpCallInAsyncFunction, - func.range(), - )); - } + if checker + .semantic() + .resolve_call_path(call.func.as_ref()) + .as_ref() + .is_some_and(is_blocking_http_call) + { + checker.diagnostics.push(Diagnostic::new( + BlockingHttpCallInAsyncFunction, + call.func.range(), + )); } } } diff --git a/crates/ruff_linter/src/rules/flake8_async/rules/blocking_os_call.rs b/crates/ruff_linter/src/rules/flake8_async/rules/blocking_os_call.rs index 48081ad5e3ef3..f5d86c0793910 100644 --- a/crates/ruff_linter/src/rules/flake8_async/rules/blocking_os_call.rs +++ b/crates/ruff_linter/src/rules/flake8_async/rules/blocking_os_call.rs @@ -1,5 +1,4 @@ -use ruff_python_ast as ast; -use ruff_python_ast::Expr; +use ruff_python_ast::ExprCall; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -42,19 +41,18 @@ impl Violation for BlockingOsCallInAsyncFunction { } /// ASYNC102 -pub(crate) fn blocking_os_call(checker: &mut Checker, expr: &Expr) { +pub(crate) fn blocking_os_call(checker: &mut Checker, call: &ExprCall) { if checker.semantic().in_async_context() { - if let Expr::Call(ast::ExprCall { func, .. }) = expr { - if checker - .semantic() - .resolve_call_path(func) - .as_ref() - .is_some_and(is_unsafe_os_method) - { - checker - .diagnostics - .push(Diagnostic::new(BlockingOsCallInAsyncFunction, func.range())); - } + if checker + .semantic() + .resolve_call_path(call.func.as_ref()) + .as_ref() + .is_some_and(is_unsafe_os_method) + { + checker.diagnostics.push(Diagnostic::new( + BlockingOsCallInAsyncFunction, + call.func.range(), + )); } } } diff --git a/crates/ruff_linter/src/rules/flake8_async/rules/open_sleep_or_subprocess_call.rs b/crates/ruff_linter/src/rules/flake8_async/rules/open_sleep_or_subprocess_call.rs index bdc05e598ec0a..b125e01afd5a2 100644 --- a/crates/ruff_linter/src/rules/flake8_async/rules/open_sleep_or_subprocess_call.rs +++ b/crates/ruff_linter/src/rules/flake8_async/rules/open_sleep_or_subprocess_call.rs @@ -1,5 +1,4 @@ -use ruff_python_ast as ast; -use ruff_python_ast::Expr; +use ruff_python_ast::ExprCall; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -42,20 +41,18 @@ impl Violation for OpenSleepOrSubprocessInAsyncFunction { } /// ASYNC101 -pub(crate) fn open_sleep_or_subprocess_call(checker: &mut Checker, expr: &Expr) { +pub(crate) fn open_sleep_or_subprocess_call(checker: &mut Checker, call: &ExprCall) { if checker.semantic().in_async_context() { - if let Expr::Call(ast::ExprCall { func, .. }) = expr { - if checker - .semantic() - .resolve_call_path(func) - .as_ref() - .is_some_and(is_open_sleep_or_subprocess_call) - { - checker.diagnostics.push(Diagnostic::new( - OpenSleepOrSubprocessInAsyncFunction, - func.range(), - )); - } + if checker + .semantic() + .resolve_call_path(call.func.as_ref()) + .as_ref() + .is_some_and(is_open_sleep_or_subprocess_call) + { + checker.diagnostics.push(Diagnostic::new( + OpenSleepOrSubprocessInAsyncFunction, + call.func.range(), + )); } } } diff --git a/crates/ruff_linter/src/rules/flake8_bandit/mod.rs b/crates/ruff_linter/src/rules/flake8_bandit/mod.rs index 8c64fd4d9fdcd..f915fd88190ad 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/mod.rs @@ -42,11 +42,13 @@ mod tests { #[test_case(Rule::SubprocessWithoutShellEqualsTrue, Path::new("S603.py"))] #[test_case(Rule::SuspiciousPickleUsage, Path::new("S301.py"))] #[test_case(Rule::SuspiciousEvalUsage, Path::new("S307.py"))] + #[test_case(Rule::SuspiciousURLOpenUsage, Path::new("S310.py"))] #[test_case(Rule::SuspiciousTelnetUsage, Path::new("S312.py"))] #[test_case(Rule::TryExceptContinue, Path::new("S112.py"))] #[test_case(Rule::TryExceptPass, Path::new("S110.py"))] #[test_case(Rule::UnixCommandWildcardInjection, Path::new("S609.py"))] #[test_case(Rule::UnsafeYAMLLoad, Path::new("S506.py"))] + #[test_case(Rule::WeakCryptographicKey, Path::new("S505.py"))] fn rules(rule_code: Rule, path: &Path) -> Result<()> { let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy()); let diagnostics = test_path( diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/bad_file_permissions.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/bad_file_permissions.rs index 0fdf07cd12751..61d5bbd77555c 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/rules/bad_file_permissions.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/bad_file_permissions.rs @@ -1,4 +1,4 @@ -use num_traits::ToPrimitive; +use anyhow::Result; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -36,17 +36,28 @@ use crate::checkers::ast::Checker; /// - [Common Weakness Enumeration: CWE-732](https://cwe.mitre.org/data/definitions/732.html) #[violation] pub struct BadFilePermissions { - mask: u16, + reason: Reason, } impl Violation for BadFilePermissions { #[derive_message_formats] fn message(&self) -> String { - let BadFilePermissions { mask } = self; - format!("`os.chmod` setting a permissive mask `{mask:#o}` on file or directory") + let BadFilePermissions { reason } = self; + match reason { + Reason::Permissive(mask) => { + format!("`os.chmod` setting a permissive mask `{mask:#o}` on file or directory") + } + Reason::Invalid => format!("`os.chmod` setting an invalid mask on file or directory"), + } } } +#[derive(Debug, PartialEq, Eq)] +enum Reason { + Permissive(u16), + Invalid, +} + /// S103 pub(crate) fn bad_file_permissions(checker: &mut Checker, call: &ast::ExprCall) { if checker @@ -55,10 +66,26 @@ pub(crate) fn bad_file_permissions(checker: &mut Checker, call: &ast::ExprCall) .is_some_and(|call_path| matches!(call_path.as_slice(), ["os", "chmod"])) { if let Some(mode_arg) = call.arguments.find_argument("mode", 1) { - if let Some(int_value) = int_value(mode_arg, checker.semantic()) { - if (int_value & WRITE_WORLD > 0) || (int_value & EXECUTE_GROUP > 0) { + match parse_mask(mode_arg, checker.semantic()) { + // The mask couldn't be determined (e.g., it's dynamic). + Ok(None) => {} + // The mask is a valid integer value -- check for overly permissive permissions. + Ok(Some(mask)) => { + if (mask & WRITE_WORLD > 0) || (mask & EXECUTE_GROUP > 0) { + checker.diagnostics.push(Diagnostic::new( + BadFilePermissions { + reason: Reason::Permissive(mask), + }, + mode_arg.range(), + )); + } + } + // The mask is an invalid integer value (i.e., it's out of range). + Err(_) => { checker.diagnostics.push(Diagnostic::new( - BadFilePermissions { mask: int_value }, + BadFilePermissions { + reason: Reason::Invalid, + }, mode_arg.range(), )); } @@ -113,28 +140,37 @@ fn py_stat(call_path: &CallPath) -> Option { } } -fn int_value(expr: &Expr, semantic: &SemanticModel) -> Option { +/// Return the mask value as a `u16`, if it can be determined. Returns an error if the mask is +/// an integer value, but that value is out of range. +fn parse_mask(expr: &Expr, semantic: &SemanticModel) -> Result> { match expr { Expr::Constant(ast::ExprConstant { - value: Constant::Int(value), + value: Constant::Int(int), .. - }) => value.to_u16(), - Expr::Attribute(_) => semantic.resolve_call_path(expr).as_ref().and_then(py_stat), + }) => match int.as_u16() { + Some(value) => Ok(Some(value)), + None => anyhow::bail!("int value out of range"), + }, + Expr::Attribute(_) => Ok(semantic.resolve_call_path(expr).as_ref().and_then(py_stat)), Expr::BinOp(ast::ExprBinOp { left, op, right, range: _, }) => { - let left_value = int_value(left, semantic)?; - let right_value = int_value(right, semantic)?; - match op { + let Some(left_value) = parse_mask(left, semantic)? else { + return Ok(None); + }; + let Some(right_value) = parse_mask(right, semantic)? else { + return Ok(None); + }; + Ok(match op { Operator::BitAnd => Some(left_value & right_value), Operator::BitOr => Some(left_value | right_value), Operator::BitXor => Some(left_value ^ right_value), _ => None, - } + }) } - _ => None, + _ => Ok(None), } } diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/mod.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/mod.rs index 8a467e169f7d2..24ad5a3721c85 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/rules/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/mod.rs @@ -22,6 +22,7 @@ pub(crate) use suspicious_function_call::*; pub(crate) use try_except_continue::*; pub(crate) use try_except_pass::*; pub(crate) use unsafe_yaml_load::*; +pub(crate) use weak_cryptographic_key::*; mod assert_used; mod bad_file_permissions; @@ -47,3 +48,4 @@ mod suspicious_function_call; mod try_except_continue; mod try_except_pass; mod unsafe_yaml_load; +mod weak_cryptographic_key; diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/shell_injection.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/shell_injection.rs index fa9e01829c0a1..6fde131b5b4fc 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/rules/shell_injection.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/shell_injection.rs @@ -88,6 +88,32 @@ impl Violation for SubprocessWithoutShellEqualsTrue { } } +/// ## What it does +/// Checks for method calls that set the `shell` parameter to `true` when +/// invoking a subprocess. +/// +/// ## Why is this bad? +/// Setting the `shell` parameter to `true` when invoking a subprocess can +/// introduce security vulnerabilities, as it allows shell metacharacters and +/// whitespace to be passed to child processes, potentially leading to shell +/// injection attacks. It is recommended to avoid using `shell=True` unless +/// absolutely necessary, and when used, to ensure that all inputs are properly +/// sanitized and quoted to prevent such vulnerabilities. +/// +/// ## Known problems +/// Prone to false positives as it is triggered on any function call with a +/// `shell=True` parameter. +/// +/// ## Example +/// ```python +/// import subprocess +/// +/// user_input = input("Enter a command: ") +/// subprocess.run(user_input, shell=True) +/// ``` +/// +/// ## References +/// - [Python documentation: Security Considerations](https://docs.python.org/3/library/subprocess.html#security-considerations) #[violation] pub struct CallWithShellEqualsTrue; @@ -98,6 +124,42 @@ impl Violation for CallWithShellEqualsTrue { } } +/// ## What it does +/// Checks for calls that start a process with a shell, providing guidance on +/// whether the usage is safe or not. +/// +/// ## Why is this bad? +/// Starting a process with a shell can introduce security risks, such as +/// code injection vulnerabilities. It's important to be aware of whether the +/// usage of the shell is safe or not. +/// +/// This rule triggers on functions like `os.system`, `popen`, etc., which +/// start processes with a shell. It evaluates whether the provided command +/// is a literal string or an expression. If the command is a literal string, +/// it's considered safe. If the command is an expression, it's considered +/// (potentially) unsafe. +/// +/// ## Example +/// ```python +/// import os +/// +/// # Safe usage (literal string) +/// command = "ls -l" +/// os.system(command) +/// +/// # Potentially unsafe usage (expression) +/// cmd = get_user_input() +/// os.system(cmd) +/// ``` +/// +/// ## Note +/// The `subprocess` module provides more powerful facilities for spawning new +/// processes and retrieving their results, and using that module is preferable +/// to using `os.system` or similar functions. Consider replacing such usages +/// with `subprocess.call` or related functions. +/// +/// ## References +/// - [Python documentation: `subprocess`](https://docs.python.org/3/library/subprocess.html) #[violation] pub struct StartProcessWithAShell { seems_safe: bool, @@ -114,6 +176,26 @@ impl Violation for StartProcessWithAShell { } } +/// ## What it does +/// Checks for functions that start a process without a shell. +/// +/// ## Why is this bad? +/// The `subprocess` module provides more powerful facilities for spawning new +/// processes and retrieving their results; using that module is preferable to +/// using these functions. +/// +/// ## Example +/// ```python +/// os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg") +/// ``` +/// +/// Use instead: +/// ```python +/// subprocess.Popen(["/bin/mycmd", "myarg"]) +/// ``` +/// +/// ## References +/// - [Python documentation: Replacing the `os.spawn` family](https://docs.python.org/3/library/subprocess.html#replacing-the-os-spawn-family) #[violation] pub struct StartProcessWithNoShell; diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/snmp_insecure_version.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/snmp_insecure_version.rs index 6e6b2b8aed620..62ec65103bc03 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/rules/snmp_insecure_version.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/snmp_insecure_version.rs @@ -1,8 +1,6 @@ -use num_traits::{One, Zero}; - use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::{self as ast, Constant, Expr}; +use ruff_python_ast::{self as ast, Constant, Expr, Int}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -52,16 +50,16 @@ pub(crate) fn snmp_insecure_version(checker: &mut Checker, call: &ast::ExprCall) }) { if let Some(keyword) = call.arguments.find_keyword("mpModel") { - if let Expr::Constant(ast::ExprConstant { - value: Constant::Int(value), - .. - }) = &keyword.value - { - if value.is_zero() || value.is_one() { - checker - .diagnostics - .push(Diagnostic::new(SnmpInsecureVersion, keyword.range())); - } + if matches!( + keyword.value, + Expr::Constant(ast::ExprConstant { + value: Constant::Int(Int::ZERO | Int::ONE), + .. + }) + ) { + checker + .diagnostics + .push(Diagnostic::new(SnmpInsecureVersion, keyword.range())); } } } diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/ssh_no_host_key_verification.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/ssh_no_host_key_verification.rs index d653fdf6586e6..ba7cdf6134095 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/rules/ssh_no_host_key_verification.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/ssh_no_host_key_verification.rs @@ -1,5 +1,6 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::helpers::map_callable; use ruff_python_ast::{Expr, ExprAttribute, ExprCall}; use ruff_python_semantic::analyze::typing; use ruff_text_size::Ranged; @@ -56,13 +57,15 @@ pub(crate) fn ssh_no_host_key_verification(checker: &mut Checker, call: &ExprCal return; }; + // Detect either, e.g., `paramiko.client.AutoAddPolicy` or `paramiko.client.AutoAddPolicy()`. if !checker .semantic() - .resolve_call_path(policy_argument) + .resolve_call_path(map_callable(policy_argument)) .is_some_and(|call_path| { matches!( call_path.as_slice(), ["paramiko", "client", "AutoAddPolicy" | "WarningPolicy"] + | ["paramiko", "AutoAddPolicy" | "WarningPolicy"] ) }) { @@ -70,7 +73,10 @@ pub(crate) fn ssh_no_host_key_verification(checker: &mut Checker, call: &ExprCal } if typing::resolve_assignment(value, checker.semantic()).is_some_and(|call_path| { - matches!(call_path.as_slice(), ["paramiko", "client", "SSHClient"]) + matches!( + call_path.as_slice(), + ["paramiko", "client", "SSHClient"] | ["paramiko", "SSHClient"] + ) }) { checker.diagnostics.push(Diagnostic::new( SSHNoHostKeyVerification, diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/suspicious_function_call.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/suspicious_function_call.rs index bb24f3b9a46b4..50260a7f8fa17 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/rules/suspicious_function_call.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/suspicious_function_call.rs @@ -1,10 +1,9 @@ //! Check for calls to suspicious functions, or calls into suspicious modules. //! //! See: -use ruff_python_ast::{self as ast, Expr}; - use ruff_diagnostics::{Diagnostic, DiagnosticKind, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, Expr, ExprCall}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -825,12 +824,8 @@ impl Violation for SuspiciousFTPLibUsage { } /// S301, S302, S303, S304, S305, S306, S307, S308, S310, S311, S312, S313, S314, S315, S316, S317, S318, S319, S320, S321, S323 -pub(crate) fn suspicious_function_call(checker: &mut Checker, expr: &Expr) { - let Expr::Call(ast::ExprCall { func, .. }) = expr else { - return; - }; - - let Some(diagnostic_kind) = checker.semantic().resolve_call_path(func).and_then(|call_path| { +pub(crate) fn suspicious_function_call(checker: &mut Checker, call: &ExprCall) { + let Some(diagnostic_kind) = checker.semantic().resolve_call_path(call.func.as_ref()).and_then(|call_path| { match call_path.as_slice() { // Pickle ["pickle" | "dill", "load" | "loads" | "Unpickler"] | @@ -854,10 +849,23 @@ pub(crate) fn suspicious_function_call(checker: &mut Checker, expr: &Expr) { ["" | "builtins", "eval"] => Some(SuspiciousEvalUsage.into()), // MarkSafe ["django", "utils", "safestring", "mark_safe"] => Some(SuspiciousMarkSafeUsage.into()), - // URLOpen - ["urllib", "urlopen" | "urlretrieve" | "URLopener" | "FancyURLopener" | "Request"] | - ["urllib", "request", "urlopen" | "urlretrieve" | "URLopener" | "FancyURLopener"] | - ["six", "moves", "urllib", "request", "urlopen" | "urlretrieve" | "URLopener" | "FancyURLopener"] => Some(SuspiciousURLOpenUsage.into()), + // URLOpen (`urlopen`, `urlretrieve`, `Request`) + ["urllib", "request", "urlopen" | "urlretrieve" | "Request"] | + ["six", "moves", "urllib", "request", "urlopen" | "urlretrieve" | "Request"] => { + // If the `url` argument is a string literal, allow `http` and `https` schemes. + if call.arguments.args.iter().all(|arg| !arg.is_starred_expr()) && call.arguments.keywords.iter().all(|keyword| keyword.arg.is_some()) { + if let Some(Expr::Constant(ast::ExprConstant { value: ast::Constant::Str(url), .. })) = &call.arguments.find_argument("url", 0) { + let url = url.trim_start(); + if url.starts_with("http://") || url.starts_with("https://") { + return None; + } + } + } + Some(SuspiciousURLOpenUsage.into()) + }, + // URLOpen (`URLopener`, `FancyURLopener`) + ["urllib", "request", "URLopener" | "FancyURLopener"] | + ["six", "moves", "urllib", "request", "URLopener" | "FancyURLopener"] => Some(SuspiciousURLOpenUsage.into()), // NonCryptographicRandom ["random", "random" | "randrange" | "randint" | "choice" | "choices" | "uniform" | "triangular"] => Some(SuspiciousNonCryptographicRandomUsage.into()), // UnverifiedContext @@ -888,7 +896,7 @@ pub(crate) fn suspicious_function_call(checker: &mut Checker, expr: &Expr) { return; }; - let diagnostic = Diagnostic::new::(diagnostic_kind, expr.range()); + let diagnostic = Diagnostic::new::(diagnostic_kind, call.range()); if checker.enabled(diagnostic.kind.rule()) { checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/weak_cryptographic_key.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/weak_cryptographic_key.rs new file mode 100644 index 0000000000000..af4ae9f3d6342 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/weak_cryptographic_key.rs @@ -0,0 +1,162 @@ +use std::fmt::{Display, Formatter}; + +use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, Constant, Expr, ExprAttribute, ExprCall}; +use ruff_text_size::{Ranged, TextRange}; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for uses of cryptographic keys with vulnerable key sizes. +/// +/// ## Why is this bad? +/// Small keys are easily breakable. For DSA and RSA, keys should be at least +/// 2048 bits long. For EC, keys should be at least 224 bits long. +/// +/// ## Example +/// ```python +/// from cryptography.hazmat.primitives.asymmetric import dsa, ec +/// +/// dsa.generate_private_key(key_size=512) +/// ec.generate_private_key(curve=ec.SECT163K1) +/// ``` +/// +/// Use instead: +/// ```python +/// from cryptography.hazmat.primitives.asymmetric import dsa, ec +/// +/// dsa.generate_private_key(key_size=4096) +/// ec.generate_private_key(curve=ec.SECP384R1) +/// ``` +/// +/// ## References +/// - [CSRC: Transitioning the Use of Cryptographic Algorithms and Key Lengths](https://csrc.nist.gov/pubs/sp/800/131/a/r2/final) +#[violation] +pub struct WeakCryptographicKey { + cryptographic_key: CryptographicKey, +} + +impl Violation for WeakCryptographicKey { + #[derive_message_formats] + fn message(&self) -> String { + let WeakCryptographicKey { cryptographic_key } = self; + let minimum_key_size = cryptographic_key.minimum_key_size(); + format!( + "{cryptographic_key} key sizes below {minimum_key_size} bits are considered breakable" + ) + } +} + +/// S505 +pub(crate) fn weak_cryptographic_key(checker: &mut Checker, call: &ExprCall) { + let Some((cryptographic_key, range)) = extract_cryptographic_key(checker, call) else { + return; + }; + + if cryptographic_key.is_vulnerable() { + checker.diagnostics.push(Diagnostic::new( + WeakCryptographicKey { cryptographic_key }, + range, + )); + } +} + +#[derive(Debug, PartialEq, Eq)] +enum CryptographicKey { + Dsa { key_size: u16 }, + Ec { algorithm: String }, + Rsa { key_size: u16 }, +} + +impl CryptographicKey { + const fn minimum_key_size(&self) -> u16 { + match self { + Self::Dsa { .. } | Self::Rsa { .. } => 2048, + Self::Ec { .. } => 224, + } + } + + fn is_vulnerable(&self) -> bool { + match self { + Self::Dsa { key_size } | Self::Rsa { key_size } => key_size < &self.minimum_key_size(), + Self::Ec { algorithm } => { + matches!(algorithm.as_str(), "SECP192R1" | "SECT163K1" | "SECT163R2") + } + } + } +} + +impl Display for CryptographicKey { + fn fmt(&self, fmt: &mut Formatter) -> std::fmt::Result { + match self { + CryptographicKey::Dsa { .. } => fmt.write_str("DSA"), + CryptographicKey::Ec { .. } => fmt.write_str("EC"), + CryptographicKey::Rsa { .. } => fmt.write_str("RSA"), + } + } +} + +fn extract_cryptographic_key( + checker: &mut Checker, + call: &ExprCall, +) -> Option<(CryptographicKey, TextRange)> { + let call_path = checker.semantic().resolve_call_path(&call.func)?; + match call_path.as_slice() { + ["cryptography", "hazmat", "primitives", "asymmetric", function, "generate_private_key"] => { + match *function { + "dsa" => { + let (key_size, range) = extract_int_argument(call, "key_size", 0)?; + Some((CryptographicKey::Dsa { key_size }, range)) + } + "rsa" => { + let (key_size, range) = extract_int_argument(call, "key_size", 1)?; + Some((CryptographicKey::Rsa { key_size }, range)) + } + "ec" => { + let argument = call.arguments.find_argument("curve", 0)?; + let ExprAttribute { attr, value, .. } = argument.as_attribute_expr()?; + let call_path = checker.semantic().resolve_call_path(value)?; + if matches!( + call_path.as_slice(), + ["cryptography", "hazmat", "primitives", "asymmetric", "ec"] + ) { + Some(( + CryptographicKey::Ec { + algorithm: attr.to_string(), + }, + argument.range(), + )) + } else { + None + } + } + _ => None, + } + } + ["Crypto" | "Cryptodome", "PublicKey", function, "generate"] => match *function { + "DSA" => { + let (key_size, range) = extract_int_argument(call, "bits", 0)?; + Some((CryptographicKey::Dsa { key_size }, range)) + } + "RSA" => { + let (key_size, range) = extract_int_argument(call, "bits", 0)?; + Some((CryptographicKey::Dsa { key_size }, range)) + } + _ => None, + }, + _ => None, + } +} + +fn extract_int_argument(call: &ExprCall, name: &str, position: usize) -> Option<(u16, TextRange)> { + let argument = call.arguments.find_argument(name, position)?; + let Expr::Constant(ast::ExprConstant { + value: Constant::Int(i), + .. + }) = argument + else { + return None; + }; + Some((i.as_u16()?, argument.range())) +} diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S103_S103.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S103_S103.py.snap index 60379d8f1ceee..b3da522349858 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S103_S103.py.snap +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S103_S103.py.snap @@ -126,6 +126,15 @@ S103.py:22:25: S103 `os.chmod` setting a permissive mask `0o2` on file or direct 21 | os.chmod("~/hidden_exec", stat.S_IXOTH) # OK 22 | os.chmod("/etc/passwd", stat.S_IWOTH) # Error | ^^^^^^^^^^^^ S103 +23 | os.chmod("/etc/passwd", 0o100000000) # Error + | + +S103.py:23:25: S103 `os.chmod` setting an invalid mask on file or directory + | +21 | os.chmod("~/hidden_exec", stat.S_IXOTH) # OK +22 | os.chmod("/etc/passwd", stat.S_IWOTH) # Error +23 | os.chmod("/etc/passwd", 0o100000000) # Error + | ^^^^^^^^^^^ S103 | diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S310_S310.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S310_S310.py.snap new file mode 100644 index 0000000000000..ddf363cb4b608 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S310_S310.py.snap @@ -0,0 +1,107 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S310.py:4:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected. + | +3 | urllib.request.urlopen(url='http://www.google.com') +4 | urllib.request.urlopen(url='http://www.google.com', **kwargs) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310 +5 | urllib.request.urlopen('http://www.google.com') +6 | urllib.request.urlopen('file:///foo/bar/baz') + | + +S310.py:6:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected. + | +4 | urllib.request.urlopen(url='http://www.google.com', **kwargs) +5 | urllib.request.urlopen('http://www.google.com') +6 | urllib.request.urlopen('file:///foo/bar/baz') + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310 +7 | urllib.request.urlopen(url) + | + +S310.py:7:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected. + | +5 | urllib.request.urlopen('http://www.google.com') +6 | urllib.request.urlopen('file:///foo/bar/baz') +7 | urllib.request.urlopen(url) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310 +8 | +9 | urllib.request.Request(url='http://www.google.com', **kwargs) + | + +S310.py:9:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected. + | + 7 | urllib.request.urlopen(url) + 8 | + 9 | urllib.request.Request(url='http://www.google.com', **kwargs) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310 +10 | urllib.request.Request(url='http://www.google.com') +11 | urllib.request.Request('http://www.google.com') + | + +S310.py:12:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected. + | +10 | urllib.request.Request(url='http://www.google.com') +11 | urllib.request.Request('http://www.google.com') +12 | urllib.request.Request('file:///foo/bar/baz') + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310 +13 | urllib.request.Request(url) + | + +S310.py:13:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected. + | +11 | urllib.request.Request('http://www.google.com') +12 | urllib.request.Request('file:///foo/bar/baz') +13 | urllib.request.Request(url) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ S310 +14 | +15 | urllib.request.URLopener().open(fullurl='http://www.google.com', **kwargs) + | + +S310.py:15:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected. + | +13 | urllib.request.Request(url) +14 | +15 | urllib.request.URLopener().open(fullurl='http://www.google.com', **kwargs) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310 +16 | urllib.request.URLopener().open(fullurl='http://www.google.com') +17 | urllib.request.URLopener().open('http://www.google.com') + | + +S310.py:16:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected. + | +15 | urllib.request.URLopener().open(fullurl='http://www.google.com', **kwargs) +16 | urllib.request.URLopener().open(fullurl='http://www.google.com') + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310 +17 | urllib.request.URLopener().open('http://www.google.com') +18 | urllib.request.URLopener().open('file:///foo/bar/baz') + | + +S310.py:17:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected. + | +15 | urllib.request.URLopener().open(fullurl='http://www.google.com', **kwargs) +16 | urllib.request.URLopener().open(fullurl='http://www.google.com') +17 | urllib.request.URLopener().open('http://www.google.com') + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310 +18 | urllib.request.URLopener().open('file:///foo/bar/baz') +19 | urllib.request.URLopener().open(url) + | + +S310.py:18:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected. + | +16 | urllib.request.URLopener().open(fullurl='http://www.google.com') +17 | urllib.request.URLopener().open('http://www.google.com') +18 | urllib.request.URLopener().open('file:///foo/bar/baz') + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310 +19 | urllib.request.URLopener().open(url) + | + +S310.py:19:1: S310 Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected. + | +17 | urllib.request.URLopener().open('http://www.google.com') +18 | urllib.request.URLopener().open('file:///foo/bar/baz') +19 | urllib.request.URLopener().open(url) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ S310 + | + + diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S505_S505.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S505_S505.py.snap new file mode 100644 index 0000000000000..bc14a8556f74a --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S505_S505.py.snap @@ -0,0 +1,142 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs +--- +S505.py:29:35: S505 DSA key sizes below 2048 bits are considered breakable + | +28 | # Errors +29 | dsa.generate_private_key(key_size=2047, backend=backends.default_backend()) + | ^^^^ S505 +30 | ec.generate_private_key(curve=ec.SECT163R2, backend=backends.default_backend()) +31 | rsa.generate_private_key( + | + +S505.py:30:31: S505 EC key sizes below 224 bits are considered breakable + | +28 | # Errors +29 | dsa.generate_private_key(key_size=2047, backend=backends.default_backend()) +30 | ec.generate_private_key(curve=ec.SECT163R2, backend=backends.default_backend()) + | ^^^^^^^^^^^^ S505 +31 | rsa.generate_private_key( +32 | public_exponent=65537, key_size=2047, backend=backends.default_backend() + | + +S505.py:32:37: S505 RSA key sizes below 2048 bits are considered breakable + | +30 | ec.generate_private_key(curve=ec.SECT163R2, backend=backends.default_backend()) +31 | rsa.generate_private_key( +32 | public_exponent=65537, key_size=2047, backend=backends.default_backend() + | ^^^^ S505 +33 | ) +34 | pycrypto_dsa.generate(bits=2047) + | + +S505.py:34:28: S505 DSA key sizes below 2048 bits are considered breakable + | +32 | public_exponent=65537, key_size=2047, backend=backends.default_backend() +33 | ) +34 | pycrypto_dsa.generate(bits=2047) + | ^^^^ S505 +35 | pycrypto_rsa.generate(bits=2047) +36 | pycryptodomex_dsa.generate(bits=2047) + | + +S505.py:35:28: S505 DSA key sizes below 2048 bits are considered breakable + | +33 | ) +34 | pycrypto_dsa.generate(bits=2047) +35 | pycrypto_rsa.generate(bits=2047) + | ^^^^ S505 +36 | pycryptodomex_dsa.generate(bits=2047) +37 | pycryptodomex_rsa.generate(bits=2047) + | + +S505.py:36:33: S505 DSA key sizes below 2048 bits are considered breakable + | +34 | pycrypto_dsa.generate(bits=2047) +35 | pycrypto_rsa.generate(bits=2047) +36 | pycryptodomex_dsa.generate(bits=2047) + | ^^^^ S505 +37 | pycryptodomex_rsa.generate(bits=2047) +38 | dsa.generate_private_key(2047, backends.default_backend()) + | + +S505.py:37:33: S505 DSA key sizes below 2048 bits are considered breakable + | +35 | pycrypto_rsa.generate(bits=2047) +36 | pycryptodomex_dsa.generate(bits=2047) +37 | pycryptodomex_rsa.generate(bits=2047) + | ^^^^ S505 +38 | dsa.generate_private_key(2047, backends.default_backend()) +39 | ec.generate_private_key(ec.SECT163R2, backends.default_backend()) + | + +S505.py:38:26: S505 DSA key sizes below 2048 bits are considered breakable + | +36 | pycryptodomex_dsa.generate(bits=2047) +37 | pycryptodomex_rsa.generate(bits=2047) +38 | dsa.generate_private_key(2047, backends.default_backend()) + | ^^^^ S505 +39 | ec.generate_private_key(ec.SECT163R2, backends.default_backend()) +40 | rsa.generate_private_key(3, 2047, backends.default_backend()) + | + +S505.py:39:25: S505 EC key sizes below 224 bits are considered breakable + | +37 | pycryptodomex_rsa.generate(bits=2047) +38 | dsa.generate_private_key(2047, backends.default_backend()) +39 | ec.generate_private_key(ec.SECT163R2, backends.default_backend()) + | ^^^^^^^^^^^^ S505 +40 | rsa.generate_private_key(3, 2047, backends.default_backend()) +41 | pycrypto_dsa.generate(2047) + | + +S505.py:40:29: S505 RSA key sizes below 2048 bits are considered breakable + | +38 | dsa.generate_private_key(2047, backends.default_backend()) +39 | ec.generate_private_key(ec.SECT163R2, backends.default_backend()) +40 | rsa.generate_private_key(3, 2047, backends.default_backend()) + | ^^^^ S505 +41 | pycrypto_dsa.generate(2047) +42 | pycrypto_rsa.generate(2047) + | + +S505.py:41:23: S505 DSA key sizes below 2048 bits are considered breakable + | +39 | ec.generate_private_key(ec.SECT163R2, backends.default_backend()) +40 | rsa.generate_private_key(3, 2047, backends.default_backend()) +41 | pycrypto_dsa.generate(2047) + | ^^^^ S505 +42 | pycrypto_rsa.generate(2047) +43 | pycryptodomex_dsa.generate(2047) + | + +S505.py:42:23: S505 DSA key sizes below 2048 bits are considered breakable + | +40 | rsa.generate_private_key(3, 2047, backends.default_backend()) +41 | pycrypto_dsa.generate(2047) +42 | pycrypto_rsa.generate(2047) + | ^^^^ S505 +43 | pycryptodomex_dsa.generate(2047) +44 | pycryptodomex_rsa.generate(2047) + | + +S505.py:43:28: S505 DSA key sizes below 2048 bits are considered breakable + | +41 | pycrypto_dsa.generate(2047) +42 | pycrypto_rsa.generate(2047) +43 | pycryptodomex_dsa.generate(2047) + | ^^^^ S505 +44 | pycryptodomex_rsa.generate(2047) + | + +S505.py:44:28: S505 DSA key sizes below 2048 bits are considered breakable + | +42 | pycrypto_rsa.generate(2047) +43 | pycryptodomex_dsa.generate(2047) +44 | pycryptodomex_rsa.generate(2047) + | ^^^^ S505 +45 | +46 | # Don't crash when the size is variable. + | + + diff --git a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S507_S507.py.snap b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S507_S507.py.snap index bd590f67eaad3..6ff5a45021d54 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S507_S507.py.snap +++ b/crates/ruff_linter/src/rules/flake8_bandit/snapshots/ruff_linter__rules__flake8_bandit__tests__S507_S507.py.snap @@ -1,62 +1,82 @@ --- source: crates/ruff_linter/src/rules/flake8_bandit/mod.rs --- -S507.py:13:40: S507 Paramiko call with policy set to automatically trust the unknown host key +S507.py:15:40: S507 Paramiko call with policy set to automatically trust the unknown host key | -12 | # Errors -13 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy) +14 | # Errors +15 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy) | ^^^^^^^^^^^^^^^^^^^^ S507 -14 | ssh_client.set_missing_host_key_policy(client.WarningPolicy) -15 | ssh_client.set_missing_host_key_policy(AutoAddPolicy) +16 | ssh_client.set_missing_host_key_policy(client.WarningPolicy) +17 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy()) | -S507.py:14:40: S507 Paramiko call with policy set to automatically trust the unknown host key +S507.py:16:40: S507 Paramiko call with policy set to automatically trust the unknown host key | -12 | # Errors -13 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy) -14 | ssh_client.set_missing_host_key_policy(client.WarningPolicy) +14 | # Errors +15 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy) +16 | ssh_client.set_missing_host_key_policy(client.WarningPolicy) | ^^^^^^^^^^^^^^^^^^^^ S507 -15 | ssh_client.set_missing_host_key_policy(AutoAddPolicy) -16 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) +17 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy()) +18 | ssh_client.set_missing_host_key_policy(AutoAddPolicy) | -S507.py:15:40: S507 Paramiko call with policy set to automatically trust the unknown host key +S507.py:17:40: S507 Paramiko call with policy set to automatically trust the unknown host key + | +15 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy) +16 | ssh_client.set_missing_host_key_policy(client.WarningPolicy) +17 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy()) + | ^^^^^^^^^^^^^^^^^^^^^^ S507 +18 | ssh_client.set_missing_host_key_policy(AutoAddPolicy) +19 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) + | + +S507.py:18:40: S507 Paramiko call with policy set to automatically trust the unknown host key | -13 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy) -14 | ssh_client.set_missing_host_key_policy(client.WarningPolicy) -15 | ssh_client.set_missing_host_key_policy(AutoAddPolicy) +16 | ssh_client.set_missing_host_key_policy(client.WarningPolicy) +17 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy()) +18 | ssh_client.set_missing_host_key_policy(AutoAddPolicy) | ^^^^^^^^^^^^^ S507 -16 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) -17 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) +19 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) +20 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) | -S507.py:16:47: S507 Paramiko call with policy set to automatically trust the unknown host key +S507.py:19:47: S507 Paramiko call with policy set to automatically trust the unknown host key | -14 | ssh_client.set_missing_host_key_policy(client.WarningPolicy) -15 | ssh_client.set_missing_host_key_policy(AutoAddPolicy) -16 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) +17 | ssh_client.set_missing_host_key_policy(client.AutoAddPolicy()) +18 | ssh_client.set_missing_host_key_policy(AutoAddPolicy) +19 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) | ^^^^^^^^^^^^^^^^^^^^ S507 -17 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) -18 | ssh_client.set_missing_host_key_policy(policy=WarningPolicy) +20 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) +21 | ssh_client.set_missing_host_key_policy(policy=WarningPolicy) | -S507.py:17:47: S507 Paramiko call with policy set to automatically trust the unknown host key +S507.py:20:47: S507 Paramiko call with policy set to automatically trust the unknown host key | -15 | ssh_client.set_missing_host_key_policy(AutoAddPolicy) -16 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) -17 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) +18 | ssh_client.set_missing_host_key_policy(AutoAddPolicy) +19 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) +20 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) | ^^^^^^^^^^^^^^^^^^^^ S507 -18 | ssh_client.set_missing_host_key_policy(policy=WarningPolicy) +21 | ssh_client.set_missing_host_key_policy(policy=WarningPolicy) +22 | ssh_client_from_paramiko.set_missing_host_key_policy(paramiko.AutoAddPolicy) | -S507.py:18:47: S507 Paramiko call with policy set to automatically trust the unknown host key +S507.py:21:47: S507 Paramiko call with policy set to automatically trust the unknown host key | -16 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) -17 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) -18 | ssh_client.set_missing_host_key_policy(policy=WarningPolicy) +19 | ssh_client.set_missing_host_key_policy(policy=client.AutoAddPolicy) +20 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) +21 | ssh_client.set_missing_host_key_policy(policy=WarningPolicy) | ^^^^^^^^^^^^^ S507 -19 | -20 | # Unrelated +22 | ssh_client_from_paramiko.set_missing_host_key_policy(paramiko.AutoAddPolicy) + | + +S507.py:22:54: S507 Paramiko call with policy set to automatically trust the unknown host key + | +20 | ssh_client.set_missing_host_key_policy(policy=client.WarningPolicy) +21 | ssh_client.set_missing_host_key_policy(policy=WarningPolicy) +22 | ssh_client_from_paramiko.set_missing_host_key_policy(paramiko.AutoAddPolicy) + | ^^^^^^^^^^^^^^^^^^^^^^ S507 +23 | +24 | # Unrelated | diff --git a/crates/ruff_linter/src/rules/flake8_blind_except/rules/blind_except.rs b/crates/ruff_linter/src/rules/flake8_blind_except/rules/blind_except.rs index 0dece92c29397..102f40be9913e 100644 --- a/crates/ruff_linter/src/rules/flake8_blind_except/rules/blind_except.rs +++ b/crates/ruff_linter/src/rules/flake8_blind_except/rules/blind_except.rs @@ -98,24 +98,49 @@ pub(crate) fn blind_except( func, arguments, .. }) = value.as_ref() { - if logging::is_logger_candidate( - func, - checker.semantic(), - &checker.settings.logger_objects, - ) { - if let Some(attribute) = func.as_attribute_expr() { - let attr = attribute.attr.as_str(); - if attr == "exception" { - return true; - } - if attr == "error" { - if let Some(keyword) = arguments.find_keyword("exc_info") { - if is_const_true(&keyword.value) { - return true; + match func.as_ref() { + Expr::Attribute(ast::ExprAttribute { attr, .. }) => { + if logging::is_logger_candidate( + func, + checker.semantic(), + &checker.settings.logger_objects, + ) { + match attr.as_str() { + "exception" => return true, + "error" => { + if let Some(keyword) = arguments.find_keyword("exc_info") { + if is_const_true(&keyword.value) { + return true; + } + } } + _ => {} } } } + Expr::Name(ast::ExprName { .. }) => { + if checker + .semantic() + .resolve_call_path(func.as_ref()) + .is_some_and(|call_path| match call_path.as_slice() { + ["logging", "exception"] => true, + ["logging", "error"] => { + if let Some(keyword) = arguments.find_keyword("exc_info") { + if is_const_true(&keyword.value) { + return true; + } + } + false + } + _ => false, + }) + { + return true; + } + } + _ => { + return false; + } } } } diff --git a/crates/ruff_linter/src/rules/flake8_blind_except/snapshots/ruff_linter__rules__flake8_blind_except__tests__BLE001_BLE.py.snap b/crates/ruff_linter/src/rules/flake8_blind_except/snapshots/ruff_linter__rules__flake8_blind_except__tests__BLE001_BLE.py.snap index 0555d9a748f6b..16313b5f91537 100644 --- a/crates/ruff_linter/src/rules/flake8_blind_except/snapshots/ruff_linter__rules__flake8_blind_except__tests__BLE001_BLE.py.snap +++ b/crates/ruff_linter/src/rules/flake8_blind_except/snapshots/ruff_linter__rules__flake8_blind_except__tests__BLE001_BLE.py.snap @@ -94,4 +94,31 @@ BLE.py:81:8: BLE001 Do not catch blind exception: `Exception` 82 | logging.error("...", exc_info=None) | +BLE.py:101:8: BLE001 Do not catch blind exception: `Exception` + | + 99 | try: +100 | pass +101 | except Exception: + | ^^^^^^^^^ BLE001 +102 | error("...") + | + +BLE.py:107:8: BLE001 Do not catch blind exception: `Exception` + | +105 | try: +106 | pass +107 | except Exception: + | ^^^^^^^^^ BLE001 +108 | error("...", exc_info=False) + | + +BLE.py:113:8: BLE001 Do not catch blind exception: `Exception` + | +111 | try: +112 | pass +113 | except Exception: + | ^^^^^^^^^ BLE001 +114 | error("...", exc_info=None) + | + diff --git a/crates/ruff_linter/src/rules/flake8_boolean_trap/helpers.rs b/crates/ruff_linter/src/rules/flake8_boolean_trap/helpers.rs index 8ff583d7fbd78..038ab49c12d2a 100644 --- a/crates/ruff_linter/src/rules/flake8_boolean_trap/helpers.rs +++ b/crates/ruff_linter/src/rules/flake8_boolean_trap/helpers.rs @@ -12,6 +12,7 @@ pub(super) fn is_allowed_func_call(name: &str) -> bool { | "assertNotEquals" | "bool" | "bytes" + | "coalesce" | "count" | "failIfEqual" | "failUnlessEqual" @@ -22,12 +23,15 @@ pub(super) fn is_allowed_func_call(name: &str) -> bool { | "getboolean" | "getfloat" | "getint" + | "ifnull" | "index" | "insert" | "int" | "is_" | "is_not" + | "isnull" | "next" + | "nvl" | "param" | "pop" | "remove" diff --git a/crates/ruff_linter/src/rules/flake8_boolean_trap/snapshots/ruff_linter__rules__flake8_boolean_trap__tests__FBT001_FBT.py.snap b/crates/ruff_linter/src/rules/flake8_boolean_trap/snapshots/ruff_linter__rules__flake8_boolean_trap__tests__FBT001_FBT.py.snap index b1f894ec5c32a..fe9adc83fc21f 100644 --- a/crates/ruff_linter/src/rules/flake8_boolean_trap/snapshots/ruff_linter__rules__flake8_boolean_trap__tests__FBT001_FBT.py.snap +++ b/crates/ruff_linter/src/rules/flake8_boolean_trap/snapshots/ruff_linter__rules__flake8_boolean_trap__tests__FBT001_FBT.py.snap @@ -81,12 +81,12 @@ FBT.py:19:5: FBT001 Boolean-typed positional argument in function definition 21 | kwonly_nonvalued_nohint, | -FBT.py:87:19: FBT001 Boolean-typed positional argument in function definition +FBT.py:89:19: FBT001 Boolean-typed positional argument in function definition | -86 | # FBT001: Boolean positional arg in function definition -87 | def foo(self, value: bool) -> None: +88 | # FBT001: Boolean positional arg in function definition +89 | def foo(self, value: bool) -> None: | ^^^^^ FBT001 -88 | pass +90 | pass | diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/mod.rs b/crates/ruff_linter/src/rules/flake8_bugbear/mod.rs index 8ce32f9e071fc..e31681ca43a5b 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/mod.rs @@ -37,6 +37,9 @@ mod tests { #[test_case(Rule::MutableArgumentDefault, Path::new("B006_2.py"))] #[test_case(Rule::MutableArgumentDefault, Path::new("B006_3.py"))] #[test_case(Rule::MutableArgumentDefault, Path::new("B006_4.py"))] + #[test_case(Rule::MutableArgumentDefault, Path::new("B006_5.py"))] + #[test_case(Rule::MutableArgumentDefault, Path::new("B006_6.py"))] + #[test_case(Rule::MutableArgumentDefault, Path::new("B006_7.py"))] #[test_case(Rule::NoExplicitStacklevel, Path::new("B028.py"))] #[test_case(Rule::RaiseLiteral, Path::new("B016.py"))] #[test_case(Rule::RaiseWithoutFromInsideExcept, Path::new("B904.py"))] diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/assert_false.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/assert_false.rs index 209a79d719895..92c22e01fb7f5 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/assert_false.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/assert_false.rs @@ -1,12 +1,11 @@ use ruff_python_ast::{self as ast, Arguments, Expr, ExprContext, Stmt}; use ruff_text_size::{Ranged, TextRange}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::is_const_false; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of `assert False`. @@ -33,13 +32,13 @@ use crate::registry::AsRule; #[violation] pub struct AssertFalse; -impl AlwaysAutofixableViolation for AssertFalse { +impl AlwaysFixableViolation for AssertFalse { #[derive_message_formats] fn message(&self) -> String { format!("Do not `assert False` (`python -O` removes these calls), raise `AssertionError()`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace `assert False`".to_string() } } @@ -75,11 +74,9 @@ pub(crate) fn assert_false(checker: &mut Checker, stmt: &Stmt, test: &Expr, msg: } let mut diagnostic = Diagnostic::new(AssertFalse, test.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.generator().stmt(&assertion_error(msg)), - stmt.range(), - ))); - } + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + checker.generator().stmt(&assertion_error(msg)), + stmt.range(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/duplicate_exceptions.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/duplicate_exceptions.rs index b8daa83ffc705..8357b6670b38c 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/duplicate_exceptions.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/duplicate_exceptions.rs @@ -3,14 +3,15 @@ use ruff_python_ast::{self as ast, ExceptHandler, Expr, ExprContext}; use ruff_text_size::{Ranged, TextRange}; use rustc_hash::{FxHashMap, FxHashSet}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Violation}; use ruff_diagnostics::{Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::call_path; use ruff_python_ast::call_path::CallPath; use crate::checkers::ast::Checker; -use crate::registry::{AsRule, Rule}; +use crate::fix::edits::pad; +use crate::registry::Rule; /// ## What it does /// Checks for `try-except` blocks with duplicate exception handlers. @@ -86,7 +87,7 @@ pub struct DuplicateHandlerException { pub names: Vec, } -impl AlwaysAutofixableViolation for DuplicateHandlerException { +impl AlwaysFixableViolation for DuplicateHandlerException { #[derive_message_formats] fn message(&self) -> String { let DuplicateHandlerException { names } = self; @@ -98,7 +99,7 @@ impl AlwaysAutofixableViolation for DuplicateHandlerException { } } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "De-duplicate exceptions".to_string() } } @@ -112,6 +113,7 @@ fn type_pattern(elts: Vec<&Expr>) -> Expr { .into() } +/// B014 fn duplicate_handler_exceptions<'a>( checker: &mut Checker, expr: &'a Expr, @@ -144,18 +146,22 @@ fn duplicate_handler_exceptions<'a>( }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - if unique_elts.len() == 1 { - checker.generator().expr(unique_elts[0]) - } else { - // Multiple exceptions must always be parenthesized. This is done - // manually as the generator never parenthesizes lone tuples. - format!("({})", checker.generator().expr(&type_pattern(unique_elts))) - }, - expr.range(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + // Single exceptions don't require parentheses, but since we're _removing_ + // parentheses, insert whitespace as needed. + if let [elt] = unique_elts.as_slice() { + pad( + checker.generator().expr(elt), + expr.range(), + checker.locator(), + ) + } else { + // Multiple exceptions must always be parenthesized. This is done + // manually as the generator never parenthesizes lone tuples. + format!("({})", checker.generator().expr(&type_pattern(unique_elts))) + }, + expr.range(), + ))); checker.diagnostics.push(diagnostic); } } @@ -163,6 +169,7 @@ fn duplicate_handler_exceptions<'a>( seen } +/// B025 pub(crate) fn duplicate_exceptions(checker: &mut Checker, handlers: &[ExceptHandler]) { let mut seen: FxHashSet = FxHashSet::default(); let mut duplicates: FxHashMap> = FxHashMap::default(); diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/getattr_with_constant.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/getattr_with_constant.rs index 99097b4137d10..b9b2624950123 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/getattr_with_constant.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/getattr_with_constant.rs @@ -1,12 +1,11 @@ -use crate::autofix::edits::pad; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use crate::fix::edits::pad; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Constant, Expr}; use ruff_python_stdlib::identifiers::{is_identifier, is_mangled_private}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of `getattr` that take a constant attribute value as an @@ -34,7 +33,7 @@ use crate::registry::AsRule; #[violation] pub struct GetAttrWithConstant; -impl AlwaysAutofixableViolation for GetAttrWithConstant { +impl AlwaysFixableViolation for GetAttrWithConstant { #[derive_message_formats] fn message(&self) -> String { format!( @@ -43,7 +42,7 @@ impl AlwaysAutofixableViolation for GetAttrWithConstant { ) } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace `getattr` with attribute access".to_string() } } @@ -85,25 +84,24 @@ pub(crate) fn getattr_with_constant( } let mut diagnostic = Diagnostic::new(GetAttrWithConstant, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - pad( - if matches!( - obj, - Expr::Name(_) | Expr::Attribute(_) | Expr::Subscript(_) | Expr::Call(_) - ) { - format!("{}.{}", checker.locator().slice(obj), value) - } else { - // Defensively parenthesize any other expressions. For example, attribute accesses - // on `int` literals must be parenthesized, e.g., `getattr(1, "real")` becomes - // `(1).real`. The same is true for named expressions and others. - format!("({}).{}", checker.locator().slice(obj), value) - }, - expr.range(), - checker.locator(), - ), + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + pad( + if matches!( + obj, + Expr::Name(_) | Expr::Attribute(_) | Expr::Subscript(_) | Expr::Call(_) + ) && !checker.locator().contains_line_break(obj.range()) + { + format!("{}.{}", checker.locator().slice(obj), value) + } else { + // Defensively parenthesize any other expressions. For example, attribute accesses + // on `int` literals must be parenthesized, e.g., `getattr(1, "real")` becomes + // `(1).real`. The same is true for named expressions and others. + format!("({}).{}", checker.locator().slice(obj), value) + }, expr.range(), - ))); - } + checker.locator(), + ), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/mutable_argument_default.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/mutable_argument_default.rs index f604d18d0c887..71925d0f2da08 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/mutable_argument_default.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/mutable_argument_default.rs @@ -1,5 +1,5 @@ use ast::call_path::{from_qualified_name, CallPath}; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::is_docstring_stmt; use ruff_python_ast::{self as ast, Expr, Parameter, ParameterWithDefault}; @@ -11,7 +11,6 @@ use ruff_source_file::Locator; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of mutable objects as function argument defaults. @@ -31,6 +30,12 @@ use crate::registry::AsRule; /// Types outside of the standard library can be marked as immutable with the /// [`flake8-bugbear.extend-immutable-calls`] configuration option. /// +/// ## Known problems +/// Mutable argument defaults can be used intentionally to cache computation +/// results. Replacing the default with `None` or an immutable data structure +/// does not work for such usages. Instead, prefer the `@functools.lru_cache` +/// decorator from the standard library. +/// /// ## Example /// ```python /// def add_to_list(item, some_list=[]): @@ -64,14 +69,14 @@ use crate::registry::AsRule; pub struct MutableArgumentDefault; impl Violation for MutableArgumentDefault { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Do not use mutable data structures for argument defaults") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some(format!("Replace with `None`; initialize within function")) } } @@ -110,18 +115,16 @@ pub(crate) fn mutable_argument_default(checker: &mut Checker, function_def: &ast let mut diagnostic = Diagnostic::new(MutableArgumentDefault, default.range()); // If the function body is on the same line as the function def, do not fix - if checker.patch(diagnostic.kind.rule()) { - if let Some(fix) = move_initialization( - function_def, - parameter, - default, - checker.locator(), - checker.stylist(), - checker.indexer(), - checker.generator(), - ) { - diagnostic.set_fix(fix); - } + if let Some(fix) = move_initialization( + function_def, + parameter, + default, + checker.locator(), + checker.stylist(), + checker.indexer(), + checker.generator(), + ) { + diagnostic.set_fix(fix); } checker.diagnostics.push(diagnostic); } @@ -139,16 +142,14 @@ fn move_initialization( indexer: &Indexer, generator: Generator, ) -> Option { - let mut body = function_def.body.iter(); + let mut body = function_def.body.iter().peekable(); - let statement = body.next()?; - if indexer.in_multi_statement_line(statement, locator) { + // Avoid attempting to fix single-line functions. + let statement = body.peek()?; + if indexer.preceded_by_multi_statement_line(statement, locator) { return None; } - // Determine the indentation depth of the function body. - let indentation = indentation_at_offset(statement.start(), locator)?; - // Set the default argument value to `None`. let default_edit = Edit::range_replacement("None".to_string(), default.range()); @@ -164,34 +165,43 @@ fn move_initialization( )); content.push_str(stylist.line_ending().as_str()); + // Determine the indentation depth of the function body. + let indentation = indentation_at_offset(statement.start(), locator)?; + // Indent the edit to match the body indentation. - let content = textwrap::indent(&content, indentation).to_string(); - - let initialization_edit = if is_docstring_stmt(statement) { - // If the first statement in the function is a docstring, insert _after_ it. - if let Some(statement) = body.next() { - // If there's a second statement, insert _before_ it, but ensure this isn't a - // multi-statement line. - if indexer.in_multi_statement_line(statement, locator) { - return None; + let mut content = textwrap::indent(&content, indentation).to_string(); + + // Find the position to insert the initialization after docstring and imports + let mut pos = locator.line_start(statement.start()); + while let Some(statement) = body.next() { + // If the statement is a docstring or an import, insert _after_ it. + if is_docstring_stmt(statement) + || statement.is_import_stmt() + || statement.is_import_from_stmt() + { + if let Some(next) = body.peek() { + // If there's a second statement, insert _before_ it, but ensure this isn't a + // multi-statement line. + if indexer.in_multi_statement_line(statement, locator) { + continue; + } + pos = locator.line_start(next.start()); + } else if locator.full_line_end(statement.end()) == locator.text_len() { + // If the statement is at the end of the file, without a trailing newline, insert + // _after_ it with an extra newline. + content = format!("{}{}", stylist.line_ending().as_str(), content); + pos = locator.full_line_end(statement.end()); + break; + } else { + // If this is the only statement, insert _after_ it. + pos = locator.full_line_end(statement.end()); + break; } - Edit::insertion(content, locator.line_start(statement.start())) - } else if locator.full_line_end(statement.end()) == locator.text_len() { - // If the statement is at the end of the file, without a trailing newline, insert - // _after_ it with an extra newline. - Edit::insertion( - format!("{}{}", stylist.line_ending().as_str(), content), - locator.full_line_end(statement.end()), - ) } else { - // If the docstring is the only statement, insert _after_ it. - Edit::insertion(content, locator.full_line_end(statement.end())) - } - } else { - // Otherwise, insert before the first statement. - let at = locator.line_start(statement.start()); - Edit::insertion(content, at) - }; + break; + }; + } - Some(Fix::manual_edits(default_edit, [initialization_edit])) + let initialization_edit = Edit::insertion(content, pos); + Some(Fix::unsafe_edits(default_edit, [initialization_edit])) } diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/redundant_tuple_in_exception_handler.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/redundant_tuple_in_exception_handler.rs index cabcd9b55843d..0f0240d6a4147 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/redundant_tuple_in_exception_handler.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/redundant_tuple_in_exception_handler.rs @@ -1,12 +1,11 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::map_starred; use ruff_python_ast::{self as ast, ExceptHandler, Expr}; use ruff_text_size::Ranged; -use crate::autofix::edits::pad; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix::edits::pad; /// ## What it does /// Checks for single-element tuples in exception handlers (e.g., @@ -39,13 +38,13 @@ pub struct RedundantTupleInExceptionHandler { name: String, } -impl AlwaysAutofixableViolation for RedundantTupleInExceptionHandler { +impl AlwaysFixableViolation for RedundantTupleInExceptionHandler { #[derive_message_formats] fn message(&self) -> String { format!("A length-one tuple literal is redundant in exception handlers") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let RedundantTupleInExceptionHandler { name } = self; format!("Replace with `except {name}`") } @@ -77,23 +76,21 @@ pub(crate) fn redundant_tuple_in_exception_handler( }, type_.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // If there's no space between the `except` and the tuple, we need to insert a space, - // as in: - // ```python - // except(ValueError,): - // ``` - // Otherwise, the output will be invalid syntax, since we're removing a set of - // parentheses. - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - pad( - checker.generator().expr(elt), - type_.range(), - checker.locator(), - ), + // If there's no space between the `except` and the tuple, we need to insert a space, + // as in: + // ```python + // except(ValueError,): + // ``` + // Otherwise, the output will be invalid syntax, since we're removing a set of + // parentheses. + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + pad( + checker.generator().expr(elt), type_.range(), - ))); - } + checker.locator(), + ), + type_.range(), + ))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/setattr_with_constant.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/setattr_with_constant.rs index 5dfbd8d2aa02b..290f3ebc87197 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/setattr_with_constant.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/setattr_with_constant.rs @@ -1,13 +1,12 @@ use ruff_python_ast::{self as ast, Constant, Expr, ExprContext, Identifier, Stmt}; use ruff_text_size::{Ranged, TextRange}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_codegen::Generator; use ruff_python_stdlib::identifiers::{is_identifier, is_mangled_private}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of `setattr` that take a constant attribute value as an @@ -34,7 +33,7 @@ use crate::registry::AsRule; #[violation] pub struct SetAttrWithConstant; -impl AlwaysAutofixableViolation for SetAttrWithConstant { +impl AlwaysFixableViolation for SetAttrWithConstant { #[derive_message_formats] fn message(&self) -> String { format!( @@ -43,7 +42,7 @@ impl AlwaysAutofixableViolation for SetAttrWithConstant { ) } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace `setattr` with assignment".to_string() } } @@ -108,12 +107,10 @@ pub(crate) fn setattr_with_constant( { if expr == child.as_ref() { let mut diagnostic = Diagnostic::new(SetAttrWithConstant, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - assignment(obj, name, value, checker.generator()), - expr.range(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + assignment(obj, name, value, checker.generator()), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/strip_with_multi_characters.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/strip_with_multi_characters.rs index ae50f8ff2f798..3fd3dacdaab9b 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/strip_with_multi_characters.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/strip_with_multi_characters.rs @@ -34,7 +34,7 @@ use crate::checkers::ast::Checker; /// /// ## Example /// ```python -/// "text.txt".strip(".txt") # "ex" +/// "text.txt".strip(".txt") # "e" /// ``` /// /// Use instead: diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/unreliable_callable_check.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/unreliable_callable_check.rs index 0ab04c3e60387..400f5d31c1396 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/unreliable_callable_check.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/unreliable_callable_check.rs @@ -1,11 +1,10 @@ use ruff_python_ast::{self as ast, Constant, Expr}; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of `hasattr` to test if an object is callable (e.g., @@ -37,7 +36,7 @@ use crate::registry::AsRule; pub struct UnreliableCallableCheck; impl Violation for UnreliableCallableCheck { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -47,7 +46,7 @@ impl Violation for UnreliableCallableCheck { ) } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some(format!("Replace with `callable()`")) } } @@ -80,14 +79,12 @@ pub(crate) fn unreliable_callable_check( } let mut diagnostic = Diagnostic::new(UnreliableCallableCheck, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - if id == "hasattr" { - if checker.semantic().is_builtin("callable") { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - format!("callable({})", checker.locator().slice(obj)), - expr.range(), - ))); - } + if id == "hasattr" { + if checker.semantic().is_builtin("callable") { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + format!("callable({})", checker.locator().slice(obj)), + expr.range(), + ))); } } checker.diagnostics.push(diagnostic); diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/unused_loop_control_variable.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/unused_loop_control_variable.rs index b2a40527b4a2a..20e29e179b4c2 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/unused_loop_control_variable.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/unused_loop_control_variable.rs @@ -1,6 +1,6 @@ use rustc_hash::FxHashMap; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::visitor::Visitor; use ruff_python_ast::{self as ast, Expr}; @@ -8,7 +8,6 @@ use ruff_python_ast::{helpers, visitor}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; #[derive(Debug, Copy, Clone, PartialEq, Eq, result_like::BoolLike)] enum Certainty { @@ -56,7 +55,7 @@ pub struct UnusedLoopControlVariable { } impl Violation for UnusedLoopControlVariable { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -70,7 +69,7 @@ impl Violation for UnusedLoopControlVariable { } } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let UnusedLoopControlVariable { rename, name, .. } = self; rename @@ -156,23 +155,21 @@ pub(crate) fn unused_loop_control_variable(checker: &mut Checker, stmt_for: &ast }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if let Some(rename) = rename { - if certainty.into() { - // Avoid fixing if the variable, or any future bindings to the variable, are - // used _after_ the loop. - let scope = checker.semantic().current_scope(); - if scope - .get_all(name) - .map(|binding_id| checker.semantic().binding(binding_id)) - .filter(|binding| binding.start() >= expr.start()) - .all(|binding| !binding.is_used()) - { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - rename, - expr.range(), - ))); - } + if let Some(rename) = rename { + if certainty.into() { + // Avoid fixing if the variable, or any future bindings to the variable, are + // used _after_ the loop. + let scope = checker.semantic().current_scope(); + if scope + .get_all(name) + .map(|binding_id| checker.semantic().binding(binding_id)) + .filter(|binding| binding.start() >= expr.start()) + .all(|binding| !binding.is_used()) + { + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + rename, + expr.range(), + ))); } } } diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_comparison.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_comparison.rs index 698f94e6f5216..d5f62107d46e0 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_comparison.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_comparison.rs @@ -1,7 +1,6 @@ -use ruff_python_ast::Expr; - use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::Expr; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -33,15 +32,15 @@ impl Violation for UselessComparison { #[derive_message_formats] fn message(&self) -> String { format!( - "Pointless comparison. This comparison does nothing but waste CPU instructions. \ - Either prepend `assert` or remove it." + "Pointless comparison. Did you mean to assign a value? \ + Otherwise, prepend `assert` or remove it." ) } } /// B015 pub(crate) fn useless_comparison(checker: &mut Checker, expr: &Expr) { - if matches!(expr, Expr::Compare(_)) { + if expr.is_compare_expr() { checker .diagnostics .push(Diagnostic::new(UselessComparison, expr.range())); diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_expression.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_expression.rs index 5b98107290e1a..57521418eae84 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_expression.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_expression.rs @@ -1,8 +1,7 @@ -use ruff_python_ast::{self as ast, Constant, Expr}; - use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::contains_effect; +use ruff_python_ast::{self as ast, Constant, Expr}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -48,7 +47,7 @@ impl Violation for UselessExpression { /// B018 pub(crate) fn useless_expression(checker: &mut Checker, value: &Expr) { // Ignore comparisons, as they're handled by `useless_comparison`. - if matches!(value, Expr::Compare(_)) { + if value.is_compare_expr() { return; } @@ -68,7 +67,7 @@ pub(crate) fn useless_expression(checker: &mut Checker, value: &Expr) { if contains_effect(value, |id| checker.semantic().is_builtin(id)) { // Flag attributes as useless expressions, even if they're attached to calls or other // expressions. - if matches!(value, Expr::Attribute(_)) { + if value.is_attribute_expr() { checker.diagnostics.push(Diagnostic::new( UselessExpression { kind: Kind::Attribute, diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_1.py.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_1.py.snap index 5bf88bfe614de..aa5ecfb3f14d4 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_1.py.snap +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_1.py.snap @@ -12,7 +12,7 @@ B006_1.py:3:22: B006 [*] Do not use mutable data structures for argument default | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 1 1 | # Docstring followed by a newline 2 2 | 3 |-def foobar(foor, bar={}): diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_2.py.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_2.py.snap index 5cf776a5985f9..f37779627eff2 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_2.py.snap +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_2.py.snap @@ -12,7 +12,7 @@ B006_2.py:4:22: B006 [*] Do not use mutable data structures for argument default | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 1 1 | # Docstring followed by whitespace with no newline 2 2 | # Regression test for https://github.com/astral-sh/ruff/issues/7155 3 3 | diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_3.py.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_3.py.snap index aed13094fb804..2013a5d199eff 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_3.py.snap +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_3.py.snap @@ -10,7 +10,7 @@ B006_3.py:4:22: B006 [*] Do not use mutable data structures for argument default | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 1 1 | # Docstring with no newline 2 2 | 3 3 | diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_4.py.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_4.py.snap index d1452087066df..59188b0678d9d 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_4.py.snap +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_4.py.snap @@ -10,7 +10,7 @@ B006_4.py:7:26: B006 [*] Do not use mutable data structures for argument default | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 4 4 | 5 5 | 6 6 | class FormFeedIndent: diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_5.py.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_5.py.snap new file mode 100644 index 0000000000000..bea5f44bb4e74 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_5.py.snap @@ -0,0 +1,313 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs +--- +B006_5.py:5:49: B006 [*] Do not use mutable data structures for argument defaults + | +5 | def import_module_wrong(value: dict[str, str] = {}): + | ^^ B006 +6 | import os + | + = help: Replace with `None`; initialize within function + +ℹ Suggested fix +2 2 | # https://github.com/astral-sh/ruff/issues/7616 +3 3 | +4 4 | +5 |-def import_module_wrong(value: dict[str, str] = {}): + 5 |+def import_module_wrong(value: dict[str, str] = None): +6 6 | import os + 7 |+ if value is None: + 8 |+ value = {} +7 9 | +8 10 | +9 11 | def import_module_with_values_wrong(value: dict[str, str] = {}): + +B006_5.py:9:61: B006 [*] Do not use mutable data structures for argument defaults + | + 9 | def import_module_with_values_wrong(value: dict[str, str] = {}): + | ^^ B006 +10 | import os + | + = help: Replace with `None`; initialize within function + +ℹ Suggested fix +6 6 | import os +7 7 | +8 8 | +9 |-def import_module_with_values_wrong(value: dict[str, str] = {}): + 9 |+def import_module_with_values_wrong(value: dict[str, str] = None): +10 10 | import os +11 11 | + 12 |+ if value is None: + 13 |+ value = {} +12 14 | return 2 +13 15 | +14 16 | + +B006_5.py:15:50: B006 [*] Do not use mutable data structures for argument defaults + | +15 | def import_modules_wrong(value: dict[str, str] = {}): + | ^^ B006 +16 | import os +17 | import sys + | + = help: Replace with `None`; initialize within function + +ℹ Suggested fix +12 12 | return 2 +13 13 | +14 14 | +15 |-def import_modules_wrong(value: dict[str, str] = {}): + 15 |+def import_modules_wrong(value: dict[str, str] = None): +16 16 | import os +17 17 | import sys +18 18 | import itertools + 19 |+ if value is None: + 20 |+ value = {} +19 21 | +20 22 | +21 23 | def from_import_module_wrong(value: dict[str, str] = {}): + +B006_5.py:21:54: B006 [*] Do not use mutable data structures for argument defaults + | +21 | def from_import_module_wrong(value: dict[str, str] = {}): + | ^^ B006 +22 | from os import path + | + = help: Replace with `None`; initialize within function + +ℹ Suggested fix +18 18 | import itertools +19 19 | +20 20 | +21 |-def from_import_module_wrong(value: dict[str, str] = {}): + 21 |+def from_import_module_wrong(value: dict[str, str] = None): +22 22 | from os import path + 23 |+ if value is None: + 24 |+ value = {} +23 25 | +24 26 | +25 27 | def from_imports_module_wrong(value: dict[str, str] = {}): + +B006_5.py:25:55: B006 [*] Do not use mutable data structures for argument defaults + | +25 | def from_imports_module_wrong(value: dict[str, str] = {}): + | ^^ B006 +26 | from os import path +27 | from sys import version_info + | + = help: Replace with `None`; initialize within function + +ℹ Suggested fix +22 22 | from os import path +23 23 | +24 24 | +25 |-def from_imports_module_wrong(value: dict[str, str] = {}): + 25 |+def from_imports_module_wrong(value: dict[str, str] = None): +26 26 | from os import path +27 27 | from sys import version_info + 28 |+ if value is None: + 29 |+ value = {} +28 30 | +29 31 | +30 32 | def import_and_from_imports_module_wrong(value: dict[str, str] = {}): + +B006_5.py:30:66: B006 [*] Do not use mutable data structures for argument defaults + | +30 | def import_and_from_imports_module_wrong(value: dict[str, str] = {}): + | ^^ B006 +31 | import os +32 | from sys import version_info + | + = help: Replace with `None`; initialize within function + +ℹ Suggested fix +27 27 | from sys import version_info +28 28 | +29 29 | +30 |-def import_and_from_imports_module_wrong(value: dict[str, str] = {}): + 30 |+def import_and_from_imports_module_wrong(value: dict[str, str] = None): +31 31 | import os +32 32 | from sys import version_info + 33 |+ if value is None: + 34 |+ value = {} +33 35 | +34 36 | +35 37 | def import_docstring_module_wrong(value: dict[str, str] = {}): + +B006_5.py:35:59: B006 [*] Do not use mutable data structures for argument defaults + | +35 | def import_docstring_module_wrong(value: dict[str, str] = {}): + | ^^ B006 +36 | """Docstring""" +37 | import os + | + = help: Replace with `None`; initialize within function + +ℹ Suggested fix +32 32 | from sys import version_info +33 33 | +34 34 | +35 |-def import_docstring_module_wrong(value: dict[str, str] = {}): + 35 |+def import_docstring_module_wrong(value: dict[str, str] = None): +36 36 | """Docstring""" +37 37 | import os + 38 |+ if value is None: + 39 |+ value = {} +38 40 | +39 41 | +40 42 | def import_module_wrong(value: dict[str, str] = {}): + +B006_5.py:40:49: B006 [*] Do not use mutable data structures for argument defaults + | +40 | def import_module_wrong(value: dict[str, str] = {}): + | ^^ B006 +41 | """Docstring""" +42 | import os; import sys + | + = help: Replace with `None`; initialize within function + +ℹ Suggested fix +37 37 | import os +38 38 | +39 39 | +40 |-def import_module_wrong(value: dict[str, str] = {}): + 40 |+def import_module_wrong(value: dict[str, str] = None): +41 41 | """Docstring""" +42 42 | import os; import sys + 43 |+ if value is None: + 44 |+ value = {} +43 45 | +44 46 | +45 47 | def import_module_wrong(value: dict[str, str] = {}): + +B006_5.py:45:49: B006 [*] Do not use mutable data structures for argument defaults + | +45 | def import_module_wrong(value: dict[str, str] = {}): + | ^^ B006 +46 | """Docstring""" +47 | import os; import sys; x = 1 + | + = help: Replace with `None`; initialize within function + +ℹ Suggested fix +42 42 | import os; import sys +43 43 | +44 44 | +45 |-def import_module_wrong(value: dict[str, str] = {}): + 45 |+def import_module_wrong(value: dict[str, str] = None): +46 46 | """Docstring""" + 47 |+ if value is None: + 48 |+ value = {} +47 49 | import os; import sys; x = 1 +48 50 | +49 51 | + +B006_5.py:50:49: B006 [*] Do not use mutable data structures for argument defaults + | +50 | def import_module_wrong(value: dict[str, str] = {}): + | ^^ B006 +51 | """Docstring""" +52 | import os; import sys + | + = help: Replace with `None`; initialize within function + +ℹ Suggested fix +47 47 | import os; import sys; x = 1 +48 48 | +49 49 | +50 |-def import_module_wrong(value: dict[str, str] = {}): + 50 |+def import_module_wrong(value: dict[str, str] = None): +51 51 | """Docstring""" +52 52 | import os; import sys + 53 |+ if value is None: + 54 |+ value = {} +53 55 | +54 56 | +55 57 | def import_module_wrong(value: dict[str, str] = {}): + +B006_5.py:55:49: B006 [*] Do not use mutable data structures for argument defaults + | +55 | def import_module_wrong(value: dict[str, str] = {}): + | ^^ B006 +56 | import os; import sys + | + = help: Replace with `None`; initialize within function + +ℹ Suggested fix +52 52 | import os; import sys +53 53 | +54 54 | +55 |-def import_module_wrong(value: dict[str, str] = {}): + 55 |+def import_module_wrong(value: dict[str, str] = None): +56 56 | import os; import sys + 57 |+ if value is None: + 58 |+ value = {} +57 59 | +58 60 | +59 61 | def import_module_wrong(value: dict[str, str] = {}): + +B006_5.py:59:49: B006 [*] Do not use mutable data structures for argument defaults + | +59 | def import_module_wrong(value: dict[str, str] = {}): + | ^^ B006 +60 | import os; import sys; x = 1 + | + = help: Replace with `None`; initialize within function + +ℹ Suggested fix +56 56 | import os; import sys +57 57 | +58 58 | +59 |-def import_module_wrong(value: dict[str, str] = {}): + 59 |+def import_module_wrong(value: dict[str, str] = None): + 60 |+ if value is None: + 61 |+ value = {} +60 62 | import os; import sys; x = 1 +61 63 | +62 64 | + +B006_5.py:63:49: B006 [*] Do not use mutable data structures for argument defaults + | +63 | def import_module_wrong(value: dict[str, str] = {}): + | ^^ B006 +64 | import os; import sys + | + = help: Replace with `None`; initialize within function + +ℹ Suggested fix +60 60 | import os; import sys; x = 1 +61 61 | +62 62 | +63 |-def import_module_wrong(value: dict[str, str] = {}): + 63 |+def import_module_wrong(value: dict[str, str] = None): +64 64 | import os; import sys + 65 |+ if value is None: + 66 |+ value = {} +65 67 | +66 68 | +67 69 | def import_module_wrong(value: dict[str, str] = {}): import os + +B006_5.py:67:49: B006 Do not use mutable data structures for argument defaults + | +67 | def import_module_wrong(value: dict[str, str] = {}): import os + | ^^ B006 + | + = help: Replace with `None`; initialize within function + +B006_5.py:70:49: B006 Do not use mutable data structures for argument defaults + | +70 | def import_module_wrong(value: dict[str, str] = {}): import os; import sys + | ^^ B006 + | + = help: Replace with `None`; initialize within function + +B006_5.py:73:49: B006 Do not use mutable data structures for argument defaults + | +73 | def import_module_wrong(value: dict[str, str] = {}): \ + | ^^ B006 +74 | import os + | + = help: Replace with `None`; initialize within function + + diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_6.py.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_6.py.snap new file mode 100644 index 0000000000000..be764fc13791e --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_6.py.snap @@ -0,0 +1,25 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs +--- +B006_6.py:4:22: B006 [*] Do not use mutable data structures for argument defaults + | +2 | # Same as B006_2.py, but import instead of docstring +3 | +4 | def foobar(foor, bar={}): + | ^^ B006 +5 | import os + | + = help: Replace with `None`; initialize within function + +ℹ Suggested fix +1 1 | # Import followed by whitespace with no newline +2 2 | # Same as B006_2.py, but import instead of docstring +3 3 | +4 |-def foobar(foor, bar={}): +5 |- import os + 4 |+def foobar(foor, bar=None): + 5 |+ import os + 6 |+ if bar is None: + 7 |+ bar = {} + + diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_7.py.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_7.py.snap new file mode 100644 index 0000000000000..39599123bd8be --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_7.py.snap @@ -0,0 +1,25 @@ +--- +source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs +--- +B006_7.py:4:22: B006 [*] Do not use mutable data structures for argument defaults + | +2 | # Same as B006_3.py, but import instead of docstring +3 | +4 | def foobar(foor, bar={}): + | ^^ B006 +5 | import os + | + = help: Replace with `None`; initialize within function + +ℹ Suggested fix +1 1 | # Import with no newline +2 2 | # Same as B006_3.py, but import instead of docstring +3 3 | +4 |-def foobar(foor, bar={}): +5 |- import os + 4 |+def foobar(foor, bar=None): + 5 |+ import os + 6 |+ if bar is None: + 7 |+ bar = {} + + diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_B008.py.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_B008.py.snap index 8272eb6aa6a09..1f5f6764a6996 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_B008.py.snap +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B006_B006_B008.py.snap @@ -9,7 +9,7 @@ B006_B008.py:63:25: B006 [*] Do not use mutable data structures for argument def | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 60 60 | # Flag mutable literals/comprehensions 61 61 | 62 62 | @@ -29,7 +29,7 @@ B006_B008.py:67:30: B006 [*] Do not use mutable data structures for argument def | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 64 64 | ... 65 65 | 66 66 | @@ -51,7 +51,7 @@ B006_B008.py:73:52: B006 [*] Do not use mutable data structures for argument def | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 70 70 | 71 71 | class Foo: 72 72 | @staticmethod @@ -74,7 +74,7 @@ B006_B008.py:77:31: B006 [*] Do not use mutable data structures for argument def | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 74 74 | pass 75 75 | 76 76 | @@ -105,7 +105,7 @@ B006_B008.py:85:20: B006 [*] Do not use mutable data structures for argument def | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 82 82 | def single_line_func_wrong(value = {}): ... 83 83 | 84 84 | @@ -125,7 +125,7 @@ B006_B008.py:89:20: B006 [*] Do not use mutable data structures for argument def | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 86 86 | ... 87 87 | 88 88 | @@ -145,7 +145,7 @@ B006_B008.py:93:32: B006 [*] Do not use mutable data structures for argument def | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 90 90 | ... 91 91 | 92 92 | @@ -165,7 +165,7 @@ B006_B008.py:97:26: B006 [*] Do not use mutable data structures for argument def | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 94 94 | ... 95 95 | 96 96 | @@ -186,7 +186,7 @@ B006_B008.py:102:46: B006 [*] Do not use mutable data structures for argument de | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 99 99 | 100 100 | 101 101 | # N.B. we're also flagging the function call in the comprehension @@ -206,7 +206,7 @@ B006_B008.py:106:46: B006 [*] Do not use mutable data structures for argument de | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 103 103 | pass 104 104 | 105 105 | @@ -226,7 +226,7 @@ B006_B008.py:110:45: B006 [*] Do not use mutable data structures for argument de | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 107 107 | pass 108 108 | 109 109 | @@ -246,7 +246,7 @@ B006_B008.py:114:33: B006 [*] Do not use mutable data structures for argument de | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 111 111 | pass 112 112 | 113 113 | @@ -268,7 +268,7 @@ B006_B008.py:239:20: B006 [*] Do not use mutable data structures for argument de | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 236 236 | 237 237 | # B006 and B008 238 238 | # We should handle arbitrary nesting of these B008. @@ -290,7 +290,7 @@ B006_B008.py:276:27: B006 [*] Do not use mutable data structures for argument de | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 273 273 | 274 274 | 275 275 | def mutable_annotations( @@ -317,7 +317,7 @@ B006_B008.py:277:35: B006 [*] Do not use mutable data structures for argument de | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 274 274 | 275 275 | def mutable_annotations( 276 276 | a: list[int] | None = [], @@ -343,7 +343,7 @@ B006_B008.py:278:62: B006 [*] Do not use mutable data structures for argument de | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 275 275 | def mutable_annotations( 276 276 | a: list[int] | None = [], 277 277 | b: Optional[Dict[int, int]] = {}, @@ -368,7 +368,7 @@ B006_B008.py:279:80: B006 [*] Do not use mutable data structures for argument de | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 276 276 | a: list[int] | None = [], 277 277 | b: Optional[Dict[int, int]] = {}, 278 278 | c: Annotated[Union[Set[str], abc.Sized], "annotation"] = set(), @@ -389,7 +389,7 @@ B006_B008.py:284:52: B006 [*] Do not use mutable data structures for argument de | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 281 281 | pass 282 282 | 283 283 | @@ -411,7 +411,7 @@ B006_B008.py:288:52: B006 [*] Do not use mutable data structures for argument de | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 285 285 | """Docstring""" 286 286 | 287 287 | @@ -424,7 +424,7 @@ B006_B008.py:288:52: B006 [*] Do not use mutable data structures for argument de 291 293 | 292 294 | -B006_B008.py:293:52: B006 Do not use mutable data structures for argument defaults +B006_B008.py:293:52: B006 [*] Do not use mutable data structures for argument defaults | 293 | def single_line_func_wrong(value: dict[str, str] = {}): | ^^ B006 @@ -432,7 +432,19 @@ B006_B008.py:293:52: B006 Do not use mutable data structures for argument defaul | = help: Replace with `None`; initialize within function -B006_B008.py:297:52: B006 Do not use mutable data structures for argument defaults +ℹ Suggested fix +290 290 | ... +291 291 | +292 292 | +293 |-def single_line_func_wrong(value: dict[str, str] = {}): + 293 |+def single_line_func_wrong(value: dict[str, str] = None): + 294 |+ if value is None: + 295 |+ value = {} +294 296 | """Docstring"""; ... +295 297 | +296 298 | + +B006_B008.py:297:52: B006 [*] Do not use mutable data structures for argument defaults | 297 | def single_line_func_wrong(value: dict[str, str] = {}): | ^^ B006 @@ -441,6 +453,18 @@ B006_B008.py:297:52: B006 Do not use mutable data structures for argument defaul | = help: Replace with `None`; initialize within function +ℹ Suggested fix +294 294 | """Docstring"""; ... +295 295 | +296 296 | +297 |-def single_line_func_wrong(value: dict[str, str] = {}): + 297 |+def single_line_func_wrong(value: dict[str, str] = None): + 298 |+ if value is None: + 299 |+ value = {} +298 300 | """Docstring"""; \ +299 301 | ... +300 302 | + B006_B008.py:302:52: B006 [*] Do not use mutable data structures for argument defaults | 302 | def single_line_func_wrong(value: dict[str, str] = { @@ -452,7 +476,7 @@ B006_B008.py:302:52: B006 [*] Do not use mutable data structures for argument de | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 299 299 | ... 300 300 | 301 301 | @@ -484,7 +508,7 @@ B006_B008.py:313:52: B006 [*] Do not use mutable data structures for argument de | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 310 310 | """Docstring""" 311 311 | 312 312 | diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B009_B009_B010.py.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B009_B009_B010.py.snap index 51c3a9339db00..42c4808fecf9b 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B009_B009_B010.py.snap +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B009_B009_B010.py.snap @@ -11,7 +11,7 @@ B009_B010.py:19:1: B009 [*] Do not call `getattr` with a constant attribute valu | = help: Replace `getattr` with attribute access -ℹ Suggested fix +ℹ Fix 16 16 | getattr(foo, "__123abc") 17 17 | 18 18 | # Invalid usage @@ -32,7 +32,7 @@ B009_B010.py:20:1: B009 [*] Do not call `getattr` with a constant attribute valu | = help: Replace `getattr` with attribute access -ℹ Suggested fix +ℹ Fix 17 17 | 18 18 | # Invalid usage 19 19 | getattr(foo, "bar") @@ -53,7 +53,7 @@ B009_B010.py:21:1: B009 [*] Do not call `getattr` with a constant attribute valu | = help: Replace `getattr` with attribute access -ℹ Suggested fix +ℹ Fix 18 18 | # Invalid usage 19 19 | getattr(foo, "bar") 20 20 | getattr(foo, "_123abc") @@ -74,7 +74,7 @@ B009_B010.py:22:1: B009 [*] Do not call `getattr` with a constant attribute valu | = help: Replace `getattr` with attribute access -ℹ Suggested fix +ℹ Fix 19 19 | getattr(foo, "bar") 20 20 | getattr(foo, "_123abc") 21 21 | getattr(foo, "__123abc__") @@ -95,7 +95,7 @@ B009_B010.py:23:1: B009 [*] Do not call `getattr` with a constant attribute valu | = help: Replace `getattr` with attribute access -ℹ Suggested fix +ℹ Fix 20 20 | getattr(foo, "_123abc") 21 21 | getattr(foo, "__123abc__") 22 22 | getattr(foo, "abc123") @@ -116,7 +116,7 @@ B009_B010.py:24:15: B009 [*] Do not call `getattr` with a constant attribute val | = help: Replace `getattr` with attribute access -ℹ Suggested fix +ℹ Fix 21 21 | getattr(foo, "__123abc__") 22 22 | getattr(foo, "abc123") 23 23 | getattr(foo, r"abc123") @@ -137,7 +137,7 @@ B009_B010.py:25:4: B009 [*] Do not call `getattr` with a constant attribute valu | = help: Replace `getattr` with attribute access -ℹ Suggested fix +ℹ Fix 22 22 | getattr(foo, "abc123") 23 23 | getattr(foo, r"abc123") 24 24 | _ = lambda x: getattr(x, "bar") @@ -158,7 +158,7 @@ B009_B010.py:27:1: B009 [*] Do not call `getattr` with a constant attribute valu | = help: Replace `getattr` with attribute access -ℹ Suggested fix +ℹ Fix 24 24 | _ = lambda x: getattr(x, "bar") 25 25 | if getattr(x, "bar"): 26 26 | pass @@ -179,7 +179,7 @@ B009_B010.py:28:1: B009 [*] Do not call `getattr` with a constant attribute valu | = help: Replace `getattr` with attribute access -ℹ Suggested fix +ℹ Fix 25 25 | if getattr(x, "bar"): 26 26 | pass 27 27 | getattr(1, "real") @@ -200,7 +200,7 @@ B009_B010.py:29:1: B009 [*] Do not call `getattr` with a constant attribute valu | = help: Replace `getattr` with attribute access -ℹ Suggested fix +ℹ Fix 26 26 | pass 27 27 | getattr(1, "real") 28 28 | getattr(1., "real") @@ -221,7 +221,7 @@ B009_B010.py:30:1: B009 [*] Do not call `getattr` with a constant attribute valu | = help: Replace `getattr` with attribute access -ℹ Suggested fix +ℹ Fix 27 27 | getattr(1, "real") 28 28 | getattr(1., "real") 29 29 | getattr(1.0, "real") @@ -242,7 +242,7 @@ B009_B010.py:31:1: B009 [*] Do not call `getattr` with a constant attribute valu | = help: Replace `getattr` with attribute access -ℹ Suggested fix +ℹ Fix 28 28 | getattr(1., "real") 29 29 | getattr(1.0, "real") 30 30 | getattr(1j, "real") @@ -263,7 +263,7 @@ B009_B010.py:32:1: B009 [*] Do not call `getattr` with a constant attribute valu | = help: Replace `getattr` with attribute access -ℹ Suggested fix +ℹ Fix 29 29 | getattr(1.0, "real") 30 30 | getattr(1j, "real") 31 31 | getattr(True, "real") @@ -284,7 +284,7 @@ B009_B010.py:33:1: B009 [*] Do not call `getattr` with a constant attribute valu | = help: Replace `getattr` with attribute access -ℹ Suggested fix +ℹ Fix 30 30 | getattr(1j, "real") 31 31 | getattr(True, "real") 32 32 | getattr(x := 1, "real") @@ -304,7 +304,7 @@ B009_B010.py:34:1: B009 [*] Do not call `getattr` with a constant attribute valu | = help: Replace `getattr` with attribute access -ℹ Suggested fix +ℹ Fix 31 31 | getattr(True, "real") 32 32 | getattr(x := 1, "real") 33 33 | getattr(x + y, "real") @@ -326,7 +326,7 @@ B009_B010.py:58:8: B009 [*] Do not call `getattr` with a constant attribute valu | = help: Replace `getattr` with attribute access -ℹ Suggested fix +ℹ Fix 55 55 | setattr(foo.bar, r"baz", None) 56 56 | 57 57 | # Regression test for: https://github.com/astral-sh/ruff/issues/7455#issuecomment-1722458885 @@ -336,4 +336,22 @@ B009_B010.py:58:8: B009 [*] Do not call `getattr` with a constant attribute valu 60 60 | # Regression test for: https://github.com/astral-sh/ruff/issues/7455#issuecomment-1732387247 61 61 | getattr(*foo, "bar") +B009_B010.py:65:1: B009 [*] Do not call `getattr` with a constant attribute value. It is not any safer than normal property access. + | +64 | # Regression test for: https://github.com/astral-sh/ruff/issues/7455#issuecomment-1739800901 +65 | / getattr(self. +66 | | registration.registry, '__name__') + | |_____________________________________^ B009 + | + = help: Replace `getattr` with attribute access + +ℹ Fix +62 62 | setattr(*foo, "bar", None) +63 63 | +64 64 | # Regression test for: https://github.com/astral-sh/ruff/issues/7455#issuecomment-1739800901 +65 |-getattr(self. +66 |- registration.registry, '__name__') + 65 |+(self. + 66 |+ registration.registry).__name__ + diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B010_B009_B010.py.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B010_B009_B010.py.snap index 2945aafb436c9..cb21aba09f6dd 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B010_B009_B010.py.snap +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B010_B009_B010.py.snap @@ -11,7 +11,7 @@ B009_B010.py:50:1: B010 [*] Do not call `setattr` with a constant attribute valu | = help: Replace `setattr` with assignment -ℹ Suggested fix +ℹ Fix 47 47 | pass 48 48 | 49 49 | # Invalid usage @@ -32,7 +32,7 @@ B009_B010.py:51:1: B010 [*] Do not call `setattr` with a constant attribute valu | = help: Replace `setattr` with assignment -ℹ Suggested fix +ℹ Fix 48 48 | 49 49 | # Invalid usage 50 50 | setattr(foo, "bar", None) @@ -53,7 +53,7 @@ B009_B010.py:52:1: B010 [*] Do not call `setattr` with a constant attribute valu | = help: Replace `setattr` with assignment -ℹ Suggested fix +ℹ Fix 49 49 | # Invalid usage 50 50 | setattr(foo, "bar", None) 51 51 | setattr(foo, "_123abc", None) @@ -74,7 +74,7 @@ B009_B010.py:53:1: B010 [*] Do not call `setattr` with a constant attribute valu | = help: Replace `setattr` with assignment -ℹ Suggested fix +ℹ Fix 50 50 | setattr(foo, "bar", None) 51 51 | setattr(foo, "_123abc", None) 52 52 | setattr(foo, "__123abc__", None) @@ -94,7 +94,7 @@ B009_B010.py:54:1: B010 [*] Do not call `setattr` with a constant attribute valu | = help: Replace `setattr` with assignment -ℹ Suggested fix +ℹ Fix 51 51 | setattr(foo, "_123abc", None) 52 52 | setattr(foo, "__123abc__", None) 53 53 | setattr(foo, "abc123", None) @@ -115,7 +115,7 @@ B009_B010.py:55:1: B010 [*] Do not call `setattr` with a constant attribute valu | = help: Replace `setattr` with assignment -ℹ Suggested fix +ℹ Fix 52 52 | setattr(foo, "__123abc__", None) 53 53 | setattr(foo, "abc123", None) 54 54 | setattr(foo, r"abc123", None) diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B014_B014.py.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B014_B014.py.snap index 87ececd961267..75b8d36fc7703 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B014_B014.py.snap +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B014_B014.py.snap @@ -75,11 +75,31 @@ B014.py:82:8: B014 [*] Exception handler with duplicate exception: `ValueError` = help: De-duplicate exceptions ℹ Fix -79 79 | # https://github.com/astral-sh/ruff/issues/6412 +79 79 | # Regression test for: https://github.com/astral-sh/ruff/issues/6412 80 80 | try: 81 81 | pass 82 |-except (ValueError, ValueError, TypeError): 82 |+except (ValueError, TypeError): 83 83 | pass +84 84 | +85 85 | + +B014.py:89:7: B014 [*] Exception handler with duplicate exception: `re.error` + | +87 | try: +88 | pas +89 | except(re.error, re.error): + | ^^^^^^^^^^^^^^^^^^^^ B014 +90 | p + | + = help: De-duplicate exceptions + +ℹ Fix +86 86 | # Regression test for: https://github.com/astral-sh/ruff/issues/7455#issuecomment-1739801758 +87 87 | try: +88 88 | pas +89 |-except(re.error, re.error): + 89 |+except re.error: +90 90 | p diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B015_B015.py.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B015_B015.py.snap index 46702e5a58a66..a59d23cb43b92 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B015_B015.py.snap +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B015_B015.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs --- -B015.py:3:1: B015 Pointless comparison. This comparison does nothing but waste CPU instructions. Either prepend `assert` or remove it. +B015.py:3:1: B015 Pointless comparison. Did you mean to assign a value? Otherwise, prepend `assert` or remove it. | 1 | assert 1 == 1 2 | @@ -11,7 +11,7 @@ B015.py:3:1: B015 Pointless comparison. This comparison does nothing but waste C 5 | assert 1 in (1, 2) | -B015.py:7:1: B015 Pointless comparison. This comparison does nothing but waste CPU instructions. Either prepend `assert` or remove it. +B015.py:7:1: B015 Pointless comparison. Did you mean to assign a value? Otherwise, prepend `assert` or remove it. | 5 | assert 1 in (1, 2) 6 | @@ -19,7 +19,7 @@ B015.py:7:1: B015 Pointless comparison. This comparison does nothing but waste C | ^^^^^^^^^^^ B015 | -B015.py:17:5: B015 Pointless comparison. This comparison does nothing but waste CPU instructions. Either prepend `assert` or remove it. +B015.py:17:5: B015 Pointless comparison. Did you mean to assign a value? Otherwise, prepend `assert` or remove it. | 15 | assert 1 in (1, 2) 16 | @@ -27,7 +27,7 @@ B015.py:17:5: B015 Pointless comparison. This comparison does nothing but waste | ^^^^^^^^^^^ B015 | -B015.py:24:5: B015 Pointless comparison. This comparison does nothing but waste CPU instructions. Either prepend `assert` or remove it. +B015.py:24:5: B015 Pointless comparison. Did you mean to assign a value? Otherwise, prepend `assert` or remove it. | 23 | class TestClass: 24 | 1 == 1 diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__extend_immutable_calls_arg_annotation.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__extend_immutable_calls_arg_annotation.snap index d191804dd6772..3a211c6e944d4 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__extend_immutable_calls_arg_annotation.snap +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__extend_immutable_calls_arg_annotation.snap @@ -9,7 +9,7 @@ B006_extended.py:17:55: B006 [*] Do not use mutable data structures for argument | = help: Replace with `None`; initialize within function -ℹ Possible fix +ℹ Suggested fix 14 14 | ... 15 15 | 16 16 | diff --git a/crates/ruff_linter/src/rules/flake8_commas/rules/trailing_commas.rs b/crates/ruff_linter/src/rules/flake8_commas/rules/trailing_commas.rs index 3b79acf051e86..e3fdd58a7e256 100644 --- a/crates/ruff_linter/src/rules/flake8_commas/rules/trailing_commas.rs +++ b/crates/ruff_linter/src/rules/flake8_commas/rules/trailing_commas.rs @@ -1,6 +1,6 @@ use itertools::Itertools; -use ruff_diagnostics::{AlwaysAutofixableViolation, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Violation}; use ruff_diagnostics::{Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_parser::lexer::{LexResult, Spanned}; @@ -8,9 +8,6 @@ use ruff_python_parser::Tok; use ruff_source_file::Locator; use ruff_text_size::{Ranged, TextRange}; -use crate::registry::Rule; -use crate::settings::LinterSettings; - /// Simplified token type. #[derive(Copy, Clone, PartialEq, Eq)] enum TokenType { @@ -138,13 +135,13 @@ impl Context { #[violation] pub struct MissingTrailingComma; -impl AlwaysAutofixableViolation for MissingTrailingComma { +impl AlwaysFixableViolation for MissingTrailingComma { #[derive_message_formats] fn message(&self) -> String { format!("Trailing comma missing") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Add trailing comma".to_string() } } @@ -209,13 +206,13 @@ impl Violation for TrailingCommaOnBareTuple { #[violation] pub struct ProhibitedTrailingComma; -impl AlwaysAutofixableViolation for ProhibitedTrailingComma { +impl AlwaysFixableViolation for ProhibitedTrailingComma { #[derive_message_formats] fn message(&self) -> String { format!("Trailing comma prohibited") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove trailing comma".to_string() } } @@ -225,7 +222,6 @@ pub(crate) fn trailing_commas( diagnostics: &mut Vec, tokens: &[LexResult], locator: &Locator, - settings: &LinterSettings, ) { let tokens = tokens .iter() @@ -324,9 +320,7 @@ pub(crate) fn trailing_commas( if comma_prohibited { let comma = prev.spanned.unwrap(); let mut diagnostic = Diagnostic::new(ProhibitedTrailingComma, comma.1); - if settings.rules.should_fix(Rule::ProhibitedTrailingComma) { - diagnostic.set_fix(Fix::automatic(Edit::range_deletion(diagnostic.range()))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(diagnostic.range()))); diagnostics.push(diagnostic); } @@ -359,17 +353,15 @@ pub(crate) fn trailing_commas( MissingTrailingComma, TextRange::empty(missing_comma.1.end()), ); - if settings.rules.should_fix(Rule::MissingTrailingComma) { - // Create a replacement that includes the final bracket (or other token), - // rather than just inserting a comma at the end. This prevents the UP034 autofix - // removing any brackets in the same linter pass - doing both at the same time could - // lead to a syntax error. - let contents = locator.slice(missing_comma.1); - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - format!("{contents},"), - missing_comma.1, - ))); - } + // Create a replacement that includes the final bracket (or other token), + // rather than just inserting a comma at the end. This prevents the UP034 fix + // removing any brackets in the same linter pass - doing both at the same time could + // lead to a syntax error. + let contents = locator.slice(missing_comma.1); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + format!("{contents},"), + missing_comma.1, + ))); diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_commas/snapshots/ruff_linter__rules__flake8_commas__tests__COM81.py.snap b/crates/ruff_linter/src/rules/flake8_commas/snapshots/ruff_linter__rules__flake8_commas__tests__COM81.py.snap index 0fa18c2cea99b..fe61754579e6a 100644 --- a/crates/ruff_linter/src/rules/flake8_commas/snapshots/ruff_linter__rules__flake8_commas__tests__COM81.py.snap +++ b/crates/ruff_linter/src/rules/flake8_commas/snapshots/ruff_linter__rules__flake8_commas__tests__COM81.py.snap @@ -917,11 +917,11 @@ COM81.py:627:20: COM812 [*] Trailing comma missing 627 |+ **{'ham': spam}, 628 628 | ) 629 629 | -630 630 | # Make sure the COM812 and UP034 rules don't autofix simultaneously and cause a syntax error. +630 630 | # Make sure the COM812 and UP034 rules don't fix simultaneously and cause a syntax error. COM81.py:632:42: COM812 [*] Trailing comma missing | -630 | # Make sure the COM812 and UP034 rules don't autofix simultaneously and cause a syntax error. +630 | # Make sure the COM812 and UP034 rules don't fix simultaneously and cause a syntax error. 631 | the_first_one = next( 632 | (i for i in range(10) if i // 2 == 0) # COM812 fix should include the final bracket | COM812 @@ -931,7 +931,7 @@ COM81.py:632:42: COM812 [*] Trailing comma missing ℹ Fix 629 629 | -630 630 | # Make sure the COM812 and UP034 rules don't autofix simultaneously and cause a syntax error. +630 630 | # Make sure the COM812 and UP034 rules don't fix simultaneously and cause a syntax error. 631 631 | the_first_one = next( 632 |- (i for i in range(10) if i // 2 == 0) # COM812 fix should include the final bracket 632 |+ (i for i in range(10) if i // 2 == 0), # COM812 fix should include the final bracket diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/fixes.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/fixes.rs index 6ede08874185e..7772b430dc1ad 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/fixes.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/fixes.rs @@ -7,6 +7,7 @@ use libcst_native::{ RightCurlyBrace, RightParen, RightSquareBracket, Set, SetComp, SimpleString, SimpleWhitespace, TrailingWhitespace, Tuple, }; +use std::iter; use ruff_diagnostics::{Edit, Fix}; use ruff_python_ast::Expr; @@ -15,9 +16,9 @@ use ruff_python_semantic::SemanticModel; use ruff_source_file::Locator; use ruff_text_size::{Ranged, TextRange}; -use crate::autofix::codemods::CodegenStylist; -use crate::autofix::edits::pad; use crate::cst::helpers::{negate, space}; +use crate::fix::codemods::CodegenStylist; +use crate::fix::edits::pad; use crate::rules::flake8_comprehensions::rules::ObjectType; use crate::{ checkers::ast::Checker, @@ -823,14 +824,20 @@ pub(crate) fn fix_unnecessary_double_cast_or_process( outer_call.args = match outer_call.args.split_first() { Some((first, rest)) => { let inner_call = match_call(&first.value)?; - inner_call + if let Some(arg) = inner_call .args .iter() - .filter(|argument| argument.keyword.is_none()) - .take(1) - .chain(rest.iter()) - .cloned() - .collect::>() + .find(|argument| argument.keyword.is_none()) + { + let mut arg = arg.clone(); + arg.comma = first.comma.clone(); + arg.whitespace_after_arg = first.whitespace_after_arg.clone(); + iter::once(arg) + .chain(rest.iter().cloned()) + .collect::>() + } else { + rest.to_vec() + } } None => bail!("Expected at least one argument in outer function call"), }; @@ -1286,7 +1293,7 @@ pub(crate) fn fix_unnecessary_comprehension_any_all( _ => whitespace_after_arg, }; - Ok(Fix::suggested(Edit::range_replacement( + Ok(Fix::unsafe_edit(Edit::range_replacement( tree.codegen_stylist(stylist), expr.range(), ))) diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs index bc233cc6651fe..7117d09991687 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs @@ -1,10 +1,10 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Expr}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_comprehensions::fixes; /// ## What it does @@ -35,14 +35,14 @@ pub struct UnnecessaryCallAroundSorted { func: String, } -impl AlwaysAutofixableViolation for UnnecessaryCallAroundSorted { +impl AlwaysFixableViolation for UnnecessaryCallAroundSorted { #[derive_message_formats] fn message(&self) -> String { let UnnecessaryCallAroundSorted { func } = self; format!("Unnecessary `{func}` call around `sorted()`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let UnnecessaryCallAroundSorted { func } = self; format!("Remove unnecessary `{func}` call") } @@ -82,19 +82,14 @@ pub(crate) fn unnecessary_call_around_sorted( }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - let edit = fixes::fix_unnecessary_call_around_sorted( - expr, - checker.locator(), - checker.stylist(), - )?; - if outer.id == "reversed" { - Ok(Fix::suggested(edit)) - } else { - Ok(Fix::automatic(edit)) - } - }); - } + diagnostic.try_set_fix(|| { + let edit = + fixes::fix_unnecessary_call_around_sorted(expr, checker.locator(), checker.stylist())?; + if outer.id == "reversed" { + Ok(Fix::unsafe_edit(edit)) + } else { + Ok(Fix::safe_edit(edit)) + } + }); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_collection_call.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_collection_call.rs index 01e6e0b38388b..8d40f83506666 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_collection_call.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_collection_call.rs @@ -1,10 +1,10 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{Expr, Keyword}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_comprehensions::fixes; use crate::rules::flake8_comprehensions::settings::Settings; @@ -37,14 +37,14 @@ pub struct UnnecessaryCollectionCall { obj_type: String, } -impl AlwaysAutofixableViolation for UnnecessaryCollectionCall { +impl AlwaysFixableViolation for UnnecessaryCollectionCall { #[derive_message_formats] fn message(&self) -> String { let UnnecessaryCollectionCall { obj_type } = self; format!("Unnecessary `{obj_type}` call (rewrite as a literal)") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Rewrite as a literal".to_string() } } @@ -86,10 +86,8 @@ pub(crate) fn unnecessary_collection_call( }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - fixes::fix_unnecessary_collection_call(expr, checker).map(Fix::suggested) - }); - } + diagnostic.try_set_fix(|| { + fixes::fix_unnecessary_collection_call(expr, checker).map(Fix::unsafe_edit) + }); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_comprehension.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_comprehension.rs index a31ed5fa92d15..f11aa25b63a4e 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_comprehension.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_comprehension.rs @@ -1,11 +1,11 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::comparable::ComparableExpr; use ruff_python_ast::{self as ast, Comprehension, Expr}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_comprehensions::fixes; /// ## What it does @@ -34,14 +34,14 @@ pub struct UnnecessaryComprehension { obj_type: String, } -impl AlwaysAutofixableViolation for UnnecessaryComprehension { +impl AlwaysFixableViolation for UnnecessaryComprehension { #[derive_message_formats] fn message(&self) -> String { let UnnecessaryComprehension { obj_type } = self; format!("Unnecessary `{obj_type}` comprehension (rewrite using `{obj_type}()`)") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let UnnecessaryComprehension { obj_type } = self; format!("Rewrite using `{obj_type}()`") } @@ -64,12 +64,10 @@ fn add_diagnostic(checker: &mut Checker, expr: &Expr) { }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - fixes::fix_unnecessary_comprehension(expr, checker.locator(), checker.stylist()) - .map(Fix::suggested) - }); - } + diagnostic.try_set_fix(|| { + fixes::fix_unnecessary_comprehension(expr, checker.locator(), checker.stylist()) + .map(Fix::unsafe_edit) + }); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_comprehension_any_all.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_comprehension_any_all.rs index d50a5de057414..9527082ae8ebf 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_comprehension_any_all.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_comprehension_any_all.rs @@ -1,13 +1,13 @@ use ruff_python_ast::{self as ast, Expr, Keyword}; use ruff_diagnostics::Violation; -use ruff_diagnostics::{AutofixKind, Diagnostic}; +use ruff_diagnostics::{Diagnostic, FixAvailability}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::any_over_expr; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_comprehensions::fixes; /// ## What it does @@ -44,14 +44,14 @@ use crate::rules::flake8_comprehensions::fixes; pub struct UnnecessaryComprehensionAnyAll; impl Violation for UnnecessaryComprehensionAnyAll { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Unnecessary list comprehension.") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Remove unnecessary list comprehension".to_string()) } } @@ -89,11 +89,9 @@ pub(crate) fn unnecessary_comprehension_any_all( } let mut diagnostic = Diagnostic::new(UnnecessaryComprehensionAnyAll, arg.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - fixes::fix_unnecessary_comprehension_any_all(expr, checker.locator(), checker.stylist()) - }); - } + diagnostic.try_set_fix(|| { + fixes::fix_unnecessary_comprehension_any_all(expr, checker.locator(), checker.stylist()) + }); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs index bb4922afd46eb..5bdeca9a5725b 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs @@ -1,11 +1,11 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::comparable::ComparableKeyword; use ruff_python_ast::{self as ast, Arguments, Expr, Keyword}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_comprehensions::fixes; /// ## What it does @@ -49,14 +49,14 @@ pub struct UnnecessaryDoubleCastOrProcess { outer: String, } -impl AlwaysAutofixableViolation for UnnecessaryDoubleCastOrProcess { +impl AlwaysFixableViolation for UnnecessaryDoubleCastOrProcess { #[derive_message_formats] fn message(&self) -> String { let UnnecessaryDoubleCastOrProcess { inner, outer } = self; format!("Unnecessary `{inner}` call within `{outer}()`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let UnnecessaryDoubleCastOrProcess { inner, .. } = self; format!("Remove the inner `{inner}` call") } @@ -130,16 +130,14 @@ pub(crate) fn unnecessary_double_cast_or_process( }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - fixes::fix_unnecessary_double_cast_or_process( - expr, - checker.locator(), - checker.stylist(), - ) - .map(Fix::suggested) - }); - } + diagnostic.try_set_fix(|| { + fixes::fix_unnecessary_double_cast_or_process( + expr, + checker.locator(), + checker.stylist(), + ) + .map(Fix::unsafe_edit) + }); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_dict.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_dict.rs index e507c77a1f93a..e9be9ad143996 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_dict.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_dict.rs @@ -1,10 +1,10 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Expr, Keyword}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_comprehensions::fixes; use super::helpers; @@ -30,13 +30,13 @@ use super::helpers; #[violation] pub struct UnnecessaryGeneratorDict; -impl AlwaysAutofixableViolation for UnnecessaryGeneratorDict { +impl AlwaysFixableViolation for UnnecessaryGeneratorDict { #[derive_message_formats] fn message(&self) -> String { format!("Unnecessary generator (rewrite as a `dict` comprehension)") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Rewrite as a `dict` comprehension".to_string() } } @@ -67,10 +67,7 @@ pub(crate) fn unnecessary_generator_dict( return; } let mut diagnostic = Diagnostic::new(UnnecessaryGeneratorDict, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - fixes::fix_unnecessary_generator_dict(expr, checker).map(Fix::suggested) - }); - } + diagnostic + .try_set_fix(|| fixes::fix_unnecessary_generator_dict(expr, checker).map(Fix::unsafe_edit)); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_list.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_list.rs index 8c8b43591e53d..06648ef7b52b7 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_list.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_list.rs @@ -1,11 +1,11 @@ use ruff_python_ast::{Expr, Keyword}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_comprehensions::fixes; use super::helpers; @@ -31,13 +31,13 @@ use super::helpers; #[violation] pub struct UnnecessaryGeneratorList; -impl AlwaysAutofixableViolation for UnnecessaryGeneratorList { +impl AlwaysFixableViolation for UnnecessaryGeneratorList { #[derive_message_formats] fn message(&self) -> String { format!("Unnecessary generator (rewrite as a `list` comprehension)") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Rewrite as a `list` comprehension".to_string() } } @@ -60,12 +60,10 @@ pub(crate) fn unnecessary_generator_list( } if let Expr::GeneratorExp(_) = argument { let mut diagnostic = Diagnostic::new(UnnecessaryGeneratorList, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - fixes::fix_unnecessary_generator_list(expr, checker.locator(), checker.stylist()) - .map(Fix::suggested) - }); - } + diagnostic.try_set_fix(|| { + fixes::fix_unnecessary_generator_list(expr, checker.locator(), checker.stylist()) + .map(Fix::unsafe_edit) + }); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs index d4fd13c33e2d7..124a838dd23a7 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs @@ -1,11 +1,11 @@ use ruff_python_ast::{Expr, Keyword}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_comprehensions::fixes; use super::helpers; @@ -31,13 +31,13 @@ use super::helpers; #[violation] pub struct UnnecessaryGeneratorSet; -impl AlwaysAutofixableViolation for UnnecessaryGeneratorSet { +impl AlwaysFixableViolation for UnnecessaryGeneratorSet { #[derive_message_formats] fn message(&self) -> String { format!("Unnecessary generator (rewrite as a `set` comprehension)") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Rewrite as a `set` comprehension".to_string() } } @@ -60,11 +60,9 @@ pub(crate) fn unnecessary_generator_set( } if let Expr::GeneratorExp(_) = argument { let mut diagnostic = Diagnostic::new(UnnecessaryGeneratorSet, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - fixes::fix_unnecessary_generator_set(expr, checker).map(Fix::suggested) - }); - } + diagnostic.try_set_fix(|| { + fixes::fix_unnecessary_generator_set(expr, checker).map(Fix::unsafe_edit) + }); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs index 1f4cf31a830cd..587b2754c7708 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs @@ -1,11 +1,11 @@ use ruff_python_ast::Expr; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_comprehensions::fixes; use super::helpers; @@ -28,13 +28,13 @@ use super::helpers; #[violation] pub struct UnnecessaryListCall; -impl AlwaysAutofixableViolation for UnnecessaryListCall { +impl AlwaysFixableViolation for UnnecessaryListCall { #[derive_message_formats] fn message(&self) -> String { format!("Unnecessary `list` call (remove the outer call to `list()`)") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove outer `list` call".to_string() } } @@ -56,11 +56,9 @@ pub(crate) fn unnecessary_list_call( return; } let mut diagnostic = Diagnostic::new(UnnecessaryListCall, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - fixes::fix_unnecessary_list_call(expr, checker.locator(), checker.stylist()) - .map(Fix::suggested) - }); - } + diagnostic.try_set_fix(|| { + fixes::fix_unnecessary_list_call(expr, checker.locator(), checker.stylist()) + .map(Fix::unsafe_edit) + }); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_dict.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_dict.rs index e92d5b6663d12..90b90afcddec8 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_dict.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_dict.rs @@ -1,10 +1,10 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Expr, Keyword}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_comprehensions::fixes; use super::helpers; @@ -28,13 +28,13 @@ use super::helpers; #[violation] pub struct UnnecessaryListComprehensionDict; -impl AlwaysAutofixableViolation for UnnecessaryListComprehensionDict { +impl AlwaysFixableViolation for UnnecessaryListComprehensionDict { #[derive_message_formats] fn message(&self) -> String { format!("Unnecessary `list` comprehension (rewrite as a `dict` comprehension)") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Rewrite as a `dict` comprehension".to_string() } } @@ -65,10 +65,8 @@ pub(crate) fn unnecessary_list_comprehension_dict( return; } let mut diagnostic = Diagnostic::new(UnnecessaryListComprehensionDict, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - fixes::fix_unnecessary_list_comprehension_dict(expr, checker).map(Fix::suggested) - }); - } + diagnostic.try_set_fix(|| { + fixes::fix_unnecessary_list_comprehension_dict(expr, checker).map(Fix::unsafe_edit) + }); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_set.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_set.rs index 34e775fc39407..3e5902ccd5afd 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_set.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_set.rs @@ -1,11 +1,11 @@ use ruff_python_ast::{Expr, Keyword}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_comprehensions::fixes; use super::helpers; @@ -29,13 +29,13 @@ use super::helpers; #[violation] pub struct UnnecessaryListComprehensionSet; -impl AlwaysAutofixableViolation for UnnecessaryListComprehensionSet { +impl AlwaysFixableViolation for UnnecessaryListComprehensionSet { #[derive_message_formats] fn message(&self) -> String { format!("Unnecessary `list` comprehension (rewrite as a `set` comprehension)") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Rewrite as a `set` comprehension".to_string() } } @@ -58,11 +58,9 @@ pub(crate) fn unnecessary_list_comprehension_set( } if argument.is_list_comp_expr() { let mut diagnostic = Diagnostic::new(UnnecessaryListComprehensionSet, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - fixes::fix_unnecessary_list_comprehension_set(expr, checker).map(Fix::suggested) - }); - } + diagnostic.try_set_fix(|| { + fixes::fix_unnecessary_list_comprehension_set(expr, checker).map(Fix::unsafe_edit) + }); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_dict.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_dict.rs index 36403f70c6bf3..26ea9ea0d3563 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_dict.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_dict.rs @@ -1,10 +1,10 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Expr, Keyword}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_comprehensions::fixes; use super::helpers; @@ -34,14 +34,14 @@ pub struct UnnecessaryLiteralDict { obj_type: String, } -impl AlwaysAutofixableViolation for UnnecessaryLiteralDict { +impl AlwaysFixableViolation for UnnecessaryLiteralDict { #[derive_message_formats] fn message(&self) -> String { let UnnecessaryLiteralDict { obj_type } = self; format!("Unnecessary `{obj_type}` literal (rewrite as a `dict` literal)") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Rewrite as a `dict` literal".to_string() } } @@ -80,9 +80,7 @@ pub(crate) fn unnecessary_literal_dict( }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic - .try_set_fix(|| fixes::fix_unnecessary_literal_dict(expr, checker).map(Fix::suggested)); - } + diagnostic + .try_set_fix(|| fixes::fix_unnecessary_literal_dict(expr, checker).map(Fix::unsafe_edit)); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_set.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_set.rs index 2d22f0b804a57..fc4c33a0e8df1 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_set.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_set.rs @@ -1,11 +1,11 @@ use ruff_python_ast::{Expr, Keyword}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_comprehensions::fixes; use super::helpers; @@ -36,14 +36,14 @@ pub struct UnnecessaryLiteralSet { obj_type: String, } -impl AlwaysAutofixableViolation for UnnecessaryLiteralSet { +impl AlwaysFixableViolation for UnnecessaryLiteralSet { #[derive_message_formats] fn message(&self) -> String { let UnnecessaryLiteralSet { obj_type } = self; format!("Unnecessary `{obj_type}` literal (rewrite as a `set` literal)") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Rewrite as a `set` literal".to_string() } } @@ -75,9 +75,7 @@ pub(crate) fn unnecessary_literal_set( }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic - .try_set_fix(|| fixes::fix_unnecessary_literal_set(expr, checker).map(Fix::suggested)); - } + diagnostic + .try_set_fix(|| fixes::fix_unnecessary_literal_set(expr, checker).map(Fix::unsafe_edit)); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs index 5ee01a75276c2..121ceaf685886 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs @@ -2,12 +2,12 @@ use std::fmt; use ruff_python_ast::{Expr, Keyword}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_comprehensions::fixes; use super::helpers; @@ -51,14 +51,14 @@ pub struct UnnecessaryLiteralWithinDictCall { kind: DictKind, } -impl AlwaysAutofixableViolation for UnnecessaryLiteralWithinDictCall { +impl AlwaysFixableViolation for UnnecessaryLiteralWithinDictCall { #[derive_message_formats] fn message(&self) -> String { let UnnecessaryLiteralWithinDictCall { kind } = self; format!("Unnecessary `dict` {kind} passed to `dict()` (remove the outer call to `dict()`)") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove outer `dict` call".to_string() } } @@ -91,15 +91,9 @@ pub(crate) fn unnecessary_literal_within_dict_call( }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - fixes::fix_unnecessary_literal_within_dict_call( - expr, - checker.locator(), - checker.stylist(), - ) - .map(Fix::suggested) - }); - } + diagnostic.try_set_fix(|| { + fixes::fix_unnecessary_literal_within_dict_call(expr, checker.locator(), checker.stylist()) + .map(Fix::unsafe_edit) + }); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs index f6810ad4468e2..6cb4596f9f116 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs @@ -1,10 +1,10 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{Expr, Keyword}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_comprehensions::fixes; use super::helpers; @@ -37,7 +37,7 @@ pub struct UnnecessaryLiteralWithinListCall { literal: String, } -impl AlwaysAutofixableViolation for UnnecessaryLiteralWithinListCall { +impl AlwaysFixableViolation for UnnecessaryLiteralWithinListCall { #[derive_message_formats] fn message(&self) -> String { let UnnecessaryLiteralWithinListCall { literal } = self; @@ -53,7 +53,7 @@ impl AlwaysAutofixableViolation for UnnecessaryLiteralWithinListCall { } } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let UnnecessaryLiteralWithinListCall { literal } = self; { if literal == "list" { @@ -93,15 +93,9 @@ pub(crate) fn unnecessary_literal_within_list_call( }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - fixes::fix_unnecessary_literal_within_list_call( - expr, - checker.locator(), - checker.stylist(), - ) - .map(Fix::suggested) - }); - } + diagnostic.try_set_fix(|| { + fixes::fix_unnecessary_literal_within_list_call(expr, checker.locator(), checker.stylist()) + .map(Fix::unsafe_edit) + }); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_tuple_call.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_tuple_call.rs index 83ae8d141093d..d1600979faf59 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_tuple_call.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_tuple_call.rs @@ -1,11 +1,11 @@ use ruff_python_ast::{Expr, Keyword}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_comprehensions::fixes; use super::helpers; @@ -38,7 +38,7 @@ pub struct UnnecessaryLiteralWithinTupleCall { literal: String, } -impl AlwaysAutofixableViolation for UnnecessaryLiteralWithinTupleCall { +impl AlwaysFixableViolation for UnnecessaryLiteralWithinTupleCall { #[derive_message_formats] fn message(&self) -> String { let UnnecessaryLiteralWithinTupleCall { literal } = self; @@ -55,7 +55,7 @@ impl AlwaysAutofixableViolation for UnnecessaryLiteralWithinTupleCall { } } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let UnnecessaryLiteralWithinTupleCall { literal } = self; { if literal == "list" { @@ -95,15 +95,9 @@ pub(crate) fn unnecessary_literal_within_tuple_call( }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - fixes::fix_unnecessary_literal_within_tuple_call( - expr, - checker.locator(), - checker.stylist(), - ) - .map(Fix::suggested) - }); - } + diagnostic.try_set_fix(|| { + fixes::fix_unnecessary_literal_within_tuple_call(expr, checker.locator(), checker.stylist()) + .map(Fix::unsafe_edit) + }); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_map.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_map.rs index 2dd0fa0025656..549906f0e780c 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_map.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_map.rs @@ -1,7 +1,7 @@ use std::fmt; -use ruff_diagnostics::{AutofixKind, Violation}; use ruff_diagnostics::{Diagnostic, Fix}; +use ruff_diagnostics::{FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::visitor; use ruff_python_ast::visitor::Visitor; @@ -9,7 +9,7 @@ use ruff_python_ast::{self as ast, Arguments, Expr, ExprContext, Parameters, Stm use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_comprehensions::fixes; use super::helpers; @@ -47,7 +47,7 @@ pub struct UnnecessaryMap { } impl Violation for UnnecessaryMap { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -55,7 +55,7 @@ impl Violation for UnnecessaryMap { format!("Unnecessary `map` usage (rewrite using a {object_type})") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let UnnecessaryMap { object_type } = self; Some(format!("Replace `map` with a {object_type}")) } @@ -221,18 +221,16 @@ pub(crate) fn unnecessary_map( }; let mut diagnostic = Diagnostic::new(UnnecessaryMap { object_type }, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - fixes::fix_unnecessary_map( - expr, - parent, - object_type, - checker.locator(), - checker.stylist(), - ) - .map(Fix::suggested) - }); - } + diagnostic.try_set_fix(|| { + fixes::fix_unnecessary_map( + expr, + parent, + object_type, + checker.locator(), + checker.stylist(), + ) + .map(Fix::unsafe_edit) + }); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_subscript_reversal.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_subscript_reversal.rs index ab00f7892d926..4caa72892eceb 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_subscript_reversal.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_subscript_reversal.rs @@ -1,5 +1,3 @@ -use num_bigint::BigInt; - use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Constant, Expr, UnaryOp}; @@ -17,16 +15,16 @@ use crate::checkers::ast::Checker; /// /// ## Examples /// ```python -/// reversed(iterable[::-1]) +/// sorted(iterable[::-1]) /// set(iterable[::-1]) -/// sorted(iterable)[::-1] +/// reversed(iterable[::-1]) /// ``` /// /// Use instead: /// ```python -/// reversed(iterable) +/// sorted(iterable) /// set(iterable) -/// sorted(iterable, reverse=True) +/// iterable /// ``` #[violation] pub struct UnnecessarySubscriptReversal { @@ -42,16 +40,11 @@ impl Violation for UnnecessarySubscriptReversal { } /// C415 -pub(crate) fn unnecessary_subscript_reversal( - checker: &mut Checker, - expr: &Expr, - func: &Expr, - args: &[Expr], -) { - let Some(first_arg) = args.first() else { +pub(crate) fn unnecessary_subscript_reversal(checker: &mut Checker, call: &ast::ExprCall) { + let Some(first_arg) = call.arguments.args.first() else { return; }; - let Some(func) = func.as_name_expr() else { + let Some(func) = call.func.as_name_expr() else { return; }; if !matches!(func.id.as_str(), "reversed" | "set" | "sorted") { @@ -93,13 +86,13 @@ pub(crate) fn unnecessary_subscript_reversal( else { return; }; - if *val != BigInt::from(1) { + if *val != 1 { return; }; checker.diagnostics.push(Diagnostic::new( UnnecessarySubscriptReversal { func: func.id.to_string(), }, - expr.range(), + call.range(), )); } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C414_C414.py.snap b/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C414_C414.py.snap index d2cae0af64f84..396a8d26ab0eb 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C414_C414.py.snap +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C414_C414.py.snap @@ -181,7 +181,7 @@ C414.py:10:1: C414 [*] Unnecessary `sorted` call within `set()` 8 8 | set(tuple(x)) 9 9 | set(sorted(x)) 10 |-set(sorted(x, key=lambda y: y)) - 10 |+set(x, ) + 10 |+set(x) 11 11 | set(reversed(x)) 12 12 | sorted(list(x)) 13 13 | sorted(tuple(x)) @@ -378,11 +378,10 @@ C414.py:19:1: C414 [*] Unnecessary `list` call within `tuple()` 21 |- [x, 3, "hell"\ 20 |+ [x, 3, "hell"\ 22 21 | "o"] -23 22 | ) -24 |-) +23 |- ) +24 22 | ) 25 23 | set(set()) 26 24 | set(list()) -27 25 | set(tuple()) C414.py:25:1: C414 [*] Unnecessary `set` call within `set()` | @@ -467,4 +466,52 @@ C414.py:28:1: C414 [*] Unnecessary `reversed` call within `sorted()` 30 30 | # Nested sorts with differing keyword arguments. Not flagged. 31 31 | sorted(sorted(x, key=lambda y: y)) +C414.py:37:27: C414 [*] Unnecessary `list` call within `sorted()` + | +36 | # Preserve trailing comments. +37 | xxxxxxxxxxx_xxxxx_xxxxx = sorted( + | ___________________________^ +38 | | list(x_xxxx_xxxxxxxxxxx_xxxxx.xxxx()), +39 | | # xxxxxxxxxxx xxxxx xxxx xxx xx Nxxx, xxx xxxxxx3 xxxxxxxxx xx +40 | | # xx xxxx xxxxxxx xxxx xxx xxxxxxxx Nxxx +41 | | key=lambda xxxxx: xxxxx or "", +42 | | ) + | |_^ C414 +43 | +44 | xxxxxxxxxxx_xxxxx_xxxxx = sorted( + | + = help: Remove the inner `list` call + +ℹ Suggested fix +35 35 | +36 36 | # Preserve trailing comments. +37 37 | xxxxxxxxxxx_xxxxx_xxxxx = sorted( +38 |- list(x_xxxx_xxxxxxxxxxx_xxxxx.xxxx()), + 38 |+ x_xxxx_xxxxxxxxxxx_xxxxx.xxxx(), +39 39 | # xxxxxxxxxxx xxxxx xxxx xxx xx Nxxx, xxx xxxxxx3 xxxxxxxxx xx +40 40 | # xx xxxx xxxxxxx xxxx xxx xxxxxxxx Nxxx +41 41 | key=lambda xxxxx: xxxxx or "", + +C414.py:44:27: C414 [*] Unnecessary `list` call within `sorted()` + | +42 | ) +43 | +44 | xxxxxxxxxxx_xxxxx_xxxxx = sorted( + | ___________________________^ +45 | | list(x_xxxx_xxxxxxxxxxx_xxxxx.xxxx()), # xxxxxxxxxxx xxxxx xxxx xxx xx Nxxx +46 | | key=lambda xxxxx: xxxxx or "", +47 | | ) + | |_^ C414 + | + = help: Remove the inner `list` call + +ℹ Suggested fix +42 42 | ) +43 43 | +44 44 | xxxxxxxxxxx_xxxxx_xxxxx = sorted( +45 |- list(x_xxxx_xxxxxxxxxxx_xxxxx.xxxx()), # xxxxxxxxxxx xxxxx xxxx xxx xx Nxxx + 45 |+ x_xxxx_xxxxxxxxxxx_xxxxx.xxxx(), # xxxxxxxxxxx xxxxx xxxx xxx xx Nxxx +46 46 | key=lambda xxxxx: xxxxx or "", +47 47 | ) + diff --git a/crates/ruff_linter/src/rules/flake8_errmsg/rules/string_in_exception.rs b/crates/ruff_linter/src/rules/flake8_errmsg/rules/string_in_exception.rs index d3668322a1aac..06543424f46e8 100644 --- a/crates/ruff_linter/src/rules/flake8_errmsg/rules/string_in_exception.rs +++ b/crates/ruff_linter/src/rules/flake8_errmsg/rules/string_in_exception.rs @@ -1,13 +1,13 @@ use ruff_python_ast::{self as ast, Arguments, Constant, Expr, ExprContext, Stmt}; use ruff_text_size::{Ranged, TextRange}; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::whitespace; use ruff_python_codegen::{Generator, Stylist}; use crate::checkers::ast::Checker; -use crate::registry::{AsRule, Rule}; +use crate::registry::Rule; /// ## What it does /// Checks for the use of string literals in exception constructors. @@ -50,14 +50,14 @@ use crate::registry::{AsRule, Rule}; pub struct RawStringInException; impl Violation for RawStringInException { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Exception must not use a string literal, assign to variable first") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Assign to variable; remove string literal".to_string()) } } @@ -104,14 +104,14 @@ impl Violation for RawStringInException { pub struct FStringInException; impl Violation for FStringInException { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Exception must not use an f-string literal, assign to variable first") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Assign to variable; remove f-string literal".to_string()) } } @@ -160,14 +160,14 @@ impl Violation for FStringInException { pub struct DotFormatInException; impl Violation for DotFormatInException { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Exception must not use a `.format()` string directly, assign to variable first") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Assign to variable; remove `.format()` string".to_string()) } } @@ -190,30 +190,6 @@ pub(crate) fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr if string.len() >= checker.settings.flake8_errmsg.max_string_length { let mut diagnostic = Diagnostic::new(RawStringInException, first.range()); - if checker.patch(diagnostic.kind.rule()) { - if let Some(indentation) = - whitespace::indentation(checker.locator(), stmt) - { - if checker.semantic().is_available("msg") { - diagnostic.set_fix(generate_fix( - stmt, - first, - indentation, - checker.stylist(), - checker.generator(), - )); - } - } - } - checker.diagnostics.push(diagnostic); - } - } - } - // Check for f-strings. - Expr::FString(_) => { - if checker.enabled(Rule::FStringInException) { - let mut diagnostic = Diagnostic::new(FStringInException, first.range()); - if checker.patch(diagnostic.kind.rule()) { if let Some(indentation) = whitespace::indentation(checker.locator(), stmt) { @@ -227,6 +203,25 @@ pub(crate) fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr )); } } + checker.diagnostics.push(diagnostic); + } + } + } + // Check for f-strings. + Expr::FString(_) => { + if checker.enabled(Rule::FStringInException) { + let mut diagnostic = Diagnostic::new(FStringInException, first.range()); + if let Some(indentation) = whitespace::indentation(checker.locator(), stmt) + { + if checker.semantic().is_available("msg") { + diagnostic.set_fix(generate_fix( + stmt, + first, + indentation, + checker.stylist(), + checker.generator(), + )); + } } checker.diagnostics.push(diagnostic); } @@ -240,19 +235,17 @@ pub(crate) fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr if attr == "format" && value.is_constant_expr() { let mut diagnostic = Diagnostic::new(DotFormatInException, first.range()); - if checker.patch(diagnostic.kind.rule()) { - if let Some(indentation) = - whitespace::indentation(checker.locator(), stmt) - { - if checker.semantic().is_available("msg") { - diagnostic.set_fix(generate_fix( - stmt, - first, - indentation, - checker.stylist(), - checker.generator(), - )); - } + if let Some(indentation) = + whitespace::indentation(checker.locator(), stmt) + { + if checker.semantic().is_available("msg") { + diagnostic.set_fix(generate_fix( + stmt, + first, + indentation, + checker.stylist(), + checker.generator(), + )); } } checker.diagnostics.push(diagnostic); @@ -293,7 +286,7 @@ fn generate_fix( range: TextRange::default(), }); - Fix::suggested_edits( + Fix::unsafe_edits( Edit::insertion( format!( "{}{}{}", diff --git a/crates/ruff_linter/src/rules/flake8_executable/rules/mod.rs b/crates/ruff_linter/src/rules/flake8_executable/rules/mod.rs index 506a5a63ca538..e47e7a4d2cdc2 100644 --- a/crates/ruff_linter/src/rules/flake8_executable/rules/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_executable/rules/mod.rs @@ -12,7 +12,6 @@ pub(crate) use shebang_not_executable::*; pub(crate) use shebang_not_first_line::*; use crate::comments::shebang::ShebangDirective; -use crate::settings::LinterSettings; mod shebang_leading_whitespace; mod shebang_missing_executable_file; @@ -24,7 +23,6 @@ pub(crate) fn from_tokens( tokens: &[LexResult], path: &Path, locator: &Locator, - settings: &LinterSettings, diagnostics: &mut Vec, ) { let mut has_any_shebang = false; @@ -41,7 +39,7 @@ pub(crate) fn from_tokens( diagnostics.push(diagnostic); } - if let Some(diagnostic) = shebang_leading_whitespace(*range, locator, settings) { + if let Some(diagnostic) = shebang_leading_whitespace(*range, locator) { diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_executable/rules/shebang_leading_whitespace.rs b/crates/ruff_linter/src/rules/flake8_executable/rules/shebang_leading_whitespace.rs index 7055a3061e192..0aa88beaf17b4 100644 --- a/crates/ruff_linter/src/rules/flake8_executable/rules/shebang_leading_whitespace.rs +++ b/crates/ruff_linter/src/rules/flake8_executable/rules/shebang_leading_whitespace.rs @@ -1,13 +1,10 @@ use ruff_text_size::{TextRange, TextSize}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_trivia::is_python_whitespace; use ruff_source_file::Locator; -use crate::registry::AsRule; -use crate::settings::LinterSettings; - /// ## What it does /// Checks for whitespace before a shebang directive. /// @@ -35,13 +32,13 @@ use crate::settings::LinterSettings; #[violation] pub struct ShebangLeadingWhitespace; -impl AlwaysAutofixableViolation for ShebangLeadingWhitespace { +impl AlwaysFixableViolation for ShebangLeadingWhitespace { #[derive_message_formats] fn message(&self) -> String { format!("Avoid whitespace before shebang") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { format!("Remove whitespace before shebang") } } @@ -50,7 +47,6 @@ impl AlwaysAutofixableViolation for ShebangLeadingWhitespace { pub(crate) fn shebang_leading_whitespace( range: TextRange, locator: &Locator, - settings: &LinterSettings, ) -> Option { // If the shebang is at the beginning of the file, abort. if range.start() == TextSize::from(0) { @@ -68,8 +64,6 @@ pub(crate) fn shebang_leading_whitespace( let prefix = TextRange::up_to(range.start()); let mut diagnostic = Diagnostic::new(ShebangLeadingWhitespace, prefix); - if settings.rules.should_fix(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::range_deletion(prefix))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(prefix))); Some(diagnostic) } diff --git a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/rules/implicit.rs b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/rules/implicit.rs index 0a2e381a55a9a..5e91f0ccead47 100644 --- a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/rules/implicit.rs +++ b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/rules/implicit.rs @@ -1,13 +1,15 @@ use itertools::Itertools; -use ruff_python_parser::lexer::LexResult; -use ruff_text_size::{Ranged, TextRange}; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::str::{leading_quote, trailing_quote}; +use ruff_python_index::Indexer; +use ruff_python_parser::lexer::LexResult; +use ruff_python_parser::Tok; use ruff_source_file::Locator; +use ruff_text_size::{Ranged, TextRange}; -use crate::rules::flake8_implicit_str_concat::settings::Settings; +use crate::settings::LinterSettings; /// ## What it does /// Checks for implicitly concatenated strings on a single line. @@ -18,7 +20,7 @@ use crate::rules::flake8_implicit_str_concat::settings::Settings; /// negatively affects code readability. /// /// In some cases, the implicit concatenation may also be unintentional, as -/// autoformatters are capable of introducing single-line implicit +/// code formatters are capable of introducing single-line implicit /// concatenations when collapsing long lines. /// /// ## Example @@ -34,14 +36,14 @@ use crate::rules::flake8_implicit_str_concat::settings::Settings; pub struct SingleLineImplicitStringConcatenation; impl Violation for SingleLineImplicitStringConcatenation { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Implicitly concatenated string literals on one line") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Combine string literals".to_string()) } } @@ -92,35 +94,62 @@ impl Violation for MultiLineImplicitStringConcatenation { pub(crate) fn implicit( diagnostics: &mut Vec, tokens: &[LexResult], - settings: &Settings, + settings: &LinterSettings, locator: &Locator, + indexer: &Indexer, ) { for ((a_tok, a_range), (b_tok, b_range)) in tokens .iter() .flatten() .filter(|(tok, _)| { - !tok.is_comment() && (settings.allow_multiline || !tok.is_non_logical_newline()) + !tok.is_comment() + && (settings.flake8_implicit_str_concat.allow_multiline + || !tok.is_non_logical_newline()) }) .tuple_windows() { - if a_tok.is_string() && b_tok.is_string() { - if locator.contains_line_break(TextRange::new(a_range.end(), b_range.start())) { - diagnostics.push(Diagnostic::new( - MultiLineImplicitStringConcatenation, - TextRange::new(a_range.start(), b_range.end()), - )); - } else { - let mut diagnostic = Diagnostic::new( - SingleLineImplicitStringConcatenation, - TextRange::new(a_range.start(), b_range.end()), - ); - - if let Some(fix) = concatenate_strings(*a_range, *b_range, locator) { - diagnostic.set_fix(fix); + let (a_range, b_range) = match (a_tok, b_tok) { + (Tok::String { .. }, Tok::String { .. }) => (*a_range, *b_range), + (Tok::String { .. }, Tok::FStringStart) => { + match indexer.fstring_ranges().innermost(b_range.start()) { + Some(b_range) => (*a_range, b_range), + None => continue, } + } + (Tok::FStringEnd, Tok::String { .. }) => { + match indexer.fstring_ranges().innermost(a_range.start()) { + Some(a_range) => (a_range, *b_range), + None => continue, + } + } + (Tok::FStringEnd, Tok::FStringStart) => { + match ( + indexer.fstring_ranges().innermost(a_range.start()), + indexer.fstring_ranges().innermost(b_range.start()), + ) { + (Some(a_range), Some(b_range)) => (a_range, b_range), + _ => continue, + } + } + _ => continue, + }; - diagnostics.push(diagnostic); - }; + if locator.contains_line_break(TextRange::new(a_range.end(), b_range.start())) { + diagnostics.push(Diagnostic::new( + MultiLineImplicitStringConcatenation, + TextRange::new(a_range.start(), b_range.end()), + )); + } else { + let mut diagnostic = Diagnostic::new( + SingleLineImplicitStringConcatenation, + TextRange::new(a_range.start(), b_range.end()), + ); + + if let Some(fix) = concatenate_strings(a_range, b_range, locator) { + diagnostic.set_fix(fix); + } + + diagnostics.push(diagnostic); }; } } @@ -151,7 +180,7 @@ fn concatenate_strings(a_range: TextRange, b_range: TextRange, locator: &Locator let concatenation = format!("{a_leading_quote}{a_body}{b_body}{a_trailing_quote}"); let range = TextRange::new(a_range.start(), b_range.end()); - Some(Fix::automatic(Edit::range_replacement( + Some(Fix::safe_edit(Edit::range_replacement( concatenation, range, ))) diff --git a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC001_ISC.py.snap b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC001_ISC.py.snap index f939661b4ae93..9e7a0638e2a49 100644 --- a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC001_ISC.py.snap +++ b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC001_ISC.py.snap @@ -153,4 +153,147 @@ ISC.py:52:5: ISC001 [*] Implicitly concatenated string literals on one line 54 54 | # Single-line explicit concatenation should be ignored. 55 55 | _ = "abc" + "def" + "ghi" +ISC.py:64:10: ISC001 [*] Implicitly concatenated string literals on one line + | +63 | # Multiple strings nested inside a f-string +64 | _ = f"a {'b' 'c' 'd'} e" + | ^^^^^^^ ISC001 +65 | _ = f"""abc {"def" "ghi"} jkl""" +66 | _ = f"""abc { + | + = help: Combine string literals + +ℹ Fix +61 61 | _ = foo + "abc" + bar +62 62 | +63 63 | # Multiple strings nested inside a f-string +64 |-_ = f"a {'b' 'c' 'd'} e" + 64 |+_ = f"a {'bc' 'd'} e" +65 65 | _ = f"""abc {"def" "ghi"} jkl""" +66 66 | _ = f"""abc { +67 67 | "def" + +ISC.py:64:14: ISC001 [*] Implicitly concatenated string literals on one line + | +63 | # Multiple strings nested inside a f-string +64 | _ = f"a {'b' 'c' 'd'} e" + | ^^^^^^^ ISC001 +65 | _ = f"""abc {"def" "ghi"} jkl""" +66 | _ = f"""abc { + | + = help: Combine string literals + +ℹ Fix +61 61 | _ = foo + "abc" + bar +62 62 | +63 63 | # Multiple strings nested inside a f-string +64 |-_ = f"a {'b' 'c' 'd'} e" + 64 |+_ = f"a {'b' 'cd'} e" +65 65 | _ = f"""abc {"def" "ghi"} jkl""" +66 66 | _ = f"""abc { +67 67 | "def" + +ISC.py:65:14: ISC001 [*] Implicitly concatenated string literals on one line + | +63 | # Multiple strings nested inside a f-string +64 | _ = f"a {'b' 'c' 'd'} e" +65 | _ = f"""abc {"def" "ghi"} jkl""" + | ^^^^^^^^^^^ ISC001 +66 | _ = f"""abc { +67 | "def" + | + = help: Combine string literals + +ℹ Fix +62 62 | +63 63 | # Multiple strings nested inside a f-string +64 64 | _ = f"a {'b' 'c' 'd'} e" +65 |-_ = f"""abc {"def" "ghi"} jkl""" + 65 |+_ = f"""abc {"defghi"} jkl""" +66 66 | _ = f"""abc { +67 67 | "def" +68 68 | "ghi" + +ISC.py:72:5: ISC001 Implicitly concatenated string literals on one line + | +71 | # Nested f-strings +72 | _ = "a" f"b {f"c" f"d"} e" "f" + | ^^^^^^^^^^^^^^^^^^^^^^ ISC001 +73 | _ = f"b {f"c" f"d {f"e" f"f"} g"} h" +74 | _ = f"b {f"abc" \ + | + = help: Combine string literals + +ISC.py:72:9: ISC001 Implicitly concatenated string literals on one line + | +71 | # Nested f-strings +72 | _ = "a" f"b {f"c" f"d"} e" "f" + | ^^^^^^^^^^^^^^^^^^^^^^ ISC001 +73 | _ = f"b {f"c" f"d {f"e" f"f"} g"} h" +74 | _ = f"b {f"abc" \ + | + = help: Combine string literals + +ISC.py:72:14: ISC001 [*] Implicitly concatenated string literals on one line + | +71 | # Nested f-strings +72 | _ = "a" f"b {f"c" f"d"} e" "f" + | ^^^^^^^^^ ISC001 +73 | _ = f"b {f"c" f"d {f"e" f"f"} g"} h" +74 | _ = f"b {f"abc" \ + | + = help: Combine string literals + +ℹ Fix +69 69 | } jkl""" +70 70 | +71 71 | # Nested f-strings +72 |-_ = "a" f"b {f"c" f"d"} e" "f" + 72 |+_ = "a" f"b {f"cd"} e" "f" +73 73 | _ = f"b {f"c" f"d {f"e" f"f"} g"} h" +74 74 | _ = f"b {f"abc" \ +75 75 | f"def"} g" + +ISC.py:73:10: ISC001 [*] Implicitly concatenated string literals on one line + | +71 | # Nested f-strings +72 | _ = "a" f"b {f"c" f"d"} e" "f" +73 | _ = f"b {f"c" f"d {f"e" f"f"} g"} h" + | ^^^^^^^^^^^^^^^^^^^^^^^ ISC001 +74 | _ = f"b {f"abc" \ +75 | f"def"} g" + | + = help: Combine string literals + +ℹ Fix +70 70 | +71 71 | # Nested f-strings +72 72 | _ = "a" f"b {f"c" f"d"} e" "f" +73 |-_ = f"b {f"c" f"d {f"e" f"f"} g"} h" + 73 |+_ = f"b {f"cd {f"e" f"f"} g"} h" +74 74 | _ = f"b {f"abc" \ +75 75 | f"def"} g" +76 76 | + +ISC.py:73:20: ISC001 [*] Implicitly concatenated string literals on one line + | +71 | # Nested f-strings +72 | _ = "a" f"b {f"c" f"d"} e" "f" +73 | _ = f"b {f"c" f"d {f"e" f"f"} g"} h" + | ^^^^^^^^^ ISC001 +74 | _ = f"b {f"abc" \ +75 | f"def"} g" + | + = help: Combine string literals + +ℹ Fix +70 70 | +71 71 | # Nested f-strings +72 72 | _ = "a" f"b {f"c" f"d"} e" "f" +73 |-_ = f"b {f"c" f"d {f"e" f"f"} g"} h" + 73 |+_ = f"b {f"c" f"d {f"ef"} g"} h" +74 74 | _ = f"b {f"abc" \ +75 75 | f"def"} g" +76 76 | + diff --git a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC002_ISC.py.snap b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC002_ISC.py.snap index 93a64327e2cae..8daa1c7e219de 100644 --- a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC002_ISC.py.snap +++ b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC002_ISC.py.snap @@ -13,4 +13,16 @@ ISC.py:5:5: ISC002 Implicitly concatenated string literals over multiple lines 8 | _ = ( | +ISC.py:74:10: ISC002 Implicitly concatenated string literals over multiple lines + | +72 | _ = "a" f"b {f"c" f"d"} e" "f" +73 | _ = f"b {f"c" f"d {f"e" f"f"} g"} h" +74 | _ = f"b {f"abc" \ + | __________^ +75 | | f"def"} g" + | |__________^ ISC002 +76 | +77 | # Explicitly concatenated nested f-strings + | + diff --git a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC003_ISC.py.snap b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC003_ISC.py.snap index 5c993ef97f167..e168bae22374a 100644 --- a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC003_ISC.py.snap +++ b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__ISC003_ISC.py.snap @@ -31,4 +31,25 @@ ISC.py:19:3: ISC003 Explicitly concatenated string should be implicitly concaten 21 | ) | +ISC.py:78:10: ISC003 Explicitly concatenated string should be implicitly concatenated + | +77 | # Explicitly concatenated nested f-strings +78 | _ = f"a {f"first" + | __________^ +79 | | + f"second"} d" + | |_______________^ ISC003 +80 | _ = f"a {f"first {f"middle"}" +81 | + f"second"} d" + | + +ISC.py:80:10: ISC003 Explicitly concatenated string should be implicitly concatenated + | +78 | _ = f"a {f"first" +79 | + f"second"} d" +80 | _ = f"a {f"first {f"middle"}" + | __________^ +81 | | + f"second"} d" + | |_______________^ ISC003 + | + diff --git a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__multiline_ISC001_ISC.py.snap b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__multiline_ISC001_ISC.py.snap index f939661b4ae93..9e7a0638e2a49 100644 --- a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__multiline_ISC001_ISC.py.snap +++ b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__multiline_ISC001_ISC.py.snap @@ -153,4 +153,147 @@ ISC.py:52:5: ISC001 [*] Implicitly concatenated string literals on one line 54 54 | # Single-line explicit concatenation should be ignored. 55 55 | _ = "abc" + "def" + "ghi" +ISC.py:64:10: ISC001 [*] Implicitly concatenated string literals on one line + | +63 | # Multiple strings nested inside a f-string +64 | _ = f"a {'b' 'c' 'd'} e" + | ^^^^^^^ ISC001 +65 | _ = f"""abc {"def" "ghi"} jkl""" +66 | _ = f"""abc { + | + = help: Combine string literals + +ℹ Fix +61 61 | _ = foo + "abc" + bar +62 62 | +63 63 | # Multiple strings nested inside a f-string +64 |-_ = f"a {'b' 'c' 'd'} e" + 64 |+_ = f"a {'bc' 'd'} e" +65 65 | _ = f"""abc {"def" "ghi"} jkl""" +66 66 | _ = f"""abc { +67 67 | "def" + +ISC.py:64:14: ISC001 [*] Implicitly concatenated string literals on one line + | +63 | # Multiple strings nested inside a f-string +64 | _ = f"a {'b' 'c' 'd'} e" + | ^^^^^^^ ISC001 +65 | _ = f"""abc {"def" "ghi"} jkl""" +66 | _ = f"""abc { + | + = help: Combine string literals + +ℹ Fix +61 61 | _ = foo + "abc" + bar +62 62 | +63 63 | # Multiple strings nested inside a f-string +64 |-_ = f"a {'b' 'c' 'd'} e" + 64 |+_ = f"a {'b' 'cd'} e" +65 65 | _ = f"""abc {"def" "ghi"} jkl""" +66 66 | _ = f"""abc { +67 67 | "def" + +ISC.py:65:14: ISC001 [*] Implicitly concatenated string literals on one line + | +63 | # Multiple strings nested inside a f-string +64 | _ = f"a {'b' 'c' 'd'} e" +65 | _ = f"""abc {"def" "ghi"} jkl""" + | ^^^^^^^^^^^ ISC001 +66 | _ = f"""abc { +67 | "def" + | + = help: Combine string literals + +ℹ Fix +62 62 | +63 63 | # Multiple strings nested inside a f-string +64 64 | _ = f"a {'b' 'c' 'd'} e" +65 |-_ = f"""abc {"def" "ghi"} jkl""" + 65 |+_ = f"""abc {"defghi"} jkl""" +66 66 | _ = f"""abc { +67 67 | "def" +68 68 | "ghi" + +ISC.py:72:5: ISC001 Implicitly concatenated string literals on one line + | +71 | # Nested f-strings +72 | _ = "a" f"b {f"c" f"d"} e" "f" + | ^^^^^^^^^^^^^^^^^^^^^^ ISC001 +73 | _ = f"b {f"c" f"d {f"e" f"f"} g"} h" +74 | _ = f"b {f"abc" \ + | + = help: Combine string literals + +ISC.py:72:9: ISC001 Implicitly concatenated string literals on one line + | +71 | # Nested f-strings +72 | _ = "a" f"b {f"c" f"d"} e" "f" + | ^^^^^^^^^^^^^^^^^^^^^^ ISC001 +73 | _ = f"b {f"c" f"d {f"e" f"f"} g"} h" +74 | _ = f"b {f"abc" \ + | + = help: Combine string literals + +ISC.py:72:14: ISC001 [*] Implicitly concatenated string literals on one line + | +71 | # Nested f-strings +72 | _ = "a" f"b {f"c" f"d"} e" "f" + | ^^^^^^^^^ ISC001 +73 | _ = f"b {f"c" f"d {f"e" f"f"} g"} h" +74 | _ = f"b {f"abc" \ + | + = help: Combine string literals + +ℹ Fix +69 69 | } jkl""" +70 70 | +71 71 | # Nested f-strings +72 |-_ = "a" f"b {f"c" f"d"} e" "f" + 72 |+_ = "a" f"b {f"cd"} e" "f" +73 73 | _ = f"b {f"c" f"d {f"e" f"f"} g"} h" +74 74 | _ = f"b {f"abc" \ +75 75 | f"def"} g" + +ISC.py:73:10: ISC001 [*] Implicitly concatenated string literals on one line + | +71 | # Nested f-strings +72 | _ = "a" f"b {f"c" f"d"} e" "f" +73 | _ = f"b {f"c" f"d {f"e" f"f"} g"} h" + | ^^^^^^^^^^^^^^^^^^^^^^^ ISC001 +74 | _ = f"b {f"abc" \ +75 | f"def"} g" + | + = help: Combine string literals + +ℹ Fix +70 70 | +71 71 | # Nested f-strings +72 72 | _ = "a" f"b {f"c" f"d"} e" "f" +73 |-_ = f"b {f"c" f"d {f"e" f"f"} g"} h" + 73 |+_ = f"b {f"cd {f"e" f"f"} g"} h" +74 74 | _ = f"b {f"abc" \ +75 75 | f"def"} g" +76 76 | + +ISC.py:73:20: ISC001 [*] Implicitly concatenated string literals on one line + | +71 | # Nested f-strings +72 | _ = "a" f"b {f"c" f"d"} e" "f" +73 | _ = f"b {f"c" f"d {f"e" f"f"} g"} h" + | ^^^^^^^^^ ISC001 +74 | _ = f"b {f"abc" \ +75 | f"def"} g" + | + = help: Combine string literals + +ℹ Fix +70 70 | +71 71 | # Nested f-strings +72 72 | _ = "a" f"b {f"c" f"d"} e" "f" +73 |-_ = f"b {f"c" f"d {f"e" f"f"} g"} h" + 73 |+_ = f"b {f"c" f"d {f"ef"} g"} h" +74 74 | _ = f"b {f"abc" \ +75 75 | f"def"} g" +76 76 | + diff --git a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__multiline_ISC002_ISC.py.snap b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__multiline_ISC002_ISC.py.snap index 64cb7e8acbc70..54dfbdc2e33dc 100644 --- a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__multiline_ISC002_ISC.py.snap +++ b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__multiline_ISC002_ISC.py.snap @@ -43,4 +43,27 @@ ISC.py:34:3: ISC002 Implicitly concatenated string literals over multiple lines 36 | ) | +ISC.py:67:5: ISC002 Implicitly concatenated string literals over multiple lines + | +65 | _ = f"""abc {"def" "ghi"} jkl""" +66 | _ = f"""abc { +67 | "def" + | _____^ +68 | | "ghi" + | |_________^ ISC002 +69 | } jkl""" + | + +ISC.py:74:10: ISC002 Implicitly concatenated string literals over multiple lines + | +72 | _ = "a" f"b {f"c" f"d"} e" "f" +73 | _ = f"b {f"c" f"d {f"e" f"f"} g"} h" +74 | _ = f"b {f"abc" \ + | __________^ +75 | | f"def"} g" + | |__________^ ISC002 +76 | +77 | # Explicitly concatenated nested f-strings + | + diff --git a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__multiline_ISC003_ISC.py.snap b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__multiline_ISC003_ISC.py.snap index 5c993ef97f167..e168bae22374a 100644 --- a/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__multiline_ISC003_ISC.py.snap +++ b/crates/ruff_linter/src/rules/flake8_implicit_str_concat/snapshots/ruff_linter__rules__flake8_implicit_str_concat__tests__multiline_ISC003_ISC.py.snap @@ -31,4 +31,25 @@ ISC.py:19:3: ISC003 Explicitly concatenated string should be implicitly concaten 21 | ) | +ISC.py:78:10: ISC003 Explicitly concatenated string should be implicitly concatenated + | +77 | # Explicitly concatenated nested f-strings +78 | _ = f"a {f"first" + | __________^ +79 | | + f"second"} d" + | |_______________^ ISC003 +80 | _ = f"a {f"first {f"middle"}" +81 | + f"second"} d" + | + +ISC.py:80:10: ISC003 Explicitly concatenated string should be implicitly concatenated + | +78 | _ = f"a {f"first" +79 | + f"second"} d" +80 | _ = f"a {f"first {f"middle"}" + | __________^ +81 | | + f"second"} d" + | |_______________^ ISC003 + | + diff --git a/crates/ruff_linter/src/rules/flake8_import_conventions/rules/banned_import_alias.rs b/crates/ruff_linter/src/rules/flake8_import_conventions/rules/banned_import_alias.rs index dec35f17cba54..955967020847f 100644 --- a/crates/ruff_linter/src/rules/flake8_import_conventions/rules/banned_import_alias.rs +++ b/crates/ruff_linter/src/rules/flake8_import_conventions/rules/banned_import_alias.rs @@ -27,6 +27,9 @@ use ruff_text_size::Ranged; /// /// tf.keras.backend /// ``` +/// +/// ## Options +/// - `flake8-import-conventions.banned-aliases` #[violation] pub struct BannedImportAlias { name: String, diff --git a/crates/ruff_linter/src/rules/flake8_import_conventions/rules/banned_import_from.rs b/crates/ruff_linter/src/rules/flake8_import_conventions/rules/banned_import_from.rs index 23566137318fa..6cd5eccd2c337 100644 --- a/crates/ruff_linter/src/rules/flake8_import_conventions/rules/banned_import_from.rs +++ b/crates/ruff_linter/src/rules/flake8_import_conventions/rules/banned_import_from.rs @@ -28,6 +28,9 @@ use ruff_text_size::Ranged; /// /// pd.Series /// ``` +/// +/// ## Options +/// - `flake8-import-conventions.banned-from` #[violation] pub struct BannedImportFrom { name: String, diff --git a/crates/ruff_linter/src/rules/flake8_import_conventions/rules/unconventional_import_alias.rs b/crates/ruff_linter/src/rules/flake8_import_conventions/rules/unconventional_import_alias.rs index 4fb54aa1c531a..403bdcda9f023 100644 --- a/crates/ruff_linter/src/rules/flake8_import_conventions/rules/unconventional_import_alias.rs +++ b/crates/ruff_linter/src/rules/flake8_import_conventions/rules/unconventional_import_alias.rs @@ -1,12 +1,12 @@ use rustc_hash::FxHashMap; -use ruff_diagnostics::{AutofixKind, Diagnostic, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_semantic::{Binding, Imported}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::renamer::Renamer; /// ## What it does @@ -30,6 +30,10 @@ use crate::renamer::Renamer; /// ```python /// import pandas as pd /// ``` +/// +/// ## Options +/// - `flake8-import-conventions.aliases` +/// - `flake8-import-conventions.extend-aliases` #[violation] pub struct UnconventionalImportAlias { name: String, @@ -37,7 +41,7 @@ pub struct UnconventionalImportAlias { } impl Violation for UnconventionalImportAlias { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -45,7 +49,7 @@ impl Violation for UnconventionalImportAlias { format!("`{name}` should be imported as `{asname}`") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let UnconventionalImportAlias { name, asname } = self; Some(format!("Alias `{name}` to `{asname}`")) } @@ -79,16 +83,14 @@ pub(crate) fn unconventional_import_alias( }, binding.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if !import.is_submodule_import() { - if checker.semantic().is_available(expected_alias) { - diagnostic.try_set_fix(|| { - let scope = &checker.semantic().scopes[binding.scope]; - let (edit, rest) = - Renamer::rename(name, expected_alias, scope, checker.semantic())?; - Ok(Fix::suggested_edits(edit, rest)) - }); - } + if !import.is_submodule_import() { + if checker.semantic().is_available(expected_alias) { + diagnostic.try_set_fix(|| { + let scope = &checker.semantic().scopes[binding.scope]; + let (edit, rest) = + Renamer::rename(name, expected_alias, scope, checker.semantic())?; + Ok(Fix::unsafe_edits(edit, rest)) + }); } } Some(diagnostic) diff --git a/crates/ruff_linter/src/rules/flake8_logging/rules/direct_logger_instantiation.rs b/crates/ruff_linter/src/rules/flake8_logging/rules/direct_logger_instantiation.rs index c0c2893e736da..552bee9c4fa5a 100644 --- a/crates/ruff_linter/src/rules/flake8_logging/rules/direct_logger_instantiation.rs +++ b/crates/ruff_linter/src/rules/flake8_logging/rules/direct_logger_instantiation.rs @@ -1,11 +1,10 @@ -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast as ast; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::importer::ImportRequest; -use crate::registry::AsRule; /// ## What it does /// Checks for direct instantiation of `logging.Logger`, as opposed to using @@ -41,14 +40,14 @@ use crate::registry::AsRule; pub struct DirectLoggerInstantiation; impl Violation for DirectLoggerInstantiation { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Use `logging.getLogger()` to instantiate loggers") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some(format!("Replace with `logging.getLogger()`")) } } @@ -61,17 +60,15 @@ pub(crate) fn direct_logger_instantiation(checker: &mut Checker, call: &ast::Exp .is_some_and(|call_path| matches!(call_path.as_slice(), ["logging", "Logger"])) { let mut diagnostic = Diagnostic::new(DirectLoggerInstantiation, call.func.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - let (import_edit, binding) = checker.importer().get_or_import_symbol( - &ImportRequest::import("logging", "getLogger"), - call.func.start(), - checker.semantic(), - )?; - let reference_edit = Edit::range_replacement(binding, call.func.range()); - Ok(Fix::suggested_edits(import_edit, [reference_edit])) - }); - } + diagnostic.try_set_fix(|| { + let (import_edit, binding) = checker.importer().get_or_import_symbol( + &ImportRequest::import("logging", "getLogger"), + call.func.start(), + checker.semantic(), + )?; + let reference_edit = Edit::range_replacement(binding, call.func.range()); + Ok(Fix::unsafe_edits(import_edit, [reference_edit])) + }); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_logging/rules/exception_without_exc_info.rs b/crates/ruff_linter/src/rules/flake8_logging/rules/exception_without_exc_info.rs index 49eb539b31595..d3eac436387f5 100644 --- a/crates/ruff_linter/src/rules/flake8_logging/rules/exception_without_exc_info.rs +++ b/crates/ruff_linter/src/rules/flake8_logging/rules/exception_without_exc_info.rs @@ -1,8 +1,7 @@ -use ruff_python_ast::{self as ast, Expr, ExprCall}; - use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::Truthiness; +use ruff_python_ast::{self as ast, Expr, ExprCall}; use ruff_python_semantic::analyze::logging; use ruff_python_stdlib::logging::LoggingLevel; use ruff_text_size::Ranged; @@ -43,35 +42,47 @@ impl Violation for ExceptionWithoutExcInfo { /// LOG007 pub(crate) fn exception_without_exc_info(checker: &mut Checker, call: &ExprCall) { - let Expr::Attribute(ast::ExprAttribute { value: _, attr, .. }) = call.func.as_ref() else { - return; - }; + match call.func.as_ref() { + Expr::Attribute(ast::ExprAttribute { attr, .. }) => { + if !matches!( + LoggingLevel::from_attribute(attr.as_str()), + Some(LoggingLevel::Exception) + ) { + return; + } - if !matches!( - LoggingLevel::from_attribute(attr.as_str()), - Some(LoggingLevel::Exception) - ) { - return; + if !logging::is_logger_candidate( + &call.func, + checker.semantic(), + &checker.settings.logger_objects, + ) { + return; + } + } + Expr::Name(_) => { + if !checker + .semantic() + .resolve_call_path(call.func.as_ref()) + .is_some_and(|call_path| matches!(call_path.as_slice(), ["logging", "exception"])) + { + return; + } + } + _ => return, } - if !logging::is_logger_candidate( - &call.func, - checker.semantic(), - &checker.settings.logger_objects, - ) { - return; + if exc_info_arg_is_falsey(call, checker) { + checker + .diagnostics + .push(Diagnostic::new(ExceptionWithoutExcInfo, call.range())); } +} - if call - .arguments +fn exc_info_arg_is_falsey(call: &ExprCall, checker: &mut Checker) -> bool { + call.arguments .find_keyword("exc_info") .map(|keyword| &keyword.value) .is_some_and(|value| { Truthiness::from_expr(value, |id| checker.semantic().is_builtin(id)).is_falsey() }) - { - checker - .diagnostics - .push(Diagnostic::new(ExceptionWithoutExcInfo, call.range())); - } } diff --git a/crates/ruff_linter/src/rules/flake8_logging/rules/invalid_get_logger_argument.rs b/crates/ruff_linter/src/rules/flake8_logging/rules/invalid_get_logger_argument.rs index 80f3b2bc62833..e7d4c8fd2ad5b 100644 --- a/crates/ruff_linter/src/rules/flake8_logging/rules/invalid_get_logger_argument.rs +++ b/crates/ruff_linter/src/rules/flake8_logging/rules/invalid_get_logger_argument.rs @@ -1,10 +1,9 @@ -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Expr}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for any usage of `__cached__` and `__file__` as an argument to @@ -44,14 +43,14 @@ use crate::registry::AsRule; pub struct InvalidGetLoggerArgument; impl Violation for InvalidGetLoggerArgument { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Use `__name__` with `logging.getLogger()`") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some(format!("Replace with `__name__`")) } } @@ -80,13 +79,11 @@ pub(crate) fn invalid_get_logger_argument(checker: &mut Checker, call: &ast::Exp } let mut diagnostic = Diagnostic::new(InvalidGetLoggerArgument, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - if checker.semantic().is_builtin("__name__") { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - "__name__".to_string(), - expr.range(), - ))); - } + if checker.semantic().is_builtin("__name__") { + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + "__name__".to_string(), + expr.range(), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_logging/rules/undocumented_warn.rs b/crates/ruff_linter/src/rules/flake8_logging/rules/undocumented_warn.rs index d09b32da891d9..134c4feef7d31 100644 --- a/crates/ruff_linter/src/rules/flake8_logging/rules/undocumented_warn.rs +++ b/crates/ruff_linter/src/rules/flake8_logging/rules/undocumented_warn.rs @@ -1,12 +1,11 @@ use ruff_python_ast::Expr; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::importer::ImportRequest; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of `logging.WARN`. @@ -36,13 +35,13 @@ use crate::registry::AsRule; pub struct UndocumentedWarn; impl Violation for UndocumentedWarn { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Use of undocumented `logging.WARN` constant") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some(format!("Replace `logging.WARN` with `logging.WARNING`")) } } @@ -55,17 +54,15 @@ pub(crate) fn undocumented_warn(checker: &mut Checker, expr: &Expr) { .is_some_and(|call_path| matches!(call_path.as_slice(), ["logging", "WARN"])) { let mut diagnostic = Diagnostic::new(UndocumentedWarn, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - let (import_edit, binding) = checker.importer().get_or_import_symbol( - &ImportRequest::import("logging", "WARNING"), - expr.start(), - checker.semantic(), - )?; - let reference_edit = Edit::range_replacement(binding, expr.range()); - Ok(Fix::suggested_edits(import_edit, [reference_edit])) - }); - } + diagnostic.try_set_fix(|| { + let (import_edit, binding) = checker.importer().get_or_import_symbol( + &ImportRequest::import("logging", "WARNING"), + expr.start(), + checker.semantic(), + )?; + let reference_edit = Edit::range_replacement(binding, expr.range()); + Ok(Fix::safe_edits(import_edit, [reference_edit])) + }); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_logging/snapshots/ruff_linter__rules__flake8_logging__tests__LOG007_LOG007.py.snap b/crates/ruff_linter/src/rules/flake8_logging/snapshots/ruff_linter__rules__flake8_logging__tests__LOG007_LOG007.py.snap index df6cb6a004be0..a8df5679127e4 100644 --- a/crates/ruff_linter/src/rules/flake8_logging/snapshots/ruff_linter__rules__flake8_logging__tests__LOG007_LOG007.py.snap +++ b/crates/ruff_linter/src/rules/flake8_logging/snapshots/ruff_linter__rules__flake8_logging__tests__LOG007_LOG007.py.snap @@ -40,4 +40,13 @@ LOG007.py:10:1: LOG007 Use of `logging.exception` with falsy `exc_info` 12 | logger.info("foo", exc_info=False) # OK | +LOG007.py:17:1: LOG007 Use of `logging.exception` with falsy `exc_info` + | +15 | from logging import exception +16 | +17 | exception("foo", exc_info=False) # LOG007 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LOG007 +18 | exception("foo", exc_info=True) # OK + | + diff --git a/crates/ruff_linter/src/rules/flake8_logging/snapshots/ruff_linter__rules__flake8_logging__tests__LOG009_LOG009.py.snap b/crates/ruff_linter/src/rules/flake8_logging/snapshots/ruff_linter__rules__flake8_logging__tests__LOG009_LOG009.py.snap index a31c6a2b1c302..7624d57af44a8 100644 --- a/crates/ruff_linter/src/rules/flake8_logging/snapshots/ruff_linter__rules__flake8_logging__tests__LOG009_LOG009.py.snap +++ b/crates/ruff_linter/src/rules/flake8_logging/snapshots/ruff_linter__rules__flake8_logging__tests__LOG009_LOG009.py.snap @@ -11,7 +11,7 @@ LOG009.py:3:1: LOG009 [*] Use of undocumented `logging.WARN` constant | = help: Replace `logging.WARN` with `logging.WARNING` -ℹ Suggested fix +ℹ Fix 1 1 | import logging 2 2 | 3 |-logging.WARN # LOG009 @@ -30,7 +30,7 @@ LOG009.py:8:1: LOG009 [*] Use of undocumented `logging.WARN` constant | = help: Replace `logging.WARN` with `logging.WARNING` -ℹ Suggested fix +ℹ Fix 5 5 | 6 6 | from logging import WARN, WARNING 7 7 | diff --git a/crates/ruff_linter/src/rules/flake8_logging_format/rules/logging_call.rs b/crates/ruff_linter/src/rules/flake8_logging_format/rules/logging_call.rs index 29b2b9711b602..2074f5cc8588b 100644 --- a/crates/ruff_linter/src/rules/flake8_logging_format/rules/logging_call.rs +++ b/crates/ruff_linter/src/rules/flake8_logging_format/rules/logging_call.rs @@ -5,7 +5,7 @@ use ruff_python_stdlib::logging::LoggingLevel; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::{AsRule, Rule}; +use crate::registry::Rule; use crate::rules::flake8_logging_format::violations::{ LoggingExcInfo, LoggingExtraAttrClash, LoggingFString, LoggingPercentFormat, LoggingRedundantExcInfo, LoggingStringConcat, LoggingStringFormat, LoggingWarn, @@ -153,22 +153,36 @@ impl LoggingCallType { /// Check logging calls for violations. pub(crate) fn logging_call(checker: &mut Checker, call: &ast::ExprCall) { - let Expr::Attribute(ast::ExprAttribute { value: _, attr, .. }) = call.func.as_ref() else { - return; - }; - - let Some(logging_call_type) = LoggingCallType::from_attribute(attr.as_str()) else { - return; + // Determine the call type (e.g., `info` vs. `exception`) and the range of the attribute. + let (logging_call_type, range) = match call.func.as_ref() { + Expr::Attribute(ast::ExprAttribute { value: _, attr, .. }) => { + let Some(call_type) = LoggingCallType::from_attribute(attr.as_str()) else { + return; + }; + if !logging::is_logger_candidate( + &call.func, + checker.semantic(), + &checker.settings.logger_objects, + ) { + return; + } + (call_type, attr.range()) + } + Expr::Name(_) => { + let Some(call_path) = checker.semantic().resolve_call_path(call.func.as_ref()) else { + return; + }; + let ["logging", attribute] = call_path.as_slice() else { + return; + }; + let Some(call_type) = LoggingCallType::from_attribute(attribute) else { + return; + }; + (call_type, call.func.range()) + } + _ => return, }; - if !logging::is_logger_candidate( - &call.func, - checker.semantic(), - &checker.settings.logger_objects, - ) { - return; - } - // G001 - G004 let msg_pos = usize::from(matches!(logging_call_type, LoggingCallType::LogCall)); if let Some(format_arg) = call.arguments.find_argument("msg", msg_pos) { @@ -181,13 +195,11 @@ pub(crate) fn logging_call(checker: &mut Checker, call: &ast::ExprCall) { logging_call_type, LoggingCallType::LevelCall(LoggingLevel::Warn) ) { - let mut diagnostic = Diagnostic::new(LoggingWarn, attr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - "warning".to_string(), - attr.range(), - ))); - } + let mut diagnostic = Diagnostic::new(LoggingWarn, range); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "warning".to_string(), + range, + ))); checker.diagnostics.push(diagnostic); } } @@ -213,7 +225,7 @@ pub(crate) fn logging_call(checker: &mut Checker, call: &ast::ExprCall) { if checker.enabled(Rule::LoggingExcInfo) { checker .diagnostics - .push(Diagnostic::new(LoggingExcInfo, attr.range())); + .push(Diagnostic::new(LoggingExcInfo, range)); } } LoggingLevel::Exception => { diff --git a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G001.py.snap b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G001.py.snap index 7e2391e7b35b5..f6e052cf559f7 100644 --- a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G001.py.snap +++ b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G001.py.snap @@ -83,6 +83,64 @@ G001.py:18:30: G001 Logging statement uses `str.format` 17 | current_app.logger.info("Hello {}".format("World!")) 18 | app.logger.log(logging.INFO, "Hello {}".format("World!")) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ G001 +19 | +20 | from logging import info, log + | + +G001.py:22:6: G001 Logging statement uses `str.format` + | +20 | from logging import info, log +21 | +22 | info("Hello {}".format("World!")) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ G001 +23 | log(logging.INFO, "Hello {}".format("World!")) +24 | info("Hello {}".format("World!")) + | + +G001.py:23:19: G001 Logging statement uses `str.format` + | +22 | info("Hello {}".format("World!")) +23 | log(logging.INFO, "Hello {}".format("World!")) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ G001 +24 | info("Hello {}".format("World!")) +25 | log(logging.INFO, msg="Hello {}".format("World!")) + | + +G001.py:24:6: G001 Logging statement uses `str.format` + | +22 | info("Hello {}".format("World!")) +23 | log(logging.INFO, "Hello {}".format("World!")) +24 | info("Hello {}".format("World!")) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ G001 +25 | log(logging.INFO, msg="Hello {}".format("World!")) +26 | log(level=logging.INFO, msg="Hello {}".format("World!")) + | + +G001.py:25:23: G001 Logging statement uses `str.format` + | +23 | log(logging.INFO, "Hello {}".format("World!")) +24 | info("Hello {}".format("World!")) +25 | log(logging.INFO, msg="Hello {}".format("World!")) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ G001 +26 | log(level=logging.INFO, msg="Hello {}".format("World!")) +27 | log(msg="Hello {}".format("World!"), level=logging.INFO) + | + +G001.py:26:29: G001 Logging statement uses `str.format` + | +24 | info("Hello {}".format("World!")) +25 | log(logging.INFO, msg="Hello {}".format("World!")) +26 | log(level=logging.INFO, msg="Hello {}".format("World!")) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ G001 +27 | log(msg="Hello {}".format("World!"), level=logging.INFO) + | + +G001.py:27:9: G001 Logging statement uses `str.format` + | +25 | log(logging.INFO, msg="Hello {}".format("World!")) +26 | log(level=logging.INFO, msg="Hello {}".format("World!")) +27 | log(msg="Hello {}".format("World!"), level=logging.INFO) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ G001 | diff --git a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G002.py.snap b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G002.py.snap index ebe2ad34825a0..6ba827bafa5e2 100644 --- a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G002.py.snap +++ b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G002.py.snap @@ -15,6 +15,24 @@ G002.py:4:27: G002 Logging statement uses `%` 3 | logging.info("Hello %s" % "World!") 4 | logging.log(logging.INFO, "Hello %s" % "World!") | ^^^^^^^^^^^^^^^^^^^^^ G002 +5 | +6 | from logging import info, log + | + +G002.py:8:6: G002 Logging statement uses `%` + | +6 | from logging import info, log +7 | +8 | info("Hello %s" % "World!") + | ^^^^^^^^^^^^^^^^^^^^^ G002 +9 | log(logging.INFO, "Hello %s" % "World!") + | + +G002.py:9:19: G002 Logging statement uses `%` + | +8 | info("Hello %s" % "World!") +9 | log(logging.INFO, "Hello %s" % "World!") + | ^^^^^^^^^^^^^^^^^^^^^ G002 | diff --git a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G003.py.snap b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G003.py.snap index 873b9e74f91da..494761d268587 100644 --- a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G003.py.snap +++ b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G003.py.snap @@ -15,6 +15,24 @@ G003.py:4:27: G003 Logging statement uses `+` 3 | logging.info("Hello" + " " + "World!") 4 | logging.log(logging.INFO, "Hello" + " " + "World!") | ^^^^^^^^^^^^^^^^^^^^^^^^ G003 +5 | +6 | from logging import info, log + | + +G003.py:8:6: G003 Logging statement uses `+` + | +6 | from logging import info, log +7 | +8 | info("Hello" + " " + "World!") + | ^^^^^^^^^^^^^^^^^^^^^^^^ G003 +9 | log(logging.INFO, "Hello" + " " + "World!") + | + +G003.py:9:19: G003 Logging statement uses `+` + | +8 | info("Hello" + " " + "World!") +9 | log(logging.INFO, "Hello" + " " + "World!") + | ^^^^^^^^^^^^^^^^^^^^^^^^ G003 | diff --git a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G004.py.snap b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G004.py.snap index a2d3ef00f8417..5594145d4fc34 100644 --- a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G004.py.snap +++ b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G004.py.snap @@ -20,10 +20,28 @@ G004.py:5:27: G004 Logging statement uses f-string | G004.py:8:14: G004 Logging statement uses f-string - | -7 | _LOGGER = logging.getLogger() -8 | _LOGGER.info(f"{__name__}") - | ^^^^^^^^^^^^^ G004 - | + | + 7 | _LOGGER = logging.getLogger() + 8 | _LOGGER.info(f"{__name__}") + | ^^^^^^^^^^^^^ G004 + 9 | +10 | from logging import info + | + +G004.py:11:6: G004 Logging statement uses f-string + | +10 | from logging import info +11 | info(f"{name}") + | ^^^^^^^^^ G004 +12 | info(f"{__name__}") + | + +G004.py:12:6: G004 Logging statement uses f-string + | +10 | from logging import info +11 | info(f"{name}") +12 | info(f"{__name__}") + | ^^^^^^^^^^^^^ G004 + | diff --git a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G010.py.snap b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G010.py.snap index f56206e88c036..df5ab9dfa124f 100644 --- a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G010.py.snap +++ b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G010.py.snap @@ -41,6 +41,7 @@ G010.py:8:8: G010 [*] Logging statement uses `warn` instead of `warning` 8 |+logger.warning("Hello world!") 9 9 | 10 10 | logging . warn("Hello World!") +11 11 | G010.py:10:11: G010 [*] Logging statement uses `warn` instead of `warning` | @@ -48,6 +49,8 @@ G010.py:10:11: G010 [*] Logging statement uses `warn` instead of `warning` 9 | 10 | logging . warn("Hello World!") | ^^^^ G010 +11 | +12 | from logging import warn, warning, exception | = help: Convert to `warn` @@ -57,5 +60,27 @@ G010.py:10:11: G010 [*] Logging statement uses `warn` instead of `warning` 9 9 | 10 |-logging . warn("Hello World!") 10 |+logging . warning("Hello World!") +11 11 | +12 12 | from logging import warn, warning, exception +13 13 | warn("foo") + +G010.py:13:1: G010 [*] Logging statement uses `warn` instead of `warning` + | +12 | from logging import warn, warning, exception +13 | warn("foo") + | ^^^^ G010 +14 | warning("foo") +15 | exception("foo") + | + = help: Convert to `warn` + +ℹ Fix +10 10 | logging . warn("Hello World!") +11 11 | +12 12 | from logging import warn, warning, exception +13 |-warn("foo") +14 13 | warning("foo") + 14 |+warning("foo") +15 15 | exception("foo") diff --git a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G101_1.py.snap b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G101_1.py.snap index d35d9f2bd46ba..e0fff24c03a91 100644 --- a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G101_1.py.snap +++ b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G101_1.py.snap @@ -11,4 +11,14 @@ G101_1.py:6:9: G101 Logging statement uses an `extra` field that clashes with a 8 | ) | +G101_1.py:15:9: G101 Logging statement uses an `extra` field that clashes with a `LogRecord` field: `name` + | +13 | "Hello world!", +14 | extra={ +15 | "name": "foobar", + | ^^^^^^ G101 +16 | }, +17 | ) + | + diff --git a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G101_2.py.snap b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G101_2.py.snap index 2ea3d56ded6ad..7e5e636f87afb 100644 --- a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G101_2.py.snap +++ b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G101_2.py.snap @@ -11,4 +11,14 @@ G101_2.py:6:9: G101 Logging statement uses an `extra` field that clashes with a 8 | ) | +G101_2.py:15:9: G101 Logging statement uses an `extra` field that clashes with a `LogRecord` field: `name` + | +13 | "Hello world!", +14 | extra=dict( +15 | name="foobar", + | ^^^^^^^^^^^^^ G101 +16 | ), +17 | ) + | + diff --git a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G201.py.snap b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G201.py.snap index a4cbafa5d2356..34c469ae68bbd 100644 --- a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G201.py.snap +++ b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G201.py.snap @@ -21,4 +21,24 @@ G201.py:13:13: G201 Logging `.exception(...)` should be used instead of `.error( 15 | # OK | +G201.py:28:5: G201 Logging `.exception(...)` should be used instead of `.error(..., exc_info=True)` + | +26 | pass +27 | except: +28 | error("Hello World", exc_info=True) + | ^^^^^ G201 +29 | +30 | try: + | + +G201.py:33:5: G201 Logging `.exception(...)` should be used instead of `.error(..., exc_info=True)` + | +31 | pass +32 | except: +33 | error("Hello World", exc_info=sys.exc_info()) + | ^^^^^ G201 +34 | +35 | # OK + | + diff --git a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G202.py.snap b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G202.py.snap index 9fc9a87608bec..17daeba81a893 100644 --- a/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G202.py.snap +++ b/crates/ruff_linter/src/rules/flake8_logging_format/snapshots/ruff_linter__rules__flake8_logging_format__tests__G202.py.snap @@ -21,4 +21,24 @@ G202.py:13:38: G202 Logging statement has redundant `exc_info` 15 | # OK | +G202.py:28:30: G202 Logging statement has redundant `exc_info` + | +26 | pass +27 | except: +28 | exception("Hello World", exc_info=True) + | ^^^^^^^^^^^^^ G202 +29 | +30 | try: + | + +G202.py:33:30: G202 Logging statement has redundant `exc_info` + | +31 | pass +32 | except: +33 | exception("Hello World", exc_info=sys.exc_info()) + | ^^^^^^^^^^^^^^^^^^^^^^^ G202 +34 | +35 | # OK + | + diff --git a/crates/ruff_linter/src/rules/flake8_logging_format/violations.rs b/crates/ruff_linter/src/rules/flake8_logging_format/violations.rs index 77a96c7fce53f..114a1fa68a538 100644 --- a/crates/ruff_linter/src/rules/flake8_logging_format/violations.rs +++ b/crates/ruff_linter/src/rules/flake8_logging_format/violations.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Violation}; use ruff_macros::{derive_message_formats, violation}; /// ## What it does @@ -376,13 +376,13 @@ impl Violation for LoggingFString { #[violation] pub struct LoggingWarn; -impl AlwaysAutofixableViolation for LoggingWarn { +impl AlwaysFixableViolation for LoggingWarn { #[derive_message_formats] fn message(&self) -> String { format!("Logging statement uses `warn` instead of `warning`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Convert to `warn`".to_string() } } diff --git a/crates/ruff_linter/src/rules/flake8_pie/rules/duplicate_class_field_definition.rs b/crates/ruff_linter/src/rules/flake8_pie/rules/duplicate_class_field_definition.rs index 07c49fcd41529..4fa34d1450eb3 100644 --- a/crates/ruff_linter/src/rules/flake8_pie/rules/duplicate_class_field_definition.rs +++ b/crates/ruff_linter/src/rules/flake8_pie/rules/duplicate_class_field_definition.rs @@ -1,14 +1,13 @@ use rustc_hash::FxHashSet; use ruff_diagnostics::Diagnostic; -use ruff_diagnostics::{AlwaysAutofixableViolation, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Expr, Stmt}; use ruff_text_size::Ranged; -use crate::autofix; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix; /// ## What it does /// Checks for duplicate field definitions in classes. @@ -36,14 +35,14 @@ pub struct DuplicateClassFieldDefinition { name: String, } -impl AlwaysAutofixableViolation for DuplicateClassFieldDefinition { +impl AlwaysFixableViolation for DuplicateClassFieldDefinition { #[derive_message_formats] fn message(&self) -> String { let DuplicateClassFieldDefinition { name } = self; format!("Class field `{name}` is defined multiple times") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let DuplicateClassFieldDefinition { name } = self; format!("Remove duplicate field definition for `{name}`") } @@ -79,17 +78,11 @@ pub(crate) fn duplicate_class_field_definition(checker: &mut Checker, body: &[St }, stmt.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let edit = autofix::edits::delete_stmt( - stmt, - Some(stmt), - checker.locator(), - checker.indexer(), - ); - diagnostic.set_fix(Fix::suggested(edit).isolate(Checker::isolation(Some( - checker.semantic().current_statement_id(), - )))); - } + let edit = + fix::edits::delete_stmt(stmt, Some(stmt), checker.locator(), checker.indexer()); + diagnostic.set_fix(Fix::unsafe_edit(edit).isolate(Checker::isolation( + checker.semantic().current_statement_id(), + ))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_pie/rules/mod.rs b/crates/ruff_linter/src/rules/flake8_pie/rules/mod.rs index 79012144acf6d..aa030ca27519a 100644 --- a/crates/ruff_linter/src/rules/flake8_pie/rules/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_pie/rules/mod.rs @@ -1,17 +1,17 @@ pub(crate) use duplicate_class_field_definition::*; pub(crate) use multiple_starts_ends_with::*; -pub(crate) use no_unnecessary_pass::*; pub(crate) use non_unique_enums::*; pub(crate) use reimplemented_list_builtin::*; pub(crate) use unnecessary_dict_kwargs::*; +pub(crate) use unnecessary_pass::*; pub(crate) use unnecessary_range_start::*; pub(crate) use unnecessary_spread::*; mod duplicate_class_field_definition; mod multiple_starts_ends_with; -mod no_unnecessary_pass; mod non_unique_enums; mod reimplemented_list_builtin; mod unnecessary_dict_kwargs; +mod unnecessary_pass; mod unnecessary_range_start; mod unnecessary_spread; diff --git a/crates/ruff_linter/src/rules/flake8_pie/rules/multiple_starts_ends_with.rs b/crates/ruff_linter/src/rules/flake8_pie/rules/multiple_starts_ends_with.rs index 9a1f55194d537..ef4a5ad167fd0 100644 --- a/crates/ruff_linter/src/rules/flake8_pie/rules/multiple_starts_ends_with.rs +++ b/crates/ruff_linter/src/rules/flake8_pie/rules/multiple_starts_ends_with.rs @@ -7,12 +7,11 @@ use ruff_text_size::{Ranged, TextRange}; use ruff_python_ast::{self as ast, Arguments, BoolOp, Expr, ExprContext, Identifier}; -use ruff_diagnostics::AlwaysAutofixableViolation; +use ruff_diagnostics::AlwaysFixableViolation; use ruff_diagnostics::{Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for `startswith` or `endswith` calls on the same value with @@ -45,14 +44,14 @@ pub struct MultipleStartsEndsWith { attr: String, } -impl AlwaysAutofixableViolation for MultipleStartsEndsWith { +impl AlwaysFixableViolation for MultipleStartsEndsWith { #[derive_message_formats] fn message(&self) -> String { let MultipleStartsEndsWith { attr } = self; format!("Call `{attr}` once with a `tuple`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let MultipleStartsEndsWith { attr } = self; format!("Merge into a single `{attr}` call") } @@ -115,92 +114,90 @@ pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) { }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let words: Vec<&Expr> = indices + let words: Vec<&Expr> = indices + .iter() + .map(|index| &values[*index]) + .map(|expr| { + let Expr::Call(ast::ExprCall { + func: _, + arguments: + Arguments { + args, + keywords: _, + range: _, + }, + range: _, + }) = expr + else { + unreachable!( + "{}", + format!("Indices should only contain `{attr_name}` calls") + ) + }; + args.get(0) + .unwrap_or_else(|| panic!("`{attr_name}` should have one argument")) + }) + .collect(); + + let node = Expr::Tuple(ast::ExprTuple { + elts: words .iter() - .map(|index| &values[*index]) - .map(|expr| { - let Expr::Call(ast::ExprCall { - func: _, - arguments: - Arguments { - args, - keywords: _, - range: _, - }, - range: _, - }) = expr - else { - unreachable!( - "{}", - format!("Indices should only contain `{attr_name}` calls") - ) - }; - args.get(0) - .unwrap_or_else(|| panic!("`{attr_name}` should have one argument")) + .flat_map(|value| { + if let Expr::Tuple(ast::ExprTuple { elts, .. }) = value { + Left(elts.iter()) + } else { + Right(iter::once(*value)) + } }) - .collect(); - - let node = Expr::Tuple(ast::ExprTuple { - elts: words - .iter() - .flat_map(|value| { - if let Expr::Tuple(ast::ExprTuple { elts, .. }) = value { - Left(elts.iter()) - } else { - Right(iter::once(*value)) - } - }) - .map(Clone::clone) - .collect(), - ctx: ExprContext::Load, + .map(Clone::clone) + .collect(), + ctx: ExprContext::Load, + range: TextRange::default(), + }); + let node1 = Expr::Name(ast::ExprName { + id: arg_name.into(), + ctx: ExprContext::Load, + range: TextRange::default(), + }); + let node2 = Expr::Attribute(ast::ExprAttribute { + value: Box::new(node1), + attr: Identifier::new(attr_name.to_string(), TextRange::default()), + ctx: ExprContext::Load, + range: TextRange::default(), + }); + let node3 = Expr::Call(ast::ExprCall { + func: Box::new(node2), + arguments: Arguments { + args: vec![node], + keywords: vec![], range: TextRange::default(), - }); - let node1 = Expr::Name(ast::ExprName { - id: arg_name.into(), - ctx: ExprContext::Load, - range: TextRange::default(), - }); - let node2 = Expr::Attribute(ast::ExprAttribute { - value: Box::new(node1), - attr: Identifier::new(attr_name.to_string(), TextRange::default()), - ctx: ExprContext::Load, - range: TextRange::default(), - }); - let node3 = Expr::Call(ast::ExprCall { - func: Box::new(node2), - arguments: Arguments { - args: vec![node], - keywords: vec![], - range: TextRange::default(), - }, - range: TextRange::default(), - }); - let call = node3; - - // Generate the combined `BoolOp`. - let mut call = Some(call); - let node = Expr::BoolOp(ast::ExprBoolOp { - op: BoolOp::Or, - values: values - .iter() - .enumerate() - .filter_map(|(index, elt)| { - if indices.contains(&index) { - std::mem::take(&mut call) - } else { - Some(elt.clone()) - } - }) - .collect(), - range: TextRange::default(), - }); - let bool_op = node; - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.generator().expr(&bool_op), - expr.range(), - ))); - } + }, + range: TextRange::default(), + }); + let call = node3; + + // Generate the combined `BoolOp`. + let mut call = Some(call); + let node = Expr::BoolOp(ast::ExprBoolOp { + op: BoolOp::Or, + values: values + .iter() + .enumerate() + .filter_map(|(index, elt)| { + if indices.contains(&index) { + std::mem::take(&mut call) + } else { + Some(elt.clone()) + } + }) + .collect(), + range: TextRange::default(), + }); + let bool_op = node; + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + checker.generator().expr(&bool_op), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_pie/rules/no_unnecessary_pass.rs b/crates/ruff_linter/src/rules/flake8_pie/rules/no_unnecessary_pass.rs deleted file mode 100644 index 569c8a66d87a4..0000000000000 --- a/crates/ruff_linter/src/rules/flake8_pie/rules/no_unnecessary_pass.rs +++ /dev/null @@ -1,78 +0,0 @@ -use ruff_python_ast::Stmt; - -use ruff_diagnostics::AlwaysAutofixableViolation; -use ruff_diagnostics::{Diagnostic, Edit, Fix}; -use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::helpers::is_docstring_stmt; -use ruff_python_ast::whitespace::trailing_comment_start_offset; -use ruff_text_size::Ranged; - -use crate::autofix; -use crate::checkers::ast::Checker; -use crate::registry::AsRule; - -/// ## What it does -/// Checks for unnecessary `pass` statements in class and function bodies. -/// where it is not needed syntactically (e.g., when an indented docstring is -/// present). -/// -/// ## Why is this bad? -/// When a function or class definition contains a docstring, an additional -/// `pass` statement is redundant. -/// -/// ## Example -/// ```python -/// def foo(): -/// """Placeholder docstring.""" -/// pass -/// ``` -/// -/// Use instead: -/// ```python -/// def foo(): -/// """Placeholder docstring.""" -/// ``` -/// -/// ## References -/// - [Python documentation: The `pass` statement](https://docs.python.org/3/reference/simple_stmts.html#the-pass-statement) -#[violation] -pub struct UnnecessaryPass; - -impl AlwaysAutofixableViolation for UnnecessaryPass { - #[derive_message_formats] - fn message(&self) -> String { - format!("Unnecessary `pass` statement") - } - - fn autofix_title(&self) -> String { - "Remove unnecessary `pass`".to_string() - } -} - -/// PIE790 -pub(crate) fn no_unnecessary_pass(checker: &mut Checker, body: &[Stmt]) { - let [first, second, ..] = body else { - return; - }; - // This only catches the case in which a docstring makes a `pass` statement - // redundant. Consider removing all `pass` statements instead. - if !is_docstring_stmt(first) { - return; - } - - // The second statement must be a `pass` statement. - if !second.is_pass_stmt() { - return; - } - - let mut diagnostic = Diagnostic::new(UnnecessaryPass, second.range()); - if checker.patch(diagnostic.kind.rule()) { - let edit = if let Some(index) = trailing_comment_start_offset(second, checker.locator()) { - Edit::range_deletion(second.range().add_end(index)) - } else { - autofix::edits::delete_stmt(second, None, checker.locator(), checker.indexer()) - }; - diagnostic.set_fix(Fix::automatic(edit)); - } - checker.diagnostics.push(diagnostic); -} diff --git a/crates/ruff_linter/src/rules/flake8_pie/rules/reimplemented_list_builtin.rs b/crates/ruff_linter/src/rules/flake8_pie/rules/reimplemented_list_builtin.rs index 3903b7cfe6027..6195d09357533 100644 --- a/crates/ruff_linter/src/rules/flake8_pie/rules/reimplemented_list_builtin.rs +++ b/crates/ruff_linter/src/rules/flake8_pie/rules/reimplemented_list_builtin.rs @@ -1,12 +1,11 @@ use ruff_python_ast::{self as ast, Expr, ExprLambda}; -use ruff_diagnostics::{AutofixKind, Violation}; use ruff_diagnostics::{Diagnostic, Edit, Fix}; +use ruff_diagnostics::{FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for lambdas that can be replaced with the `list` builtin. @@ -40,14 +39,14 @@ use crate::registry::AsRule; pub struct ReimplementedListBuiltin; impl Violation for ReimplementedListBuiltin { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Prefer `list` over useless lambda") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Replace with `list`".to_string()) } } @@ -64,13 +63,11 @@ pub(crate) fn reimplemented_list_builtin(checker: &mut Checker, expr: &ExprLambd if let Expr::List(ast::ExprList { elts, .. }) = body.as_ref() { if elts.is_empty() { let mut diagnostic = Diagnostic::new(ReimplementedListBuiltin, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - if checker.semantic().is_builtin("list") { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - "list".to_string(), - expr.range(), - ))); - } + if checker.semantic().is_builtin("list") { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "list".to_string(), + expr.range(), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_dict_kwargs.rs b/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_dict_kwargs.rs index 550892b3f379a..b28000c41b0c9 100644 --- a/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_dict_kwargs.rs +++ b/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_dict_kwargs.rs @@ -1,7 +1,7 @@ +use itertools::Itertools; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_python_ast::{self as ast, Constant, Expr, Keyword}; -use ruff_diagnostics::Diagnostic; -use ruff_diagnostics::Violation; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; @@ -40,41 +40,83 @@ use crate::checkers::ast::Checker; #[violation] pub struct UnnecessaryDictKwargs; -impl Violation for UnnecessaryDictKwargs { +impl AlwaysFixableViolation for UnnecessaryDictKwargs { #[derive_message_formats] fn message(&self) -> String { format!("Unnecessary `dict` kwargs") } + + fn fix_title(&self) -> String { + format!("Remove unnecessary kwargs") + } } /// PIE804 pub(crate) fn unnecessary_dict_kwargs(checker: &mut Checker, expr: &Expr, kwargs: &[Keyword]) { for kw in kwargs { // keyword is a spread operator (indicated by None) - if kw.arg.is_none() { - if let Expr::Dict(ast::ExprDict { keys, .. }) = &kw.value { - // ensure foo(**{"bar-bar": 1}) doesn't error - if keys.iter().all(|expr| expr.as_ref().is_some_and( is_valid_kwarg_name)) || - // handle case of foo(**{**bar}) - (keys.len() == 1 && keys[0].is_none()) - { - let diagnostic = Diagnostic::new(UnnecessaryDictKwargs, expr.range()); - checker.diagnostics.push(diagnostic); - } - } + if kw.arg.is_some() { + continue; + } + + let Expr::Dict(ast::ExprDict { keys, values, .. }) = &kw.value else { + continue; + }; + + // Ex) `foo(**{**bar})` + if matches!(keys.as_slice(), [None]) { + let mut diagnostic = Diagnostic::new(UnnecessaryDictKwargs, expr.range()); + + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + format!("**{}", checker.locator().slice(values[0].range())), + kw.range(), + ))); + + checker.diagnostics.push(diagnostic); + continue; } + + // Ensure that every keyword is a valid keyword argument (e.g., avoid errors for cases like + // `foo(**{"bar-bar": 1})`). + let kwargs = keys + .iter() + .filter_map(|key| key.as_ref().and_then(as_kwarg)) + .collect::>(); + if kwargs.len() != keys.len() { + continue; + } + + let mut diagnostic = Diagnostic::new(UnnecessaryDictKwargs, expr.range()); + + if values.is_empty() { + diagnostic.set_fix(Fix::safe_edit(Edit::deletion(kw.start(), kw.end()))); + } else { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + kwargs + .iter() + .zip(values.iter()) + .map(|(kwarg, value)| { + format!("{}={}", kwarg.value, checker.locator().slice(value.range())) + }) + .join(", "), + kw.range(), + ))); + } + + checker.diagnostics.push(diagnostic); } } -/// Return `true` if a key is a valid keyword argument name. -fn is_valid_kwarg_name(key: &Expr) -> bool { +/// Return `Some` if a key is a valid keyword argument name, or `None` otherwise. +fn as_kwarg(key: &Expr) -> Option<&ast::StringConstant> { if let Expr::Constant(ast::ExprConstant { value: Constant::Str(value), .. }) = key { - is_identifier(value) - } else { - false + if is_identifier(value) { + return Some(value); + } } + None } diff --git a/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_pass.rs b/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_pass.rs new file mode 100644 index 0000000000000..fe845646a2c35 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_pass.rs @@ -0,0 +1,75 @@ +use ruff_python_ast::Stmt; + +use ruff_diagnostics::AlwaysFixableViolation; +use ruff_diagnostics::{Diagnostic, Edit, Fix}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::whitespace::trailing_comment_start_offset; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; +use crate::fix; + +/// ## What it does +/// Checks for unnecessary `pass` statements in functions, classes, and other +/// blocks. +/// +/// ## Why is this bad? +/// In Python, the `pass` statement serves as a placeholder, allowing for +/// syntactically correct empty code blocks. The primary purpose of the `pass` +/// statement is to avoid syntax errors in situations where a statement is +/// syntactically required, but no code needs to be executed. +/// +/// If a `pass` statement is present in a code block that includes at least +/// one other statement (even, e.g., a docstring), it is unnecessary and should +/// be removed. +/// +/// ## Example +/// ```python +/// def func(): +/// """Placeholder docstring.""" +/// pass +/// ``` +/// +/// Use instead: +/// ```python +/// def func(): +/// """Placeholder docstring.""" +/// ``` +/// +/// ## References +/// - [Python documentation: The `pass` statement](https://docs.python.org/3/reference/simple_stmts.html#the-pass-statement) +#[violation] +pub struct UnnecessaryPass; + +impl AlwaysFixableViolation for UnnecessaryPass { + #[derive_message_formats] + fn message(&self) -> String { + format!("Unnecessary `pass` statement") + } + + fn fix_title(&self) -> String { + "Remove unnecessary `pass`".to_string() + } +} + +/// PIE790 +pub(crate) fn no_unnecessary_pass(checker: &mut Checker, body: &[Stmt]) { + if body.len() < 2 { + return; + } + + body.iter() + .filter(|stmt| stmt.is_pass_stmt()) + .for_each(|stmt| { + let mut diagnostic = Diagnostic::new(UnnecessaryPass, stmt.range()); + let edit = if let Some(index) = trailing_comment_start_offset(stmt, checker.locator()) { + Edit::range_deletion(stmt.range().add_end(index)) + } else { + fix::edits::delete_stmt(stmt, None, checker.locator(), checker.indexer()) + }; + diagnostic.set_fix(Fix::safe_edit(edit).isolate(Checker::isolation( + checker.semantic().current_statement_id(), + ))); + checker.diagnostics.push(diagnostic); + }); +} diff --git a/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_range_start.rs b/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_range_start.rs index a6275ac602644..1bc2bd1cf7923 100644 --- a/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_range_start.rs +++ b/crates/ruff_linter/src/rules/flake8_pie/rules/unnecessary_range_start.rs @@ -1,14 +1,11 @@ -use num_bigint::BigInt; - use ruff_diagnostics::Diagnostic; -use ruff_diagnostics::{AlwaysAutofixableViolation, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Constant, Expr}; use ruff_text_size::Ranged; -use crate::autofix::edits::{remove_argument, Parentheses}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix::edits::{remove_argument, Parentheses}; /// ## What it does /// Checks for `range` calls with an unnecessary `start` argument. @@ -33,13 +30,13 @@ use crate::registry::AsRule; #[violation] pub struct UnnecessaryRangeStart; -impl AlwaysAutofixableViolation for UnnecessaryRangeStart { +impl AlwaysFixableViolation for UnnecessaryRangeStart { #[derive_message_formats] fn message(&self) -> String { format!("Unnecessary `start` argument in `range`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { format!("Remove `start` argument") } } @@ -75,21 +72,19 @@ pub(crate) fn unnecessary_range_start(checker: &mut Checker, call: &ast::ExprCal else { return; }; - if *value != BigInt::from(0) { + if *value != 0 { return; }; let mut diagnostic = Diagnostic::new(UnnecessaryRangeStart, start.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - remove_argument( - &start, - &call.arguments, - Parentheses::Preserve, - checker.locator().contents(), - ) - .map(Fix::automatic) - }); - } + diagnostic.try_set_fix(|| { + remove_argument( + &start, + &call.arguments, + Parentheses::Preserve, + checker.locator().contents(), + ) + .map(Fix::safe_edit) + }); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE790_PIE790.py.snap b/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE790_PIE790.py.snap index 8a10e5db448fa..1107602350c2c 100644 --- a/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE790_PIE790.py.snap +++ b/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE790_PIE790.py.snap @@ -317,4 +317,149 @@ PIE790.py:101:5: PIE790 [*] Unnecessary `pass` statement 103 103 | 104 104 | class Foo: +PIE790.py:130:5: PIE790 [*] Unnecessary `pass` statement + | +128 | def foo(): +129 | print("foo") +130 | pass + | ^^^^ PIE790 + | + = help: Remove unnecessary `pass` + +ℹ Fix +127 127 | +128 128 | def foo(): +129 129 | print("foo") +130 |- pass +131 130 | +132 131 | +133 132 | def foo(): + +PIE790.py:136:5: PIE790 [*] Unnecessary `pass` statement + | +134 | """A docstring.""" +135 | print("foo") +136 | pass + | ^^^^ PIE790 + | + = help: Remove unnecessary `pass` + +ℹ Fix +133 133 | def foo(): +134 134 | """A docstring.""" +135 135 | print("foo") +136 |- pass +137 136 | +138 137 | +139 138 | for i in range(10): + +PIE790.py:140:5: PIE790 [*] Unnecessary `pass` statement + | +139 | for i in range(10): +140 | pass + | ^^^^ PIE790 +141 | pass + | + = help: Remove unnecessary `pass` + +ℹ Fix +138 138 | +139 139 | for i in range(10): +140 140 | pass +141 |- pass +142 141 | +143 142 | for i in range(10): +144 143 | pass + +PIE790.py:141:5: PIE790 [*] Unnecessary `pass` statement + | +139 | for i in range(10): +140 | pass +141 | pass + | ^^^^ PIE790 +142 | +143 | for i in range(10): + | + = help: Remove unnecessary `pass` + +ℹ Fix +138 138 | +139 139 | for i in range(10): +140 140 | pass +141 |- pass +142 141 | +143 142 | for i in range(10): +144 143 | pass + +PIE790.py:144:5: PIE790 [*] Unnecessary `pass` statement + | +143 | for i in range(10): +144 | pass + | ^^^^ PIE790 +145 | +146 | pass + | + = help: Remove unnecessary `pass` + +ℹ Fix +141 141 | pass +142 142 | +143 143 | for i in range(10): +144 |- pass +145 144 | +146 145 | pass +147 146 | + +PIE790.py:146:5: PIE790 [*] Unnecessary `pass` statement + | +144 | pass +145 | +146 | pass + | ^^^^ PIE790 +147 | +148 | for i in range(10): + | + = help: Remove unnecessary `pass` + +ℹ Fix +143 143 | for i in range(10): +144 144 | pass +145 145 | +146 |- pass +147 146 | +148 147 | for i in range(10): +149 148 | pass # comment + +PIE790.py:149:5: PIE790 [*] Unnecessary `pass` statement + | +148 | for i in range(10): +149 | pass # comment + | ^^^^ PIE790 +150 | pass + | + = help: Remove unnecessary `pass` + +ℹ Fix +146 146 | pass +147 147 | +148 148 | for i in range(10): +149 |- pass # comment + 149 |+ # comment +150 150 | pass + +PIE790.py:150:5: PIE790 [*] Unnecessary `pass` statement + | +148 | for i in range(10): +149 | pass # comment +150 | pass + | ^^^^ PIE790 + | + = help: Remove unnecessary `pass` + +ℹ Fix +147 147 | +148 148 | for i in range(10): +149 149 | pass # comment +150 |- pass + diff --git a/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE804_PIE804.py.snap b/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE804_PIE804.py.snap index 7f7b0c95210fe..fee4c78e95c2a 100644 --- a/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE804_PIE804.py.snap +++ b/crates/ruff_linter/src/rules/flake8_pie/snapshots/ruff_linter__rules__flake8_pie__tests__PIE804_PIE804.py.snap @@ -1,15 +1,23 @@ --- source: crates/ruff_linter/src/rules/flake8_pie/mod.rs --- -PIE804.py:1:1: PIE804 Unnecessary `dict` kwargs +PIE804.py:1:1: PIE804 [*] Unnecessary `dict` kwargs | 1 | foo(**{"bar": True}) # PIE804 | ^^^^^^^^^^^^^^^^^^^^ PIE804 2 | 3 | foo(**{"r2d2": True}) # PIE804 | + = help: Remove unnecessary kwargs -PIE804.py:3:1: PIE804 Unnecessary `dict` kwargs +ℹ Fix +1 |-foo(**{"bar": True}) # PIE804 + 1 |+foo(bar=True) # PIE804 +2 2 | +3 3 | foo(**{"r2d2": True}) # PIE804 +4 4 | + +PIE804.py:3:1: PIE804 [*] Unnecessary `dict` kwargs | 1 | foo(**{"bar": True}) # PIE804 2 | @@ -18,8 +26,18 @@ PIE804.py:3:1: PIE804 Unnecessary `dict` kwargs 4 | 5 | Foo.objects.create(**{"bar": True}) # PIE804 | + = help: Remove unnecessary kwargs + +ℹ Fix +1 1 | foo(**{"bar": True}) # PIE804 +2 2 | +3 |-foo(**{"r2d2": True}) # PIE804 + 3 |+foo(r2d2=True) # PIE804 +4 4 | +5 5 | Foo.objects.create(**{"bar": True}) # PIE804 +6 6 | -PIE804.py:5:1: PIE804 Unnecessary `dict` kwargs +PIE804.py:5:1: PIE804 [*] Unnecessary `dict` kwargs | 3 | foo(**{"r2d2": True}) # PIE804 4 | @@ -28,8 +46,19 @@ PIE804.py:5:1: PIE804 Unnecessary `dict` kwargs 6 | 7 | Foo.objects.create(**{"_id": some_id}) # PIE804 | + = help: Remove unnecessary kwargs + +ℹ Fix +2 2 | +3 3 | foo(**{"r2d2": True}) # PIE804 +4 4 | +5 |-Foo.objects.create(**{"bar": True}) # PIE804 + 5 |+Foo.objects.create(bar=True) # PIE804 +6 6 | +7 7 | Foo.objects.create(**{"_id": some_id}) # PIE804 +8 8 | -PIE804.py:7:1: PIE804 Unnecessary `dict` kwargs +PIE804.py:7:1: PIE804 [*] Unnecessary `dict` kwargs | 5 | Foo.objects.create(**{"bar": True}) # PIE804 6 | @@ -38,13 +67,56 @@ PIE804.py:7:1: PIE804 Unnecessary `dict` kwargs 8 | 9 | Foo.objects.create(**{**bar}) # PIE804 | + = help: Remove unnecessary kwargs -PIE804.py:9:1: PIE804 Unnecessary `dict` kwargs - | -7 | Foo.objects.create(**{"_id": some_id}) # PIE804 -8 | -9 | Foo.objects.create(**{**bar}) # PIE804 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PIE804 - | +ℹ Fix +4 4 | +5 5 | Foo.objects.create(**{"bar": True}) # PIE804 +6 6 | +7 |-Foo.objects.create(**{"_id": some_id}) # PIE804 + 7 |+Foo.objects.create(_id=some_id) # PIE804 +8 8 | +9 9 | Foo.objects.create(**{**bar}) # PIE804 +10 10 | + +PIE804.py:9:1: PIE804 [*] Unnecessary `dict` kwargs + | + 7 | Foo.objects.create(**{"_id": some_id}) # PIE804 + 8 | + 9 | Foo.objects.create(**{**bar}) # PIE804 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PIE804 +10 | +11 | foo(**{}) + | + = help: Remove unnecessary kwargs + +ℹ Fix +6 6 | +7 7 | Foo.objects.create(**{"_id": some_id}) # PIE804 +8 8 | +9 |-Foo.objects.create(**{**bar}) # PIE804 + 9 |+Foo.objects.create(**bar) # PIE804 +10 10 | +11 11 | foo(**{}) +12 12 | + +PIE804.py:11:1: PIE804 [*] Unnecessary `dict` kwargs + | + 9 | Foo.objects.create(**{**bar}) # PIE804 +10 | +11 | foo(**{}) + | ^^^^^^^^^ PIE804 + | + = help: Remove unnecessary kwargs + +ℹ Fix +8 8 | +9 9 | Foo.objects.create(**{**bar}) # PIE804 +10 10 | +11 |-foo(**{}) + 11 |+foo() +12 12 | +13 13 | +14 14 | foo(**{**data, "foo": "buzz"}) diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/any_eq_ne_annotation.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/any_eq_ne_annotation.rs index d26879e414b77..a1937322265af 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/any_eq_ne_annotation.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/any_eq_ne_annotation.rs @@ -1,11 +1,10 @@ use ruff_python_ast::Parameters; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for `__eq__` and `__ne__` implementations that use `typing.Any` as @@ -35,20 +34,20 @@ use crate::registry::AsRule; /// ``` /// ## References /// - [Python documentation: The `Any` type](https://docs.python.org/3/library/typing.html#the-any-type) -/// - [Mypy documentation](https://mypy.readthedocs.io/en/latest/dynamic_typing.html#any-vs-object) +/// - [Mypy documentation: Any vs. object](https://mypy.readthedocs.io/en/latest/dynamic_typing.html#any-vs-object) #[violation] pub struct AnyEqNeAnnotation { method_name: String, } -impl AlwaysAutofixableViolation for AnyEqNeAnnotation { +impl AlwaysFixableViolation for AnyEqNeAnnotation { #[derive_message_formats] fn message(&self) -> String { let AnyEqNeAnnotation { method_name } = self; format!("Prefer `object` to `Any` for the second parameter to `{method_name}`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { format!("Replace with `object`") } } @@ -78,14 +77,12 @@ pub(crate) fn any_eq_ne_annotation(checker: &mut Checker, name: &str, parameters }, annotation.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // Ex) `def __eq__(self, obj: Any): ...` - if checker.semantic().is_builtin("object") { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - "object".to_string(), - annotation.range(), - ))); - } + // Ex) `def __eq__(self, obj: Any): ...` + if checker.semantic().is_builtin("object") { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "object".to_string(), + annotation.range(), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/collections_named_tuple.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/collections_named_tuple.rs index 6166d1aee1bad..b045a443746e6 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/collections_named_tuple.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/collections_named_tuple.rs @@ -43,7 +43,7 @@ impl Violation for CollectionsNamedTuple { format!("Use `typing.NamedTuple` instead of `collections.namedtuple`") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some(format!("Replace with `typing.NamedTuple`")) } } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/docstring_in_stubs.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/docstring_in_stubs.rs index 6f96e8d29ef5a..38d06d0335c48 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/docstring_in_stubs.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/docstring_in_stubs.rs @@ -6,6 +6,25 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; +/// ## What it does +/// Checks for the presence of docstrings in stub files. +/// +/// ## Why is this bad? +/// Stub files should omit docstrings, as they're intended to provide type +/// hints, rather than documentation. +/// +/// ## Example +/// ```python +/// def func(param: int) -> str: +/// """This is a docstring.""" +/// ... +/// ``` +/// +/// Use instead: +/// ```python +/// def func(param: int) -> str: +/// ... +/// ``` #[violation] pub struct DocstringInStub; diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/duplicate_union_member.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/duplicate_union_member.rs index c36c4f5a51f78..b12c741620f86 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/duplicate_union_member.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/duplicate_union_member.rs @@ -3,9 +3,9 @@ use rustc_hash::FxHashSet; use std::collections::HashSet; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_pyi::helpers::traverse_union; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::comparable::ComparableExpr; use ruff_text_size::Ranged; @@ -34,14 +34,14 @@ pub struct DuplicateUnionMember { } impl Violation for DuplicateUnionMember { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Duplicate union member `{}`", self.duplicate_name) } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some(format!( "Remove duplicate union member `{}`", self.duplicate_name @@ -64,19 +64,17 @@ pub(crate) fn duplicate_union_member<'a>(checker: &mut Checker, expr: &'a Expr) }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // Delete the "|" character as well as the duplicate value by reconstructing the - // parent without the duplicate. + // Delete the "|" character as well as the duplicate value by reconstructing the + // parent without the duplicate. - // If the parent node is not a `BinOp` we will not perform a fix - if let Some(parent @ Expr::BinOp(ast::ExprBinOp { left, right, .. })) = parent { - // Replace the parent with its non-duplicate child. - let child = if expr == left.as_ref() { right } else { left }; - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - checker.locator().slice(child.as_ref()).to_string(), - parent.range(), - ))); - } + // If the parent node is not a `BinOp` we will not perform a fix + if let Some(parent @ Expr::BinOp(ast::ExprBinOp { left, right, .. })) = parent { + // Replace the parent with its non-duplicate child. + let child = if expr == left.as_ref() { right } else { left }; + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + checker.locator().slice(child.as_ref()).to_string(), + parent.range(), + ))); } diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/ellipsis_in_non_empty_class_body.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/ellipsis_in_non_empty_class_body.rs index c29b24697de53..6afb063a4ab4d 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/ellipsis_in_non_empty_class_body.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/ellipsis_in_non_empty_class_body.rs @@ -1,11 +1,10 @@ -use ruff_diagnostics::{AutofixKind, Diagnostic, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{Constant, Expr, ExprConstant, Stmt, StmtExpr}; use ruff_text_size::Ranged; -use crate::autofix; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix; /// ## What it does /// Removes ellipses (`...`) in otherwise non-empty class bodies. @@ -31,14 +30,14 @@ use crate::registry::AsRule; pub struct EllipsisInNonEmptyClassBody; impl Violation for EllipsisInNonEmptyClassBody { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Non-empty class body must not contain `...`") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Remove unnecessary `...`".to_string()) } } @@ -63,17 +62,11 @@ pub(crate) fn ellipsis_in_non_empty_class_body(checker: &mut Checker, body: &[St }) ) { let mut diagnostic = Diagnostic::new(EllipsisInNonEmptyClassBody, stmt.range()); - if checker.patch(diagnostic.kind.rule()) { - let edit = autofix::edits::delete_stmt( - stmt, - Some(stmt), - checker.locator(), - checker.indexer(), - ); - diagnostic.set_fix(Fix::automatic(edit).isolate(Checker::isolation(Some( - checker.semantic().current_statement_id(), - )))); - } + let edit = + fix::edits::delete_stmt(stmt, Some(stmt), checker.locator(), checker.indexer()); + diagnostic.set_fix(Fix::safe_edit(edit).isolate(Checker::isolation( + checker.semantic().current_statement_id(), + ))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/exit_annotations.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/exit_annotations.rs index 4add4c70abfc9..4e21bb56416d8 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/exit_annotations.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/exit_annotations.rs @@ -6,14 +6,13 @@ use ruff_python_ast::{ }; use smallvec::SmallVec; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::is_const_none; use ruff_python_semantic::SemanticModel; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for incorrect function signatures on `__exit__` and `__aexit__` @@ -49,7 +48,7 @@ pub struct BadExitAnnotation { } impl Violation for BadExitAnnotation { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -65,7 +64,7 @@ impl Violation for BadExitAnnotation { } } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { if matches!(self.error_kind, ErrorKind::StarArgsNotAnnotated) { Some("Annotate star-args with `object`".to_string()) } else { @@ -175,13 +174,11 @@ fn check_short_args_list(checker: &mut Checker, parameters: &Parameters, func_ki annotation.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if checker.semantic().is_builtin("object") { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - "object".to_string(), - annotation.range(), - ))); - } + if checker.semantic().is_builtin("object") { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "object".to_string(), + annotation.range(), + ))); } checker.diagnostics.push(diagnostic); diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/future_annotations_in_stub.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/future_annotations_in_stub.rs index deaae2b0f7dcc..bdbaf4a274c53 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/future_annotations_in_stub.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/future_annotations_in_stub.rs @@ -5,6 +5,17 @@ use ruff_macros::{derive_message_formats, violation}; use crate::checkers::ast::Checker; +/// ## What it does +/// Checks for the presence of the `from __future__ import annotations` import +/// statement in stub files. +/// +/// ## Why is this bad? +/// Stub files are already evaluated under `annotations` semantics. As such, +/// the `from __future__ import annotations` import statement has no effect +/// and should be omitted. +/// +/// ## Resources +/// - [Static Typing with Python: Type Stubs](https://typing.readthedocs.io/en/latest/source/stubs.html) #[violation] pub struct FutureAnnotationsInStub; diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/no_return_argument_annotation.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/no_return_argument_annotation.rs index 7dd300115b4ae..f10946236be2d 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/no_return_argument_annotation.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/no_return_argument_annotation.rs @@ -8,11 +8,6 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::settings::types::PythonVersion::Py311; -#[violation] -pub struct NoReturnArgumentAnnotationInStub { - module: TypingModule, -} - /// ## What it does /// Checks for uses of `typing.NoReturn` (and `typing_extensions.NoReturn`) in /// stubs. @@ -37,6 +32,15 @@ pub struct NoReturnArgumentAnnotationInStub { /// /// def foo(x: Never): ... /// ``` +/// +/// ## References +/// - [Python documentation: `typing.Never`](https://docs.python.org/3/library/typing.html#typing.Never) +/// - [Python documentation: `typing.NoReturn`](https://docs.python.org/3/library/typing.html#typing.NoReturn) +#[violation] +pub struct NoReturnArgumentAnnotationInStub { + module: TypingModule, +} + impl Violation for NoReturnArgumentAnnotationInStub { #[derive_message_formats] fn message(&self) -> String { diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/non_empty_stub_body.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/non_empty_stub_body.rs index 86f2a42ae8b71..55827e066515d 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/non_empty_stub_body.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/non_empty_stub_body.rs @@ -1,11 +1,10 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::is_docstring_stmt; use ruff_python_ast::{self as ast, Expr, Stmt}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::Rule; /// ## What it does /// Checks for non-empty function stub bodies. @@ -31,13 +30,13 @@ use crate::registry::Rule; #[violation] pub struct NonEmptyStubBody; -impl AlwaysAutofixableViolation for NonEmptyStubBody { +impl AlwaysFixableViolation for NonEmptyStubBody { #[derive_message_formats] fn message(&self) -> String { format!("Function body must contain only `...`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { format!("Replace function body with `...`") } } @@ -69,11 +68,9 @@ pub(crate) fn non_empty_stub_body(checker: &mut Checker, body: &[Stmt]) { } let mut diagnostic = Diagnostic::new(NonEmptyStubBody, stmt.range()); - if checker.patch(Rule::NonEmptyStubBody) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - format!("..."), - stmt.range(), - ))); - }; + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + format!("..."), + stmt.range(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/non_self_return_type.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/non_self_return_type.rs index 0f251297cb6f1..ad8902dd46570 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/non_self_return_type.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/non_self_return_type.rs @@ -104,7 +104,7 @@ impl Violation for NonSelfReturnType { } } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Consider using `typing_extensions.Self` as return type".to_string()) } } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/numeric_literal_too_long.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/numeric_literal_too_long.rs index 2eaaf64a27edb..64092f3035a7d 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/numeric_literal_too_long.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/numeric_literal_too_long.rs @@ -1,14 +1,10 @@ use ruff_python_ast::Expr; use ruff_text_size::{Ranged, TextSize}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; - -#[violation] -pub struct NumericLiteralTooLong; /// ## What it does /// Checks for numeric literals with a string representation longer than ten @@ -23,20 +19,25 @@ pub struct NumericLiteralTooLong; /// /// ## Example /// ```python -/// def foo(arg: int = 12345678901) -> None: ... +/// def foo(arg: int = 12345678901) -> None: +/// ... /// ``` /// /// Use instead: /// ```python -/// def foo(arg: int = ...) -> None: ... +/// def foo(arg: int = ...) -> None: +/// ... /// ``` -impl AlwaysAutofixableViolation for NumericLiteralTooLong { +#[violation] +pub struct NumericLiteralTooLong; + +impl AlwaysFixableViolation for NumericLiteralTooLong { #[derive_message_formats] fn message(&self) -> String { format!("Numeric literals with a string representation longer than ten characters are not permitted") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace with `...`".to_string() } } @@ -48,11 +49,9 @@ pub(crate) fn numeric_literal_too_long(checker: &mut Checker, expr: &Expr) { } let mut diagnostic = Diagnostic::new(NumericLiteralTooLong, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - "...".to_string(), - expr.range(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "...".to_string(), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/pass_in_class_body.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/pass_in_class_body.rs index 81028788408b8..1e26b76c6e527 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/pass_in_class_body.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/pass_in_class_body.rs @@ -1,22 +1,47 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast}; use ruff_text_size::Ranged; -use crate::autofix; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix; +/// ## What it does +/// Checks for the presence of the `pass` statement within a class body +/// in a stub (`.pyi`) file. +/// +/// ## Why is this bad? +/// In stub files, class definitions are intended to provide type hints, but +/// are never actually evaluated. As such, it's unnecessary to include a `pass` +/// statement in a class body, since it has no effect. +/// +/// Instead of `pass`, prefer `...` to indicate that the class body is empty +/// and adhere to common stub file conventions. +/// +/// ## Example +/// ```python +/// class MyClass: +/// pass +/// ``` +/// +/// Use instead: +/// ```python +/// class MyClass: +/// ... +/// ``` +/// +/// ## References +/// - [Mypy documentation: Stub files](https://mypy.readthedocs.io/en/stable/stubs.html) #[violation] pub struct PassInClassBody; -impl AlwaysAutofixableViolation for PassInClassBody { +impl AlwaysFixableViolation for PassInClassBody { #[derive_message_formats] fn message(&self) -> String { format!("Class body must not contain `pass`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { format!("Remove unnecessary `pass`") } } @@ -34,13 +59,10 @@ pub(crate) fn pass_in_class_body(checker: &mut Checker, class_def: &ast::StmtCla } let mut diagnostic = Diagnostic::new(PassInClassBody, stmt.range()); - if checker.patch(diagnostic.kind.rule()) { - let edit = - autofix::edits::delete_stmt(stmt, Some(stmt), checker.locator(), checker.indexer()); - diagnostic.set_fix(Fix::automatic(edit).isolate(Checker::isolation(Some( - checker.semantic().current_statement_id(), - )))); - } + let edit = fix::edits::delete_stmt(stmt, Some(stmt), checker.locator(), checker.indexer()); + diagnostic.set_fix(Fix::safe_edit(edit).isolate(Checker::isolation( + checker.semantic().current_statement_id(), + ))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/pass_statement_stub_body.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/pass_statement_stub_body.rs index 3dd8f13b868f0..3e1a0d3a8d35f 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/pass_statement_stub_body.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/pass_statement_stub_body.rs @@ -1,10 +1,9 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::Stmt; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::Rule; /// ## What it does /// Checks for `pass` statements in empty stub bodies. @@ -29,13 +28,13 @@ use crate::registry::Rule; #[violation] pub struct PassStatementStubBody; -impl AlwaysAutofixableViolation for PassStatementStubBody { +impl AlwaysFixableViolation for PassStatementStubBody { #[derive_message_formats] fn message(&self) -> String { format!("Empty body should contain `...`, not `pass`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { format!("Replace `pass` with `...`") } } @@ -47,11 +46,9 @@ pub(crate) fn pass_statement_stub_body(checker: &mut Checker, body: &[Stmt]) { }; let mut diagnostic = Diagnostic::new(PassStatementStubBody, pass.range()); - if checker.patch(Rule::PassStatementStubBody) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - format!("..."), - pass.range(), - ))); - }; + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + format!("..."), + pass.range(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/quoted_annotation_in_stub.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/quoted_annotation_in_stub.rs index 49e624735a1d6..96330f7573966 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/quoted_annotation_in_stub.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/quoted_annotation_in_stub.rs @@ -1,21 +1,40 @@ use ruff_text_size::TextRange; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use crate::checkers::ast::Checker; -use crate::registry::Rule; +/// ## What it does +/// Checks for quoted type annotations in stub (`.pyi`) files, which should be avoided. +/// +/// ## Why is this bad? +/// Stub files are evaluated using `annotations` semantics, as if +/// `from __future__ import annotations` were included in the file. As such, +/// quotes are never required for type annotations in stub files, and should be +/// omitted. +/// +/// ## Example +/// ```python +/// def function() -> "int": +/// ... +/// ``` +/// +/// Use instead: +/// ```python +/// def function() -> int: +/// ... +/// ``` #[violation] pub struct QuotedAnnotationInStub; -impl AlwaysAutofixableViolation for QuotedAnnotationInStub { +impl AlwaysFixableViolation for QuotedAnnotationInStub { #[derive_message_formats] fn message(&self) -> String { format!("Quoted annotations should not be included in stubs") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove quotes".to_string() } } @@ -23,11 +42,9 @@ impl AlwaysAutofixableViolation for QuotedAnnotationInStub { /// PYI020 pub(crate) fn quoted_annotation_in_stub(checker: &mut Checker, annotation: &str, range: TextRange) { let mut diagnostic = Diagnostic::new(QuotedAnnotationInStub, range); - if checker.patch(Rule::QuotedAnnotationInStub) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - annotation.to_string(), - range, - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + annotation.to_string(), + range, + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/redundant_literal_union.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/redundant_literal_union.rs index f486da3fd4cde..dcd080c66a5e6 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/redundant_literal_union.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/redundant_literal_union.rs @@ -8,7 +8,7 @@ use ruff_python_ast::{self as ast, Expr}; use ruff_python_semantic::SemanticModel; use ruff_text_size::Ranged; -use crate::autofix::snippet::SourceCodeSnippet; +use crate::fix::snippet::SourceCodeSnippet; use crate::{checkers::ast::Checker, rules::flake8_pyi::helpers::traverse_union}; /// ## What it does diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/simple_defaults.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/simple_defaults.rs index 9ca545ebc7744..dd93d496138c4 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/simple_defaults.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/simple_defaults.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::call_path::CallPath; use ruff_python_ast::{ @@ -11,52 +11,152 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::importer::ImportRequest; -use crate::registry::AsRule; + use crate::rules::flake8_pyi::rules::TypingModule; use crate::settings::types::PythonVersion; +/// ## What it does +/// Checks for typed function arguments in stubs with default values that +/// are not "simple" /// (i.e., `int`, `float`, `complex`, `bytes`, `str`, +/// `bool`, `None`, `...`, or simple container literals). +/// +/// ## Why is this bad? +/// Stub (`.pyi`) files exist to define type hints, and are not evaluated at +/// runtime. As such, function arguments in stub files should not have default +/// values, as they are ignored by type checkers. +/// +/// However, the use of default values may be useful for IDEs and other +/// consumers of stub files, and so "simple" values may be worth including and +/// are permitted by this rule. +/// +/// Instead of including and reproducing a complex value, use `...` to indicate +/// that the assignment has a default value, but that the value is non-simple +/// or varies according to the current platform or Python version. +/// +/// ## Example +/// ```python +/// def foo(arg: List[int] = []) -> None: +/// ... +/// ``` +/// +/// Use instead: +/// ```python +/// def foo(arg: List[int] = ...) -> None: +/// ... +/// ``` +/// +/// ## References +/// - [`flake8-pyi`](https://github.com/PyCQA/flake8-pyi/blob/main/ERRORCODES.md) #[violation] pub struct TypedArgumentDefaultInStub; -impl AlwaysAutofixableViolation for TypedArgumentDefaultInStub { +impl AlwaysFixableViolation for TypedArgumentDefaultInStub { #[derive_message_formats] fn message(&self) -> String { format!("Only simple default values allowed for typed arguments") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace default value with `...`".to_string() } } +/// ## What it does +/// Checks for untyped function arguments in stubs with default values that +/// are not "simple" /// (i.e., `int`, `float`, `complex`, `bytes`, `str`, +/// `bool`, `None`, `...`, or simple container literals). +/// +/// ## Why is this bad? +/// Stub (`.pyi`) files exist to define type hints, and are not evaluated at +/// runtime. As such, function arguments in stub files should not have default +/// values, as they are ignored by type checkers. +/// +/// However, the use of default values may be useful for IDEs and other +/// consumers of stub files, and so "simple" values may be worth including and +/// are permitted by this rule. +/// +/// Instead of including and reproducing a complex value, use `...` to indicate +/// that the assignment has a default value, but that the value is non-simple +/// or varies according to the current platform or Python version. +/// +/// ## Example +/// ```python +/// def foo(arg=[]) -> None: +/// ... +/// ``` +/// +/// Use instead: +/// ```python +/// def foo(arg=...) -> None: +/// ... +/// ``` +/// +/// ## References +/// - [`flake8-pyi`](https://github.com/PyCQA/flake8-pyi/blob/main/ERRORCODES.md) #[violation] pub struct ArgumentDefaultInStub; -impl AlwaysAutofixableViolation for ArgumentDefaultInStub { +impl AlwaysFixableViolation for ArgumentDefaultInStub { #[derive_message_formats] fn message(&self) -> String { format!("Only simple default values allowed for arguments") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace default value with `...`".to_string() } } +/// ## What it does +/// Checks for assignments in stubs with default values that are not "simple" +/// (i.e., `int`, `float`, `complex`, `bytes`, `str`, `bool`, `None`, `...`, or +/// simple container literals). +/// +/// ## Why is this bad? +/// Stub (`.pyi`) files exist to define type hints, and are not evaluated at +/// runtime. As such, assignments in stub files should not include values, +/// as they are ignored by type checkers. +/// +/// However, the use of such values may be useful for IDEs and other consumers +/// of stub files, and so "simple" values may be worth including and are +/// permitted by this rule. +/// +/// Instead of including and reproducing a complex value, use `...` to indicate +/// that the assignment has a default value, but that the value is non-simple +/// or varies according to the current platform or Python version. +/// +/// ## Example +/// ```python +/// foo: str = "..." +/// ``` +/// +/// Use instead: +/// ```python +/// foo: str = ... +/// ``` +/// +/// ## References +/// - [`flake8-pyi`](https://github.com/PyCQA/flake8-pyi/blob/main/ERRORCODES.md) #[violation] pub struct AssignmentDefaultInStub; -impl AlwaysAutofixableViolation for AssignmentDefaultInStub { +impl AlwaysFixableViolation for AssignmentDefaultInStub { #[derive_message_formats] fn message(&self) -> String { format!("Only simple default values allowed for assignments") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace default value with `...`".to_string() } } +/// ## What it does? +/// Checks for unannotated assignments in stub (`.pyi`) files. +/// +/// ## Why is this bad? +/// Stub files exist to provide type hints, and are never executed. As such, +/// all assignments in stub files should be annotated with a type. #[violation] pub struct UnannotatedAssignmentInStub { name: String, @@ -70,11 +170,6 @@ impl Violation for UnannotatedAssignmentInStub { } } -#[violation] -pub struct UnassignedSpecialVariableInStub { - name: String, -} - /// ## What it does /// Checks that `__all__`, `__match_args__`, and `__slots__` variables are /// assigned to values when defined in stub files. @@ -93,6 +188,11 @@ pub struct UnassignedSpecialVariableInStub { /// ```python /// __all__: list[str] = ["foo", "bar"] /// ``` +#[violation] +pub struct UnassignedSpecialVariableInStub { + name: String, +} + impl Violation for UnassignedSpecialVariableInStub { #[derive_message_formats] fn message(&self) -> String { @@ -131,7 +231,7 @@ pub struct TypeAliasWithoutAnnotation { value: String, } -impl AlwaysAutofixableViolation for TypeAliasWithoutAnnotation { +impl AlwaysFixableViolation for TypeAliasWithoutAnnotation { #[derive_message_formats] fn message(&self) -> String { let TypeAliasWithoutAnnotation { @@ -142,7 +242,7 @@ impl AlwaysAutofixableViolation for TypeAliasWithoutAnnotation { format!("Use `{module}.TypeAlias` for type alias, e.g., `{name}: TypeAlias = {value}`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Add `TypeAlias` annotation".to_string() } } @@ -434,12 +534,10 @@ pub(crate) fn typed_argument_simple_defaults(checker: &mut Checker, parameters: ) { let mut diagnostic = Diagnostic::new(TypedArgumentDefaultInStub, default.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - "...".to_string(), - default.range(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "...".to_string(), + default.range(), + ))); checker.diagnostics.push(diagnostic); } @@ -471,12 +569,10 @@ pub(crate) fn argument_simple_defaults(checker: &mut Checker, parameters: &Param ) { let mut diagnostic = Diagnostic::new(ArgumentDefaultInStub, default.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - "...".to_string(), - default.range(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "...".to_string(), + default.range(), + ))); checker.diagnostics.push(diagnostic); } @@ -506,12 +602,10 @@ pub(crate) fn assignment_default_in_stub(checker: &mut Checker, targets: &[Expr] } let mut diagnostic = Diagnostic::new(AssignmentDefaultInStub, value.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - "...".to_string(), - value.range(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "...".to_string(), + value.range(), + ))); checker.diagnostics.push(diagnostic); } @@ -542,12 +636,10 @@ pub(crate) fn annotated_assignment_default_in_stub( } let mut diagnostic = Diagnostic::new(AssignmentDefaultInStub, value.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - "...".to_string(), - value.range(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "...".to_string(), + value.range(), + ))); checker.diagnostics.push(diagnostic); } @@ -641,18 +733,16 @@ pub(crate) fn type_alias_without_annotation(checker: &mut Checker, value: &Expr, }, target.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - let (import_edit, binding) = checker.importer().get_or_import_symbol( - &ImportRequest::import(module.as_str(), "TypeAlias"), - target.start(), - checker.semantic(), - )?; - Ok(Fix::suggested_edits( - Edit::range_replacement(format!("{id}: {binding}"), target.range()), - [import_edit], - )) - }); - } + diagnostic.try_set_fix(|| { + let (import_edit, binding) = checker.importer().get_or_import_symbol( + &ImportRequest::import(module.as_str(), "TypeAlias"), + target.start(), + checker.semantic(), + )?; + Ok(Fix::safe_edits( + Edit::range_replacement(format!("{id}: {binding}"), target.range()), + [import_edit], + )) + }); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/str_or_repr_defined_in_stub.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/str_or_repr_defined_in_stub.rs index 6676c9009e213..ee8a0de530503 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/str_or_repr_defined_in_stub.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/str_or_repr_defined_in_stub.rs @@ -1,14 +1,13 @@ use ruff_python_ast as ast; use ruff_python_ast::Stmt; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::identifier::Identifier; use ruff_python_semantic::analyze::visibility::is_abstract; -use crate::autofix::edits::delete_stmt; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix::edits::delete_stmt; /// ## What it does /// Checks for redundant definitions of `__str__` or `__repr__` in stubs. @@ -29,14 +28,14 @@ pub struct StrOrReprDefinedInStub { name: String, } -impl AlwaysAutofixableViolation for StrOrReprDefinedInStub { +impl AlwaysFixableViolation for StrOrReprDefinedInStub { #[derive_message_formats] fn message(&self) -> String { let StrOrReprDefinedInStub { name } = self; format!("Defining `{name}` in a stub is almost always redundant") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let StrOrReprDefinedInStub { name } = self; format!("Remove definition of `{name}`") } @@ -95,13 +94,11 @@ pub(crate) fn str_or_repr_defined_in_stub(checker: &mut Checker, stmt: &Stmt) { }, stmt.identifier(), ); - if checker.patch(diagnostic.kind.rule()) { - let stmt = checker.semantic().current_statement(); - let parent = checker.semantic().current_statement_parent(); - let edit = delete_stmt(stmt, parent, checker.locator(), checker.indexer()); - diagnostic.set_fix(Fix::automatic(edit).isolate(Checker::isolation( - checker.semantic().current_statement_parent_id(), - ))); - } + let stmt = checker.semantic().current_statement(); + let parent = checker.semantic().current_statement_parent(); + let edit = delete_stmt(stmt, parent, checker.locator(), checker.indexer()); + diagnostic.set_fix(Fix::safe_edit(edit).isolate(Checker::isolation( + checker.semantic().current_statement_parent_id(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/string_or_bytes_too_long.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/string_or_bytes_too_long.rs index bbf20bda6273c..2ad818501c3a4 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/string_or_bytes_too_long.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/string_or_bytes_too_long.rs @@ -1,18 +1,15 @@ use ruff_python_ast::{self as ast, Constant, Expr}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::is_docstring_stmt; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; - -#[violation] -pub struct StringOrBytesTooLong; /// ## What it does -/// Checks for the use of string and bytes literals longer than 50 characters. +/// Checks for the use of string and bytes literals longer than 50 characters +/// in stub (`.pyi`) files. /// /// ## Why is this bad? /// If a function has a default value where the string or bytes representation @@ -23,20 +20,25 @@ pub struct StringOrBytesTooLong; /// /// ## Example /// ```python -/// def foo(arg: str = "51 character stringgggggggggggggggggggggggggggggggg") -> None: ... +/// def foo(arg: str = "51 character stringgggggggggggggggggggggggggggggggg") -> None: +/// ... /// ``` /// /// Use instead: /// ```python -/// def foo(arg: str = ...) -> None: ... +/// def foo(arg: str = ...) -> None: +/// ... /// ``` -impl AlwaysAutofixableViolation for StringOrBytesTooLong { +#[violation] +pub struct StringOrBytesTooLong; + +impl AlwaysFixableViolation for StringOrBytesTooLong { #[derive_message_formats] fn message(&self) -> String { format!("String and bytes literals longer than 50 characters are not permitted") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace with `...`".to_string() } } @@ -64,11 +66,9 @@ pub(crate) fn string_or_bytes_too_long(checker: &mut Checker, expr: &Expr) { } let mut diagnostic = Diagnostic::new(StringOrBytesTooLong, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - "...".to_string(), - expr.range(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "...".to_string(), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/stub_body_multiple_statements.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/stub_body_multiple_statements.rs index 77c20d5e942c9..efe4b918f7d22 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/stub_body_multiple_statements.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/stub_body_multiple_statements.rs @@ -5,6 +5,28 @@ use ruff_python_ast::Stmt; use crate::checkers::ast::Checker; +/// ## What it does +/// Checks for functions in stub (`.pyi`) files that contain multiple +/// statements. +/// +/// ## Why is this bad? +/// Stub files are never executed, and are only intended to define type hints. +/// As such, functions in stub files should not contain functional code, and +/// should instead contain only a single statement (e.g., `...`). +/// +/// ## Example +/// ```python +/// def function(): +/// x = 1 +/// y = 2 +/// return x + y +/// ``` +/// +/// Use instead: +/// ```python +/// def function(): +/// ... +/// ``` #[violation] pub struct StubBodyMultipleStatements; diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/type_alias_naming.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/type_alias_naming.rs index 38b0ea0c5e854..e240bd3bd8191 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/type_alias_naming.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/type_alias_naming.rs @@ -5,6 +5,22 @@ use ruff_macros::{derive_message_formats, violation}; use crate::checkers::ast::Checker; +/// ## What it does +/// Checks for type aliases that do not use the CamelCase naming convention. +/// +/// ## Why is this bad? +/// It's conventional to use the CamelCase naming convention for type aliases, +/// to distinguish them from other variables. +/// +/// ## Example +/// ```python +/// type_alias_name: TypeAlias = int +/// ``` +/// +/// Use instead: +/// ```python +/// TypeAliasName: TypeAlias = int +/// ``` #[violation] pub struct SnakeCaseTypeAlias { name: String, @@ -18,6 +34,25 @@ impl Violation for SnakeCaseTypeAlias { } } +/// ## What it does +/// Checks for private type alias definitions suffixed with 'T'. +/// +/// ## Why is this bad? +/// It's conventional to use the 'T' suffix for type variables; the use of +/// such a suffix implies that the object is a `TypeVar`. +/// +/// Adding the 'T' suffix to a non-`TypeVar`, it can be misleading and should +/// be avoided. +/// +/// ## Example +/// ```python +/// MyTypeT = int +/// ``` +/// +/// Use instead: +/// ```python +/// MyType = int +/// ``` #[violation] pub struct TSuffixedTypeAlias { name: String, diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/unaliased_collections_abc_set_import.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/unaliased_collections_abc_set_import.rs index 8ec902316e95a..79e6ba61a776e 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/unaliased_collections_abc_set_import.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/unaliased_collections_abc_set_import.rs @@ -1,11 +1,11 @@ -use ruff_diagnostics::{AutofixKind, Diagnostic, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_semantic::Imported; use ruff_python_semantic::{Binding, BindingKind}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::renamer::Renamer; /// ## What it does @@ -33,7 +33,7 @@ use crate::renamer::Renamer; pub struct UnaliasedCollectionsAbcSetImport; impl Violation for UnaliasedCollectionsAbcSetImport { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -42,7 +42,7 @@ impl Violation for UnaliasedCollectionsAbcSetImport { ) } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some(format!("Alias `Set` to `AbstractSet`")) } } @@ -65,14 +65,12 @@ pub(crate) fn unaliased_collections_abc_set_import( } let mut diagnostic = Diagnostic::new(UnaliasedCollectionsAbcSetImport, binding.range()); - if checker.patch(diagnostic.kind.rule()) { - if checker.semantic().is_available("AbstractSet") { - diagnostic.try_set_fix(|| { - let scope = &checker.semantic().scopes[binding.scope]; - let (edit, rest) = Renamer::rename(name, "AbstractSet", scope, checker.semantic())?; - Ok(Fix::suggested_edits(edit, rest)) - }); - } + if checker.semantic().is_available("AbstractSet") { + diagnostic.try_set_fix(|| { + let scope = &checker.semantic().scopes[binding.scope]; + let (edit, rest) = Renamer::rename(name, "AbstractSet", scope, checker.semantic())?; + Ok(Fix::unsafe_edits(edit, rest)) + }); } Some(diagnostic) } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/unnecessary_type_union.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/unnecessary_type_union.rs index 4eb4e8de3a848..75ba6ab9bc59f 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/unnecessary_type_union.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/unnecessary_type_union.rs @@ -1,7 +1,8 @@ -use ruff_diagnostics::{Diagnostic, Violation}; +use ast::{ExprContext, Operator}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::Expr; -use ruff_text_size::Ranged; +use ruff_python_ast::{self as ast, Expr}; +use ruff_text_size::{Ranged, TextRange}; use crate::{checkers::ast::Checker, rules::flake8_pyi::helpers::traverse_union}; @@ -9,8 +10,8 @@ use crate::{checkers::ast::Checker, rules::flake8_pyi::helpers::traverse_union}; /// Checks for the presence of multiple `type`s in a union. /// /// ## Why is this bad? -/// The `type` built-in function accepts unions, and it is -/// clearer to explicitly specify them as a single `type`. +/// The `type` built-in function accepts unions, and it is clearer to +/// explicitly specify them as a single `type`. /// /// ## Example /// ```python @@ -28,6 +29,8 @@ pub struct UnnecessaryTypeUnion { } impl Violation for UnnecessaryTypeUnion { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; + #[derive_message_formats] fn message(&self) -> String { let union_str = if self.is_pep604_union { @@ -40,6 +43,23 @@ impl Violation for UnnecessaryTypeUnion { "Multiple `type` members in a union. Combine them into one, e.g., `type[{union_str}]`." ) } + + fn fix_title(&self) -> Option { + Some(format!("Combine multiple `type` members")) + } +} + +fn concatenate_bin_ors(exprs: Vec<&Expr>) -> Expr { + let mut exprs = exprs.into_iter(); + let first = exprs.next().unwrap(); + exprs.fold((*first).clone(), |acc, expr| { + Expr::BinOp(ast::ExprBinOp { + left: Box::new(acc), + op: Operator::BitOr, + right: Box::new((*expr).clone()), + range: TextRange::default(), + }) + }) } /// PYI055 @@ -49,14 +69,17 @@ pub(crate) fn unnecessary_type_union<'a>(checker: &mut Checker, union: &'a Expr) return; } - let mut type_exprs = Vec::new(); - // Check if `union` is a PEP604 union (e.g. `float | int`) or a `typing.Union[float, int]` - let is_pep604_union = !union.as_subscript_expr().is_some_and(|subscript| { - checker + let subscript = union.as_subscript_expr(); + if subscript.is_some_and(|subscript| { + !checker .semantic() .match_typing_expr(&subscript.value, "Union") - }); + }) { + return; + } + + let mut type_exprs = Vec::new(); let mut collect_type_exprs = |expr: &'a Expr, _| { let Some(subscript) = expr.as_subscript_expr() else { @@ -74,15 +97,79 @@ pub(crate) fn unnecessary_type_union<'a>(checker: &mut Checker, union: &'a Expr) traverse_union(&mut collect_type_exprs, checker.semantic(), union, None); if type_exprs.len() > 1 { - checker.diagnostics.push(Diagnostic::new( + let type_members: Vec = type_exprs + .clone() + .into_iter() + .map(|type_expr| checker.locator().slice(type_expr.as_ref()).to_string()) + .collect(); + + let mut diagnostic = Diagnostic::new( UnnecessaryTypeUnion { - members: type_exprs - .into_iter() - .map(|type_expr| checker.locator().slice(type_expr.as_ref()).to_string()) - .collect(), - is_pep604_union, + members: type_members.clone(), + is_pep604_union: subscript.is_none(), }, union.range(), - )); + ); + + if checker.semantic().is_builtin("type") { + let content = if let Some(subscript) = subscript { + checker + .generator() + .expr(&Expr::Subscript(ast::ExprSubscript { + value: Box::new(Expr::Name(ast::ExprName { + id: "type".into(), + ctx: ExprContext::Load, + range: TextRange::default(), + })), + slice: Box::new(Expr::Subscript(ast::ExprSubscript { + value: subscript.value.clone(), + slice: Box::new(Expr::Tuple(ast::ExprTuple { + elts: type_members + .into_iter() + .map(|type_member| { + Expr::Name(ast::ExprName { + id: type_member, + ctx: ExprContext::Load, + range: TextRange::default(), + }) + }) + .collect(), + ctx: ExprContext::Load, + range: TextRange::default(), + })), + ctx: ExprContext::Load, + range: TextRange::default(), + })), + ctx: ExprContext::Load, + range: TextRange::default(), + })) + } else { + checker + .generator() + .expr(&Expr::Subscript(ast::ExprSubscript { + value: Box::new(Expr::Name(ast::ExprName { + id: "type".into(), + ctx: ExprContext::Load, + range: TextRange::default(), + })), + slice: Box::new(concatenate_bin_ors( + type_exprs + .clone() + .into_iter() + .map(std::convert::AsRef::as_ref) + .collect(), + )), + ctx: ExprContext::Load, + range: TextRange::default(), + })) + }; + + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + content, + union.range(), + ))); + } + + checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/unrecognized_version_info.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/unrecognized_version_info.rs index 4df6441d9358e..3d9a743f84510 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/unrecognized_version_info.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/unrecognized_version_info.rs @@ -1,10 +1,7 @@ -use num_bigint::BigInt; -use num_traits::{One, Zero}; -use ruff_python_ast::{self as ast, CmpOp, Constant, Expr}; - use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::map_subscript; +use ruff_python_ast::{self as ast, CmpOp, Constant, Expr, Int}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -249,18 +246,18 @@ impl ExpectedComparator { .. }) = upper.as_ref() { - if *upper == BigInt::one() { + if *upper == 1 { return Some(ExpectedComparator::MajorTuple); } - if *upper == BigInt::from(2) { + if *upper == 2 { return Some(ExpectedComparator::MajorMinorTuple); } } } Expr::Constant(ast::ExprConstant { - value: Constant::Int(n), + value: Constant::Int(Int::ZERO), .. - }) if n.is_zero() => { + }) => { return Some(ExpectedComparator::MajorDigit); } _ => (), diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI010_PYI010.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI010_PYI010.pyi.snap index b68bdf828cfc9..fe2c8c14edd25 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI010_PYI010.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI010_PYI010.pyi.snap @@ -11,7 +11,7 @@ PYI010.pyi:6:5: PYI010 [*] Function body must contain only `...` | = help: Replace function body with `...` -ℹ Suggested fix +ℹ Fix 3 3 | """foo""" # OK, docstrings are handled by another rule 4 4 | 5 5 | def buzz(): @@ -31,7 +31,7 @@ PYI010.pyi:9:5: PYI010 [*] Function body must contain only `...` | = help: Replace function body with `...` -ℹ Suggested fix +ℹ Fix 6 6 | print("buzz") # ERROR PYI010 7 7 | 8 8 | def foo2(): @@ -51,7 +51,7 @@ PYI010.pyi:12:5: PYI010 [*] Function body must contain only `...` | = help: Replace function body with `...` -ℹ Suggested fix +ℹ Fix 9 9 | 123 # ERROR PYI010 10 10 | 11 11 | def bizz(): diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI011_PYI011.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI011_PYI011.pyi.snap index b883a369b2915..362e2b72fba4a 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI011_PYI011.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI011_PYI011.pyi.snap @@ -12,7 +12,7 @@ PYI011.pyi:10:14: PYI011 [*] Only simple default values allowed for typed argume | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 7 7 | 8 8 | def f12( 9 9 | x, @@ -37,7 +37,7 @@ PYI011.pyi:38:9: PYI011 [*] Only simple default values allowed for typed argumen | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 35 35 | def f152( 36 36 | x: dict[ 37 37 | int, int @@ -74,7 +74,7 @@ PYI011.pyi:46:9: PYI011 [*] Only simple default values allowed for typed argumen | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 43 43 | def f153( 44 44 | x: list[ 45 45 | int @@ -111,7 +111,7 @@ PYI011.pyi:63:9: PYI011 [*] Only simple default values allowed for typed argumen | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 60 60 | def f154( 61 61 | x: tuple[ 62 62 | str, tuple[str, ...] @@ -138,7 +138,7 @@ PYI011.pyi:71:9: PYI011 [*] Only simple default values allowed for typed argumen | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 68 68 | def f141( 69 69 | x: list[ 70 70 | int @@ -164,7 +164,7 @@ PYI011.pyi:78:9: PYI011 [*] Only simple default values allowed for typed argumen | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 75 75 | def f142( 76 76 | x: list[ 77 77 | int @@ -190,7 +190,7 @@ PYI011.pyi:85:9: PYI011 [*] Only simple default values allowed for typed argumen | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 82 82 | def f16( 83 83 | x: frozenset[ 84 84 | bytes @@ -215,7 +215,7 @@ PYI011.pyi:90:14: PYI011 [*] Only simple default values allowed for typed argume | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 87 87 | ) 88 88 | ) -> None: ... 89 89 | def f17( @@ -239,7 +239,7 @@ PYI011.pyi:94:14: PYI011 [*] Only simple default values allowed for typed argume | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 91 91 | + "bar", 92 92 | ) -> None: ... 93 93 | def f18( @@ -263,7 +263,7 @@ PYI011.pyi:98:17: PYI011 [*] Only simple default values allowed for typed argume | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 95 95 | + b"bar", 96 96 | ) -> None: ... 97 97 | def f19( @@ -287,7 +287,7 @@ PYI011.pyi:102:14: PYI011 [*] Only simple default values allowed for typed argum | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 99 99 | + 4, 100 100 | ) -> None: ... 101 101 | def f20( @@ -311,7 +311,7 @@ PYI011.pyi:106:18: PYI011 [*] Only simple default values allowed for typed argum | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 103 103 | + 5, # Error PYI011 Only simple default values allowed for typed arguments 104 104 | ) -> None: ... 105 105 | def f21( @@ -335,7 +335,7 @@ PYI011.pyi:110:18: PYI011 [*] Only simple default values allowed for typed argum | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 107 107 | - 3j, # Error PYI011 Only simple default values allowed for typed arguments 108 108 | ) -> None: ... 109 109 | def f22( @@ -357,7 +357,7 @@ PYI011.pyi:138:16: PYI011 [*] Only simple default values allowed for typed argum | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 135 135 | x: float = -math.inf, # OK 136 136 | ) -> None: ... 137 137 | def f31( @@ -378,7 +378,7 @@ PYI011.pyi:141:16: PYI011 [*] Only simple default values allowed for typed argum | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 138 138 | x: float = inf, # Error PYI011 Only simple default values allowed for typed arguments 139 139 | ) -> None: ... 140 140 | def f32( @@ -399,7 +399,7 @@ PYI011.pyi:147:16: PYI011 [*] Only simple default values allowed for typed argum | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 144 144 | x: float = math.nan, # OK 145 145 | ) -> None: ... 146 146 | def f34( @@ -422,7 +422,7 @@ PYI011.pyi:150:18: PYI011 [*] Only simple default values allowed for typed argum | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 147 147 | x: float = -math.nan, # Error PYI011 Only simple default values allowed for typed arguments 148 148 | ) -> None: ... 149 149 | def f35( @@ -445,7 +445,7 @@ PYI011.pyi:159:14: PYI011 [*] Only simple default values allowed for typed argum | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 156 156 | ) -> None: ... 157 157 | def f37( 158 158 | *, diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI014_PYI014.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI014_PYI014.pyi.snap index f16400fffca02..d4224facc8b90 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI014_PYI014.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI014_PYI014.pyi.snap @@ -12,7 +12,7 @@ PYI014.pyi:3:7: PYI014 [*] Only simple default values allowed for arguments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 1 1 | def f12( 2 2 | x, 3 |- y=os.pathsep, # Error PYI014 @@ -36,7 +36,7 @@ PYI014.pyi:29:7: PYI014 [*] Only simple default values allowed for arguments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 26 26 | ) -> None: ... 27 27 | def f151(x={1: 2}) -> None: ... 28 28 | def f152( @@ -73,7 +73,7 @@ PYI014.pyi:35:7: PYI014 [*] Only simple default values allowed for arguments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 32 32 | } 33 33 | ) -> None: ... 34 34 | def f153( @@ -110,7 +110,7 @@ PYI014.pyi:50:7: PYI014 [*] Only simple default values allowed for arguments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 47 47 | ] 48 48 | ) -> None: ... 49 49 | def f154( @@ -134,7 +134,7 @@ PYI014.pyi:56:7: PYI014 [*] Only simple default values allowed for arguments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 53 53 | ) 54 54 | ) -> None: ... 55 55 | def f141( @@ -155,7 +155,7 @@ PYI014.pyi:59:7: PYI014 [*] Only simple default values allowed for arguments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 56 56 | x=[*range(10)], # Error PYI014 57 57 | ) -> None: ... 58 58 | def f142( @@ -176,7 +176,7 @@ PYI014.pyi:61:11: PYI014 [*] Only simple default values allowed for arguments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 58 58 | def f142( 59 59 | x=list(range(10)), # Error PYI014 60 60 | ) -> None: ... @@ -197,7 +197,7 @@ PYI014.pyi:63:7: PYI014 [*] Only simple default values allowed for arguments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 60 60 | ) -> None: ... 61 61 | def f16(x=frozenset({b"foo", b"bar", b"baz"})) -> None: ... # Error PYI014 62 62 | def f17( @@ -218,7 +218,7 @@ PYI014.pyi:66:7: PYI014 [*] Only simple default values allowed for arguments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 63 63 | x="foo" + "bar", # Error PYI014 64 64 | ) -> None: ... 65 65 | def f18( @@ -239,7 +239,7 @@ PYI014.pyi:69:7: PYI014 [*] Only simple default values allowed for arguments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 66 66 | x=b"foo" + b"bar", # Error PYI014 67 67 | ) -> None: ... 68 68 | def f19( @@ -260,7 +260,7 @@ PYI014.pyi:72:7: PYI014 [*] Only simple default values allowed for arguments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 69 69 | x="foo" + 4, # Error PYI014 70 70 | ) -> None: ... 71 71 | def f20( @@ -281,7 +281,7 @@ PYI014.pyi:75:7: PYI014 [*] Only simple default values allowed for arguments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 72 72 | x=5 + 5, # Error PYI014 73 73 | ) -> None: ... 74 74 | def f21( @@ -302,7 +302,7 @@ PYI014.pyi:78:7: PYI014 [*] Only simple default values allowed for arguments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 75 75 | x=3j - 3j, # Error PYI014 76 76 | ) -> None: ... 77 77 | def f22( diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI015_PYI015.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI015_PYI015.pyi.snap index a083c72f1b07e..3cf50bdee43c5 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI015_PYI015.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI015_PYI015.pyi.snap @@ -11,7 +11,7 @@ PYI015.pyi:44:23: PYI015 [*] Only simple default values allowed for assignments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 41 41 | field22: Final = {"foo": 5} 42 42 | 43 43 | # We *should* emit Y015 for more complex default values @@ -32,7 +32,7 @@ PYI015.pyi:45:23: PYI015 [*] Only simple default values allowed for assignments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 42 42 | 43 43 | # We *should* emit Y015 for more complex default values 44 44 | field221: list[int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] # Y015 Only simple default values are allowed for assignments @@ -53,7 +53,7 @@ PYI015.pyi:46:23: PYI015 [*] Only simple default values allowed for assignments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 43 43 | # We *should* emit Y015 for more complex default values 44 44 | field221: list[int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] # Y015 Only simple default values are allowed for assignments 45 45 | field223: list[int] = [*range(10)] # Y015 Only simple default values are allowed for assignments @@ -74,7 +74,7 @@ PYI015.pyi:47:26: PYI015 [*] Only simple default values allowed for assignments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 44 44 | field221: list[int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] # Y015 Only simple default values are allowed for assignments 45 45 | field223: list[int] = [*range(10)] # Y015 Only simple default values are allowed for assignments 46 46 | field224: list[int] = list(range(10)) # Y015 Only simple default values are allowed for assignments @@ -95,7 +95,7 @@ PYI015.pyi:48:47: PYI015 [*] Only simple default values allowed for assignments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 45 45 | field223: list[int] = [*range(10)] # Y015 Only simple default values are allowed for assignments 46 46 | field224: list[int] = list(range(10)) # Y015 Only simple default values are allowed for assignments 47 47 | field225: list[object] = [{}, 1, 2] # Y015 Only simple default values are allowed for assignments @@ -116,7 +116,7 @@ PYI015.pyi:49:31: PYI015 [*] Only simple default values allowed for assignments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 46 46 | field224: list[int] = list(range(10)) # Y015 Only simple default values are allowed for assignments 47 47 | field225: list[object] = [{}, 1, 2] # Y015 Only simple default values are allowed for assignments 48 48 | field226: tuple[str | tuple[str, ...], ...] = ("foo", ("foo", "bar")) # Y015 Only simple default values are allowed for assignments @@ -137,7 +137,7 @@ PYI015.pyi:50:37: PYI015 [*] Only simple default values allowed for assignments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 47 47 | field225: list[object] = [{}, 1, 2] # Y015 Only simple default values are allowed for assignments 48 48 | field226: tuple[str | tuple[str, ...], ...] = ("foo", ("foo", "bar")) # Y015 Only simple default values are allowed for assignments 49 49 | field227: dict[str, object] = {"foo": {"foo": "bar"}} # Y015 Only simple default values are allowed for assignments @@ -158,7 +158,7 @@ PYI015.pyi:52:28: PYI015 [*] Only simple default values allowed for assignments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 49 49 | field227: dict[str, object] = {"foo": {"foo": "bar"}} # Y015 Only simple default values are allowed for assignments 50 50 | field228: dict[str, list[object]] = {"foo": []} # Y015 Only simple default values are allowed for assignments 51 51 | # When parsed, this case results in `None` being placed in the `.keys` list for the `ast.Dict` node @@ -179,7 +179,7 @@ PYI015.pyi:53:11: PYI015 [*] Only simple default values allowed for assignments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 50 50 | field228: dict[str, list[object]] = {"foo": []} # Y015 Only simple default values are allowed for assignments 51 51 | # When parsed, this case results in `None` being placed in the `.keys` list for the `ast.Dict` node 52 52 | field229: dict[int, int] = {1: 2, **{3: 4}} # Y015 Only simple default values are allowed for assignments @@ -199,7 +199,7 @@ PYI015.pyi:54:11: PYI015 [*] Only simple default values allowed for assignments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 51 51 | # When parsed, this case results in `None` being placed in the `.keys` list for the `ast.Dict` node 52 52 | field229: dict[int, int] = {1: 2, **{3: 4}} # Y015 Only simple default values are allowed for assignments 53 53 | field23 = "foo" + "bar" # Y015 Only simple default values are allowed for assignments @@ -220,7 +220,7 @@ PYI015.pyi:55:11: PYI015 [*] Only simple default values allowed for assignments | = help: Replace default value with `...` -ℹ Suggested fix +ℹ Fix 52 52 | field229: dict[int, int] = {1: 2, **{3: 4}} # Y015 Only simple default values are allowed for assignments 53 53 | field23 = "foo" + "bar" # Y015 Only simple default values are allowed for assignments 54 54 | field24 = b"foo" + b"bar" # Y015 Only simple default values are allowed for assignments diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI026_PYI026.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI026_PYI026.pyi.snap index b4c117f2ecf49..4136a0a8ba56a 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI026_PYI026.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI026_PYI026.pyi.snap @@ -12,7 +12,7 @@ PYI026.pyi:3:1: PYI026 [*] Use `typing.TypeAlias` for type alias, e.g., `NewAny: | = help: Add `TypeAlias` annotation -ℹ Suggested fix +ℹ Fix 1 |-from typing import Literal, Any 1 |+from typing import Literal, Any, TypeAlias 2 2 | @@ -32,7 +32,7 @@ PYI026.pyi:4:1: PYI026 [*] Use `typing.TypeAlias` for type alias, e.g., `Optiona | = help: Add `TypeAlias` annotation -ℹ Suggested fix +ℹ Fix 1 |-from typing import Literal, Any 1 |+from typing import Literal, Any, TypeAlias 2 2 | @@ -54,7 +54,7 @@ PYI026.pyi:5:1: PYI026 [*] Use `typing.TypeAlias` for type alias, e.g., `Foo: Ty | = help: Add `TypeAlias` annotation -ℹ Suggested fix +ℹ Fix 1 |-from typing import Literal, Any 1 |+from typing import Literal, Any, TypeAlias 2 2 | @@ -76,7 +76,7 @@ PYI026.pyi:6:1: PYI026 [*] Use `typing.TypeAlias` for type alias, e.g., `IntOrSt | = help: Add `TypeAlias` annotation -ℹ Suggested fix +ℹ Fix 1 |-from typing import Literal, Any 1 |+from typing import Literal, Any, TypeAlias 2 2 | @@ -100,7 +100,7 @@ PYI026.pyi:7:1: PYI026 [*] Use `typing.TypeAlias` for type alias, e.g., `AliasNo | = help: Add `TypeAlias` annotation -ℹ Suggested fix +ℹ Fix 1 |-from typing import Literal, Any 1 |+from typing import Literal, Any, TypeAlias 2 2 | diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI053_PYI053.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI053_PYI053.pyi.snap index 5b9f3aa1a1332..6c1a2c40d481c 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI053_PYI053.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI053_PYI053.pyi.snap @@ -12,7 +12,7 @@ PYI053.pyi:3:14: PYI053 [*] String and bytes literals longer than 50 characters | = help: Replace with `...` -ℹ Suggested fix +ℹ Fix 1 1 | def f1(x: str = "50 character stringggggggggggggggggggggggggggggggg") -> None: ... # OK 2 2 | def f2( 3 |- x: str = "51 character stringgggggggggggggggggggggggggggggggg", # Error: PYI053 @@ -32,7 +32,7 @@ PYI053.pyi:9:14: PYI053 [*] String and bytes literals longer than 50 characters | = help: Replace with `...` -ℹ Suggested fix +ℹ Fix 6 6 | x: str = "50 character stringgggggggggggggggggggggggggggggg\U0001f600", # OK 7 7 | ) -> None: ... 8 8 | def f4( @@ -52,7 +52,7 @@ PYI053.pyi:21:16: PYI053 [*] String and bytes literals longer than 50 characters | = help: Replace with `...` -ℹ Suggested fix +ℹ Fix 18 18 | x: bytes = b"50 character byte stringggggggggggggggggggggggggg\xff", # OK 19 19 | ) -> None: ... 20 20 | def f8( @@ -73,7 +73,7 @@ PYI053.pyi:26:12: PYI053 [*] String and bytes literals longer than 50 characters | = help: Replace with `...` -ℹ Suggested fix +ℹ Fix 23 23 | 24 24 | foo: str = "50 character stringggggggggggggggggggggggggggggggg" # OK 25 25 | @@ -94,7 +94,7 @@ PYI053.pyi:30:14: PYI053 [*] String and bytes literals longer than 50 characters | = help: Replace with `...` -ℹ Suggested fix +ℹ Fix 27 27 | 28 28 | baz: bytes = b"50 character byte stringgggggggggggggggggggggggggg" # OK 29 29 | diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI054_PYI054.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI054_PYI054.pyi.snap index 7db8611cad8e8..bcd68892901ae 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI054_PYI054.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI054_PYI054.pyi.snap @@ -11,7 +11,7 @@ PYI054.pyi:2:16: PYI054 [*] Numeric literals with a string representation longer | = help: Replace with `...` -ℹ Suggested fix +ℹ Fix 1 1 | field01: int = 0xFFFFFFFF 2 |-field02: int = 0xFFFFFFFFF # Error: PYI054 2 |+field02: int = ... # Error: PYI054 @@ -30,7 +30,7 @@ PYI054.pyi:4:17: PYI054 [*] Numeric literals with a string representation longer | = help: Replace with `...` -ℹ Suggested fix +ℹ Fix 1 1 | field01: int = 0xFFFFFFFF 2 2 | field02: int = 0xFFFFFFFFF # Error: PYI054 3 3 | field03: int = -0xFFFFFFFF @@ -51,7 +51,7 @@ PYI054.pyi:8:16: PYI054 [*] Numeric literals with a string representation longer | = help: Replace with `...` -ℹ Suggested fix +ℹ Fix 5 5 | 6 6 | field05: int = 1234567890 7 7 | field06: int = 12_456_890 @@ -72,7 +72,7 @@ PYI054.pyi:10:17: PYI054 [*] Numeric literals with a string representation longe | = help: Replace with `...` -ℹ Suggested fix +ℹ Fix 7 7 | field06: int = 12_456_890 8 8 | field07: int = 12345678901 # Error: PYI054 9 9 | field08: int = -1234567801 @@ -92,7 +92,7 @@ PYI054.pyi:13:18: PYI054 [*] Numeric literals with a string representation longe | = help: Replace with `...` -ℹ Suggested fix +ℹ Fix 10 10 | field09: int = -234_567_890 # Error: PYI054 11 11 | 12 12 | field10: float = 123.456789 @@ -113,7 +113,7 @@ PYI054.pyi:15:19: PYI054 [*] Numeric literals with a string representation longe | = help: Replace with `...` -ℹ Suggested fix +ℹ Fix 12 12 | field10: float = 123.456789 13 13 | field11: float = 123.4567890 # Error: PYI054 14 14 | field12: float = -123.456789 @@ -133,7 +133,7 @@ PYI054.pyi:18:20: PYI054 [*] Numeric literals with a string representation longe | = help: Replace with `...` -ℹ Suggested fix +ℹ Fix 15 15 | field13: float = -123.567_890 # Error: PYI054 16 16 | 17 17 | field14: complex = 1e1234567j @@ -151,7 +151,7 @@ PYI054.pyi:20:20: PYI054 [*] Numeric literals with a string representation longe | = help: Replace with `...` -ℹ Suggested fix +ℹ Fix 17 17 | field14: complex = 1e1234567j 18 18 | field15: complex = 1e12345678j # Error: PYI054 19 19 | field16: complex = -1e1234567j diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI055_PYI055.py.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI055_PYI055.py.snap index 8addf09918645..691a671b4e7bc 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI055_PYI055.py.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI055_PYI055.py.snap @@ -1,12 +1,58 @@ --- source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs --- -PYI055.py:31:11: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[requests_mock.Mocker | httpretty]`. +PYI055.py:31:8: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[requests_mock.Mocker | httpretty | str]`. | 29 | def func(): 30 | # PYI055 -31 | item: type[requests_mock.Mocker] | type[httpretty] = requests_mock.Mocker - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 +31 | x: type[requests_mock.Mocker] | type[httpretty] | type[str] = requests_mock.Mocker + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 +32 | y: Union[type[requests_mock.Mocker], type[httpretty], type[str]] = requests_mock.Mocker | + = help: Combine multiple `type` members + +ℹ Fix +28 28 | +29 29 | def func(): +30 30 | # PYI055 +31 |- x: type[requests_mock.Mocker] | type[httpretty] | type[str] = requests_mock.Mocker + 31 |+ x: type[requests_mock.Mocker | httpretty | str] = requests_mock.Mocker +32 32 | y: Union[type[requests_mock.Mocker], type[httpretty], type[str]] = requests_mock.Mocker +33 33 | +34 34 | + +PYI055.py:32:8: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[Union[requests_mock.Mocker, httpretty, str]]`. + | +30 | # PYI055 +31 | x: type[requests_mock.Mocker] | type[httpretty] | type[str] = requests_mock.Mocker +32 | y: Union[type[requests_mock.Mocker], type[httpretty], type[str]] = requests_mock.Mocker + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 + | + = help: Combine multiple `type` members + +ℹ Fix +29 29 | def func(): +30 30 | # PYI055 +31 31 | x: type[requests_mock.Mocker] | type[httpretty] | type[str] = requests_mock.Mocker +32 |- y: Union[type[requests_mock.Mocker], type[httpretty], type[str]] = requests_mock.Mocker + 32 |+ y: type[Union[requests_mock.Mocker, httpretty, str]] = requests_mock.Mocker +33 33 | +34 34 | +35 35 | def func(): + +PYI055.py:39:8: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[Union[requests_mock.Mocker, httpretty, str]]`. + | +38 | # PYI055 +39 | x: Union[type[requests_mock.Mocker], type[httpretty], type[str]] = requests_mock.Mocker + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 + | + = help: Combine multiple `type` members + +ℹ Fix +36 36 | from typing import Union as U +37 37 | +38 38 | # PYI055 +39 |- x: Union[type[requests_mock.Mocker], type[httpretty], type[str]] = requests_mock.Mocker + 39 |+ x: type[Union[requests_mock.Mocker, httpretty, str]] = requests_mock.Mocker diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI055_PYI055.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI055_PYI055.pyi.snap index f28020e40050f..c8fc0694eaff5 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI055_PYI055.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__PYI055_PYI055.pyi.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs --- -PYI055.pyi:4:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | complex]`. +PYI055.pyi:4:4: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | complex]`. | 2 | from typing import Union 3 | @@ -10,8 +10,19 @@ PYI055.pyi:4:4: PYI055 Multiple `type` members in a union. Combine them into one 5 | x: type[int] | type[str] | type[float] 6 | y: builtins.type[int] | type[str] | builtins.type[complex] | + = help: Combine multiple `type` members -PYI055.pyi:5:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | float]`. +ℹ Fix +1 1 | import builtins +2 2 | from typing import Union +3 3 | +4 |-w: builtins.type[int] | builtins.type[str] | builtins.type[complex] + 4 |+w: type[int | str | complex] +5 5 | x: type[int] | type[str] | type[float] +6 6 | y: builtins.type[int] | type[str] | builtins.type[complex] +7 7 | z: Union[type[float], type[complex]] + +PYI055.pyi:5:4: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | float]`. | 4 | w: builtins.type[int] | builtins.type[str] | builtins.type[complex] 5 | x: type[int] | type[str] | type[float] @@ -19,8 +30,19 @@ PYI055.pyi:5:4: PYI055 Multiple `type` members in a union. Combine them into one 6 | y: builtins.type[int] | type[str] | builtins.type[complex] 7 | z: Union[type[float], type[complex]] | + = help: Combine multiple `type` members + +ℹ Fix +2 2 | from typing import Union +3 3 | +4 4 | w: builtins.type[int] | builtins.type[str] | builtins.type[complex] +5 |-x: type[int] | type[str] | type[float] + 5 |+x: type[int | str | float] +6 6 | y: builtins.type[int] | type[str] | builtins.type[complex] +7 7 | z: Union[type[float], type[complex]] +8 8 | z: Union[type[float, int], type[complex]] -PYI055.pyi:6:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | complex]`. +PYI055.pyi:6:4: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | complex]`. | 4 | w: builtins.type[int] | builtins.type[str] | builtins.type[complex] 5 | x: type[int] | type[str] | type[float] @@ -29,8 +51,19 @@ PYI055.pyi:6:4: PYI055 Multiple `type` members in a union. Combine them into one 7 | z: Union[type[float], type[complex]] 8 | z: Union[type[float, int], type[complex]] | + = help: Combine multiple `type` members -PYI055.pyi:7:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[Union[float, complex]]`. +ℹ Fix +3 3 | +4 4 | w: builtins.type[int] | builtins.type[str] | builtins.type[complex] +5 5 | x: type[int] | type[str] | type[float] +6 |-y: builtins.type[int] | type[str] | builtins.type[complex] + 6 |+y: type[int | str | complex] +7 7 | z: Union[type[float], type[complex]] +8 8 | z: Union[type[float, int], type[complex]] +9 9 | + +PYI055.pyi:7:4: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[Union[float, complex]]`. | 5 | x: type[int] | type[str] | type[float] 6 | y: builtins.type[int] | type[str] | builtins.type[complex] @@ -38,8 +71,19 @@ PYI055.pyi:7:4: PYI055 Multiple `type` members in a union. Combine them into one | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 8 | z: Union[type[float, int], type[complex]] | + = help: Combine multiple `type` members + +ℹ Fix +4 4 | w: builtins.type[int] | builtins.type[str] | builtins.type[complex] +5 5 | x: type[int] | type[str] | type[float] +6 6 | y: builtins.type[int] | type[str] | builtins.type[complex] +7 |-z: Union[type[float], type[complex]] + 7 |+z: type[Union[float, complex]] +8 8 | z: Union[type[float, int], type[complex]] +9 9 | +10 10 | def func(arg: type[int] | str | type[float]) -> None: ... -PYI055.pyi:8:4: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[Union[float, int, complex]]`. +PYI055.pyi:8:4: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[Union[float, int, complex]]`. | 6 | y: builtins.type[int] | type[str] | builtins.type[complex] 7 | z: Union[type[float], type[complex]] @@ -48,8 +92,19 @@ PYI055.pyi:8:4: PYI055 Multiple `type` members in a union. Combine them into one 9 | 10 | def func(arg: type[int] | str | type[float]) -> None: ... | + = help: Combine multiple `type` members -PYI055.pyi:10:15: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[int | float]`. +ℹ Fix +5 5 | x: type[int] | type[str] | type[float] +6 6 | y: builtins.type[int] | type[str] | builtins.type[complex] +7 7 | z: Union[type[float], type[complex]] +8 |-z: Union[type[float, int], type[complex]] + 8 |+z: type[Union[float, int, complex]] +9 9 | +10 10 | def func(arg: type[int] | str | type[float]) -> None: ... +11 11 | + +PYI055.pyi:10:15: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[int | float]`. | 8 | z: Union[type[float, int], type[complex]] 9 | @@ -58,8 +113,19 @@ PYI055.pyi:10:15: PYI055 Multiple `type` members in a union. Combine them into o 11 | 12 | # OK | + = help: Combine multiple `type` members + +ℹ Fix +7 7 | z: Union[type[float], type[complex]] +8 8 | z: Union[type[float, int], type[complex]] +9 9 | +10 |-def func(arg: type[int] | str | type[float]) -> None: ... + 10 |+def func(arg: type[int | float]) -> None: ... +11 11 | +12 12 | # OK +13 13 | x: type[int, str, float] -PYI055.pyi:20:7: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[requests_mock.Mocker | httpretty]`. +PYI055.pyi:20:7: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[requests_mock.Mocker | httpretty]`. | 19 | # OK 20 | item: type[requests_mock.Mocker] | type[httpretty] = requests_mock.Mocker @@ -67,13 +133,50 @@ PYI055.pyi:20:7: PYI055 Multiple `type` members in a union. Combine them into on 21 | 22 | def func(): | + = help: Combine multiple `type` members + +ℹ Fix +17 17 | def func(arg: type[int, float] | str) -> None: ... +18 18 | +19 19 | # OK +20 |-item: type[requests_mock.Mocker] | type[httpretty] = requests_mock.Mocker + 20 |+item: type[requests_mock.Mocker | httpretty] = requests_mock.Mocker +21 21 | +22 22 | def func(): +23 23 | # PYI055 -PYI055.pyi:24:11: PYI055 Multiple `type` members in a union. Combine them into one, e.g., `type[requests_mock.Mocker | httpretty]`. +PYI055.pyi:24:11: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[requests_mock.Mocker | httpretty | str]`. | 22 | def func(): 23 | # PYI055 -24 | item: type[requests_mock.Mocker] | type[httpretty] = requests_mock.Mocker - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 +24 | item: type[requests_mock.Mocker] | type[httpretty] | type[str] = requests_mock.Mocker + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 +25 | item2: Union[type[requests_mock.Mocker], type[httpretty], type[str]] = requests_mock.Mocker | + = help: Combine multiple `type` members + +ℹ Fix +21 21 | +22 22 | def func(): +23 23 | # PYI055 +24 |- item: type[requests_mock.Mocker] | type[httpretty] | type[str] = requests_mock.Mocker + 24 |+ item: type[requests_mock.Mocker | httpretty | str] = requests_mock.Mocker +25 25 | item2: Union[type[requests_mock.Mocker], type[httpretty], type[str]] = requests_mock.Mocker + +PYI055.pyi:25:12: PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[Union[requests_mock.Mocker, httpretty, str]]`. + | +23 | # PYI055 +24 | item: type[requests_mock.Mocker] | type[httpretty] | type[str] = requests_mock.Mocker +25 | item2: Union[type[requests_mock.Mocker], type[httpretty], type[str]] = requests_mock.Mocker + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI055 + | + = help: Combine multiple `type` members + +ℹ Fix +22 22 | def func(): +23 23 | # PYI055 +24 24 | item: type[requests_mock.Mocker] | type[httpretty] | type[str] = requests_mock.Mocker +25 |- item2: Union[type[requests_mock.Mocker], type[httpretty], type[str]] = requests_mock.Mocker + 25 |+ item2: type[Union[requests_mock.Mocker, httpretty, str]] = requests_mock.Mocker diff --git a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__py38_PYI026_PYI026.pyi.snap b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__py38_PYI026_PYI026.pyi.snap index f8db4ff1b2612..1cfafc1426401 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__py38_PYI026_PYI026.pyi.snap +++ b/crates/ruff_linter/src/rules/flake8_pyi/snapshots/ruff_linter__rules__flake8_pyi__tests__py38_PYI026_PYI026.pyi.snap @@ -12,7 +12,7 @@ PYI026.pyi:3:1: PYI026 [*] Use `typing_extensions.TypeAlias` for type alias, e.g | = help: Add `TypeAlias` annotation -ℹ Suggested fix +ℹ Fix 1 1 | from typing import Literal, Any 2 |+import typing_extensions 2 3 | @@ -32,7 +32,7 @@ PYI026.pyi:4:1: PYI026 [*] Use `typing_extensions.TypeAlias` for type alias, e.g | = help: Add `TypeAlias` annotation -ℹ Suggested fix +ℹ Fix 1 1 | from typing import Literal, Any 2 |+import typing_extensions 2 3 | @@ -54,7 +54,7 @@ PYI026.pyi:5:1: PYI026 [*] Use `typing_extensions.TypeAlias` for type alias, e.g | = help: Add `TypeAlias` annotation -ℹ Suggested fix +ℹ Fix 1 1 | from typing import Literal, Any 2 |+import typing_extensions 2 3 | @@ -76,7 +76,7 @@ PYI026.pyi:6:1: PYI026 [*] Use `typing_extensions.TypeAlias` for type alias, e.g | = help: Add `TypeAlias` annotation -ℹ Suggested fix +ℹ Fix 1 1 | from typing import Literal, Any 2 |+import typing_extensions 2 3 | @@ -100,7 +100,7 @@ PYI026.pyi:7:1: PYI026 [*] Use `typing_extensions.TypeAlias` for type alias, e.g | = help: Add `TypeAlias` annotation -ℹ Suggested fix +ℹ Fix 1 1 | from typing import Literal, Any 2 |+import typing_extensions 2 3 | diff --git a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/assertion.rs b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/assertion.rs index b3de92653322d..1ccc208298a52 100644 --- a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/assertion.rs +++ b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/assertion.rs @@ -7,7 +7,7 @@ use libcst_native::{ SimpleWhitespace, SmallStatement, Statement, TrailingWhitespace, }; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::Truthiness; use ruff_python_ast::parenthesize::parenthesized_range; @@ -20,13 +20,12 @@ use ruff_python_codegen::Stylist; use ruff_source_file::Locator; use ruff_text_size::Ranged; -use crate::autofix::codemods::CodegenStylist; use crate::checkers::ast::Checker; use crate::cst::helpers::negate; use crate::cst::matchers::match_indented_block; use crate::cst::matchers::match_module; +use crate::fix::codemods::CodegenStylist; use crate::importer::ImportRequest; -use crate::registry::AsRule; use super::unittest_assert::UnittestAssert; @@ -62,14 +61,14 @@ use super::unittest_assert::UnittestAssert; pub struct PytestCompositeAssertion; impl Violation for PytestCompositeAssertion { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Assertion should be broken down into multiple parts") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Break down assertion into multiple parts".to_string()) } } @@ -192,7 +191,7 @@ pub struct PytestUnittestAssertion { } impl Violation for PytestUnittestAssertion { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -200,7 +199,7 @@ impl Violation for PytestUnittestAssertion { format!("Use a regular `assert` instead of unittest-style `{assertion}`") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let PytestUnittestAssertion { assertion } = self; Some(format!("Replace `{assertion}(...)` with `assert ...`")) } @@ -284,25 +283,23 @@ pub(crate) fn unittest_assertion( }, func.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // We're converting an expression to a statement, so avoid applying the fix if - // the assertion is part of a larger expression. - if checker.semantic().current_statement().is_expr_stmt() - && checker.semantic().current_expression_parent().is_none() - && !checker.indexer().comment_ranges().intersects(expr.range()) - { - if let Ok(stmt) = unittest_assert.generate_assert(args, keywords) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.generator().stmt(&stmt), - parenthesized_range( - expr.into(), - checker.semantic().current_statement().into(), - checker.indexer().comment_ranges(), - checker.locator().contents(), - ) - .unwrap_or(expr.range()), - ))); - } + // We're converting an expression to a statement, so avoid applying the fix if + // the assertion is part of a larger expression. + if checker.semantic().current_statement().is_expr_stmt() + && checker.semantic().current_expression_parent().is_none() + && !checker.indexer().comment_ranges().intersects(expr.range()) + { + if let Ok(stmt) = unittest_assert.generate_assert(args, keywords) { + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + checker.generator().stmt(&stmt), + parenthesized_range( + expr.into(), + checker.semantic().current_statement().into(), + checker.indexer().comment_ranges(), + checker.locator().contents(), + ) + .unwrap_or(expr.range()), + ))); } } Some(diagnostic) @@ -354,7 +351,7 @@ pub struct PytestUnittestRaisesAssertion { } impl Violation for PytestUnittestRaisesAssertion { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -362,7 +359,7 @@ impl Violation for PytestUnittestRaisesAssertion { format!("Use `pytest.raises` instead of unittest-style `{assertion}`") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let PytestUnittestRaisesAssertion { assertion } = self; Some(format!("Replace `{assertion}` with `pytest.raises`")) } @@ -390,9 +387,7 @@ pub(crate) fn unittest_raises_assertion( }, call.func.range(), ); - if checker.patch(diagnostic.kind.rule()) - && !checker.indexer().has_comments(call, checker.locator()) - { + if !checker.indexer().has_comments(call, checker.locator()) { if let Some(args) = to_pytest_raises_args(checker, attr.as_str(), &call.arguments) { diagnostic.try_set_fix(|| { let (import_edit, binding) = checker.importer().get_or_import_symbol( @@ -401,7 +396,7 @@ pub(crate) fn unittest_raises_assertion( checker.semantic(), )?; let edit = Edit::range_replacement(format!("{binding}({args})"), call.range()); - Ok(Fix::suggested_edits(import_edit, [edit])) + Ok(Fix::unsafe_edits(import_edit, [edit])) }); } } @@ -746,19 +741,17 @@ pub(crate) fn composite_condition( let composite = is_composite_condition(test); if matches!(composite, CompositionKind::Simple | CompositionKind::Mixed) { let mut diagnostic = Diagnostic::new(PytestCompositeAssertion, stmt.range()); - if checker.patch(diagnostic.kind.rule()) { - if matches!(composite, CompositionKind::Simple) - && msg.is_none() - && !checker.indexer().comment_ranges().intersects(stmt.range()) - && !checker - .indexer() - .in_multi_statement_line(stmt, checker.locator()) - { - diagnostic.try_set_fix(|| { - fix_composite_condition(stmt, checker.locator(), checker.stylist()) - .map(Fix::suggested) - }); - } + if matches!(composite, CompositionKind::Simple) + && msg.is_none() + && !checker.indexer().comment_ranges().intersects(stmt.range()) + && !checker + .indexer() + .in_multi_statement_line(stmt, checker.locator()) + { + diagnostic.try_set_fix(|| { + fix_composite_condition(stmt, checker.locator(), checker.stylist()) + .map(Fix::unsafe_edit) + }); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/fixture.rs b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/fixture.rs index b3374ba07ee5d..5918dfd02718f 100644 --- a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/fixture.rs +++ b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/fixture.rs @@ -1,6 +1,6 @@ use std::fmt; -use ruff_diagnostics::{AlwaysAutofixableViolation, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Violation}; use ruff_diagnostics::{Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::call_path::collect_call_path; @@ -14,9 +14,9 @@ use ruff_python_semantic::SemanticModel; use ruff_text_size::Ranged; use ruff_text_size::{TextLen, TextRange}; -use crate::autofix::edits; use crate::checkers::ast::Checker; -use crate::registry::{AsRule, Rule}; +use crate::fix::edits; +use crate::registry::Rule; use super::helpers::{ get_mark_decorators, is_pytest_fixture, is_pytest_yield_fixture, keyword_is_literal, @@ -28,7 +28,7 @@ use super::helpers::{ /// setting. /// /// ## Why is this bad? -/// If a `@pytext.fixture()` doesn't take any arguments, the parentheses are +/// If a `@pytest.fixture()` doesn't take any arguments, the parentheses are /// optional. /// /// Either removing those unnecessary parentheses _or_ requiring them for all @@ -65,14 +65,14 @@ pub struct PytestFixtureIncorrectParenthesesStyle { actual: Parentheses, } -impl AlwaysAutofixableViolation for PytestFixtureIncorrectParenthesesStyle { +impl AlwaysFixableViolation for PytestFixtureIncorrectParenthesesStyle { #[derive_message_formats] fn message(&self) -> String { let PytestFixtureIncorrectParenthesesStyle { expected, actual } = self; format!("Use `@pytest.fixture{expected}` over `@pytest.fixture{actual}`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let PytestFixtureIncorrectParenthesesStyle { expected, .. } = self; match expected { Parentheses::None => "Remove parentheses".to_string(), @@ -154,13 +154,13 @@ impl Violation for PytestFixturePositionalArgs { #[violation] pub struct PytestExtraneousScopeFunction; -impl AlwaysAutofixableViolation for PytestExtraneousScopeFunction { +impl AlwaysFixableViolation for PytestExtraneousScopeFunction { #[derive_message_formats] fn message(&self) -> String { format!("`scope='function'` is implied in `@pytest.fixture()`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove implied `scope` argument".to_string() } } @@ -488,14 +488,14 @@ pub struct PytestUselessYieldFixture { name: String, } -impl AlwaysAutofixableViolation for PytestUselessYieldFixture { +impl AlwaysFixableViolation for PytestUselessYieldFixture { #[derive_message_formats] fn message(&self) -> String { let PytestUselessYieldFixture { name } = self; format!("No teardown in fixture `{name}`, use `return` instead of `yield`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace `yield` with `return`".to_string() } } @@ -543,13 +543,13 @@ impl AlwaysAutofixableViolation for PytestUselessYieldFixture { #[violation] pub struct PytestErroneousUseFixturesOnFixture; -impl AlwaysAutofixableViolation for PytestErroneousUseFixturesOnFixture { +impl AlwaysFixableViolation for PytestErroneousUseFixturesOnFixture { #[derive_message_formats] fn message(&self) -> String { format!("`pytest.mark.usefixtures` has no effect on fixtures") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove `pytest.mark.usefixtures`".to_string() } } @@ -586,13 +586,13 @@ impl AlwaysAutofixableViolation for PytestErroneousUseFixturesOnFixture { #[violation] pub struct PytestUnnecessaryAsyncioMarkOnFixture; -impl AlwaysAutofixableViolation for PytestUnnecessaryAsyncioMarkOnFixture { +impl AlwaysFixableViolation for PytestUnnecessaryAsyncioMarkOnFixture { #[derive_message_formats] fn message(&self) -> String { format!("`pytest.mark.asyncio` is unnecessary for fixtures") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove `pytest.mark.asyncio`".to_string() } } @@ -681,9 +681,7 @@ fn pytest_fixture_parentheses( PytestFixtureIncorrectParenthesesStyle { expected, actual }, decorator.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(fix); - } + diagnostic.set_fix(fix); checker.diagnostics.push(diagnostic); } @@ -700,7 +698,7 @@ fn check_fixture_decorator(checker: &mut Checker, func_name: &str, decorator: &D && arguments.args.is_empty() && arguments.keywords.is_empty() { - let fix = Fix::automatic(Edit::deletion(func.end(), decorator.end())); + let fix = Fix::safe_edit(Edit::deletion(func.end(), decorator.end())); pytest_fixture_parentheses( checker, decorator, @@ -727,17 +725,15 @@ fn check_fixture_decorator(checker: &mut Checker, func_name: &str, decorator: &D if keyword_is_literal(keyword, "function") { let mut diagnostic = Diagnostic::new(PytestExtraneousScopeFunction, keyword.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - edits::remove_argument( - keyword, - arguments, - edits::Parentheses::Preserve, - checker.locator().contents(), - ) - .map(Fix::suggested) - }); - } + diagnostic.try_set_fix(|| { + edits::remove_argument( + keyword, + arguments, + edits::Parentheses::Preserve, + checker.locator().contents(), + ) + .map(Fix::unsafe_edit) + }); checker.diagnostics.push(diagnostic); } } @@ -746,7 +742,7 @@ fn check_fixture_decorator(checker: &mut Checker, func_name: &str, decorator: &D _ => { if checker.enabled(Rule::PytestFixtureIncorrectParenthesesStyle) { if checker.settings.flake8_pytest_style.fixture_parentheses { - let fix = Fix::automatic(Edit::insertion( + let fix = Fix::safe_edit(Edit::insertion( Parentheses::Empty.to_string(), decorator.end(), )); @@ -819,30 +815,28 @@ fn check_fixture_returns( }, stmt.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let yield_edit = Edit::range_replacement( - "return".to_string(), - TextRange::at(stmt.start(), "yield".text_len()), - ); - let return_type_edit = returns.and_then(|returns| { - let ast::ExprSubscript { value, slice, .. } = returns.as_subscript_expr()?; - let ast::ExprTuple { elts, .. } = slice.as_tuple_expr()?; - let [first, ..] = elts.as_slice() else { - return None; - }; - if !checker.semantic().match_typing_expr(value, "Generator") { - return None; - } - Some(Edit::range_replacement( - checker.generator().expr(first), - returns.range(), - )) - }); - if let Some(return_type_edit) = return_type_edit { - diagnostic.set_fix(Fix::automatic_edits(yield_edit, [return_type_edit])); - } else { - diagnostic.set_fix(Fix::automatic(yield_edit)); + let yield_edit = Edit::range_replacement( + "return".to_string(), + TextRange::at(stmt.start(), "yield".text_len()), + ); + let return_type_edit = returns.and_then(|returns| { + let ast::ExprSubscript { value, slice, .. } = returns.as_subscript_expr()?; + let ast::ExprTuple { elts, .. } = slice.as_tuple_expr()?; + let [first, ..] = elts.as_slice() else { + return None; + }; + if !checker.semantic().match_typing_expr(value, "Generator") { + return None; } + Some(Edit::range_replacement( + checker.generator().expr(first), + returns.range(), + )) + }); + if let Some(return_type_edit) = return_type_edit { + diagnostic.set_fix(Fix::safe_edits(yield_edit, [return_type_edit])); + } else { + diagnostic.set_fix(Fix::safe_edit(yield_edit)); } checker.diagnostics.push(diagnostic); } @@ -906,28 +900,23 @@ fn check_fixture_addfinalizer(checker: &mut Checker, parameters: &Parameters, bo /// PT024, PT025 fn check_fixture_marks(checker: &mut Checker, decorators: &[Decorator]) { - for (expr, call_path) in get_mark_decorators(decorators) { - let name = call_path.last().expect("Expected a mark name"); + for (expr, marker) in get_mark_decorators(decorators) { if checker.enabled(Rule::PytestUnnecessaryAsyncioMarkOnFixture) { - if *name == "asyncio" { + if marker == "asyncio" { let mut diagnostic = Diagnostic::new(PytestUnnecessaryAsyncioMarkOnFixture, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - let range = checker.locator().full_lines_range(expr.range()); - diagnostic.set_fix(Fix::automatic(Edit::range_deletion(range))); - } + let range = checker.locator().full_lines_range(expr.range()); + diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(range))); checker.diagnostics.push(diagnostic); } } if checker.enabled(Rule::PytestErroneousUseFixturesOnFixture) { - if *name == "usefixtures" { + if marker == "usefixtures" { let mut diagnostic = Diagnostic::new(PytestErroneousUseFixturesOnFixture, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - let line_range = checker.locator().full_lines_range(expr.range()); - diagnostic.set_fix(Fix::automatic(Edit::range_deletion(line_range))); - } + let line_range = checker.locator().full_lines_range(expr.range()); + diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(line_range))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/helpers.rs b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/helpers.rs index 43a183267fa78..43c066ff65e00 100644 --- a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/helpers.rs +++ b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/helpers.rs @@ -1,22 +1,21 @@ use ruff_python_ast::{self as ast, Constant, Decorator, Expr, Keyword}; -use ruff_python_ast::call_path::{collect_call_path, CallPath}; +use ruff_python_ast::call_path::collect_call_path; use ruff_python_ast::helpers::map_callable; use ruff_python_semantic::SemanticModel; use ruff_python_trivia::PythonWhitespace; pub(super) fn get_mark_decorators( decorators: &[Decorator], -) -> impl Iterator { +) -> impl Iterator { decorators.iter().filter_map(|decorator| { let Some(call_path) = collect_call_path(map_callable(&decorator.expression)) else { return None; }; - if call_path.len() > 2 && call_path.as_slice()[..2] == ["pytest", "mark"] { - Some((decorator, call_path)) - } else { - None - } + let ["pytest", "mark", marker] = call_path.as_slice() else { + return None; + }; + Some((decorator, *marker)) }) } diff --git a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/marks.rs b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/marks.rs index 01a3d3fc60da4..0be4eb4d508c8 100644 --- a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/marks.rs +++ b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/marks.rs @@ -1,12 +1,11 @@ use ruff_python_ast::{self as ast, Arguments, Decorator, Expr}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::call_path::CallPath; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::{AsRule, Rule}; +use crate::registry::Rule; use super::helpers::get_mark_decorators; @@ -54,7 +53,7 @@ pub struct PytestIncorrectMarkParenthesesStyle { actual_parens: String, } -impl AlwaysAutofixableViolation for PytestIncorrectMarkParenthesesStyle { +impl AlwaysFixableViolation for PytestIncorrectMarkParenthesesStyle { #[derive_message_formats] fn message(&self) -> String { let PytestIncorrectMarkParenthesesStyle { @@ -68,7 +67,7 @@ impl AlwaysAutofixableViolation for PytestIncorrectMarkParenthesesStyle { ) } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Add/remove parentheses".to_string() } } @@ -103,13 +102,13 @@ impl AlwaysAutofixableViolation for PytestIncorrectMarkParenthesesStyle { #[violation] pub struct PytestUseFixturesWithoutParameters; -impl AlwaysAutofixableViolation for PytestUseFixturesWithoutParameters { +impl AlwaysFixableViolation for PytestUseFixturesWithoutParameters { #[derive_message_formats] fn message(&self) -> String { format!("Useless `pytest.mark.usefixtures` without parameters") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove `usefixtures` decorator or pass parameters".to_string() } } @@ -117,26 +116,24 @@ impl AlwaysAutofixableViolation for PytestUseFixturesWithoutParameters { fn pytest_mark_parentheses( checker: &mut Checker, decorator: &Decorator, - call_path: &CallPath, + marker: &str, fix: Fix, preferred: &str, actual: &str, ) { let mut diagnostic = Diagnostic::new( PytestIncorrectMarkParenthesesStyle { - mark_name: (*call_path.last().unwrap()).to_string(), + mark_name: marker.to_string(), expected_parens: preferred.to_string(), actual_parens: actual.to_string(), }, decorator.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(fix); - } + diagnostic.set_fix(fix); checker.diagnostics.push(diagnostic); } -fn check_mark_parentheses(checker: &mut Checker, decorator: &Decorator, call_path: &CallPath) { +fn check_mark_parentheses(checker: &mut Checker, decorator: &Decorator, marker: &str) { match &decorator.expression { Expr::Call(ast::ExprCall { func, @@ -152,55 +149,54 @@ fn check_mark_parentheses(checker: &mut Checker, decorator: &Decorator, call_pat && args.is_empty() && keywords.is_empty() { - let fix = Fix::automatic(Edit::deletion(func.end(), decorator.end())); - pytest_mark_parentheses(checker, decorator, call_path, fix, "", "()"); + let fix = Fix::safe_edit(Edit::deletion(func.end(), decorator.end())); + pytest_mark_parentheses(checker, decorator, marker, fix, "", "()"); } } _ => { if checker.settings.flake8_pytest_style.mark_parentheses { - let fix = Fix::automatic(Edit::insertion("()".to_string(), decorator.end())); - pytest_mark_parentheses(checker, decorator, call_path, fix, "()", ""); + let fix = Fix::safe_edit(Edit::insertion("()".to_string(), decorator.end())); + pytest_mark_parentheses(checker, decorator, marker, fix, "()", ""); } } } } -fn check_useless_usefixtures(checker: &mut Checker, decorator: &Decorator, call_path: &CallPath) { - if *call_path.last().unwrap() != "usefixtures" { +fn check_useless_usefixtures(checker: &mut Checker, decorator: &Decorator, marker: &str) { + if marker != "usefixtures" { return; } - let mut has_parameters = false; - - if let Expr::Call(ast::ExprCall { - arguments: Arguments { args, keywords, .. }, - .. - }) = &decorator.expression - { - if !args.is_empty() || !keywords.is_empty() { - has_parameters = true; + match &decorator.expression { + // @pytest.mark.usefixtures + Expr::Attribute(..) => {} + // @pytest.mark.usefixtures(...) + Expr::Call(ast::ExprCall { + arguments: Arguments { args, keywords, .. }, + .. + }) => { + if !args.is_empty() || !keywords.is_empty() { + return; + } } + _ => return, } - if !has_parameters { - let mut diagnostic = Diagnostic::new(PytestUseFixturesWithoutParameters, decorator.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_deletion(decorator.range()))); - } - checker.diagnostics.push(diagnostic); - } + let mut diagnostic = Diagnostic::new(PytestUseFixturesWithoutParameters, decorator.range()); + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_deletion(decorator.range()))); + checker.diagnostics.push(diagnostic); } pub(crate) fn marks(checker: &mut Checker, decorators: &[Decorator]) { let enforce_parentheses = checker.enabled(Rule::PytestIncorrectMarkParenthesesStyle); let enforce_useless_usefixtures = checker.enabled(Rule::PytestUseFixturesWithoutParameters); - for (decorator, call_path) in get_mark_decorators(decorators) { + for (decorator, marker) in get_mark_decorators(decorators) { if enforce_parentheses { - check_mark_parentheses(checker, decorator, &call_path); + check_mark_parentheses(checker, decorator, marker); } if enforce_useless_usefixtures { - check_useless_usefixtures(checker, decorator, &call_path); + check_useless_usefixtures(checker, decorator, marker); } } } diff --git a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/parametrize.rs b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/parametrize.rs index 293c4b8f08c75..4ab938ffef5cc 100644 --- a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/parametrize.rs +++ b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/parametrize.rs @@ -2,11 +2,11 @@ use std::hash::BuildHasherDefault; use rustc_hash::FxHashMap; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::comparable::ComparableExpr; -use ruff_python_ast::node::AstNode; use ruff_python_ast::parenthesize::parenthesized_range; +use ruff_python_ast::AstNode; use ruff_python_ast::{self as ast, Arguments, Constant, Decorator, Expr, ExprContext}; use ruff_python_codegen::Generator; use ruff_python_trivia::CommentRanges; @@ -14,7 +14,7 @@ use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer}; use ruff_text_size::{Ranged, TextRange, TextSize}; use crate::checkers::ast::Checker; -use crate::registry::{AsRule, Rule}; +use crate::registry::Rule; use super::super::types; use super::helpers::{is_pytest_parametrize, split_names}; @@ -77,7 +77,7 @@ pub struct PytestParametrizeNamesWrongType { } impl Violation for PytestParametrizeNamesWrongType { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -85,7 +85,7 @@ impl Violation for PytestParametrizeNamesWrongType { format!("Wrong name(s) type in `@pytest.mark.parametrize`, expected `{expected}`") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let PytestParametrizeNamesWrongType { expected } = self; Some(format!("Use a `{expected}` for parameter names")) } @@ -234,7 +234,7 @@ pub struct PytestDuplicateParametrizeTestCases { } impl Violation for PytestDuplicateParametrizeTestCases { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -242,7 +242,7 @@ impl Violation for PytestDuplicateParametrizeTestCases { format!("Duplicate of test case at index {index} in `@pytest_mark.parametrize`") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Remove duplicate test case".to_string()) } } @@ -338,25 +338,23 @@ fn check_names(checker: &mut Checker, decorator: &Decorator, expr: &Expr) { }, name_range, ); - if checker.patch(diagnostic.kind.rule()) { - let node = Expr::Tuple(ast::ExprTuple { - elts: names - .iter() - .map(|name| { - Expr::Constant(ast::ExprConstant { - value: (*name).to_string().into(), - range: TextRange::default(), - }) + let node = Expr::Tuple(ast::ExprTuple { + elts: names + .iter() + .map(|name| { + Expr::Constant(ast::ExprConstant { + value: (*name).to_string().into(), + range: TextRange::default(), }) - .collect(), - ctx: ExprContext::Load, - range: TextRange::default(), - }); - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - format!("({})", checker.generator().expr(&node)), - name_range, - ))); - } + }) + .collect(), + ctx: ExprContext::Load, + range: TextRange::default(), + }); + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + format!("({})", checker.generator().expr(&node)), + name_range, + ))); checker.diagnostics.push(diagnostic); } types::ParametrizeNameType::List => { @@ -373,25 +371,23 @@ fn check_names(checker: &mut Checker, decorator: &Decorator, expr: &Expr) { }, name_range, ); - if checker.patch(diagnostic.kind.rule()) { - let node = Expr::List(ast::ExprList { - elts: names - .iter() - .map(|name| { - Expr::Constant(ast::ExprConstant { - value: (*name).to_string().into(), - range: TextRange::default(), - }) + let node = Expr::List(ast::ExprList { + elts: names + .iter() + .map(|name| { + Expr::Constant(ast::ExprConstant { + value: (*name).to_string().into(), + range: TextRange::default(), }) - .collect(), - ctx: ExprContext::Load, - range: TextRange::default(), - }); - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.generator().expr(&node), - name_range, - ))); - } + }) + .collect(), + ctx: ExprContext::Load, + range: TextRange::default(), + }); + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + checker.generator().expr(&node), + name_range, + ))); checker.diagnostics.push(diagnostic); } types::ParametrizeNameType::Csv => {} @@ -413,17 +409,15 @@ fn check_names(checker: &mut Checker, decorator: &Decorator, expr: &Expr) { }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let node = Expr::List(ast::ExprList { - elts: elts.clone(), - ctx: ExprContext::Load, - range: TextRange::default(), - }); - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.generator().expr(&node), - expr.range(), - ))); - } + let node = Expr::List(ast::ExprList { + elts: elts.clone(), + ctx: ExprContext::Load, + range: TextRange::default(), + }); + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + checker.generator().expr(&node), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } types::ParametrizeNameType::Csv => { @@ -433,13 +427,11 @@ fn check_names(checker: &mut Checker, decorator: &Decorator, expr: &Expr) { }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if let Some(content) = elts_to_csv(elts, checker.generator()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - content, - expr.range(), - ))); - } + if let Some(content) = elts_to_csv(elts, checker.generator()) { + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + content, + expr.range(), + ))); } checker.diagnostics.push(diagnostic); } @@ -461,17 +453,15 @@ fn check_names(checker: &mut Checker, decorator: &Decorator, expr: &Expr) { }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let node = Expr::Tuple(ast::ExprTuple { - elts: elts.clone(), - ctx: ExprContext::Load, - range: TextRange::default(), - }); - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - format!("({})", checker.generator().expr(&node)), - expr.range(), - ))); - } + let node = Expr::Tuple(ast::ExprTuple { + elts: elts.clone(), + ctx: ExprContext::Load, + range: TextRange::default(), + }); + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + format!("({})", checker.generator().expr(&node)), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } types::ParametrizeNameType::Csv => { @@ -481,13 +471,11 @@ fn check_names(checker: &mut Checker, decorator: &Decorator, expr: &Expr) { }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if let Some(content) = elts_to_csv(elts, checker.generator()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - content, - expr.range(), - ))); - } + if let Some(content) = elts_to_csv(elts, checker.generator()) { + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + content, + expr.range(), + ))); } checker.diagnostics.push(diagnostic); } @@ -585,22 +573,19 @@ fn check_duplicates(checker: &mut Checker, values: &Expr) { PytestDuplicateParametrizeTestCases { index: *index }, element.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if let Some(prev) = prev { - let values_end = values.range().end() - TextSize::new(1); - let previous_end = trailing_comma(prev, checker.locator().contents()) - .unwrap_or(values_end); - let element_end = trailing_comma(element, checker.locator().contents()) - .unwrap_or(values_end); - let deletion_range = TextRange::new(previous_end, element_end); - if !checker - .indexer() - .comment_ranges() - .intersects(deletion_range) - { - diagnostic - .set_fix(Fix::suggested(Edit::range_deletion(deletion_range))); - } + if let Some(prev) = prev { + let values_end = values.range().end() - TextSize::new(1); + let previous_end = + trailing_comma(prev, checker.locator().contents()).unwrap_or(values_end); + let element_end = + trailing_comma(element, checker.locator().contents()).unwrap_or(values_end); + let deletion_range = TextRange::new(previous_end, element_end); + if !checker + .indexer() + .comment_ranges() + .intersects(deletion_range) + { + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_deletion(deletion_range))); } } checker.diagnostics.push(diagnostic); @@ -618,13 +603,11 @@ fn handle_single_name(checker: &mut Checker, expr: &Expr, value: &Expr) { expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let node = value.clone(); - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - checker.generator().expr(&node), - expr.range(), - ))); - } + let node = value.clone(); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + checker.generator().expr(&node), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/unittest_assert.rs b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/unittest_assert.rs index d319cd32b3ea7..5dcbf58f2e0dc 100644 --- a/crates/ruff_linter/src/rules/flake8_pytest_style/rules/unittest_assert.rs +++ b/crates/ruff_linter/src/rules/flake8_pytest_style/rules/unittest_assert.rs @@ -453,7 +453,7 @@ impl UnittestAssert { Ok(assert(&node.into(), msg)) } } - _ => bail!("Cannot autofix `{self}`"), + _ => bail!("Cannot fix `{self}`"), } } } diff --git a/crates/ruff_linter/src/rules/flake8_pytest_style/snapshots/ruff_linter__rules__flake8_pytest_style__tests__PT018.snap b/crates/ruff_linter/src/rules/flake8_pytest_style/snapshots/ruff_linter__rules__flake8_pytest_style__tests__PT018.snap index c32ecf025b444..a656a5c666f59 100644 --- a/crates/ruff_linter/src/rules/flake8_pytest_style/snapshots/ruff_linter__rules__flake8_pytest_style__tests__PT018.snap +++ b/crates/ruff_linter/src/rules/flake8_pytest_style/snapshots/ruff_linter__rules__flake8_pytest_style__tests__PT018.snap @@ -228,7 +228,7 @@ PT018.py:33:5: PT018 [*] Assertion should be broken down into multiple parts 34 |+ assert (b or c) 34 35 | assert not (a or not (b and c)) 35 36 | -36 37 | # detected, but no autofix for messages +36 37 | # detected, but no fix for messages PT018.py:34:5: PT018 [*] Assertion should be broken down into multiple parts | @@ -237,7 +237,7 @@ PT018.py:34:5: PT018 [*] Assertion should be broken down into multiple parts 34 | assert not (a or not (b and c)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PT018 35 | -36 | # detected, but no autofix for messages +36 | # detected, but no fix for messages | = help: Break down assertion into multiple parts @@ -249,26 +249,26 @@ PT018.py:34:5: PT018 [*] Assertion should be broken down into multiple parts 34 |+ assert not a 35 |+ assert (b and c) 35 36 | -36 37 | # detected, but no autofix for messages +36 37 | # detected, but no fix for messages 37 38 | assert something and something_else, "error message" PT018.py:37:5: PT018 Assertion should be broken down into multiple parts | -36 | # detected, but no autofix for messages +36 | # detected, but no fix for messages 37 | assert something and something_else, "error message" | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PT018 38 | assert not (something or something_else and something_third), "with message" -39 | # detected, but no autofix for mixed conditions (e.g. `a or b and c`) +39 | # detected, but no fix for mixed conditions (e.g. `a or b and c`) | = help: Break down assertion into multiple parts PT018.py:38:5: PT018 Assertion should be broken down into multiple parts | -36 | # detected, but no autofix for messages +36 | # detected, but no fix for messages 37 | assert something and something_else, "error message" 38 | assert not (something or something_else and something_third), "with message" | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PT018 -39 | # detected, but no autofix for mixed conditions (e.g. `a or b and c`) +39 | # detected, but no fix for mixed conditions (e.g. `a or b and c`) 40 | assert not (something or something_else and something_third) | = help: Break down assertion into multiple parts @@ -276,7 +276,7 @@ PT018.py:38:5: PT018 Assertion should be broken down into multiple parts PT018.py:40:5: PT018 Assertion should be broken down into multiple parts | 38 | assert not (something or something_else and something_third), "with message" -39 | # detected, but no autofix for mixed conditions (e.g. `a or b and c`) +39 | # detected, but no fix for mixed conditions (e.g. `a or b and c`) 40 | assert not (something or something_else and something_third) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PT018 | diff --git a/crates/ruff_linter/src/rules/flake8_quotes/mod.rs b/crates/ruff_linter/src/rules/flake8_quotes/mod.rs index f3c1e86ad1046..1d178d1f1412d 100644 --- a/crates/ruff_linter/src/rules/flake8_quotes/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_quotes/mod.rs @@ -11,6 +11,7 @@ mod tests { use crate::assert_messages; use crate::registry::Rule; + use crate::settings::types::PythonVersion; use crate::settings::LinterSettings; use crate::test::test_path; @@ -45,6 +46,44 @@ mod tests { Ok(()) } + #[test] + fn require_singles_over_doubles_escaped_py311() -> Result<()> { + let diagnostics = test_path( + Path::new("flake8_quotes/doubles_escaped.py"), + &LinterSettings { + flake8_quotes: super::settings::Settings { + inline_quotes: Quote::Single, + multiline_quotes: Quote::Single, + docstring_quotes: Quote::Single, + avoid_escape: true, + }, + ..LinterSettings::for_rule(Rule::AvoidableEscapedQuote) + .with_target_version(PythonVersion::Py311) + }, + )?; + assert_messages!(diagnostics); + Ok(()) + } + + #[test] + fn require_doubles_over_singles_escaped_py311() -> Result<()> { + let diagnostics = test_path( + Path::new("flake8_quotes/singles_escaped.py"), + &LinterSettings { + flake8_quotes: super::settings::Settings { + inline_quotes: Quote::Double, + multiline_quotes: Quote::Double, + docstring_quotes: Quote::Double, + avoid_escape: true, + }, + ..LinterSettings::for_rule(Rule::AvoidableEscapedQuote) + .with_target_version(PythonVersion::Py311) + }, + )?; + assert_messages!(diagnostics); + Ok(()) + } + #[test_case(Path::new("singles.py"))] #[test_case(Path::new("singles_escaped.py"))] #[test_case(Path::new("singles_implicit.py"))] diff --git a/crates/ruff_linter/src/rules/flake8_quotes/rules/avoidable_escaped_quote.rs b/crates/ruff_linter/src/rules/flake8_quotes/rules/avoidable_escaped_quote.rs new file mode 100644 index 0000000000000..ab4f2ef42ebbe --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_quotes/rules/avoidable_escaped_quote.rs @@ -0,0 +1,256 @@ +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::str::{is_triple_quote, leading_quote}; +use ruff_python_parser::lexer::LexResult; +use ruff_python_parser::Tok; +use ruff_source_file::Locator; +use ruff_text_size::TextRange; + +use crate::lex::docstring_detection::StateMachine; + +use crate::settings::LinterSettings; + +/// ## What it does +/// Checks for strings that include escaped quotes, and suggests changing +/// the quote style to avoid the need to escape them. +/// +/// ## Why is this bad? +/// It's preferable to avoid escaped quotes in strings. By changing the +/// outer quote style, you can avoid escaping inner quotes. +/// +/// ## Example +/// ```python +/// foo = 'bar\'s' +/// ``` +/// +/// Use instead: +/// ```python +/// foo = "bar's" +/// ``` +/// +/// ## Formatter compatibility +/// We recommend against using this rule alongside the [formatter]. The +/// formatter automatically removes unnecessary escapes, making the rule +/// redundant. +/// +/// [formatter]: https://docs.astral.sh/ruff/formatter +#[violation] +pub struct AvoidableEscapedQuote; + +impl AlwaysFixableViolation for AvoidableEscapedQuote { + #[derive_message_formats] + fn message(&self) -> String { + format!("Change outer quotes to avoid escaping inner quotes") + } + + fn fix_title(&self) -> String { + "Change outer quotes to avoid escaping inner quotes".to_string() + } +} + +struct FStringContext { + /// Whether to check for escaped quotes in the f-string. + check_for_escaped_quote: bool, + /// The range of the f-string start token. + start_range: TextRange, + /// The ranges of the f-string middle tokens containing escaped quotes. + middle_ranges_with_escapes: Vec, +} + +impl FStringContext { + fn new(check_for_escaped_quote: bool, fstring_start_range: TextRange) -> Self { + Self { + check_for_escaped_quote, + start_range: fstring_start_range, + middle_ranges_with_escapes: vec![], + } + } + + /// Update the context to not check for escaped quotes, and clear any + /// existing reported ranges. + fn ignore_escaped_quotes(&mut self) { + self.check_for_escaped_quote = false; + self.middle_ranges_with_escapes.clear(); + } + + fn push_fstring_middle_range(&mut self, range: TextRange) { + self.middle_ranges_with_escapes.push(range); + } +} + +/// Q003 +pub(crate) fn avoidable_escaped_quote( + diagnostics: &mut Vec, + lxr: &[LexResult], + locator: &Locator, + settings: &LinterSettings, +) { + let quotes_settings = &settings.flake8_quotes; + let supports_pep701 = settings.target_version.supports_pep701(); + let mut fstrings: Vec = Vec::new(); + let mut state_machine = StateMachine::default(); + + for &(ref tok, tok_range) in lxr.iter().flatten() { + let is_docstring = state_machine.consume(tok); + if is_docstring { + continue; + } + + if !supports_pep701 { + // If this is a string or a start of a f-string which is inside another + // f-string, we won't check for escaped quotes for the entire f-string + // if the target version doesn't support PEP 701. For example: + // + // ```python + // f"\"foo\" {'nested'}" + // # ^^^^^^^^ + // # We're here + // ``` + // + // If we try to fix the above example, the outer and inner quote + // will be the same which is invalid pre 3.12: + // + // ```python + // f'"foo" {'nested'}" + // ``` + if matches!(tok, Tok::String { .. } | Tok::FStringStart) { + if let Some(fstring_context) = fstrings.last_mut() { + fstring_context.ignore_escaped_quotes(); + continue; + } + } + } + + match tok { + Tok::String { + value: string_contents, + kind, + triple_quoted, + } => { + if kind.is_raw() || *triple_quoted { + continue; + } + + // Check if we're using the preferred quotation style. + if !leading_quote(locator.slice(tok_range)) + .is_some_and(|text| text.contains(quotes_settings.inline_quotes.as_char())) + { + continue; + } + + if string_contents.contains(quotes_settings.inline_quotes.as_char()) + && !string_contents.contains(quotes_settings.inline_quotes.opposite().as_char()) + { + let mut diagnostic = Diagnostic::new(AvoidableEscapedQuote, tok_range); + let fixed_contents = format!( + "{prefix}{quote}{value}{quote}", + prefix = kind.as_str(), + quote = quotes_settings.inline_quotes.opposite().as_char(), + value = unescape_string(string_contents) + ); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + fixed_contents, + tok_range, + ))); + diagnostics.push(diagnostic); + } + } + Tok::FStringStart => { + let text = locator.slice(tok_range); + // Check for escaped quote only if we're using the preferred quotation + // style and it isn't a triple-quoted f-string. + let check_for_escaped_quote = text + .contains(quotes_settings.inline_quotes.as_char()) + && !is_triple_quote(text); + fstrings.push(FStringContext::new(check_for_escaped_quote, tok_range)); + } + Tok::FStringMiddle { + value: string_contents, + is_raw, + } if !is_raw => { + let Some(context) = fstrings.last_mut() else { + continue; + }; + if !context.check_for_escaped_quote { + continue; + } + // If any part of the f-string contains the opposite quote, + // we can't change the quote style in the entire f-string. + if string_contents.contains(quotes_settings.inline_quotes.opposite().as_char()) { + context.ignore_escaped_quotes(); + continue; + } + if string_contents.contains(quotes_settings.inline_quotes.as_char()) { + context.push_fstring_middle_range(tok_range); + } + } + Tok::FStringEnd => { + let Some(context) = fstrings.pop() else { + continue; + }; + if context.middle_ranges_with_escapes.is_empty() { + // There are no `FStringMiddle` tokens containing any escaped + // quotes. + continue; + } + let mut diagnostic = Diagnostic::new( + AvoidableEscapedQuote, + TextRange::new(context.start_range.start(), tok_range.end()), + ); + let fstring_start_edit = Edit::range_replacement( + // No need for `r`/`R` as we don't perform the checks + // for raw strings. + format!("f{}", quotes_settings.inline_quotes.opposite().as_char()), + context.start_range, + ); + let fstring_middle_and_end_edits = context + .middle_ranges_with_escapes + .iter() + .map(|&range| { + Edit::range_replacement(unescape_string(locator.slice(range)), range) + }) + .chain(std::iter::once( + // `FStringEnd` edit + Edit::range_replacement( + quotes_settings + .inline_quotes + .opposite() + .as_char() + .to_string(), + tok_range, + ), + )); + diagnostic.set_fix(Fix::safe_edits( + fstring_start_edit, + fstring_middle_and_end_edits, + )); + diagnostics.push(diagnostic); + } + _ => {} + } + } +} + +fn unescape_string(value: &str) -> String { + let mut fixed_contents = String::with_capacity(value.len()); + + let mut chars = value.chars().peekable(); + while let Some(char) = chars.next() { + if char != '\\' { + fixed_contents.push(char); + continue; + } + // If we're at the end of the line + let Some(next_char) = chars.peek() else { + fixed_contents.push(char); + continue; + }; + // Remove quote escape + if matches!(*next_char, '\'' | '"') { + continue; + } + fixed_contents.push(char); + } + + fixed_contents +} diff --git a/crates/ruff_linter/src/rules/flake8_quotes/rules/from_tokens.rs b/crates/ruff_linter/src/rules/flake8_quotes/rules/check_string_quotes.rs similarity index 50% rename from crates/ruff_linter/src/rules/flake8_quotes/rules/from_tokens.rs rename to crates/ruff_linter/src/rules/flake8_quotes/rules/check_string_quotes.rs index 7cb159008147a..45a845fc6459a 100644 --- a/crates/ruff_linter/src/rules/flake8_quotes/rules/from_tokens.rs +++ b/crates/ruff_linter/src/rules/flake8_quotes/rules/check_string_quotes.rs @@ -1,13 +1,13 @@ use ruff_python_parser::lexer::LexResult; use ruff_python_parser::Tok; -use ruff_text_size::TextRange; +use ruff_text_size::{TextRange, TextSize}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_source_file::Locator; use crate::lex::docstring_detection::StateMachine; -use crate::registry::Rule; + use crate::settings::LinterSettings; use super::super::settings::Quote; @@ -32,24 +32,31 @@ use super::super::settings::Quote; /// /// ## Options /// - `flake8-quotes.inline-quotes` +/// +/// ## Formatter compatibility +/// We recommend against using this rule alongside the [formatter]. The +/// formatter enforces consistent quotes for inline strings, making the rule +/// redundant. +/// +/// [formatter]: https://docs.astral.sh/ruff/formatter #[violation] pub struct BadQuotesInlineString { - quote: Quote, + preferred_quote: Quote, } -impl AlwaysAutofixableViolation for BadQuotesInlineString { +impl AlwaysFixableViolation for BadQuotesInlineString { #[derive_message_formats] fn message(&self) -> String { - let BadQuotesInlineString { quote } = self; - match quote { + let BadQuotesInlineString { preferred_quote } = self; + match preferred_quote { Quote::Double => format!("Single quotes found but double quotes preferred"), Quote::Single => format!("Double quotes found but single quotes preferred"), } } - fn autofix_title(&self) -> String { - let BadQuotesInlineString { quote } = self; - match quote { + fn fix_title(&self) -> String { + let BadQuotesInlineString { preferred_quote } = self; + match preferred_quote { Quote::Double => "Replace single quotes with double quotes".to_string(), Quote::Single => "Replace double quotes with single quotes".to_string(), } @@ -81,24 +88,31 @@ impl AlwaysAutofixableViolation for BadQuotesInlineString { /// /// ## Options /// - `flake8-quotes.multiline-quotes` +/// +/// ## Formatter compatibility +/// We recommend against using this rule alongside the [formatter]. The +/// formatter enforces double quotes for multiline strings, making the rule +/// redundant. +/// +/// [formatter]: https://docs.astral.sh/ruff/formatter #[violation] pub struct BadQuotesMultilineString { - quote: Quote, + preferred_quote: Quote, } -impl AlwaysAutofixableViolation for BadQuotesMultilineString { +impl AlwaysFixableViolation for BadQuotesMultilineString { #[derive_message_formats] fn message(&self) -> String { - let BadQuotesMultilineString { quote } = self; - match quote { + let BadQuotesMultilineString { preferred_quote } = self; + match preferred_quote { Quote::Double => format!("Single quote multiline found but double quotes preferred"), Quote::Single => format!("Double quote multiline found but single quotes preferred"), } } - fn autofix_title(&self) -> String { - let BadQuotesMultilineString { quote } = self; - match quote { + fn fix_title(&self) -> String { + let BadQuotesMultilineString { preferred_quote } = self; + match preferred_quote { Quote::Double => "Replace single multiline quotes with double quotes".to_string(), Quote::Single => "Replace double multiline quotes with single quotes".to_string(), } @@ -129,75 +143,37 @@ impl AlwaysAutofixableViolation for BadQuotesMultilineString { /// /// ## Options /// - `flake8-quotes.docstring-quotes` +/// +/// ## Formatter compatibility +/// We recommend against using this rule alongside the [formatter]. The +/// formatter enforces double quotes for docstrings, making the rule +/// redundant. +/// +/// [formatter]: https://docs.astral.sh/ruff/formatter #[violation] pub struct BadQuotesDocstring { - quote: Quote, + preferred_quote: Quote, } -impl AlwaysAutofixableViolation for BadQuotesDocstring { +impl AlwaysFixableViolation for BadQuotesDocstring { #[derive_message_formats] fn message(&self) -> String { - let BadQuotesDocstring { quote } = self; - match quote { + let BadQuotesDocstring { preferred_quote } = self; + match preferred_quote { Quote::Double => format!("Single quote docstring found but double quotes preferred"), Quote::Single => format!("Double quote docstring found but single quotes preferred"), } } - fn autofix_title(&self) -> String { - let BadQuotesDocstring { quote } = self; - match quote { + fn fix_title(&self) -> String { + let BadQuotesDocstring { preferred_quote } = self; + match preferred_quote { Quote::Double => "Replace single quotes docstring with double quotes".to_string(), Quote::Single => "Replace double quotes docstring with single quotes".to_string(), } } } -/// ## What it does -/// Checks for strings that include escaped quotes, and suggests changing -/// the quote style to avoid the need to escape them. -/// -/// ## Why is this bad? -/// It's preferable to avoid escaped quotes in strings. By changing the -/// outer quote style, you can avoid escaping inner quotes. -/// -/// ## Example -/// ```python -/// foo = 'bar\'s' -/// ``` -/// -/// Use instead: -/// ```python -/// foo = "bar's" -/// ``` -#[violation] -pub struct AvoidableEscapedQuote; - -impl AlwaysAutofixableViolation for AvoidableEscapedQuote { - #[derive_message_formats] - fn message(&self) -> String { - format!("Change outer quotes to avoid escaping inner quotes") - } - - fn autofix_title(&self) -> String { - "Change outer quotes to avoid escaping inner quotes".to_string() - } -} - -const fn good_single(quote: Quote) -> char { - match quote { - Quote::Double => '"', - Quote::Single => '\'', - } -} - -const fn bad_single(quote: Quote) -> char { - match quote { - Quote::Double => '\'', - Quote::Single => '"', - } -} - const fn good_multiline(quote: Quote) -> &'static str { match quote { Quote::Double => "\"\"\"", @@ -219,6 +195,7 @@ const fn good_docstring(quote: Quote) -> &'static str { } } +#[derive(Debug)] struct Trivia<'a> { last_quote_char: char, prefix: &'a str, @@ -254,7 +231,7 @@ impl<'a> From<&'a str> for Trivia<'a> { } } -/// Q003 +/// Q002 fn docstring(locator: &Locator, range: TextRange, settings: &LinterSettings) -> Option { let quotes_settings = &settings.flake8_quotes; @@ -270,29 +247,27 @@ fn docstring(locator: &Locator, range: TextRange, settings: &LinterSettings) -> let mut diagnostic = Diagnostic::new( BadQuotesDocstring { - quote: quotes_settings.docstring_quotes, + preferred_quote: quotes_settings.docstring_quotes, }, range, ); - if settings.rules.should_fix(Rule::BadQuotesDocstring) { - let quote_count = if trivia.is_multiline { 3 } else { 1 }; - let string_contents = &trivia.raw_text[quote_count..trivia.raw_text.len() - quote_count]; - let quote = good_docstring(quotes_settings.docstring_quotes).repeat(quote_count); - let mut fixed_contents = - String::with_capacity(trivia.prefix.len() + string_contents.len() + quote.len() * 2); - fixed_contents.push_str(trivia.prefix); - fixed_contents.push_str("e); - fixed_contents.push_str(string_contents); - fixed_contents.push_str("e); - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - fixed_contents, - range, - ))); - } + let quote_count = if trivia.is_multiline { 3 } else { 1 }; + let string_contents = &trivia.raw_text[quote_count..trivia.raw_text.len() - quote_count]; + let quote = good_docstring(quotes_settings.docstring_quotes).repeat(quote_count); + let mut fixed_contents = + String::with_capacity(trivia.prefix.len() + string_contents.len() + quote.len() * 2); + fixed_contents.push_str(trivia.prefix); + fixed_contents.push_str("e); + fixed_contents.push_str(string_contents); + fixed_contents.push_str("e); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + fixed_contents, + range, + ))); Some(diagnostic) } -/// Q001, Q002 +/// Q000, Q001 fn strings( locator: &Locator, sequence: &[TextRange], @@ -318,12 +293,12 @@ fn strings( return false; } - if trivia.last_quote_char == good_single(quotes_settings.inline_quotes) { + if trivia.last_quote_char == quotes_settings.inline_quotes.as_char() { return false; } let string_contents = &trivia.raw_text[1..trivia.raw_text.len() - 1]; - string_contents.contains(good_single(quotes_settings.inline_quotes)) + string_contents.contains(quotes_settings.inline_quotes.as_char()) }); for (range, trivia) in sequence.iter().zip(trivia) { @@ -346,128 +321,107 @@ fn strings( let mut diagnostic = Diagnostic::new( BadQuotesMultilineString { - quote: quotes_settings.multiline_quotes, + preferred_quote: quotes_settings.multiline_quotes, }, *range, ); - if settings.rules.should_fix(Rule::BadQuotesMultilineString) { - let string_contents = &trivia.raw_text[3..trivia.raw_text.len() - 3]; - let quote = good_multiline(quotes_settings.multiline_quotes); - let mut fixed_contents = String::with_capacity( - trivia.prefix.len() + string_contents.len() + quote.len() * 2, - ); - fixed_contents.push_str(trivia.prefix); - fixed_contents.push_str(quote); - fixed_contents.push_str(string_contents); - fixed_contents.push_str(quote); - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - fixed_contents, - *range, - ))); - } + let string_contents = &trivia.raw_text[3..trivia.raw_text.len() - 3]; + let quote = good_multiline(quotes_settings.multiline_quotes); + let mut fixed_contents = String::with_capacity( + trivia.prefix.len() + string_contents.len() + quote.len() * 2, + ); + fixed_contents.push_str(trivia.prefix); + fixed_contents.push_str(quote); + fixed_contents.push_str(string_contents); + fixed_contents.push_str(quote); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + fixed_contents, + *range, + ))); diagnostics.push(diagnostic); - } else { + } else if trivia.last_quote_char != quotes_settings.inline_quotes.as_char() + // If we're not using the preferred type, only allow use to avoid escapes. + && !relax_quote + { + let mut diagnostic = Diagnostic::new( + BadQuotesInlineString { + preferred_quote: quotes_settings.inline_quotes, + }, + *range, + ); + let quote = quotes_settings.inline_quotes.as_char(); let string_contents = &trivia.raw_text[1..trivia.raw_text.len() - 1]; + let mut fixed_contents = + String::with_capacity(trivia.prefix.len() + string_contents.len() + 2); + fixed_contents.push_str(trivia.prefix); + fixed_contents.push(quote); + fixed_contents.push_str(string_contents); + fixed_contents.push(quote); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + fixed_contents, + *range, + ))); + diagnostics.push(diagnostic); + } + } - // If we're using the preferred quotation type, check for escapes. - if trivia.last_quote_char == good_single(quotes_settings.inline_quotes) { - if !quotes_settings.avoid_escape - || trivia.prefix.contains('r') - || trivia.prefix.contains('R') - { - continue; - } + diagnostics +} - if string_contents.contains(good_single(quotes_settings.inline_quotes)) - && !string_contents.contains(bad_single(quotes_settings.inline_quotes)) - { - let mut diagnostic = Diagnostic::new(AvoidableEscapedQuote, *range); - if settings.rules.should_fix(Rule::AvoidableEscapedQuote) { - let quote = bad_single(quotes_settings.inline_quotes); - - let mut fixed_contents = - String::with_capacity(trivia.prefix.len() + string_contents.len() + 2); - fixed_contents.push_str(trivia.prefix); - fixed_contents.push(quote); - - let chars: Vec = string_contents.chars().collect(); - let mut backslash_count = 0; - for col_offset in 0..chars.len() { - let char = chars[col_offset]; - if char != '\\' { - fixed_contents.push(char); - continue; - } - backslash_count += 1; - // If the previous character was also a backslash - if col_offset > 0 - && chars[col_offset - 1] == '\\' - && backslash_count == 2 - { - fixed_contents.push(char); - // reset to 0 - backslash_count = 0; - continue; - } - // If we're at the end of the line - if col_offset == chars.len() - 1 { - fixed_contents.push(char); - continue; - } - let next_char = chars[col_offset + 1]; - // Remove quote escape - if next_char == '\'' || next_char == '"' { - // reset to 0 - backslash_count = 0; - continue; - } - fixed_contents.push(char); - } - - fixed_contents.push(quote); - - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - fixed_contents, - *range, - ))); - } - diagnostics.push(diagnostic); +/// A builder for the f-string range. +/// +/// For now, this is limited to the outermost f-string and doesn't support +/// nested f-strings. +#[derive(Debug, Default)] +struct FStringRangeBuilder { + start_location: TextSize, + end_location: TextSize, + nesting: u32, +} + +impl FStringRangeBuilder { + fn visit_token(&mut self, token: &Tok, range: TextRange) { + match token { + Tok::FStringStart => { + if self.nesting == 0 { + self.start_location = range.start(); } - continue; + self.nesting += 1; } - - // If we're not using the preferred type, only allow use to avoid escapes. - if !relax_quote { - let mut diagnostic = Diagnostic::new( - BadQuotesInlineString { - quote: quotes_settings.inline_quotes, - }, - *range, - ); - if settings.rules.should_fix(Rule::BadQuotesInlineString) { - let quote = good_single(quotes_settings.inline_quotes); - let mut fixed_contents = - String::with_capacity(trivia.prefix.len() + string_contents.len() + 2); - fixed_contents.push_str(trivia.prefix); - fixed_contents.push(quote); - fixed_contents.push_str(string_contents); - fixed_contents.push(quote); - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - fixed_contents, - *range, - ))); + Tok::FStringEnd => { + self.nesting = self.nesting.saturating_sub(1); + if self.nesting == 0 { + self.end_location = range.end(); } - diagnostics.push(diagnostic); } + _ => {} } } - diagnostics + /// Returns `true` if the lexer is currently inside of a f-string. + /// + /// It'll return `false` once the `FStringEnd` token for the outermost + /// f-string is visited. + const fn in_fstring(&self) -> bool { + self.nesting > 0 + } + + /// Returns the complete range of the previously visited f-string. + /// + /// This method should only be called once the lexer is outside of any + /// f-string otherwise it might return an invalid range. + /// + /// It doesn't consume the builder because there can be multiple f-strings + /// throughout the source code. + fn finish(&self) -> TextRange { + debug_assert!(!self.in_fstring()); + TextRange::new(self.start_location, self.end_location) + } } /// Generate `flake8-quote` diagnostics from a token stream. -pub(crate) fn from_tokens( +pub(crate) fn check_string_quotes( diagnostics: &mut Vec, lxr: &[LexResult], locator: &Locator, @@ -477,7 +431,13 @@ pub(crate) fn from_tokens( // concatenation, and should thus be handled as a single unit. let mut sequence = vec![]; let mut state_machine = StateMachine::default(); + let mut fstring_range_builder = FStringRangeBuilder::default(); for &(ref tok, range) in lxr.iter().flatten() { + fstring_range_builder.visit_token(tok, range); + if fstring_range_builder.in_fstring() { + continue; + } + let is_docstring = state_machine.consume(tok); // If this is a docstring, consume the existing sequence, then consume the @@ -491,14 +451,23 @@ pub(crate) fn from_tokens( diagnostics.push(diagnostic); } } else { - if tok.is_string() { - // If this is a string, add it to the sequence. - sequence.push(range); - } else if !matches!(tok, Tok::Comment(..) | Tok::NonLogicalNewline) { - // Otherwise, consume the sequence. - if !sequence.is_empty() { - diagnostics.extend(strings(locator, &sequence, settings)); - sequence.clear(); + match tok { + Tok::String { .. } => { + // If this is a string, add it to the sequence. + sequence.push(range); + } + Tok::FStringEnd => { + // If this is the end of an f-string, add the entire f-string + // range to the sequence. + sequence.push(fstring_range_builder.finish()); + } + Tok::Comment(..) | Tok::NonLogicalNewline => continue, + _ => { + // Otherwise, consume the sequence. + if !sequence.is_empty() { + diagnostics.extend(strings(locator, &sequence, settings)); + sequence.clear(); + } } } } diff --git a/crates/ruff_linter/src/rules/flake8_quotes/rules/mod.rs b/crates/ruff_linter/src/rules/flake8_quotes/rules/mod.rs index 8ad6bad659da4..1f64976bf24b1 100644 --- a/crates/ruff_linter/src/rules/flake8_quotes/rules/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_quotes/rules/mod.rs @@ -1,3 +1,5 @@ -pub(crate) use from_tokens::*; +pub(crate) use avoidable_escaped_quote::*; +pub(crate) use check_string_quotes::*; -mod from_tokens; +mod avoidable_escaped_quote; +mod check_string_quotes; diff --git a/crates/ruff_linter/src/rules/flake8_quotes/settings.rs b/crates/ruff_linter/src/rules/flake8_quotes/settings.rs index 4a69c1da46064..620fb2e53a8b8 100644 --- a/crates/ruff_linter/src/rules/flake8_quotes/settings.rs +++ b/crates/ruff_linter/src/rules/flake8_quotes/settings.rs @@ -38,3 +38,21 @@ impl Default for Settings { } } } + +impl Quote { + #[must_use] + pub const fn opposite(self) -> Self { + match self { + Self::Double => Self::Single, + Self::Single => Self::Double, + } + } + + /// Get the character used to represent this quote. + pub const fn as_char(self) -> char { + match self { + Self::Double => '"', + Self::Single => '\'', + } + } +} diff --git a/crates/ruff_linter/src/rules/flake8_quotes/snapshots/ruff_linter__rules__flake8_quotes__tests__require_doubles_over_singles_escaped.py.snap b/crates/ruff_linter/src/rules/flake8_quotes/snapshots/ruff_linter__rules__flake8_quotes__tests__require_doubles_over_singles_escaped.py.snap index a05a28bb5a43b..911eff0086edc 100644 --- a/crates/ruff_linter/src/rules/flake8_quotes/snapshots/ruff_linter__rules__flake8_quotes__tests__require_doubles_over_singles_escaped.py.snap +++ b/crates/ruff_linter/src/rules/flake8_quotes/snapshots/ruff_linter__rules__flake8_quotes__tests__require_doubles_over_singles_escaped.py.snap @@ -34,5 +34,184 @@ singles_escaped.py:9:5: Q003 [*] Change outer quotes to avoid escaping inner quo 9 |- "\"string\"" 9 |+ '"string"' 10 10 | ) +11 11 | +12 12 | # Same as above, but with f-strings + +singles_escaped.py:13:1: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +12 | # Same as above, but with f-strings +13 | f"This is a \"string\"" + | ^^^^^^^^^^^^^^^^^^^^^^^ Q003 +14 | f"'This' is a \"string\"" +15 | f'This is a "string"' + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +10 10 | ) +11 11 | +12 12 | # Same as above, but with f-strings +13 |-f"This is a \"string\"" + 13 |+f'This is a "string"' +14 14 | f"'This' is a \"string\"" +15 15 | f'This is a "string"' +16 16 | f'\'This\' is a "string"' + +singles_escaped.py:21:5: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +19 | foo = ( +20 | f"This is a" +21 | f"\"string\"" + | ^^^^^^^^^^^^^ Q003 +22 | ) + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +18 18 | fR"This is a \"string\"" +19 19 | foo = ( +20 20 | f"This is a" +21 |- f"\"string\"" + 21 |+ f'"string"' +22 22 | ) +23 23 | +24 24 | # Nested f-strings (Python 3.12+) + +singles_escaped.py:31:1: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +29 | # +30 | # but as the actual string itself is invalid pre 3.12, we don't catch it. +31 | f"\"foo\" {"foo"}" # Q003 + | ^^^^^^^^^^^^^^^^^^ Q003 +32 | f"\"foo\" {f"foo"}" # Q003 +33 | f"\"foo\" {f"\"foo\""} \"\"" # Q003 + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +28 28 | # f'"foo" {"nested"}' +29 29 | # +30 30 | # but as the actual string itself is invalid pre 3.12, we don't catch it. +31 |-f"\"foo\" {"foo"}" # Q003 + 31 |+f'"foo" {"foo"}' # Q003 +32 32 | f"\"foo\" {f"foo"}" # Q003 +33 33 | f"\"foo\" {f"\"foo\""} \"\"" # Q003 +34 34 | + +singles_escaped.py:32:1: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +30 | # but as the actual string itself is invalid pre 3.12, we don't catch it. +31 | f"\"foo\" {"foo"}" # Q003 +32 | f"\"foo\" {f"foo"}" # Q003 + | ^^^^^^^^^^^^^^^^^^^ Q003 +33 | f"\"foo\" {f"\"foo\""} \"\"" # Q003 + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +29 29 | # +30 30 | # but as the actual string itself is invalid pre 3.12, we don't catch it. +31 31 | f"\"foo\" {"foo"}" # Q003 +32 |-f"\"foo\" {f"foo"}" # Q003 + 32 |+f'"foo" {f"foo"}' # Q003 +33 33 | f"\"foo\" {f"\"foo\""} \"\"" # Q003 +34 34 | +35 35 | f"normal {f"nested"} normal" + +singles_escaped.py:33:1: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +31 | f"\"foo\" {"foo"}" # Q003 +32 | f"\"foo\" {f"foo"}" # Q003 +33 | f"\"foo\" {f"\"foo\""} \"\"" # Q003 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Q003 +34 | +35 | f"normal {f"nested"} normal" + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +30 30 | # but as the actual string itself is invalid pre 3.12, we don't catch it. +31 31 | f"\"foo\" {"foo"}" # Q003 +32 32 | f"\"foo\" {f"foo"}" # Q003 +33 |-f"\"foo\" {f"\"foo\""} \"\"" # Q003 + 33 |+f'"foo" {f"\"foo\""} ""' # Q003 +34 34 | +35 35 | f"normal {f"nested"} normal" +36 36 | f"\"normal\" {f"nested"} normal" # Q003 + +singles_escaped.py:33:12: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +31 | f"\"foo\" {"foo"}" # Q003 +32 | f"\"foo\" {f"foo"}" # Q003 +33 | f"\"foo\" {f"\"foo\""} \"\"" # Q003 + | ^^^^^^^^^^ Q003 +34 | +35 | f"normal {f"nested"} normal" + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +30 30 | # but as the actual string itself is invalid pre 3.12, we don't catch it. +31 31 | f"\"foo\" {"foo"}" # Q003 +32 32 | f"\"foo\" {f"foo"}" # Q003 +33 |-f"\"foo\" {f"\"foo\""} \"\"" # Q003 + 33 |+f"\"foo\" {f'"foo"'} \"\"" # Q003 +34 34 | +35 35 | f"normal {f"nested"} normal" +36 36 | f"\"normal\" {f"nested"} normal" # Q003 + +singles_escaped.py:36:1: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +35 | f"normal {f"nested"} normal" +36 | f"\"normal\" {f"nested"} normal" # Q003 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Q003 +37 | f"\"normal\" {f"nested"} 'single quotes'" +38 | f"\"normal\" {f"\"nested\" {"other"} normal"} 'single quotes'" # Q003 + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +33 33 | f"\"foo\" {f"\"foo\""} \"\"" # Q003 +34 34 | +35 35 | f"normal {f"nested"} normal" +36 |-f"\"normal\" {f"nested"} normal" # Q003 + 36 |+f'"normal" {f"nested"} normal' # Q003 +37 37 | f"\"normal\" {f"nested"} 'single quotes'" +38 38 | f"\"normal\" {f"\"nested\" {"other"} normal"} 'single quotes'" # Q003 +39 39 | f"\"normal\" {f"\"nested\" {"other"} 'single quotes'"} normal" # Q003 + +singles_escaped.py:38:15: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +36 | f"\"normal\" {f"nested"} normal" # Q003 +37 | f"\"normal\" {f"nested"} 'single quotes'" +38 | f"\"normal\" {f"\"nested\" {"other"} normal"} 'single quotes'" # Q003 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Q003 +39 | f"\"normal\" {f"\"nested\" {"other"} 'single quotes'"} normal" # Q003 + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +35 35 | f"normal {f"nested"} normal" +36 36 | f"\"normal\" {f"nested"} normal" # Q003 +37 37 | f"\"normal\" {f"nested"} 'single quotes'" +38 |-f"\"normal\" {f"\"nested\" {"other"} normal"} 'single quotes'" # Q003 + 38 |+f"\"normal\" {f'"nested" {"other"} normal'} 'single quotes'" # Q003 +39 39 | f"\"normal\" {f"\"nested\" {"other"} 'single quotes'"} normal" # Q003 + +singles_escaped.py:39:1: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +37 | f"\"normal\" {f"nested"} 'single quotes'" +38 | f"\"normal\" {f"\"nested\" {"other"} normal"} 'single quotes'" # Q003 +39 | f"\"normal\" {f"\"nested\" {"other"} 'single quotes'"} normal" # Q003 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Q003 + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +36 36 | f"\"normal\" {f"nested"} normal" # Q003 +37 37 | f"\"normal\" {f"nested"} 'single quotes'" +38 38 | f"\"normal\" {f"\"nested\" {"other"} normal"} 'single quotes'" # Q003 +39 |-f"\"normal\" {f"\"nested\" {"other"} 'single quotes'"} normal" # Q003 + 39 |+f'"normal" {f"\"nested\" {"other"} 'single quotes'"} normal' # Q003 diff --git a/crates/ruff_linter/src/rules/flake8_quotes/snapshots/ruff_linter__rules__flake8_quotes__tests__require_doubles_over_singles_escaped_py311.snap b/crates/ruff_linter/src/rules/flake8_quotes/snapshots/ruff_linter__rules__flake8_quotes__tests__require_doubles_over_singles_escaped_py311.snap new file mode 100644 index 0000000000000..0bc6a10ac635e --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_quotes/snapshots/ruff_linter__rules__flake8_quotes__tests__require_doubles_over_singles_escaped_py311.snap @@ -0,0 +1,80 @@ +--- +source: crates/ruff_linter/src/rules/flake8_quotes/mod.rs +--- +singles_escaped.py:1:26: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +1 | this_should_raise_Q003 = "This is a \"string\"" + | ^^^^^^^^^^^^^^^^^^^^^^ Q003 +2 | this_is_fine = "'This' is a \"string\"" +3 | this_is_fine = 'This is a "string"' + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +1 |-this_should_raise_Q003 = "This is a \"string\"" + 1 |+this_should_raise_Q003 = 'This is a "string"' +2 2 | this_is_fine = "'This' is a \"string\"" +3 3 | this_is_fine = 'This is a "string"' +4 4 | this_is_fine = '\'This\' is a "string"' + +singles_escaped.py:9:5: Q003 [*] Change outer quotes to avoid escaping inner quotes + | + 7 | this_should_raise = ( + 8 | "This is a" + 9 | "\"string\"" + | ^^^^^^^^^^^^ Q003 +10 | ) + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +6 6 | this_is_fine = R"This is a \"string\"" +7 7 | this_should_raise = ( +8 8 | "This is a" +9 |- "\"string\"" + 9 |+ '"string"' +10 10 | ) +11 11 | +12 12 | # Same as above, but with f-strings + +singles_escaped.py:13:1: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +12 | # Same as above, but with f-strings +13 | f"This is a \"string\"" + | ^^^^^^^^^^^^^^^^^^^^^^^ Q003 +14 | f"'This' is a \"string\"" +15 | f'This is a "string"' + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +10 10 | ) +11 11 | +12 12 | # Same as above, but with f-strings +13 |-f"This is a \"string\"" + 13 |+f'This is a "string"' +14 14 | f"'This' is a \"string\"" +15 15 | f'This is a "string"' +16 16 | f'\'This\' is a "string"' + +singles_escaped.py:21:5: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +19 | foo = ( +20 | f"This is a" +21 | f"\"string\"" + | ^^^^^^^^^^^^^ Q003 +22 | ) + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +18 18 | fR"This is a \"string\"" +19 19 | foo = ( +20 20 | f"This is a" +21 |- f"\"string\"" + 21 |+ f'"string"' +22 22 | ) +23 23 | +24 24 | # Nested f-strings (Python 3.12+) + + diff --git a/crates/ruff_linter/src/rules/flake8_quotes/snapshots/ruff_linter__rules__flake8_quotes__tests__require_singles_over_doubles_escaped.py.snap b/crates/ruff_linter/src/rules/flake8_quotes/snapshots/ruff_linter__rules__flake8_quotes__tests__require_singles_over_doubles_escaped.py.snap index ccc63c71d3149..c5d6253904ff6 100644 --- a/crates/ruff_linter/src/rules/flake8_quotes/snapshots/ruff_linter__rules__flake8_quotes__tests__require_singles_over_doubles_escaped.py.snap +++ b/crates/ruff_linter/src/rules/flake8_quotes/snapshots/ruff_linter__rules__flake8_quotes__tests__require_singles_over_doubles_escaped.py.snap @@ -52,5 +52,205 @@ doubles_escaped.py:10:5: Q003 [*] Change outer quotes to avoid escaping inner qu 10 |- '\'string\'' 10 |+ "'string'" 11 11 | ) +12 12 | +13 13 | # Same as above, but with f-strings + +doubles_escaped.py:14:1: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +13 | # Same as above, but with f-strings +14 | f'This is a \'string\'' # Q003 + | ^^^^^^^^^^^^^^^^^^^^^^^ Q003 +15 | f'This is \\ a \\\'string\'' # Q003 +16 | f'"This" is a \'string\'' + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +11 11 | ) +12 12 | +13 13 | # Same as above, but with f-strings +14 |-f'This is a \'string\'' # Q003 + 14 |+f"This is a 'string'" # Q003 +15 15 | f'This is \\ a \\\'string\'' # Q003 +16 16 | f'"This" is a \'string\'' +17 17 | f"This is a 'string'" + +doubles_escaped.py:15:1: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +13 | # Same as above, but with f-strings +14 | f'This is a \'string\'' # Q003 +15 | f'This is \\ a \\\'string\'' # Q003 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Q003 +16 | f'"This" is a \'string\'' +17 | f"This is a 'string'" + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +12 12 | +13 13 | # Same as above, but with f-strings +14 14 | f'This is a \'string\'' # Q003 +15 |-f'This is \\ a \\\'string\'' # Q003 + 15 |+f"This is \\ a \\'string'" # Q003 +16 16 | f'"This" is a \'string\'' +17 17 | f"This is a 'string'" +18 18 | f"\"This\" is a 'string'" + +doubles_escaped.py:23:5: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +21 | foo = ( +22 | f'This is a' +23 | f'\'string\'' # Q003 + | ^^^^^^^^^^^^^ Q003 +24 | ) + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +20 20 | fR'This is a \'string\'' +21 21 | foo = ( +22 22 | f'This is a' +23 |- f'\'string\'' # Q003 + 23 |+ f"'string'" # Q003 +24 24 | ) +25 25 | +26 26 | # Nested f-strings (Python 3.12+) + +doubles_escaped.py:33:1: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +31 | # +32 | # but as the actual string itself is invalid pre 3.12, we don't catch it. +33 | f'\'foo\' {'nested'}' # Q003 + | ^^^^^^^^^^^^^^^^^^^^^ Q003 +34 | f'\'foo\' {f'nested'}' # Q003 +35 | f'\'foo\' {f'\'nested\''} \'\'' # Q003 + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +30 30 | # f"'foo' {'nested'}" +31 31 | # +32 32 | # but as the actual string itself is invalid pre 3.12, we don't catch it. +33 |-f'\'foo\' {'nested'}' # Q003 + 33 |+f"'foo' {'nested'}" # Q003 +34 34 | f'\'foo\' {f'nested'}' # Q003 +35 35 | f'\'foo\' {f'\'nested\''} \'\'' # Q003 +36 36 | + +doubles_escaped.py:34:1: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +32 | # but as the actual string itself is invalid pre 3.12, we don't catch it. +33 | f'\'foo\' {'nested'}' # Q003 +34 | f'\'foo\' {f'nested'}' # Q003 + | ^^^^^^^^^^^^^^^^^^^^^^ Q003 +35 | f'\'foo\' {f'\'nested\''} \'\'' # Q003 + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +31 31 | # +32 32 | # but as the actual string itself is invalid pre 3.12, we don't catch it. +33 33 | f'\'foo\' {'nested'}' # Q003 +34 |-f'\'foo\' {f'nested'}' # Q003 + 34 |+f"'foo' {f'nested'}" # Q003 +35 35 | f'\'foo\' {f'\'nested\''} \'\'' # Q003 +36 36 | +37 37 | f'normal {f'nested'} normal' + +doubles_escaped.py:35:1: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +33 | f'\'foo\' {'nested'}' # Q003 +34 | f'\'foo\' {f'nested'}' # Q003 +35 | f'\'foo\' {f'\'nested\''} \'\'' # Q003 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Q003 +36 | +37 | f'normal {f'nested'} normal' + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +32 32 | # but as the actual string itself is invalid pre 3.12, we don't catch it. +33 33 | f'\'foo\' {'nested'}' # Q003 +34 34 | f'\'foo\' {f'nested'}' # Q003 +35 |-f'\'foo\' {f'\'nested\''} \'\'' # Q003 + 35 |+f"'foo' {f'\'nested\''} ''" # Q003 +36 36 | +37 37 | f'normal {f'nested'} normal' +38 38 | f'\'normal\' {f'nested'} normal' # Q003 + +doubles_escaped.py:35:12: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +33 | f'\'foo\' {'nested'}' # Q003 +34 | f'\'foo\' {f'nested'}' # Q003 +35 | f'\'foo\' {f'\'nested\''} \'\'' # Q003 + | ^^^^^^^^^^^^^ Q003 +36 | +37 | f'normal {f'nested'} normal' + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +32 32 | # but as the actual string itself is invalid pre 3.12, we don't catch it. +33 33 | f'\'foo\' {'nested'}' # Q003 +34 34 | f'\'foo\' {f'nested'}' # Q003 +35 |-f'\'foo\' {f'\'nested\''} \'\'' # Q003 + 35 |+f'\'foo\' {f"'nested'"} \'\'' # Q003 +36 36 | +37 37 | f'normal {f'nested'} normal' +38 38 | f'\'normal\' {f'nested'} normal' # Q003 + +doubles_escaped.py:38:1: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +37 | f'normal {f'nested'} normal' +38 | f'\'normal\' {f'nested'} normal' # Q003 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Q003 +39 | f'\'normal\' {f'nested'} "double quotes"' +40 | f'\'normal\' {f'\'nested\' {'other'} normal'} "double quotes"' # Q003 + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +35 35 | f'\'foo\' {f'\'nested\''} \'\'' # Q003 +36 36 | +37 37 | f'normal {f'nested'} normal' +38 |-f'\'normal\' {f'nested'} normal' # Q003 + 38 |+f"'normal' {f'nested'} normal" # Q003 +39 39 | f'\'normal\' {f'nested'} "double quotes"' +40 40 | f'\'normal\' {f'\'nested\' {'other'} normal'} "double quotes"' # Q003 +41 41 | f'\'normal\' {f'\'nested\' {'other'} "double quotes"'} normal' # Q00l + +doubles_escaped.py:40:15: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +38 | f'\'normal\' {f'nested'} normal' # Q003 +39 | f'\'normal\' {f'nested'} "double quotes"' +40 | f'\'normal\' {f'\'nested\' {'other'} normal'} "double quotes"' # Q003 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Q003 +41 | f'\'normal\' {f'\'nested\' {'other'} "double quotes"'} normal' # Q00l + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +37 37 | f'normal {f'nested'} normal' +38 38 | f'\'normal\' {f'nested'} normal' # Q003 +39 39 | f'\'normal\' {f'nested'} "double quotes"' +40 |-f'\'normal\' {f'\'nested\' {'other'} normal'} "double quotes"' # Q003 + 40 |+f'\'normal\' {f"'nested' {'other'} normal"} "double quotes"' # Q003 +41 41 | f'\'normal\' {f'\'nested\' {'other'} "double quotes"'} normal' # Q00l + +doubles_escaped.py:41:1: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +39 | f'\'normal\' {f'nested'} "double quotes"' +40 | f'\'normal\' {f'\'nested\' {'other'} normal'} "double quotes"' # Q003 +41 | f'\'normal\' {f'\'nested\' {'other'} "double quotes"'} normal' # Q00l + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Q003 + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +38 38 | f'\'normal\' {f'nested'} normal' # Q003 +39 39 | f'\'normal\' {f'nested'} "double quotes"' +40 40 | f'\'normal\' {f'\'nested\' {'other'} normal'} "double quotes"' # Q003 +41 |-f'\'normal\' {f'\'nested\' {'other'} "double quotes"'} normal' # Q00l + 41 |+f"'normal' {f'\'nested\' {'other'} "double quotes"'} normal" # Q00l diff --git a/crates/ruff_linter/src/rules/flake8_quotes/snapshots/ruff_linter__rules__flake8_quotes__tests__require_singles_over_doubles_escaped_py311.snap b/crates/ruff_linter/src/rules/flake8_quotes/snapshots/ruff_linter__rules__flake8_quotes__tests__require_singles_over_doubles_escaped_py311.snap new file mode 100644 index 0000000000000..32f3d219be247 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_quotes/snapshots/ruff_linter__rules__flake8_quotes__tests__require_singles_over_doubles_escaped_py311.snap @@ -0,0 +1,119 @@ +--- +source: crates/ruff_linter/src/rules/flake8_quotes/mod.rs +--- +doubles_escaped.py:1:26: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +1 | this_should_raise_Q003 = 'This is a \'string\'' + | ^^^^^^^^^^^^^^^^^^^^^^ Q003 +2 | this_should_raise_Q003 = 'This is \\ a \\\'string\'' +3 | this_is_fine = '"This" is a \'string\'' + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +1 |-this_should_raise_Q003 = 'This is a \'string\'' + 1 |+this_should_raise_Q003 = "This is a 'string'" +2 2 | this_should_raise_Q003 = 'This is \\ a \\\'string\'' +3 3 | this_is_fine = '"This" is a \'string\'' +4 4 | this_is_fine = "This is a 'string'" + +doubles_escaped.py:2:26: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +1 | this_should_raise_Q003 = 'This is a \'string\'' +2 | this_should_raise_Q003 = 'This is \\ a \\\'string\'' + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Q003 +3 | this_is_fine = '"This" is a \'string\'' +4 | this_is_fine = "This is a 'string'" + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +1 1 | this_should_raise_Q003 = 'This is a \'string\'' +2 |-this_should_raise_Q003 = 'This is \\ a \\\'string\'' + 2 |+this_should_raise_Q003 = "This is \\ a \\'string'" +3 3 | this_is_fine = '"This" is a \'string\'' +4 4 | this_is_fine = "This is a 'string'" +5 5 | this_is_fine = "\"This\" is a 'string'" + +doubles_escaped.py:10:5: Q003 [*] Change outer quotes to avoid escaping inner quotes + | + 8 | this_should_raise = ( + 9 | 'This is a' +10 | '\'string\'' + | ^^^^^^^^^^^^ Q003 +11 | ) + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +7 7 | this_is_fine = R'This is a \'string\'' +8 8 | this_should_raise = ( +9 9 | 'This is a' +10 |- '\'string\'' + 10 |+ "'string'" +11 11 | ) +12 12 | +13 13 | # Same as above, but with f-strings + +doubles_escaped.py:14:1: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +13 | # Same as above, but with f-strings +14 | f'This is a \'string\'' # Q003 + | ^^^^^^^^^^^^^^^^^^^^^^^ Q003 +15 | f'This is \\ a \\\'string\'' # Q003 +16 | f'"This" is a \'string\'' + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +11 11 | ) +12 12 | +13 13 | # Same as above, but with f-strings +14 |-f'This is a \'string\'' # Q003 + 14 |+f"This is a 'string'" # Q003 +15 15 | f'This is \\ a \\\'string\'' # Q003 +16 16 | f'"This" is a \'string\'' +17 17 | f"This is a 'string'" + +doubles_escaped.py:15:1: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +13 | # Same as above, but with f-strings +14 | f'This is a \'string\'' # Q003 +15 | f'This is \\ a \\\'string\'' # Q003 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Q003 +16 | f'"This" is a \'string\'' +17 | f"This is a 'string'" + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +12 12 | +13 13 | # Same as above, but with f-strings +14 14 | f'This is a \'string\'' # Q003 +15 |-f'This is \\ a \\\'string\'' # Q003 + 15 |+f"This is \\ a \\'string'" # Q003 +16 16 | f'"This" is a \'string\'' +17 17 | f"This is a 'string'" +18 18 | f"\"This\" is a 'string'" + +doubles_escaped.py:23:5: Q003 [*] Change outer quotes to avoid escaping inner quotes + | +21 | foo = ( +22 | f'This is a' +23 | f'\'string\'' # Q003 + | ^^^^^^^^^^^^^ Q003 +24 | ) + | + = help: Change outer quotes to avoid escaping inner quotes + +ℹ Fix +20 20 | fR'This is a \'string\'' +21 21 | foo = ( +22 22 | f'This is a' +23 |- f'\'string\'' # Q003 + 23 |+ f"'string'" # Q003 +24 24 | ) +25 25 | +26 26 | # Nested f-strings (Python 3.12+) + + diff --git a/crates/ruff_linter/src/rules/flake8_raise/rules/unnecessary_paren_on_raise_exception.rs b/crates/ruff_linter/src/rules/flake8_raise/rules/unnecessary_paren_on_raise_exception.rs index 2b8895dc60f3d..2fde8e5a8f320 100644 --- a/crates/ruff_linter/src/rules/flake8_raise/rules/unnecessary_paren_on_raise_exception.rs +++ b/crates/ruff_linter/src/rules/flake8_raise/rules/unnecessary_paren_on_raise_exception.rs @@ -1,10 +1,10 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Expr}; +use ruff_python_semantic::BindingKind; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for unnecessary parentheses on raised exceptions. @@ -16,6 +16,16 @@ use crate::registry::AsRule; /// /// Removing the parentheses makes the code more concise. /// +/// ## Known problems +/// Parentheses can only be omitted if the exception is a class, as opposed to +/// a function call. This rule isn't always capable of distinguishing between +/// the two. +/// +/// For example, if you import a function `module.get_exception` from another +/// module, and `module.get_exception` returns an exception object, this rule will +/// incorrectly mark the parentheses in `raise module.get_exception()` as +/// unnecessary. +/// /// ## Example /// ```python /// raise TypeError() @@ -31,13 +41,13 @@ use crate::registry::AsRule; #[violation] pub struct UnnecessaryParenOnRaiseException; -impl AlwaysAutofixableViolation for UnnecessaryParenOnRaiseException { +impl AlwaysFixableViolation for UnnecessaryParenOnRaiseException { #[derive_message_formats] fn message(&self) -> String { format!("Unnecessary parentheses on raised exception") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { format!("Remove unnecessary parentheses") } } @@ -55,46 +65,63 @@ pub(crate) fn unnecessary_paren_on_raise_exception(checker: &mut Checker, expr: if arguments.is_empty() { // `raise func()` still requires parentheses; only `raise Class()` does not. - if checker - .semantic() - .lookup_attribute(func) - .is_some_and(|id| checker.semantic().binding(id).kind.is_function_definition()) - { - return; - } + let exception_type = if let Some(id) = checker.semantic().lookup_attribute(func) { + match checker.semantic().binding(id).kind { + BindingKind::FunctionDefinition(_) => return, + BindingKind::ClassDefinition(_) => Some(ExceptionType::Class), + BindingKind::Builtin => Some(ExceptionType::Builtin), + _ => None, + } + } else { + None + }; // `ctypes.WinError()` is a function, not a class. It's part of the standard library, so // we might as well get it right. - if checker - .semantic() - .resolve_call_path(func) - .is_some_and(|call_path| matches!(call_path.as_slice(), ["ctypes", "WinError"])) + if exception_type + .as_ref() + .is_some_and(ExceptionType::is_builtin) + && checker + .semantic() + .resolve_call_path(func) + .is_some_and(|call_path| matches!(call_path.as_slice(), ["ctypes", "WinError"])) { return; } let mut diagnostic = Diagnostic::new(UnnecessaryParenOnRaiseException, arguments.range()); - if checker.patch(diagnostic.kind.rule()) { - // If the arguments are immediately followed by a `from`, insert whitespace to avoid - // a syntax error, as in: - // ```python - // raise IndexError()from ZeroDivisionError - // ``` - if checker - .locator() - .after(arguments.end()) - .chars() - .next() - .is_some_and(char::is_alphanumeric) - { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - " ".to_string(), - arguments.range(), - ))); + + // If the arguments are immediately followed by a `from`, insert whitespace to avoid + // a syntax error, as in: + // ```python + // raise IndexError()from ZeroDivisionError + // ``` + if checker + .locator() + .after(arguments.end()) + .chars() + .next() + .is_some_and(char::is_alphanumeric) + { + diagnostic.set_fix(if exception_type.is_some() { + Fix::safe_edit(Edit::range_replacement(" ".to_string(), arguments.range())) } else { - diagnostic.set_fix(Fix::automatic(Edit::range_deletion(arguments.range()))); - } + Fix::unsafe_edit(Edit::range_replacement(" ".to_string(), arguments.range())) + }); + } else { + diagnostic.set_fix(if exception_type.is_some() { + Fix::safe_edit(Edit::range_deletion(arguments.range())) + } else { + Fix::unsafe_edit(Edit::range_deletion(arguments.range())) + }); } + checker.diagnostics.push(diagnostic); } } + +#[derive(Debug, is_macro::Is)] +enum ExceptionType { + Class, + Builtin, +} diff --git a/crates/ruff_linter/src/rules/flake8_raise/snapshots/ruff_linter__rules__flake8_raise__tests__unnecessary-paren-on-raise-exception_RSE102.py.snap b/crates/ruff_linter/src/rules/flake8_raise/snapshots/ruff_linter__rules__flake8_raise__tests__unnecessary-paren-on-raise-exception_RSE102.py.snap index 4a87268b618c9..7c839f78592e4 100644 --- a/crates/ruff_linter/src/rules/flake8_raise/snapshots/ruff_linter__rules__flake8_raise__tests__unnecessary-paren-on-raise-exception_RSE102.py.snap +++ b/crates/ruff_linter/src/rules/flake8_raise/snapshots/ruff_linter__rules__flake8_raise__tests__unnecessary-paren-on-raise-exception_RSE102.py.snap @@ -238,6 +238,7 @@ RSE102.py:79:17: RSE102 [*] Unnecessary parentheses on raised exception 79 |+raise IndexError from ZeroDivisionError 80 80 | 81 81 | raise IndexError(); +82 82 | RSE102.py:81:17: RSE102 [*] Unnecessary parentheses on raised exception | @@ -245,6 +246,8 @@ RSE102.py:81:17: RSE102 [*] Unnecessary parentheses on raised exception 80 | 81 | raise IndexError(); | ^^ RSE102 +82 | +83 | # RSE102 | = help: Remove unnecessary parentheses @@ -254,5 +257,23 @@ RSE102.py:81:17: RSE102 [*] Unnecessary parentheses on raised exception 80 80 | 81 |-raise IndexError(); 81 |+raise IndexError; +82 82 | +83 83 | # RSE102 +84 84 | raise Foo() + +RSE102.py:84:10: RSE102 [*] Unnecessary parentheses on raised exception + | +83 | # RSE102 +84 | raise Foo() + | ^^ RSE102 + | + = help: Remove unnecessary parentheses + +ℹ Suggested fix +81 81 | raise IndexError(); +82 82 | +83 83 | # RSE102 +84 |-raise Foo() + 84 |+raise Foo diff --git a/crates/ruff_linter/src/rules/flake8_return/rules/function.rs b/crates/ruff_linter/src/rules/flake8_return/rules/function.rs index a3002e9bac758..eed24b12d6d33 100644 --- a/crates/ruff_linter/src/rules/flake8_return/rules/function.rs +++ b/crates/ruff_linter/src/rules/flake8_return/rules/function.rs @@ -3,7 +3,7 @@ use std::ops::Add; use ruff_python_ast::{self as ast, ElifElseClause, Expr, Stmt}; use ruff_text_size::{Ranged, TextRange, TextSize}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Violation}; use ruff_diagnostics::{Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::is_const_none; @@ -14,8 +14,8 @@ use ruff_python_ast::whitespace::indentation; use ruff_python_semantic::SemanticModel; use ruff_python_trivia::is_python_whitespace; -use crate::autofix::edits; use crate::checkers::ast::Checker; +use crate::fix::edits; use crate::registry::{AsRule, Rule}; use crate::rules::flake8_return::helpers::end_of_last_statement; @@ -51,7 +51,7 @@ use super::super::visitor::{ReturnVisitor, Stack}; #[violation] pub struct UnnecessaryReturnNone; -impl AlwaysAutofixableViolation for UnnecessaryReturnNone { +impl AlwaysFixableViolation for UnnecessaryReturnNone { #[derive_message_formats] fn message(&self) -> String { format!( @@ -59,7 +59,7 @@ impl AlwaysAutofixableViolation for UnnecessaryReturnNone { ) } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove explicit `return None`".to_string() } } @@ -93,13 +93,13 @@ impl AlwaysAutofixableViolation for UnnecessaryReturnNone { #[violation] pub struct ImplicitReturnValue; -impl AlwaysAutofixableViolation for ImplicitReturnValue { +impl AlwaysFixableViolation for ImplicitReturnValue { #[derive_message_formats] fn message(&self) -> String { format!("Do not implicitly `return None` in function able to return non-`None` value") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Add explicit `None` return value".to_string() } } @@ -131,13 +131,13 @@ impl AlwaysAutofixableViolation for ImplicitReturnValue { #[violation] pub struct ImplicitReturn; -impl AlwaysAutofixableViolation for ImplicitReturn { +impl AlwaysFixableViolation for ImplicitReturn { #[derive_message_formats] fn message(&self) -> String { format!("Missing explicit `return` at the end of function able to return non-`None` value") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Add explicit `return` statement".to_string() } } @@ -167,14 +167,14 @@ pub struct UnnecessaryAssign { name: String, } -impl AlwaysAutofixableViolation for UnnecessaryAssign { +impl AlwaysFixableViolation for UnnecessaryAssign { #[derive_message_formats] fn message(&self) -> String { let UnnecessaryAssign { name } = self; format!("Unnecessary assignment to `{name}` before `return` statement") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove unnecessary assignment".to_string() } } @@ -345,12 +345,10 @@ fn unnecessary_return_none(checker: &mut Checker, stack: &Stack) { continue; } let mut diagnostic = Diagnostic::new(UnnecessaryReturnNone, stmt.range); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - "return".to_string(), - stmt.range(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "return".to_string(), + stmt.range(), + ))); checker.diagnostics.push(diagnostic); } } @@ -362,12 +360,10 @@ fn implicit_return_value(checker: &mut Checker, stack: &Stack) { continue; } let mut diagnostic = Diagnostic::new(ImplicitReturnValue, stmt.range); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - "return None".to_string(), - stmt.range, - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "return None".to_string(), + stmt.range, + ))); checker.diagnostics.push(diagnostic); } } @@ -409,17 +405,15 @@ fn implicit_return(checker: &mut Checker, stmt: &Stmt) { None | Some(ast::ElifElseClause { test: Some(_), .. }) ) { let mut diagnostic = Diagnostic::new(ImplicitReturn, stmt.range()); - if checker.patch(diagnostic.kind.rule()) { - if let Some(indent) = indentation(checker.locator(), stmt) { - let mut content = String::new(); - content.push_str(checker.stylist().line_ending().as_str()); - content.push_str(indent); - content.push_str("return None"); - diagnostic.set_fix(Fix::suggested(Edit::insertion( - content, - end_of_last_statement(stmt, checker.locator()), - ))); - } + if let Some(indent) = indentation(checker.locator(), stmt) { + let mut content = String::new(); + content.push_str(checker.stylist().line_ending().as_str()); + content.push_str(indent); + content.push_str("return None"); + diagnostic.set_fix(Fix::unsafe_edit(Edit::insertion( + content, + end_of_last_statement(stmt, checker.locator()), + ))); } checker.diagnostics.push(diagnostic); } @@ -431,17 +425,15 @@ fn implicit_return(checker: &mut Checker, stmt: &Stmt) { implicit_return(checker, last_stmt); } else { let mut diagnostic = Diagnostic::new(ImplicitReturn, stmt.range()); - if checker.patch(diagnostic.kind.rule()) { - if let Some(indent) = indentation(checker.locator(), stmt) { - let mut content = String::new(); - content.push_str(checker.stylist().line_ending().as_str()); - content.push_str(indent); - content.push_str("return None"); - diagnostic.set_fix(Fix::suggested(Edit::insertion( - content, - end_of_last_statement(stmt, checker.locator()), - ))); - } + if let Some(indent) = indentation(checker.locator(), stmt) { + let mut content = String::new(); + content.push_str(checker.stylist().line_ending().as_str()); + content.push_str(indent); + content.push_str("return None"); + diagnostic.set_fix(Fix::unsafe_edit(Edit::insertion( + content, + end_of_last_statement(stmt, checker.locator()), + ))); } checker.diagnostics.push(diagnostic); } @@ -467,17 +459,15 @@ fn implicit_return(checker: &mut Checker, stmt: &Stmt) { ) => {} _ => { let mut diagnostic = Diagnostic::new(ImplicitReturn, stmt.range()); - if checker.patch(diagnostic.kind.rule()) { - if let Some(indent) = indentation(checker.locator(), stmt) { - let mut content = String::new(); - content.push_str(checker.stylist().line_ending().as_str()); - content.push_str(indent); - content.push_str("return None"); - diagnostic.set_fix(Fix::suggested(Edit::insertion( - content, - end_of_last_statement(stmt, checker.locator()), - ))); - } + if let Some(indent) = indentation(checker.locator(), stmt) { + let mut content = String::new(); + content.push_str(checker.stylist().line_ending().as_str()); + content.push_str(indent); + content.push_str("return None"); + diagnostic.set_fix(Fix::unsafe_edit(Edit::insertion( + content, + end_of_last_statement(stmt, checker.locator()), + ))); } checker.diagnostics.push(diagnostic); } @@ -529,47 +519,45 @@ fn unnecessary_assign(checker: &mut Checker, stack: &Stack) { }, value.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - // Delete the `return` statement. There's no need to treat this as an isolated - // edit, since we're editing the preceding statement, so no conflicting edit would - // be allowed to remove that preceding statement. - let delete_return = - edits::delete_stmt(stmt, None, checker.locator(), checker.indexer()); - - // Replace the `x = 1` statement with `return 1`. - let content = checker.locator().slice(assign); - let equals_index = content - .find('=') - .ok_or(anyhow::anyhow!("expected '=' in assignment statement"))?; - let after_equals = equals_index + 1; - - let replace_assign = Edit::range_replacement( - // If necessary, add whitespace after the `return` keyword. - // Ex) Convert `x=y` to `return y` (instead of `returny`). - if content[after_equals..] - .chars() - .next() - .is_some_and(is_python_whitespace) - { - "return".to_string() - } else { - "return ".to_string() - }, - // Replace from the start of the assignment statement to the end of the equals - // sign. - TextRange::new( - assign.start(), - assign - .range() - .start() - .add(TextSize::try_from(after_equals)?), - ), - ); - - Ok(Fix::suggested_edits(replace_assign, [delete_return])) - }); - } + diagnostic.try_set_fix(|| { + // Delete the `return` statement. There's no need to treat this as an isolated + // edit, since we're editing the preceding statement, so no conflicting edit would + // be allowed to remove that preceding statement. + let delete_return = + edits::delete_stmt(stmt, None, checker.locator(), checker.indexer()); + + // Replace the `x = 1` statement with `return 1`. + let content = checker.locator().slice(assign); + let equals_index = content + .find('=') + .ok_or(anyhow::anyhow!("expected '=' in assignment statement"))?; + let after_equals = equals_index + 1; + + let replace_assign = Edit::range_replacement( + // If necessary, add whitespace after the `return` keyword. + // Ex) Convert `x=y` to `return y` (instead of `returny`). + if content[after_equals..] + .chars() + .next() + .is_some_and(is_python_whitespace) + { + "return".to_string() + } else { + "return ".to_string() + }, + // Replace from the start of the assignment statement to the end of the equals + // sign. + TextRange::new( + assign.start(), + assign + .range() + .start() + .add(TextSize::try_from(after_equals)?), + ), + ); + + Ok(Fix::unsafe_edits(replace_assign, [delete_return])) + }); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_return/snapshots/ruff_linter__rules__flake8_return__tests__RET504_RET504.py.snap b/crates/ruff_linter/src/rules/flake8_return/snapshots/ruff_linter__rules__flake8_return__tests__RET504_RET504.py.snap index 0d2fea7fe3a2e..c9bcc8798437d 100644 --- a/crates/ruff_linter/src/rules/flake8_return/snapshots/ruff_linter__rules__flake8_return__tests__RET504_RET504.py.snap +++ b/crates/ruff_linter/src/rules/flake8_return/snapshots/ruff_linter__rules__flake8_return__tests__RET504_RET504.py.snap @@ -131,7 +131,7 @@ RET504.py:342:12: RET504 [*] Unnecessary assignment to `b` before `return` state = help: Remove unnecessary assignment ℹ Suggested fix -338 338 | # Autofix cases +338 338 | # Fix cases 339 339 | def foo(): 340 340 | a = 1 341 |- b=a diff --git a/crates/ruff_linter/src/rules/flake8_simplify/mod.rs b/crates/ruff_linter/src/rules/flake8_simplify/mod.rs index 82a7d33c9b0c8..fe3eaecb8ddd3 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/mod.rs @@ -9,6 +9,7 @@ mod tests { use test_case::test_case; use crate::registry::Rule; + use crate::settings::types::PreviewMode; use crate::test::test_path; use crate::{assert_messages, settings}; @@ -53,4 +54,22 @@ mod tests { assert_messages!(snapshot, diagnostics); Ok(()) } + + #[test_case(Rule::IfElseBlockInsteadOfDictGet, Path::new("SIM401.py"))] + fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> { + let snapshot = format!( + "preview__{}_{}", + rule_code.noqa_code(), + path.to_string_lossy() + ); + let diagnostics = test_path( + Path::new("flake8_simplify").join(path).as_path(), + &settings::LinterSettings { + preview: PreviewMode::Enabled, + ..settings::LinterSettings::for_rule(rule_code) + }, + )?; + assert_messages!(snapshot, diagnostics); + Ok(()) + } } diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_bool_op.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_bool_op.rs index b60b5de1228c8..7694dd021cb33 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_bool_op.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_bool_op.rs @@ -5,17 +5,16 @@ use itertools::Either::{Left, Right}; use itertools::Itertools; use ruff_python_ast::{self as ast, Arguments, BoolOp, CmpOp, Expr, ExprContext, UnaryOp}; use ruff_text_size::{Ranged, TextRange}; -use rustc_hash::FxHashMap; -use ruff_diagnostics::{AlwaysAutofixableViolation, AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::comparable::ComparableExpr; use ruff_python_ast::helpers::{contains_effect, Truthiness}; use ruff_python_ast::parenthesize::parenthesized_range; use ruff_python_codegen::Generator; +use ruff_python_semantic::SemanticModel; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for multiple `isinstance` calls on the same target. @@ -49,7 +48,7 @@ pub struct DuplicateIsinstanceCall { } impl Violation for DuplicateIsinstanceCall { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -61,7 +60,7 @@ impl Violation for DuplicateIsinstanceCall { } } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let DuplicateIsinstanceCall { name } = self; Some(if let Some(name) = name { @@ -99,14 +98,14 @@ pub struct CompareWithTuple { replacement: String, } -impl AlwaysAutofixableViolation for CompareWithTuple { +impl AlwaysFixableViolation for CompareWithTuple { #[derive_message_formats] fn message(&self) -> String { let CompareWithTuple { replacement } = self; format!("Use `{replacement}` instead of multiple equality comparisons") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let CompareWithTuple { replacement } = self; format!("Replace with `{replacement}`") } @@ -132,14 +131,14 @@ pub struct ExprAndNotExpr { name: String, } -impl AlwaysAutofixableViolation for ExprAndNotExpr { +impl AlwaysFixableViolation for ExprAndNotExpr { #[derive_message_formats] fn message(&self) -> String { let ExprAndNotExpr { name } = self; format!("Use `False` instead of `{name} and not {name}`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace with `False`".to_string() } } @@ -164,14 +163,14 @@ pub struct ExprOrNotExpr { name: String, } -impl AlwaysAutofixableViolation for ExprOrNotExpr { +impl AlwaysFixableViolation for ExprOrNotExpr { #[derive_message_formats] fn message(&self) -> String { let ExprOrNotExpr { name } = self; format!("Use `True` instead of `{name} or not {name}`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace with `True`".to_string() } } @@ -217,7 +216,7 @@ pub struct ExprOrTrue { remove: ContentAround, } -impl AlwaysAutofixableViolation for ExprOrTrue { +impl AlwaysFixableViolation for ExprOrTrue { #[derive_message_formats] fn message(&self) -> String { let ExprOrTrue { expr, remove } = self; @@ -229,7 +228,7 @@ impl AlwaysAutofixableViolation for ExprOrTrue { format!("Use `{expr}` instead of `{replaced}`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let ExprOrTrue { expr, .. } = self; format!("Replace with `{expr}`") } @@ -269,7 +268,7 @@ pub struct ExprAndFalse { remove: ContentAround, } -impl AlwaysAutofixableViolation for ExprAndFalse { +impl AlwaysFixableViolation for ExprAndFalse { #[derive_message_formats] fn message(&self) -> String { let ExprAndFalse { expr, remove } = self; @@ -281,7 +280,7 @@ impl AlwaysAutofixableViolation for ExprAndFalse { format!("Use `{expr}` instead of `{replaced}`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let ExprAndFalse { expr, .. } = self; format!("Replace with `{expr}`") } @@ -299,6 +298,42 @@ fn is_same_expr<'a>(a: &'a Expr, b: &'a Expr) -> Option<&'a str> { None } +/// If `call` is an `isinstance()` call, return its target. +fn isinstance_target<'a>(call: &'a Expr, semantic: &'a SemanticModel) -> Option<&'a Expr> { + // Verify that this is an `isinstance` call. + let Expr::Call(ast::ExprCall { + func, + arguments: + Arguments { + args, + keywords, + range: _, + }, + range: _, + }) = &call + else { + return None; + }; + if args.len() != 2 { + return None; + } + if !keywords.is_empty() { + return None; + } + let Expr::Name(ast::ExprName { id: func_name, .. }) = func.as_ref() else { + return None; + }; + if func_name != "isinstance" { + return None; + } + if !semantic.is_builtin("isinstance") { + return None; + } + + // Collect the target (e.g., `obj` in `isinstance(obj, int)`). + Some(&args[0]) +} + /// SIM101 pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) { let Expr::BoolOp(ast::ExprBoolOp { @@ -310,50 +345,32 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) { return; }; - // Locate duplicate `isinstance` calls, represented as a map from `ComparableExpr` - // to indices of the relevant `Expr` instances in `values`. - let mut duplicates: FxHashMap> = FxHashMap::default(); + // Locate duplicate `isinstance` calls, represented as a vector of vectors + // of indices of the relevant `Expr` instances in `values`. + let mut duplicates: Vec> = Vec::new(); + let mut last_target_option: Option = None; for (index, call) in values.iter().enumerate() { - // Verify that this is an `isinstance` call. - let Expr::Call(ast::ExprCall { - func, - arguments: - Arguments { - args, - keywords, - range: _, - }, - range: _, - }) = &call - else { - continue; - }; - if args.len() != 2 { - continue; - } - if !keywords.is_empty() { - continue; - } - let Expr::Name(ast::ExprName { id: func_name, .. }) = func.as_ref() else { + let Some(target) = isinstance_target(call, checker.semantic()) else { + last_target_option = None; continue; }; - if func_name != "isinstance" { - continue; - } - if !checker.semantic().is_builtin("isinstance") { - continue; - } - // Collect the target (e.g., `obj` in `isinstance(obj, int)`). - let target = &args[0]; - duplicates - .entry(target.into()) - .or_insert_with(Vec::new) - .push(index); + if last_target_option + .as_ref() + .is_some_and(|last_target| *last_target == ComparableExpr::from(target)) + { + duplicates + .last_mut() + .expect("last_target should have a corresponding entry") + .push(index); + } else { + last_target_option = Some(target.into()); + duplicates.push(vec![index]); + } } // Generate a `Diagnostic` for each duplicate. - for indices in duplicates.values() { + for indices in duplicates { if indices.len() > 1 { // Grab the target used in each duplicate `isinstance` call (e.g., `obj` in // `isinstance(obj, int)`). @@ -376,81 +393,76 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) { }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if !contains_effect(target, |id| checker.semantic().is_builtin(id)) { - // Grab the types used in each duplicate `isinstance` call (e.g., `int` and `str` - // in `isinstance(obj, int) or isinstance(obj, str)`). - let types: Vec<&Expr> = indices + if !contains_effect(target, |id| checker.semantic().is_builtin(id)) { + // Grab the types used in each duplicate `isinstance` call (e.g., `int` and `str` + // in `isinstance(obj, int) or isinstance(obj, str)`). + let types: Vec<&Expr> = indices + .iter() + .map(|index| &values[*index]) + .map(|expr| { + let Expr::Call(ast::ExprCall { + arguments: Arguments { args, .. }, + .. + }) = expr + else { + unreachable!("Indices should only contain `isinstance` calls") + }; + args.get(1).expect("`isinstance` should have two arguments") + }) + .collect(); + + // Generate a single `isinstance` call. + let node = ast::ExprTuple { + // Flatten all the types used across the `isinstance` calls. + elts: types .iter() - .map(|index| &values[*index]) - .map(|expr| { - let Expr::Call(ast::ExprCall { - arguments: Arguments { args, .. }, - .. - }) = expr - else { - unreachable!("Indices should only contain `isinstance` calls") - }; - args.get(1).expect("`isinstance` should have two arguments") + .flat_map(|value| { + if let Expr::Tuple(ast::ExprTuple { elts, .. }) = value { + Left(elts.iter()) + } else { + Right(iter::once(*value)) + } }) - .collect(); - - // Generate a single `isinstance` call. - let node = ast::ExprTuple { - // Flatten all the types used across the `isinstance` calls. - elts: types - .iter() - .flat_map(|value| { - if let Expr::Tuple(ast::ExprTuple { elts, .. }) = value { - Left(elts.iter()) - } else { - Right(iter::once(*value)) - } - }) - .map(Clone::clone) - .collect(), - ctx: ExprContext::Load, - range: TextRange::default(), - }; - let node1 = ast::ExprName { - id: "isinstance".into(), - ctx: ExprContext::Load, - range: TextRange::default(), - }; - let node2 = ast::ExprCall { - func: Box::new(node1.into()), - arguments: Arguments { - args: vec![target.clone(), node.into()], - keywords: vec![], - range: TextRange::default(), - }, - range: TextRange::default(), - }; - let call = node2.into(); - - // Generate the combined `BoolOp`. - let node = ast::ExprBoolOp { - op: BoolOp::Or, - values: iter::once(call) - .chain( - values - .iter() - .enumerate() - .filter(|(index, _)| !indices.contains(index)) - .map(|(_, elt)| elt.clone()), - ) - .collect(), + .map(Clone::clone) + .collect(), + ctx: ExprContext::Load, + range: TextRange::default(), + }; + let node1 = ast::ExprName { + id: "isinstance".into(), + ctx: ExprContext::Load, + range: TextRange::default(), + }; + let node2 = ast::ExprCall { + func: Box::new(node1.into()), + arguments: Arguments { + args: vec![target.clone(), node.into()], + keywords: vec![], range: TextRange::default(), - }; - let bool_op = node.into(); - - // Populate the `Fix`. Replace the _entire_ `BoolOp`. Note that if we have - // multiple duplicates, the fixes will conflict. - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.generator().expr(&bool_op), - expr.range(), - ))); - } + }, + range: TextRange::default(), + }; + let call = node2.into(); + + // Generate the combined `BoolOp`. + let [first, .., last] = indices.as_slice() else { + unreachable!("Indices should have at least two elements") + }; + let before = values.iter().take(*first).cloned(); + let after = values.iter().skip(last + 1).cloned(); + let node = ast::ExprBoolOp { + op: BoolOp::Or, + values: before.chain(iter::once(call)).chain(after).collect(), + range: TextRange::default(), + }; + let bool_op = node.into(); + + // Populate the `Fix`. Replace the _entire_ `BoolOp`. Note that if we have + // multiple duplicates, the fixes will conflict. + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + checker.generator().expr(&bool_op), + expr.range(), + ))); } checker.diagnostics.push(diagnostic); } @@ -476,7 +488,7 @@ fn match_eq_target(expr: &Expr) -> Option<(&str, &Expr)> { let [comparator] = comparators.as_slice() else { return None; }; - if !matches!(&comparator, Expr::Name(_)) { + if !comparator.is_name_expr() { return None; } Some((id, comparator)) @@ -549,29 +561,27 @@ pub(crate) fn compare_with_tuple(checker: &mut Checker, expr: &Expr) { }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let unmatched: Vec = values - .iter() - .enumerate() - .filter(|(index, _)| !indices.contains(index)) - .map(|(_, elt)| elt.clone()) - .collect(); - let in_expr = if unmatched.is_empty() { - in_expr - } else { - // Wrap in a `x in (a, b) or ...` boolean operation. - let node = ast::ExprBoolOp { - op: BoolOp::Or, - values: iter::once(in_expr).chain(unmatched).collect(), - range: TextRange::default(), - }; - node.into() + let unmatched: Vec = values + .iter() + .enumerate() + .filter(|(index, _)| !indices.contains(index)) + .map(|(_, elt)| elt.clone()) + .collect(); + let in_expr = if unmatched.is_empty() { + in_expr + } else { + // Wrap in a `x in (a, b) or ...` boolean operation. + let node = ast::ExprBoolOp { + op: BoolOp::Or, + values: iter::once(in_expr).chain(unmatched).collect(), + range: TextRange::default(), }; - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.generator().expr(&in_expr), - expr.range(), - ))); - } + node.into() + }; + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + checker.generator().expr(&in_expr), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } } @@ -623,12 +633,10 @@ pub(crate) fn expr_and_not_expr(checker: &mut Checker, expr: &Expr) { }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - "False".to_string(), - expr.range(), - ))); - } + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + "False".to_string(), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } } @@ -682,12 +690,10 @@ pub(crate) fn expr_or_not_expr(checker: &mut Checker, expr: &Expr) { }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - "True".to_string(), - expr.range(), - ))); - } + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + "True".to_string(), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } } @@ -835,9 +841,7 @@ pub(crate) fn expr_or_true(checker: &mut Checker, expr: &Expr) { }, edit.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(edit)); - } + diagnostic.set_fix(Fix::unsafe_edit(edit)); checker.diagnostics.push(diagnostic); } } @@ -852,9 +856,7 @@ pub(crate) fn expr_and_false(checker: &mut Checker, expr: &Expr) { }, edit.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(edit)); - } + diagnostic.set_fix(Fix::unsafe_edit(edit)); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_expr.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_expr.rs index 40ac939d0bf5e..511a0e373b9a3 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_expr.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_expr.rs @@ -1,13 +1,12 @@ use ruff_python_ast::{self as ast, Arguments, Constant, Expr}; use ruff_text_size::{Ranged, TextRange}; -use crate::autofix::snippet::SourceCodeSnippet; -use ruff_diagnostics::{AlwaysAutofixableViolation, AutofixKind, Diagnostic, Edit, Fix, Violation}; +use crate::fix::snippet::SourceCodeSnippet; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::is_const_none; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Check for environment variables that are not capitalized. @@ -41,7 +40,7 @@ pub struct UncapitalizedEnvironmentVariables { } impl Violation for UncapitalizedEnvironmentVariables { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -53,7 +52,7 @@ impl Violation for UncapitalizedEnvironmentVariables { } } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let UncapitalizedEnvironmentVariables { expected, actual } = self; if let (Some(expected), Some(actual)) = (expected.full_display(), actual.full_display()) { Some(format!("Replace `{actual}` with `{expected}`")) @@ -90,7 +89,7 @@ pub struct DictGetWithNoneDefault { actual: SourceCodeSnippet, } -impl AlwaysAutofixableViolation for DictGetWithNoneDefault { +impl AlwaysFixableViolation for DictGetWithNoneDefault { #[derive_message_formats] fn message(&self) -> String { let DictGetWithNoneDefault { expected, actual } = self; @@ -101,7 +100,7 @@ impl AlwaysAutofixableViolation for DictGetWithNoneDefault { } } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let DictGetWithNoneDefault { expected, actual } = self; if let (Some(expected), Some(actual)) = (expected.full_display(), actual.full_display()) { format!("Replace `{actual}` with `{expected}`") @@ -111,6 +110,15 @@ impl AlwaysAutofixableViolation for DictGetWithNoneDefault { } } +/// Returns whether the given environment variable is allowed to be lowercase. +/// +/// References: +/// - +/// - +fn is_lowercase_allowed(env_var: &str) -> bool { + matches!(env_var, "https_proxy" | "http_proxy" | "no_proxy") +} + /// SIM112 pub(crate) fn use_capital_environment_variables(checker: &mut Checker, expr: &Expr) { // Ex) `os.environ['foo']` @@ -151,6 +159,10 @@ pub(crate) fn use_capital_environment_variables(checker: &mut Checker, expr: &Ex return; } + if is_lowercase_allowed(env_var) { + return; + } + let capital_env_var = env_var.to_ascii_uppercase(); if &capital_env_var == env_var { return; @@ -195,6 +207,11 @@ fn check_os_environ_subscript(checker: &mut Checker, expr: &Expr) { else { return; }; + + if is_lowercase_allowed(env_var) { + return; + } + let capital_env_var = env_var.to_ascii_uppercase(); if &capital_env_var == env_var { return; @@ -207,21 +224,19 @@ fn check_os_environ_subscript(checker: &mut Checker, expr: &Expr) { }, slice.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let node = ast::ExprConstant { - value: ast::Constant::Str(ast::StringConstant { - value: capital_env_var, - unicode: *unicode, - implicit_concatenated: false, - }), - range: TextRange::default(), - }; - let new_env_var = node.into(); - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.generator().expr(&new_env_var), - slice.range(), - ))); - } + let node = ast::ExprConstant { + value: ast::Constant::Str(ast::StringConstant { + value: capital_env_var, + unicode: *unicode, + implicit_concatenated: false, + }), + range: TextRange::default(), + }; + let new_env_var = node.into(); + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + checker.generator().expr(&new_env_var), + slice.range(), + ))); checker.diagnostics.push(diagnostic); } @@ -275,11 +290,9 @@ pub(crate) fn dict_get_with_none_default(checker: &mut Checker, expr: &Expr) { expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - expected, - expr.range(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + expected, + expr.range(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_if.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_if.rs deleted file mode 100644 index 3ceee59438b68..0000000000000 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_if.rs +++ /dev/null @@ -1,990 +0,0 @@ -use log::error; -use ruff_python_ast::{ - self as ast, Arguments, CmpOp, Constant, ElifElseClause, Expr, ExprContext, Identifier, Stmt, -}; -use ruff_text_size::{Ranged, TextRange}; -use rustc_hash::FxHashSet; - -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; -use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::comparable::{ComparableConstant, ComparableExpr, ComparableStmt}; -use ruff_python_ast::helpers::{any_over_expr, contains_effect}; -use ruff_python_ast::stmt_if::{if_elif_branches, IfElifBranch}; -use ruff_python_semantic::SemanticModel; -use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer}; -use ruff_source_file::{Locator, UniversalNewlines}; - -use crate::checkers::ast::Checker; -use crate::line_width::LineWidthBuilder; -use crate::registry::AsRule; -use crate::rules::flake8_simplify::rules::fix_if; - -fn compare_expr(expr1: &ComparableExpr, expr2: &ComparableExpr) -> bool { - expr1.eq(expr2) -} - -fn compare_stmt(stmt1: &ComparableStmt, stmt2: &ComparableStmt) -> bool { - stmt1.eq(stmt2) -} - -/// ## What it does -/// Checks for nested `if` statements that can be collapsed into a single `if` -/// statement. -/// -/// ## Why is this bad? -/// Nesting `if` statements leads to deeper indentation and makes code harder to -/// read. Instead, combine the conditions into a single `if` statement with an -/// `and` operator. -/// -/// ## Example -/// ```python -/// if foo: -/// if bar: -/// ... -/// ``` -/// -/// Use instead: -/// ```python -/// if foo and bar: -/// ... -/// ``` -/// -/// ## References -/// - [Python documentation: The `if` statement](https://docs.python.org/3/reference/compound_stmts.html#the-if-statement) -/// - [Python documentation: Boolean operations](https://docs.python.org/3/reference/expressions.html#boolean-operations) -#[violation] -pub struct CollapsibleIf; - -impl Violation for CollapsibleIf { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; - - #[derive_message_formats] - fn message(&self) -> String { - format!("Use a single `if` statement instead of nested `if` statements") - } - - fn autofix_title(&self) -> Option { - Some("Combine `if` statements using `and`".to_string()) - } -} - -/// ## What it does -/// Checks for `if` statements that can be replaced with `bool`. -/// -/// ## Why is this bad? -/// `if` statements that return `True` for a truthy condition and `False` for -/// a falsey condition can be replaced with boolean casts. -/// -/// ## Example -/// ```python -/// if foo: -/// return True -/// else: -/// return False -/// ``` -/// -/// Use instead: -/// ```python -/// return bool(foo) -/// ``` -/// -/// ## References -/// - [Python documentation: Truth Value Testing](https://docs.python.org/3/library/stdtypes.html#truth-value-testing) -#[violation] -pub struct NeedlessBool { - condition: String, -} - -impl Violation for NeedlessBool { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; - - #[derive_message_formats] - fn message(&self) -> String { - let NeedlessBool { condition } = self; - format!("Return the condition `{condition}` directly") - } - - fn autofix_title(&self) -> Option { - let NeedlessBool { condition } = self; - Some(format!("Replace with `return {condition}`")) - } -} - -/// ## What it does -/// Checks for three or more consecutive if-statements with direct returns -/// -/// ## Why is this bad? -/// These can be simplified by using a dictionary -/// -/// ## Example -/// ```python -/// if x == 1: -/// return "Hello" -/// elif x == 2: -/// return "Goodbye" -/// else: -/// return "Goodnight" -/// ``` -/// -/// Use instead: -/// ```python -/// return {1: "Hello", 2: "Goodbye"}.get(x, "Goodnight") -/// ``` -#[violation] -pub struct IfElseBlockInsteadOfDictLookup; - -impl Violation for IfElseBlockInsteadOfDictLookup { - #[derive_message_formats] - fn message(&self) -> String { - format!("Use a dictionary instead of consecutive `if` statements") - } -} - -/// ## What it does -/// Check for `if`-`else`-blocks that can be replaced with a ternary operator. -/// -/// ## Why is this bad? -/// `if`-`else`-blocks that assign a value to a variable in both branches can -/// be expressed more concisely by using a ternary operator. -/// -/// ## Example -/// ```python -/// if foo: -/// bar = x -/// else: -/// bar = y -/// ``` -/// -/// Use instead: -/// ```python -/// bar = x if foo else y -/// ``` -/// -/// ## References -/// - [Python documentation: Conditional expressions](https://docs.python.org/3/reference/expressions.html#conditional-expressions) -#[violation] -pub struct IfElseBlockInsteadOfIfExp { - contents: String, -} - -impl Violation for IfElseBlockInsteadOfIfExp { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; - - #[derive_message_formats] - fn message(&self) -> String { - let IfElseBlockInsteadOfIfExp { contents } = self; - format!("Use ternary operator `{contents}` instead of `if`-`else`-block") - } - - fn autofix_title(&self) -> Option { - let IfElseBlockInsteadOfIfExp { contents } = self; - Some(format!("Replace `if`-`else`-block with `{contents}`")) - } -} - -/// ## What it does -/// Checks for `if` branches with identical arm bodies. -/// -/// ## Why is this bad? -/// If multiple arms of an `if` statement have the same body, using `or` -/// better signals the intent of the statement. -/// -/// ## Example -/// ```python -/// if x == 1: -/// print("Hello") -/// elif x == 2: -/// print("Hello") -/// ``` -/// -/// Use instead: -/// ```python -/// if x == 1 or x == 2: -/// print("Hello") -/// ``` -#[violation] -pub struct IfWithSameArms; - -impl Violation for IfWithSameArms { - #[derive_message_formats] - fn message(&self) -> String { - format!("Combine `if` branches using logical `or` operator") - } -} - -/// ## What it does -/// Checks for `if` statements that can be replaced with `dict.get` calls. -/// -/// ## Why is this bad? -/// `dict.get()` calls can be used to replace `if` statements that assign a -/// value to a variable in both branches, falling back to a default value if -/// the key is not found. When possible, using `dict.get` is more concise and -/// more idiomatic. -/// -/// ## Example -/// ```python -/// if "bar" in foo: -/// value = foo["bar"] -/// else: -/// value = 0 -/// ``` -/// -/// Use instead: -/// ```python -/// value = foo.get("bar", 0) -/// ``` -/// -/// ## References -/// - [Python documentation: Mapping Types](https://docs.python.org/3/library/stdtypes.html#mapping-types-dict) -#[violation] -pub struct IfElseBlockInsteadOfDictGet { - contents: String, -} - -impl Violation for IfElseBlockInsteadOfDictGet { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; - - #[derive_message_formats] - fn message(&self) -> String { - let IfElseBlockInsteadOfDictGet { contents } = self; - format!("Use `{contents}` instead of an `if` block") - } - - fn autofix_title(&self) -> Option { - let IfElseBlockInsteadOfDictGet { contents } = self; - Some(format!("Replace with `{contents}`")) - } -} - -fn is_main_check(expr: &Expr) -> bool { - if let Expr::Compare(ast::ExprCompare { - left, comparators, .. - }) = expr - { - if let Expr::Name(ast::ExprName { id, .. }) = left.as_ref() { - if id == "__name__" { - if let [Expr::Constant(ast::ExprConstant { - value: Constant::Str(ast::StringConstant { value, .. }), - .. - })] = comparators.as_slice() - { - if value == "__main__" { - return true; - } - } - } - } - } - false -} - -/// Find the last nested if statement and return the test expression and the -/// last statement. -/// -/// ```python -/// if xxx: -/// if yyy: -/// # ^^^ returns this expression -/// z = 1 -/// # ^^^^^ and this statement -/// ... -/// ``` -fn find_last_nested_if(body: &[Stmt]) -> Option<(&Expr, &Stmt)> { - let [Stmt::If(ast::StmtIf { - test, - body: inner_body, - elif_else_clauses, - .. - })] = body - else { - return None; - }; - if !elif_else_clauses.is_empty() { - return None; - } - find_last_nested_if(inner_body).or_else(|| { - Some(( - test, - inner_body.last().expect("Expected body to be non-empty"), - )) - }) -} - -/// Returns the body, the range of the `if` or `elif` and whether the range is for an `if` or `elif` -fn nested_if_body(stmt_if: &ast::StmtIf) -> Option<(&[Stmt], TextRange, bool)> { - let ast::StmtIf { - test, - body, - elif_else_clauses, - .. - } = stmt_if; - - // It must be the last condition, otherwise there could be another `elif` or `else` that only - // depends on the outer of the two conditions - let (test, body, range, is_elif) = if let Some(clause) = elif_else_clauses.last() { - if let Some(test) = &clause.test { - (test, &clause.body, clause.range(), true) - } else { - // The last condition is an `else` (different rule) - return None; - } - } else { - (test.as_ref(), body, stmt_if.range(), false) - }; - - // The nested if must be the only child, otherwise there is at least one more statement that - // only depends on the outer condition - if body.len() > 1 { - return None; - } - - // Allow `if __name__ == "__main__":` statements. - if is_main_check(test) { - return None; - } - - // Allow `if True:` and `if False:` statements. - if matches!( - test, - Expr::Constant(ast::ExprConstant { - value: Constant::Bool(..), - .. - }) - ) { - return None; - } - - Some((body, range, is_elif)) -} - -/// SIM102 -pub(crate) fn nested_if_statements( - checker: &mut Checker, - stmt_if: &ast::StmtIf, - parent: Option<&Stmt>, -) { - let Some((body, range, is_elif)) = nested_if_body(stmt_if) else { - return; - }; - - // Find the deepest nested if-statement, to inform the range. - let Some((test, _first_stmt)) = find_last_nested_if(body) else { - return; - }; - - // Check if the parent is already emitting a larger diagnostic including this if statement - if let Some(Stmt::If(stmt_if)) = parent { - if let Some((body, _range, _is_elif)) = nested_if_body(stmt_if) { - // In addition to repeating the `nested_if_body` and `find_last_nested_if` check, we - // also need to be the first child in the parent - if matches!(&body[0], Stmt::If(inner) if inner == stmt_if) - && find_last_nested_if(body).is_some() - { - return; - } - } - } - - let Some(colon) = SimpleTokenizer::starts_at(test.end(), checker.locator().contents()) - .skip_trivia() - .find(|token| token.kind == SimpleTokenKind::Colon) - else { - return; - }; - - let mut diagnostic = Diagnostic::new(CollapsibleIf, TextRange::new(range.start(), colon.end())); - if checker.patch(diagnostic.kind.rule()) { - // The fixer preserves comments in the nested body, but removes comments between - // the outer and inner if statements. - let nested_if = &body[0]; - if !checker - .indexer() - .comment_ranges() - .intersects(TextRange::new(range.start(), nested_if.start())) - { - match fix_if::fix_nested_if_statements( - checker.locator(), - checker.stylist(), - range, - is_elif, - ) { - Ok(edit) => { - if edit - .content() - .unwrap_or_default() - .universal_newlines() - .all(|line| { - LineWidthBuilder::new(checker.settings.tab_size).add_str(&line) - <= checker.settings.line_length - }) - { - diagnostic.set_fix(Fix::suggested(edit)); - } - } - Err(err) => error!("Failed to fix nested if: {err}"), - } - } - } - checker.diagnostics.push(diagnostic); -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -enum Bool { - True, - False, -} - -impl From for Bool { - fn from(value: bool) -> Self { - if value { - Bool::True - } else { - Bool::False - } - } -} - -fn is_one_line_return_bool(stmts: &[Stmt]) -> Option { - let [stmt] = stmts else { - return None; - }; - let Stmt::Return(ast::StmtReturn { value, range: _ }) = stmt else { - return None; - }; - let Some(Expr::Constant(ast::ExprConstant { value, .. })) = value.as_deref() else { - return None; - }; - let Constant::Bool(value) = value else { - return None; - }; - Some((*value).into()) -} - -/// SIM103 -pub(crate) fn needless_bool(checker: &mut Checker, stmt: &Stmt) { - let Stmt::If(ast::StmtIf { - test: if_test, - body: if_body, - elif_else_clauses, - range: _, - }) = stmt - else { - return; - }; - // Extract an `if` or `elif` (that returns) followed by an else (that returns the same value) - let (if_test, if_body, else_body, range) = match elif_else_clauses.as_slice() { - // if-else case - [ElifElseClause { - body: else_body, - test: None, - .. - }] => (if_test.as_ref(), if_body, else_body, stmt.range()), - // elif-else case - [.., ElifElseClause { - body: elif_body, - test: Some(elif_test), - range: elif_range, - }, ElifElseClause { - body: else_body, - test: None, - range: else_range, - }] => ( - elif_test, - elif_body, - else_body, - TextRange::new(elif_range.start(), else_range.end()), - ), - _ => return, - }; - - let (Some(if_return), Some(else_return)) = ( - is_one_line_return_bool(if_body), - is_one_line_return_bool(else_body), - ) else { - return; - }; - - // If the branches have the same condition, abort (although the code could be - // simplified). - if if_return == else_return { - return; - } - - let condition = checker.generator().expr(if_test); - let mut diagnostic = Diagnostic::new(NeedlessBool { condition }, range); - if checker.patch(diagnostic.kind.rule()) { - if matches!(if_return, Bool::True) - && matches!(else_return, Bool::False) - && !checker.indexer().has_comments(&range, checker.locator()) - && (if_test.is_compare_expr() || checker.semantic().is_builtin("bool")) - { - if if_test.is_compare_expr() { - // If the condition is a comparison, we can replace it with the condition. - let node = ast::StmtReturn { - value: Some(Box::new(if_test.clone())), - range: TextRange::default(), - }; - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.generator().stmt(&node.into()), - range, - ))); - } else { - // Otherwise, we need to wrap the condition in a call to `bool`. (We've already - // verified, above, that `bool` is a builtin.) - let node = ast::ExprName { - id: "bool".into(), - ctx: ExprContext::Load, - range: TextRange::default(), - }; - let node1 = ast::ExprCall { - func: Box::new(node.into()), - arguments: Arguments { - args: vec![if_test.clone()], - keywords: vec![], - range: TextRange::default(), - }, - range: TextRange::default(), - }; - let node2 = ast::StmtReturn { - value: Some(Box::new(node1.into())), - range: TextRange::default(), - }; - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.generator().stmt(&node2.into()), - range, - ))); - }; - } - } - checker.diagnostics.push(diagnostic); -} - -fn ternary(target_var: &Expr, body_value: &Expr, test: &Expr, orelse_value: &Expr) -> Stmt { - let node = ast::ExprIfExp { - test: Box::new(test.clone()), - body: Box::new(body_value.clone()), - orelse: Box::new(orelse_value.clone()), - range: TextRange::default(), - }; - let node1 = ast::StmtAssign { - targets: vec![target_var.clone()], - value: Box::new(node.into()), - range: TextRange::default(), - }; - node1.into() -} - -/// Return `true` if the `Expr` contains a reference to any of the given `${module}.${target}`. -fn contains_call_path(expr: &Expr, targets: &[&[&str]], semantic: &SemanticModel) -> bool { - any_over_expr(expr, &|expr| { - semantic - .resolve_call_path(expr) - .is_some_and(|call_path| targets.iter().any(|target| &call_path.as_slice() == target)) - }) -} - -/// SIM108 -pub(crate) fn use_ternary_operator(checker: &mut Checker, stmt: &Stmt) { - let Stmt::If(ast::StmtIf { - test, - body, - elif_else_clauses, - range: _, - }) = stmt - else { - return; - }; - // `test: None` to only match an `else` clause - let [ElifElseClause { - body: else_body, - test: None, - .. - }] = elif_else_clauses.as_slice() - else { - return; - }; - let [Stmt::Assign(ast::StmtAssign { - targets: body_targets, - value: body_value, - .. - })] = body.as_slice() - else { - return; - }; - let [Stmt::Assign(ast::StmtAssign { - targets: else_targets, - value: else_value, - .. - })] = else_body.as_slice() - else { - return; - }; - let ([body_target], [else_target]) = (body_targets.as_slice(), else_targets.as_slice()) else { - return; - }; - let Expr::Name(ast::ExprName { id: body_id, .. }) = body_target else { - return; - }; - let Expr::Name(ast::ExprName { id: else_id, .. }) = else_target else { - return; - }; - if body_id != else_id { - return; - } - - // Avoid suggesting ternary for `if sys.version_info >= ...`-style and - // `if sys.platform.startswith("...")`-style checks. - let ignored_call_paths: &[&[&str]] = &[&["sys", "version_info"], &["sys", "platform"]]; - if contains_call_path(test, ignored_call_paths, checker.semantic()) { - return; - } - - // Avoid suggesting ternary for `if (yield ...)`-style checks. - // TODO(charlie): Fix precedence handling for yields in generator. - if matches!( - body_value.as_ref(), - Expr::Yield(_) | Expr::YieldFrom(_) | Expr::Await(_) - ) { - return; - } - if matches!( - else_value.as_ref(), - Expr::Yield(_) | Expr::YieldFrom(_) | Expr::Await(_) - ) { - return; - } - - let target_var = &body_target; - let ternary = ternary(target_var, body_value, test, else_value); - let contents = checker.generator().stmt(&ternary); - - // Don't flag if the resulting expression would exceed the maximum line length. - let line_start = checker.locator().line_start(stmt.start()); - if LineWidthBuilder::new(checker.settings.tab_size) - .add_str(&checker.locator().contents()[TextRange::new(line_start, stmt.start())]) - .add_str(&contents) - > checker.settings.line_length - { - return; - } - - let mut diagnostic = Diagnostic::new( - IfElseBlockInsteadOfIfExp { - contents: contents.clone(), - }, - stmt.range(), - ); - if checker.patch(diagnostic.kind.rule()) { - if !checker.indexer().has_comments(stmt, checker.locator()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - contents, - stmt.range(), - ))); - } - } - checker.diagnostics.push(diagnostic); -} - -/// Return the [`TextRange`] of an [`IfElifBranch`]'s body (from the end of the test to the end of -/// the body). -fn body_range(branch: &IfElifBranch, locator: &Locator) -> TextRange { - TextRange::new( - locator.line_end(branch.test.end()), - locator.line_end(branch.end()), - ) -} - -/// SIM114 -pub(crate) fn if_with_same_arms(checker: &mut Checker, locator: &Locator, stmt_if: &ast::StmtIf) { - let mut branches_iter = if_elif_branches(stmt_if).peekable(); - while let Some(current_branch) = branches_iter.next() { - let Some(following_branch) = branches_iter.peek() else { - continue; - }; - - // The bodies must have the same code ... - if current_branch.body.len() != following_branch.body.len() { - continue; - } - if !current_branch - .body - .iter() - .zip(following_branch.body.iter()) - .all(|(stmt1, stmt2)| compare_stmt(&stmt1.into(), &stmt2.into())) - { - continue; - } - - // ...and the same comments - let first_comments = checker - .indexer() - .comment_ranges() - .comments_in_range(body_range(¤t_branch, locator)) - .iter() - .map(|range| locator.slice(*range)); - let second_comments = checker - .indexer() - .comment_ranges() - .comments_in_range(body_range(following_branch, locator)) - .iter() - .map(|range| locator.slice(*range)); - if !first_comments.eq(second_comments) { - continue; - } - - checker.diagnostics.push(Diagnostic::new( - IfWithSameArms, - TextRange::new(current_branch.start(), following_branch.end()), - )); - } -} - -/// SIM116 -pub(crate) fn manual_dict_lookup(checker: &mut Checker, stmt_if: &ast::StmtIf) { - // Throughout this rule: - // * Each if or elif statement's test must consist of a constant equality check with the same variable. - // * Each if or elif statement's body must consist of a single `return`. - // * The else clause must be empty, or a single `return`. - let ast::StmtIf { - body, - test, - elif_else_clauses, - .. - } = stmt_if; - - let Expr::Compare(ast::ExprCompare { - left, - ops, - comparators, - range: _, - }) = test.as_ref() - else { - return; - }; - let Expr::Name(ast::ExprName { id: target, .. }) = left.as_ref() else { - return; - }; - if ops != &[CmpOp::Eq] { - return; - } - let [Expr::Constant(ast::ExprConstant { - value: constant, .. - })] = comparators.as_slice() - else { - return; - }; - let [Stmt::Return(ast::StmtReturn { value, range: _ })] = body.as_slice() else { - return; - }; - if value - .as_ref() - .is_some_and(|value| contains_effect(value, |id| checker.semantic().is_builtin(id))) - { - return; - } - - let mut constants: FxHashSet = FxHashSet::default(); - constants.insert(constant.into()); - - for clause in elif_else_clauses { - let ElifElseClause { test, body, .. } = clause; - let [Stmt::Return(ast::StmtReturn { value, range: _ })] = body.as_slice() else { - return; - }; - - match test.as_ref() { - // `else` - None => { - // The else must also be a single effect-free return statement - let [Stmt::Return(ast::StmtReturn { value, range: _ })] = body.as_slice() else { - return; - }; - if value.as_ref().is_some_and(|value| { - contains_effect(value, |id| checker.semantic().is_builtin(id)) - }) { - return; - }; - } - // `elif` - Some(Expr::Compare(ast::ExprCompare { - left, - ops, - comparators, - range: _, - })) => { - let Expr::Name(ast::ExprName { id, .. }) = left.as_ref() else { - return; - }; - if id != target || ops != &[CmpOp::Eq] { - return; - } - let [Expr::Constant(ast::ExprConstant { - value: constant, .. - })] = comparators.as_slice() - else { - return; - }; - - if value.as_ref().is_some_and(|value| { - contains_effect(value, |id| checker.semantic().is_builtin(id)) - }) { - return; - }; - - constants.insert(constant.into()); - } - // Different `elif` - _ => { - return; - } - } - } - - if constants.len() < 3 { - return; - } - - checker.diagnostics.push(Diagnostic::new( - IfElseBlockInsteadOfDictLookup, - stmt_if.range(), - )); -} - -/// SIM401 -pub(crate) fn use_dict_get_with_default(checker: &mut Checker, stmt_if: &ast::StmtIf) { - let ast::StmtIf { - test, - body, - elif_else_clauses, - .. - } = stmt_if; - - let [body_stmt] = body.as_slice() else { - return; - }; - let [ElifElseClause { - body: else_body, - test: None, - .. - }] = elif_else_clauses.as_slice() - else { - return; - }; - let [else_body_stmt] = else_body.as_slice() else { - return; - }; - let Stmt::Assign(ast::StmtAssign { - targets: body_var, - value: body_value, - .. - }) = &body_stmt - else { - return; - }; - let [body_var] = body_var.as_slice() else { - return; - }; - let Stmt::Assign(ast::StmtAssign { - targets: orelse_var, - value: orelse_value, - .. - }) = &else_body_stmt - else { - return; - }; - let [orelse_var] = orelse_var.as_slice() else { - return; - }; - let Expr::Compare(ast::ExprCompare { - left: test_key, - ops, - comparators: test_dict, - range: _, - }) = test.as_ref() - else { - return; - }; - let [test_dict] = test_dict.as_slice() else { - return; - }; - let (expected_var, expected_value, default_var, default_value) = match ops[..] { - [CmpOp::In] => (body_var, body_value, orelse_var, orelse_value.as_ref()), - [CmpOp::NotIn] => (orelse_var, orelse_value, body_var, body_value.as_ref()), - _ => { - return; - } - }; - let Expr::Subscript(ast::ExprSubscript { - value: expected_subscript, - slice: expected_slice, - .. - }) = expected_value.as_ref() - else { - return; - }; - - // Check that the dictionary key, target variables, and dictionary name are all - // equivalent. - if !compare_expr(&expected_slice.into(), &test_key.into()) - || !compare_expr(&expected_var.into(), &default_var.into()) - || !compare_expr(&test_dict.into(), &expected_subscript.into()) - { - return; - } - - // Check that the default value is not "complex". - if contains_effect(default_value, |id| checker.semantic().is_builtin(id)) { - return; - } - - let node = default_value.clone(); - let node1 = *test_key.clone(); - let node2 = ast::ExprAttribute { - value: expected_subscript.clone(), - attr: Identifier::new("get".to_string(), TextRange::default()), - ctx: ExprContext::Load, - range: TextRange::default(), - }; - let node3 = ast::ExprCall { - func: Box::new(node2.into()), - arguments: Arguments { - args: vec![node1, node], - keywords: vec![], - range: TextRange::default(), - }, - range: TextRange::default(), - }; - let node4 = expected_var.clone(); - let node5 = ast::StmtAssign { - targets: vec![node4], - value: Box::new(node3.into()), - range: TextRange::default(), - }; - let contents = checker.generator().stmt(&node5.into()); - - // Don't flag if the resulting expression would exceed the maximum line length. - let line_start = checker.locator().line_start(stmt_if.start()); - if LineWidthBuilder::new(checker.settings.tab_size) - .add_str(&checker.locator().contents()[TextRange::new(line_start, stmt_if.start())]) - .add_str(&contents) - > checker.settings.line_length - { - return; - } - - let mut diagnostic = Diagnostic::new( - IfElseBlockInsteadOfDictGet { - contents: contents.clone(), - }, - stmt_if.range(), - ); - if checker.patch(diagnostic.kind.rule()) { - if !checker.indexer().has_comments(stmt_if, checker.locator()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - contents, - stmt_if.range(), - ))); - } - } - checker.diagnostics.push(diagnostic); -} diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_ifexp.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_ifexp.rs index f5d890f61b5eb..764253fee05f1 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_ifexp.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_ifexp.rs @@ -1,13 +1,12 @@ use ruff_python_ast::{self as ast, Arguments, Expr, ExprContext, UnaryOp}; use ruff_text_size::{Ranged, TextRange}; -use ruff_diagnostics::{AlwaysAutofixableViolation, AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::{is_const_false, is_const_true}; use ruff_python_ast::parenthesize::parenthesized_range; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for `if` expressions that can be replaced with `bool()` calls. @@ -35,7 +34,7 @@ pub struct IfExprWithTrueFalse { } impl Violation for IfExprWithTrueFalse { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -47,7 +46,7 @@ impl Violation for IfExprWithTrueFalse { } } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let IfExprWithTrueFalse { is_compare } = self; if *is_compare { Some(format!("Remove unnecessary `True if ... else False`")) @@ -81,13 +80,13 @@ impl Violation for IfExprWithTrueFalse { #[violation] pub struct IfExprWithFalseTrue; -impl AlwaysAutofixableViolation for IfExprWithFalseTrue { +impl AlwaysFixableViolation for IfExprWithFalseTrue { #[derive_message_formats] fn message(&self) -> String { format!("Use `not ...` instead of `False if ... else True`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { format!("Replace with `not ...`") } } @@ -117,7 +116,7 @@ pub struct IfExprWithTwistedArms { expr_else: String, } -impl AlwaysAutofixableViolation for IfExprWithTwistedArms { +impl AlwaysFixableViolation for IfExprWithTwistedArms { #[derive_message_formats] fn message(&self) -> String { let IfExprWithTwistedArms { @@ -130,7 +129,7 @@ impl AlwaysAutofixableViolation for IfExprWithTwistedArms { ) } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let IfExprWithTwistedArms { expr_body, expr_else, @@ -157,48 +156,46 @@ pub(crate) fn if_expr_with_true_false( }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if test.is_compare_expr() { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker - .locator() - .slice( - parenthesized_range( - test.into(), - expr.into(), - checker.indexer().comment_ranges(), - checker.locator().contents(), - ) - .unwrap_or(test.range()), + if test.is_compare_expr() { + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + checker + .locator() + .slice( + parenthesized_range( + test.into(), + expr.into(), + checker.indexer().comment_ranges(), + checker.locator().contents(), ) - .to_string(), - expr.range(), - ))); - } else if checker.semantic().is_builtin("bool") { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.generator().expr( - &ast::ExprCall { - func: Box::new( - ast::ExprName { - id: "bool".into(), - ctx: ExprContext::Load, - range: TextRange::default(), - } - .into(), - ), - arguments: Arguments { - args: vec![test.clone()], - keywords: vec![], + .unwrap_or(test.range()), + ) + .to_string(), + expr.range(), + ))); + } else if checker.semantic().is_builtin("bool") { + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + checker.generator().expr( + &ast::ExprCall { + func: Box::new( + ast::ExprName { + id: "bool".into(), + ctx: ExprContext::Load, range: TextRange::default(), - }, + } + .into(), + ), + arguments: Arguments { + args: vec![test.clone()], + keywords: vec![], range: TextRange::default(), - } - .into(), - ), - expr.range(), - ))); - }; - } + }, + range: TextRange::default(), + } + .into(), + ), + expr.range(), + ))); + }; checker.diagnostics.push(diagnostic); } @@ -215,19 +212,17 @@ pub(crate) fn if_expr_with_false_true( } let mut diagnostic = Diagnostic::new(IfExprWithFalseTrue, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.generator().expr( - &ast::ExprUnaryOp { - op: UnaryOp::Not, - operand: Box::new(test.clone()), - range: TextRange::default(), - } - .into(), - ), - expr.range(), - ))); - } + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + checker.generator().expr( + &ast::ExprUnaryOp { + op: UnaryOp::Not, + operand: Box::new(test.clone()), + range: TextRange::default(), + } + .into(), + ), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } @@ -269,20 +264,18 @@ pub(crate) fn twisted_arms_in_ifexpr( }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let node = body.clone(); - let node1 = orelse.clone(); - let node2 = orelse.clone(); - let node3 = ast::ExprIfExp { - test: Box::new(node2), - body: Box::new(node1), - orelse: Box::new(node), - range: TextRange::default(), - }; - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.generator().expr(&node3.into()), - expr.range(), - ))); - } + let node = body.clone(); + let node1 = orelse.clone(); + let node2 = orelse.clone(); + let node3 = ast::ExprIfExp { + test: Box::new(node2), + body: Box::new(node1), + orelse: Box::new(node), + range: TextRange::default(), + }; + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + checker.generator().expr(&node3.into()), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_unary_op.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_unary_op.rs index e6636fb7007c4..8cc58ebda1a78 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_unary_op.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_unary_op.rs @@ -1,12 +1,11 @@ use ruff_python_ast::{self as ast, Arguments, CmpOp, Expr, ExprContext, Stmt, UnaryOp}; use ruff_text_size::{Ranged, TextRange}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_semantic::ScopeKind; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for negated `==` operators. @@ -33,14 +32,14 @@ pub struct NegateEqualOp { right: String, } -impl AlwaysAutofixableViolation for NegateEqualOp { +impl AlwaysFixableViolation for NegateEqualOp { #[derive_message_formats] fn message(&self) -> String { let NegateEqualOp { left, right } = self; format!("Use `{left} != {right}` instead of `not {left} == {right}`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace with `!=` operator".to_string() } } @@ -70,14 +69,14 @@ pub struct NegateNotEqualOp { right: String, } -impl AlwaysAutofixableViolation for NegateNotEqualOp { +impl AlwaysFixableViolation for NegateNotEqualOp { #[derive_message_formats] fn message(&self) -> String { let NegateNotEqualOp { left, right } = self; format!("Use `{left} == {right}` instead of `not {left} != {right}`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace with `==` operator".to_string() } } @@ -106,14 +105,14 @@ pub struct DoubleNegation { expr: String, } -impl AlwaysAutofixableViolation for DoubleNegation { +impl AlwaysFixableViolation for DoubleNegation { #[derive_message_formats] fn message(&self) -> String { let DoubleNegation { expr } = self; format!("Use `{expr}` instead of `not (not {expr})`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let DoubleNegation { expr } = self; format!("Replace with `{expr}`") } @@ -175,18 +174,16 @@ pub(crate) fn negation_with_equal_op( }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let node = ast::ExprCompare { - left: left.clone(), - ops: vec![CmpOp::NotEq], - comparators: comparators.clone(), - range: TextRange::default(), - }; - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - checker.generator().expr(&node.into()), - expr.range(), - ))); - } + let node = ast::ExprCompare { + left: left.clone(), + ops: vec![CmpOp::NotEq], + comparators: comparators.clone(), + range: TextRange::default(), + }; + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + checker.generator().expr(&node.into()), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } @@ -232,18 +229,16 @@ pub(crate) fn negation_with_not_equal_op( }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let node = ast::ExprCompare { - left: left.clone(), - ops: vec![CmpOp::Eq], - comparators: comparators.clone(), - range: TextRange::default(), - }; - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.generator().expr(&node.into()), - expr.range(), - ))); - } + let node = ast::ExprCompare { + left: left.clone(), + ops: vec![CmpOp::Eq], + comparators: comparators.clone(), + range: TextRange::default(), + }; + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + checker.generator().expr(&node.into()), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } @@ -270,32 +265,30 @@ pub(crate) fn double_negation(checker: &mut Checker, expr: &Expr, op: UnaryOp, o }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if checker.semantic().in_boolean_test() { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.locator().slice(operand.as_ref()).to_string(), - expr.range(), - ))); - } else if checker.semantic().is_builtin("bool") { - let node = ast::ExprName { - id: "bool".into(), - ctx: ExprContext::Load, - range: TextRange::default(), - }; - let node1 = ast::ExprCall { - func: Box::new(node.into()), - arguments: Arguments { - args: vec![*operand.clone()], - keywords: vec![], - range: TextRange::default(), - }, + if checker.semantic().in_boolean_test() { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + checker.locator().slice(operand.as_ref()).to_string(), + expr.range(), + ))); + } else if checker.semantic().is_builtin("bool") { + let node = ast::ExprName { + id: "bool".into(), + ctx: ExprContext::Load, + range: TextRange::default(), + }; + let node1 = ast::ExprCall { + func: Box::new(node.into()), + arguments: Arguments { + args: vec![*operand.clone()], + keywords: vec![], range: TextRange::default(), - }; - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.generator().expr(&node1.into()), - expr.range(), - ))); + }, + range: TextRange::default(), }; - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + checker.generator().expr(&node1.into()), + expr.range(), + ))); + }; checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_with.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_with.rs index da34dc0841bcd..e3dedd26a477c 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_with.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_with.rs @@ -1,16 +1,14 @@ use log::error; -use ruff_diagnostics::{AutofixKind, Violation}; use ruff_diagnostics::{Diagnostic, Fix}; +use ruff_diagnostics::{FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Stmt, WithItem}; use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer}; -use ruff_source_file::UniversalNewlines; use ruff_text_size::{Ranged, TextRange}; use crate::checkers::ast::Checker; -use crate::line_width::LineWidthBuilder; -use crate::registry::AsRule; +use crate::fix::edits::fits; use super::fix_with; @@ -45,7 +43,7 @@ use super::fix_with; pub struct MultipleWithStatements; impl Violation for MultipleWithStatements { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -55,7 +53,7 @@ impl Violation for MultipleWithStatements { ) } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Combine `with` statements".to_string()) } } @@ -125,32 +123,30 @@ pub(crate) fn multiple_with_statements( MultipleWithStatements, TextRange::new(with_stmt.start(), colon.end()), ); - if checker.patch(diagnostic.kind.rule()) { - if !checker - .indexer() - .comment_ranges() - .intersects(TextRange::new(with_stmt.start(), with_stmt.body[0].start())) - { - match fix_with::fix_multiple_with_statements( - checker.locator(), - checker.stylist(), - with_stmt, - ) { - Ok(edit) => { - if edit - .content() - .unwrap_or_default() - .universal_newlines() - .all(|line| { - LineWidthBuilder::new(checker.settings.tab_size).add_str(&line) - <= checker.settings.line_length - }) - { - diagnostic.set_fix(Fix::suggested(edit)); - } + if !checker + .indexer() + .comment_ranges() + .intersects(TextRange::new(with_stmt.start(), with_stmt.body[0].start())) + { + match fix_with::fix_multiple_with_statements( + checker.locator(), + checker.stylist(), + with_stmt, + ) { + Ok(edit) => { + if edit.content().map_or(true, |content| { + fits( + content, + with_stmt.into(), + checker.locator(), + checker.settings.pycodestyle.max_line_length, + checker.settings.tab_size, + ) + }) { + diagnostic.set_fix(Fix::unsafe_edit(edit)); } - Err(err) => error!("Failed to fix nested with: {err}"), } + Err(err) => error!("Failed to fix nested with: {err}"), } } checker.diagnostics.push(diagnostic); diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/collapsible_if.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/collapsible_if.rs new file mode 100644 index 0000000000000..584c8c4182a2c --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/collapsible_if.rs @@ -0,0 +1,400 @@ +use std::borrow::Cow; + +use anyhow::{bail, Result}; +use libcst_native::ParenthesizedNode; +use log::error; + +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::AnyNodeRef; +use ruff_python_ast::{self as ast, whitespace, Constant, ElifElseClause, Expr, Stmt}; +use ruff_python_codegen::Stylist; +use ruff_python_semantic::analyze::typing::{is_sys_version_block, is_type_checking_block}; +use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer}; +use ruff_source_file::Locator; +use ruff_text_size::{Ranged, TextRange}; + +use crate::checkers::ast::Checker; +use crate::cst::helpers::space; +use crate::cst::matchers::{match_function_def, match_if, match_indented_block, match_statement}; +use crate::fix::codemods::CodegenStylist; +use crate::fix::edits::fits; + +/// ## What it does +/// Checks for nested `if` statements that can be collapsed into a single `if` +/// statement. +/// +/// ## Why is this bad? +/// Nesting `if` statements leads to deeper indentation and makes code harder to +/// read. Instead, combine the conditions into a single `if` statement with an +/// `and` operator. +/// +/// ## Example +/// ```python +/// if foo: +/// if bar: +/// ... +/// ``` +/// +/// Use instead: +/// ```python +/// if foo and bar: +/// ... +/// ``` +/// +/// ## References +/// - [Python documentation: The `if` statement](https://docs.python.org/3/reference/compound_stmts.html#the-if-statement) +/// - [Python documentation: Boolean operations](https://docs.python.org/3/reference/expressions.html#boolean-operations) +#[violation] +pub struct CollapsibleIf; + +impl Violation for CollapsibleIf { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; + + #[derive_message_formats] + fn message(&self) -> String { + format!("Use a single `if` statement instead of nested `if` statements") + } + + fn fix_title(&self) -> Option { + Some("Combine `if` statements using `and`".to_string()) + } +} + +/// SIM102 +pub(crate) fn nested_if_statements( + checker: &mut Checker, + stmt_if: &ast::StmtIf, + parent: Option<&Stmt>, +) { + let Some(nested_if) = nested_if_body(stmt_if) else { + return; + }; + + // Find the deepest nested if-statement, to inform the range. + let Some(test) = find_last_nested_if(nested_if.body()) else { + return; + }; + + // Check if the parent is already emitting a larger diagnostic including this if statement + if let Some(Stmt::If(stmt_if)) = parent { + if let Some(nested_if) = nested_if_body(stmt_if) { + // In addition to repeating the `nested_if_body` and `find_last_nested_if` check, we + // also need to be the first child in the parent + let body = nested_if.body(); + if matches!(&body[0], Stmt::If(inner) if *inner == *stmt_if) + && find_last_nested_if(body).is_some() + { + return; + } + } + } + + let Some(colon) = SimpleTokenizer::starts_at(test.end(), checker.locator().contents()) + .skip_trivia() + .find(|token| token.kind == SimpleTokenKind::Colon) + else { + return; + }; + + // Avoid suggesting ternary for `if sys.version_info >= ...`-style checks. + if is_sys_version_block(stmt_if, checker.semantic()) { + return; + } + + // Avoid suggesting ternary for `if TYPE_CHECKING:`-style checks. + if is_type_checking_block(stmt_if, checker.semantic()) { + return; + } + + let mut diagnostic = Diagnostic::new( + CollapsibleIf, + TextRange::new(nested_if.start(), colon.end()), + ); + // The fixer preserves comments in the nested body, but removes comments between + // the outer and inner if statements. + if !checker + .indexer() + .comment_ranges() + .intersects(TextRange::new( + nested_if.start(), + nested_if.body()[0].start(), + )) + { + match collapse_nested_if(checker.locator(), checker.stylist(), nested_if) { + Ok(edit) => { + if edit.content().map_or(true, |content| { + fits( + content, + (&nested_if).into(), + checker.locator(), + checker.settings.pycodestyle.max_line_length, + checker.settings.tab_size, + ) + }) { + diagnostic.set_fix(Fix::unsafe_edit(edit)); + } + } + Err(err) => error!("Failed to fix nested if: {err}"), + } + } + checker.diagnostics.push(diagnostic); +} + +#[derive(Debug, Clone, Copy)] +pub(super) enum NestedIf<'a> { + If(&'a ast::StmtIf), + Elif(&'a ElifElseClause), +} + +impl<'a> NestedIf<'a> { + pub(super) fn body(self) -> &'a [Stmt] { + match self { + NestedIf::If(stmt_if) => &stmt_if.body, + NestedIf::Elif(clause) => &clause.body, + } + } + + pub(super) fn is_elif(self) -> bool { + matches!(self, NestedIf::Elif(..)) + } +} + +impl Ranged for NestedIf<'_> { + fn range(&self) -> TextRange { + match self { + NestedIf::If(stmt_if) => stmt_if.range(), + NestedIf::Elif(clause) => clause.range(), + } + } +} + +impl<'a> From<&NestedIf<'a>> for AnyNodeRef<'a> { + fn from(value: &NestedIf<'a>) -> Self { + match value { + NestedIf::If(stmt_if) => (*stmt_if).into(), + NestedIf::Elif(clause) => (*clause).into(), + } + } +} + +/// Returns the body, the range of the `if` or `elif` and whether the range is for an `if` or `elif` +fn nested_if_body(stmt_if: &ast::StmtIf) -> Option { + let ast::StmtIf { + test, + body, + elif_else_clauses, + .. + } = stmt_if; + + // It must be the last condition, otherwise there could be another `elif` or `else` that only + // depends on the outer of the two conditions + let (test, nested_if) = if let Some(clause) = elif_else_clauses.last() { + if let Some(test) = &clause.test { + (test, NestedIf::Elif(clause)) + } else { + // The last condition is an `else` (different rule) + return None; + } + } else { + (test.as_ref(), NestedIf::If(stmt_if)) + }; + + // The nested if must be the only child, otherwise there is at least one more statement that + // only depends on the outer condition + if body.len() > 1 { + return None; + } + + // Allow `if __name__ == "__main__":` statements. + if is_main_check(test) { + return None; + } + + // Allow `if True:` and `if False:` statements. + if matches!( + test, + Expr::Constant(ast::ExprConstant { + value: Constant::Bool(..), + .. + }) + ) { + return None; + } + + Some(nested_if) +} + +/// Find the last nested if statement and return the test expression and the +/// last statement. +/// +/// ```python +/// if xxx: +/// if yyy: +/// # ^^^ returns this expression +/// z = 1 +/// ... +/// ``` +fn find_last_nested_if(body: &[Stmt]) -> Option<&Expr> { + let [Stmt::If(ast::StmtIf { + test, + body: inner_body, + elif_else_clauses, + .. + })] = body + else { + return None; + }; + if !elif_else_clauses.is_empty() { + return None; + } + find_last_nested_if(inner_body).or(Some(test)) +} + +/// Returns `true` if an expression is an `if __name__ == "__main__":` check. +fn is_main_check(expr: &Expr) -> bool { + if let Expr::Compare(ast::ExprCompare { + left, comparators, .. + }) = expr + { + if let Expr::Name(ast::ExprName { id, .. }) = left.as_ref() { + if id == "__name__" { + if let [Expr::Constant(ast::ExprConstant { + value: Constant::Str(ast::StringConstant { value, .. }), + .. + })] = comparators.as_slice() + { + if value == "__main__" { + return true; + } + } + } + } + } + false +} + +fn parenthesize_and_operand(expr: libcst_native::Expression) -> libcst_native::Expression { + match &expr { + _ if !expr.lpar().is_empty() => expr, + libcst_native::Expression::BooleanOperation(boolean_operation) + if matches!( + boolean_operation.operator, + libcst_native::BooleanOp::Or { .. } + ) => + { + expr.with_parens( + libcst_native::LeftParen::default(), + libcst_native::RightParen::default(), + ) + } + libcst_native::Expression::IfExp(_) + | libcst_native::Expression::Lambda(_) + | libcst_native::Expression::NamedExpr(_) => expr.with_parens( + libcst_native::LeftParen::default(), + libcst_native::RightParen::default(), + ), + _ => expr, + } +} + +/// Convert `if a: if b:` to `if a and b:`. +pub(super) fn collapse_nested_if( + locator: &Locator, + stylist: &Stylist, + nested_if: NestedIf, +) -> Result { + // Infer the indentation of the outer block. + let Some(outer_indent) = whitespace::indentation(locator, &nested_if) else { + bail!("Unable to fix multiline statement"); + }; + + // Extract the module text. + let contents = locator.lines(nested_if.range()); + + // If this is an `elif`, we have to remove the `elif` keyword for now. (We'll + // restore the `el` later on.) + let module_text = if nested_if.is_elif() { + Cow::Owned(contents.replacen("elif", "if", 1)) + } else { + Cow::Borrowed(contents) + }; + + // If the block is indented, "embed" it in a function definition, to preserve + // indentation while retaining valid source code. (We'll strip the prefix later + // on.) + let module_text = if outer_indent.is_empty() { + module_text + } else { + Cow::Owned(format!( + "def f():{}{module_text}", + stylist.line_ending().as_str() + )) + }; + + // Parse the CST. + let mut tree = match_statement(&module_text)?; + + let statement = if outer_indent.is_empty() { + &mut tree + } else { + let embedding = match_function_def(&mut tree)?; + + let indented_block = match_indented_block(&mut embedding.body)?; + indented_block.indent = Some(outer_indent); + + let Some(statement) = indented_block.body.first_mut() else { + bail!("Expected indented block to have at least one statement") + }; + statement + }; + + let outer_if = match_if(statement)?; + + let libcst_native::If { + body: libcst_native::Suite::IndentedBlock(ref mut outer_body), + orelse: None, + .. + } = outer_if + else { + bail!("Expected outer if to have indented body and no else") + }; + + let [libcst_native::Statement::Compound(libcst_native::CompoundStatement::If( + inner_if @ libcst_native::If { orelse: None, .. }, + ))] = &mut *outer_body.body + else { + bail!("Expected one inner if statement"); + }; + + outer_if.test = + libcst_native::Expression::BooleanOperation(Box::new(libcst_native::BooleanOperation { + left: Box::new(parenthesize_and_operand(outer_if.test.clone())), + operator: libcst_native::BooleanOp::And { + whitespace_before: space(), + whitespace_after: space(), + }, + right: Box::new(parenthesize_and_operand(inner_if.test.clone())), + lpar: vec![], + rpar: vec![], + })); + outer_if.body = inner_if.body.clone(); + + // Reconstruct and reformat the code. + let module_text = tree.codegen_stylist(stylist); + let module_text = if outer_indent.is_empty() { + &module_text + } else { + module_text + .strip_prefix(&format!("def f():{}", stylist.line_ending().as_str())) + .unwrap() + }; + let contents = if nested_if.is_elif() { + Cow::Owned(module_text.replacen("if", "elif", 1)) + } else { + Cow::Borrowed(module_text) + }; + + let range = locator.lines_range(nested_if.range()); + Ok(Edit::range_replacement(contents.to_string(), range)) +} diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/fix_if.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/fix_if.rs deleted file mode 100644 index e03b685abb5a2..0000000000000 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/fix_if.rs +++ /dev/null @@ -1,132 +0,0 @@ -use std::borrow::Cow; - -use anyhow::{bail, Result}; -use libcst_native::{ - BooleanOp, BooleanOperation, CompoundStatement, Expression, If, LeftParen, ParenthesizedNode, - RightParen, Statement, Suite, -}; - -use ruff_diagnostics::Edit; -use ruff_python_ast::whitespace; -use ruff_python_codegen::Stylist; -use ruff_source_file::Locator; -use ruff_text_size::TextRange; - -use crate::autofix::codemods::CodegenStylist; -use crate::cst::helpers::space; -use crate::cst::matchers::{match_function_def, match_if, match_indented_block, match_statement}; - -fn parenthesize_and_operand(expr: Expression) -> Expression { - match &expr { - _ if !expr.lpar().is_empty() => expr, - Expression::BooleanOperation(boolean_operation) - if matches!(boolean_operation.operator, BooleanOp::Or { .. }) => - { - expr.with_parens(LeftParen::default(), RightParen::default()) - } - Expression::IfExp(_) | Expression::Lambda(_) | Expression::NamedExpr(_) => { - expr.with_parens(LeftParen::default(), RightParen::default()) - } - _ => expr, - } -} - -/// (SIM102) Convert `if a: if b:` to `if a and b:`. -pub(crate) fn fix_nested_if_statements( - locator: &Locator, - stylist: &Stylist, - range: TextRange, - is_elif: bool, -) -> Result { - // Infer the indentation of the outer block. - let Some(outer_indent) = whitespace::indentation(locator, &range) else { - bail!("Unable to fix multiline statement"); - }; - - // Extract the module text. - let contents = locator.lines(range); - - // If this is an `elif`, we have to remove the `elif` keyword for now. (We'll - // restore the `el` later on.) - let module_text = if is_elif { - Cow::Owned(contents.replacen("elif", "if", 1)) - } else { - Cow::Borrowed(contents) - }; - - // If the block is indented, "embed" it in a function definition, to preserve - // indentation while retaining valid source code. (We'll strip the prefix later - // on.) - let module_text = if outer_indent.is_empty() { - module_text - } else { - Cow::Owned(format!( - "def f():{}{module_text}", - stylist.line_ending().as_str() - )) - }; - - // Parse the CST. - let mut tree = match_statement(&module_text)?; - - let statement = if outer_indent.is_empty() { - &mut tree - } else { - let embedding = match_function_def(&mut tree)?; - - let indented_block = match_indented_block(&mut embedding.body)?; - indented_block.indent = Some(outer_indent); - - let Some(statement) = indented_block.body.first_mut() else { - bail!("Expected indented block to have at least one statement") - }; - statement - }; - - let outer_if = match_if(statement)?; - - let If { - body: Suite::IndentedBlock(ref mut outer_body), - orelse: None, - .. - } = outer_if - else { - bail!("Expected outer if to have indented body and no else") - }; - - let [Statement::Compound(CompoundStatement::If(inner_if @ If { orelse: None, .. }))] = - &mut *outer_body.body - else { - bail!("Expected one inner if statement"); - }; - - outer_if.test = Expression::BooleanOperation(Box::new(BooleanOperation { - left: Box::new(parenthesize_and_operand(outer_if.test.clone())), - operator: BooleanOp::And { - whitespace_before: space(), - whitespace_after: space(), - }, - right: Box::new(parenthesize_and_operand(inner_if.test.clone())), - lpar: vec![], - rpar: vec![], - })); - outer_if.body = inner_if.body.clone(); - - // Reconstruct and reformat the code. - let module_text = tree.codegen_stylist(stylist); - let module_text = if outer_indent.is_empty() { - &module_text - } else { - module_text - .strip_prefix(&format!("def f():{}", stylist.line_ending().as_str())) - .unwrap() - }; - let contents = if is_elif { - Cow::Owned(module_text.replacen("if", "elif", 1)) - } else { - Cow::Borrowed(module_text) - }; - - let range = locator.lines_range(range); - Ok(Edit::range_replacement(contents.to_string(), range)) -} diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/fix_with.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/fix_with.rs index 3e0f6f0b13832..1738aa8023142 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/fix_with.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/fix_with.rs @@ -8,8 +8,8 @@ use ruff_python_codegen::Stylist; use ruff_source_file::Locator; use ruff_text_size::Ranged; -use crate::autofix::codemods::CodegenStylist; use crate::cst::matchers::{match_function_def, match_indented_block, match_statement, match_with}; +use crate::fix::codemods::CodegenStylist; /// (SIM117) Convert `with a: with b:` to `with a, b:`. pub(crate) fn fix_multiple_with_statements( diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_dict_get.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_dict_get.rs new file mode 100644 index 0000000000000..50d6e8b7bb129 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_dict_get.rs @@ -0,0 +1,305 @@ +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::comparable::ComparableExpr; +use ruff_python_ast::helpers::contains_effect; +use ruff_python_ast::{ + self as ast, Arguments, CmpOp, ElifElseClause, Expr, ExprContext, Identifier, Stmt, +}; +use ruff_python_semantic::analyze::typing::{is_sys_version_block, is_type_checking_block}; +use ruff_text_size::{Ranged, TextRange}; + +use crate::checkers::ast::Checker; +use crate::fix::edits::fits; + +/// ## What it does +/// Checks for `if` statements that can be replaced with `dict.get` calls. +/// +/// ## Why is this bad? +/// `dict.get()` calls can be used to replace `if` statements that assign a +/// value to a variable in both branches, falling back to a default value if +/// the key is not found. When possible, using `dict.get` is more concise and +/// more idiomatic. +/// +/// Under [preview mode](https://docs.astral.sh/ruff/preview), this rule will +/// also suggest replacing `if`-`else` _expressions_ with `dict.get` calls. +/// +/// ## Example +/// ```python +/// if "bar" in foo: +/// value = foo["bar"] +/// else: +/// value = 0 +/// ``` +/// +/// Use instead: +/// ```python +/// value = foo.get("bar", 0) +/// ``` +/// +/// If preview mode is enabled: +/// ```python +/// value = foo["bar"] if "bar" in foo else 0 +/// ``` +/// +/// Use instead: +/// ```python +/// value = foo.get("bar", 0) +/// ``` +/// +/// ## References +/// - [Python documentation: Mapping Types](https://docs.python.org/3/library/stdtypes.html#mapping-types-dict) +#[violation] +pub struct IfElseBlockInsteadOfDictGet { + contents: String, +} + +impl Violation for IfElseBlockInsteadOfDictGet { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; + + #[derive_message_formats] + fn message(&self) -> String { + let IfElseBlockInsteadOfDictGet { contents } = self; + format!("Use `{contents}` instead of an `if` block") + } + + fn fix_title(&self) -> Option { + let IfElseBlockInsteadOfDictGet { contents } = self; + Some(format!("Replace with `{contents}`")) + } +} + +/// SIM401 +pub(crate) fn if_else_block_instead_of_dict_get(checker: &mut Checker, stmt_if: &ast::StmtIf) { + let ast::StmtIf { + test, + body, + elif_else_clauses, + .. + } = stmt_if; + + let [body_stmt] = body.as_slice() else { + return; + }; + let [ElifElseClause { + body: else_body, + test: None, + .. + }] = elif_else_clauses.as_slice() + else { + return; + }; + let [else_body_stmt] = else_body.as_slice() else { + return; + }; + let Stmt::Assign(ast::StmtAssign { + targets: body_var, + value: body_value, + .. + }) = &body_stmt + else { + return; + }; + let [body_var] = body_var.as_slice() else { + return; + }; + let Stmt::Assign(ast::StmtAssign { + targets: orelse_var, + value: orelse_value, + .. + }) = &else_body_stmt + else { + return; + }; + let [orelse_var] = orelse_var.as_slice() else { + return; + }; + let Expr::Compare(ast::ExprCompare { + left: test_key, + ops, + comparators: test_dict, + range: _, + }) = test.as_ref() + else { + return; + }; + let [test_dict] = test_dict.as_slice() else { + return; + }; + let (expected_var, expected_value, default_var, default_value) = match ops[..] { + [CmpOp::In] => (body_var, body_value, orelse_var, orelse_value.as_ref()), + [CmpOp::NotIn] => (orelse_var, orelse_value, body_var, body_value.as_ref()), + _ => { + return; + } + }; + let Expr::Subscript(ast::ExprSubscript { + value: expected_subscript, + slice: expected_slice, + .. + }) = expected_value.as_ref() + else { + return; + }; + + // Check that the dictionary key, target variables, and dictionary name are all + // equivalent. + if ComparableExpr::from(expected_slice) != ComparableExpr::from(test_key) + || ComparableExpr::from(expected_var) != ComparableExpr::from(default_var) + || ComparableExpr::from(test_dict) != ComparableExpr::from(expected_subscript) + { + return; + } + + // Avoid suggesting ternary for `if sys.version_info >= ...`-style checks. + if is_sys_version_block(stmt_if, checker.semantic()) { + return; + } + + // Avoid suggesting ternary for `if TYPE_CHECKING:`-style checks. + if is_type_checking_block(stmt_if, checker.semantic()) { + return; + } + + // Check that the default value is not "complex". + if contains_effect(default_value, |id| checker.semantic().is_builtin(id)) { + return; + } + + let node = default_value.clone(); + let node1 = *test_key.clone(); + let node2 = ast::ExprAttribute { + value: expected_subscript.clone(), + attr: Identifier::new("get".to_string(), TextRange::default()), + ctx: ExprContext::Load, + range: TextRange::default(), + }; + let node3 = ast::ExprCall { + func: Box::new(node2.into()), + arguments: Arguments { + args: vec![node1, node], + keywords: vec![], + range: TextRange::default(), + }, + range: TextRange::default(), + }; + let node4 = expected_var.clone(); + let node5 = ast::StmtAssign { + targets: vec![node4], + value: Box::new(node3.into()), + range: TextRange::default(), + }; + let contents = checker.generator().stmt(&node5.into()); + + // Don't flag if the resulting expression would exceed the maximum line length. + if !fits( + &contents, + stmt_if.into(), + checker.locator(), + checker.settings.pycodestyle.max_line_length, + checker.settings.tab_size, + ) { + return; + } + + let mut diagnostic = Diagnostic::new( + IfElseBlockInsteadOfDictGet { + contents: contents.clone(), + }, + stmt_if.range(), + ); + if !checker.indexer().has_comments(stmt_if, checker.locator()) { + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + contents, + stmt_if.range(), + ))); + } + checker.diagnostics.push(diagnostic); +} + +/// SIM401 +pub(crate) fn if_exp_instead_of_dict_get( + checker: &mut Checker, + expr: &Expr, + test: &Expr, + body: &Expr, + orelse: &Expr, +) { + if checker.settings.preview.is_disabled() { + return; + } + + let Expr::Compare(ast::ExprCompare { + left: test_key, + ops, + comparators: test_dict, + range: _, + }) = test + else { + return; + }; + let [test_dict] = test_dict.as_slice() else { + return; + }; + + let (body, default_value) = match ops.as_slice() { + [CmpOp::In] => (body, orelse), + [CmpOp::NotIn] => (orelse, body), + _ => { + return; + } + }; + + let Expr::Subscript(ast::ExprSubscript { + value: expected_subscript, + slice: expected_slice, + .. + }) = body + else { + return; + }; + + if ComparableExpr::from(expected_slice) != ComparableExpr::from(test_key) + || ComparableExpr::from(test_dict) != ComparableExpr::from(expected_subscript) + { + return; + } + + // Check that the default value is not "complex". + if contains_effect(default_value, |id| checker.semantic().is_builtin(id)) { + return; + } + + let default_value_node = default_value.clone(); + let dict_key_node = *test_key.clone(); + let dict_get_node = ast::ExprAttribute { + value: expected_subscript.clone(), + attr: Identifier::new("get".to_string(), TextRange::default()), + ctx: ExprContext::Load, + range: TextRange::default(), + }; + let fixed_node = ast::ExprCall { + func: Box::new(dict_get_node.into()), + arguments: Arguments { + args: vec![dict_key_node, default_value_node], + keywords: vec![], + range: TextRange::default(), + }, + range: TextRange::default(), + }; + + let contents = checker.generator().expr(&fixed_node.into()); + + let mut diagnostic = Diagnostic::new( + IfElseBlockInsteadOfDictGet { + contents: contents.clone(), + }, + expr.range(), + ); + if !checker.indexer().has_comments(expr, checker.locator()) { + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + contents, + expr.range(), + ))); + } + checker.diagnostics.push(diagnostic); +} diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_dict_lookup.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_dict_lookup.rs new file mode 100644 index 0000000000000..f5fc09c2c0d66 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_dict_lookup.rs @@ -0,0 +1,162 @@ +use rustc_hash::FxHashSet; + +use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::comparable::ComparableConstant; +use ruff_python_ast::helpers::contains_effect; +use ruff_python_ast::{self as ast, CmpOp, ElifElseClause, Expr, Stmt}; +use ruff_python_semantic::analyze::typing::{is_sys_version_block, is_type_checking_block}; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for three or more consecutive if-statements with direct returns +/// +/// ## Why is this bad? +/// These can be simplified by using a dictionary +/// +/// ## Example +/// ```python +/// if x == 1: +/// return "Hello" +/// elif x == 2: +/// return "Goodbye" +/// else: +/// return "Goodnight" +/// ``` +/// +/// Use instead: +/// ```python +/// return {1: "Hello", 2: "Goodbye"}.get(x, "Goodnight") +/// ``` +#[violation] +pub struct IfElseBlockInsteadOfDictLookup; + +impl Violation for IfElseBlockInsteadOfDictLookup { + #[derive_message_formats] + fn message(&self) -> String { + format!("Use a dictionary instead of consecutive `if` statements") + } +} +/// SIM116 +pub(crate) fn if_else_block_instead_of_dict_lookup(checker: &mut Checker, stmt_if: &ast::StmtIf) { + // Throughout this rule: + // * Each if or elif statement's test must consist of a constant equality check with the same variable. + // * Each if or elif statement's body must consist of a single `return`. + // * The else clause must be empty, or a single `return`. + let ast::StmtIf { + body, + test, + elif_else_clauses, + .. + } = stmt_if; + + let Expr::Compare(ast::ExprCompare { + left, + ops, + comparators, + range: _, + }) = test.as_ref() + else { + return; + }; + let Expr::Name(ast::ExprName { id: target, .. }) = left.as_ref() else { + return; + }; + if ops != &[CmpOp::Eq] { + return; + } + let [Expr::Constant(ast::ExprConstant { + value: constant, .. + })] = comparators.as_slice() + else { + return; + }; + let [Stmt::Return(ast::StmtReturn { value, range: _ })] = body.as_slice() else { + return; + }; + + if value + .as_ref() + .is_some_and(|value| contains_effect(value, |id| checker.semantic().is_builtin(id))) + { + return; + } + + // Avoid suggesting ternary for `if sys.version_info >= ...`-style checks. + if is_sys_version_block(stmt_if, checker.semantic()) { + return; + } + + // Avoid suggesting ternary for `if TYPE_CHECKING:`-style checks. + if is_type_checking_block(stmt_if, checker.semantic()) { + return; + } + + let mut constants: FxHashSet = FxHashSet::default(); + constants.insert(constant.into()); + + for clause in elif_else_clauses { + let ElifElseClause { test, body, .. } = clause; + let [Stmt::Return(ast::StmtReturn { value, range: _ })] = body.as_slice() else { + return; + }; + + match test.as_ref() { + // `else` + None => { + // The else must also be a single effect-free return statement + let [Stmt::Return(ast::StmtReturn { value, range: _ })] = body.as_slice() else { + return; + }; + if value.as_ref().is_some_and(|value| { + contains_effect(value, |id| checker.semantic().is_builtin(id)) + }) { + return; + }; + } + // `elif` + Some(Expr::Compare(ast::ExprCompare { + left, + ops, + comparators, + range: _, + })) => { + let Expr::Name(ast::ExprName { id, .. }) = left.as_ref() else { + return; + }; + if id != target || ops != &[CmpOp::Eq] { + return; + } + let [Expr::Constant(ast::ExprConstant { + value: constant, .. + })] = comparators.as_slice() + else { + return; + }; + + if value.as_ref().is_some_and(|value| { + contains_effect(value, |id| checker.semantic().is_builtin(id)) + }) { + return; + }; + + constants.insert(constant.into()); + } + // Different `elif` + _ => { + return; + } + } + } + + if constants.len() < 3 { + return; + } + + checker.diagnostics.push(Diagnostic::new( + IfElseBlockInsteadOfDictLookup, + stmt_if.range(), + )); +} diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_if_exp.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_if_exp.rs new file mode 100644 index 0000000000000..c44c3d2a1c13c --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/if_else_block_instead_of_if_exp.rs @@ -0,0 +1,167 @@ +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, ElifElseClause, Expr, Stmt}; +use ruff_python_semantic::analyze::typing::{is_sys_version_block, is_type_checking_block}; +use ruff_text_size::{Ranged, TextRange}; + +use crate::checkers::ast::Checker; +use crate::fix::edits::fits; + +/// ## What it does +/// Check for `if`-`else`-blocks that can be replaced with a ternary operator. +/// +/// ## Why is this bad? +/// `if`-`else`-blocks that assign a value to a variable in both branches can +/// be expressed more concisely by using a ternary operator. +/// +/// ## Example +/// ```python +/// if foo: +/// bar = x +/// else: +/// bar = y +/// ``` +/// +/// Use instead: +/// ```python +/// bar = x if foo else y +/// ``` +/// +/// ## References +/// - [Python documentation: Conditional expressions](https://docs.python.org/3/reference/expressions.html#conditional-expressions) +#[violation] +pub struct IfElseBlockInsteadOfIfExp { + contents: String, +} + +impl Violation for IfElseBlockInsteadOfIfExp { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; + + #[derive_message_formats] + fn message(&self) -> String { + let IfElseBlockInsteadOfIfExp { contents } = self; + format!("Use ternary operator `{contents}` instead of `if`-`else`-block") + } + + fn fix_title(&self) -> Option { + let IfElseBlockInsteadOfIfExp { contents } = self; + Some(format!("Replace `if`-`else`-block with `{contents}`")) + } +} + +/// SIM108 +pub(crate) fn if_else_block_instead_of_if_exp(checker: &mut Checker, stmt_if: &ast::StmtIf) { + let ast::StmtIf { + test, + body, + elif_else_clauses, + range: _, + } = stmt_if; + + // `test: None` to only match an `else` clause + let [ElifElseClause { + body: else_body, + test: None, + .. + }] = elif_else_clauses.as_slice() + else { + return; + }; + let [Stmt::Assign(ast::StmtAssign { + targets: body_targets, + value: body_value, + .. + })] = body.as_slice() + else { + return; + }; + let [Stmt::Assign(ast::StmtAssign { + targets: else_targets, + value: else_value, + .. + })] = else_body.as_slice() + else { + return; + }; + let ([body_target], [else_target]) = (body_targets.as_slice(), else_targets.as_slice()) else { + return; + }; + let Expr::Name(ast::ExprName { id: body_id, .. }) = body_target else { + return; + }; + let Expr::Name(ast::ExprName { id: else_id, .. }) = else_target else { + return; + }; + if body_id != else_id { + return; + } + + // Avoid suggesting ternary for `if (yield ...)`-style checks. + // TODO(charlie): Fix precedence handling for yields in generator. + if matches!( + body_value.as_ref(), + Expr::Yield(_) | Expr::YieldFrom(_) | Expr::Await(_) + ) { + return; + } + if matches!( + else_value.as_ref(), + Expr::Yield(_) | Expr::YieldFrom(_) | Expr::Await(_) + ) { + return; + } + + // Avoid suggesting ternary for `if sys.version_info >= ...`-style checks. + if is_sys_version_block(stmt_if, checker.semantic()) { + return; + } + + // Avoid suggesting ternary for `if TYPE_CHECKING:`-style checks. + if is_type_checking_block(stmt_if, checker.semantic()) { + return; + } + + let target_var = &body_target; + let ternary = ternary(target_var, body_value, test, else_value); + let contents = checker.generator().stmt(&ternary); + + // Don't flag if the resulting expression would exceed the maximum line length. + if !fits( + &contents, + stmt_if.into(), + checker.locator(), + checker.settings.pycodestyle.max_line_length, + checker.settings.tab_size, + ) { + return; + } + + let mut diagnostic = Diagnostic::new( + IfElseBlockInsteadOfIfExp { + contents: contents.clone(), + }, + stmt_if.range(), + ); + if !checker.indexer().has_comments(stmt_if, checker.locator()) { + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + contents, + stmt_if.range(), + ))); + } + checker.diagnostics.push(diagnostic); +} + +fn ternary(target_var: &Expr, body_value: &Expr, test: &Expr, orelse_value: &Expr) -> Stmt { + let node = ast::ExprIfExp { + test: Box::new(test.clone()), + body: Box::new(body_value.clone()), + orelse: Box::new(orelse_value.clone()), + range: TextRange::default(), + }; + let node1 = ast::StmtAssign { + targets: vec![target_var.clone()], + value: Box::new(node.into()), + range: TextRange::default(), + }; + node1.into() +} diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/if_with_same_arms.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/if_with_same_arms.rs new file mode 100644 index 0000000000000..9ffc34b236a00 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/if_with_same_arms.rs @@ -0,0 +1,93 @@ +use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast as ast; +use ruff_python_ast::comparable::ComparableStmt; +use ruff_python_ast::stmt_if::{if_elif_branches, IfElifBranch}; +use ruff_source_file::Locator; +use ruff_text_size::{Ranged, TextRange}; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for `if` branches with identical arm bodies. +/// +/// ## Why is this bad? +/// If multiple arms of an `if` statement have the same body, using `or` +/// better signals the intent of the statement. +/// +/// ## Example +/// ```python +/// if x == 1: +/// print("Hello") +/// elif x == 2: +/// print("Hello") +/// ``` +/// +/// Use instead: +/// ```python +/// if x == 1 or x == 2: +/// print("Hello") +/// ``` +#[violation] +pub struct IfWithSameArms; + +impl Violation for IfWithSameArms { + #[derive_message_formats] + fn message(&self) -> String { + format!("Combine `if` branches using logical `or` operator") + } +} + +/// SIM114 +pub(crate) fn if_with_same_arms(checker: &mut Checker, locator: &Locator, stmt_if: &ast::StmtIf) { + let mut branches_iter = if_elif_branches(stmt_if).peekable(); + while let Some(current_branch) = branches_iter.next() { + let Some(following_branch) = branches_iter.peek() else { + continue; + }; + + // The bodies must have the same code ... + if current_branch.body.len() != following_branch.body.len() { + continue; + } + if !current_branch + .body + .iter() + .zip(following_branch.body.iter()) + .all(|(stmt1, stmt2)| ComparableStmt::from(stmt1) == ComparableStmt::from(stmt2)) + { + continue; + } + + // ...and the same comments + let first_comments = checker + .indexer() + .comment_ranges() + .comments_in_range(body_range(¤t_branch, locator)) + .iter() + .map(|range| locator.slice(*range)); + let second_comments = checker + .indexer() + .comment_ranges() + .comments_in_range(body_range(following_branch, locator)) + .iter() + .map(|range| locator.slice(*range)); + if !first_comments.eq(second_comments) { + continue; + } + + checker.diagnostics.push(Diagnostic::new( + IfWithSameArms, + TextRange::new(current_branch.start(), following_branch.end()), + )); + } +} + +/// Return the [`TextRange`] of an [`IfElifBranch`]'s body (from the end of the test to the end of +/// the body). +fn body_range(branch: &IfElifBranch, locator: &Locator) -> TextRange { + TextRange::new( + locator.line_end(branch.test.end()), + locator.line_end(branch.end()), + ) +} diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/key_in_dict.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/key_in_dict.rs index bddbeffc84158..36592a3874cdf 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/key_in_dict.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/key_in_dict.rs @@ -1,14 +1,13 @@ use ruff_diagnostics::Edit; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::node::AnyNodeRef; use ruff_python_ast::parenthesize::parenthesized_range; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{self as ast, Arguments, CmpOp, Comprehension, Expr}; use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer}; use ruff_text_size::{Ranged, TextRange}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for key-existence checks against `dict.keys()` calls. @@ -35,14 +34,14 @@ pub struct InDictKeys { operator: String, } -impl AlwaysAutofixableViolation for InDictKeys { +impl AlwaysFixableViolation for InDictKeys { #[derive_message_formats] fn message(&self) -> String { let InDictKeys { operator } = self; format!("Use `key {operator} dict` instead of `key {operator} dict.keys()`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let InDictKeys { operator: _ } = self; format!("Remove `.keys()`") } @@ -109,32 +108,30 @@ fn key_in_dict( }, TextRange::new(left_range.start(), right_range.end()), ); - if checker.patch(diagnostic.kind.rule()) { - // Delete from the start of the dot to the end of the expression. - if let Some(dot) = SimpleTokenizer::starts_at(value.end(), checker.locator().contents()) - .skip_trivia() - .find(|token| token.kind == SimpleTokenKind::Dot) + // Delete from the start of the dot to the end of the expression. + if let Some(dot) = SimpleTokenizer::starts_at(value.end(), checker.locator().contents()) + .skip_trivia() + .find(|token| token.kind == SimpleTokenKind::Dot) + { + // If the `.keys()` is followed by (e.g.) a keyword, we need to insert a space, + // since we're removing parentheses, which could lead to invalid syntax, as in: + // ```python + // if key in foo.keys()and bar: + // ``` + let range = TextRange::new(dot.start(), right.end()); + if checker + .locator() + .after(range.end()) + .chars() + .next() + .is_some_and(|char| char.is_ascii_alphabetic()) { - // If the `.keys()` is followed by (e.g.) a keyword, we need to insert a space, - // since we're removing parentheses, which could lead to invalid syntax, as in: - // ```python - // if key in foo.keys()and bar: - // ``` - let range = TextRange::new(dot.start(), right.end()); - if checker - .locator() - .after(range.end()) - .chars() - .next() - .is_some_and(|char| char.is_ascii_alphabetic()) - { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - " ".to_string(), - range, - ))); - } else { - diagnostic.set_fix(Fix::suggested(Edit::range_deletion(range))); - } + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + " ".to_string(), + range, + ))); + } else { + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_deletion(range))); } } checker.diagnostics.push(diagnostic); diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/mod.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/mod.rs index 0e4b3b4937686..731eb845403dd 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/mod.rs @@ -1,10 +1,15 @@ pub(crate) use ast_bool_op::*; pub(crate) use ast_expr::*; -pub(crate) use ast_if::*; pub(crate) use ast_ifexp::*; pub(crate) use ast_unary_op::*; pub(crate) use ast_with::*; +pub(crate) use collapsible_if::*; +pub(crate) use if_else_block_instead_of_dict_get::*; +pub(crate) use if_else_block_instead_of_dict_lookup::*; +pub(crate) use if_else_block_instead_of_if_exp::*; +pub(crate) use if_with_same_arms::*; pub(crate) use key_in_dict::*; +pub(crate) use needless_bool::*; pub(crate) use open_file_with_context_handler::*; pub(crate) use reimplemented_builtin::*; pub(crate) use return_in_try_except_finally::*; @@ -13,13 +18,17 @@ pub(crate) use yoda_conditions::*; mod ast_bool_op; mod ast_expr; -mod ast_if; mod ast_ifexp; mod ast_unary_op; mod ast_with; -mod fix_if; +mod collapsible_if; mod fix_with; +mod if_else_block_instead_of_dict_get; +mod if_else_block_instead_of_dict_lookup; +mod if_else_block_instead_of_if_exp; +mod if_with_same_arms; mod key_in_dict; +mod needless_bool; mod open_file_with_context_handler; mod reimplemented_builtin; mod return_in_try_except_finally; diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/needless_bool.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/needless_bool.rs new file mode 100644 index 0000000000000..783dfe4fb55aa --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/needless_bool.rs @@ -0,0 +1,186 @@ +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, Arguments, Constant, ElifElseClause, Expr, ExprContext, Stmt}; +use ruff_python_semantic::analyze::typing::{is_sys_version_block, is_type_checking_block}; +use ruff_text_size::{Ranged, TextRange}; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for `if` statements that can be replaced with `bool`. +/// +/// ## Why is this bad? +/// `if` statements that return `True` for a truthy condition and `False` for +/// a falsey condition can be replaced with boolean casts. +/// +/// ## Example +/// ```python +/// if foo: +/// return True +/// else: +/// return False +/// ``` +/// +/// Use instead: +/// ```python +/// return bool(foo) +/// ``` +/// +/// ## References +/// - [Python documentation: Truth Value Testing](https://docs.python.org/3/library/stdtypes.html#truth-value-testing) +#[violation] +pub struct NeedlessBool { + condition: String, +} + +impl Violation for NeedlessBool { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; + + #[derive_message_formats] + fn message(&self) -> String { + let NeedlessBool { condition } = self; + format!("Return the condition `{condition}` directly") + } + + fn fix_title(&self) -> Option { + let NeedlessBool { condition } = self; + Some(format!("Replace with `return {condition}`")) + } +} + +/// SIM103 +pub(crate) fn needless_bool(checker: &mut Checker, stmt_if: &ast::StmtIf) { + let ast::StmtIf { + test: if_test, + body: if_body, + elif_else_clauses, + range: _, + } = stmt_if; + + // Extract an `if` or `elif` (that returns) followed by an else (that returns the same value) + let (if_test, if_body, else_body, range) = match elif_else_clauses.as_slice() { + // if-else case + [ElifElseClause { + body: else_body, + test: None, + .. + }] => (if_test.as_ref(), if_body, else_body, stmt_if.range()), + // elif-else case + [.., ElifElseClause { + body: elif_body, + test: Some(elif_test), + range: elif_range, + }, ElifElseClause { + body: else_body, + test: None, + range: else_range, + }] => ( + elif_test, + elif_body, + else_body, + TextRange::new(elif_range.start(), else_range.end()), + ), + _ => return, + }; + + let (Some(if_return), Some(else_return)) = ( + is_one_line_return_bool(if_body), + is_one_line_return_bool(else_body), + ) else { + return; + }; + + // If the branches have the same condition, abort (although the code could be + // simplified). + if if_return == else_return { + return; + } + + // Avoid suggesting ternary for `if sys.version_info >= ...`-style checks. + if is_sys_version_block(stmt_if, checker.semantic()) { + return; + } + + // Avoid suggesting ternary for `if TYPE_CHECKING:`-style checks. + if is_type_checking_block(stmt_if, checker.semantic()) { + return; + } + + let condition = checker.generator().expr(if_test); + let mut diagnostic = Diagnostic::new(NeedlessBool { condition }, range); + if matches!(if_return, Bool::True) + && matches!(else_return, Bool::False) + && !checker.indexer().has_comments(&range, checker.locator()) + && (if_test.is_compare_expr() || checker.semantic().is_builtin("bool")) + { + if if_test.is_compare_expr() { + // If the condition is a comparison, we can replace it with the condition. + let node = ast::StmtReturn { + value: Some(Box::new(if_test.clone())), + range: TextRange::default(), + }; + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + checker.generator().stmt(&node.into()), + range, + ))); + } else { + // Otherwise, we need to wrap the condition in a call to `bool`. (We've already + // verified, above, that `bool` is a builtin.) + let node = ast::ExprName { + id: "bool".into(), + ctx: ExprContext::Load, + range: TextRange::default(), + }; + let node1 = ast::ExprCall { + func: Box::new(node.into()), + arguments: Arguments { + args: vec![if_test.clone()], + keywords: vec![], + range: TextRange::default(), + }, + range: TextRange::default(), + }; + let node2 = ast::StmtReturn { + value: Some(Box::new(node1.into())), + range: TextRange::default(), + }; + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + checker.generator().stmt(&node2.into()), + range, + ))); + }; + } + checker.diagnostics.push(diagnostic); +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Bool { + True, + False, +} + +impl From for Bool { + fn from(value: bool) -> Self { + if value { + Bool::True + } else { + Bool::False + } + } +} + +fn is_one_line_return_bool(stmts: &[Stmt]) -> Option { + let [stmt] = stmts else { + return None; + }; + let Stmt::Return(ast::StmtReturn { value, range: _ }) = stmt else { + return None; + }; + let Some(Expr::Constant(ast::ExprConstant { value, .. })) = value.as_deref() else { + return None; + }; + let Constant::Bool(value) = value else { + return None; + }; + Some((*value).into()) +} diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/open_file_with_context_handler.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/open_file_with_context_handler.rs index a55c49d8808c3..49e7826217114 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/open_file_with_context_handler.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/open_file_with_context_handler.rs @@ -127,12 +127,41 @@ fn is_open(checker: &mut Checker, func: &Expr) -> bool { } } +/// Return `true` if the current expression is followed by a `close` call. +fn is_closed(semantic: &SemanticModel) -> bool { + let Some(expr) = semantic.current_expression_grandparent() else { + return false; + }; + + let Expr::Call(ast::ExprCall { + func, arguments, .. + }) = expr + else { + return false; + }; + + if !arguments.is_empty() { + return false; + } + + let Expr::Attribute(ast::ExprAttribute { attr, .. }) = func.as_ref() else { + return false; + }; + + attr.as_str() == "close" +} + /// SIM115 pub(crate) fn open_file_with_context_handler(checker: &mut Checker, func: &Expr) { if !is_open(checker, func) { return; } + // Ex) `open("foo.txt").close()` + if is_closed(checker.semantic()) { + return; + } + // Ex) `with open("foo.txt") as f: ...` if checker.semantic().current_statement().is_with_stmt() { return; diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/reimplemented_builtin.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/reimplemented_builtin.rs index 7529ba9ee4854..53e911e297779 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/reimplemented_builtin.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/reimplemented_builtin.rs @@ -1,17 +1,16 @@ -use ruff_python_ast::{ - self as ast, Arguments, CmpOp, Comprehension, Constant, Expr, ExprContext, Stmt, UnaryOp, -}; -use ruff_text_size::{Ranged, TextRange}; - -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::any_over_expr; use ruff_python_ast::traversal; +use ruff_python_ast::{ + self as ast, Arguments, CmpOp, Comprehension, Constant, Expr, ExprContext, Stmt, UnaryOp, +}; use ruff_python_codegen::Generator; +use ruff_text_size::{Ranged, TextRange}; use crate::checkers::ast::Checker; +use crate::fix::edits::fits; use crate::line_width::LineWidthBuilder; -use crate::registry::AsRule; /// ## What it does /// Checks for `for` loops that can be replaced with a builtin function, like @@ -43,7 +42,7 @@ pub struct ReimplementedBuiltin { } impl Violation for ReimplementedBuiltin { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -51,7 +50,7 @@ impl Violation for ReimplementedBuiltin { format!("Use `{replacement}` instead of `for` loop") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let ReimplementedBuiltin { replacement } = self; Some(format!("Replace with `{replacement}`")) } @@ -80,8 +79,9 @@ pub(crate) fn convert_for_loop_to_any_all(checker: &mut Checker, stmt: &Stmt) { return; }; - // Check if any of the expressions contain an `await` expression. - if contains_await(loop_.target) || contains_await(loop_.iter) || contains_await(loop_.test) { + // Check if any of the expressions contain an `await`, `yield`, or `yield from` expression. + // If so, turning the code into an any() or all() call would produce a SyntaxError. + if contains_yield_like(loop_.target) || contains_yield_like(loop_.test) { return; } @@ -97,12 +97,13 @@ pub(crate) fn convert_for_loop_to_any_all(checker: &mut Checker, stmt: &Stmt) { ); // Don't flag if the resulting expression would exceed the maximum line length. - let line_start = checker.locator().line_start(stmt.start()); - if LineWidthBuilder::new(checker.settings.tab_size) - .add_str(&checker.locator().contents()[TextRange::new(line_start, stmt.start())]) - .add_str(&contents) - > checker.settings.line_length - { + if !fits( + &contents, + stmt.into(), + checker.locator(), + checker.settings.pycodestyle.max_line_length, + checker.settings.tab_size, + ) { return; } @@ -112,8 +113,8 @@ pub(crate) fn convert_for_loop_to_any_all(checker: &mut Checker, stmt: &Stmt) { }, TextRange::new(stmt.start(), terminal.stmt.end()), ); - if checker.patch(diagnostic.kind.rule()) && checker.semantic().is_builtin("any") { - diagnostic.set_fix(Fix::suggested(Edit::replacement( + if checker.semantic().is_builtin("any") { + diagnostic.set_fix(Fix::unsafe_edit(Edit::replacement( contents, stmt.start(), terminal.stmt.end(), @@ -181,9 +182,13 @@ pub(crate) fn convert_for_loop_to_any_all(checker: &mut Checker, stmt: &Stmt) { // Don't flag if the resulting expression would exceed the maximum line length. let line_start = checker.locator().line_start(stmt.start()); if LineWidthBuilder::new(checker.settings.tab_size) - .add_str(&checker.locator().contents()[TextRange::new(line_start, stmt.start())]) + .add_str( + checker + .locator() + .slice(TextRange::new(line_start, stmt.start())), + ) .add_str(&contents) - > checker.settings.line_length + > checker.settings.pycodestyle.max_line_length { return; } @@ -194,8 +199,8 @@ pub(crate) fn convert_for_loop_to_any_all(checker: &mut Checker, stmt: &Stmt) { }, TextRange::new(stmt.start(), terminal.stmt.end()), ); - if checker.patch(diagnostic.kind.rule()) && checker.semantic().is_builtin("all") { - diagnostic.set_fix(Fix::suggested(Edit::replacement( + if checker.semantic().is_builtin("all") { + diagnostic.set_fix(Fix::unsafe_edit(Edit::replacement( contents, stmt.start(), terminal.stmt.end(), @@ -405,7 +410,9 @@ fn return_stmt(id: &str, test: &Expr, target: &Expr, iter: &Expr, generator: Gen generator.stmt(&node3.into()) } -/// Return `true` if the [`Expr`] contains an `await` expression. -fn contains_await(expr: &Expr) -> bool { +/// Return `true` if the [`Expr`] contains an `await`, `yield`, or `yield from` expression. +fn contains_yield_like(expr: &Expr) -> bool { any_over_expr(expr, &Expr::is_await_expr) + || any_over_expr(expr, &Expr::is_yield_expr) + || any_over_expr(expr, &Expr::is_yield_from_expr) } diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/suppressible_exception.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/suppressible_exception.rs index 03e4b2f08c232..60d625f5656e6 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/suppressible_exception.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/suppressible_exception.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::call_path::compose_call_path; use ruff_python_ast::helpers; @@ -8,7 +8,6 @@ use ruff_text_size::{TextLen, TextRange}; use crate::checkers::ast::Checker; use crate::importer::ImportRequest; -use crate::registry::AsRule; /// ## What it does /// Checks for `try`-`except`-`pass` blocks that can be replaced with the @@ -48,7 +47,7 @@ pub struct SuppressibleException { } impl Violation for SuppressibleException { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -56,7 +55,7 @@ impl Violation for SuppressibleException { format!("Use `contextlib.suppress({exception})` instead of `try`-`except`-`pass`") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let SuppressibleException { exception } = self; Some(format!("Replace with `contextlib.suppress({exception})`")) } @@ -132,28 +131,25 @@ pub(crate) fn suppressible_exception( }, stmt.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if !checker.indexer().has_comments(stmt, checker.locator()) { - diagnostic.try_set_fix(|| { - // let range = statement_range(stmt, checker.locator(), checker.indexer()); + if !checker.indexer().has_comments(stmt, checker.locator()) { + diagnostic.try_set_fix(|| { + // let range = statement_range(stmt, checker.locator(), checker.indexer()); - let (import_edit, binding) = checker.importer().get_or_import_symbol( - &ImportRequest::import("contextlib", "suppress"), - stmt.start(), - checker.semantic(), - )?; - let replace_try = Edit::range_replacement( - format!("with {binding}({exception})"), - TextRange::at(stmt.start(), "try".text_len()), - ); - let remove_handler = - Edit::range_deletion(checker.locator().full_lines_range(*range)); - Ok(Fix::suggested_edits( - import_edit, - [replace_try, remove_handler], - )) - }); - } + let (import_edit, binding) = checker.importer().get_or_import_symbol( + &ImportRequest::import("contextlib", "suppress"), + stmt.start(), + checker.semantic(), + )?; + let replace_try = Edit::range_replacement( + format!("with {binding}({exception})"), + TextRange::at(stmt.start(), "try".text_len()), + ); + let remove_handler = Edit::range_deletion(checker.locator().full_lines_range(*range)); + Ok(Fix::unsafe_edits( + import_edit, + [replace_try, remove_handler], + )) + }); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/yoda_conditions.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/yoda_conditions.rs index 2fc1ae1fb11f1..f58c2f165255b 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/yoda_conditions.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/yoda_conditions.rs @@ -1,7 +1,7 @@ use anyhow::Result; use libcst_native::CompOp; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, CmpOp, Expr, UnaryOp}; use ruff_python_codegen::Stylist; @@ -9,12 +9,11 @@ use ruff_python_stdlib::str::{self}; use ruff_source_file::Locator; use ruff_text_size::Ranged; -use crate::autofix::edits::pad; -use crate::autofix::snippet::SourceCodeSnippet; use crate::checkers::ast::Checker; use crate::cst::helpers::or_space; use crate::cst::matchers::{match_comparison, transform_expression}; -use crate::registry::AsRule; +use crate::fix::edits::pad; +use crate::fix::snippet::SourceCodeSnippet; /// ## What it does /// Checks for conditions that position a constant on the left-hand side of the @@ -52,7 +51,7 @@ pub struct YodaConditions { } impl Violation for YodaConditions { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -67,7 +66,7 @@ impl Violation for YodaConditions { } } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let YodaConditions { suggestion } = self; suggestion.as_ref().map(|suggestion| { if let Some(suggestion) = suggestion.full_display() { @@ -193,12 +192,10 @@ pub(crate) fn yoda_conditions( }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - pad(suggestion, expr.range(), checker.locator()), - expr.range(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + pad(suggestion, expr.range(), checker.locator()), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } else { checker.diagnostics.push(Diagnostic::new( diff --git a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM101_SIM101.py.snap b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM101_SIM101.py.snap index 1368303ffa0b8..11dda2b013cce 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM101_SIM101.py.snap +++ b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM101_SIM101.py.snap @@ -71,31 +71,11 @@ SIM101.py:10:4: SIM101 [*] Multiple `isinstance` calls for `a`, merge into a sin 8 8 | pass 9 9 | 10 |-if isinstance(b, bool) or isinstance(a, int) or isinstance(a, float): # SIM101 - 10 |+if isinstance(a, (int, float)) or isinstance(b, bool): # SIM101 + 10 |+if isinstance(b, bool) or isinstance(a, (int, float)): # SIM101 11 11 | pass 12 12 | 13 13 | if isinstance(a, int) or isinstance(b, bool) or isinstance(a, float): # SIM101 -SIM101.py:13:4: SIM101 [*] Multiple `isinstance` calls for `a`, merge into a single call - | -11 | pass -12 | -13 | if isinstance(a, int) or isinstance(b, bool) or isinstance(a, float): # SIM101 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM101 -14 | pass - | - = help: Merge `isinstance` calls for `a` - -ℹ Suggested fix -10 10 | if isinstance(b, bool) or isinstance(a, int) or isinstance(a, float): # SIM101 -11 11 | pass -12 12 | -13 |-if isinstance(a, int) or isinstance(b, bool) or isinstance(a, float): # SIM101 - 13 |+if isinstance(a, (int, float)) or isinstance(b, bool): # SIM101 -14 14 | pass -15 15 | -16 16 | if (isinstance(a, int) or isinstance(a, float)) and isinstance(b, bool): # SIM101 - SIM101.py:16:5: SIM101 [*] Multiple `isinstance` calls for `a`, merge into a single call | 14 | pass @@ -146,4 +126,44 @@ SIM101.py:22:4: SIM101 Multiple `isinstance` calls for expression, merge into a | = help: Merge `isinstance` calls +SIM101.py:38:4: SIM101 [*] Multiple `isinstance` calls for `a`, merge into a single call + | +36 | pass +37 | +38 | if x or isinstance(a, int) or isinstance(a, float): + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM101 +39 | pass + | + = help: Merge `isinstance` calls for `a` + +ℹ Suggested fix +35 35 | if isinstance(a, int) or unrelated_condition or isinstance(a, float): +36 36 | pass +37 37 | +38 |-if x or isinstance(a, int) or isinstance(a, float): + 38 |+if x or isinstance(a, (int, float)): +39 39 | pass +40 40 | +41 41 | if x or y or isinstance(a, int) or isinstance(a, float) or z: + +SIM101.py:41:4: SIM101 [*] Multiple `isinstance` calls for `a`, merge into a single call + | +39 | pass +40 | +41 | if x or y or isinstance(a, int) or isinstance(a, float) or z: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM101 +42 | pass + | + = help: Merge `isinstance` calls for `a` + +ℹ Suggested fix +38 38 | if x or isinstance(a, int) or isinstance(a, float): +39 39 | pass +40 40 | +41 |-if x or y or isinstance(a, int) or isinstance(a, float) or z: + 41 |+if x or y or isinstance(a, (int, float)) or z: +42 42 | pass +43 43 | +44 44 | def f(): + diff --git a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM110_SIM110.py.snap b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM110_SIM110.py.snap index 1473e4bfdaab3..6ddf17ea9046f 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM110_SIM110.py.snap +++ b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM110_SIM110.py.snap @@ -304,6 +304,8 @@ SIM110.py:184:5: SIM110 [*] Use `return any(check(x) for x in iterable)` instead 186 | | return True 187 | | return False | |________________^ SIM110 +188 | +189 | async def f(): | = help: Replace with `return any(check(x) for x in iterable)` @@ -316,5 +318,36 @@ SIM110.py:184:5: SIM110 [*] Use `return any(check(x) for x in iterable)` instead 186 |- return True 187 |- return False 184 |+ return any(check(x) for x in iterable) +188 185 | +189 186 | async def f(): +190 187 | # SIM110 + +SIM110.py:191:5: SIM110 [*] Use `return any(check(x) for x in await iterable)` instead of `for` loop + | +189 | async def f(): +190 | # SIM110 +191 | for x in await iterable: + | _____^ +192 | | if check(x): +193 | | return True +194 | | return False + | |________________^ SIM110 +195 | +196 | def f(): + | + = help: Replace with `return any(check(x) for x in await iterable)` + +ℹ Suggested fix +188 188 | +189 189 | async def f(): +190 190 | # SIM110 +191 |- for x in await iterable: +192 |- if check(x): +193 |- return True +194 |- return False + 191 |+ return any(check(x) for x in await iterable) +195 192 | +196 193 | def f(): +197 194 | # OK (can't turn this into any() because the yield would end up inside a genexp) diff --git a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM117_SIM117.py.snap b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM117_SIM117.py.snap index d2b6f1de2b2c2..bbc83f3ed4cd6 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM117_SIM117.py.snap +++ b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM117_SIM117.py.snap @@ -284,4 +284,37 @@ SIM117.py:106:5: SIM117 Use a single `with` statement with multiple contexts ins | = help: Combine `with` statements +SIM117.py:126:1: SIM117 [*] Use a single `with` statement with multiple contexts instead of nested `with` statements + | +125 | # SIM117 +126 | / with A() as a: +127 | | with B() as b: + | |__________________^ SIM117 +128 | type ListOrSet[T] = list[T] | set[T] + | + = help: Combine `with` statements + +ℹ Suggested fix +123 123 | f(b2, c2, d2) +124 124 | +125 125 | # SIM117 +126 |-with A() as a: +127 |- with B() as b: +128 |- type ListOrSet[T] = list[T] | set[T] + 126 |+with A() as a, B() as b: + 127 |+ type ListOrSet[T] = list[T] | set[T] +129 128 | +130 |- class ClassA[T: str]: +131 |- def method1(self) -> T: +132 |- ... + 129 |+ class ClassA[T: str]: + 130 |+ def method1(self) -> T: + 131 |+ ... +133 132 | +134 |- f" something { my_dict["key"] } something else " + 133 |+ f" something { my_dict["key"] } something else " +135 134 | +136 |- f"foo {f"bar {x}"} baz" + 135 |+ f"foo {f"bar {x}"} baz" + diff --git a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM202_SIM202.py.snap b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM202_SIM202.py.snap index 739679e4deb3c..e29314b74baee 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM202_SIM202.py.snap +++ b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM202_SIM202.py.snap @@ -10,7 +10,7 @@ SIM202.py:2:4: SIM202 [*] Use `a == b` instead of `not a != b` | = help: Replace with `==` operator -ℹ Suggested fix +ℹ Fix 1 1 | # SIM202 2 |-if not a != b: 2 |+if a == b: @@ -27,7 +27,7 @@ SIM202.py:6:4: SIM202 [*] Use `a == b + c` instead of `not a != b + c` | = help: Replace with `==` operator -ℹ Suggested fix +ℹ Fix 3 3 | pass 4 4 | 5 5 | # SIM202 @@ -46,7 +46,7 @@ SIM202.py:10:4: SIM202 [*] Use `a + b == c` instead of `not a + b != c` | = help: Replace with `==` operator -ℹ Suggested fix +ℹ Fix 7 7 | pass 8 8 | 9 9 | # SIM202 diff --git a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM208_SIM208.py.snap b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM208_SIM208.py.snap index f1b5030c024dd..481781d5aa959 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM208_SIM208.py.snap +++ b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__SIM208_SIM208.py.snap @@ -9,7 +9,7 @@ SIM208.py:1:4: SIM208 [*] Use `a` instead of `not (not a)` | = help: Replace with `a` -ℹ Suggested fix +ℹ Fix 1 |-if not (not a): # SIM208 1 |+if a: # SIM208 2 2 | pass @@ -26,7 +26,7 @@ SIM208.py:4:4: SIM208 [*] Use `a == b` instead of `not (not a == b)` | = help: Replace with `a == b` -ℹ Suggested fix +ℹ Fix 1 1 | if not (not a): # SIM208 2 2 | pass 3 3 | @@ -47,7 +47,7 @@ SIM208.py:16:5: SIM208 [*] Use `b` instead of `not (not b)` | = help: Replace with `b` -ℹ Suggested fix +ℹ Fix 13 13 | if not a != b: # OK 14 14 | pass 15 15 | @@ -68,7 +68,7 @@ SIM208.py:18:3: SIM208 [*] Use `a` instead of `not (not a)` | = help: Replace with `a` -ℹ Suggested fix +ℹ Fix 15 15 | 16 16 | a = not not b # SIM208 17 17 | @@ -88,7 +88,7 @@ SIM208.py:20:9: SIM208 [*] Use `a` instead of `not (not a)` | = help: Replace with `a` -ℹ Suggested fix +ℹ Fix 17 17 | 18 18 | f(not not a) # SIM208 19 19 | diff --git a/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__preview__SIM401_SIM401.py.snap b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__preview__SIM401_SIM401.py.snap new file mode 100644 index 0000000000000..6f807586d4c77 --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_simplify/snapshots/ruff_linter__rules__flake8_simplify__tests__preview__SIM401_SIM401.py.snap @@ -0,0 +1,202 @@ +--- +source: crates/ruff_linter/src/rules/flake8_simplify/mod.rs +--- +SIM401.py:6:1: SIM401 [*] Use `var = a_dict.get(key, "default1")` instead of an `if` block + | + 5 | # SIM401 (pattern-1) + 6 | / if key in a_dict: + 7 | | var = a_dict[key] + 8 | | else: + 9 | | var = "default1" + | |____________________^ SIM401 +10 | +11 | # SIM401 (pattern-2) + | + = help: Replace with `var = a_dict.get(key, "default1")` + +ℹ Suggested fix +3 3 | ### +4 4 | +5 5 | # SIM401 (pattern-1) +6 |-if key in a_dict: +7 |- var = a_dict[key] +8 |-else: +9 |- var = "default1" + 6 |+var = a_dict.get(key, "default1") +10 7 | +11 8 | # SIM401 (pattern-2) +12 9 | if key not in a_dict: + +SIM401.py:12:1: SIM401 [*] Use `var = a_dict.get(key, "default2")` instead of an `if` block + | +11 | # SIM401 (pattern-2) +12 | / if key not in a_dict: +13 | | var = "default2" +14 | | else: +15 | | var = a_dict[key] + | |_____________________^ SIM401 +16 | +17 | # OK (default contains effect) + | + = help: Replace with `var = a_dict.get(key, "default2")` + +ℹ Suggested fix +9 9 | var = "default1" +10 10 | +11 11 | # SIM401 (pattern-2) +12 |-if key not in a_dict: +13 |- var = "default2" +14 |-else: +15 |- var = a_dict[key] + 12 |+var = a_dict.get(key, "default2") +16 13 | +17 14 | # OK (default contains effect) +18 15 | if key in a_dict: + +SIM401.py:24:1: SIM401 [*] Use `var = a_dict.get(keys[idx], "default")` instead of an `if` block + | +23 | # SIM401 (complex expression in key) +24 | / if keys[idx] in a_dict: +25 | | var = a_dict[keys[idx]] +26 | | else: +27 | | var = "default" + | |___________________^ SIM401 +28 | +29 | # SIM401 (complex expression in dict) + | + = help: Replace with `var = a_dict.get(keys[idx], "default")` + +ℹ Suggested fix +21 21 | var = val1 + val2 +22 22 | +23 23 | # SIM401 (complex expression in key) +24 |-if keys[idx] in a_dict: +25 |- var = a_dict[keys[idx]] +26 |-else: +27 |- var = "default" + 24 |+var = a_dict.get(keys[idx], "default") +28 25 | +29 26 | # SIM401 (complex expression in dict) +30 27 | if key in dicts[idx]: + +SIM401.py:30:1: SIM401 [*] Use `var = dicts[idx].get(key, "default")` instead of an `if` block + | +29 | # SIM401 (complex expression in dict) +30 | / if key in dicts[idx]: +31 | | var = dicts[idx][key] +32 | | else: +33 | | var = "default" + | |___________________^ SIM401 +34 | +35 | # SIM401 (complex expression in var) + | + = help: Replace with `var = dicts[idx].get(key, "default")` + +ℹ Suggested fix +27 27 | var = "default" +28 28 | +29 29 | # SIM401 (complex expression in dict) +30 |-if key in dicts[idx]: +31 |- var = dicts[idx][key] +32 |-else: +33 |- var = "default" + 30 |+var = dicts[idx].get(key, "default") +34 31 | +35 32 | # SIM401 (complex expression in var) +36 33 | if key in a_dict: + +SIM401.py:36:1: SIM401 [*] Use `vars[idx] = a_dict.get(key, "defaultß9💣2ℝ6789ß9💣2ℝ6789ß9💣2ℝ6789ß9💣2ℝ6789ß9💣2ℝ6789")` instead of an `if` block + | +35 | # SIM401 (complex expression in var) +36 | / if key in a_dict: +37 | | vars[idx] = a_dict[key] +38 | | else: +39 | | vars[idx] = "defaultß9💣2ℝ6789ß9💣2ℝ6789ß9💣2ℝ6789ß9💣2ℝ6789ß9💣2ℝ6789" + | |___________________________________________________________________________^ SIM401 +40 | +41 | # SIM401 + | + = help: Replace with `vars[idx] = a_dict.get(key, "defaultß9💣2ℝ6789ß9💣2ℝ6789ß9💣2ℝ6789ß9💣2ℝ6789ß9💣2ℝ6789")` + +ℹ Suggested fix +33 33 | var = "default" +34 34 | +35 35 | # SIM401 (complex expression in var) +36 |-if key in a_dict: +37 |- vars[idx] = a_dict[key] +38 |-else: +39 |- vars[idx] = "defaultß9💣2ℝ6789ß9💣2ℝ6789ß9💣2ℝ6789ß9💣2ℝ6789ß9💣2ℝ6789" + 36 |+vars[idx] = a_dict.get(key, "defaultß9💣2ℝ6789ß9💣2ℝ6789ß9💣2ℝ6789ß9💣2ℝ6789ß9💣2ℝ6789") +40 37 | +41 38 | # SIM401 +42 39 | if foo(): + +SIM401.py:45:5: SIM401 [*] Use `vars[idx] = a_dict.get(key, "default")` instead of an `if` block + | +43 | pass +44 | else: +45 | if key in a_dict: + | _____^ +46 | | vars[idx] = a_dict[key] +47 | | else: +48 | | vars[idx] = "default" + | |_____________________________^ SIM401 +49 | +50 | ### + | + = help: Replace with `vars[idx] = a_dict.get(key, "default")` + +ℹ Suggested fix +42 42 | if foo(): +43 43 | pass +44 44 | else: +45 |- if key in a_dict: +46 |- vars[idx] = a_dict[key] +47 |- else: +48 |- vars[idx] = "default" + 45 |+ vars[idx] = a_dict.get(key, "default") +49 46 | +50 47 | ### +51 48 | # Negative cases + +SIM401.py:123:7: SIM401 [*] Use `a_dict.get(key, "default3")` instead of an `if` block + | +122 | # SIM401 +123 | var = a_dict[key] if key in a_dict else "default3" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM401 +124 | +125 | # SIM401 + | + = help: Replace with `a_dict.get(key, "default3")` + +ℹ Suggested fix +120 120 | ### +121 121 | +122 122 | # SIM401 +123 |-var = a_dict[key] if key in a_dict else "default3" + 123 |+var = a_dict.get(key, "default3") +124 124 | +125 125 | # SIM401 +126 126 | var = "default-1" if key not in a_dict else a_dict[key] + +SIM401.py:126:7: SIM401 [*] Use `a_dict.get(key, "default-1")` instead of an `if` block + | +125 | # SIM401 +126 | var = "default-1" if key not in a_dict else a_dict[key] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM401 +127 | +128 | # OK (default contains effect) + | + = help: Replace with `a_dict.get(key, "default-1")` + +ℹ Suggested fix +123 123 | var = a_dict[key] if key in a_dict else "default3" +124 124 | +125 125 | # SIM401 +126 |-var = "default-1" if key not in a_dict else a_dict[key] + 126 |+var = a_dict.get(key, "default-1") +127 127 | +128 128 | # OK (default contains effect) +129 129 | var = a_dict[key] if key in a_dict else val1 + val2 + + diff --git a/crates/ruff_linter/src/rules/flake8_tidy_imports/rules/relative_imports.rs b/crates/ruff_linter/src/rules/flake8_tidy_imports/rules/relative_imports.rs index 143f35f7d4a6d..befbd919de356 100644 --- a/crates/ruff_linter/src/rules/flake8_tidy_imports/rules/relative_imports.rs +++ b/crates/ruff_linter/src/rules/flake8_tidy_imports/rules/relative_imports.rs @@ -1,14 +1,14 @@ use ruff_python_ast::{self as ast, Identifier, Stmt}; use ruff_text_size::{Ranged, TextRange}; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::resolve_imported_module_path; use ruff_python_codegen::Generator; use ruff_python_stdlib::identifiers::is_identifier; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::flake8_tidy_imports::settings::Strictness; /// ## What it does @@ -51,7 +51,7 @@ pub struct RelativeImports { } impl Violation for RelativeImports { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -61,7 +61,7 @@ impl Violation for RelativeImports { } } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let RelativeImports { strictness } = self; Some(match strictness { Strictness::Parents => { @@ -103,7 +103,7 @@ fn fix_banned_relative_import( range: TextRange::default(), }; let content = generator.stmt(&node.into()); - Some(Fix::suggested(Edit::range_replacement( + Some(Fix::unsafe_edit(Edit::range_replacement( content, stmt.range(), ))) @@ -124,13 +124,11 @@ pub(crate) fn banned_relative_import( }; if level? > strictness_level { let mut diagnostic = Diagnostic::new(RelativeImports { strictness }, stmt.range()); - if checker.patch(diagnostic.kind.rule()) { - if let Some(fix) = - fix_banned_relative_import(stmt, level, module, module_path, checker.generator()) - { - diagnostic.set_fix(fix); - }; - } + if let Some(fix) = + fix_banned_relative_import(stmt, level, module, module_path, checker.generator()) + { + diagnostic.set_fix(fix); + }; Some(diagnostic) } else { None diff --git a/crates/ruff_linter/src/rules/flake8_todos/rules/todos.rs b/crates/ruff_linter/src/rules/flake8_todos/rules/todos.rs index 5e6f84253b77f..cbd5a1b2a2cc9 100644 --- a/crates/ruff_linter/src/rules/flake8_todos/rules/todos.rs +++ b/crates/ruff_linter/src/rules/flake8_todos/rules/todos.rs @@ -4,14 +4,10 @@ use ruff_python_index::Indexer; use ruff_source_file::Locator; use ruff_text_size::{TextLen, TextRange, TextSize}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; -use crate::settings::LinterSettings; -use crate::{ - directives::{TodoComment, TodoDirective, TodoDirectiveKind}, - registry::Rule, -}; +use crate::directives::{TodoComment, TodoDirective, TodoDirectiveKind}; /// ## What it does /// Checks that a TODO comment is labelled with "TODO". @@ -184,14 +180,14 @@ pub struct InvalidTodoCapitalization { tag: String, } -impl AlwaysAutofixableViolation for InvalidTodoCapitalization { +impl AlwaysFixableViolation for InvalidTodoCapitalization { #[derive_message_formats] fn message(&self) -> String { let InvalidTodoCapitalization { tag } = self; format!("Invalid TODO capitalization: `{tag}` should be `TODO`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let InvalidTodoCapitalization { tag } = self; format!("Replace `{tag}` with `TODO`") } @@ -240,7 +236,6 @@ pub(crate) fn todos( todo_comments: &[TodoComment], locator: &Locator, indexer: &Indexer, - settings: &LinterSettings, ) { for todo_comment in todo_comments { let TodoComment { @@ -256,7 +251,7 @@ pub(crate) fn todos( continue; } - directive_errors(diagnostics, directive, settings); + directive_errors(diagnostics, directive); static_errors(diagnostics, content, range, directive); let mut has_issue_link = false; @@ -300,11 +295,7 @@ pub(crate) fn todos( } /// Check that the directive itself is valid. This function modifies `diagnostics` in-place. -fn directive_errors( - diagnostics: &mut Vec, - directive: &TodoDirective, - settings: &LinterSettings, -) { +fn directive_errors(diagnostics: &mut Vec, directive: &TodoDirective) { if directive.content == "TODO" { return; } @@ -318,12 +309,10 @@ fn directive_errors( directive.range, ); - if settings.rules.should_fix(Rule::InvalidTodoCapitalization) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - "TODO".to_string(), - directive.range, - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "TODO".to_string(), + directive.range, + ))); diagnostics.push(diagnostic); } else { diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs b/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs index 31b5c6d2c3c86..b2f0e456e3804 100644 --- a/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs +++ b/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs @@ -1,5 +1,5 @@ use ruff_python_ast::call_path::from_qualified_name; -use ruff_python_ast::helpers::map_callable; +use ruff_python_ast::helpers::{map_callable, map_subscript}; use ruff_python_semantic::{Binding, BindingKind, ScopeKind, SemanticModel}; pub(crate) fn is_valid_runtime_import(binding: &Binding, semantic: &SemanticModel) -> bool { @@ -40,11 +40,13 @@ fn runtime_evaluated_base_class(base_classes: &[String], semantic: &SemanticMode }; class_def.bases().iter().any(|base| { - semantic.resolve_call_path(base).is_some_and(|call_path| { - base_classes - .iter() - .any(|base_class| from_qualified_name(base_class) == call_path) - }) + semantic + .resolve_call_path(map_subscript(base)) + .is_some_and(|call_path| { + base_classes + .iter() + .any(|base_class| from_qualified_name(base_class) == call_path) + }) }) } diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/mod.rs b/crates/ruff_linter/src/rules/flake8_type_checking/mod.rs index 314e1a67851f5..8bda8ec66dd6f 100644 --- a/crates/ruff_linter/src/rules/flake8_type_checking/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_type_checking/mod.rs @@ -22,6 +22,7 @@ mod tests { #[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_12.py"))] #[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_13.py"))] #[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_14.pyi"))] + #[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_15.py"))] #[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_2.py"))] #[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_3.py"))] #[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_4.py"))] diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/rules/empty_type_checking_block.rs b/crates/ruff_linter/src/rules/flake8_type_checking/rules/empty_type_checking_block.rs index 1a00637c85b80..10ccdd1a9e7e3 100644 --- a/crates/ruff_linter/src/rules/flake8_type_checking/rules/empty_type_checking_block.rs +++ b/crates/ruff_linter/src/rules/flake8_type_checking/rules/empty_type_checking_block.rs @@ -1,12 +1,11 @@ use ruff_python_ast as ast; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; -use crate::autofix; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix; /// ## What it does /// Checks for an empty type-checking block. @@ -35,13 +34,13 @@ use crate::registry::AsRule; #[violation] pub struct EmptyTypeCheckingBlock; -impl AlwaysAutofixableViolation for EmptyTypeCheckingBlock { +impl AlwaysFixableViolation for EmptyTypeCheckingBlock { #[derive_message_formats] fn message(&self) -> String { format!("Found empty type-checking block") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { format!("Delete empty type-checking block") } } @@ -56,14 +55,12 @@ pub(crate) fn empty_type_checking_block(checker: &mut Checker, stmt: &ast::StmtI } let mut diagnostic = Diagnostic::new(EmptyTypeCheckingBlock, stmt.range()); - if checker.patch(diagnostic.kind.rule()) { - // Delete the entire type-checking block. - let stmt = checker.semantic().current_statement(); - let parent = checker.semantic().current_statement_parent(); - let edit = autofix::edits::delete_stmt(stmt, parent, checker.locator(), checker.indexer()); - diagnostic.set_fix(Fix::automatic(edit).isolate(Checker::isolation( - checker.semantic().current_statement_parent_id(), - ))); - } + // Delete the entire type-checking block. + let stmt = checker.semantic().current_statement(); + let parent = checker.semantic().current_statement_parent(); + let edit = fix::edits::delete_stmt(stmt, parent, checker.locator(), checker.indexer()); + diagnostic.set_fix(Fix::safe_edit(edit).isolate(Checker::isolation( + checker.semantic().current_statement_parent_id(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/rules/runtime_import_in_type_checking_block.rs b/crates/ruff_linter/src/rules/flake8_type_checking/rules/runtime_import_in_type_checking_block.rs index 3f39d4ad542af..dea0f4007e0cd 100644 --- a/crates/ruff_linter/src/rules/flake8_type_checking/rules/runtime_import_in_type_checking_block.rs +++ b/crates/ruff_linter/src/rules/flake8_type_checking/rules/runtime_import_in_type_checking_block.rs @@ -3,14 +3,14 @@ use std::borrow::Cow; use anyhow::Result; use rustc_hash::FxHashMap; -use ruff_diagnostics::{AutofixKind, Diagnostic, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_semantic::{AnyImport, Imported, NodeId, ResolvedReferenceId, Scope}; use ruff_text_size::{Ranged, TextRange}; -use crate::autofix; use crate::checkers::ast::Checker; use crate::codes::Rule; +use crate::fix; use crate::importer::ImportedMembers; /// ## What it does @@ -49,7 +49,7 @@ pub struct RuntimeImportInTypeCheckingBlock { } impl Violation for RuntimeImportInTypeCheckingBlock { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -59,7 +59,7 @@ impl Violation for RuntimeImportInTypeCheckingBlock { ) } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Move out of type-checking block".to_string()) } } @@ -126,11 +126,7 @@ pub(crate) fn runtime_import_in_type_checking_block( // Generate a diagnostic for every import, but share a fix across all imports within the same // statement (excluding those that are ignored). for (node_id, imports) in errors_by_statement { - let fix = if checker.patch(Rule::RuntimeImportInTypeCheckingBlock) { - fix_imports(checker, node_id, &imports).ok() - } else { - None - }; + let fix = fix_imports(checker, node_id, &imports).ok(); for ImportBinding { import, @@ -216,7 +212,7 @@ fn fix_imports(checker: &Checker, node_id: NodeId, imports: &[ImportBinding]) -> .expect("Expected at least one import"); // Step 1) Remove the import. - let remove_import_edit = autofix::edits::remove_unused_imports( + let remove_import_edit = fix::edits::remove_unused_imports( member_names.iter().map(AsRef::as_ref), statement, parent, @@ -235,7 +231,7 @@ fn fix_imports(checker: &Checker, node_id: NodeId, imports: &[ImportBinding]) -> )?; Ok( - Fix::suggested_edits(remove_import_edit, add_import_edit.into_edits()).isolate( + Fix::unsafe_edits(remove_import_edit, add_import_edit.into_edits()).isolate( Checker::isolation(checker.semantic().parent_statement_id(node_id)), ), ) diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs b/crates/ruff_linter/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs index eb933f2c31e9a..2b9c39f8cb0c6 100644 --- a/crates/ruff_linter/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs +++ b/crates/ruff_linter/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs @@ -3,14 +3,14 @@ use std::borrow::Cow; use anyhow::Result; use rustc_hash::FxHashMap; -use ruff_diagnostics::{AutofixKind, Diagnostic, DiagnosticKind, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, DiagnosticKind, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_semantic::{AnyImport, Binding, Imported, NodeId, ResolvedReferenceId, Scope}; use ruff_text_size::{Ranged, TextRange}; -use crate::autofix; use crate::checkers::ast::Checker; use crate::codes::Rule; +use crate::fix; use crate::importer::ImportedMembers; use crate::rules::isort::{categorize, ImportSection, ImportType}; @@ -67,7 +67,7 @@ pub struct TypingOnlyFirstPartyImport { } impl Violation for TypingOnlyFirstPartyImport { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -77,7 +77,7 @@ impl Violation for TypingOnlyFirstPartyImport { ) } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Move into type-checking block".to_string()) } } @@ -135,7 +135,7 @@ pub struct TypingOnlyThirdPartyImport { } impl Violation for TypingOnlyThirdPartyImport { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -145,7 +145,7 @@ impl Violation for TypingOnlyThirdPartyImport { ) } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Move into type-checking block".to_string()) } } @@ -203,7 +203,7 @@ pub struct TypingOnlyStandardLibraryImport { } impl Violation for TypingOnlyStandardLibraryImport { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -213,7 +213,7 @@ impl Violation for TypingOnlyStandardLibraryImport { ) } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Move into type-checking block".to_string()) } } @@ -334,11 +334,7 @@ pub(crate) fn typing_only_runtime_import( // Generate a diagnostic for every import, but share a fix across all imports within the same // statement (excluding those that are ignored). for ((node_id, import_type), imports) in errors_by_statement { - let fix = if checker.patch(rule_for(import_type)) { - fix_imports(checker, node_id, &imports).ok() - } else { - None - }; + let fix = fix_imports(checker, node_id, &imports).ok(); for ImportBinding { import, @@ -465,7 +461,7 @@ fn fix_imports(checker: &Checker, node_id: NodeId, imports: &[ImportBinding]) -> .expect("Expected at least one import"); // Step 1) Remove the import. - let remove_import_edit = autofix::edits::remove_unused_imports( + let remove_import_edit = fix::edits::remove_unused_imports( member_names.iter().map(AsRef::as_ref), statement, parent, @@ -486,7 +482,7 @@ fn fix_imports(checker: &Checker, node_id: NodeId, imports: &[ImportBinding]) -> )?; Ok( - Fix::suggested_edits(remove_import_edit, add_import_edit.into_edits()).isolate( + Fix::unsafe_edits(remove_import_edit, add_import_edit.into_edits()).isolate( Checker::isolation(checker.semantic().parent_statement_id(node_id)), ), ) diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__runtime-import-in-type-checking-block_TCH004_15.py.snap b/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__runtime-import-in-type-checking-block_TCH004_15.py.snap new file mode 100644 index 0000000000000..6c5ead27428ce --- /dev/null +++ b/crates/ruff_linter/src/rules/flake8_type_checking/snapshots/ruff_linter__rules__flake8_type_checking__tests__runtime-import-in-type-checking-block_TCH004_15.py.snap @@ -0,0 +1,4 @@ +--- +source: crates/ruff_linter/src/rules/flake8_type_checking/mod.rs +--- + diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/path_constructor_current_directory.rs b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/path_constructor_current_directory.rs index 3103f0577e235..b85bba684e10c 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/path_constructor_current_directory.rs +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/path_constructor_current_directory.rs @@ -1,10 +1,9 @@ use ruff_python_ast::{self as ast, Arguments, Constant, Expr, ExprCall, ExprConstant}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for `pathlib.Path` objects that are initialized with the current @@ -33,13 +32,13 @@ use crate::registry::AsRule; #[violation] pub struct PathConstructorCurrentDirectory; -impl AlwaysAutofixableViolation for PathConstructorCurrentDirectory { +impl AlwaysFixableViolation for PathConstructorCurrentDirectory { #[derive_message_formats] fn message(&self) -> String { format!("Do not pass the current directory explicitly to `Path`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove the current directory argument".to_string() } } @@ -76,9 +75,7 @@ pub(crate) fn path_constructor_current_directory(checker: &mut Checker, expr: &E if matches!(value.as_str(), "" | ".") { let mut diagnostic = Diagnostic::new(PathConstructorCurrentDirectory, *range); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::range_deletion(*range))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(*range))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs index 7e65c574559a8..18d14b091f90c 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs @@ -1,5 +1,5 @@ use ruff_diagnostics::{Diagnostic, DiagnosticKind}; -use ruff_python_ast::Expr; +use ruff_python_ast::{Constant, Expr, ExprCall, ExprConstant}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -8,18 +8,18 @@ use crate::rules::flake8_use_pathlib::rules::{ Glob, OsPathGetatime, OsPathGetctime, OsPathGetmtime, OsPathGetsize, }; use crate::rules::flake8_use_pathlib::violations::{ - BuiltinOpen, OsChmod, OsGetcwd, OsMakedirs, OsMkdir, OsPathAbspath, OsPathBasename, + BuiltinOpen, Joiner, OsChmod, OsGetcwd, OsMakedirs, OsMkdir, OsPathAbspath, OsPathBasename, OsPathDirname, OsPathExists, OsPathExpanduser, OsPathIsabs, OsPathIsdir, OsPathIsfile, OsPathIslink, OsPathJoin, OsPathSamefile, OsPathSplitext, OsReadlink, OsRemove, OsRename, OsReplace, OsRmdir, OsStat, OsUnlink, PyPath, }; use crate::settings::types::PythonVersion; -pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr) { +pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, call: &ExprCall) { if let Some(diagnostic_kind) = checker .semantic() - .resolve_call_path(expr) + .resolve_call_path(&call.func) .and_then(|call_path| match call_path.as_slice() { // PTH100 ["os", "path", "abspath"] => Some(OsPathAbspath.into()), @@ -60,12 +60,22 @@ pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr) { ["os", "path", "join"] => Some( OsPathJoin { module: "path".to_string(), + joiner: if call.arguments.args.iter().any(Expr::is_starred_expr) { + Joiner::Joinpath + } else { + Joiner::Slash + }, } .into(), ), ["os", "sep", "join"] => Some( OsPathJoin { module: "sep".to_string(), + joiner: if call.arguments.args.iter().any(Expr::is_starred_expr) { + Joiner::Joinpath + } else { + Joiner::Slash + }, } .into(), ), @@ -86,7 +96,51 @@ pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr) { // PTH205 ["os", "path", "getctime"] => Some(OsPathGetctime.into()), // PTH123 - ["" | "builtin", "open"] => Some(BuiltinOpen.into()), + ["" | "builtin", "open"] => { + // `closefd` and `openener` are not supported by pathlib, so check if they are + // are set to non-default values. + // https://github.com/astral-sh/ruff/issues/7620 + // Signature as of Python 3.11 (https://docs.python.org/3/library/functions.html#open): + // ```text + // 0 1 2 3 4 5 + // open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, + // 6 7 + // closefd=True, opener=None) + // ^^^^ ^^^^ + // ``` + // For `pathlib` (https://docs.python.org/3/library/pathlib.html#pathlib.Path.open): + // ```text + // Path.open(mode='r', buffering=-1, encoding=None, errors=None, newline=None) + // ``` + if call + .arguments + .find_argument("closefd", 6) + .is_some_and(|expr| { + !matches!( + expr, + Expr::Constant(ExprConstant { + value: Constant::Bool(true), + .. + }) + ) + }) + || call + .arguments + .find_argument("opener", 7) + .is_some_and(|expr| { + !matches!( + expr, + Expr::Constant(ExprConstant { + value: Constant::None, + .. + }) + ) + }) + { + return None; + } + Some(BuiltinOpen.into()) + } // PTH124 ["py", "path", "local"] => Some(PyPath.into()), // PTH207 @@ -110,7 +164,7 @@ pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr) { _ => None, }) { - let diagnostic = Diagnostic::new::(diagnostic_kind, expr.range()); + let diagnostic = Diagnostic::new::(diagnostic_kind, call.func.range()); if checker.enabled(diagnostic.kind.rule()) { checker.diagnostics.push(diagnostic); diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/snapshots/ruff_linter__rules__flake8_use_pathlib__tests__full_name.py.snap b/crates/ruff_linter/src/rules/flake8_use_pathlib/snapshots/ruff_linter__rules__flake8_use_pathlib__tests__full_name.py.snap index 1f087acbf24cf..92dd4a47e4b2e 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/snapshots/ruff_linter__rules__flake8_use_pathlib__tests__full_name.py.snap +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/snapshots/ruff_linter__rules__flake8_use_pathlib__tests__full_name.py.snap @@ -267,6 +267,7 @@ full_name.py:34:1: PTH123 `open()` should be replaced by `Path.open()` 34 | open(p).close() | ^^^^ PTH123 35 | os.getcwdb(p) +36 | os.path.join(p, *q) | full_name.py:35:1: PTH109 `os.getcwd()` should be replaced by `Path.cwd()` @@ -275,6 +276,46 @@ full_name.py:35:1: PTH109 `os.getcwd()` should be replaced by `Path.cwd()` 34 | open(p).close() 35 | os.getcwdb(p) | ^^^^^^^^^^ PTH109 +36 | os.path.join(p, *q) +37 | os.sep.join(p, *q) + | + +full_name.py:36:1: PTH118 `os.path.join()` should be replaced by `Path.joinpath()` + | +34 | open(p).close() +35 | os.getcwdb(p) +36 | os.path.join(p, *q) + | ^^^^^^^^^^^^ PTH118 +37 | os.sep.join(p, *q) + | + +full_name.py:37:1: PTH118 `os.sep.join()` should be replaced by `Path.joinpath()` + | +35 | os.getcwdb(p) +36 | os.path.join(p, *q) +37 | os.sep.join(p, *q) + | ^^^^^^^^^^^ PTH118 +38 | +39 | # https://github.com/astral-sh/ruff/issues/7620 + | + +full_name.py:46:1: PTH123 `open()` should be replaced by `Path.open()` + | +44 | open(p, closefd=False) +45 | open(p, opener=opener) +46 | open(p, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + | ^^^^ PTH123 +47 | open(p, 'r', - 1, None, None, None, True, None) +48 | open(p, 'r', - 1, None, None, None, False, opener) + | + +full_name.py:47:1: PTH123 `open()` should be replaced by `Path.open()` + | +45 | open(p, opener=opener) +46 | open(p, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +47 | open(p, 'r', - 1, None, None, None, True, None) + | ^^^^ PTH123 +48 | open(p, 'r', - 1, None, None, None, False, opener) | diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/violations.rs b/crates/ruff_linter/src/rules/flake8_use_pathlib/violations.rs index b53250c2f757d..7e18f8290ed4f 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/violations.rs +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/violations.rs @@ -799,8 +799,8 @@ impl Violation for OsPathIsabs { /// ## Why is this bad? /// `pathlib` offers a high-level API for path manipulation, as compared to /// the lower-level API offered by `os`. When possible, using `Path` object -/// methods such as `Path.joinpath()` can improve readability over the `os` -/// module's counterparts (e.g., `os.path.join()`). +/// methods such as `Path.joinpath()` or the `/` operator can improve +/// readability over the `os` module's counterparts (e.g., `os.path.join()`). /// /// Note that `os` functions may be preferable if performance is a concern, /// e.g., in hot loops. @@ -828,17 +828,31 @@ impl Violation for OsPathIsabs { /// - [No really, pathlib is great](https://treyhunner.com/2019/01/no-really-pathlib-is-great/) #[violation] pub struct OsPathJoin { - pub module: String, + pub(crate) module: String, + pub(crate) joiner: Joiner, } impl Violation for OsPathJoin { #[derive_message_formats] fn message(&self) -> String { - let OsPathJoin { module } = self; - format!("`os.{module}.join()` should be replaced by `Path` with `/` operator") + let OsPathJoin { module, joiner } = self; + match joiner { + Joiner::Slash => { + format!("`os.{module}.join()` should be replaced by `Path` with `/` operator") + } + Joiner::Joinpath => { + format!("`os.{module}.join()` should be replaced by `Path.joinpath()`") + } + } } } +#[derive(Debug, PartialEq, Eq)] +pub(crate) enum Joiner { + Slash, + Joinpath, +} + /// ## What it does /// Checks for uses of `os.path.basename`. /// diff --git a/crates/ruff_linter/src/rules/flynt/rules/static_join_to_fstring.rs b/crates/ruff_linter/src/rules/flynt/rules/static_join_to_fstring.rs index 969b7cf94bed0..4f4c68c5e7975 100644 --- a/crates/ruff_linter/src/rules/flynt/rules/static_join_to_fstring.rs +++ b/crates/ruff_linter/src/rules/flynt/rules/static_join_to_fstring.rs @@ -1,14 +1,14 @@ use itertools::Itertools; -use crate::autofix::edits::pad; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use crate::fix::edits::pad; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Arguments, Constant, Expr}; use ruff_text_size::{Ranged, TextRange}; -use crate::autofix::snippet::SourceCodeSnippet; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix::snippet::SourceCodeSnippet; + use crate::rules::flynt::helpers; /// ## What it does @@ -34,7 +34,7 @@ pub struct StaticJoinToFString { expression: SourceCodeSnippet, } -impl AlwaysAutofixableViolation for StaticJoinToFString { +impl AlwaysFixableViolation for StaticJoinToFString { #[derive_message_formats] fn message(&self) -> String { let StaticJoinToFString { expression } = self; @@ -45,7 +45,7 @@ impl AlwaysAutofixableViolation for StaticJoinToFString { } } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let StaticJoinToFString { expression } = self; if let Some(expression) = expression.full_display() { format!("Replace with `{expression}`") @@ -154,11 +154,9 @@ pub(crate) fn static_join_to_fstring(checker: &mut Checker, expr: &Expr, joiner: }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - pad(contents, expr.range(), checker.locator()), - expr.range(), - ))); - } + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + pad(contents, expr.range(), checker.locator()), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/isort/mod.rs b/crates/ruff_linter/src/rules/isort/mod.rs index 84b0cf7c425d0..bbe155c6effa8 100644 --- a/crates/ruff_linter/src/rules/isort/mod.rs +++ b/crates/ruff_linter/src/rules/isort/mod.rs @@ -1,6 +1,5 @@ //! Rules from [isort](https://pypi.org/project/isort/). -use std::collections::BTreeSet; use std::path::{Path, PathBuf}; use annotate::annotate_imports; @@ -14,14 +13,12 @@ use order::order_imports; use ruff_python_ast::PySourceType; use ruff_python_codegen::Stylist; use ruff_source_file::Locator; -use settings::RelativeImportsOrder; +use settings::Settings; use sorting::cmp_either_import; use types::EitherImport::{Import, ImportFrom}; -use types::{AliasData, EitherImport, TrailingComma}; +use types::{AliasData, EitherImport, ImportBlock, TrailingComma}; use crate::line_width::{LineLength, LineWidthBuilder}; -use crate::rules::isort::categorize::KnownModules; -use crate::rules::isort::types::ImportBlock; use crate::settings::types::PythonVersion; mod annotate; @@ -74,49 +71,25 @@ pub(crate) fn format_imports( src: &[PathBuf], package: Option<&Path>, source_type: PySourceType, - combine_as_imports: bool, - force_single_line: bool, - force_sort_within_sections: bool, - case_sensitive: bool, - force_wrap_aliases: bool, - force_to_top: &BTreeSet, - known_modules: &KnownModules, - order_by_type: bool, - detect_same_package: bool, - relative_imports_order: RelativeImportsOrder, - single_line_exclusions: &BTreeSet, - split_on_trailing_comma: bool, - classes: &BTreeSet, - constants: &BTreeSet, - variables: &BTreeSet, - no_lines_before: &BTreeSet, - lines_after_imports: isize, - lines_between_types: usize, - forced_separate: &[String], target_version: PythonVersion, - section_order: &[ImportSection], + settings: &Settings, ) -> String { let trailer = &block.trailer; let block = annotate_imports( &block.imports, comments, locator, - split_on_trailing_comma, + settings.split_on_trailing_comma, source_type, ); // Normalize imports (i.e., deduplicate, aggregate `from` imports). - let block = normalize_imports( - block, - combine_as_imports, - force_single_line, - single_line_exclusions, - ); + let block = normalize_imports(block, settings); // Categorize imports. let mut output = String::new(); - for block in split::split_by_forced_separate(block, forced_separate) { + for block in split::split_by_forced_separate(block, &settings.forced_separate) { let block_output = format_import_block( block, line_length, @@ -124,22 +97,8 @@ pub(crate) fn format_imports( stylist, src, package, - force_sort_within_sections, - case_sensitive, - force_wrap_aliases, - force_to_top, - known_modules, - order_by_type, - detect_same_package, - relative_imports_order, - split_on_trailing_comma, - classes, - constants, - variables, - no_lines_before, - lines_between_types, target_version, - section_order, + settings, ); if !block_output.is_empty() && !output.is_empty() { @@ -150,6 +109,7 @@ pub(crate) fn format_imports( output.push_str(block_output.as_str()); } + let lines_after_imports = settings.lines_after_imports; match trailer { None => {} Some(Trailer::Sibling) => { @@ -183,30 +143,16 @@ fn format_import_block( stylist: &Stylist, src: &[PathBuf], package: Option<&Path>, - force_sort_within_sections: bool, - case_sensitive: bool, - force_wrap_aliases: bool, - force_to_top: &BTreeSet, - known_modules: &KnownModules, - order_by_type: bool, - detect_same_package: bool, - relative_imports_order: RelativeImportsOrder, - split_on_trailing_comma: bool, - classes: &BTreeSet, - constants: &BTreeSet, - variables: &BTreeSet, - no_lines_before: &BTreeSet, - lines_between_types: usize, target_version: PythonVersion, - section_order: &[ImportSection], + settings: &Settings, ) -> String { // Categorize by type (e.g., first-party vs. third-party). let mut block_by_type = categorize_imports( block, src, package, - detect_same_package, - known_modules, + settings.detect_same_package, + &settings.known_modules, target_version, ); @@ -215,26 +161,17 @@ fn format_import_block( // Generate replacement source code. let mut is_first_block = true; let mut pending_lines_before = false; - for import_section in section_order { + for import_section in &settings.section_order { let import_block = block_by_type.remove(import_section); - if !no_lines_before.contains(import_section) { + if !settings.no_lines_before.contains(import_section) { pending_lines_before = true; } let Some(import_block) = import_block else { continue; }; - let imports = order_imports( - import_block, - order_by_type, - case_sensitive, - relative_imports_order, - classes, - constants, - variables, - force_to_top, - ); + let imports = order_imports(import_block, settings); let imports = { let mut imports = imports @@ -243,16 +180,8 @@ fn format_import_block( .map(Import) .chain(imports.import_from.into_iter().map(ImportFrom)) .collect::>(); - if force_sort_within_sections { - imports.sort_by(|import1, import2| { - cmp_either_import( - import1, - import2, - relative_imports_order, - force_to_top, - case_sensitive, - ) - }); + if settings.force_sort_within_sections { + imports.sort_by(|import1, import2| cmp_either_import(import1, import2, settings)); }; imports }; @@ -269,6 +198,7 @@ fn format_import_block( let mut lines_inserted = false; let mut has_direct_import = false; let mut is_first_statement = true; + let lines_between_types = settings.lines_between_types; for import in imports { match import { Import((alias, comments)) => { @@ -299,9 +229,10 @@ fn format_import_block( line_length, indentation_width, stylist, - force_wrap_aliases, + settings.force_wrap_aliases, is_first_statement, - split_on_trailing_comma && matches!(trailing_comma, TrailingComma::Present), + settings.split_on_trailing_comma + && matches!(trailing_comma, TrailingComma::Present), )); } } diff --git a/crates/ruff_linter/src/rules/isort/normalize.rs b/crates/ruff_linter/src/rules/isort/normalize.rs index ceee1cb4a35f1..01896580232bb 100644 --- a/crates/ruff_linter/src/rules/isort/normalize.rs +++ b/crates/ruff_linter/src/rules/isort/normalize.rs @@ -1,15 +1,10 @@ -use std::collections::BTreeSet; - -use crate::rules::isort::types::TrailingComma; - -use super::types::{AliasData, ImportBlock, ImportFromData}; +use super::settings::Settings; +use super::types::{AliasData, ImportBlock, ImportFromData, TrailingComma}; use super::AnnotatedImport; pub(crate) fn normalize_imports<'a>( imports: Vec>, - combine_as_imports: bool, - force_single_line: bool, - single_line_exclusions: &'a BTreeSet, + settings: &Settings, ) -> ImportBlock<'a> { let mut block = ImportBlock::default(); for import in imports { @@ -56,8 +51,10 @@ pub(crate) fn normalize_imports<'a>( trailing_comma, } => { // Whether to track each member of the import as a separate entry. - let isolate_aliases = force_single_line - && module.map_or(true, |module| !single_line_exclusions.contains(module)) + let isolate_aliases = settings.force_single_line + && module.map_or(true, |module| { + !settings.single_line_exclusions.contains(module) + }) && !names.first().is_some_and(|alias| alias.name == "*"); // Insert comments on the statement itself. @@ -95,7 +92,7 @@ pub(crate) fn normalize_imports<'a>( .import_from_star .entry(ImportFromData { module, level }) .or_default() - } else if alias.asname.is_none() || combine_as_imports { + } else if alias.asname.is_none() || settings.combine_as_imports { block .import_from .entry(ImportFromData { module, level }) @@ -130,7 +127,9 @@ pub(crate) fn normalize_imports<'a>( .import_from_star .entry(ImportFromData { module, level }) .or_default() - } else if !isolate_aliases && (alias.asname.is_none() || combine_as_imports) { + } else if !isolate_aliases + && (alias.asname.is_none() || settings.combine_as_imports) + { block .import_from .entry(ImportFromData { module, level }) diff --git a/crates/ruff_linter/src/rules/isort/order.rs b/crates/ruff_linter/src/rules/isort/order.rs index a2210ed43adb7..c2110457a0e8c 100644 --- a/crates/ruff_linter/src/rules/isort/order.rs +++ b/crates/ruff_linter/src/rules/isort/order.rs @@ -1,24 +1,14 @@ use std::cmp::Ordering; -use std::collections::BTreeSet; use itertools::Itertools; -use crate::rules::isort::types::ImportFromStatement; - -use super::settings::RelativeImportsOrder; +use super::settings::Settings; use super::sorting::{cmp_import_from, cmp_members, cmp_modules}; -use super::types::{AliasData, CommentSet, ImportBlock, OrderedImportBlock}; +use super::types::{AliasData, CommentSet, ImportBlock, ImportFromStatement, OrderedImportBlock}; -#[allow(clippy::too_many_arguments)] pub(crate) fn order_imports<'a>( block: ImportBlock<'a>, - order_by_type: bool, - case_sensitive: bool, - relative_imports_order: RelativeImportsOrder, - classes: &'a BTreeSet, - constants: &'a BTreeSet, - variables: &'a BTreeSet, - force_to_top: &'a BTreeSet, + settings: &Settings, ) -> OrderedImportBlock<'a> { let mut ordered = OrderedImportBlock::default(); @@ -27,9 +17,7 @@ pub(crate) fn order_imports<'a>( block .import .into_iter() - .sorted_by(|(alias1, _), (alias2, _)| { - cmp_modules(alias1, alias2, force_to_top, case_sensitive) - }), + .sorted_by(|(alias1, _), (alias2, _)| cmp_modules(alias1, alias2, settings)), ); // Sort `Stmt::ImportFrom`. @@ -66,16 +54,7 @@ pub(crate) fn order_imports<'a>( aliases .into_iter() .sorted_by(|(alias1, _), (alias2, _)| { - cmp_members( - alias1, - alias2, - order_by_type, - classes, - constants, - variables, - force_to_top, - case_sensitive, - ) + cmp_members(alias1, alias2, settings) }) .collect::>(), ) @@ -83,27 +62,15 @@ pub(crate) fn order_imports<'a>( ) .sorted_by( |(import_from1, _, _, aliases1), (import_from2, _, _, aliases2)| { - cmp_import_from( - import_from1, - import_from2, - relative_imports_order, - force_to_top, - case_sensitive, - ) - .then_with(|| match (aliases1.first(), aliases2.first()) { - (None, None) => Ordering::Equal, - (None, Some(_)) => Ordering::Less, - (Some(_), None) => Ordering::Greater, - (Some((alias1, _)), Some((alias2, _))) => cmp_members( - alias1, - alias2, - order_by_type, - classes, - constants, - variables, - force_to_top, - case_sensitive, - ), + cmp_import_from(import_from1, import_from2, settings).then_with(|| { + match (aliases1.first(), aliases2.first()) { + (None, None) => Ordering::Equal, + (None, Some(_)) => Ordering::Less, + (Some(_), None) => Ordering::Greater, + (Some((alias1, _)), Some((alias2, _))) => { + cmp_members(alias1, alias2, settings) + } + } }) }, ), diff --git a/crates/ruff_linter/src/rules/isort/rules/add_required_imports.rs b/crates/ruff_linter/src/rules/isort/rules/add_required_imports.rs index cc4e017ff665c..4b30dc869eb28 100644 --- a/crates/ruff_linter/src/rules/isort/rules/add_required_imports.rs +++ b/crates/ruff_linter/src/rules/isort/rules/add_required_imports.rs @@ -1,6 +1,6 @@ use log::error; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::is_docstring_stmt; use ruff_python_ast::imports::{Alias, AnyImport, FutureImport, Import, ImportFrom}; @@ -11,7 +11,7 @@ use ruff_source_file::Locator; use ruff_text_size::{TextRange, TextSize}; use crate::importer::Importer; -use crate::registry::Rule; + use crate::settings::LinterSettings; /// ## What it does @@ -40,14 +40,14 @@ use crate::settings::LinterSettings; #[violation] pub struct MissingRequiredImport(pub String); -impl AlwaysAutofixableViolation for MissingRequiredImport { +impl AlwaysFixableViolation for MissingRequiredImport { #[derive_message_formats] fn message(&self) -> String { let MissingRequiredImport(name) = self; format!("Missing required import: `{name}`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let MissingRequiredImport(name) = self; format!("Insert required import: `{name}`") } @@ -90,7 +90,6 @@ fn add_required_import( python_ast: &Suite, locator: &Locator, stylist: &Stylist, - settings: &LinterSettings, source_type: PySourceType, ) -> Option { // Don't add imports to semantically-empty files. @@ -116,12 +115,10 @@ fn add_required_import( MissingRequiredImport(required_import.to_string()), TextRange::default(), ); - if settings.rules.should_fix(Rule::MissingRequiredImport) { - diagnostic.set_fix(Fix::automatic( - Importer::new(python_ast, locator, stylist) - .add_import(required_import, TextSize::default()), - )); - } + diagnostic.set_fix(Fix::safe_edit( + Importer::new(python_ast, locator, stylist) + .add_import(required_import, TextSize::default()), + )); Some(diagnostic) } @@ -171,7 +168,6 @@ pub(crate) fn add_required_imports( python_ast, locator, stylist, - settings, source_type, ) }) @@ -189,7 +185,6 @@ pub(crate) fn add_required_imports( python_ast, locator, stylist, - settings, source_type, ) }) diff --git a/crates/ruff_linter/src/rules/isort/rules/organize_imports.rs b/crates/ruff_linter/src/rules/isort/rules/organize_imports.rs index 62b2043f8c49a..e571271d08c00 100644 --- a/crates/ruff_linter/src/rules/isort/rules/organize_imports.rs +++ b/crates/ruff_linter/src/rules/isort/rules/organize_imports.rs @@ -2,7 +2,7 @@ use std::path::Path; use itertools::{EitherOrBoth, Itertools}; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::whitespace::trailing_lines_end; use ruff_python_ast::{PySourceType, Stmt}; @@ -13,7 +13,7 @@ use ruff_source_file::{Locator, UniversalNewlines}; use ruff_text_size::{Ranged, TextRange}; use crate::line_width::LineWidthBuilder; -use crate::registry::AsRule; + use crate::settings::LinterSettings; use super::super::block::Block; @@ -41,14 +41,14 @@ use super::super::{comments, format_imports}; pub struct UnsortedImports; impl Violation for UnsortedImports { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Import block is un-sorted or un-formatted") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Organize imports".to_string()) } } @@ -126,27 +126,8 @@ pub(crate) fn organize_imports( &settings.src, package, source_type, - settings.isort.combine_as_imports, - settings.isort.force_single_line, - settings.isort.force_sort_within_sections, - settings.isort.case_sensitive, - settings.isort.force_wrap_aliases, - &settings.isort.force_to_top, - &settings.isort.known_modules, - settings.isort.order_by_type, - settings.isort.detect_same_package, - settings.isort.relative_imports_order, - &settings.isort.single_line_exclusions, - settings.isort.split_on_trailing_comma, - &settings.isort.classes, - &settings.isort.constants, - &settings.isort.variables, - &settings.isort.no_lines_before, - settings.isort.lines_after_imports, - settings.isort.lines_between_types, - &settings.isort.forced_separate, settings.target_version, - &settings.isort.section_order, + &settings.isort, ); // Expand the span the entire range, including leading and trailing space. @@ -157,11 +138,9 @@ pub(crate) fn organize_imports( } let mut diagnostic = Diagnostic::new(UnsortedImports, range); - if settings.rules.should_fix(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - indent(&expected, indentation).to_string(), - range, - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + indent(&expected, indentation).to_string(), + range, + ))); Some(diagnostic) } diff --git a/crates/ruff_linter/src/rules/isort/sorting.rs b/crates/ruff_linter/src/rules/isort/sorting.rs index 444e550406d0d..959d5f7a13628 100644 --- a/crates/ruff_linter/src/rules/isort/sorting.rs +++ b/crates/ruff_linter/src/rules/isort/sorting.rs @@ -4,11 +4,9 @@ use std::collections::BTreeSet; use ruff_python_stdlib::str; -use crate::rules::isort::types::Importable; - -use super::settings::RelativeImportsOrder; +use super::settings::{RelativeImportsOrder, Settings}; use super::types::EitherImport::{Import, ImportFrom}; -use super::types::{AliasData, EitherImport, ImportFromData}; +use super::types::{AliasData, EitherImport, ImportFromData, Importable}; #[derive(PartialOrd, Ord, PartialEq, Eq, Copy, Clone)] pub(crate) enum Prefix { @@ -17,19 +15,14 @@ pub(crate) enum Prefix { Variables, } -fn prefix( - name: &str, - classes: &BTreeSet, - constants: &BTreeSet, - variables: &BTreeSet, -) -> Prefix { - if constants.contains(name) { +fn prefix(name: &str, settings: &Settings) -> Prefix { + if settings.constants.contains(name) { // Ex) `CONSTANT` Prefix::Constants - } else if classes.contains(name) { + } else if settings.classes.contains(name) { // Ex) `CLASS` Prefix::Classes - } else if variables.contains(name) { + } else if settings.variables.contains(name) { // Ex) `variable` Prefix::Variables } else if name.len() > 1 && str::is_cased_uppercase(name) { @@ -52,15 +45,10 @@ fn cmp_force_to_top(name1: &str, name2: &str, force_to_top: &BTreeSet) - } /// Compare two top-level modules. -pub(crate) fn cmp_modules( - alias1: &AliasData, - alias2: &AliasData, - force_to_top: &BTreeSet, - case_sensitive: bool, -) -> Ordering { - cmp_force_to_top(alias1.name, alias2.name, force_to_top) +pub(crate) fn cmp_modules(alias1: &AliasData, alias2: &AliasData, settings: &Settings) -> Ordering { + cmp_force_to_top(alias1.name, alias2.name, &settings.force_to_top) .then_with(|| { - if case_sensitive { + if settings.case_sensitive { natord::compare(alias1.name, alias2.name) } else { natord::compare_ignore_case(alias1.name, alias2.name) @@ -76,27 +64,17 @@ pub(crate) fn cmp_modules( } /// Compare two member imports within `Stmt::ImportFrom` blocks. -#[allow(clippy::too_many_arguments)] -pub(crate) fn cmp_members( - alias1: &AliasData, - alias2: &AliasData, - order_by_type: bool, - classes: &BTreeSet, - constants: &BTreeSet, - variables: &BTreeSet, - force_to_top: &BTreeSet, - case_sensitive: bool, -) -> Ordering { +pub(crate) fn cmp_members(alias1: &AliasData, alias2: &AliasData, settings: &Settings) -> Ordering { match (alias1.name == "*", alias2.name == "*") { (true, false) => Ordering::Less, (false, true) => Ordering::Greater, _ => { - if order_by_type { - prefix(alias1.name, classes, constants, variables) - .cmp(&prefix(alias2.name, classes, constants, variables)) - .then_with(|| cmp_modules(alias1, alias2, force_to_top, case_sensitive)) + if settings.order_by_type { + prefix(alias1.name, settings) + .cmp(&prefix(alias2.name, settings)) + .then_with(|| cmp_modules(alias1, alias2, settings)) } else { - cmp_modules(alias1, alias2, force_to_top, case_sensitive) + cmp_modules(alias1, alias2, settings) } } } @@ -123,20 +101,18 @@ pub(crate) fn cmp_levels( pub(crate) fn cmp_import_from( import_from1: &ImportFromData, import_from2: &ImportFromData, - relative_imports_order: RelativeImportsOrder, - force_to_top: &BTreeSet, - case_sensitive: bool, + settings: &Settings, ) -> Ordering { cmp_levels( import_from1.level, import_from2.level, - relative_imports_order, + settings.relative_imports_order, ) .then_with(|| { cmp_force_to_top( &import_from1.module_name(), &import_from2.module_name(), - force_to_top, + &settings.force_to_top, ) }) .then_with(|| match (&import_from1.module, import_from2.module) { @@ -144,7 +120,7 @@ pub(crate) fn cmp_import_from( (None, Some(_)) => Ordering::Less, (Some(_), None) => Ordering::Greater, (Some(module1), Some(module2)) => { - if case_sensitive { + if settings.case_sensitive { natord::compare(module1, module2) } else { natord::compare_ignore_case(module1, module2) @@ -157,11 +133,15 @@ pub(crate) fn cmp_import_from( fn cmp_import_import_from( import: &AliasData, import_from: &ImportFromData, - force_to_top: &BTreeSet, - case_sensitive: bool, + settings: &Settings, ) -> Ordering { - cmp_force_to_top(import.name, &import_from.module_name(), force_to_top).then_with(|| { - if case_sensitive { + cmp_force_to_top( + import.name, + &import_from.module_name(), + &settings.force_to_top, + ) + .then_with(|| { + if settings.case_sensitive { natord::compare(import.name, import_from.module.unwrap_or_default()) } else { natord::compare_ignore_case(import.name, import_from.module.unwrap_or_default()) @@ -174,26 +154,18 @@ fn cmp_import_import_from( pub(crate) fn cmp_either_import( a: &EitherImport, b: &EitherImport, - relative_imports_order: RelativeImportsOrder, - force_to_top: &BTreeSet, - case_sensitive: bool, + settings: &Settings, ) -> Ordering { match (a, b) { - (Import((alias1, _)), Import((alias2, _))) => { - cmp_modules(alias1, alias2, force_to_top, case_sensitive) - } + (Import((alias1, _)), Import((alias2, _))) => cmp_modules(alias1, alias2, settings), (ImportFrom((import_from, ..)), Import((alias, _))) => { - cmp_import_import_from(alias, import_from, force_to_top, case_sensitive).reverse() + cmp_import_import_from(alias, import_from, settings).reverse() } (Import((alias, _)), ImportFrom((import_from, ..))) => { - cmp_import_import_from(alias, import_from, force_to_top, case_sensitive) + cmp_import_import_from(alias, import_from, settings) + } + (ImportFrom((import_from1, ..)), ImportFrom((import_from2, ..))) => { + cmp_import_from(import_from1, import_from2, settings) } - (ImportFrom((import_from1, ..)), ImportFrom((import_from2, ..))) => cmp_import_from( - import_from1, - import_from2, - relative_imports_order, - force_to_top, - case_sensitive, - ), } } diff --git a/crates/ruff_linter/src/rules/numpy/rules/deprecated_function.rs b/crates/ruff_linter/src/rules/numpy/rules/deprecated_function.rs index b88581fe914d8..7a106716541f9 100644 --- a/crates/ruff_linter/src/rules/numpy/rules/deprecated_function.rs +++ b/crates/ruff_linter/src/rules/numpy/rules/deprecated_function.rs @@ -1,11 +1,10 @@ -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::Expr; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::importer::ImportRequest; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of deprecated NumPy functions. @@ -37,7 +36,7 @@ pub struct NumpyDeprecatedFunction { } impl Violation for NumpyDeprecatedFunction { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -48,7 +47,7 @@ impl Violation for NumpyDeprecatedFunction { format!("`np.{existing}` is deprecated; use `np.{replacement}` instead") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let NumpyDeprecatedFunction { replacement, .. } = self; Some(format!("Replace with `np.{replacement}`")) } @@ -76,17 +75,15 @@ pub(crate) fn deprecated_function(checker: &mut Checker, expr: &Expr) { }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - let (import_edit, binding) = checker.importer().get_or_import_symbol( - &ImportRequest::import_from("numpy", replacement), - expr.start(), - checker.semantic(), - )?; - let replacement_edit = Edit::range_replacement(binding, expr.range()); - Ok(Fix::suggested_edits(import_edit, [replacement_edit])) - }); - } + diagnostic.try_set_fix(|| { + let (import_edit, binding) = checker.importer().get_or_import_symbol( + &ImportRequest::import_from("numpy", replacement), + expr.start(), + checker.semantic(), + )?; + let replacement_edit = Edit::range_replacement(binding, expr.range()); + Ok(Fix::safe_edits(import_edit, [replacement_edit])) + }); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/numpy/rules/deprecated_type_alias.rs b/crates/ruff_linter/src/rules/numpy/rules/deprecated_type_alias.rs index fe24ec08dd382..265a04d2ffb2f 100644 --- a/crates/ruff_linter/src/rules/numpy/rules/deprecated_type_alias.rs +++ b/crates/ruff_linter/src/rules/numpy/rules/deprecated_type_alias.rs @@ -1,10 +1,9 @@ -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::Expr; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for deprecated NumPy type aliases. @@ -34,7 +33,7 @@ pub struct NumpyDeprecatedTypeAlias { } impl Violation for NumpyDeprecatedTypeAlias { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -42,7 +41,7 @@ impl Violation for NumpyDeprecatedTypeAlias { format!("Type alias `np.{type_name}` is deprecated, replace with builtin type") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let NumpyDeprecatedTypeAlias { type_name } = self; Some(format!("Replace `np.{type_name}` with builtin type")) } @@ -73,18 +72,16 @@ pub(crate) fn deprecated_type_alias(checker: &mut Checker, expr: &Expr) { }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let type_name = match type_name { - "unicode" => "str", - "long" => "int", - _ => type_name, - }; - if checker.semantic().is_builtin(type_name) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - type_name.to_string(), - expr.range(), - ))); - } + let type_name = match type_name { + "unicode" => "str", + "long" => "int", + _ => type_name, + }; + if checker.semantic().is_builtin(type_name) { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + type_name.to_string(), + expr.range(), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/numpy/snapshots/ruff_linter__rules__numpy__tests__numpy-deprecated-function_NPY003.py.snap b/crates/ruff_linter/src/rules/numpy/snapshots/ruff_linter__rules__numpy__tests__numpy-deprecated-function_NPY003.py.snap index 1d8aa9dc02fdc..6cae9594dd651 100644 --- a/crates/ruff_linter/src/rules/numpy/snapshots/ruff_linter__rules__numpy__tests__numpy-deprecated-function_NPY003.py.snap +++ b/crates/ruff_linter/src/rules/numpy/snapshots/ruff_linter__rules__numpy__tests__numpy-deprecated-function_NPY003.py.snap @@ -12,7 +12,7 @@ NPY003.py:4:5: NPY003 [*] `np.round_` is deprecated; use `np.round` instead | = help: Replace with `np.round` -ℹ Suggested fix +ℹ Fix 1 1 | def func(): 2 2 | import numpy as np 3 3 | @@ -32,7 +32,7 @@ NPY003.py:5:5: NPY003 [*] `np.product` is deprecated; use `np.prod` instead | = help: Replace with `np.prod` -ℹ Suggested fix +ℹ Fix 2 2 | import numpy as np 3 3 | 4 4 | np.round_(np.random.rand(5, 5), 2) @@ -53,7 +53,7 @@ NPY003.py:6:5: NPY003 [*] `np.cumproduct` is deprecated; use `np.cumprod` instea | = help: Replace with `np.cumprod` -ℹ Suggested fix +ℹ Fix 3 3 | 4 4 | np.round_(np.random.rand(5, 5), 2) 5 5 | np.product(np.random.rand(5, 5)) @@ -73,7 +73,7 @@ NPY003.py:7:5: NPY003 [*] `np.sometrue` is deprecated; use `np.any` instead | = help: Replace with `np.any` -ℹ Suggested fix +ℹ Fix 4 4 | np.round_(np.random.rand(5, 5), 2) 5 5 | np.product(np.random.rand(5, 5)) 6 6 | np.cumproduct(np.random.rand(5, 5)) @@ -92,7 +92,7 @@ NPY003.py:8:5: NPY003 [*] `np.alltrue` is deprecated; use `np.all` instead | = help: Replace with `np.all` -ℹ Suggested fix +ℹ Fix 5 5 | np.product(np.random.rand(5, 5)) 6 6 | np.cumproduct(np.random.rand(5, 5)) 7 7 | np.sometrue(np.random.rand(5, 5)) @@ -113,7 +113,7 @@ NPY003.py:14:5: NPY003 [*] `np.round_` is deprecated; use `np.round` instead | = help: Replace with `np.round` -ℹ Suggested fix +ℹ Fix 1 |+from numpy import round 1 2 | def func(): 2 3 | import numpy as np @@ -138,7 +138,7 @@ NPY003.py:15:5: NPY003 [*] `np.product` is deprecated; use `np.prod` instead | = help: Replace with `np.prod` -ℹ Suggested fix +ℹ Fix 1 |+from numpy import prod 1 2 | def func(): 2 3 | import numpy as np @@ -164,7 +164,7 @@ NPY003.py:16:5: NPY003 [*] `np.cumproduct` is deprecated; use `np.cumprod` inste | = help: Replace with `np.cumprod` -ℹ Suggested fix +ℹ Fix 1 |+from numpy import cumprod 1 2 | def func(): 2 3 | import numpy as np @@ -188,7 +188,7 @@ NPY003.py:17:5: NPY003 [*] `np.sometrue` is deprecated; use `np.any` instead | = help: Replace with `np.any` -ℹ Suggested fix +ℹ Fix 1 |+from numpy import any 1 2 | def func(): 2 3 | import numpy as np @@ -210,7 +210,7 @@ NPY003.py:18:5: NPY003 [*] `np.alltrue` is deprecated; use `np.all` instead | = help: Replace with `np.all` -ℹ Suggested fix +ℹ Fix 1 |+from numpy import all 1 2 | def func(): 2 3 | import numpy as np diff --git a/crates/ruff_linter/src/rules/numpy/snapshots/ruff_linter__rules__numpy__tests__numpy-deprecated-type-alias_NPY001.py.snap b/crates/ruff_linter/src/rules/numpy/snapshots/ruff_linter__rules__numpy__tests__numpy-deprecated-type-alias_NPY001.py.snap index f83b5e3a322c5..6a149763650ce 100644 --- a/crates/ruff_linter/src/rules/numpy/snapshots/ruff_linter__rules__numpy__tests__numpy-deprecated-type-alias_NPY001.py.snap +++ b/crates/ruff_linter/src/rules/numpy/snapshots/ruff_linter__rules__numpy__tests__numpy-deprecated-type-alias_NPY001.py.snap @@ -10,7 +10,7 @@ NPY001.py:6:1: NPY001 [*] Type alias `np.bool` is deprecated, replace with built | = help: Replace `np.bool` with builtin type -ℹ Suggested fix +ℹ Fix 3 3 | import numpy 4 4 | 5 5 | # Error @@ -31,7 +31,7 @@ NPY001.py:7:1: NPY001 [*] Type alias `np.int` is deprecated, replace with builti | = help: Replace `np.int` with builtin type -ℹ Suggested fix +ℹ Fix 4 4 | 5 5 | # Error 6 6 | npy.bool @@ -51,7 +51,7 @@ NPY001.py:9:13: NPY001 [*] Type alias `np.object` is deprecated, replace with bu | = help: Replace `np.object` with builtin type -ℹ Suggested fix +ℹ Fix 6 6 | npy.bool 7 7 | npy.int 8 8 | @@ -72,7 +72,7 @@ NPY001.py:12:72: NPY001 [*] Type alias `np.int` is deprecated, replace with buil | = help: Replace `np.int` with builtin type -ℹ Suggested fix +ℹ Fix 9 9 | if dtype == np.object: 10 10 | ... 11 11 | @@ -93,7 +93,7 @@ NPY001.py:12:80: NPY001 [*] Type alias `np.long` is deprecated, replace with bui | = help: Replace `np.long` with builtin type -ℹ Suggested fix +ℹ Fix 9 9 | if dtype == np.object: 10 10 | ... 11 11 | @@ -113,7 +113,7 @@ NPY001.py:17:11: NPY001 [*] Type alias `np.object` is deprecated, replace with b | = help: Replace `np.object` with builtin type -ℹ Suggested fix +ℹ Fix 14 14 | pdf = pd.DataFrame( 15 15 | data=[[1, 2, 3]], 16 16 | columns=["a", "b", "c"], @@ -134,7 +134,7 @@ NPY001.py:20:16: NPY001 [*] Type alias `np.int` is deprecated, replace with buil | = help: Replace `np.int` with builtin type -ℹ Suggested fix +ℹ Fix 17 17 | dtype=numpy.object, 18 18 | ) 19 19 | diff --git a/crates/ruff_linter/src/rules/pandas_vet/rules/attr.rs b/crates/ruff_linter/src/rules/pandas_vet/rules/attr.rs index 9d54b58cd7e62..e59b8228a5a28 100644 --- a/crates/ruff_linter/src/rules/pandas_vet/rules/attr.rs +++ b/crates/ruff_linter/src/rules/pandas_vet/rules/attr.rs @@ -1,8 +1,7 @@ -use ruff_python_ast::{self as ast, Expr, ExprContext}; - use ruff_diagnostics::Violation; use ruff_diagnostics::{Diagnostic, DiagnosticKind}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, Expr, ExprContext}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -60,10 +59,12 @@ pub(crate) fn attr(checker: &mut Checker, attribute: &ast::ExprAttribute) { }; // Avoid flagging on function calls (e.g., `df.values()`). - if let Some(parent) = checker.semantic().current_expression_parent() { - if matches!(parent, Expr::Call(_)) { - return; - } + if checker + .semantic() + .current_expression_parent() + .is_some_and(Expr::is_call_expr) + { + return; } // Avoid flagging on non-DataFrames (e.g., `{"a": 1}.values`), and on irrelevant bindings diff --git a/crates/ruff_linter/src/rules/pandas_vet/rules/inplace_argument.rs b/crates/ruff_linter/src/rules/pandas_vet/rules/inplace_argument.rs index 417b76959194f..f4924b0a6653d 100644 --- a/crates/ruff_linter/src/rules/pandas_vet/rules/inplace_argument.rs +++ b/crates/ruff_linter/src/rules/pandas_vet/rules/inplace_argument.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::is_const_true; use ruff_python_ast::parenthesize::parenthesized_range; @@ -7,9 +7,8 @@ use ruff_python_trivia::CommentRanges; use ruff_source_file::Locator; use ruff_text_size::Ranged; -use crate::autofix::edits::{remove_argument, Parentheses}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix::edits::{remove_argument, Parentheses}; /// ## What it does /// Checks for `inplace=True` usages in `pandas` function and method @@ -39,14 +38,14 @@ use crate::registry::AsRule; pub struct PandasUseOfInplaceArgument; impl Violation for PandasUseOfInplaceArgument { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("`inplace=True` should be avoided; it has inconsistent behavior") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Assign to variable; remove `inplace` arg".to_string()) } } @@ -71,26 +70,24 @@ pub(crate) fn inplace_argument(checker: &mut Checker, call: &ast::ExprCall) { if arg == "inplace" { if is_const_true(&keyword.value) { let mut diagnostic = Diagnostic::new(PandasUseOfInplaceArgument, keyword.range()); - if checker.patch(diagnostic.kind.rule()) { - // Avoid applying the fix if: - // 1. The keyword argument is followed by a star argument (we can't be certain that - // the star argument _doesn't_ contain an override). - // 2. The call is part of a larger expression (we're converting an expression to a - // statement, and expressions can't contain statements). - let statement = checker.semantic().current_statement(); - if !seen_star - && checker.semantic().current_expression_parent().is_none() - && statement.is_expr_stmt() - { - if let Some(fix) = convert_inplace_argument_to_assignment( - call, - keyword, - statement, - checker.indexer().comment_ranges(), - checker.locator(), - ) { - diagnostic.set_fix(fix); - } + // Avoid applying the fix if: + // 1. The keyword argument is followed by a star argument (we can't be certain that + // the star argument _doesn't_ contain an override). + // 2. The call is part of a larger expression (we're converting an expression to a + // statement, and expressions can't contain statements). + let statement = checker.semantic().current_statement(); + if !seen_star + && checker.semantic().current_expression_parent().is_none() + && statement.is_expr_stmt() + { + if let Some(fix) = convert_inplace_argument_to_assignment( + call, + keyword, + statement, + checker.indexer().comment_ranges(), + checker.locator(), + ) { + diagnostic.set_fix(fix); } } @@ -135,5 +132,5 @@ fn convert_inplace_argument_to_assignment( ) .ok()?; - Some(Fix::suggested_edits(insert_assignment, [remove_argument])) + Some(Fix::unsafe_edits(insert_assignment, [remove_argument])) } diff --git a/crates/ruff_linter/src/rules/pandas_vet/rules/nunique_constant_series_check.rs b/crates/ruff_linter/src/rules/pandas_vet/rules/nunique_constant_series_check.rs index 6147f18a878f7..6be1585fd0bfb 100644 --- a/crates/ruff_linter/src/rules/pandas_vet/rules/nunique_constant_series_check.rs +++ b/crates/ruff_linter/src/rules/pandas_vet/rules/nunique_constant_series_check.rs @@ -1,9 +1,7 @@ -use num_traits::One; -use ruff_python_ast::{self as ast, CmpOp, Constant, Expr}; - use ruff_diagnostics::Diagnostic; use ruff_diagnostics::Violation; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, CmpOp, Constant, Expr, Int}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -80,7 +78,13 @@ pub(crate) fn nunique_constant_series_check( } // Right should be the integer 1. - if !is_constant_one(right) { + if !matches!( + right, + Expr::Constant(ast::ExprConstant { + value: Constant::Int(Int::ONE), + range: _, + }) + ) { return; } @@ -110,14 +114,3 @@ pub(crate) fn nunique_constant_series_check( expr.range(), )); } - -/// Return `true` if an [`Expr`] is a constant `1`. -fn is_constant_one(expr: &Expr) -> bool { - match expr { - Expr::Constant(constant) => match &constant.value { - Constant::Int(int) => int.is_one(), - _ => false, - }, - _ => false, - } -} diff --git a/crates/ruff_linter/src/rules/pep8_naming/rules/invalid_first_argument_name_for_class_method.rs b/crates/ruff_linter/src/rules/pep8_naming/rules/invalid_first_argument_name_for_class_method.rs index ff0846786d5ee..cc7092c7f757e 100644 --- a/crates/ruff_linter/src/rules/pep8_naming/rules/invalid_first_argument_name_for_class_method.rs +++ b/crates/ruff_linter/src/rules/pep8_naming/rules/invalid_first_argument_name_for_class_method.rs @@ -22,6 +22,11 @@ use crate::checkers::ast::Checker; /// > append a single trailing underscore rather than use an abbreviation or spelling corruption. /// > Thus `class_` is better than `clss`. (Perhaps better is to avoid such clashes by using a synonym.) /// +/// Names can be excluded from this rule using the [`pep8-naming.ignore-names`] +/// or [`pep8-naming.extend-ignore-names`] configuration options. For example, +/// to allow the use of `klass` as the first argument to class methods, set +/// the [`pep8-naming.extend-ignore-names`] option to `["klass"]`. +/// /// ## Example /// ```python /// class Example: @@ -42,6 +47,7 @@ use crate::checkers::ast::Checker; /// - `pep8-naming.classmethod-decorators` /// - `pep8-naming.staticmethod-decorators` /// - `pep8-naming.ignore-names` +/// - `pep8-naming.extend-ignore-names` /// /// [PEP 8]: https://peps.python.org/pep-0008/#function-and-method-arguments #[violation] diff --git a/crates/ruff_linter/src/rules/pep8_naming/rules/invalid_first_argument_name_for_method.rs b/crates/ruff_linter/src/rules/pep8_naming/rules/invalid_first_argument_name_for_method.rs index 4e18781e624e6..e2e83dcbf7381 100644 --- a/crates/ruff_linter/src/rules/pep8_naming/rules/invalid_first_argument_name_for_method.rs +++ b/crates/ruff_linter/src/rules/pep8_naming/rules/invalid_first_argument_name_for_method.rs @@ -22,6 +22,11 @@ use crate::checkers::ast::Checker; /// > append a single trailing underscore rather than use an abbreviation or spelling corruption. /// > Thus `class_` is better than `clss`. (Perhaps better is to avoid such clashes by using a synonym.) /// +/// Names can be excluded from this rule using the [`pep8-naming.ignore-names`] +/// or [`pep8-naming.extend-ignore-names`] configuration options. For example, +/// to allow the use of `this` as the first argument to instance methods, set +/// the [`pep8-naming.extend-ignore-names`] option to `["this"]`. +/// /// ## Example /// ```python /// class Example: @@ -40,6 +45,7 @@ use crate::checkers::ast::Checker; /// - `pep8-naming.classmethod-decorators` /// - `pep8-naming.staticmethod-decorators` /// - `pep8-naming.ignore-names` +/// - `pep8-naming.extend-ignore-names` /// /// [PEP 8]: https://peps.python.org/pep-0008/#function-and-method-arguments #[violation] diff --git a/crates/ruff_linter/src/rules/pep8_naming/rules/invalid_function_name.rs b/crates/ruff_linter/src/rules/pep8_naming/rules/invalid_function_name.rs index 468b29dc7a2c4..f38222a79061b 100644 --- a/crates/ruff_linter/src/rules/pep8_naming/rules/invalid_function_name.rs +++ b/crates/ruff_linter/src/rules/pep8_naming/rules/invalid_function_name.rs @@ -20,6 +20,11 @@ use crate::settings::types::IdentifierPattern; /// > improve readability. mixedCase is allowed only in contexts where that’s already the /// > prevailing style (e.g. threading.py), to retain backwards compatibility. /// +/// Names can be excluded from this rule using the [`pep8-naming.ignore-names`] +/// or [`pep8-naming.extend-ignore-names`] configuration options. For example, +/// to ignore all functions starting with `test_` from this rule, set the +/// [`pep8-naming.extend-ignore-names`] option to `["test_*"]`. +/// /// ## Example /// ```python /// def myFunction(): @@ -34,6 +39,7 @@ use crate::settings::types::IdentifierPattern; /// /// ## Options /// - `pep8-naming.ignore-names` +/// - `pep8-naming.extend-ignore-names` /// /// [PEP 8]: https://peps.python.org/pep-0008/#function-and-variable-names #[violation] diff --git a/crates/ruff_linter/src/rules/pep8_naming/rules/non_lowercase_variable_in_function.rs b/crates/ruff_linter/src/rules/pep8_naming/rules/non_lowercase_variable_in_function.rs index e8bae1c0eee3c..59df8bf60eeae 100644 --- a/crates/ruff_linter/src/rules/pep8_naming/rules/non_lowercase_variable_in_function.rs +++ b/crates/ruff_linter/src/rules/pep8_naming/rules/non_lowercase_variable_in_function.rs @@ -35,6 +35,7 @@ use crate::rules::pep8_naming::helpers; /// /// ## Options /// - `pep8-naming.ignore-names` +/// - `pep8-naming.extend-ignore-names` /// /// [PEP 8]: https://peps.python.org/pep-0008/#function-and-variable-names #[violation] diff --git a/crates/ruff_linter/src/rules/perflint/rules/incorrect_dict_iterator.rs b/crates/ruff_linter/src/rules/perflint/rules/incorrect_dict_iterator.rs index ab693beae8b26..829e63e0ddea4 100644 --- a/crates/ruff_linter/src/rules/perflint/rules/incorrect_dict_iterator.rs +++ b/crates/ruff_linter/src/rules/perflint/rules/incorrect_dict_iterator.rs @@ -1,14 +1,13 @@ use std::fmt; -use crate::autofix::edits::pad; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use crate::fix::edits::pad; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast as ast; use ruff_python_ast::{Arguments, Expr}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of `dict.items()` that discard either the key or the value @@ -43,14 +42,14 @@ pub struct IncorrectDictIterator { subset: DictSubset, } -impl AlwaysAutofixableViolation for IncorrectDictIterator { +impl AlwaysFixableViolation for IncorrectDictIterator { #[derive_message_formats] fn message(&self) -> String { let IncorrectDictIterator { subset } = self; format!("When using only the {subset} of a dict use the `{subset}()` method") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let IncorrectDictIterator { subset } = self; format!("Replace `.items()` with `.{subset}()`") } @@ -100,18 +99,16 @@ pub(crate) fn incorrect_dict_iterator(checker: &mut Checker, stmt_for: &ast::Stm }, func.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let replace_attribute = Edit::range_replacement("values".to_string(), attr.range()); - let replace_target = Edit::range_replacement( - pad( - checker.locator().slice(value).to_string(), - stmt_for.target.range(), - checker.locator(), - ), + let replace_attribute = Edit::range_replacement("values".to_string(), attr.range()); + let replace_target = Edit::range_replacement( + pad( + checker.locator().slice(value).to_string(), stmt_for.target.range(), - ); - diagnostic.set_fix(Fix::suggested_edits(replace_attribute, [replace_target])); - } + checker.locator(), + ), + stmt_for.target.range(), + ); + diagnostic.set_fix(Fix::unsafe_edits(replace_attribute, [replace_target])); checker.diagnostics.push(diagnostic); } (false, true) => { @@ -122,18 +119,16 @@ pub(crate) fn incorrect_dict_iterator(checker: &mut Checker, stmt_for: &ast::Stm }, func.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let replace_attribute = Edit::range_replacement("keys".to_string(), attr.range()); - let replace_target = Edit::range_replacement( - pad( - checker.locator().slice(key).to_string(), - stmt_for.target.range(), - checker.locator(), - ), + let replace_attribute = Edit::range_replacement("keys".to_string(), attr.range()); + let replace_target = Edit::range_replacement( + pad( + checker.locator().slice(key).to_string(), stmt_for.target.range(), - ); - diagnostic.set_fix(Fix::suggested_edits(replace_attribute, [replace_target])); - } + checker.locator(), + ), + stmt_for.target.range(), + ); + diagnostic.set_fix(Fix::unsafe_edits(replace_attribute, [replace_target])); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/perflint/rules/unnecessary_list_cast.rs b/crates/ruff_linter/src/rules/perflint/rules/unnecessary_list_cast.rs index a9d062554a90f..9769eed8d71e3 100644 --- a/crates/ruff_linter/src/rules/perflint/rules/unnecessary_list_cast.rs +++ b/crates/ruff_linter/src/rules/perflint/rules/unnecessary_list_cast.rs @@ -1,11 +1,10 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::Stmt; use ruff_python_ast::{self as ast, Arguments, Expr}; use ruff_text_size::TextRange; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for explicit casts to `list` on for-loop iterables. @@ -38,13 +37,13 @@ use crate::registry::AsRule; #[violation] pub struct UnnecessaryListCast; -impl AlwaysAutofixableViolation for UnnecessaryListCast { +impl AlwaysFixableViolation for UnnecessaryListCast { #[derive_message_formats] fn message(&self) -> String { format!("Do not cast an iterable to `list` before iterating over it") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { format!("Remove `list()` cast") } } @@ -91,9 +90,7 @@ pub(crate) fn unnecessary_list_cast(checker: &mut Checker, iter: &Expr) { .. }) => { let mut diagnostic = Diagnostic::new(UnnecessaryListCast, *list_range); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(remove_cast(*list_range, *iterable_range)); - } + diagnostic.set_fix(remove_cast(*list_range, *iterable_range)); checker.diagnostics.push(diagnostic); } Expr::Name(ast::ExprName { @@ -119,9 +116,7 @@ pub(crate) fn unnecessary_list_cast(checker: &mut Checker, iter: &Expr) { ) { let mut diagnostic = Diagnostic::new(UnnecessaryListCast, *list_range); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(remove_cast(*list_range, *iterable_range)); - } + diagnostic.set_fix(remove_cast(*list_range, *iterable_range)); checker.diagnostics.push(diagnostic); } } @@ -135,7 +130,7 @@ pub(crate) fn unnecessary_list_cast(checker: &mut Checker, iter: &Expr) { /// Generate a [`Fix`] to remove a `list` cast from an expression. fn remove_cast(list_range: TextRange, iterable_range: TextRange) -> Fix { - Fix::automatic_edits( + Fix::safe_edits( Edit::deletion(list_range.start(), iterable_range.start()), [Edit::deletion(iterable_range.end(), list_range.end())], ) diff --git a/crates/ruff_linter/src/rules/pycodestyle/helpers.rs b/crates/ruff_linter/src/rules/pycodestyle/helpers.rs index 9b01107260fa1..0c7b133787f99 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/helpers.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/helpers.rs @@ -1,143 +1,3 @@ -use unicode_width::UnicodeWidthStr; - -use ruff_python_ast::node::AnyNodeRef; -use ruff_python_ast::parenthesize::parenthesized_range; -use ruff_python_ast::{CmpOp, Expr}; -use ruff_python_trivia::CommentRanges; -use ruff_source_file::{Line, Locator}; -use ruff_text_size::{Ranged, TextLen, TextRange}; - -use crate::line_width::{LineLength, LineWidthBuilder, TabSize}; - pub(super) fn is_ambiguous_name(name: &str) -> bool { name == "l" || name == "I" || name == "O" } - -pub(super) fn generate_comparison( - left: &Expr, - ops: &[CmpOp], - comparators: &[Expr], - parent: AnyNodeRef, - comment_ranges: &CommentRanges, - locator: &Locator, -) -> String { - let start = left.start(); - let end = comparators.last().map_or_else(|| left.end(), Ranged::end); - let mut contents = String::with_capacity(usize::from(end - start)); - - // Add the left side of the comparison. - contents.push_str( - locator.slice( - parenthesized_range(left.into(), parent, comment_ranges, locator.contents()) - .unwrap_or(left.range()), - ), - ); - - for (op, comparator) in ops.iter().zip(comparators) { - // Add the operator. - contents.push_str(match op { - CmpOp::Eq => " == ", - CmpOp::NotEq => " != ", - CmpOp::Lt => " < ", - CmpOp::LtE => " <= ", - CmpOp::Gt => " > ", - CmpOp::GtE => " >= ", - CmpOp::In => " in ", - CmpOp::NotIn => " not in ", - CmpOp::Is => " is ", - CmpOp::IsNot => " is not ", - }); - - // Add the right side of the comparison. - contents.push_str( - locator.slice( - parenthesized_range( - comparator.into(), - parent, - comment_ranges, - locator.contents(), - ) - .unwrap_or(comparator.range()), - ), - ); - } - - contents -} - -pub(super) fn is_overlong( - line: &Line, - limit: LineLength, - ignore_overlong_task_comments: bool, - task_tags: &[String], - tab_size: TabSize, -) -> Option { - // The maximum width of the line is the number of bytes multiplied by the tab size (the - // worst-case scenario is that the line is all tabs). If the maximum width is less than the - // limit, then the line is not overlong. - let max_width = line.len() * tab_size.as_usize(); - if max_width < limit.value() as usize { - return None; - } - - let mut width = LineWidthBuilder::new(tab_size); - width = width.add_str(line.as_str()); - if width <= limit { - return None; - } - - let mut chunks = line.split_whitespace(); - let (Some(first_chunk), Some(second_chunk)) = (chunks.next(), chunks.next()) else { - // Single word / no printable chars - no way to make the line shorter - return None; - }; - - if first_chunk == "#" { - if ignore_overlong_task_comments { - let second = second_chunk.trim_end_matches(':'); - if task_tags.iter().any(|task_tag| task_tag == second) { - return None; - } - } - } - - // Do not enforce the line length for lines that end with a URL, as long as the URL - // begins before the limit. - let last_chunk = chunks.last().unwrap_or(second_chunk); - if last_chunk.contains("://") { - if width.get() - last_chunk.width() <= limit.value() as usize { - return None; - } - } - - // Obtain the start offset of the part of the line that exceeds the limit - let mut start_offset = line.start(); - let mut start_width = LineWidthBuilder::new(tab_size); - for c in line.chars() { - if start_width < limit { - start_offset += c.text_len(); - start_width = start_width.add_char(c); - } else { - break; - } - } - Some(Overlong { - range: TextRange::new(start_offset, line.end()), - width: width.get(), - }) -} - -pub(super) struct Overlong { - range: TextRange, - width: usize, -} - -impl Overlong { - pub(super) const fn range(&self) -> TextRange { - self.range - } - - pub(super) const fn width(&self) -> usize { - self.width - } -} diff --git a/crates/ruff_linter/src/rules/pycodestyle/mod.rs b/crates/ruff_linter/src/rules/pycodestyle/mod.rs index 7ee1bdc3e32e3..14a69f5872c1a 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/mod.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/mod.rs @@ -3,6 +3,7 @@ pub(crate) mod rules; pub mod settings; pub(crate) mod helpers; +pub(super) mod overlong; #[cfg(test)] mod tests { @@ -15,6 +16,8 @@ mod tests { use crate::line_width::LineLength; use crate::registry::Rule; + use crate::rules::pycodestyle; + use crate::settings::types::PreviewMode; use crate::test::test_path; use crate::{assert_messages, settings}; @@ -28,7 +31,9 @@ mod tests { #[test_case(Rule::BlankLineWithWhitespace, Path::new("W29.py"))] #[test_case(Rule::InvalidEscapeSequence, Path::new("W605_0.py"))] #[test_case(Rule::InvalidEscapeSequence, Path::new("W605_1.py"))] + #[test_case(Rule::InvalidEscapeSequence, Path::new("W605_2.py"))] #[test_case(Rule::LineTooLong, Path::new("E501.py"))] + #[test_case(Rule::LineTooLong, Path::new("E501_3.py"))] #[test_case(Rule::MixedSpacesAndTabs, Path::new("E101.py"))] #[test_case(Rule::ModuleImportNotAtTopOfFile, Path::new("E40.py"))] #[test_case(Rule::ModuleImportNotAtTopOfFile, Path::new("E402.py"))] @@ -58,6 +63,24 @@ mod tests { Ok(()) } + #[test_case(Rule::TypeComparison, Path::new("E721.py"))] + fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> { + let snapshot = format!( + "preview__{}_{}", + rule_code.noqa_code(), + path.to_string_lossy() + ); + let diagnostics = test_path( + Path::new("pycodestyle").join(path).as_path(), + &settings::LinterSettings { + preview: PreviewMode::Enabled, + ..settings::LinterSettings::for_rule(rule_code) + }, + )?; + assert_messages!(snapshot, diagnostics); + Ok(()) + } + #[test] fn w292_4() -> Result<()> { let diagnostics = test_path( @@ -208,7 +231,10 @@ mod tests { Path::new("pycodestyle/E501_2.py"), &settings::LinterSettings { tab_size: NonZeroU8::new(tab_size).unwrap().into(), - line_length: LineLength::try_from(6).unwrap(), + pycodestyle: pycodestyle::settings::Settings { + max_line_length: LineLength::try_from(6).unwrap(), + ..pycodestyle::settings::Settings::default() + }, ..settings::LinterSettings::for_rule(Rule::LineTooLong) }, )?; diff --git a/crates/ruff_linter/src/rules/pycodestyle/overlong.rs b/crates/ruff_linter/src/rules/pycodestyle/overlong.rs new file mode 100644 index 0000000000000..950bafa0554a5 --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/overlong.rs @@ -0,0 +1,165 @@ +use std::ops::Deref; + +use unicode_width::UnicodeWidthStr; + +use ruff_python_index::Indexer; +use ruff_python_trivia::is_pragma_comment; +use ruff_source_file::Line; +use ruff_text_size::{TextLen, TextRange}; + +use crate::line_width::{IndentWidth, LineLength, LineWidthBuilder}; + +#[derive(Debug)] +pub(super) struct Overlong { + range: TextRange, + width: usize, +} + +impl Overlong { + /// Returns an [`Overlong`] if the measured line exceeds the configured line length, or `None` + /// otherwise. + pub(super) fn try_from_line( + line: &Line, + indexer: &Indexer, + limit: LineLength, + task_tags: &[String], + tab_size: IndentWidth, + ) -> Option { + // The maximum width of the line is the number of bytes multiplied by the tab size (the + // worst-case scenario is that the line is all tabs). If the maximum width is less than the + // limit, then the line is not overlong. + let max_width = line.len() * tab_size.as_usize(); + if max_width < limit.value() as usize { + return None; + } + + // Measure the line. If it's already below the limit, exit early. + let width = measure(line.as_str(), tab_size); + if width <= limit { + return None; + } + + // Strip trailing comments and re-measure the line, if needed. + let line = StrippedLine::from_line(line, indexer, task_tags); + let width = match &line { + StrippedLine::WithoutPragma(line) => { + let width = measure(line.as_str(), tab_size); + if width <= limit { + return None; + } + width + } + StrippedLine::Unchanged(_) => width, + }; + + let mut chunks = line.split_whitespace(); + let (Some(_), Some(second_chunk)) = (chunks.next(), chunks.next()) else { + // Single word / no printable chars - no way to make the line shorter. + return None; + }; + + // Do not enforce the line length for lines that end with a URL, as long as the URL + // begins before the limit. + let last_chunk = chunks.last().unwrap_or(second_chunk); + if last_chunk.contains("://") { + if width.get() - last_chunk.width() <= limit.value() as usize { + return None; + } + } + + // Obtain the start offset of the part of the line that exceeds the limit. + let mut start_offset = line.start(); + let mut start_width = LineWidthBuilder::new(tab_size); + for c in line.chars() { + if start_width < limit { + start_offset += c.text_len(); + start_width = start_width.add_char(c); + } else { + break; + } + } + + Some(Self { + range: TextRange::new(start_offset, line.end()), + width: width.get(), + }) + } + + /// Return the range of the overlong portion of the line. + pub(super) const fn range(&self) -> TextRange { + self.range + } + + /// Return the measured width of the line, without any trailing pragma comments. + pub(super) const fn width(&self) -> usize { + self.width + } +} + +/// A [`Line`] that may have trailing pragma comments stripped. +#[derive(Debug)] +enum StrippedLine<'a> { + /// The [`Line`] was unchanged. + Unchanged(&'a Line<'a>), + /// The [`Line`] was changed such that a trailing pragma comment (e.g., `# type: ignore`) was + /// removed. The stored [`Line`] consists of the portion of the original line that precedes the + /// pragma comment. + WithoutPragma(Line<'a>), +} + +impl<'a> StrippedLine<'a> { + /// Strip trailing comments from a [`Line`], if the line ends with a pragma comment (like + /// `# type: ignore`) or, if necessary, a task comment (like `# TODO`). + fn from_line(line: &'a Line<'a>, indexer: &Indexer, task_tags: &[String]) -> Self { + let [comment_range] = indexer.comment_ranges().comments_in_range(line.range()) else { + return Self::Unchanged(line); + }; + + // Convert from absolute to relative range. + let comment_range = comment_range - line.start(); + let comment = &line.as_str()[comment_range]; + + // Ex) `# type: ignore` + if is_pragma_comment(comment) { + // Remove the pragma from the line. + let prefix = &line.as_str()[..usize::from(comment_range.start())].trim_end(); + return Self::WithoutPragma(Line::new(prefix, line.start())); + } + + // Ex) `# TODO(charlie): ...` + if !task_tags.is_empty() { + let Some(trimmed) = comment.strip_prefix('#') else { + return Self::Unchanged(line); + }; + let trimmed = trimmed.trim_start(); + if task_tags + .iter() + .any(|task_tag| trimmed.starts_with(task_tag)) + { + // Remove the task tag from the line. + let prefix = &line.as_str()[..usize::from(comment_range.start())].trim_end(); + return Self::WithoutPragma(Line::new(prefix, line.start())); + } + } + + Self::Unchanged(line) + } +} + +impl<'a> Deref for StrippedLine<'a> { + type Target = Line<'a>; + + fn deref(&self) -> &Self::Target { + match self { + Self::Unchanged(line) => line, + Self::WithoutPragma(line) => line, + } + } +} + +/// Returns the width of a given string, accounting for the tab size. +fn measure(s: &str, tab_size: IndentWidth) -> LineWidthBuilder { + let mut width = LineWidthBuilder::new(tab_size); + width = width.add_str(s); + width +} diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/compound_statements.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/compound_statements.rs index 2ca7657ff273d..a8c8dd3d287b1 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/compound_statements.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/compound_statements.rs @@ -2,15 +2,12 @@ use ruff_python_parser::lexer::LexResult; use ruff_python_parser::Tok; use ruff_text_size::TextRange; -use ruff_diagnostics::{AlwaysAutofixableViolation, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Violation}; use ruff_diagnostics::{Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_index::Indexer; use ruff_source_file::Locator; -use crate::registry::Rule; -use crate::settings::LinterSettings; - /// ## What it does /// Checks for compound statements (multiple statements on the same line). /// @@ -87,13 +84,13 @@ impl Violation for MultipleStatementsOnOneLineSemicolon { #[violation] pub struct UselessSemicolon; -impl AlwaysAutofixableViolation for UselessSemicolon { +impl AlwaysFixableViolation for UselessSemicolon { #[derive_message_formats] fn message(&self) -> String { format!("Statement ends with an unnecessary semicolon") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { format!("Remove unnecessary semicolon") } } @@ -104,7 +101,6 @@ pub(crate) fn compound_statements( lxr: &[LexResult], locator: &Locator, indexer: &Indexer, - settings: &LinterSettings, ) { // Track the last seen instance of a variety of tokens. let mut colon = None; @@ -169,14 +165,12 @@ pub(crate) fn compound_statements( if let Some((start, end)) = semi { let mut diagnostic = Diagnostic::new(UselessSemicolon, TextRange::new(start, end)); - if settings.rules.should_fix(Rule::UselessSemicolon) { - diagnostic.set_fix(Fix::automatic(Edit::deletion( - indexer - .preceded_by_continuations(start, locator) - .unwrap_or(start), - end, - ))); - }; + diagnostic.set_fix(Fix::safe_edit(Edit::deletion( + indexer + .preceded_by_continuations(start, locator) + .unwrap_or(start), + end, + ))); diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/doc_line_too_long.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/doc_line_too_long.rs index efa002ab84177..50a41f4f1b6ad 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/doc_line_too_long.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/doc_line_too_long.rs @@ -1,8 +1,9 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_index::Indexer; use ruff_source_file::Line; -use crate::rules::pycodestyle::helpers::is_overlong; +use crate::rules::pycodestyle::overlong::Overlong; use crate::settings::LinterSettings; /// ## What it does @@ -19,10 +20,17 @@ use crate::settings::LinterSettings; /// of either a standalone comment or a standalone string, like a docstring. /// /// In the interest of pragmatism, this rule makes a few exceptions when -/// determining whether a line is overlong. Namely, it ignores lines that -/// consist of a single "word" (i.e., without any whitespace between its -/// characters), and lines that end with a URL (as long as the URL starts -/// before the line-length threshold). +/// determining whether a line is overlong. Namely, it: +/// +/// 1. Ignores lines that consist of a single "word" (i.e., without any +/// whitespace between its characters). +/// 2. Ignores lines that end with a URL, as long as the URL starts before +/// the line-length threshold. +/// 3. Ignores line that end with a pragma comment (e.g., `# type: ignore` +/// or `# noqa`), as long as the pragma comment starts before the +/// line-length threshold. That is, a line will not be flagged as +/// overlong if a pragma comment _causes_ it to exceed the line length. +/// (This behavior aligns with that of the Ruff formatter.) /// /// If [`pycodestyle.ignore-overlong-task-comments`] is `true`, this rule will /// also ignore comments that start with any of the specified [`task-tags`] @@ -50,27 +58,35 @@ use crate::settings::LinterSettings; /// /// [PEP 8]: https://peps.python.org/pep-0008/#maximum-line-length #[violation] -pub struct DocLineTooLong(pub usize, pub usize); +pub struct DocLineTooLong(usize, usize); impl Violation for DocLineTooLong { #[derive_message_formats] fn message(&self) -> String { let DocLineTooLong(width, limit) = self; - format!("Doc line too long ({width} > {limit} characters)") + format!("Doc line too long ({width} > {limit})") } } /// W505 -pub(crate) fn doc_line_too_long(line: &Line, settings: &LinterSettings) -> Option { +pub(crate) fn doc_line_too_long( + line: &Line, + indexer: &Indexer, + settings: &LinterSettings, +) -> Option { let Some(limit) = settings.pycodestyle.max_doc_length else { return None; }; - is_overlong( + Overlong::try_from_line( line, + indexer, limit, - settings.pycodestyle.ignore_overlong_task_comments, - &settings.task_tags, + if settings.pycodestyle.ignore_overlong_task_comments { + &settings.task_tags + } else { + &[] + }, settings.tab_size, ) .map(|overlong| { diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/invalid_escape_sequence.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/invalid_escape_sequence.rs index 8cf0466c5cdb6..b4d100aa9d6f3 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/invalid_escape_sequence.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/invalid_escape_sequence.rs @@ -1,12 +1,13 @@ use memchr::memchr_iter; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::str::{leading_quote, trailing_quote}; +use ruff_python_index::Indexer; +use ruff_python_parser::Tok; use ruff_source_file::Locator; -use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; +use ruff_text_size::{TextLen, TextRange, TextSize}; -use crate::autofix::edits::pad_start; +use crate::fix::edits::pad_start; /// ## What it does /// Checks for invalid escape sequences. @@ -24,50 +25,83 @@ use crate::autofix::edits::pad_start; /// regex = r"\.png$" /// ``` /// +/// Or, if the string already contains a valid escape sequence: +/// ```python +/// value = "new line\nand invalid escape \_ here" +/// ``` +/// +/// Use instead: +/// ```python +/// value = "new line\nand invalid escape \\_ here" +/// ``` +/// /// ## References /// - [Python documentation: String and Bytes literals](https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals) #[violation] -pub struct InvalidEscapeSequence(char); +pub struct InvalidEscapeSequence { + ch: char, + fix_title: FixTitle, +} -impl AlwaysAutofixableViolation for InvalidEscapeSequence { +impl AlwaysFixableViolation for InvalidEscapeSequence { #[derive_message_formats] fn message(&self) -> String { - let InvalidEscapeSequence(char) = self; - format!("Invalid escape sequence: `\\{char}`") + let InvalidEscapeSequence { ch, .. } = self; + format!("Invalid escape sequence: `\\{ch}`") } - fn autofix_title(&self) -> String { - "Add backslash to escape sequence".to_string() + fn fix_title(&self) -> String { + match self.fix_title { + FixTitle::AddBackslash => format!("Add backslash to escape sequence"), + FixTitle::UseRawStringLiteral => format!("Use a raw string literal"), + } } } +#[derive(Debug, PartialEq, Eq)] +enum FixTitle { + AddBackslash, + UseRawStringLiteral, +} + +#[derive(Debug)] +struct InvalidEscapeChar { + ch: char, + range: TextRange, +} + /// W605 pub(crate) fn invalid_escape_sequence( diagnostics: &mut Vec, locator: &Locator, - range: TextRange, - autofix: bool, + indexer: &Indexer, + token: &Tok, + token_range: TextRange, ) { - let text = locator.slice(range); - - // Determine whether the string is single- or triple-quoted. - let Some(leading_quote) = leading_quote(text) else { - return; - }; - let Some(trailing_quote) = trailing_quote(text) else { - return; + let (token_source_code, string_start_location) = match token { + Tok::FStringMiddle { value, is_raw } => { + if *is_raw { + return; + } + let Some(range) = indexer.fstring_ranges().innermost(token_range.start()) else { + return; + }; + (value.as_str(), range.start()) + } + Tok::String { kind, .. } => { + if kind.is_raw() { + return; + } + (locator.slice(token_range), token_range.start()) + } + _ => return, }; - let body = &text[leading_quote.len()..text.len() - trailing_quote.len()]; - - if leading_quote.contains(['r', 'R']) { - return; - } let mut contains_valid_escape_sequence = false; - let mut invalid_escape_sequence = Vec::new(); + let mut invalid_escape_chars = Vec::new(); let mut prev = None; - let bytes = body.as_bytes(); + let bytes = token_source_code.as_bytes(); for i in memchr_iter(b'\\', bytes) { // If the previous character was also a backslash, skip. if prev.is_some_and(|prev| prev == i - 1) { @@ -77,9 +111,38 @@ pub(crate) fn invalid_escape_sequence( prev = Some(i); - let Some(next_char) = body[i + 1..].chars().next() else { + let next_char = match token_source_code[i + 1..].chars().next() { + Some(next_char) => next_char, + None if token.is_f_string_middle() => { + // If we're at the end of a f-string middle token, the next character + // is actually emitted as a different token. For example, + // + // ```python + // f"\{1}" + // ``` + // + // is lexed as `FStringMiddle('\\')` and `LBrace` (ignoring irrelevant + // tokens), so we need to check the next character in the source code. + // + // Now, if we're at the end of the f-string itself, the lexer wouldn't + // have emitted the `FStringMiddle` token in the first place. For example, + // + // ```python + // f"foo\" + // ``` + // + // Here, there won't be any `FStringMiddle` because it's an unterminated + // f-string. This means that if there's a `FStringMiddle` token and we + // encounter a `\` character, then the next character is always going to + // be part of the f-string. + if let Some(next_char) = locator.after(token_range.end()).chars().next() { + next_char + } else { + continue; + } + } // If we're at the end of the file, skip. - continue; + None => continue, }; // If we're at the end of line, skip. @@ -120,31 +183,51 @@ pub(crate) fn invalid_escape_sequence( continue; } - let location = range.start() + leading_quote.text_len() + TextSize::try_from(i).unwrap(); + let location = token_range.start() + TextSize::try_from(i).unwrap(); let range = TextRange::at(location, next_char.text_len() + TextSize::from(1)); - invalid_escape_sequence.push(Diagnostic::new(InvalidEscapeSequence(next_char), range)); + invalid_escape_chars.push(InvalidEscapeChar { + ch: next_char, + range, + }); } - if autofix { - if contains_valid_escape_sequence { - // Escape with backslash. - for diagnostic in &mut invalid_escape_sequence { - diagnostic.set_fix(Fix::automatic(Edit::insertion( - r"\".to_string(), - diagnostic.start() + TextSize::from(1), - ))); - } - } else { - // Turn into raw string. - for diagnostic in &mut invalid_escape_sequence { + let mut invalid_escape_sequence = Vec::new(); + if contains_valid_escape_sequence { + // Escape with backslash. + for invalid_escape_char in &invalid_escape_chars { + let diagnostic = Diagnostic::new( + InvalidEscapeSequence { + ch: invalid_escape_char.ch, + fix_title: FixTitle::AddBackslash, + }, + invalid_escape_char.range, + ) + .with_fix(Fix::safe_edit(Edit::insertion( + r"\".to_string(), + invalid_escape_char.range.start() + TextSize::from(1), + ))); + invalid_escape_sequence.push(diagnostic); + } + } else { + // Turn into raw string. + for invalid_escape_char in &invalid_escape_chars { + let diagnostic = Diagnostic::new( + InvalidEscapeSequence { + ch: invalid_escape_char.ch, + fix_title: FixTitle::UseRawStringLiteral, + }, + invalid_escape_char.range, + ) + .with_fix( // If necessary, add a space between any leading keyword (`return`, `yield`, // `assert`, etc.) and the string. For example, `return"foo"` is valid, but // `returnr"foo"` is not. - diagnostic.set_fix(Fix::automatic(Edit::insertion( - pad_start("r".to_string(), range.start(), locator), - range.start(), - ))); - } + Fix::safe_edit(Edit::insertion( + pad_start("r".to_string(), string_start_location, locator), + string_start_location, + )), + ); + invalid_escape_sequence.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/lambda_assignment.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/lambda_assignment.rs index 5f45d647bd840..03f8ea988f240 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/lambda_assignment.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/lambda_assignment.rs @@ -3,7 +3,7 @@ use ruff_python_ast::{ }; use ruff_text_size::{Ranged, TextRange}; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_codegen::Generator; use ruff_python_semantic::SemanticModel; @@ -11,7 +11,6 @@ use ruff_python_trivia::{has_leading_content, has_trailing_content, leading_inde use ruff_source_file::UniversalNewlines; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for lambda expressions which are assigned to a variable. @@ -42,14 +41,14 @@ pub struct LambdaAssignment { } impl Violation for LambdaAssignment { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Do not assign a `lambda` expression, use a `def`") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let LambdaAssignment { name } = self; Some(format!("Rewrite `{name}` as a `def`")) } @@ -81,58 +80,59 @@ pub(crate) fn lambda_assignment( stmt.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if !has_leading_content(stmt.start(), checker.locator()) - && !has_trailing_content(stmt.end(), checker.locator()) + if !has_leading_content(stmt.start(), checker.locator()) + && !has_trailing_content(stmt.end(), checker.locator()) + { + let first_line = checker.locator().line(stmt.start()); + let indentation = leading_indentation(first_line); + let mut indented = String::new(); + for (idx, line) in function( + id, + parameters.as_deref(), + body, + annotation, + checker.semantic(), + checker.generator(), + ) + .universal_newlines() + .enumerate() { - let first_line = checker.locator().line(stmt.start()); - let indentation = leading_indentation(first_line); - let mut indented = String::new(); - for (idx, line) in function( - id, - parameters.as_deref(), - body, - annotation, - checker.semantic(), - checker.generator(), - ) - .universal_newlines() - .enumerate() - { - if idx == 0 { - indented.push_str(&line); - } else { - indented.push_str(checker.stylist().line_ending().as_str()); - indented.push_str(indentation); - indented.push_str(&line); - } - } - - // If the assignment is in a class body, it might not be safe to replace it because the - // assignment might be carrying a type annotation that will be used by some package like - // dataclasses, which wouldn't consider the rewritten function definition to be - // equivalent. Even if it _doesn't_ have an annotation, rewriting safely would require - // making this a static method. - // See: https://github.com/astral-sh/ruff/issues/3046 - // - // Similarly, if the lambda is shadowing a variable in the current scope, - // rewriting it as a function declaration may break type-checking. - // See: https://github.com/astral-sh/ruff/issues/5421 - if checker.semantic().current_scope().kind.is_class() - || checker - .semantic() - .current_scope() - .get_all(id) - .any(|binding_id| checker.semantic().binding(binding_id).kind.is_annotation()) - { - diagnostic.set_fix(Fix::manual(Edit::range_replacement(indented, stmt.range()))); + if idx == 0 { + indented.push_str(&line); } else { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - indented, - stmt.range(), - ))); + indented.push_str(checker.stylist().line_ending().as_str()); + indented.push_str(indentation); + indented.push_str(&line); } } + + // If the assignment is in a class body, it might not be safe to replace it because the + // assignment might be carrying a type annotation that will be used by some package like + // dataclasses, which wouldn't consider the rewritten function definition to be + // equivalent. Even if it _doesn't_ have an annotation, rewriting safely would require + // making this a static method. + // See: https://github.com/astral-sh/ruff/issues/3046 + // + // Similarly, if the lambda is shadowing a variable in the current scope, + // rewriting it as a function declaration may break type-checking. + // See: https://github.com/astral-sh/ruff/issues/5421 + if checker.semantic().current_scope().kind.is_class() + || checker + .semantic() + .current_scope() + .get_all(id) + .any(|binding_id| checker.semantic().binding(binding_id).kind.is_annotation()) + { + diagnostic.set_fix(Fix::display_edit(Edit::range_replacement( + indented, + stmt.range(), + ))); + } else { + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + indented, + stmt.range(), + ))); + } } checker.diagnostics.push(diagnostic); diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/line_too_long.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/line_too_long.rs index db18c37f1e662..d803cfa559149 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/line_too_long.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/line_too_long.rs @@ -1,8 +1,9 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_index::Indexer; use ruff_source_file::Line; -use crate::rules::pycodestyle::helpers::is_overlong; +use crate::rules::pycodestyle::overlong::Overlong; use crate::settings::LinterSettings; /// ## What it does @@ -15,10 +16,17 @@ use crate::settings::LinterSettings; /// configurable via the [`line-length`] setting. /// /// In the interest of pragmatism, this rule makes a few exceptions when -/// determining whether a line is overlong. Namely, it ignores lines that -/// consist of a single "word" (i.e., without any whitespace between its -/// characters), and lines that end with a URL (as long as the URL starts -/// before the line-length threshold). +/// determining whether a line is overlong. Namely, it: +/// +/// 1. Ignores lines that consist of a single "word" (i.e., without any +/// whitespace between its characters). +/// 2. Ignores lines that end with a URL, as long as the URL starts before +/// the line-length threshold. +/// 3. Ignores line that end with a pragma comment (e.g., `# type: ignore` +/// or `# noqa`), as long as the pragma comment starts before the +/// line-length threshold. That is, a line will not be flagged as +/// overlong if a pragma comment _causes_ it to exceed the line length. +/// (This behavior aligns with that of the Ruff formatter.) /// /// If [`pycodestyle.ignore-overlong-task-comments`] is `true`, this rule will /// also ignore comments that start with any of the specified [`task-tags`] @@ -39,30 +47,39 @@ use crate::settings::LinterSettings; /// /// ## Options /// - `line-length` +/// - `pycodestyle.max-line-length` /// - `task-tags` /// - `pycodestyle.ignore-overlong-task-comments` /// /// [PEP 8]: https://peps.python.org/pep-0008/#maximum-line-length #[violation] -pub struct LineTooLong(pub usize, pub usize); +pub struct LineTooLong(usize, usize); impl Violation for LineTooLong { #[derive_message_formats] fn message(&self) -> String { let LineTooLong(width, limit) = self; - format!("Line too long ({width} > {limit} characters)") + format!("Line too long ({width} > {limit})") } } /// E501 -pub(crate) fn line_too_long(line: &Line, settings: &LinterSettings) -> Option { - let limit = settings.line_length; +pub(crate) fn line_too_long( + line: &Line, + indexer: &Indexer, + settings: &LinterSettings, +) -> Option { + let limit = settings.pycodestyle.max_line_length; - is_overlong( + Overlong::try_from_line( line, + indexer, limit, - settings.pycodestyle.ignore_overlong_task_comments, - &settings.task_tags, + if settings.pycodestyle.ignore_overlong_task_comments { + &settings.task_tags + } else { + &[] + }, settings.tab_size, ) .map(|overlong| { diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/literal_comparisons.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/literal_comparisons.rs index 2abf9faf65d37..cb8806d91961c 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/literal_comparisons.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/literal_comparisons.rs @@ -1,16 +1,14 @@ use rustc_hash::FxHashMap; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers; -use ruff_python_ast::helpers::is_const_none; +use ruff_python_ast::helpers::{generate_comparison, is_const_none}; use ruff_python_ast::{self as ast, CmpOp, Constant, Expr}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::codes::Rule; -use crate::registry::AsRule; -use crate::rules::pycodestyle::helpers::generate_comparison; #[derive(Debug, PartialEq, Eq, Copy, Clone)] enum EqCmpOp { @@ -53,7 +51,7 @@ impl EqCmpOp { #[violation] pub struct NoneComparison(EqCmpOp); -impl AlwaysAutofixableViolation for NoneComparison { +impl AlwaysFixableViolation for NoneComparison { #[derive_message_formats] fn message(&self) -> String { let NoneComparison(op) = self; @@ -63,7 +61,7 @@ impl AlwaysAutofixableViolation for NoneComparison { } } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let NoneComparison(op) = self; match op { EqCmpOp::Eq => "Replace with `cond is None`".to_string(), @@ -99,7 +97,7 @@ impl AlwaysAutofixableViolation for NoneComparison { #[violation] pub struct TrueFalseComparison(bool, EqCmpOp); -impl AlwaysAutofixableViolation for TrueFalseComparison { +impl AlwaysFixableViolation for TrueFalseComparison { #[derive_message_formats] fn message(&self) -> String { let TrueFalseComparison(value, op) = self; @@ -119,7 +117,7 @@ impl AlwaysAutofixableViolation for TrueFalseComparison { } } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let TrueFalseComparison(value, op) = self; match (value, op) { (true, EqCmpOp::Eq) => "Replace with `cond is True`".to_string(), @@ -154,16 +152,12 @@ pub(crate) fn literal_comparisons(checker: &mut Checker, compare: &ast::ExprComp match op { EqCmpOp::Eq => { let diagnostic = Diagnostic::new(NoneComparison(op), comparator.range()); - if checker.patch(diagnostic.kind.rule()) { - bad_ops.insert(0, CmpOp::Is); - } + bad_ops.insert(0, CmpOp::Is); diagnostics.push(diagnostic); } EqCmpOp::NotEq => { let diagnostic = Diagnostic::new(NoneComparison(op), comparator.range()); - if checker.patch(diagnostic.kind.rule()) { - bad_ops.insert(0, CmpOp::IsNot); - } + bad_ops.insert(0, CmpOp::IsNot); diagnostics.push(diagnostic); } } @@ -181,9 +175,7 @@ pub(crate) fn literal_comparisons(checker: &mut Checker, compare: &ast::ExprComp TrueFalseComparison(*value, op), comparator.range(), ); - if checker.patch(diagnostic.kind.rule()) { - bad_ops.insert(0, CmpOp::Is); - } + bad_ops.insert(0, CmpOp::Is); diagnostics.push(diagnostic); } EqCmpOp::NotEq => { @@ -191,9 +183,7 @@ pub(crate) fn literal_comparisons(checker: &mut Checker, compare: &ast::ExprComp TrueFalseComparison(*value, op), comparator.range(), ); - if checker.patch(diagnostic.kind.rule()) { - bad_ops.insert(0, CmpOp::IsNot); - } + bad_ops.insert(0, CmpOp::IsNot); diagnostics.push(diagnostic); } } @@ -222,16 +212,12 @@ pub(crate) fn literal_comparisons(checker: &mut Checker, compare: &ast::ExprComp match op { EqCmpOp::Eq => { let diagnostic = Diagnostic::new(NoneComparison(op), next.range()); - if checker.patch(diagnostic.kind.rule()) { - bad_ops.insert(index, CmpOp::Is); - } + bad_ops.insert(index, CmpOp::Is); diagnostics.push(diagnostic); } EqCmpOp::NotEq => { let diagnostic = Diagnostic::new(NoneComparison(op), next.range()); - if checker.patch(diagnostic.kind.rule()) { - bad_ops.insert(index, CmpOp::IsNot); - } + bad_ops.insert(index, CmpOp::IsNot); diagnostics.push(diagnostic); } } @@ -247,17 +233,13 @@ pub(crate) fn literal_comparisons(checker: &mut Checker, compare: &ast::ExprComp EqCmpOp::Eq => { let diagnostic = Diagnostic::new(TrueFalseComparison(*value, op), next.range()); - if checker.patch(diagnostic.kind.rule()) { - bad_ops.insert(index, CmpOp::Is); - } + bad_ops.insert(index, CmpOp::Is); diagnostics.push(diagnostic); } EqCmpOp::NotEq => { let diagnostic = Diagnostic::new(TrueFalseComparison(*value, op), next.range()); - if checker.patch(diagnostic.kind.rule()) { - bad_ops.insert(index, CmpOp::IsNot); - } + bad_ops.insert(index, CmpOp::IsNot); diagnostics.push(diagnostic); } } @@ -287,7 +269,7 @@ pub(crate) fn literal_comparisons(checker: &mut Checker, compare: &ast::ExprComp checker.locator(), ); for diagnostic in &mut diagnostics { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( content.to_string(), compare.range(), ))); diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs index d593078f5a28c..0273e8eeb6bd6 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs @@ -1,7 +1,12 @@ +use std::iter::zip; + use super::{LogicalLine, LogicalLineToken}; use crate::checkers::logical_lines::LogicalLinesContext; -use ruff_diagnostics::Violation; +use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_parser::TokenKind; +use ruff_source_file::Locator; +use ruff_text_size::{Ranged, TextRange, TextSize}; /// ## What it does /// Checks for continuation lines not indented as far as they should be or indented too far. @@ -30,11 +35,369 @@ impl Violation for MissingOrOutdentedIndentation { } } +#[derive(Debug)] +struct TokenInfo<'a> { + start_physical_line_idx: usize, + end_physical_line_idx: usize, + token_start_within_physical_line: usize, + token_end_within_physical_line: usize, + line: &'a str, +} + +/// Compute the TokenInfo of each token. +fn get_token_infos<'a>(logical_line: &LogicalLine, locator: &'a Locator) -> Vec> { + let mut token_infos = Vec::new(); + let mut current_line_idx: usize = 0; + // The first physical line occupied by the token, since a token can span multiple physical lines. + let mut first_physical_line_start = if let Some(first_token) = logical_line.first_token() { + first_token.range.start() + } else { + return token_infos; + }; + let mut current_physical_line_start: TextSize; + let mut prev_token: Option<&LogicalLineToken> = None; + for token in logical_line.tokens() { + let mut start_physical_line_idx = current_line_idx; + current_physical_line_start = first_physical_line_start; + + // Check for escaped ('\') continuation lines between the previous and current tokens. + if let Some(prev_token) = prev_token { + let trivia = locator.slice(TextRange::new(prev_token.range.end(), token.range.start())); + for (index, _text) in trivia.match_indices("\n") { + start_physical_line_idx += 1; + current_line_idx = start_physical_line_idx; + first_physical_line_start = + prev_token.range.end() + TextSize::try_from(index + 1).unwrap(); + current_physical_line_start = first_physical_line_start; + } + } + + if !matches!( + token.kind, + TokenKind::NonLogicalNewline | TokenKind::Newline + ) { + // Look for newlines within strings. + let trivia = locator.slice(TextRange::new(token.range.start(), token.range.end())); + for (index, _text) in trivia.match_indices("\n") { + current_line_idx += 1; + current_physical_line_start = + token.range.start() + TextSize::try_from(index + 1).unwrap(); + } + } + + token_infos.push(TokenInfo { + start_physical_line_idx, + end_physical_line_idx: current_line_idx, + token_start_within_physical_line: (token.range.start() - first_physical_line_start) + .into(), + token_end_within_physical_line: (token.range.end() - current_physical_line_start) + .into(), + line: locator.slice(locator.full_lines_range(token.range)), + }); + + if matches!( + token.kind, + TokenKind::NonLogicalNewline | TokenKind::Newline + ) { + current_line_idx += 1; + first_physical_line_start = token.range.end(); + } else { + first_physical_line_start = current_physical_line_start; + } + prev_token = Some(&token); + } + + token_infos +} + +/// Return the amount of indentation of the given line. +/// Tabs are expanded to the next multiple of 8. +fn expand_indent(line: &str) -> usize { + if !line.contains('\t') { + // If there are no tabs in the line, return the leading space count + return line.len() - line.trim_start().len(); + } + let mut indent = 0; + + for ch in line.chars() { + if ch == '\t' { + indent = indent / 8 * 8 + 8; + } else if ch == ' ' { + indent += 1; + } else { + break; + } + } + + indent +} + /// E122 pub(crate) fn continuation_line_missing_indentation_or_outdented( context: &mut LogicalLinesContext, logical_line: &LogicalLine, + locator: &Locator, indent_char: char, indent_size: usize, ) { + let token_infos = get_token_infos(logical_line, locator); + let nb_physical_lines = if let Some(last_token_info) = token_infos.last() { + 1 + last_token_info.start_physical_line_idx + } else { + 1 + }; + + if nb_physical_lines == 1 { + return; + } + + // Indent of the first physical line. + let start_indent_level = expand_indent( + locator.line( + logical_line + .first_token() + .expect("Would have returned earlier if the logical line was empty") + .start(), + ), + ); + + // indent_next tells us whether the next block is indented. + // Assuming that it is indented by 4 spaces, then we should not allow 4-space indents on the final continuation line. + // In turn, some other indents are allowed to have an extra 4 spaces. + let indent_next = logical_line.text().ends_with(':'); + + // Here "row" is the physical line index (within the logical line). + let mut row = 0; + let mut depth = 0; + let valid_hangs = if indent_char != '\t' { + vec![indent_size as i64] + } else { + vec![indent_size as i64, indent_size as i64 * 2] + }; + // Remember how many brackets were opened on each line. + let mut parens = vec![0; nb_physical_lines]; + // Relative indents of physical lines. + let mut rel_indent: Vec = vec![0; nb_physical_lines]; + // For each depth, collect a list of opening rows. + let mut open_rows = vec![vec![0]]; + // For each depth, memorize the hanging indentation. + let mut hangs: Vec> = vec![None]; + let mut hang: i64 = 0; + let mut hanging_indent: bool = false; + // Visual indents + let mut indent_chances: Vec = Vec::new(); + let mut last_indent = start_indent_level; + let mut visual_indent = false; + let mut last_token_multiline = false; + // For each depth, memorize the visual indent column. + let mut indent = vec![start_indent_level]; + + // TODO: config option: hang closing bracket instead of matching indentation of opening bracket's line. + let hang_closing = false; + + for (token, token_info) in zip(logical_line.tokens(), token_infos) { + let mut is_newline = row < token_info.start_physical_line_idx; + if is_newline { + row = token_info.start_physical_line_idx; + is_newline = !last_token_multiline + && !matches!( + token.kind, + TokenKind::NonLogicalNewline | TokenKind::Newline + ); + } + + let is_closing_bracket = matches!( + token.kind, + TokenKind::Rpar | TokenKind::Rsqb | TokenKind::Rbrace + ); + + // This is the beginning of a continuation line. + if is_newline { + last_indent = token_info.token_start_within_physical_line; + + // Record the initial indent. + rel_indent[row] = expand_indent(token_info.line) as i64 - start_indent_level as i64; + + // Is the indent relative to an opening bracket line ? + for open_row in open_rows[depth].iter().rev() { + hang = rel_indent[row] - rel_indent[*open_row]; + hanging_indent = valid_hangs.contains(&hang); + if hanging_indent { + break; + } + } + if let Some(depth_hang) = hangs[depth] { + hanging_indent = hang == depth_hang; + } + + // Is there any chance of visual indent ? + visual_indent = !is_closing_bracket + && hang > 0 + && indent_chances.contains(&token_info.token_start_within_physical_line.into()); + + if is_closing_bracket && indent[depth] != 0 { + // Closing bracket for visual indent. + if token_info.token_start_within_physical_line != indent[depth] { + dbg!("E124"); + // TODO: Raise E124. + } + } else if is_closing_bracket && hang == 0 { + // Closing bracket matches indentation of opening bracket's line + if hang_closing { + dbg!("E133"); + // TODO: Raise E133. + } + } else if indent[depth] != 0 + && token_info.token_start_within_physical_line < indent[depth] + { + // visual indent is broken + if !visual_indent { + dbg!("E128"); + // TODO: Raise E128. + } + } else if hanging_indent || (indent_next && rel_indent[row] == (2 * indent_size) as i64) + { + // hanging indent is verified + if is_closing_bracket && !hang_closing { + dbg!("E123"); + // TODO: Raise E123. + } + hangs[depth] = Some(hang); + } else if visual_indent { + // Visual indent is verified. + indent[depth] = token_info.token_start_within_physical_line; + } else { + // Indent is broken. + if hang <= 0 { + // E122. + let diagnostic = Diagnostic::new(MissingOrOutdentedIndentation, token.range); + // if autofix_after_open_bracket { + // diagnostic + // .set_fix(Fix::automatic(Edit::range_deletion(diagnostic.range()))); + // } + context.push_diagnostic(diagnostic); + } else if indent[depth] != 0 { + // TODO: Raise E127. + } else if !is_closing_bracket && hangs[depth].is_some_and(|hang| hang > 0) { + // TODO: Raise 131. + } else { + hangs[depth] = Some(hang); + if hang > indent_size as i64 { + // TODO: Raise 126. + } else { + // TODO: Raise E121. + } + } + } + } + + // Look for visual indenting. + if parens[row] != 0 + && !matches!( + token.kind, + TokenKind::Newline | TokenKind::NonLogicalNewline | TokenKind::Comment + ) + && indent[depth] == 0 + { + indent[depth] = token_info.token_start_within_physical_line; + indent_chances.push(token_info.token_start_within_physical_line); + } + // Deal with implicit string concatenation. + else if matches!(token.kind, TokenKind::Comment | TokenKind::String) { + indent_chances.push(token_info.token_start_within_physical_line); + } + // Visual indent after assert/raise/with. + else if row == 0 + && depth == 0 + && matches!( + token.kind, + TokenKind::Assert | TokenKind::Raise | TokenKind::With + ) + { + indent_chances.push(token_info.token_end_within_physical_line + 1); + } + // Special case for the "if" statement because "if (".len() == 4 + else if indent_chances.len() == 0 + && row == 0 + && depth == 0 + && matches!(token.kind, TokenKind::If) + { + indent_chances.push(token_info.token_end_within_physical_line + 1); + } else if matches!(token.kind, TokenKind::Colon) + && token_info.line[token_info.token_end_within_physical_line..] + .trim() + .is_empty() + { + open_rows[depth].push(row); + } + + let is_opening_bracket = matches!( + token.kind, + TokenKind::Lpar | TokenKind::Lsqb | TokenKind::Lbrace + ); + + // Keep track of bracket depth. + if is_opening_bracket || is_closing_bracket { + if is_opening_bracket { + depth += 1; + indent.push(0); + hangs.push(None); + if open_rows.len() == depth { + open_rows.push(Vec::new()); + } + open_rows[depth].push(row); + parens[row] += 1; + } else if is_closing_bracket && depth > 0 { + // Parent indents should not be more than this one. + let prev_indent = if let Some(i) = indent.pop() { + if i > 0 { + i + } else { + last_indent + } + } else { + last_indent + }; + hangs.pop(); + for d in 0..depth { + if indent[d] > prev_indent { + indent[d] = 0 + } + } + indent_chances = indent_chances + .into_iter() + .filter(|&ind| ind < prev_indent) + .collect(); + open_rows.truncate(depth); + depth -= 1; + if depth > 0 { + indent_chances.push(indent[depth]); + } + for idx in (0..row + 1).rev() { + if parens[idx] != 0 { + parens[idx] -= 1; + break; + } + } + } + if !indent_chances.contains(&token_info.token_start_within_physical_line) { + // Allow lining up tokens + indent_chances.push(token_info.token_start_within_physical_line); + } + } + + last_token_multiline = + token_info.start_physical_line_idx != token_info.end_physical_line_idx; + if last_token_multiline { + rel_indent[token_info.end_physical_line_idx] = rel_indent[row] + } + + if indent_next && expand_indent(token_info.line) == start_indent_level + indent_size { + if visual_indent { + // TODO: Raise 129. + } else { + // TODO: Raise 125. + } + } + } } diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/extraneous_whitespace.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/extraneous_whitespace.rs index 3d01fad8dbd21..c1be325c76422 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/extraneous_whitespace.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/extraneous_whitespace.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::AlwaysAutofixableViolation; +use ruff_diagnostics::AlwaysFixableViolation; use ruff_diagnostics::Diagnostic; use ruff_diagnostics::Edit; use ruff_diagnostics::Fix; @@ -36,14 +36,14 @@ pub struct WhitespaceAfterOpenBracket { symbol: char, } -impl AlwaysAutofixableViolation for WhitespaceAfterOpenBracket { +impl AlwaysFixableViolation for WhitespaceAfterOpenBracket { #[derive_message_formats] fn message(&self) -> String { let WhitespaceAfterOpenBracket { symbol } = self; format!("Whitespace after '{symbol}'") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let WhitespaceAfterOpenBracket { symbol } = self; format!("Remove whitespace before '{symbol}'") } @@ -75,14 +75,14 @@ pub struct WhitespaceBeforeCloseBracket { symbol: char, } -impl AlwaysAutofixableViolation for WhitespaceBeforeCloseBracket { +impl AlwaysFixableViolation for WhitespaceBeforeCloseBracket { #[derive_message_formats] fn message(&self) -> String { let WhitespaceBeforeCloseBracket { symbol } = self; format!("Whitespace before '{symbol}'") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let WhitespaceBeforeCloseBracket { symbol } = self; format!("Remove whitespace before '{symbol}'") } @@ -112,48 +112,55 @@ pub struct WhitespaceBeforePunctuation { symbol: char, } -impl AlwaysAutofixableViolation for WhitespaceBeforePunctuation { +impl AlwaysFixableViolation for WhitespaceBeforePunctuation { #[derive_message_formats] fn message(&self) -> String { let WhitespaceBeforePunctuation { symbol } = self; format!("Whitespace before '{symbol}'") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let WhitespaceBeforePunctuation { symbol } = self; format!("Remove whitespace before '{symbol}'") } } /// E201, E202, E203 -pub(crate) fn extraneous_whitespace( - line: &LogicalLine, - context: &mut LogicalLinesContext, - autofix_after_open_bracket: bool, - autofix_before_close_bracket: bool, - autofix_before_punctuation: bool, -) { +pub(crate) fn extraneous_whitespace(line: &LogicalLine, context: &mut LogicalLinesContext) { let mut prev_token = None; + let mut fstrings = 0u32; for token in line.tokens() { let kind = token.kind(); + match kind { + TokenKind::FStringStart => fstrings += 1, + TokenKind::FStringEnd => fstrings = fstrings.saturating_sub(1), + _ => {} + } if let Some(symbol) = BracketOrPunctuation::from_kind(kind) { + // Whitespace before "{" or after "}" might be required in f-strings. + // For example, + // + // ```python + // f"{ {'a': 1} }" + // ``` + // + // Here, `{{` / `}} would be interpreted as a single raw `{` / `}` + // character. match symbol { - BracketOrPunctuation::OpenBracket(symbol) => { + BracketOrPunctuation::OpenBracket(symbol) if symbol != '{' || fstrings == 0 => { let (trailing, trailing_len) = line.trailing_whitespace(token); if !matches!(trailing, Whitespace::None) { let mut diagnostic = Diagnostic::new( WhitespaceAfterOpenBracket { symbol }, TextRange::at(token.end(), trailing_len), ); - if autofix_after_open_bracket { - diagnostic - .set_fix(Fix::automatic(Edit::range_deletion(diagnostic.range()))); - } + diagnostic + .set_fix(Fix::safe_edit(Edit::range_deletion(diagnostic.range()))); context.push_diagnostic(diagnostic); } } - BracketOrPunctuation::CloseBracket(symbol) => { + BracketOrPunctuation::CloseBracket(symbol) if symbol != '}' || fstrings == 0 => { if !matches!(prev_token, Some(TokenKind::Comma)) { if let (Whitespace::Single | Whitespace::Many | Whitespace::Tab, offset) = line.leading_whitespace(token) @@ -162,11 +169,8 @@ pub(crate) fn extraneous_whitespace( WhitespaceBeforeCloseBracket { symbol }, TextRange::at(token.start() - offset, offset), ); - if autofix_before_close_bracket { - diagnostic.set_fix(Fix::automatic(Edit::range_deletion( - diagnostic.range(), - ))); - } + diagnostic + .set_fix(Fix::safe_edit(Edit::range_deletion(diagnostic.range()))); context.push_diagnostic(diagnostic); } } @@ -180,15 +184,13 @@ pub(crate) fn extraneous_whitespace( WhitespaceBeforePunctuation { symbol }, TextRange::at(token.start() - offset, offset), ); - if autofix_before_punctuation { - diagnostic.set_fix(Fix::automatic(Edit::range_deletion( - diagnostic.range(), - ))); - } + diagnostic + .set_fix(Fix::safe_edit(Edit::range_deletion(diagnostic.range()))); context.push_diagnostic(diagnostic); } } } + _ => {} } } diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/indentation.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/indentation.rs index ea4f592881023..ccad94347577b 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/indentation.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/indentation.rs @@ -23,7 +23,16 @@ use super::LogicalLine; /// a = 1 /// ``` /// +/// +/// ## Formatter compatibility +/// We recommend against using this rule alongside the [formatter]. The +/// formatter enforces consistent indentation, making the rule redundant. +/// +/// The rule is also incompatible with the [formatter] when using +/// `indent-width` with a value other than `4`. +/// /// [PEP 8]: https://peps.python.org/pep-0008/#indentation +/// [formatter]:https://docs.astral.sh/ruff/formatter/ #[violation] pub struct IndentationWithInvalidMultiple { indent_size: usize, @@ -55,7 +64,15 @@ impl Violation for IndentationWithInvalidMultiple { /// # a = 1 /// ``` /// +/// ## Formatter compatibility +/// We recommend against using this rule alongside the [formatter]. The +/// formatter enforces consistent indentation, making the rule redundant. +/// +/// The rule is also incompatible with the [formatter] when using +/// `indent-width` with a value other than `4`. +/// /// [PEP 8]: https://peps.python.org/pep-0008/#indentation +/// [formatter]:https://docs.astral.sh/ruff/formatter/ #[violation] pub struct IndentationWithInvalidMultipleComment { indent_size: usize, diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/missing_whitespace.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/missing_whitespace.rs index 89a6d038c1abc..314693446aa86 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/missing_whitespace.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/missing_whitespace.rs @@ -1,5 +1,5 @@ use ruff_diagnostics::Edit; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_parser::TokenKind; use ruff_text_size::{Ranged, TextSize}; @@ -39,26 +39,22 @@ impl MissingWhitespace { } } -impl AlwaysAutofixableViolation for MissingWhitespace { +impl AlwaysFixableViolation for MissingWhitespace { #[derive_message_formats] fn message(&self) -> String { let token = self.token_text(); format!("Missing whitespace after '{token}'") } - fn autofix_title(&self) -> String { - let token = self.token_text(); - format!("Added missing whitespace after '{token}'") + fn fix_title(&self) -> String { + format!("Add missing whitespace") } } /// E231 -pub(crate) fn missing_whitespace( - line: &LogicalLine, - autofix: bool, - context: &mut LogicalLinesContext, -) { +pub(crate) fn missing_whitespace(line: &LogicalLine, context: &mut LogicalLinesContext) { let mut open_parentheses = 0u32; + let mut fstrings = 0u32; let mut prev_lsqb = TextSize::default(); let mut prev_lbrace = TextSize::default(); let mut iter = line.tokens().iter().peekable(); @@ -66,6 +62,8 @@ pub(crate) fn missing_whitespace( while let Some(token) = iter.next() { let kind = token.kind(); match kind { + TokenKind::FStringStart => fstrings += 1, + TokenKind::FStringEnd => fstrings = fstrings.saturating_sub(1), TokenKind::Lsqb => { open_parentheses = open_parentheses.saturating_add(1); prev_lsqb = token.start(); @@ -76,6 +74,17 @@ pub(crate) fn missing_whitespace( TokenKind::Lbrace => { prev_lbrace = token.start(); } + TokenKind::Colon if fstrings > 0 => { + // Colon in f-string, no space required. This will yield false + // negatives for cases like the following as it's hard to + // differentiate between the usage of a colon in a f-string. + // + // ```python + // f'{ {'x':1} }' + // f'{(lambda x:x)}' + // ``` + continue; + } TokenKind::Comma | TokenKind::Semi | TokenKind::Colon => { let after = line.text_after(token); @@ -102,15 +111,12 @@ pub(crate) fn missing_whitespace( } } - let kind = MissingWhitespace { token: kind }; - let mut diagnostic = Diagnostic::new(kind, token.range()); - - if autofix { - diagnostic.set_fix(Fix::automatic(Edit::insertion( - " ".to_string(), - token.end(), - ))); - } + let mut diagnostic = + Diagnostic::new(MissingWhitespace { token: kind }, token.range()); + diagnostic.set_fix(Fix::safe_edit(Edit::insertion( + " ".to_string(), + token.end(), + ))); context.push_diagnostic(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/missing_whitespace_after_keyword.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/missing_whitespace_after_keyword.rs index 0dc26221e8b52..7aa8cfc24764a 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/missing_whitespace_after_keyword.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/missing_whitespace_after_keyword.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::Violation; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_parser::TokenKind; use ruff_text_size::Ranged; @@ -29,11 +29,15 @@ use crate::rules::pycodestyle::rules::logical_lines::LogicalLine; #[violation] pub struct MissingWhitespaceAfterKeyword; -impl Violation for MissingWhitespaceAfterKeyword { +impl AlwaysFixableViolation for MissingWhitespaceAfterKeyword { #[derive_message_formats] fn message(&self) -> String { format!("Missing whitespace after keyword") } + + fn fix_title(&self) -> String { + format!("Added missing whitespace after keyword") + } } /// E275 @@ -59,7 +63,9 @@ pub(crate) fn missing_whitespace_after_keyword( )) && tok0.end() == tok1.start() { - context.push(MissingWhitespaceAfterKeyword, tok0.range()); + let mut diagnostic = Diagnostic::new(MissingWhitespaceAfterKeyword, tok0.range()); + diagnostic.set_fix(Fix::safe_edit(Edit::insertion(" ".to_string(), tok0.end()))); + context.push_diagnostic(diagnostic); } } } diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/missing_whitespace_around_operator.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/missing_whitespace_around_operator.rs index 644443c4e80b7..c5432802ccd26 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/missing_whitespace_around_operator.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/missing_whitespace_around_operator.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{DiagnosticKind, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, DiagnosticKind, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_parser::TokenKind; use ruff_text_size::Ranged; @@ -30,11 +30,15 @@ use crate::rules::pycodestyle::rules::logical_lines::LogicalLine; #[violation] pub struct MissingWhitespaceAroundOperator; -impl Violation for MissingWhitespaceAroundOperator { +impl AlwaysFixableViolation for MissingWhitespaceAroundOperator { #[derive_message_formats] fn message(&self) -> String { format!("Missing whitespace around operator") } + + fn fix_title(&self) -> String { + format!("Add missing whitespace") + } } /// ## What it does @@ -59,11 +63,15 @@ impl Violation for MissingWhitespaceAroundOperator { #[violation] pub struct MissingWhitespaceAroundArithmeticOperator; -impl Violation for MissingWhitespaceAroundArithmeticOperator { +impl AlwaysFixableViolation for MissingWhitespaceAroundArithmeticOperator { #[derive_message_formats] fn message(&self) -> String { format!("Missing whitespace around arithmetic operator") } + + fn fix_title(&self) -> String { + format!("Add missing whitespace") + } } /// ## What it does @@ -88,11 +96,15 @@ impl Violation for MissingWhitespaceAroundArithmeticOperator { #[violation] pub struct MissingWhitespaceAroundBitwiseOrShiftOperator; -impl Violation for MissingWhitespaceAroundBitwiseOrShiftOperator { +impl AlwaysFixableViolation for MissingWhitespaceAroundBitwiseOrShiftOperator { #[derive_message_formats] fn message(&self) -> String { format!("Missing whitespace around bitwise or shift operator") } + + fn fix_title(&self) -> String { + format!("Add missing whitespace") + } } /// ## What it does @@ -117,11 +129,15 @@ impl Violation for MissingWhitespaceAroundBitwiseOrShiftOperator { #[violation] pub struct MissingWhitespaceAroundModuloOperator; -impl Violation for MissingWhitespaceAroundModuloOperator { +impl AlwaysFixableViolation for MissingWhitespaceAroundModuloOperator { #[derive_message_formats] fn message(&self) -> String { format!("Missing whitespace around modulo operator") } + + fn fix_title(&self) -> String { + format!("Add missing whitespace") + } } /// E225, E226, E227, E228 @@ -130,10 +146,7 @@ pub(crate) fn missing_whitespace_around_operator( context: &mut LogicalLinesContext, ) { let mut tokens = line.tokens().iter().peekable(); - let first_token = tokens.by_ref().find_map(|token| { - let kind = token.kind(); - (!kind.is_trivia()).then_some(token) - }); + let first_token = tokens.by_ref().find(|token| !token.kind().is_trivia()); let Some(mut prev_token) = first_token else { return; }; @@ -141,6 +154,7 @@ pub(crate) fn missing_whitespace_around_operator( prev_token.kind(), TokenKind::Lpar | TokenKind::Lambda )); + let mut fstrings = u32::from(matches!(prev_token.kind(), TokenKind::FStringStart)); while let Some(token) = tokens.next() { let kind = token.kind(); @@ -150,13 +164,15 @@ pub(crate) fn missing_whitespace_around_operator( } match kind { + TokenKind::FStringStart => fstrings += 1, + TokenKind::FStringEnd => fstrings = fstrings.saturating_sub(1), TokenKind::Lpar | TokenKind::Lambda => parens += 1, TokenKind::Rpar => parens = parens.saturating_sub(1), _ => {} }; - let needs_space = if kind == TokenKind::Equal && parens > 0 { - // Allow keyword args or defaults: foo(bar=None). + let needs_space = if kind == TokenKind::Equal && (parens > 0 || fstrings > 0) { + // Allow keyword args, defaults: foo(bar=None) and f-strings: f'{foo=}' NeedsSpace::No } else if kind == TokenKind::Slash { // Tolerate the "/" operator in function definition @@ -211,15 +227,35 @@ pub(crate) fn missing_whitespace_around_operator( match (has_leading_trivia, has_trailing_trivia) { // Operator with trailing but no leading space, enforce consistent spacing. - (false, true) | + (false, true) => { + let mut diagnostic = + Diagnostic::new(diagnostic_kind_for_operator(kind), token.range()); + diagnostic.set_fix(Fix::safe_edit(Edit::insertion( + " ".to_string(), + token.start(), + ))); + context.push_diagnostic(diagnostic); + } // Operator with leading but no trailing space, enforce consistent spacing. (true, false) => { - context.push(MissingWhitespaceAroundOperator, token.range()); + let mut diagnostic = + Diagnostic::new(diagnostic_kind_for_operator(kind), token.range()); + diagnostic.set_fix(Fix::safe_edit(Edit::insertion( + " ".to_string(), + token.end(), + ))); + context.push_diagnostic(diagnostic); } // Operator with no space, require spaces if it is required by the operator. (false, false) => { if needs_space == NeedsSpace::Yes { - context.push(diagnostic_kind_for_operator(kind), token.range()); + let mut diagnostic = + Diagnostic::new(diagnostic_kind_for_operator(kind), token.range()); + diagnostic.set_fix(Fix::safe_edits( + Edit::insertion(" ".to_string(), token.start()), + [Edit::insertion(" ".to_string(), token.end())], + )); + context.push_diagnostic(diagnostic); } } (true, true) => { diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/space_around_operator.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/space_around_operator.rs index 72e4d0c53caa5..b150173b854f7 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/space_around_operator.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/space_around_operator.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::Violation; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_parser::TokenKind; use ruff_text_size::{Ranged, TextRange}; @@ -28,11 +28,15 @@ use super::{LogicalLine, Whitespace}; #[violation] pub struct TabBeforeOperator; -impl Violation for TabBeforeOperator { +impl AlwaysFixableViolation for TabBeforeOperator { #[derive_message_formats] fn message(&self) -> String { format!("Tab before operator") } + + fn fix_title(&self) -> String { + format!("Replace with single space") + } } /// ## What it does @@ -84,11 +88,15 @@ impl Violation for MultipleSpacesBeforeOperator { #[violation] pub struct TabAfterOperator; -impl Violation for TabAfterOperator { +impl AlwaysFixableViolation for TabAfterOperator { #[derive_message_formats] fn message(&self) -> String { format!("Tab after operator") } + + fn fix_title(&self) -> String { + format!("Replace with single space") + } } /// ## What it does @@ -138,11 +146,15 @@ impl Violation for MultipleSpacesAfterOperator { #[violation] pub struct TabAfterComma; -impl Violation for TabAfterComma { +impl AlwaysFixableViolation for TabAfterComma { #[derive_message_formats] fn message(&self) -> String { format!("Tab after comma") } + + fn fix_title(&self) -> String { + format!("Replace with single space") + } } /// ## What it does @@ -181,10 +193,15 @@ pub(crate) fn space_around_operator(line: &LogicalLine, context: &mut LogicalLin if !after_operator { match line.leading_whitespace(token) { (Whitespace::Tab, offset) => { - context.push( + let mut diagnostic = Diagnostic::new( TabBeforeOperator, TextRange::at(token.start() - offset, offset), ); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + " ".to_string(), + TextRange::at(token.start() - offset, offset), + ))); + context.push_diagnostic(diagnostic); } (Whitespace::Many, offset) => { context.push( @@ -198,7 +215,13 @@ pub(crate) fn space_around_operator(line: &LogicalLine, context: &mut LogicalLin match line.trailing_whitespace(token) { (Whitespace::Tab, len) => { - context.push(TabAfterOperator, TextRange::at(token.end(), len)); + let mut diagnostic = + Diagnostic::new(TabAfterOperator, TextRange::at(token.end(), len)); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + " ".to_string(), + TextRange::at(token.end(), len), + ))); + context.push_diagnostic(diagnostic); } (Whitespace::Many, len) => { context.push(MultipleSpacesAfterOperator, TextRange::at(token.end(), len)); @@ -217,7 +240,13 @@ pub(crate) fn space_after_comma(line: &LogicalLine, context: &mut LogicalLinesCo if matches!(token.kind(), TokenKind::Comma) { match line.trailing_whitespace(token) { (Whitespace::Tab, len) => { - context.push(TabAfterComma, TextRange::at(token.end(), len)); + let mut diagnostic = + Diagnostic::new(TabAfterComma, TextRange::at(token.end(), len)); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + " ".to_string(), + TextRange::at(token.end(), len), + ))); + context.push_diagnostic(diagnostic); } (Whitespace::Many, len) => { context.push(MultipleSpacesAfterComma, TextRange::at(token.end(), len)); diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_around_keywords.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_around_keywords.rs index 650f92797d829..cc3e86cf8be6a 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_around_keywords.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_around_keywords.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::Violation; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::{Ranged, TextRange}; @@ -74,11 +74,15 @@ impl Violation for MultipleSpacesBeforeKeyword { #[violation] pub struct TabAfterKeyword; -impl Violation for TabAfterKeyword { +impl AlwaysFixableViolation for TabAfterKeyword { #[derive_message_formats] fn message(&self) -> String { format!("Tab after keyword") } + + fn fix_title(&self) -> String { + format!("Replace with single space") + } } /// ## What it does @@ -99,11 +103,15 @@ impl Violation for TabAfterKeyword { #[violation] pub struct TabBeforeKeyword; -impl Violation for TabBeforeKeyword { +impl AlwaysFixableViolation for TabBeforeKeyword { #[derive_message_formats] fn message(&self) -> String { format!("Tab before keyword") } + + fn fix_title(&self) -> String { + format!("Replace with single space") + } } /// E271, E272, E273, E274 @@ -117,7 +125,15 @@ pub(crate) fn whitespace_around_keywords(line: &LogicalLine, context: &mut Logic match line.leading_whitespace(token) { (Whitespace::Tab, offset) => { let start = token.start(); - context.push(TabBeforeKeyword, TextRange::at(start - offset, offset)); + let mut diagnostic = Diagnostic::new( + TabBeforeKeyword, + TextRange::at(start - offset, offset), + ); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + " ".to_string(), + TextRange::at(start - offset, offset), + ))); + context.push_diagnostic(diagnostic); } (Whitespace::Many, offset) => { let start = token.start(); @@ -132,7 +148,13 @@ pub(crate) fn whitespace_around_keywords(line: &LogicalLine, context: &mut Logic match line.trailing_whitespace(token) { (Whitespace::Tab, len) => { - context.push(TabAfterKeyword, TextRange::at(token.end(), len)); + let mut diagnostic = + Diagnostic::new(TabAfterKeyword, TextRange::at(token.end(), len)); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + " ".to_string(), + TextRange::at(token.end(), len), + ))); + context.push_diagnostic(diagnostic); } (Whitespace::Many, len) => { context.push(MultipleSpacesAfterKeyword, TextRange::at(token.end(), len)); diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_around_named_parameter_equals.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_around_named_parameter_equals.rs index 1c18184888437..f5baea15080dc 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_around_named_parameter_equals.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_around_named_parameter_equals.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::Violation; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_parser::TokenKind; use ruff_text_size::{Ranged, TextRange, TextSize}; @@ -26,7 +26,7 @@ use crate::rules::pycodestyle::rules::logical_lines::{LogicalLine, LogicalLineTo /// /// Use instead: /// ```python -/// def add(a = 0) -> int: +/// def add(a=0) -> int: /// return a + 1 /// ``` /// @@ -69,11 +69,15 @@ impl Violation for UnexpectedSpacesAroundKeywordParameterEquals { #[violation] pub struct MissingWhitespaceAroundParameterEquals; -impl Violation for MissingWhitespaceAroundParameterEquals { +impl AlwaysFixableViolation for MissingWhitespaceAroundParameterEquals { #[derive_message_formats] fn message(&self) -> String { format!("Missing whitespace around parameter equals") } + + fn fix_title(&self) -> String { + format!("Add missing whitespace") + } } fn is_in_def(tokens: &[LogicalLineToken]) -> bool { @@ -94,6 +98,7 @@ pub(crate) fn whitespace_around_named_parameter_equals( context: &mut LogicalLinesContext, ) { let mut parens = 0u32; + let mut fstrings = 0u32; let mut annotated_func_arg = false; let mut prev_end = TextSize::default(); @@ -108,6 +113,8 @@ pub(crate) fn whitespace_around_named_parameter_equals( } match kind { + TokenKind::FStringStart => fstrings += 1, + TokenKind::FStringEnd => fstrings = fstrings.saturating_sub(1), TokenKind::Lpar | TokenKind::Lsqb => { parens = parens.saturating_add(1); } @@ -124,11 +131,17 @@ pub(crate) fn whitespace_around_named_parameter_equals( TokenKind::Comma if parens == 1 => { annotated_func_arg = false; } - TokenKind::Equal if parens > 0 => { + TokenKind::Equal if parens > 0 && fstrings == 0 => { if annotated_func_arg && parens == 1 { let start = token.start(); if start == prev_end && prev_end != TextSize::new(0) { - context.push(MissingWhitespaceAroundParameterEquals, token.range()); + let mut diagnostic = + Diagnostic::new(MissingWhitespaceAroundParameterEquals, token.range); + diagnostic.set_fix(Fix::safe_edit(Edit::insertion( + " ".to_string(), + token.start(), + ))); + context.push_diagnostic(diagnostic); } while let Some(next) = iter.peek() { @@ -138,7 +151,15 @@ pub(crate) fn whitespace_around_named_parameter_equals( let next_start = next.start(); if next_start == token.end() { - context.push(MissingWhitespaceAroundParameterEquals, token.range()); + let mut diagnostic = Diagnostic::new( + MissingWhitespaceAroundParameterEquals, + token.range, + ); + diagnostic.set_fix(Fix::safe_edit(Edit::insertion( + " ".to_string(), + token.end(), + ))); + context.push_diagnostic(diagnostic); } break; } diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_before_comment.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_before_comment.rs index 366fc675b2311..235c12f7b6c65 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_before_comment.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_before_comment.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::Violation; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_parser::TokenKind; use ruff_python_trivia::PythonWhitespace; @@ -30,11 +30,15 @@ use crate::rules::pycodestyle::rules::logical_lines::LogicalLine; #[violation] pub struct TooFewSpacesBeforeInlineComment; -impl Violation for TooFewSpacesBeforeInlineComment { +impl AlwaysFixableViolation for TooFewSpacesBeforeInlineComment { #[derive_message_formats] fn message(&self) -> String { format!("Insert at least two spaces before an inline comment") } + + fn fix_title(&self) -> String { + format!("Insert spaces") + } } /// ## What it does @@ -155,10 +159,15 @@ pub(crate) fn whitespace_before_comment( let is_inline_comment = !line_text.trim_whitespace().is_empty(); if is_inline_comment { if range.start() - prev_end < " ".text_len() { - context.push( + let mut diagnostic = Diagnostic::new( TooFewSpacesBeforeInlineComment, TextRange::new(prev_end, range.start()), ); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + " ".to_string(), + TextRange::new(prev_end, range.start()), + ))); + context.push_diagnostic(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_before_parameters.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_before_parameters.rs index 0afe2e8ffb326..0f0dc8763e2a8 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_before_parameters.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/whitespace_before_parameters.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_parser::TokenKind; use ruff_text_size::{Ranged, TextRange, TextSize}; @@ -40,25 +40,21 @@ impl WhitespaceBeforeParameters { } } -impl AlwaysAutofixableViolation for WhitespaceBeforeParameters { +impl AlwaysFixableViolation for WhitespaceBeforeParameters { #[derive_message_formats] fn message(&self) -> String { let bracket = self.bracket_text(); format!("Whitespace before '{bracket}'") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let bracket = self.bracket_text(); format!("Removed whitespace before '{bracket}'") } } /// E211 -pub(crate) fn whitespace_before_parameters( - line: &LogicalLine, - autofix: bool, - context: &mut LogicalLinesContext, -) { +pub(crate) fn whitespace_before_parameters(line: &LogicalLine, context: &mut LogicalLinesContext) { let previous = line.tokens().first().unwrap(); let mut pre_pre_kind: Option = None; @@ -81,10 +77,7 @@ pub(crate) fn whitespace_before_parameters( let kind: WhitespaceBeforeParameters = WhitespaceBeforeParameters { bracket: kind }; let mut diagnostic = Diagnostic::new(kind, TextRange::new(start, end)); - - if autofix { - diagnostic.set_fix(Fix::automatic(Edit::deletion(start, end))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::deletion(start, end))); context.push_diagnostic(diagnostic); } pre_pre_kind = Some(prev_token); diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/missing_newline_at_end_of_file.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/missing_newline_at_end_of_file.rs index be44b9951fcea..22f9f64ea6577 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/missing_newline_at_end_of_file.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/missing_newline_at_end_of_file.rs @@ -1,6 +1,6 @@ use ruff_text_size::{TextLen, TextRange}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_codegen::Stylist; use ruff_source_file::Locator; @@ -24,13 +24,13 @@ use ruff_source_file::Locator; #[violation] pub struct MissingNewlineAtEndOfFile; -impl AlwaysAutofixableViolation for MissingNewlineAtEndOfFile { +impl AlwaysFixableViolation for MissingNewlineAtEndOfFile { #[derive_message_formats] fn message(&self) -> String { format!("No newline at end of file") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Add trailing newline".to_string() } } @@ -39,7 +39,6 @@ impl AlwaysAutofixableViolation for MissingNewlineAtEndOfFile { pub(crate) fn no_newline_at_end_of_file( locator: &Locator, stylist: &Stylist, - autofix: bool, ) -> Option { let source = locator.contents(); @@ -55,12 +54,10 @@ pub(crate) fn no_newline_at_end_of_file( let range = TextRange::empty(locator.contents().text_len()); let mut diagnostic = Diagnostic::new(MissingNewlineAtEndOfFile, range); - if autofix { - diagnostic.set_fix(Fix::automatic(Edit::insertion( - stylist.line_ending().to_string(), - range.start(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::insertion( + stylist.line_ending().to_string(), + range.start(), + ))); return Some(diagnostic); } None diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/not_tests.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/not_tests.rs index 908ac0baa36cf..c870d2db25620 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/not_tests.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/not_tests.rs @@ -1,12 +1,12 @@ -use crate::autofix::edits::pad; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use crate::fix::edits::pad; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::helpers::generate_comparison; use ruff_python_ast::{self as ast, CmpOp, Expr}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::{AsRule, Rule}; -use crate::rules::pycodestyle::helpers::generate_comparison; +use crate::registry::Rule; /// ## What it does /// Checks for negative comparison using `not {foo} in {bar}`. @@ -30,13 +30,13 @@ use crate::rules::pycodestyle::helpers::generate_comparison; #[violation] pub struct NotInTest; -impl AlwaysAutofixableViolation for NotInTest { +impl AlwaysFixableViolation for NotInTest { #[derive_message_formats] fn message(&self) -> String { format!("Test for membership should be `not in`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Convert to `not in`".to_string() } } @@ -63,13 +63,13 @@ impl AlwaysAutofixableViolation for NotInTest { #[violation] pub struct NotIsTest; -impl AlwaysAutofixableViolation for NotIsTest { +impl AlwaysFixableViolation for NotIsTest { #[derive_message_formats] fn message(&self) -> String { format!("Test for object identity should be `is not`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Convert to `is not`".to_string() } } @@ -94,46 +94,42 @@ pub(crate) fn not_tests(checker: &mut Checker, unary_op: &ast::ExprUnaryOp) { [CmpOp::In] => { if checker.enabled(Rule::NotInTest) { let mut diagnostic = Diagnostic::new(NotInTest, unary_op.operand.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - pad( - generate_comparison( - left, - &[CmpOp::NotIn], - comparators, - unary_op.into(), - checker.indexer().comment_ranges(), - checker.locator(), - ), - unary_op.range(), + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + pad( + generate_comparison( + left, + &[CmpOp::NotIn], + comparators, + unary_op.into(), + checker.indexer().comment_ranges(), checker.locator(), ), unary_op.range(), - ))); - } + checker.locator(), + ), + unary_op.range(), + ))); checker.diagnostics.push(diagnostic); } } [CmpOp::Is] => { if checker.enabled(Rule::NotIsTest) { let mut diagnostic = Diagnostic::new(NotIsTest, unary_op.operand.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - pad( - generate_comparison( - left, - &[CmpOp::IsNot], - comparators, - unary_op.into(), - checker.indexer().comment_ranges(), - checker.locator(), - ), - unary_op.range(), + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + pad( + generate_comparison( + left, + &[CmpOp::IsNot], + comparators, + unary_op.into(), + checker.indexer().comment_ranges(), checker.locator(), ), unary_op.range(), - ))); - } + checker.locator(), + ), + unary_op.range(), + ))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/tab_indentation.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/tab_indentation.rs index c710533e96792..153caab648456 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/tab_indentation.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/tab_indentation.rs @@ -26,7 +26,15 @@ use ruff_text_size::{TextLen, TextRange, TextSize}; /// a = 1 /// ``` /// +/// ## Formatter compatibility +/// We recommend against using this rule alongside the [formatter]. The +/// formatter enforces consistent indentation, making the rule redundant. +/// +/// The rule is also incompatible with the [formatter] when using +/// `format.indent-style="tab"`. +/// /// [PEP 8]: https://peps.python.org/pep-0008/#tabs-or-spaces +/// [formatter]: https://docs.astral.sh/ruff/formatter #[violation] pub struct TabIndentation; diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/trailing_whitespace.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/trailing_whitespace.rs index 88483409e5850..7df8ee2eb5986 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/trailing_whitespace.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/trailing_whitespace.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_index::Indexer; use ruff_source_file::{Line, Locator}; @@ -28,13 +28,13 @@ use crate::settings::LinterSettings; #[violation] pub struct TrailingWhitespace; -impl AlwaysAutofixableViolation for TrailingWhitespace { +impl AlwaysFixableViolation for TrailingWhitespace { #[derive_message_formats] fn message(&self) -> String { format!("Trailing whitespace") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove trailing whitespace".to_string() } } @@ -60,13 +60,13 @@ impl AlwaysAutofixableViolation for TrailingWhitespace { #[violation] pub struct BlankLineWithWhitespace; -impl AlwaysAutofixableViolation for BlankLineWithWhitespace { +impl AlwaysFixableViolation for BlankLineWithWhitespace { #[derive_message_formats] fn message(&self) -> String { format!("Blank line contains whitespace") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove whitespace from blank line".to_string() } } @@ -90,23 +90,19 @@ pub(crate) fn trailing_whitespace( if range == line.range() { if settings.rules.enabled(Rule::BlankLineWithWhitespace) { let mut diagnostic = Diagnostic::new(BlankLineWithWhitespace, range); - if settings.rules.should_fix(Rule::BlankLineWithWhitespace) { - // Remove any preceding continuations, to avoid introducing a potential - // syntax error. - diagnostic.set_fix(Fix::automatic(Edit::range_deletion(TextRange::new( - indexer - .preceded_by_continuations(line.start(), locator) - .unwrap_or(range.start()), - range.end(), - )))); - } + // Remove any preceding continuations, to avoid introducing a potential + // syntax error. + diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(TextRange::new( + indexer + .preceded_by_continuations(line.start(), locator) + .unwrap_or(range.start()), + range.end(), + )))); return Some(diagnostic); } } else if settings.rules.enabled(Rule::TrailingWhitespace) { let mut diagnostic = Diagnostic::new(TrailingWhitespace, range); - if settings.rules.should_fix(Rule::TrailingWhitespace) { - diagnostic.set_fix(Fix::automatic(Edit::range_deletion(range))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(range))); return Some(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/type_comparison.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/type_comparison.rs index b8ff329a3ee5b..1a7c3a67c7d5c 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/type_comparison.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/type_comparison.rs @@ -3,26 +3,31 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::is_const_none; use ruff_python_ast::{self as ast, CmpOp, Expr}; +use ruff_python_semantic::SemanticModel; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; +use crate::settings::types::PreviewMode; /// ## What it does -/// Checks for object type comparisons without using `isinstance()`. +/// Checks for object type comparisons using `==` and other comparison +/// operators. /// /// ## Why is this bad? -/// Do not compare types directly. +/// Unlike a direct type comparison, `isinstance` will also check if an object +/// is an instance of a class or a subclass thereof. /// -/// When checking if an object is a instance of a certain type, keep in mind -/// that it might be subclassed. For example, `bool` inherits from `int`, and -/// `Exception` inherits from `BaseException`. +/// Under [preview mode](https://docs.astral.sh/ruff/preview), this rule also +/// allows for direct type comparisons using `is` and `is not`, to check for +/// exact type equality (while still forbidding comparisons using `==` and +/// `!=`). /// /// ## Example /// ```python -/// if type(obj) is type(1): +/// if type(obj) == type(1): /// pass /// -/// if type(obj) is int: +/// if type(obj) == int: /// pass /// ``` /// @@ -32,17 +37,31 @@ use crate::checkers::ast::Checker; /// pass /// ``` #[violation] -pub struct TypeComparison; +pub struct TypeComparison { + preview: PreviewMode, +} impl Violation for TypeComparison { #[derive_message_formats] fn message(&self) -> String { - format!("Do not compare types, use `isinstance()`") + match self.preview { + PreviewMode::Disabled => format!("Do not compare types, use `isinstance()`"), + PreviewMode::Enabled => format!( + "Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks" + ), + } } } /// E721 pub(crate) fn type_comparison(checker: &mut Checker, compare: &ast::ExprCompare) { + match checker.settings.preview { + PreviewMode::Disabled => deprecated_type_comparison(checker, compare), + PreviewMode::Enabled => preview_type_comparison(checker, compare), + } +} + +fn deprecated_type_comparison(checker: &mut Checker, compare: &ast::ExprCompare) { for ((left, right), op) in std::iter::once(compare.left.as_ref()) .chain(compare.comparators.iter()) .tuple_windows() @@ -82,9 +101,12 @@ pub(crate) fn type_comparison(checker: &mut Checker, compare: &ast::ExprCompare) .first() .is_some_and(|arg| !arg.is_name_expr() && !is_const_none(arg)) { - checker - .diagnostics - .push(Diagnostic::new(TypeComparison, compare.range())); + checker.diagnostics.push(Diagnostic::new( + TypeComparison { + preview: PreviewMode::Disabled, + }, + compare.range(), + )); } } } @@ -95,9 +117,12 @@ pub(crate) fn type_comparison(checker: &mut Checker, compare: &ast::ExprCompare) .resolve_call_path(value.as_ref()) .is_some_and(|call_path| matches!(call_path.as_slice(), ["types", ..])) { - checker - .diagnostics - .push(Diagnostic::new(TypeComparison, compare.range())); + checker.diagnostics.push(Diagnostic::new( + TypeComparison { + preview: PreviewMode::Disabled, + }, + compare.range(), + )); } } Expr::Name(ast::ExprName { id, .. }) => { @@ -115,12 +140,66 @@ pub(crate) fn type_comparison(checker: &mut Checker, compare: &ast::ExprCompare) | "set" ) && checker.semantic().is_builtin(id) { - checker - .diagnostics - .push(Diagnostic::new(TypeComparison, compare.range())); + checker.diagnostics.push(Diagnostic::new( + TypeComparison { + preview: PreviewMode::Disabled, + }, + compare.range(), + )); } } _ => {} } } } + +pub(crate) fn preview_type_comparison(checker: &mut Checker, compare: &ast::ExprCompare) { + for (left, right) in std::iter::once(compare.left.as_ref()) + .chain(compare.comparators.iter()) + .tuple_windows() + .zip(compare.ops.iter()) + .filter(|(_, op)| matches!(op, CmpOp::Eq | CmpOp::NotEq)) + .map(|((left, right), _)| (left, right)) + { + if is_type(left, checker.semantic()) || is_type(right, checker.semantic()) { + checker.diagnostics.push(Diagnostic::new( + TypeComparison { + preview: PreviewMode::Enabled, + }, + compare.range(), + )); + } + } +} + +/// Returns `true` if the [`Expr`] is known to evaluate to a type (e.g., `int`, or `type(1)`). +fn is_type(expr: &Expr, semantic: &SemanticModel) -> bool { + match expr { + Expr::Call(ast::ExprCall { + func, arguments, .. + }) => { + // Ex) `type(obj) == type(1)` + let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() else { + return false; + }; + + if !(id == "type" && semantic.is_builtin("type")) { + return false; + }; + + // Allow comparison for types which are not obvious. + arguments + .args + .first() + .is_some_and(|arg| !arg.is_name_expr() && !is_const_none(arg)) + } + Expr::Name(ast::ExprName { id, .. }) => { + // Ex) `type(obj) == int` + matches!( + id.as_str(), + "int" | "str" | "float" | "bool" | "complex" | "bytes" | "list" | "dict" | "set" + ) && semantic.is_builtin(id) + } + _ => false, + } +} diff --git a/crates/ruff_linter/src/rules/pycodestyle/settings.rs b/crates/ruff_linter/src/rules/pycodestyle/settings.rs index 55c9890ac10ce..7990f6a65646d 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/settings.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/settings.rs @@ -6,6 +6,7 @@ use crate::line_width::LineLength; #[derive(Debug, Default, CacheKey)] pub struct Settings { + pub max_line_length: LineLength, pub max_doc_length: Option, pub ignore_overlong_task_comments: bool, } diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E122_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E122_E12.py.snap new file mode 100644 index 0000000000000..d754b53b45286 --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E122_E12.py.snap @@ -0,0 +1,119 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +--- +E12.py:3:1: E122 Continuation line missing indentation or outdented. + | +1 | #: E122 +2 | print("E122", ( +3 | "dent")) + | ^^^^^^ E122 +4 | +5 | #: E122:6:5 E122:7:5 E122:8:1 + | + +E12.py:11:5: E122 Continuation line missing indentation or outdented. + | + 9 | mv ./build/ ./{build}/%(revision)s/ +10 | '''.format( +11 | build='build', + | ^^^^^ E122 +12 | # more stuff +13 | ) + | + +E12.py:12:5: E122 Continuation line missing indentation or outdented. + | +10 | '''.format( +11 | build='build', +12 | # more stuff + | ^^^^^^^^^^^^ E122 +13 | ) +14 | )) + | + +E12.py:13:1: E122 Continuation line missing indentation or outdented. + | +11 | build='build', +12 | # more stuff +13 | ) + | ^ E122 +14 | )) + | + +E12.py:21:1: E122 Continuation line missing indentation or outdented. + | +19 | 'a', 'b', 'c', +20 | 'd', 'e', 'f', +21 | ) + | ^ E122 +22 | +23 | #: E122 + | + +E12.py:25:1: E122 Continuation line missing indentation or outdented. + | +23 | #: E122 +24 | if some_very_very_very_long_variable_name or var \ +25 | or another_very_long_variable_name: + | ^^ E122 +26 | raise Exception() + | + +E12.py:30:1: E122 Continuation line missing indentation or outdented. + | +28 | #: E122 +29 | if some_very_very_very_long_variable_name or var[0] \ +30 | or another_very_long_variable_name: + | ^^ E122 +31 | raise Exception() + | + +E12.py:36:5: E122 Continuation line missing indentation or outdented. + | +34 | if True: +35 | if some_very_very_very_long_variable_name or var \ +36 | or another_very_long_variable_name: + | ^^ E122 +37 | raise Exception() + | + +E12.py:42:5: E122 Continuation line missing indentation or outdented. + | +40 | if True: +41 | if some_very_very_very_long_variable_name or var[0] \ +42 | or another_very_long_variable_name: + | ^^ E122 +43 | raise Exception() + | + +E12.py:48:5: E122 Continuation line missing indentation or outdented. + | +46 | dictionary = { +47 | "is": { +48 | "nested": yes(), + | ^^^^^^^^ E122 +49 | }, +50 | } + | + +E12.py:56:7: E122 Continuation line missing indentation or outdented. + | +54 | scripts=[''], +55 | classifiers=[ +56 | 'Development Status :: 4 - Beta', + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E122 +57 | 'Environment :: Console', +58 | 'Intended Audience :: Developers', + | + +E12.py:63:1: E122 Continuation line missing indentation or outdented. + | +61 | #: E701:1:8 E122:2:1 E203:4:8 E128:5:1 +62 | if True:\ +63 | print(True) + | ^^^^^ E122 +64 | +65 | print(a + | + + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E201_E20.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E201_E20.py.snap index a7eb5c281c10c..14db20f7448f6 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E201_E20.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E201_E20.py.snap @@ -144,4 +144,22 @@ E20.py:81:6: E201 [*] Whitespace after '[' 83 83 | #: Okay 84 84 | x = [ # +E20.py:90:5: E201 [*] Whitespace after '[' + | +88 | # F-strings +89 | f"{ {'a': 1} }" +90 | f"{[ { {'a': 1} } ]}" + | ^ E201 +91 | f"normal { {f"{ { [1, 2] } }" } } normal" + | + = help: Remove whitespace before '[' + +ℹ Fix +87 87 | +88 88 | # F-strings +89 89 | f"{ {'a': 1} }" +90 |-f"{[ { {'a': 1} } ]}" + 90 |+f"{[{ {'a': 1} } ]}" +91 91 | f"normal { {f"{ { [1, 2] } }" } } normal" + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E202_E20.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E202_E20.py.snap index 4382a6f14d62f..6027fbafac460 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E202_E20.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E202_E20.py.snap @@ -126,4 +126,22 @@ E20.py:29:11: E202 [*] Whitespace before ']' 31 31 | spam(ham[1], {eggs: 2}) 32 32 | +E20.py:90:18: E202 [*] Whitespace before ']' + | +88 | # F-strings +89 | f"{ {'a': 1} }" +90 | f"{[ { {'a': 1} } ]}" + | ^ E202 +91 | f"normal { {f"{ { [1, 2] } }" } } normal" + | + = help: Remove whitespace before ']' + +ℹ Fix +87 87 | +88 88 | # F-strings +89 89 | f"{ {'a': 1} }" +90 |-f"{[ { {'a': 1} } ]}" + 90 |+f"{[ { {'a': 1} }]}" +91 91 | f"normal { {f"{ { [1, 2] } }" } } normal" + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E223_E22.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E223_E22.py.snap index 58f50d1a46000..393253b6ec947 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E223_E22.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E223_E22.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E22.py:43:2: E223 Tab before operator +E22.py:43:2: E223 [*] Tab before operator | 41 | #: E223 42 | foobart = 4 @@ -9,5 +9,16 @@ E22.py:43:2: E223 Tab before operator | ^^^ E223 44 | #: | + = help: Replace with single space + +ℹ Fix +40 40 | +41 41 | #: E223 +42 42 | foobart = 4 +43 |-a = 3 # aligned with tab + 43 |+a = 3 # aligned with tab +44 44 | #: +45 45 | +46 46 | diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E224_E22.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E224_E22.py.snap index 59b473485c80a..0bf770a319b8e 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E224_E22.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E224_E22.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E22.py:48:5: E224 Tab after operator +E22.py:48:5: E224 [*] Tab after operator | 47 | #: E224 48 | a += 1 @@ -9,5 +9,16 @@ E22.py:48:5: E224 Tab after operator 49 | b += 1000 50 | #: | + = help: Replace with single space + +ℹ Fix +45 45 | +46 46 | +47 47 | #: E224 +48 |-a += 1 + 48 |+a += 1 +49 49 | b += 1000 +50 50 | #: +51 51 | diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E225_E22.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E225_E22.py.snap index 635b1cdeba280..ff34e177add8d 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E225_E22.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E225_E22.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E22.py:54:11: E225 Missing whitespace around operator +E22.py:54:11: E225 [*] Missing whitespace around operator | 53 | #: E225 54 | submitted +=1 @@ -9,8 +9,19 @@ E22.py:54:11: E225 Missing whitespace around operator 55 | #: E225 56 | submitted+= 1 | + = help: Add missing whitespace -E22.py:56:10: E225 Missing whitespace around operator +ℹ Fix +51 51 | +52 52 | +53 53 | #: E225 +54 |-submitted +=1 + 54 |+submitted += 1 +55 55 | #: E225 +56 56 | submitted+= 1 +57 57 | #: E225 + +E22.py:56:10: E225 [*] Missing whitespace around operator | 54 | submitted +=1 55 | #: E225 @@ -19,8 +30,19 @@ E22.py:56:10: E225 Missing whitespace around operator 57 | #: E225 58 | c =-1 | + = help: Add missing whitespace + +ℹ Fix +53 53 | #: E225 +54 54 | submitted +=1 +55 55 | #: E225 +56 |-submitted+= 1 + 56 |+submitted += 1 +57 57 | #: E225 +58 58 | c =-1 +59 59 | #: E225 -E22.py:58:3: E225 Missing whitespace around operator +E22.py:58:3: E225 [*] Missing whitespace around operator | 56 | submitted+= 1 57 | #: E225 @@ -29,88 +51,19 @@ E22.py:58:3: E225 Missing whitespace around operator 59 | #: E225 60 | x = x /2 - 1 | + = help: Add missing whitespace -E22.py:60:7: E225 Missing whitespace around operator - | -58 | c =-1 -59 | #: E225 -60 | x = x /2 - 1 - | ^ E225 -61 | #: E225 -62 | c = alpha -4 - | - -E22.py:62:11: E225 Missing whitespace around operator - | -60 | x = x /2 - 1 -61 | #: E225 -62 | c = alpha -4 - | ^ E225 -63 | #: E225 -64 | c = alpha- 4 - | - -E22.py:64:10: E225 Missing whitespace around operator - | -62 | c = alpha -4 -63 | #: E225 -64 | c = alpha- 4 - | ^ E225 -65 | #: E225 -66 | z = x **y - | - -E22.py:66:7: E225 Missing whitespace around operator - | -64 | c = alpha- 4 -65 | #: E225 -66 | z = x **y - | ^^ E225 -67 | #: E225 -68 | z = (x + 1) **y - | - -E22.py:68:13: E225 Missing whitespace around operator - | -66 | z = x **y -67 | #: E225 -68 | z = (x + 1) **y - | ^^ E225 -69 | #: E225 -70 | z = (x + 1)** y - | +ℹ Fix +55 55 | #: E225 +56 56 | submitted+= 1 +57 57 | #: E225 +58 |-c =-1 + 58 |+c = -1 +59 59 | #: E225 +60 60 | x = x /2 - 1 +61 61 | #: E225 -E22.py:70:12: E225 Missing whitespace around operator - | -68 | z = (x + 1) **y -69 | #: E225 -70 | z = (x + 1)** y - | ^^ E225 -71 | #: E225 -72 | _1kB = _1MB >>10 - | - -E22.py:72:13: E225 Missing whitespace around operator - | -70 | z = (x + 1)** y -71 | #: E225 -72 | _1kB = _1MB >>10 - | ^^ E225 -73 | #: E225 -74 | _1kB = _1MB>> 10 - | - -E22.py:74:12: E225 Missing whitespace around operator - | -72 | _1kB = _1MB >>10 -73 | #: E225 -74 | _1kB = _1MB>> 10 - | ^^ E225 -75 | #: E225 E225 -76 | i=i+ 1 - | - -E22.py:76:2: E225 Missing whitespace around operator +E22.py:76:2: E225 [*] Missing whitespace around operator | 74 | _1kB = _1MB>> 10 75 | #: E225 E225 @@ -119,18 +72,19 @@ E22.py:76:2: E225 Missing whitespace around operator 77 | #: E225 E225 78 | i=i +1 | + = help: Add missing whitespace -E22.py:76:4: E225 Missing whitespace around operator - | -74 | _1kB = _1MB>> 10 -75 | #: E225 E225 -76 | i=i+ 1 - | ^ E225 -77 | #: E225 E225 -78 | i=i +1 - | +ℹ Fix +73 73 | #: E225 +74 74 | _1kB = _1MB>> 10 +75 75 | #: E225 E225 +76 |-i=i+ 1 + 76 |+i = i+ 1 +77 77 | #: E225 E225 +78 78 | i=i +1 +79 79 | #: E225 -E22.py:78:2: E225 Missing whitespace around operator +E22.py:78:2: E225 [*] Missing whitespace around operator | 76 | i=i+ 1 77 | #: E225 E225 @@ -139,18 +93,19 @@ E22.py:78:2: E225 Missing whitespace around operator 79 | #: E225 80 | i = 1and 1 | + = help: Add missing whitespace -E22.py:78:5: E225 Missing whitespace around operator - | -76 | i=i+ 1 -77 | #: E225 E225 -78 | i=i +1 - | ^ E225 -79 | #: E225 -80 | i = 1and 1 - | +ℹ Fix +75 75 | #: E225 E225 +76 76 | i=i+ 1 +77 77 | #: E225 E225 +78 |-i=i +1 + 78 |+i = i +1 +79 79 | #: E225 +80 80 | i = 1and 1 +81 81 | #: E225 -E22.py:80:6: E225 Missing whitespace around operator +E22.py:80:6: E225 [*] Missing whitespace around operator | 78 | i=i +1 79 | #: E225 @@ -159,8 +114,19 @@ E22.py:80:6: E225 Missing whitespace around operator 81 | #: E225 82 | i = 1or 0 | + = help: Add missing whitespace -E22.py:82:6: E225 Missing whitespace around operator +ℹ Fix +77 77 | #: E225 E225 +78 78 | i=i +1 +79 79 | #: E225 +80 |-i = 1and 1 + 80 |+i = 1 and 1 +81 81 | #: E225 +82 82 | i = 1or 0 +83 83 | #: E225 + +E22.py:82:6: E225 [*] Missing whitespace around operator | 80 | i = 1and 1 81 | #: E225 @@ -169,8 +135,19 @@ E22.py:82:6: E225 Missing whitespace around operator 83 | #: E225 84 | 1is 1 | + = help: Add missing whitespace + +ℹ Fix +79 79 | #: E225 +80 80 | i = 1and 1 +81 81 | #: E225 +82 |-i = 1or 0 + 82 |+i = 1 or 0 +83 83 | #: E225 +84 84 | 1is 1 +85 85 | #: E225 -E22.py:84:2: E225 Missing whitespace around operator +E22.py:84:2: E225 [*] Missing whitespace around operator | 82 | i = 1or 0 83 | #: E225 @@ -179,8 +156,19 @@ E22.py:84:2: E225 Missing whitespace around operator 85 | #: E225 86 | 1in [] | + = help: Add missing whitespace -E22.py:86:2: E225 Missing whitespace around operator +ℹ Fix +81 81 | #: E225 +82 82 | i = 1or 0 +83 83 | #: E225 +84 |-1is 1 + 84 |+1 is 1 +85 85 | #: E225 +86 86 | 1in [] +87 87 | #: E225 + +E22.py:86:2: E225 [*] Missing whitespace around operator | 84 | 1is 1 85 | #: E225 @@ -189,28 +177,19 @@ E22.py:86:2: E225 Missing whitespace around operator 87 | #: E225 88 | i = 1 @2 | + = help: Add missing whitespace -E22.py:88:7: E225 Missing whitespace around operator - | -86 | 1in [] -87 | #: E225 -88 | i = 1 @2 - | ^ E225 -89 | #: E225 -90 | i = 1@ 2 - | - -E22.py:90:6: E225 Missing whitespace around operator - | -88 | i = 1 @2 -89 | #: E225 -90 | i = 1@ 2 - | ^ E225 -91 | #: E225 E226 -92 | i=i+1 - | +ℹ Fix +83 83 | #: E225 +84 84 | 1is 1 +85 85 | #: E225 +86 |-1in [] + 86 |+1 in [] +87 87 | #: E225 +88 88 | i = 1 @2 +89 89 | #: E225 -E22.py:92:2: E225 Missing whitespace around operator +E22.py:92:2: E225 [*] Missing whitespace around operator | 90 | i = 1@ 2 91 | #: E225 E226 @@ -219,8 +198,19 @@ E22.py:92:2: E225 Missing whitespace around operator 93 | #: E225 E226 94 | i =i+1 | + = help: Add missing whitespace + +ℹ Fix +89 89 | #: E225 +90 90 | i = 1@ 2 +91 91 | #: E225 E226 +92 |-i=i+1 + 92 |+i = i+1 +93 93 | #: E225 E226 +94 94 | i =i+1 +95 95 | #: E225 E226 -E22.py:94:3: E225 Missing whitespace around operator +E22.py:94:3: E225 [*] Missing whitespace around operator | 92 | i=i+1 93 | #: E225 E226 @@ -229,8 +219,19 @@ E22.py:94:3: E225 Missing whitespace around operator 95 | #: E225 E226 96 | i= i+1 | + = help: Add missing whitespace -E22.py:96:2: E225 Missing whitespace around operator +ℹ Fix +91 91 | #: E225 E226 +92 92 | i=i+1 +93 93 | #: E225 E226 +94 |-i =i+1 + 94 |+i = i+1 +95 95 | #: E225 E226 +96 96 | i= i+1 +97 97 | #: E225 E226 + +E22.py:96:2: E225 [*] Missing whitespace around operator | 94 | i =i+1 95 | #: E225 E226 @@ -239,34 +240,16 @@ E22.py:96:2: E225 Missing whitespace around operator 97 | #: E225 E226 98 | c = (a +b)*(a - b) | - -E22.py:98:8: E225 Missing whitespace around operator - | - 96 | i= i+1 - 97 | #: E225 E226 - 98 | c = (a +b)*(a - b) - | ^ E225 - 99 | #: E225 E226 -100 | c = (a+ b)*(a - b) - | - -E22.py:100:7: E225 Missing whitespace around operator - | - 98 | c = (a +b)*(a - b) - 99 | #: E225 E226 -100 | c = (a+ b)*(a - b) - | ^ E225 -101 | #: - | - -E22.py:154:11: E225 Missing whitespace around operator - | -152 | func2(lambda a, b=h[:], c=0: (a, b, c)) -153 | if not -5 < x < +5: -154 | print >>sys.stderr, "x is out of range." - | ^^ E225 -155 | print >> sys.stdout, "x is an integer." -156 | x = x / 2 - 1 - | + = help: Add missing whitespace + +ℹ Fix +93 93 | #: E225 E226 +94 94 | i =i+1 +95 95 | #: E225 E226 +96 |-i= i+1 + 96 |+i = i+1 +97 97 | #: E225 E226 +98 98 | c = (a +b)*(a - b) +99 99 | #: E225 E226 diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E226_E22.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E226_E22.py.snap index 56033e4665dfa..622a32ccd4e99 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E226_E22.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E226_E22.py.snap @@ -1,7 +1,217 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E22.py:92:4: E226 Missing whitespace around arithmetic operator +E22.py:60:7: E226 [*] Missing whitespace around arithmetic operator + | +58 | c =-1 +59 | #: E225 +60 | x = x /2 - 1 + | ^ E226 +61 | #: E225 +62 | c = alpha -4 + | + = help: Add missing whitespace + +ℹ Fix +57 57 | #: E225 +58 58 | c =-1 +59 59 | #: E225 +60 |-x = x /2 - 1 + 60 |+x = x / 2 - 1 +61 61 | #: E225 +62 62 | c = alpha -4 +63 63 | #: E225 + +E22.py:62:11: E226 [*] Missing whitespace around arithmetic operator + | +60 | x = x /2 - 1 +61 | #: E225 +62 | c = alpha -4 + | ^ E226 +63 | #: E225 +64 | c = alpha- 4 + | + = help: Add missing whitespace + +ℹ Fix +59 59 | #: E225 +60 60 | x = x /2 - 1 +61 61 | #: E225 +62 |-c = alpha -4 + 62 |+c = alpha - 4 +63 63 | #: E225 +64 64 | c = alpha- 4 +65 65 | #: E225 + +E22.py:64:10: E226 [*] Missing whitespace around arithmetic operator + | +62 | c = alpha -4 +63 | #: E225 +64 | c = alpha- 4 + | ^ E226 +65 | #: E225 +66 | z = x **y + | + = help: Add missing whitespace + +ℹ Fix +61 61 | #: E225 +62 62 | c = alpha -4 +63 63 | #: E225 +64 |-c = alpha- 4 + 64 |+c = alpha - 4 +65 65 | #: E225 +66 66 | z = x **y +67 67 | #: E225 + +E22.py:66:7: E226 [*] Missing whitespace around arithmetic operator + | +64 | c = alpha- 4 +65 | #: E225 +66 | z = x **y + | ^^ E226 +67 | #: E225 +68 | z = (x + 1) **y + | + = help: Add missing whitespace + +ℹ Fix +63 63 | #: E225 +64 64 | c = alpha- 4 +65 65 | #: E225 +66 |-z = x **y + 66 |+z = x ** y +67 67 | #: E225 +68 68 | z = (x + 1) **y +69 69 | #: E225 + +E22.py:68:13: E226 [*] Missing whitespace around arithmetic operator + | +66 | z = x **y +67 | #: E225 +68 | z = (x + 1) **y + | ^^ E226 +69 | #: E225 +70 | z = (x + 1)** y + | + = help: Add missing whitespace + +ℹ Fix +65 65 | #: E225 +66 66 | z = x **y +67 67 | #: E225 +68 |-z = (x + 1) **y + 68 |+z = (x + 1) ** y +69 69 | #: E225 +70 70 | z = (x + 1)** y +71 71 | #: E225 + +E22.py:70:12: E226 [*] Missing whitespace around arithmetic operator + | +68 | z = (x + 1) **y +69 | #: E225 +70 | z = (x + 1)** y + | ^^ E226 +71 | #: E225 +72 | _1kB = _1MB >>10 + | + = help: Add missing whitespace + +ℹ Fix +67 67 | #: E225 +68 68 | z = (x + 1) **y +69 69 | #: E225 +70 |-z = (x + 1)** y + 70 |+z = (x + 1) ** y +71 71 | #: E225 +72 72 | _1kB = _1MB >>10 +73 73 | #: E225 + +E22.py:76:4: E226 [*] Missing whitespace around arithmetic operator + | +74 | _1kB = _1MB>> 10 +75 | #: E225 E225 +76 | i=i+ 1 + | ^ E226 +77 | #: E225 E225 +78 | i=i +1 + | + = help: Add missing whitespace + +ℹ Fix +73 73 | #: E225 +74 74 | _1kB = _1MB>> 10 +75 75 | #: E225 E225 +76 |-i=i+ 1 + 76 |+i=i + 1 +77 77 | #: E225 E225 +78 78 | i=i +1 +79 79 | #: E225 + +E22.py:78:5: E226 [*] Missing whitespace around arithmetic operator + | +76 | i=i+ 1 +77 | #: E225 E225 +78 | i=i +1 + | ^ E226 +79 | #: E225 +80 | i = 1and 1 + | + = help: Add missing whitespace + +ℹ Fix +75 75 | #: E225 E225 +76 76 | i=i+ 1 +77 77 | #: E225 E225 +78 |-i=i +1 + 78 |+i=i + 1 +79 79 | #: E225 +80 80 | i = 1and 1 +81 81 | #: E225 + +E22.py:88:7: E226 [*] Missing whitespace around arithmetic operator + | +86 | 1in [] +87 | #: E225 +88 | i = 1 @2 + | ^ E226 +89 | #: E225 +90 | i = 1@ 2 + | + = help: Add missing whitespace + +ℹ Fix +85 85 | #: E225 +86 86 | 1in [] +87 87 | #: E225 +88 |-i = 1 @2 + 88 |+i = 1 @ 2 +89 89 | #: E225 +90 90 | i = 1@ 2 +91 91 | #: E225 E226 + +E22.py:90:6: E226 [*] Missing whitespace around arithmetic operator + | +88 | i = 1 @2 +89 | #: E225 +90 | i = 1@ 2 + | ^ E226 +91 | #: E225 E226 +92 | i=i+1 + | + = help: Add missing whitespace + +ℹ Fix +87 87 | #: E225 +88 88 | i = 1 @2 +89 89 | #: E225 +90 |-i = 1@ 2 + 90 |+i = 1 @ 2 +91 91 | #: E225 E226 +92 92 | i=i+1 +93 93 | #: E225 E226 + +E22.py:92:4: E226 [*] Missing whitespace around arithmetic operator | 90 | i = 1@ 2 91 | #: E225 E226 @@ -10,8 +220,19 @@ E22.py:92:4: E226 Missing whitespace around arithmetic operator 93 | #: E225 E226 94 | i =i+1 | + = help: Add missing whitespace + +ℹ Fix +89 89 | #: E225 +90 90 | i = 1@ 2 +91 91 | #: E225 E226 +92 |-i=i+1 + 92 |+i=i + 1 +93 93 | #: E225 E226 +94 94 | i =i+1 +95 95 | #: E225 E226 -E22.py:94:5: E226 Missing whitespace around arithmetic operator +E22.py:94:5: E226 [*] Missing whitespace around arithmetic operator | 92 | i=i+1 93 | #: E225 E226 @@ -20,8 +241,19 @@ E22.py:94:5: E226 Missing whitespace around arithmetic operator 95 | #: E225 E226 96 | i= i+1 | + = help: Add missing whitespace -E22.py:96:5: E226 Missing whitespace around arithmetic operator +ℹ Fix +91 91 | #: E225 E226 +92 92 | i=i+1 +93 93 | #: E225 E226 +94 |-i =i+1 + 94 |+i =i + 1 +95 95 | #: E225 E226 +96 96 | i= i+1 +97 97 | #: E225 E226 + +E22.py:96:5: E226 [*] Missing whitespace around arithmetic operator | 94 | i =i+1 95 | #: E225 E226 @@ -30,8 +262,40 @@ E22.py:96:5: E226 Missing whitespace around arithmetic operator 97 | #: E225 E226 98 | c = (a +b)*(a - b) | + = help: Add missing whitespace + +ℹ Fix +93 93 | #: E225 E226 +94 94 | i =i+1 +95 95 | #: E225 E226 +96 |-i= i+1 + 96 |+i= i + 1 +97 97 | #: E225 E226 +98 98 | c = (a +b)*(a - b) +99 99 | #: E225 E226 -E22.py:98:11: E226 Missing whitespace around arithmetic operator +E22.py:98:8: E226 [*] Missing whitespace around arithmetic operator + | + 96 | i= i+1 + 97 | #: E225 E226 + 98 | c = (a +b)*(a - b) + | ^ E226 + 99 | #: E225 E226 +100 | c = (a+ b)*(a - b) + | + = help: Add missing whitespace + +ℹ Fix +95 95 | #: E225 E226 +96 96 | i= i+1 +97 97 | #: E225 E226 +98 |-c = (a +b)*(a - b) + 98 |+c = (a + b)*(a - b) +99 99 | #: E225 E226 +100 100 | c = (a+ b)*(a - b) +101 101 | #: + +E22.py:98:11: E226 [*] Missing whitespace around arithmetic operator | 96 | i= i+1 97 | #: E225 E226 @@ -40,8 +304,39 @@ E22.py:98:11: E226 Missing whitespace around arithmetic operator 99 | #: E225 E226 100 | c = (a+ b)*(a - b) | + = help: Add missing whitespace + +ℹ Fix +95 95 | #: E225 E226 +96 96 | i= i+1 +97 97 | #: E225 E226 +98 |-c = (a +b)*(a - b) + 98 |+c = (a +b) * (a - b) +99 99 | #: E225 E226 +100 100 | c = (a+ b)*(a - b) +101 101 | #: -E22.py:100:11: E226 Missing whitespace around arithmetic operator +E22.py:100:7: E226 [*] Missing whitespace around arithmetic operator + | + 98 | c = (a +b)*(a - b) + 99 | #: E225 E226 +100 | c = (a+ b)*(a - b) + | ^ E226 +101 | #: + | + = help: Add missing whitespace + +ℹ Fix +97 97 | #: E225 E226 +98 98 | c = (a +b)*(a - b) +99 99 | #: E225 E226 +100 |-c = (a+ b)*(a - b) + 100 |+c = (a + b)*(a - b) +101 101 | #: +102 102 | +103 103 | #: E226 + +E22.py:100:11: E226 [*] Missing whitespace around arithmetic operator | 98 | c = (a +b)*(a - b) 99 | #: E225 E226 @@ -49,8 +344,19 @@ E22.py:100:11: E226 Missing whitespace around arithmetic operator | ^ E226 101 | #: | + = help: Add missing whitespace + +ℹ Fix +97 97 | #: E225 E226 +98 98 | c = (a +b)*(a - b) +99 99 | #: E225 E226 +100 |-c = (a+ b)*(a - b) + 100 |+c = (a+ b) * (a - b) +101 101 | #: +102 102 | +103 103 | #: E226 -E22.py:104:6: E226 Missing whitespace around arithmetic operator +E22.py:104:6: E226 [*] Missing whitespace around arithmetic operator | 103 | #: E226 104 | z = 2//30 @@ -58,8 +364,19 @@ E22.py:104:6: E226 Missing whitespace around arithmetic operator 105 | #: E226 E226 106 | c = (a+b) * (a-b) | + = help: Add missing whitespace -E22.py:106:7: E226 Missing whitespace around arithmetic operator +ℹ Fix +101 101 | #: +102 102 | +103 103 | #: E226 +104 |-z = 2//30 + 104 |+z = 2 // 30 +105 105 | #: E226 E226 +106 106 | c = (a+b) * (a-b) +107 107 | #: E226 + +E22.py:106:7: E226 [*] Missing whitespace around arithmetic operator | 104 | z = 2//30 105 | #: E226 E226 @@ -68,8 +385,19 @@ E22.py:106:7: E226 Missing whitespace around arithmetic operator 107 | #: E226 108 | norman = True+False | + = help: Add missing whitespace + +ℹ Fix +103 103 | #: E226 +104 104 | z = 2//30 +105 105 | #: E226 E226 +106 |-c = (a+b) * (a-b) + 106 |+c = (a + b) * (a-b) +107 107 | #: E226 +108 108 | norman = True+False +109 109 | #: E226 -E22.py:106:15: E226 Missing whitespace around arithmetic operator +E22.py:106:15: E226 [*] Missing whitespace around arithmetic operator | 104 | z = 2//30 105 | #: E226 E226 @@ -78,8 +406,19 @@ E22.py:106:15: E226 Missing whitespace around arithmetic operator 107 | #: E226 108 | norman = True+False | + = help: Add missing whitespace + +ℹ Fix +103 103 | #: E226 +104 104 | z = 2//30 +105 105 | #: E226 E226 +106 |-c = (a+b) * (a-b) + 106 |+c = (a+b) * (a - b) +107 107 | #: E226 +108 108 | norman = True+False +109 109 | #: E226 -E22.py:110:6: E226 Missing whitespace around arithmetic operator +E22.py:110:6: E226 [*] Missing whitespace around arithmetic operator | 108 | norman = True+False 109 | #: E226 @@ -88,8 +427,19 @@ E22.py:110:6: E226 Missing whitespace around arithmetic operator 111 | #: E226 112 | x = x/2 - 1 | + = help: Add missing whitespace -E22.py:112:6: E226 Missing whitespace around arithmetic operator +ℹ Fix +107 107 | #: E226 +108 108 | norman = True+False +109 109 | #: E226 +110 |-x = x*2 - 1 + 110 |+x = x * 2 - 1 +111 111 | #: E226 +112 112 | x = x/2 - 1 +113 113 | #: E226 E226 + +E22.py:112:6: E226 [*] Missing whitespace around arithmetic operator | 110 | x = x*2 - 1 111 | #: E226 @@ -98,8 +448,19 @@ E22.py:112:6: E226 Missing whitespace around arithmetic operator 113 | #: E226 E226 114 | hypot2 = x*x + y*y | + = help: Add missing whitespace + +ℹ Fix +109 109 | #: E226 +110 110 | x = x*2 - 1 +111 111 | #: E226 +112 |-x = x/2 - 1 + 112 |+x = x / 2 - 1 +113 113 | #: E226 E226 +114 114 | hypot2 = x*x + y*y +115 115 | #: E226 -E22.py:114:11: E226 Missing whitespace around arithmetic operator +E22.py:114:11: E226 [*] Missing whitespace around arithmetic operator | 112 | x = x/2 - 1 113 | #: E226 E226 @@ -108,8 +469,19 @@ E22.py:114:11: E226 Missing whitespace around arithmetic operator 115 | #: E226 116 | c = (a + b)*(a - b) | + = help: Add missing whitespace -E22.py:114:17: E226 Missing whitespace around arithmetic operator +ℹ Fix +111 111 | #: E226 +112 112 | x = x/2 - 1 +113 113 | #: E226 E226 +114 |-hypot2 = x*x + y*y + 114 |+hypot2 = x * x + y*y +115 115 | #: E226 +116 116 | c = (a + b)*(a - b) +117 117 | #: E226 + +E22.py:114:17: E226 [*] Missing whitespace around arithmetic operator | 112 | x = x/2 - 1 113 | #: E226 E226 @@ -118,8 +490,19 @@ E22.py:114:17: E226 Missing whitespace around arithmetic operator 115 | #: E226 116 | c = (a + b)*(a - b) | + = help: Add missing whitespace + +ℹ Fix +111 111 | #: E226 +112 112 | x = x/2 - 1 +113 113 | #: E226 E226 +114 |-hypot2 = x*x + y*y + 114 |+hypot2 = x*x + y * y +115 115 | #: E226 +116 116 | c = (a + b)*(a - b) +117 117 | #: E226 -E22.py:116:12: E226 Missing whitespace around arithmetic operator +E22.py:116:12: E226 [*] Missing whitespace around arithmetic operator | 114 | hypot2 = x*x + y*y 115 | #: E226 @@ -128,8 +511,19 @@ E22.py:116:12: E226 Missing whitespace around arithmetic operator 117 | #: E226 118 | def halves(n): | + = help: Add missing whitespace -E22.py:119:14: E226 Missing whitespace around arithmetic operator +ℹ Fix +113 113 | #: E226 E226 +114 114 | hypot2 = x*x + y*y +115 115 | #: E226 +116 |-c = (a + b)*(a - b) + 116 |+c = (a + b) * (a - b) +117 117 | #: E226 +118 118 | def halves(n): +119 119 | return (i//2 for i in range(n)) + +E22.py:119:14: E226 [*] Missing whitespace around arithmetic operator | 117 | #: E226 118 | def halves(n): @@ -138,5 +532,16 @@ E22.py:119:14: E226 Missing whitespace around arithmetic operator 120 | #: E227 121 | _1kB = _1MB>>10 | + = help: Add missing whitespace + +ℹ Fix +116 116 | c = (a + b)*(a - b) +117 117 | #: E226 +118 118 | def halves(n): +119 |- return (i//2 for i in range(n)) + 119 |+ return (i // 2 for i in range(n)) +120 120 | #: E227 +121 121 | _1kB = _1MB>>10 +122 122 | #: E227 diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E227_E22.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E227_E22.py.snap index 1a9bb8b8f6e21..f736d1212c465 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E227_E22.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E227_E22.py.snap @@ -1,7 +1,49 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E22.py:121:12: E227 Missing whitespace around bitwise or shift operator +E22.py:72:13: E227 [*] Missing whitespace around bitwise or shift operator + | +70 | z = (x + 1)** y +71 | #: E225 +72 | _1kB = _1MB >>10 + | ^^ E227 +73 | #: E225 +74 | _1kB = _1MB>> 10 + | + = help: Add missing whitespace + +ℹ Fix +69 69 | #: E225 +70 70 | z = (x + 1)** y +71 71 | #: E225 +72 |-_1kB = _1MB >>10 + 72 |+_1kB = _1MB >> 10 +73 73 | #: E225 +74 74 | _1kB = _1MB>> 10 +75 75 | #: E225 E225 + +E22.py:74:12: E227 [*] Missing whitespace around bitwise or shift operator + | +72 | _1kB = _1MB >>10 +73 | #: E225 +74 | _1kB = _1MB>> 10 + | ^^ E227 +75 | #: E225 E225 +76 | i=i+ 1 + | + = help: Add missing whitespace + +ℹ Fix +71 71 | #: E225 +72 72 | _1kB = _1MB >>10 +73 73 | #: E225 +74 |-_1kB = _1MB>> 10 + 74 |+_1kB = _1MB >> 10 +75 75 | #: E225 E225 +76 76 | i=i+ 1 +77 77 | #: E225 E225 + +E22.py:121:12: E227 [*] Missing whitespace around bitwise or shift operator | 119 | return (i//2 for i in range(n)) 120 | #: E227 @@ -10,8 +52,19 @@ E22.py:121:12: E227 Missing whitespace around bitwise or shift operator 122 | #: E227 123 | _1MB = _1kB<<10 | + = help: Add missing whitespace -E22.py:123:12: E227 Missing whitespace around bitwise or shift operator +ℹ Fix +118 118 | def halves(n): +119 119 | return (i//2 for i in range(n)) +120 120 | #: E227 +121 |-_1kB = _1MB>>10 + 121 |+_1kB = _1MB >> 10 +122 122 | #: E227 +123 123 | _1MB = _1kB<<10 +124 124 | #: E227 + +E22.py:123:12: E227 [*] Missing whitespace around bitwise or shift operator | 121 | _1kB = _1MB>>10 122 | #: E227 @@ -20,8 +73,19 @@ E22.py:123:12: E227 Missing whitespace around bitwise or shift operator 124 | #: E227 125 | a = b|c | + = help: Add missing whitespace + +ℹ Fix +120 120 | #: E227 +121 121 | _1kB = _1MB>>10 +122 122 | #: E227 +123 |-_1MB = _1kB<<10 + 123 |+_1MB = _1kB << 10 +124 124 | #: E227 +125 125 | a = b|c +126 126 | #: E227 -E22.py:125:6: E227 Missing whitespace around bitwise or shift operator +E22.py:125:6: E227 [*] Missing whitespace around bitwise or shift operator | 123 | _1MB = _1kB<<10 124 | #: E227 @@ -30,8 +94,19 @@ E22.py:125:6: E227 Missing whitespace around bitwise or shift operator 126 | #: E227 127 | b = c&a | + = help: Add missing whitespace + +ℹ Fix +122 122 | #: E227 +123 123 | _1MB = _1kB<<10 +124 124 | #: E227 +125 |-a = b|c + 125 |+a = b | c +126 126 | #: E227 +127 127 | b = c&a +128 128 | #: E227 -E22.py:127:6: E227 Missing whitespace around bitwise or shift operator +E22.py:127:6: E227 [*] Missing whitespace around bitwise or shift operator | 125 | a = b|c 126 | #: E227 @@ -40,8 +115,19 @@ E22.py:127:6: E227 Missing whitespace around bitwise or shift operator 128 | #: E227 129 | c = b^a | + = help: Add missing whitespace -E22.py:129:6: E227 Missing whitespace around bitwise or shift operator +ℹ Fix +124 124 | #: E227 +125 125 | a = b|c +126 126 | #: E227 +127 |-b = c&a + 127 |+b = c & a +128 128 | #: E227 +129 129 | c = b^a +130 130 | #: E228 + +E22.py:129:6: E227 [*] Missing whitespace around bitwise or shift operator | 127 | b = c&a 128 | #: E227 @@ -50,5 +136,37 @@ E22.py:129:6: E227 Missing whitespace around bitwise or shift operator 130 | #: E228 131 | a = b%c | + = help: Add missing whitespace + +ℹ Fix +126 126 | #: E227 +127 127 | b = c&a +128 128 | #: E227 +129 |-c = b^a + 129 |+c = b ^ a +130 130 | #: E228 +131 131 | a = b%c +132 132 | #: E228 + +E22.py:154:11: E227 [*] Missing whitespace around bitwise or shift operator + | +152 | func2(lambda a, b=h[:], c=0: (a, b, c)) +153 | if not -5 < x < +5: +154 | print >>sys.stderr, "x is out of range." + | ^^ E227 +155 | print >> sys.stdout, "x is an integer." +156 | x = x / 2 - 1 + | + = help: Add missing whitespace + +ℹ Fix +151 151 | func1(lambda *args, **kw: (args, kw)) +152 152 | func2(lambda a, b=h[:], c=0: (a, b, c)) +153 153 | if not -5 < x < +5: +154 |- print >>sys.stderr, "x is out of range." + 154 |+ print >> sys.stderr, "x is out of range." +155 155 | print >> sys.stdout, "x is an integer." +156 156 | x = x / 2 - 1 +157 157 | x = 1 @ 2 diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E228_E22.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E228_E22.py.snap index 308f097a78c32..8876af22d4282 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E228_E22.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E228_E22.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E22.py:131:6: E228 Missing whitespace around modulo operator +E22.py:131:6: E228 [*] Missing whitespace around modulo operator | 129 | c = b^a 130 | #: E228 @@ -10,8 +10,19 @@ E22.py:131:6: E228 Missing whitespace around modulo operator 132 | #: E228 133 | msg = fmt%(errno, errmsg) | + = help: Add missing whitespace -E22.py:133:10: E228 Missing whitespace around modulo operator +ℹ Fix +128 128 | #: E227 +129 129 | c = b^a +130 130 | #: E228 +131 |-a = b%c + 131 |+a = b % c +132 132 | #: E228 +133 133 | msg = fmt%(errno, errmsg) +134 134 | #: E228 + +E22.py:133:10: E228 [*] Missing whitespace around modulo operator | 131 | a = b%c 132 | #: E228 @@ -20,8 +31,19 @@ E22.py:133:10: E228 Missing whitespace around modulo operator 134 | #: E228 135 | msg = "Error %d occurred"%errno | + = help: Add missing whitespace + +ℹ Fix +130 130 | #: E228 +131 131 | a = b%c +132 132 | #: E228 +133 |-msg = fmt%(errno, errmsg) + 133 |+msg = fmt % (errno, errmsg) +134 134 | #: E228 +135 135 | msg = "Error %d occurred"%errno +136 136 | #: -E22.py:135:26: E228 Missing whitespace around modulo operator +E22.py:135:26: E228 [*] Missing whitespace around modulo operator | 133 | msg = fmt%(errno, errmsg) 134 | #: E228 @@ -29,5 +51,16 @@ E22.py:135:26: E228 Missing whitespace around modulo operator | ^ E228 136 | #: | + = help: Add missing whitespace + +ℹ Fix +132 132 | #: E228 +133 133 | msg = fmt%(errno, errmsg) +134 134 | #: E228 +135 |-msg = "Error %d occurred"%errno + 135 |+msg = "Error %d occurred" % errno +136 136 | #: +137 137 | +138 138 | #: Okay diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E231_E23.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E231_E23.py.snap index 049c9d52b6d44..d0839a77a266f 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E231_E23.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E231_E23.py.snap @@ -9,7 +9,7 @@ E23.py:2:7: E231 [*] Missing whitespace after ',' 3 | #: E231 4 | a[b1,:] | - = help: Added missing whitespace after ',' + = help: Add missing whitespace ℹ Fix 1 1 | #: E231 @@ -28,7 +28,7 @@ E23.py:4:5: E231 [*] Missing whitespace after ',' 5 | #: E231 6 | a = [{'a':''}] | - = help: Added missing whitespace after ',' + = help: Add missing whitespace ℹ Fix 1 1 | #: E231 @@ -49,7 +49,7 @@ E23.py:6:10: E231 [*] Missing whitespace after ':' 7 | #: Okay 8 | a = (4,) | - = help: Added missing whitespace after ':' + = help: Add missing whitespace ℹ Fix 3 3 | #: E231 @@ -69,7 +69,7 @@ E23.py:19:10: E231 [*] Missing whitespace after ',' | ^ E231 20 | pass | - = help: Added missing whitespace after ',' + = help: Add missing whitespace ℹ Fix 16 16 | @@ -89,7 +89,7 @@ E23.py:29:20: E231 [*] Missing whitespace after ':' | ^ E231 30 | } | - = help: Added missing whitespace after ':' + = help: Add missing whitespace ℹ Fix 26 26 | #: E231:2:20 @@ -99,6 +99,26 @@ E23.py:29:20: E231 [*] Missing whitespace after ':' 29 |+ 'tag_smalldata': [('byte_count_mdtype', 'u4'), ('data', 'S4')], 30 30 | } 31 31 | -32 32 | #: Okay +32 32 | # E231 + +E23.py:33:6: E231 [*] Missing whitespace after ',' + | +32 | # E231 +33 | f"{(a,b)}" + | ^ E231 +34 | +35 | # Okay because it's hard to differentiate between the usages of a colon in a f-string + | + = help: Add missing whitespace + +ℹ Fix +30 30 | } +31 31 | +32 32 | # E231 +33 |-f"{(a,b)}" + 33 |+f"{(a, b)}" +34 34 | +35 35 | # Okay because it's hard to differentiate between the usages of a colon in a f-string +36 36 | f"{a:=1}" diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E242_E24.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E242_E24.py.snap index 7f74a1934204b..3b2b21cbace51 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E242_E24.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E242_E24.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E24.py:6:8: E242 Tab after comma +E24.py:6:8: E242 [*] Tab after comma | 4 | b = (1, 20) 5 | #: E242 @@ -10,5 +10,16 @@ E24.py:6:8: E242 Tab after comma 7 | #: Okay 8 | b = (1, 20) # space before 20 | + = help: Replace with single space + +ℹ Fix +3 3 | #: Okay +4 4 | b = (1, 20) +5 5 | #: E242 +6 |-a = (1, 2) # tab before 2 + 6 |+a = (1, 2) # tab before 2 +7 7 | #: Okay +8 8 | b = (1, 20) # space before 20 +9 9 | #: E241 E241 E241 diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E252_E25.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E252_E25.py.snap index 04d099aa11a09..5d27cb5025172 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E252_E25.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E252_E25.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E25.py:46:15: E252 Missing whitespace around parameter equals +E25.py:46:15: E252 [*] Missing whitespace around parameter equals | 44 | return a + b 45 | #: E252:1:15 E252:1:16 E252:1:27 E252:1:36 @@ -10,8 +10,19 @@ E25.py:46:15: E252 Missing whitespace around parameter equals 47 | return a + b + c 48 | #: Okay | + = help: Add missing whitespace -E25.py:46:15: E252 Missing whitespace around parameter equals +ℹ Fix +43 43 | async def add(a: int = 0, b: int = 0) -> int: +44 44 | return a + b +45 45 | #: E252:1:15 E252:1:16 E252:1:27 E252:1:36 +46 |-def add(a: int=0, b: int =0, c: int= 0) -> int: + 46 |+def add(a: int =0, b: int =0, c: int= 0) -> int: +47 47 | return a + b + c +48 48 | #: Okay +49 49 | def add(a: int = _default(name='f')): + +E25.py:46:15: E252 [*] Missing whitespace around parameter equals | 44 | return a + b 45 | #: E252:1:15 E252:1:16 E252:1:27 E252:1:36 @@ -20,8 +31,19 @@ E25.py:46:15: E252 Missing whitespace around parameter equals 47 | return a + b + c 48 | #: Okay | + = help: Add missing whitespace + +ℹ Fix +43 43 | async def add(a: int = 0, b: int = 0) -> int: +44 44 | return a + b +45 45 | #: E252:1:15 E252:1:16 E252:1:27 E252:1:36 +46 |-def add(a: int=0, b: int =0, c: int= 0) -> int: + 46 |+def add(a: int= 0, b: int =0, c: int= 0) -> int: +47 47 | return a + b + c +48 48 | #: Okay +49 49 | def add(a: int = _default(name='f')): -E25.py:46:26: E252 Missing whitespace around parameter equals +E25.py:46:26: E252 [*] Missing whitespace around parameter equals | 44 | return a + b 45 | #: E252:1:15 E252:1:16 E252:1:27 E252:1:36 @@ -30,8 +52,19 @@ E25.py:46:26: E252 Missing whitespace around parameter equals 47 | return a + b + c 48 | #: Okay | + = help: Add missing whitespace -E25.py:46:36: E252 Missing whitespace around parameter equals +ℹ Fix +43 43 | async def add(a: int = 0, b: int = 0) -> int: +44 44 | return a + b +45 45 | #: E252:1:15 E252:1:16 E252:1:27 E252:1:36 +46 |-def add(a: int=0, b: int =0, c: int= 0) -> int: + 46 |+def add(a: int=0, b: int = 0, c: int= 0) -> int: +47 47 | return a + b + c +48 48 | #: Okay +49 49 | def add(a: int = _default(name='f')): + +E25.py:46:36: E252 [*] Missing whitespace around parameter equals | 44 | return a + b 45 | #: E252:1:15 E252:1:16 E252:1:27 E252:1:36 @@ -40,5 +73,16 @@ E25.py:46:36: E252 Missing whitespace around parameter equals 47 | return a + b + c 48 | #: Okay | + = help: Add missing whitespace + +ℹ Fix +43 43 | async def add(a: int = 0, b: int = 0) -> int: +44 44 | return a + b +45 45 | #: E252:1:15 E252:1:16 E252:1:27 E252:1:36 +46 |-def add(a: int=0, b: int =0, c: int= 0) -> int: + 46 |+def add(a: int=0, b: int =0, c: int = 0) -> int: +47 47 | return a + b + c +48 48 | #: Okay +49 49 | def add(a: int = _default(name='f')): diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E261_E26.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E261_E26.py.snap index ab8a934e470cc..f9a8790387e0b 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E261_E26.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E261_E26.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E26.py:2:5: E261 Insert at least two spaces before an inline comment +E26.py:2:5: E261 [*] Insert at least two spaces before an inline comment | 1 | #: E261:1:5 2 | pass # an inline comment @@ -9,5 +9,14 @@ E26.py:2:5: E261 Insert at least two spaces before an inline comment 3 | #: E262:1:12 4 | x = x + 1 #Increment x | + = help: Insert spaces + +ℹ Fix +1 1 | #: E261:1:5 +2 |-pass # an inline comment + 2 |+pass # an inline comment +3 3 | #: E262:1:12 +4 4 | x = x + 1 #Increment x +5 5 | #: E262:1:12 diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E273_E27.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E273_E27.py.snap index 122c091a1e4e0..672945a191c9b 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E273_E27.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E273_E27.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E27.py:10:9: E273 Tab after keyword +E27.py:10:9: E273 [*] Tab after keyword | 8 | if 1: 9 | #: E273 @@ -10,8 +10,19 @@ E27.py:10:9: E273 Tab after keyword 11 | #: E273 E274 12 | True and False | + = help: Replace with single space -E27.py:12:5: E273 Tab after keyword +ℹ Fix +7 7 | #: E271 +8 8 | if 1: +9 9 | #: E273 +10 |-True and False + 10 |+True and False +11 11 | #: E273 E274 +12 12 | True and False +13 13 | #: E271 + +E27.py:12:5: E273 [*] Tab after keyword | 10 | True and False 11 | #: E273 E274 @@ -20,8 +31,19 @@ E27.py:12:5: E273 Tab after keyword 13 | #: E271 14 | a and b | + = help: Replace with single space + +ℹ Fix +9 9 | #: E273 +10 10 | True and False +11 11 | #: E273 E274 +12 |-True and False + 12 |+True and False +13 13 | #: E271 +14 14 | a and b +15 15 | #: E271 -E27.py:12:10: E273 Tab after keyword +E27.py:12:10: E273 [*] Tab after keyword | 10 | True and False 11 | #: E273 E274 @@ -30,8 +52,19 @@ E27.py:12:10: E273 Tab after keyword 13 | #: E271 14 | a and b | + = help: Replace with single space + +ℹ Fix +9 9 | #: E273 +10 10 | True and False +11 11 | #: E273 E274 +12 |-True and False + 12 |+True and False +13 13 | #: E271 +14 14 | a and b +15 15 | #: E271 -E27.py:26:6: E273 Tab after keyword +E27.py:26:6: E273 [*] Tab after keyword | 24 | this and False 25 | #: E273 @@ -40,8 +73,19 @@ E27.py:26:6: E273 Tab after keyword 27 | #: E274 28 | a and b | + = help: Replace with single space -E27.py:30:10: E273 Tab after keyword +ℹ Fix +23 23 | #: E272 +24 24 | this and False +25 25 | #: E273 +26 |-a and b + 26 |+a and b +27 27 | #: E274 +28 28 | a and b +29 29 | #: E273 E274 + +E27.py:30:10: E273 [*] Tab after keyword | 28 | a and b 29 | #: E273 E274 @@ -50,5 +94,16 @@ E27.py:30:10: E273 Tab after keyword 31 | #: Okay 32 | from u import (a, b) | + = help: Replace with single space + +ℹ Fix +27 27 | #: E274 +28 28 | a and b +29 29 | #: E273 E274 +30 |-this and False + 30 |+this and False +31 31 | #: Okay +32 32 | from u import (a, b) +33 33 | from v import c, d diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E274_E27.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E274_E27.py.snap index 3230f60fe8432..811e4fe70301f 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E274_E27.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E274_E27.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E27.py:28:2: E274 Tab before keyword +E27.py:28:2: E274 [*] Tab before keyword | 26 | a and b 27 | #: E274 @@ -10,8 +10,19 @@ E27.py:28:2: E274 Tab before keyword 29 | #: E273 E274 30 | this and False | + = help: Replace with single space -E27.py:30:5: E274 Tab before keyword +ℹ Fix +25 25 | #: E273 +26 26 | a and b +27 27 | #: E274 +28 |-a and b + 28 |+a and b +29 29 | #: E273 E274 +30 30 | this and False +31 31 | #: Okay + +E27.py:30:5: E274 [*] Tab before keyword | 28 | a and b 29 | #: E273 E274 @@ -20,5 +31,16 @@ E27.py:30:5: E274 Tab before keyword 31 | #: Okay 32 | from u import (a, b) | + = help: Replace with single space + +ℹ Fix +27 27 | #: E274 +28 28 | a and b +29 29 | #: E273 E274 +30 |-this and False + 30 |+this and False +31 31 | #: Okay +32 32 | from u import (a, b) +33 33 | from v import c, d diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E275_E27.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E275_E27.py.snap index 3c73cb2654d3d..8e4502513a9a3 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E275_E27.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E275_E27.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E27.py:37:8: E275 Missing whitespace after keyword +E27.py:37:8: E275 [*] Missing whitespace after keyword | 35 | from w import (e, f) 36 | #: E275 @@ -10,8 +10,19 @@ E27.py:37:8: E275 Missing whitespace after keyword 38 | #: E275 39 | from importable.module import(e, f) | + = help: Added missing whitespace after keyword -E27.py:39:24: E275 Missing whitespace after keyword +ℹ Fix +34 34 | #: E271 +35 35 | from w import (e, f) +36 36 | #: E275 +37 |-from w import(e, f) + 37 |+from w import (e, f) +38 38 | #: E275 +39 39 | from importable.module import(e, f) +40 40 | #: E275 + +E27.py:39:24: E275 [*] Missing whitespace after keyword | 37 | from w import(e, f) 38 | #: E275 @@ -20,8 +31,19 @@ E27.py:39:24: E275 Missing whitespace after keyword 40 | #: E275 41 | try: | + = help: Added missing whitespace after keyword + +ℹ Fix +36 36 | #: E275 +37 37 | from w import(e, f) +38 38 | #: E275 +39 |-from importable.module import(e, f) + 39 |+from importable.module import (e, f) +40 40 | #: E275 +41 41 | try: +42 42 | from importable.module import(e, f) -E27.py:42:28: E275 Missing whitespace after keyword +E27.py:42:28: E275 [*] Missing whitespace after keyword | 40 | #: E275 41 | try: @@ -30,8 +52,19 @@ E27.py:42:28: E275 Missing whitespace after keyword 43 | except ImportError: 44 | pass | + = help: Added missing whitespace after keyword + +ℹ Fix +39 39 | from importable.module import(e, f) +40 40 | #: E275 +41 41 | try: +42 |- from importable.module import(e, f) + 42 |+ from importable.module import (e, f) +43 43 | except ImportError: +44 44 | pass +45 45 | #: E275 -E27.py:46:1: E275 Missing whitespace after keyword +E27.py:46:1: E275 [*] Missing whitespace after keyword | 44 | pass 45 | #: E275 @@ -40,8 +73,19 @@ E27.py:46:1: E275 Missing whitespace after keyword 47 | pass 48 | else: | + = help: Added missing whitespace after keyword -E27.py:54:5: E275 Missing whitespace after keyword +ℹ Fix +43 43 | except ImportError: +44 44 | pass +45 45 | #: E275 +46 |-if(foo): + 46 |+if (foo): +47 47 | pass +48 48 | else: +49 49 | pass + +E27.py:54:5: E275 [*] Missing whitespace after keyword | 52 | #: E275:2:11 53 | if True: @@ -50,5 +94,16 @@ E27.py:54:5: E275 Missing whitespace after keyword 55 | #: Okay 56 | def f(): | + = help: Added missing whitespace after keyword + +ℹ Fix +51 51 | matched = {"true": True, "false": False} +52 52 | #: E275:2:11 +53 53 | if True: +54 |- assert(1) + 54 |+ assert (1) +55 55 | #: Okay +56 56 | def f(): +57 57 | print((yield)) diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E501_E501.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E501_E501.py.snap index 9445864d5756a..e4d4f16e242b8 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E501_E501.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E501_E501.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E501.py:5:89: E501 Line too long (123 > 88 characters) +E501.py:5:89: E501 Line too long (123 > 88) | 3 | https://github.com/PyCQA/pycodestyle/pull/258/files#diff-841c622497a8033d10152bfdfb15b20b92437ecdea21a260944ea86b77b51533 4 | @@ -10,14 +10,14 @@ E501.py:5:89: E501 Line too long (123 > 88 characters) 6 | """ | -E501.py:16:85: E501 Line too long (95 > 88 characters) +E501.py:16:85: E501 Line too long (95 > 88) | 15 | _ = "---------------------------------------------------------------------------AAAAAAA" 16 | _ = "---------------------------------------------------------------------------亜亜亜亜亜亜亜" | ^^^^^^^ E501 | -E501.py:25:89: E501 Line too long (127 > 88 characters) +E501.py:25:89: E501 Line too long (127 > 88) | 23 | caller( 24 | """ @@ -27,7 +27,7 @@ E501.py:25:89: E501 Line too long (127 > 88 characters) 27 | ) | -E501.py:40:89: E501 Line too long (132 > 88 characters) +E501.py:40:89: E501 Line too long (132 > 88) | 38 | "Lorem ipsum dolor": "sit amet", 39 | # E501 Line too long @@ -37,7 +37,7 @@ E501.py:40:89: E501 Line too long (132 > 88 characters) 42 | "Lorem ipsum dolor": """ | -E501.py:43:89: E501 Line too long (105 > 88 characters) +E501.py:43:89: E501 Line too long (105 > 88) | 41 | # E501 Line too long 42 | "Lorem ipsum dolor": """ @@ -47,7 +47,7 @@ E501.py:43:89: E501 Line too long (105 > 88 characters) 45 | # OK | -E501.py:83:89: E501 Line too long (147 > 88 characters) +E501.py:83:89: E501 Line too long (147 > 88) | 81 | class Bar: 82 | """ diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E501_E501_3.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E501_E501_3.py.snap new file mode 100644 index 0000000000000..a15f167fbed79 --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E501_E501_3.py.snap @@ -0,0 +1,11 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +--- +E501_3.py:11:89: E501 Line too long (89 > 88) + | +10 | # Error (89 characters) +11 | "shape:" + "shape:" + "shape:" + "shape:" + "shape:" + "shape:" + "shape:" + "shape:aaaa" # type: ignore + | ^ E501 + | + + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E721_E721.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E721_E721.py.snap index c1947fa971a73..e5b81848e86fe 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E721_E721.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E721_E721.py.snap @@ -17,7 +17,7 @@ E721.py:5:4: E721 Do not compare types, use `isinstance()` 5 | if type(res) != type(""): | ^^^^^^^^^^^^^^^^^^^^^ E721 6 | pass -7 | #: E721 +7 | #: Okay | E721.py:15:4: E721 Do not compare types, use `isinstance()` @@ -34,7 +34,7 @@ E721.py:18:8: E721 Do not compare types, use `isinstance()` | 16 | pass 17 | #: E721 -18 | assert type(res) == type(False) +18 | assert type(res) == type(False) or type(res) == type(None) | ^^^^^^^^^^^^^^^^^^^^^^^^ E721 19 | #: E721 20 | assert type(res) == type([]) @@ -42,7 +42,7 @@ E721.py:18:8: E721 Do not compare types, use `isinstance()` E721.py:20:8: E721 Do not compare types, use `isinstance()` | -18 | assert type(res) == type(False) +18 | assert type(res) == type(False) or type(res) == type(None) 19 | #: E721 20 | assert type(res) == type([]) | ^^^^^^^^^^^^^^^^^^^^^ E721 @@ -77,97 +77,84 @@ E721.py:26:8: E721 Do not compare types, use `isinstance()` 26 | assert type(res) == type((0)) | ^^^^^^^^^^^^^^^^^^^^^^ E721 27 | #: E721 -28 | assert type(res) != type((1,)) +28 | assert type(res) != type((1, )) | E721.py:28:8: E721 Do not compare types, use `isinstance()` | 26 | assert type(res) == type((0)) 27 | #: E721 -28 | assert type(res) != type((1,)) - | ^^^^^^^^^^^^^^^^^^^^^^^ E721 -29 | #: E721 -30 | assert type(res) is type((1,)) +28 | assert type(res) != type((1, )) + | ^^^^^^^^^^^^^^^^^^^^^^^^ E721 +29 | #: Okay +30 | assert type(res) is type((1, )) | E721.py:30:8: E721 Do not compare types, use `isinstance()` | -28 | assert type(res) != type((1,)) -29 | #: E721 -30 | assert type(res) is type((1,)) - | ^^^^^^^^^^^^^^^^^^^^^^^ E721 -31 | #: E721 -32 | assert type(res) is not type((1,)) +28 | assert type(res) != type((1, )) +29 | #: Okay +30 | assert type(res) is type((1, )) + | ^^^^^^^^^^^^^^^^^^^^^^^^ E721 +31 | #: Okay +32 | assert type(res) is not type((1, )) | E721.py:32:8: E721 Do not compare types, use `isinstance()` | -30 | assert type(res) is type((1,)) -31 | #: E721 -32 | assert type(res) is not type((1,)) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ E721 +30 | assert type(res) is type((1, )) +31 | #: Okay +32 | assert type(res) is not type((1, )) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E721 33 | #: E211 E721 -34 | assert type(res) == type( +34 | assert type(res) == type ([2, ]) | E721.py:34:8: E721 Do not compare types, use `isinstance()` | -32 | assert type(res) is not type((1,)) -33 | #: E211 E721 -34 | assert type(res) == type( - | ________^ -35 | | [ -36 | | 2, -37 | | ] -38 | | ) - | |_^ E721 -39 | #: E201 E201 E202 E721 -40 | assert type(res) == type(()) - | - -E721.py:40:8: E721 Do not compare types, use `isinstance()` - | -38 | ) -39 | #: E201 E201 E202 E721 -40 | assert type(res) == type(()) - | ^^^^^^^^^^^^^^^^^^^^^ E721 -41 | #: E201 E202 E721 -42 | assert type(res) == type((0,)) +32 | assert type(res) is not type((1, )) +33 | #: E211 E721 +34 | assert type(res) == type ([2, ]) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ E721 +35 | #: E201 E201 E202 E721 +36 | assert type(res) == type( ( ) ) | -E721.py:42:8: E721 Do not compare types, use `isinstance()` +E721.py:36:8: E721 Do not compare types, use `isinstance()` | -40 | assert type(res) == type(()) -41 | #: E201 E202 E721 -42 | assert type(res) == type((0,)) - | ^^^^^^^^^^^^^^^^^^^^^^^ E721 -43 | -44 | #: Okay +34 | assert type(res) == type ([2, ]) +35 | #: E201 E201 E202 E721 +36 | assert type(res) == type( ( ) ) + | ^^^^^^^^^^^^^^^^^^^^^^^^ E721 +37 | #: E201 E202 E721 +38 | assert type(res) == type( (0, ) ) | -E721.py:63:8: E721 Do not compare types, use `isinstance()` +E721.py:38:8: E721 Do not compare types, use `isinstance()` | -62 | #: E721 -63 | assert type(res) is int - | ^^^^^^^^^^^^^^^^ E721 +36 | assert type(res) == type( ( ) ) +37 | #: E201 E202 E721 +38 | assert type(res) == type( (0, ) ) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ E721 +39 | #: | -E721.py:69:12: E721 Do not compare types, use `isinstance()` +E721.py:96:12: E721 Do not compare types, use `isinstance()` | -67 | def asdf(self, value: str | None): -68 | #: E721 -69 | if type(value) is str: +94 | def asdf(self, value: str | None): +95 | #: E721 +96 | if type(value) is str: | ^^^^^^^^^^^^^^^^^^ E721 -70 | ... +97 | ... | -E721.py:79:12: E721 Do not compare types, use `isinstance()` - | -77 | def asdf(self, value: str | None): -78 | #: E721 -79 | if type(value) is str: - | ^^^^^^^^^^^^^^^^^^ E721 -80 | ... - | +E721.py:106:12: E721 Do not compare types, use `isinstance()` + | +104 | def asdf(self, value: str | None): +105 | #: E721 +106 | if type(value) is str: + | ^^^^^^^^^^^^^^^^^^ E721 +107 | ... + | diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E731_E731.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E731_E731.py.snap index ce00ec0a9a768..b8456517e9faf 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E731_E731.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E731_E731.py.snap @@ -100,7 +100,7 @@ E731.py:24:5: E731 [*] Do not assign a `lambda` expression, use a `def` 26 27 | 27 28 | def scope(): -E731.py:57:5: E731 [*] Do not assign a `lambda` expression, use a `def` +E731.py:57:5: E731 Do not assign a `lambda` expression, use a `def` | 55 | class Scope: 56 | # E731 @@ -120,7 +120,7 @@ E731.py:57:5: E731 [*] Do not assign a `lambda` expression, use a `def` 59 60 | 60 61 | class Scope: -E731.py:64:5: E731 [*] Do not assign a `lambda` expression, use a `def` +E731.py:64:5: E731 Do not assign a `lambda` expression, use a `def` | 63 | # E731 64 | f: Callable[[int], int] = lambda x: 2 * x @@ -139,7 +139,7 @@ E731.py:64:5: E731 [*] Do not assign a `lambda` expression, use a `def` 66 67 | 67 68 | def scope(): -E731.py:73:9: E731 [*] Do not assign a `lambda` expression, use a `def` +E731.py:73:9: E731 Do not assign a `lambda` expression, use a `def` | 71 | x: Callable[[int], int] 72 | if True: @@ -161,7 +161,7 @@ E731.py:73:9: E731 [*] Do not assign a `lambda` expression, use a `def` 75 76 | x = lambda: 2 76 77 | return x -E731.py:75:9: E731 [*] Do not assign a `lambda` expression, use a `def` +E731.py:75:9: E731 Do not assign a `lambda` expression, use a `def` | 73 | x = lambda: 1 74 | else: @@ -322,7 +322,7 @@ E731.py:135:5: E731 [*] Do not assign a `lambda` expression, use a `def` 137 138 | 138 139 | class TemperatureScales(Enum): -E731.py:139:5: E731 [*] Do not assign a `lambda` expression, use a `def` +E731.py:139:5: E731 Do not assign a `lambda` expression, use a `def` | 138 | class TemperatureScales(Enum): 139 | CELSIUS = (lambda deg_c: deg_c) @@ -342,7 +342,7 @@ E731.py:139:5: E731 [*] Do not assign a `lambda` expression, use a `def` 141 142 | 142 143 | -E731.py:140:5: E731 [*] Do not assign a `lambda` expression, use a `def` +E731.py:140:5: E731 Do not assign a `lambda` expression, use a `def` | 138 | class TemperatureScales(Enum): 139 | CELSIUS = (lambda deg_c: deg_c) diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W191_W19.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W191_W19.py.snap index ff6c28bc72a70..eb8c4e1643b5d 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W191_W19.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W191_W19.py.snap @@ -349,4 +349,20 @@ W19.py:146:1: W191 Indentation contains tabs 148 | #: W191 - okay | +W19.py:157:1: W191 Indentation contains tabs + | +156 | f"test{ +157 | tab_indented_should_be_flagged + | ^^^^ W191 +158 | } <- this tab is fine" + | + +W19.py:161:1: W191 Indentation contains tabs + | +160 | f"""test{ +161 | tab_indented_should_be_flagged + | ^^^^ W191 +162 | } <- this tab is fine""" + | + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_0.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_0.py.snap index c5997156d2aff..b61df343bdcab 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_0.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_0.py.snap @@ -9,7 +9,7 @@ W605_0.py:2:10: W605 [*] Invalid escape sequence: `\.` 3 | 4 | #: W605:2:1 | - = help: Add backslash to escape sequence + = help: Use a raw string literal ℹ Fix 1 1 | #: W605:1:10 @@ -27,7 +27,7 @@ W605_0.py:6:1: W605 [*] Invalid escape sequence: `\.` | ^^ W605 7 | ''' | - = help: Add backslash to escape sequence + = help: Use a raw string literal ℹ Fix 2 2 | regex = '\.png$' @@ -47,7 +47,7 @@ W605_0.py:11:6: W605 [*] Invalid escape sequence: `\_` | ^^ W605 12 | ) | - = help: Add backslash to escape sequence + = help: Use a raw string literal ℹ Fix 8 8 | @@ -68,7 +68,7 @@ W605_0.py:18:6: W605 [*] Invalid escape sequence: `\_` 19 | in the middle 20 | """ | - = help: Add backslash to escape sequence + = help: Use a raw string literal ℹ Fix 12 12 | ) @@ -107,7 +107,7 @@ W605_0.py:28:12: W605 [*] Invalid escape sequence: `\.` 29 | 30 | #: Okay | - = help: Add backslash to escape sequence + = help: Use a raw string literal ℹ Fix 25 25 | diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_1.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_1.py.snap index 5d7cd884cc658..72749e97c1f84 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_1.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_1.py.snap @@ -9,7 +9,7 @@ W605_1.py:2:10: W605 [*] Invalid escape sequence: `\.` 3 | 4 | #: W605:2:1 | - = help: Add backslash to escape sequence + = help: Use a raw string literal ℹ Fix 1 1 | #: W605:1:10 @@ -27,7 +27,7 @@ W605_1.py:6:1: W605 [*] Invalid escape sequence: `\.` | ^^ W605 7 | ''' | - = help: Add backslash to escape sequence + = help: Use a raw string literal ℹ Fix 2 2 | regex = '\.png$' @@ -47,7 +47,7 @@ W605_1.py:11:6: W605 [*] Invalid escape sequence: `\_` | ^^ W605 12 | ) | - = help: Add backslash to escape sequence + = help: Use a raw string literal ℹ Fix 8 8 | @@ -68,7 +68,7 @@ W605_1.py:18:6: W605 [*] Invalid escape sequence: `\_` 19 | in the middle 20 | """ | - = help: Add backslash to escape sequence + = help: Use a raw string literal ℹ Fix 12 12 | ) @@ -89,7 +89,7 @@ W605_1.py:25:12: W605 [*] Invalid escape sequence: `\.` 26 | 27 | #: Okay | - = help: Add backslash to escape sequence + = help: Use a raw string literal ℹ Fix 22 22 | diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_2.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_2.py.snap new file mode 100644 index 0000000000000..8d23dcae78eb1 --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__W605_W605_2.py.snap @@ -0,0 +1,227 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +--- +W605_2.py:4:11: W605 [*] Invalid escape sequence: `\.` + | +3 | #: W605:1:10 +4 | regex = f'\.png$' + | ^^ W605 +5 | +6 | #: W605:2:1 + | + = help: Use a raw string literal + +ℹ Fix +1 1 | # Same as `W605_0.py` but using f-strings instead. +2 2 | +3 3 | #: W605:1:10 +4 |-regex = f'\.png$' + 4 |+regex = rf'\.png$' +5 5 | +6 6 | #: W605:2:1 +7 7 | regex = f''' + +W605_2.py:8:1: W605 [*] Invalid escape sequence: `\.` + | +6 | #: W605:2:1 +7 | regex = f''' +8 | \.png$ + | ^^ W605 +9 | ''' + | + = help: Use a raw string literal + +ℹ Fix +4 4 | regex = f'\.png$' +5 5 | +6 6 | #: W605:2:1 +7 |-regex = f''' + 7 |+regex = rf''' +8 8 | \.png$ +9 9 | ''' +10 10 | + +W605_2.py:13:7: W605 [*] Invalid escape sequence: `\_` + | +11 | #: W605:2:6 +12 | f( +13 | f'\_' + | ^^ W605 +14 | ) + | + = help: Use a raw string literal + +ℹ Fix +10 10 | +11 11 | #: W605:2:6 +12 12 | f( +13 |- f'\_' + 13 |+ rf'\_' +14 14 | ) +15 15 | +16 16 | #: W605:4:6 + +W605_2.py:20:6: W605 [*] Invalid escape sequence: `\_` + | +18 | multi-line +19 | literal +20 | with \_ somewhere + | ^^ W605 +21 | in the middle +22 | """ + | + = help: Use a raw string literal + +ℹ Fix +14 14 | ) +15 15 | +16 16 | #: W605:4:6 +17 |-f""" + 17 |+rf""" +18 18 | multi-line +19 19 | literal +20 20 | with \_ somewhere + +W605_2.py:25:40: W605 [*] Invalid escape sequence: `\_` + | +24 | #: W605:1:38 +25 | value = f'new line\nand invalid escape \_ here' + | ^^ W605 + | + = help: Add backslash to escape sequence + +ℹ Fix +22 22 | """ +23 23 | +24 24 | #: W605:1:38 +25 |-value = f'new line\nand invalid escape \_ here' + 25 |+value = f'new line\nand invalid escape \\_ here' +26 26 | +27 27 | +28 28 | #: Okay + +W605_2.py:43:13: W605 [*] Invalid escape sequence: `\_` + | +41 | ''' # noqa +42 | +43 | regex = f'\\\_' + | ^^ W605 +44 | value = f'\{{1}}' +45 | value = f'\{1}' + | + = help: Add backslash to escape sequence + +ℹ Fix +40 40 | \w +41 41 | ''' # noqa +42 42 | +43 |-regex = f'\\\_' + 43 |+regex = f'\\\\_' +44 44 | value = f'\{{1}}' +45 45 | value = f'\{1}' +46 46 | value = f'{1:\}' + +W605_2.py:44:11: W605 [*] Invalid escape sequence: `\{` + | +43 | regex = f'\\\_' +44 | value = f'\{{1}}' + | ^^ W605 +45 | value = f'\{1}' +46 | value = f'{1:\}' + | + = help: Use a raw string literal + +ℹ Fix +41 41 | ''' # noqa +42 42 | +43 43 | regex = f'\\\_' +44 |-value = f'\{{1}}' + 44 |+value = rf'\{{1}}' +45 45 | value = f'\{1}' +46 46 | value = f'{1:\}' +47 47 | value = f"{f"\{1}"}" + +W605_2.py:45:11: W605 [*] Invalid escape sequence: `\{` + | +43 | regex = f'\\\_' +44 | value = f'\{{1}}' +45 | value = f'\{1}' + | ^^ W605 +46 | value = f'{1:\}' +47 | value = f"{f"\{1}"}" + | + = help: Use a raw string literal + +ℹ Fix +42 42 | +43 43 | regex = f'\\\_' +44 44 | value = f'\{{1}}' +45 |-value = f'\{1}' + 45 |+value = rf'\{1}' +46 46 | value = f'{1:\}' +47 47 | value = f"{f"\{1}"}" +48 48 | value = rf"{f"\{1}"}" + +W605_2.py:46:14: W605 [*] Invalid escape sequence: `\}` + | +44 | value = f'\{{1}}' +45 | value = f'\{1}' +46 | value = f'{1:\}' + | ^^ W605 +47 | value = f"{f"\{1}"}" +48 | value = rf"{f"\{1}"}" + | + = help: Use a raw string literal + +ℹ Fix +43 43 | regex = f'\\\_' +44 44 | value = f'\{{1}}' +45 45 | value = f'\{1}' +46 |-value = f'{1:\}' + 46 |+value = rf'{1:\}' +47 47 | value = f"{f"\{1}"}" +48 48 | value = rf"{f"\{1}"}" +49 49 | + +W605_2.py:47:14: W605 [*] Invalid escape sequence: `\{` + | +45 | value = f'\{1}' +46 | value = f'{1:\}' +47 | value = f"{f"\{1}"}" + | ^^ W605 +48 | value = rf"{f"\{1}"}" + | + = help: Use a raw string literal + +ℹ Fix +44 44 | value = f'\{{1}}' +45 45 | value = f'\{1}' +46 46 | value = f'{1:\}' +47 |-value = f"{f"\{1}"}" + 47 |+value = f"{rf"\{1}"}" +48 48 | value = rf"{f"\{1}"}" +49 49 | +50 50 | # Okay + +W605_2.py:48:15: W605 [*] Invalid escape sequence: `\{` + | +46 | value = f'{1:\}' +47 | value = f"{f"\{1}"}" +48 | value = rf"{f"\{1}"}" + | ^^ W605 +49 | +50 | # Okay + | + = help: Use a raw string literal + +ℹ Fix +45 45 | value = f'\{1}' +46 46 | value = f'{1:\}' +47 47 | value = f"{f"\{1}"}" +48 |-value = rf"{f"\{1}"}" + 48 |+value = rf"{rf"\{1}"}" +49 49 | +50 50 | # Okay +51 51 | value = rf'\{{1}}' + + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__max_doc_length.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__max_doc_length.snap index 18e19e53e295e..aea858c21f6a6 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__max_doc_length.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__max_doc_length.snap @@ -1,14 +1,14 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -W505.py:2:51: W505 Doc line too long (57 > 50 characters) +W505.py:2:51: W505 Doc line too long (57 > 50) | 1 | #!/usr/bin/env python3 2 | """Here's a top-level docstring that's over the limit.""" | ^^^^^^^ W505 | -W505.py:6:51: W505 Doc line too long (56 > 50 characters) +W505.py:6:51: W505 Doc line too long (56 > 50) | 5 | def f1(): 6 | """Here's a docstring that's also over the limit.""" @@ -17,7 +17,7 @@ W505.py:6:51: W505 Doc line too long (56 > 50 characters) 8 | x = 1 # Here's a comment that's over the limit, but it's not standalone. | -W505.py:10:51: W505 Doc line too long (56 > 50 characters) +W505.py:10:51: W505 Doc line too long (56 > 50) | 8 | x = 1 # Here's a comment that's over the limit, but it's not standalone. 9 | @@ -27,7 +27,7 @@ W505.py:10:51: W505 Doc line too long (56 > 50 characters) 12 | x = 2 | -W505.py:13:51: W505 Doc line too long (93 > 50 characters) +W505.py:13:51: W505 Doc line too long (93 > 50) | 12 | x = 2 13 | # Another standalone that is preceded by a newline and indent toke and is over the limit. @@ -36,13 +36,13 @@ W505.py:13:51: W505 Doc line too long (93 > 50 characters) 15 | print("Here's a string that's over the limit, but it's not a docstring.") | -W505.py:18:51: W505 Doc line too long (61 > 50 characters) +W505.py:18:51: W505 Doc line too long (61 > 50) | 18 | "This is also considered a docstring, and is over the limit." | ^^^^^^^^^^^ W505 | -W505.py:24:51: W505 Doc line too long (82 > 50 characters) +W505.py:24:51: W505 Doc line too long (82 > 50) | 22 | """Here's a multi-line docstring. 23 | @@ -51,7 +51,7 @@ W505.py:24:51: W505 Doc line too long (82 > 50 characters) 25 | """ | -W505.py:31:51: W505 Doc line too long (85 > 50 characters) +W505.py:31:51: W505 Doc line too long (85 > 50) | 29 | """Here's a multi-line docstring. 30 | diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__max_doc_length_with_utf_8.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__max_doc_length_with_utf_8.snap index 42bcfd88d7edb..5e9cbc36641e6 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__max_doc_length_with_utf_8.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__max_doc_length_with_utf_8.snap @@ -1,14 +1,14 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -W505_utf_8.py:2:50: W505 Doc line too long (57 > 50 characters) +W505_utf_8.py:2:50: W505 Doc line too long (57 > 50) | 1 | #!/usr/bin/env python3 2 | """Here's a top-level ß9💣2ℝing that's over theß9💣2ℝ.""" | ^^^^^^ W505 | -W505_utf_8.py:6:49: W505 Doc line too long (56 > 50 characters) +W505_utf_8.py:6:49: W505 Doc line too long (56 > 50) | 5 | def f1(): 6 | """Here's a ß9💣2ℝing that's also over theß9💣2ℝ.""" @@ -17,7 +17,7 @@ W505_utf_8.py:6:49: W505 Doc line too long (56 > 50 characters) 8 | x = 1 # Here's a comment that's over theß9💣2ℝ, but it's not standalone. | -W505_utf_8.py:10:51: W505 Doc line too long (56 > 50 characters) +W505_utf_8.py:10:51: W505 Doc line too long (56 > 50) | 8 | x = 1 # Here's a comment that's over theß9💣2ℝ, but it's not standalone. 9 | @@ -27,7 +27,7 @@ W505_utf_8.py:10:51: W505 Doc line too long (56 > 50 characters) 12 | x = 2 | -W505_utf_8.py:13:51: W505 Doc line too long (93 > 50 characters) +W505_utf_8.py:13:51: W505 Doc line too long (93 > 50) | 12 | x = 2 13 | # Another standalone that is preceded by a newline and indent toke and is over theß9💣2ℝ. @@ -36,13 +36,13 @@ W505_utf_8.py:13:51: W505 Doc line too long (93 > 50 characters) 15 | print("Here's a string that's over theß9💣2ℝ, but it's not a ß9💣2ℝing.") | -W505_utf_8.py:18:50: W505 Doc line too long (61 > 50 characters) +W505_utf_8.py:18:50: W505 Doc line too long (61 > 50) | 18 | "This is also considered a ß9💣2ℝing, and is over theß9💣2ℝ." | ^^^^^^^^^^^ W505 | -W505_utf_8.py:24:50: W505 Doc line too long (82 > 50 characters) +W505_utf_8.py:24:50: W505 Doc line too long (82 > 50) | 22 | """Here's a multi-line ß9💣2ℝing. 23 | @@ -51,7 +51,7 @@ W505_utf_8.py:24:50: W505 Doc line too long (82 > 50 characters) 25 | """ | -W505_utf_8.py:31:50: W505 Doc line too long (85 > 50 characters) +W505_utf_8.py:31:50: W505 Doc line too long (85 > 50) | 29 | """Here's a multi-line ß9💣2ℝing. 30 | diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__preview__E721_E721.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__preview__E721_E721.py.snap new file mode 100644 index 0000000000000..0c75d706f540d --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__preview__E721_E721.py.snap @@ -0,0 +1,112 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +--- +E721.py:2:4: E721 Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks + | +1 | #: E721 +2 | if type(res) == type(42): + | ^^^^^^^^^^^^^^^^^^^^^ E721 +3 | pass +4 | #: E721 + | + +E721.py:5:4: E721 Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks + | +3 | pass +4 | #: E721 +5 | if type(res) != type(""): + | ^^^^^^^^^^^^^^^^^^^^^ E721 +6 | pass +7 | #: Okay + | + +E721.py:18:8: E721 Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks + | +16 | pass +17 | #: E721 +18 | assert type(res) == type(False) or type(res) == type(None) + | ^^^^^^^^^^^^^^^^^^^^^^^^ E721 +19 | #: E721 +20 | assert type(res) == type([]) + | + +E721.py:20:8: E721 Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks + | +18 | assert type(res) == type(False) or type(res) == type(None) +19 | #: E721 +20 | assert type(res) == type([]) + | ^^^^^^^^^^^^^^^^^^^^^ E721 +21 | #: E721 +22 | assert type(res) == type(()) + | + +E721.py:22:8: E721 Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks + | +20 | assert type(res) == type([]) +21 | #: E721 +22 | assert type(res) == type(()) + | ^^^^^^^^^^^^^^^^^^^^^ E721 +23 | #: E721 +24 | assert type(res) == type((0,)) + | + +E721.py:24:8: E721 Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks + | +22 | assert type(res) == type(()) +23 | #: E721 +24 | assert type(res) == type((0,)) + | ^^^^^^^^^^^^^^^^^^^^^^^ E721 +25 | #: E721 +26 | assert type(res) == type((0)) + | + +E721.py:26:8: E721 Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks + | +24 | assert type(res) == type((0,)) +25 | #: E721 +26 | assert type(res) == type((0)) + | ^^^^^^^^^^^^^^^^^^^^^^ E721 +27 | #: E721 +28 | assert type(res) != type((1, )) + | + +E721.py:28:8: E721 Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks + | +26 | assert type(res) == type((0)) +27 | #: E721 +28 | assert type(res) != type((1, )) + | ^^^^^^^^^^^^^^^^^^^^^^^^ E721 +29 | #: Okay +30 | assert type(res) is type((1, )) + | + +E721.py:34:8: E721 Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks + | +32 | assert type(res) is not type((1, )) +33 | #: E211 E721 +34 | assert type(res) == type ([2, ]) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ E721 +35 | #: E201 E201 E202 E721 +36 | assert type(res) == type( ( ) ) + | + +E721.py:36:8: E721 Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks + | +34 | assert type(res) == type ([2, ]) +35 | #: E201 E201 E202 E721 +36 | assert type(res) == type( ( ) ) + | ^^^^^^^^^^^^^^^^^^^^^^^^ E721 +37 | #: E201 E202 E721 +38 | assert type(res) == type( (0, ) ) + | + +E721.py:38:8: E721 Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks + | +36 | assert type(res) == type( ( ) ) +37 | #: E201 E202 E721 +38 | assert type(res) == type( (0, ) ) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ E721 +39 | #: + | + + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__tab_size_1.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__tab_size_1.snap index 414ff81309510..98ee4b6d01e73 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__tab_size_1.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__tab_size_1.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E501_2.py:2:7: E501 Line too long (7 > 6 characters) +E501_2.py:2:7: E501 Line too long (7 > 6) | 1 | # aaaa 2 | # aaaaa @@ -10,7 +10,7 @@ E501_2.py:2:7: E501 Line too long (7 > 6 characters) 4 | # a | -E501_2.py:3:7: E501 Line too long (7 > 6 characters) +E501_2.py:3:7: E501 Line too long (7 > 6) | 1 | # aaaa 2 | # aaaaa @@ -20,7 +20,7 @@ E501_2.py:3:7: E501 Line too long (7 > 6 characters) 5 | # aa | -E501_2.py:7:7: E501 Line too long (7 > 6 characters) +E501_2.py:7:7: E501 Line too long (7 > 6) | 5 | # aa 6 | # aaa @@ -30,7 +30,7 @@ E501_2.py:7:7: E501 Line too long (7 > 6 characters) 9 | # aa | -E501_2.py:10:7: E501 Line too long (7 > 6 characters) +E501_2.py:10:7: E501 Line too long (7 > 6) | 8 | # a 9 | # aa @@ -40,7 +40,7 @@ E501_2.py:10:7: E501 Line too long (7 > 6 characters) 12 | if True: # noqa: E501 | -E501_2.py:16:7: E501 Line too long (7 > 6 characters) +E501_2.py:16:7: E501 Line too long (7 > 6) | 14 | [12 ] 15 | [1,2] diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__tab_size_2.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__tab_size_2.snap index 34f004a6069ad..a1800fab20a61 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__tab_size_2.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__tab_size_2.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E501_2.py:2:7: E501 Line too long (7 > 6 characters) +E501_2.py:2:7: E501 Line too long (7 > 6) | 1 | # aaaa 2 | # aaaaa @@ -10,7 +10,7 @@ E501_2.py:2:7: E501 Line too long (7 > 6 characters) 4 | # a | -E501_2.py:3:7: E501 Line too long (7 > 6 characters) +E501_2.py:3:7: E501 Line too long (7 > 6) | 1 | # aaaa 2 | # aaaaa @@ -20,7 +20,7 @@ E501_2.py:3:7: E501 Line too long (7 > 6 characters) 5 | # aa | -E501_2.py:6:6: E501 Line too long (7 > 6 characters) +E501_2.py:6:6: E501 Line too long (7 > 6) | 4 | # a 5 | # aa @@ -30,7 +30,7 @@ E501_2.py:6:6: E501 Line too long (7 > 6 characters) 8 | # a | -E501_2.py:7:6: E501 Line too long (8 > 6 characters) +E501_2.py:7:6: E501 Line too long (8 > 6) | 5 | # aa 6 | # aaa @@ -40,7 +40,7 @@ E501_2.py:7:6: E501 Line too long (8 > 6 characters) 9 | # aa | -E501_2.py:8:5: E501 Line too long (7 > 6 characters) +E501_2.py:8:5: E501 Line too long (7 > 6) | 6 | # aaa 7 | # aaaa @@ -50,7 +50,7 @@ E501_2.py:8:5: E501 Line too long (7 > 6 characters) 10 | # aaa | -E501_2.py:9:5: E501 Line too long (8 > 6 characters) +E501_2.py:9:5: E501 Line too long (8 > 6) | 7 | # aaaa 8 | # a @@ -59,7 +59,7 @@ E501_2.py:9:5: E501 Line too long (8 > 6 characters) 10 | # aaa | -E501_2.py:10:5: E501 Line too long (9 > 6 characters) +E501_2.py:10:5: E501 Line too long (9 > 6) | 8 | # a 9 | # aa @@ -69,7 +69,7 @@ E501_2.py:10:5: E501 Line too long (9 > 6 characters) 12 | if True: # noqa: E501 | -E501_2.py:14:6: E501 Line too long (7 > 6 characters) +E501_2.py:14:6: E501 Line too long (7 > 6) | 12 | if True: # noqa: E501 13 | [12] @@ -79,7 +79,7 @@ E501_2.py:14:6: E501 Line too long (7 > 6 characters) 16 | [1, 2] | -E501_2.py:16:6: E501 Line too long (8 > 6 characters) +E501_2.py:16:6: E501 Line too long (8 > 6) | 14 | [12 ] 15 | [1,2] diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__tab_size_4.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__tab_size_4.snap index b9717b2f59d97..da581f2a64ea9 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__tab_size_4.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__tab_size_4.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E501_2.py:2:7: E501 Line too long (7 > 6 characters) +E501_2.py:2:7: E501 Line too long (7 > 6) | 1 | # aaaa 2 | # aaaaa @@ -10,7 +10,7 @@ E501_2.py:2:7: E501 Line too long (7 > 6 characters) 4 | # a | -E501_2.py:3:7: E501 Line too long (7 > 6 characters) +E501_2.py:3:7: E501 Line too long (7 > 6) | 1 | # aaaa 2 | # aaaaa @@ -20,7 +20,7 @@ E501_2.py:3:7: E501 Line too long (7 > 6 characters) 5 | # aa | -E501_2.py:4:4: E501 Line too long (7 > 6 characters) +E501_2.py:4:4: E501 Line too long (7 > 6) | 2 | # aaaaa 3 | # a @@ -30,7 +30,7 @@ E501_2.py:4:4: E501 Line too long (7 > 6 characters) 6 | # aaa | -E501_2.py:5:4: E501 Line too long (8 > 6 characters) +E501_2.py:5:4: E501 Line too long (8 > 6) | 3 | # a 4 | # a @@ -40,7 +40,7 @@ E501_2.py:5:4: E501 Line too long (8 > 6 characters) 7 | # aaaa | -E501_2.py:6:4: E501 Line too long (9 > 6 characters) +E501_2.py:6:4: E501 Line too long (9 > 6) | 4 | # a 5 | # aa @@ -50,7 +50,7 @@ E501_2.py:6:4: E501 Line too long (9 > 6 characters) 8 | # a | -E501_2.py:7:4: E501 Line too long (10 > 6 characters) +E501_2.py:7:4: E501 Line too long (10 > 6) | 5 | # aa 6 | # aaa @@ -60,7 +60,7 @@ E501_2.py:7:4: E501 Line too long (10 > 6 characters) 9 | # aa | -E501_2.py:8:3: E501 Line too long (11 > 6 characters) +E501_2.py:8:3: E501 Line too long (11 > 6) | 6 | # aaa 7 | # aaaa @@ -70,7 +70,7 @@ E501_2.py:8:3: E501 Line too long (11 > 6 characters) 10 | # aaa | -E501_2.py:9:3: E501 Line too long (12 > 6 characters) +E501_2.py:9:3: E501 Line too long (12 > 6) | 7 | # aaaa 8 | # a @@ -79,7 +79,7 @@ E501_2.py:9:3: E501 Line too long (12 > 6 characters) 10 | # aaa | -E501_2.py:10:3: E501 Line too long (13 > 6 characters) +E501_2.py:10:3: E501 Line too long (13 > 6) | 8 | # a 9 | # aa @@ -89,7 +89,7 @@ E501_2.py:10:3: E501 Line too long (13 > 6 characters) 12 | if True: # noqa: E501 | -E501_2.py:14:4: E501 Line too long (9 > 6 characters) +E501_2.py:14:4: E501 Line too long (9 > 6) | 12 | if True: # noqa: E501 13 | [12] @@ -99,7 +99,7 @@ E501_2.py:14:4: E501 Line too long (9 > 6 characters) 16 | [1, 2] | -E501_2.py:16:4: E501 Line too long (10 > 6 characters) +E501_2.py:16:4: E501 Line too long (10 > 6) | 14 | [12 ] 15 | [1,2] diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__tab_size_8.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__tab_size_8.snap index 9adffbfb99aea..8494868830b5a 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__tab_size_8.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__tab_size_8.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E501_2.py:2:7: E501 Line too long (7 > 6 characters) +E501_2.py:2:7: E501 Line too long (7 > 6) | 1 | # aaaa 2 | # aaaaa @@ -10,7 +10,7 @@ E501_2.py:2:7: E501 Line too long (7 > 6 characters) 4 | # a | -E501_2.py:3:7: E501 Line too long (7 > 6 characters) +E501_2.py:3:7: E501 Line too long (7 > 6) | 1 | # aaaa 2 | # aaaaa @@ -20,7 +20,7 @@ E501_2.py:3:7: E501 Line too long (7 > 6 characters) 5 | # aa | -E501_2.py:4:2: E501 Line too long (11 > 6 characters) +E501_2.py:4:2: E501 Line too long (11 > 6) | 2 | # aaaaa 3 | # a @@ -30,7 +30,7 @@ E501_2.py:4:2: E501 Line too long (11 > 6 characters) 6 | # aaa | -E501_2.py:5:2: E501 Line too long (12 > 6 characters) +E501_2.py:5:2: E501 Line too long (12 > 6) | 3 | # a 4 | # a @@ -40,7 +40,7 @@ E501_2.py:5:2: E501 Line too long (12 > 6 characters) 7 | # aaaa | -E501_2.py:6:2: E501 Line too long (13 > 6 characters) +E501_2.py:6:2: E501 Line too long (13 > 6) | 4 | # a 5 | # aa @@ -50,7 +50,7 @@ E501_2.py:6:2: E501 Line too long (13 > 6 characters) 8 | # a | -E501_2.py:7:2: E501 Line too long (14 > 6 characters) +E501_2.py:7:2: E501 Line too long (14 > 6) | 5 | # aa 6 | # aaa @@ -60,7 +60,7 @@ E501_2.py:7:2: E501 Line too long (14 > 6 characters) 9 | # aa | -E501_2.py:8:2: E501 Line too long (19 > 6 characters) +E501_2.py:8:2: E501 Line too long (19 > 6) | 6 | # aaa 7 | # aaaa @@ -70,7 +70,7 @@ E501_2.py:8:2: E501 Line too long (19 > 6 characters) 10 | # aaa | -E501_2.py:9:2: E501 Line too long (20 > 6 characters) +E501_2.py:9:2: E501 Line too long (20 > 6) | 7 | # aaaa 8 | # a @@ -79,7 +79,7 @@ E501_2.py:9:2: E501 Line too long (20 > 6 characters) 10 | # aaa | -E501_2.py:10:2: E501 Line too long (21 > 6 characters) +E501_2.py:10:2: E501 Line too long (21 > 6) | 8 | # a 9 | # aa @@ -89,7 +89,7 @@ E501_2.py:10:2: E501 Line too long (21 > 6 characters) 12 | if True: # noqa: E501 | -E501_2.py:14:2: E501 Line too long (13 > 6 characters) +E501_2.py:14:2: E501 Line too long (13 > 6) | 12 | if True: # noqa: E501 13 | [12] @@ -99,7 +99,7 @@ E501_2.py:14:2: E501 Line too long (13 > 6 characters) 16 | [1, 2] | -E501_2.py:16:2: E501 Line too long (14 > 6 characters) +E501_2.py:16:2: E501 Line too long (14 > 6) | 14 | [12 ] 15 | [1,2] diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__task_tags_false.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__task_tags_false.snap index 0075115ad1bbc..6b373eafbf232 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__task_tags_false.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__task_tags_false.snap @@ -1,58 +1,78 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E501_1.py:1:89: E501 Line too long (149 > 88 characters) +E501_1.py:1:89: E501 Line too long (149 > 88) | 1 | # TODO: comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E501 -2 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` -3 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +2 | # TODO(charlie): comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +3 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` | -E501_1.py:2:89: E501 Line too long (148 > 88 characters) +E501_1.py:2:89: E501 Line too long (158 > 88) | 1 | # TODO: comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` -2 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E501 -3 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` -4 | # FIXME: comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +2 | # TODO(charlie): comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E501 +3 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +4 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` | -E501_1.py:3:89: E501 Line too long (155 > 88 characters) +E501_1.py:3:89: E501 Line too long (148 > 88) | 1 | # TODO: comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` -2 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` -3 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +2 | # TODO(charlie): comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +3 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E501 +4 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +5 | # FIXME: comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` + | + +E501_1.py:4:89: E501 Line too long (155 > 88) + | +2 | # TODO(charlie): comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +3 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +4 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E501 -4 | # FIXME: comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` -5 | # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +5 | # FIXME: comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +6 | # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` | -E501_1.py:4:89: E501 Line too long (150 > 88 characters) +E501_1.py:5:89: E501 Line too long (150 > 88) | -2 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` -3 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` -4 | # FIXME: comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +3 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +4 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +5 | # FIXME: comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E501 -5 | # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` -6 | # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +6 | # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +7 | # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` | -E501_1.py:5:89: E501 Line too long (149 > 88 characters) +E501_1.py:6:89: E501 Line too long (149 > 88) | -3 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` -4 | # FIXME: comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` -5 | # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +4 | # TODO comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +5 | # FIXME: comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +6 | # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E501 -6 | # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +7 | # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +8 | # FIXME(charlie): comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` | -E501_1.py:6:89: E501 Line too long (156 > 88 characters) +E501_1.py:7:89: E501 Line too long (156 > 88) | -4 | # FIXME: comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` -5 | # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` -6 | # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +5 | # FIXME: comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +6 | # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +7 | # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E501 +8 | # FIXME(charlie): comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` + | + +E501_1.py:8:89: E501 Line too long (159 > 88) + | +6 | # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +7 | # FIXME comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` +8 | # FIXME(charlie): comments starting with one of the configured task-tags sometimes are longer than line-length so that you can easily find them with `git grep` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E501 | diff --git a/crates/ruff_linter/src/rules/pydocstyle/mod.rs b/crates/ruff_linter/src/rules/pydocstyle/mod.rs index e3e51c00c6387..fad6a274a41af 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/mod.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/mod.rs @@ -12,6 +12,7 @@ mod tests { use test_case::test_case; use crate::registry::Rule; + use crate::settings::types::PreviewMode; use crate::test::test_path; use crate::{assert_messages, settings}; @@ -87,6 +88,7 @@ mod tests { #[test_case(Rule::EscapeSequenceInDocstring, Path::new("D.py"))] #[test_case(Rule::EscapeSequenceInDocstring, Path::new("D301.py"))] #[test_case(Rule::TripleSingleQuotes, Path::new("D.py"))] + #[test_case(Rule::TripleSingleQuotes, Path::new("D300.py"))] fn rules(rule_code: Rule, path: &Path) -> Result<()> { let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy()); let diagnostics = test_path( @@ -106,6 +108,33 @@ mod tests { Ok(()) } + #[test_case(Rule::TripleSingleQuotes, Path::new("D.py"))] + #[test_case(Rule::TripleSingleQuotes, Path::new("D300.py"))] + fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> { + // Tests for rules with preview features + let snapshot = format!( + "preview__{}_{}", + rule_code.noqa_code(), + path.to_string_lossy() + ); + let diagnostics = test_path( + Path::new("pydocstyle").join(path).as_path(), + &settings::LinterSettings { + pydocstyle: Settings { + convention: None, + ignore_decorators: BTreeSet::from_iter(["functools.wraps".to_string()]), + property_decorators: BTreeSet::from_iter([ + "gi.repository.GObject.Property".to_string() + ]), + }, + preview: PreviewMode::Enabled, + ..settings::LinterSettings::for_rule(rule_code) + }, + )?; + assert_messages!(snapshot, diagnostics); + Ok(()) + } + #[test] fn bom() -> Result<()> { let diagnostics = test_path( diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/backslashes.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/backslashes.rs index 91cc414c3bdc3..0c02b457a642f 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/backslashes.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/backslashes.rs @@ -1,6 +1,6 @@ use memchr::memchr_iter; -use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; @@ -46,18 +46,21 @@ use crate::docstrings::Docstring; #[violation] pub struct EscapeSequenceInDocstring; -impl Violation for EscapeSequenceInDocstring { +impl AlwaysFixableViolation for EscapeSequenceInDocstring { #[derive_message_formats] fn message(&self) -> String { format!(r#"Use `r"""` if any backslashes in a docstring"#) } + + fn fix_title(&self) -> String { + format!(r#"Add `r` prefix"#) + } } /// D301 pub(crate) fn backslashes(checker: &mut Checker, docstring: &Docstring) { // Docstring is already raw. - let contents = docstring.contents; - if contents.starts_with('r') || contents.starts_with("ur") { + if docstring.leading_quote().contains(['r', 'R']) { return; } @@ -67,11 +70,15 @@ pub(crate) fn backslashes(checker: &mut Checker, docstring: &Docstring) { if memchr_iter(b'\\', bytes).any(|position| { let escaped_char = bytes.get(position.saturating_add(1)); // Allow continuations (backslashes followed by newlines) and Unicode escapes. - !matches!(escaped_char, Some(b'\r' | b'\n' | b'u' | b'N')) + !matches!(escaped_char, Some(b'\r' | b'\n' | b'u' | b'U' | b'N')) }) { - checker.diagnostics.push(Diagnostic::new( - EscapeSequenceInDocstring, + let mut diagnostic = Diagnostic::new(EscapeSequenceInDocstring, docstring.range()); + + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + "r".to_owned() + docstring.contents, docstring.range(), - )); + ))); + + checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/blank_after_summary.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/blank_after_summary.rs index 1672ad8a23af4..bbd9ee0ab6302 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/blank_after_summary.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/blank_after_summary.rs @@ -1,11 +1,10 @@ -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_source_file::{UniversalNewlineIterator, UniversalNewlines}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::docstrings::Docstring; -use crate::registry::AsRule; /// ## What it does /// Checks for docstring summary lines that are not separated from the docstring @@ -47,7 +46,7 @@ pub struct BlankLineAfterSummary { } impl Violation for BlankLineAfterSummary { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -61,7 +60,7 @@ impl Violation for BlankLineAfterSummary { } } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Insert single blank line".to_string()) } } @@ -91,35 +90,33 @@ pub(crate) fn blank_after_summary(checker: &mut Checker, docstring: &Docstring) }, docstring.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if blanks_count > 1 { - let mut lines = UniversalNewlineIterator::with_offset(&body, body.start()); - let mut summary_end = body.start(); + if blanks_count > 1 { + let mut lines = UniversalNewlineIterator::with_offset(&body, body.start()); + let mut summary_end = body.start(); - // Find the "summary" line (defined as the first non-blank line). - for line in lines.by_ref() { - if !line.trim().is_empty() { - summary_end = line.full_end(); - break; - } + // Find the "summary" line (defined as the first non-blank line). + for line in lines.by_ref() { + if !line.trim().is_empty() { + summary_end = line.full_end(); + break; } + } - // Find the last blank line - let mut blank_end = summary_end; - for line in lines { - if !line.trim().is_empty() { - blank_end = line.start(); - break; - } + // Find the last blank line + let mut blank_end = summary_end; + for line in lines { + if !line.trim().is_empty() { + blank_end = line.start(); + break; } - - // Insert one blank line after the summary (replacing any existing lines). - diagnostic.set_fix(Fix::automatic(Edit::replacement( - checker.stylist().line_ending().to_string(), - summary_end, - blank_end, - ))); } + + // Insert one blank line after the summary (replacing any existing lines). + diagnostic.set_fix(Fix::safe_edit(Edit::replacement( + checker.stylist().line_ending().to_string(), + summary_end, + blank_end, + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/blank_before_after_class.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/blank_before_after_class.rs index 4f74fb736dc2d..bd0a1a5c0753b 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/blank_before_after_class.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/blank_before_after_class.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_trivia::{indentation_at_offset, PythonWhitespace}; use ruff_source_file::{Line, UniversalNewlineIterator}; @@ -7,7 +7,7 @@ use ruff_text_size::{TextLen, TextRange}; use crate::checkers::ast::Checker; use crate::docstrings::Docstring; -use crate::registry::{AsRule, Rule}; +use crate::registry::Rule; /// ## What it does /// Checks for docstrings on class definitions that are not preceded by a @@ -43,13 +43,13 @@ use crate::registry::{AsRule, Rule}; #[violation] pub struct OneBlankLineBeforeClass; -impl AlwaysAutofixableViolation for OneBlankLineBeforeClass { +impl AlwaysFixableViolation for OneBlankLineBeforeClass { #[derive_message_formats] fn message(&self) -> String { format!("1 blank line required before class docstring") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Insert 1 blank line before class docstring".to_string() } } @@ -95,13 +95,13 @@ impl AlwaysAutofixableViolation for OneBlankLineBeforeClass { #[violation] pub struct OneBlankLineAfterClass; -impl AlwaysAutofixableViolation for OneBlankLineAfterClass { +impl AlwaysFixableViolation for OneBlankLineAfterClass { #[derive_message_formats] fn message(&self) -> String { format!("1 blank line required after class docstring") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Insert 1 blank line after class docstring".to_string() } } @@ -140,13 +140,13 @@ impl AlwaysAutofixableViolation for OneBlankLineAfterClass { #[violation] pub struct BlankLineBeforeClass; -impl AlwaysAutofixableViolation for BlankLineBeforeClass { +impl AlwaysFixableViolation for BlankLineBeforeClass { #[derive_message_formats] fn message(&self) -> String { format!("No blank lines allowed before class docstring") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove blank line(s) before class docstring".to_string() } } @@ -189,27 +189,23 @@ pub(crate) fn blank_before_after_class(checker: &mut Checker, docstring: &Docstr if checker.enabled(Rule::BlankLineBeforeClass) { if blank_lines_before != 0 { let mut diagnostic = Diagnostic::new(BlankLineBeforeClass, docstring.range()); - if checker.patch(diagnostic.kind.rule()) { - // Delete the blank line before the class. - diagnostic.set_fix(Fix::automatic(Edit::deletion( - blank_lines_start, - docstring.start() - docstring.indentation.text_len(), - ))); - } + // Delete the blank line before the class. + diagnostic.set_fix(Fix::safe_edit(Edit::deletion( + blank_lines_start, + docstring.start() - docstring.indentation.text_len(), + ))); checker.diagnostics.push(diagnostic); } } if checker.enabled(Rule::OneBlankLineBeforeClass) { if blank_lines_before != 1 { let mut diagnostic = Diagnostic::new(OneBlankLineBeforeClass, docstring.range()); - if checker.patch(diagnostic.kind.rule()) { - // Insert one blank line before the class. - diagnostic.set_fix(Fix::automatic(Edit::replacement( - checker.stylist().line_ending().to_string(), - blank_lines_start, - docstring.start() - docstring.indentation.text_len(), - ))); - } + // Insert one blank line before the class. + diagnostic.set_fix(Fix::safe_edit(Edit::replacement( + checker.stylist().line_ending().to_string(), + blank_lines_start, + docstring.start() - docstring.indentation.text_len(), + ))); checker.diagnostics.push(diagnostic); } } @@ -243,21 +239,19 @@ pub(crate) fn blank_before_after_class(checker: &mut Checker, docstring: &Docstr let indentation = indentation_at_offset(docstring.start(), checker.locator()) .expect("Own line docstring must have indentation"); let mut diagnostic = Diagnostic::new(OneBlankLineAfterClass, docstring.range()); - if checker.patch(diagnostic.kind.rule()) { - let line_ending = checker.stylist().line_ending().as_str(); - // We have to trim the whitespace twice, once before the semicolon above and - // once after the semicolon here, or we get invalid indents: - // ```rust - // class Priority: - // """Has priorities""" ; priorities=1 - // ``` - let next_statement = next_statement.trim_whitespace_start(); - diagnostic.set_fix(Fix::automatic(Edit::replacement( - line_ending.to_string() + line_ending + indentation + next_statement, - replacement_start, - first_line.end(), - ))); - } + let line_ending = checker.stylist().line_ending().as_str(); + // We have to trim the whitespace twice, once before the semicolon above and + // once after the semicolon here, or we get invalid indents: + // ```rust + // class Priority: + // """Has priorities""" ; priorities=1 + // ``` + let next_statement = next_statement.trim_whitespace_start(); + diagnostic.set_fix(Fix::safe_edit(Edit::replacement( + line_ending.to_string() + line_ending + indentation + next_statement, + replacement_start, + first_line.end(), + ))); checker.diagnostics.push(diagnostic); return; } else if trailing.starts_with('#') { @@ -280,14 +274,12 @@ pub(crate) fn blank_before_after_class(checker: &mut Checker, docstring: &Docstr if blank_lines_after != 1 { let mut diagnostic = Diagnostic::new(OneBlankLineAfterClass, docstring.range()); - if checker.patch(diagnostic.kind.rule()) { - // Insert a blank line before the class (replacing any existing lines). - diagnostic.set_fix(Fix::automatic(Edit::replacement( - checker.stylist().line_ending().to_string(), - replacement_start, - blank_lines_end, - ))); - } + // Insert a blank line before the class (replacing any existing lines). + diagnostic.set_fix(Fix::safe_edit(Edit::replacement( + checker.stylist().line_ending().to_string(), + replacement_start, + blank_lines_end, + ))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/blank_before_after_function.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/blank_before_after_function.rs index 66428fa76ecf8..25e335e80eb62 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/blank_before_after_function.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/blank_before_after_function.rs @@ -1,7 +1,7 @@ use once_cell::sync::Lazy; use regex::Regex; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_trivia::PythonWhitespace; use ruff_source_file::{UniversalNewlineIterator, UniversalNewlines}; @@ -10,7 +10,7 @@ use ruff_text_size::{TextLen, TextRange}; use crate::checkers::ast::Checker; use crate::docstrings::Docstring; -use crate::registry::{AsRule, Rule}; +use crate::registry::Rule; /// ## What it does /// Checks for docstrings on functions that are separated by one or more blank @@ -42,14 +42,14 @@ pub struct NoBlankLineBeforeFunction { num_lines: usize, } -impl AlwaysAutofixableViolation for NoBlankLineBeforeFunction { +impl AlwaysFixableViolation for NoBlankLineBeforeFunction { #[derive_message_formats] fn message(&self) -> String { let NoBlankLineBeforeFunction { num_lines } = self; format!("No blank lines allowed before function docstring (found {num_lines})") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove blank line(s) before function docstring".to_string() } } @@ -86,14 +86,14 @@ pub struct NoBlankLineAfterFunction { num_lines: usize, } -impl AlwaysAutofixableViolation for NoBlankLineAfterFunction { +impl AlwaysFixableViolation for NoBlankLineAfterFunction { #[derive_message_formats] fn message(&self) -> String { let NoBlankLineAfterFunction { num_lines } = self; format!("No blank lines allowed after function docstring (found {num_lines})") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove blank line(s) after function docstring".to_string() } } @@ -132,13 +132,11 @@ pub(crate) fn blank_before_after_function(checker: &mut Checker, docstring: &Doc }, docstring.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // Delete the blank line before the docstring. - diagnostic.set_fix(Fix::automatic(Edit::deletion( - blank_lines_start, - docstring.start() - docstring.indentation.text_len(), - ))); - } + // Delete the blank line before the docstring. + diagnostic.set_fix(Fix::safe_edit(Edit::deletion( + blank_lines_start, + docstring.start() - docstring.indentation.text_len(), + ))); checker.diagnostics.push(diagnostic); } } @@ -188,13 +186,11 @@ pub(crate) fn blank_before_after_function(checker: &mut Checker, docstring: &Doc }, docstring.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // Delete the blank line after the docstring. - diagnostic.set_fix(Fix::automatic(Edit::deletion( - first_line_end, - blank_lines_end, - ))); - } + // Delete the blank line after the docstring. + diagnostic.set_fix(Fix::safe_edit(Edit::deletion( + first_line_end, + blank_lines_end, + ))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/capitalized.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/capitalized.rs index afcc313c80f6d..e8de2983abcc8 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/capitalized.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/capitalized.rs @@ -1,11 +1,10 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use ruff_text_size::{TextLen, TextRange}; use crate::checkers::ast::Checker; use crate::docstrings::Docstring; -use crate::registry::AsRule; /// ## What it does /// Checks for docstrings that do not start with a capital letter. @@ -36,7 +35,7 @@ pub struct FirstLineCapitalized { capitalized_word: String, } -impl AlwaysAutofixableViolation for FirstLineCapitalized { +impl AlwaysFixableViolation for FirstLineCapitalized { #[derive_message_formats] fn message(&self) -> String { format!( @@ -45,7 +44,7 @@ impl AlwaysAutofixableViolation for FirstLineCapitalized { ) } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { format!( "Capitalize `{}` to `{}`", self.first_word, self.capitalized_word @@ -90,12 +89,10 @@ pub(crate) fn capitalized(checker: &mut Checker, docstring: &Docstring) { docstring.expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - capitalized_word, - TextRange::at(body.start(), first_word.text_len()), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + capitalized_word, + TextRange::at(body.start(), first_word.text_len()), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/ends_with_period.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/ends_with_period.rs index 57c2b63fd0016..360a7fccaaffc 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/ends_with_period.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/ends_with_period.rs @@ -1,7 +1,7 @@ use ruff_text_size::TextLen; use strum::IntoEnumIterator; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_source_file::{UniversalNewlineIterator, UniversalNewlines}; use ruff_text_size::Ranged; @@ -9,7 +9,7 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::docstrings::sections::SectionKind; use crate::docstrings::Docstring; -use crate::registry::AsRule; + use crate::rules::pydocstyle::helpers::logical_line; /// ## What it does @@ -47,13 +47,13 @@ use crate::rules::pydocstyle::helpers::logical_line; #[violation] pub struct EndsInPeriod; -impl AlwaysAutofixableViolation for EndsInPeriod { +impl AlwaysFixableViolation for EndsInPeriod { #[derive_message_formats] fn message(&self) -> String { format!("First line should end with a period") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Add period".to_string() } } @@ -103,9 +103,9 @@ pub(crate) fn ends_with_period(checker: &mut Checker, docstring: &Docstring) { if !trimmed.ends_with('.') { let mut diagnostic = Diagnostic::new(EndsInPeriod, docstring.range()); - // Best-effort autofix: avoid adding a period after other punctuation marks. - if checker.patch(diagnostic.kind.rule()) && !trimmed.ends_with([':', ';']) { - diagnostic.set_fix(Fix::suggested(Edit::insertion( + // Best-effort fix: avoid adding a period after other punctuation marks. + if !trimmed.ends_with([':', ';']) { + diagnostic.set_fix(Fix::unsafe_edit(Edit::insertion( ".".to_string(), line.start() + trimmed.text_len(), ))); diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/ends_with_punctuation.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/ends_with_punctuation.rs index 05ec17ddb1500..df03f44cc0b1b 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/ends_with_punctuation.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/ends_with_punctuation.rs @@ -1,7 +1,7 @@ use ruff_text_size::TextLen; use strum::IntoEnumIterator; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_source_file::{UniversalNewlineIterator, UniversalNewlines}; use ruff_text_size::Ranged; @@ -9,7 +9,7 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::docstrings::sections::SectionKind; use crate::docstrings::Docstring; -use crate::registry::AsRule; + use crate::rules::pydocstyle::helpers::logical_line; /// ## What it does @@ -46,13 +46,13 @@ use crate::rules::pydocstyle::helpers::logical_line; #[violation] pub struct EndsInPunctuation; -impl AlwaysAutofixableViolation for EndsInPunctuation { +impl AlwaysFixableViolation for EndsInPunctuation { #[derive_message_formats] fn message(&self) -> String { format!("First line should end with a period, question mark, or exclamation point") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Add closing punctuation".to_string() } } @@ -102,9 +102,9 @@ pub(crate) fn ends_with_punctuation(checker: &mut Checker, docstring: &Docstring if !trimmed.ends_with(['.', '!', '?']) { let mut diagnostic = Diagnostic::new(EndsInPunctuation, docstring.range()); - // Best-effort autofix: avoid adding a period after other punctuation marks. - if checker.patch(diagnostic.kind.rule()) && !trimmed.ends_with([':', ';']) { - diagnostic.set_fix(Fix::suggested(Edit::insertion( + // Best-effort fix: avoid adding a period after other punctuation marks. + if !trimmed.ends_with([':', ';']) { + diagnostic.set_fix(Fix::unsafe_edit(Edit::insertion( ".".to_string(), line.start() + trimmed.text_len(), ))); diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/indent.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/indent.rs index c33bbea24a6d8..9ba7786b1475d 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/indent.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/indent.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Violation}; use ruff_diagnostics::{Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::docstrings::{clean_space, leading_space}; @@ -8,15 +8,13 @@ use ruff_text_size::{TextLen, TextRange}; use crate::checkers::ast::Checker; use crate::docstrings::Docstring; -use crate::registry::{AsRule, Rule}; +use crate::registry::Rule; /// ## What it does /// Checks for docstrings that are indented with tabs. /// /// ## Why is this bad? -/// [PEP 8](https://peps.python.org/pep-0008/#tabs-or-spaces) recommends using -/// spaces over tabs for indentation. -/// +/// [PEP 8] recommends using spaces over tabs for indentation. /// /// ## Example /// ```python @@ -38,10 +36,20 @@ use crate::registry::{AsRule, Rule}; /// """ /// ``` /// +/// ## Formatter compatibility +/// We recommend against using this rule alongside the [formatter]. The +/// formatter enforces consistent indentation, making the rule redundant. +/// +/// The rule is also incompatible with the [formatter] when using +/// `format.indent-style="tab"`. +/// /// ## References /// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) /// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) /// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) +/// +/// [PEP 8]: https://peps.python.org/pep-0008/#tabs-or-spaces +/// [formatter]: https://docs.astral.sh/ruff/formatter #[violation] pub struct IndentWithSpaces; @@ -88,13 +96,13 @@ impl Violation for IndentWithSpaces { #[violation] pub struct UnderIndentation; -impl AlwaysAutofixableViolation for UnderIndentation { +impl AlwaysFixableViolation for UnderIndentation { #[derive_message_formats] fn message(&self) -> String { format!("Docstring is under-indented") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Increase indentation".to_string() } } @@ -126,22 +134,27 @@ impl AlwaysAutofixableViolation for UnderIndentation { /// """ /// ``` /// +/// ## Formatter compatibility +/// We recommend against using this rule alongside the [formatter]. The +/// formatter enforces consistent indentation, making the rule redundant. +/// /// ## References /// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) /// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) /// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) /// /// [PEP 257]: https://peps.python.org/pep-0257/ +/// [formatter]:https://docs.astral.sh/ruff/formatter/ #[violation] pub struct OverIndentation; -impl AlwaysAutofixableViolation for OverIndentation { +impl AlwaysFixableViolation for OverIndentation { #[derive_message_formats] fn message(&self) -> String { format!("Docstring is over-indented") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove over-indentation".to_string() } } @@ -182,18 +195,16 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) { if checker.enabled(Rule::UnderIndentation) { // We report under-indentation on every line. This isn't great, but enables - // autofix. + // fix. if (i == lines.len() - 1 || !is_blank) && line_indent.len() < docstring.indentation.len() { let mut diagnostic = Diagnostic::new(UnderIndentation, TextRange::empty(line.start())); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - clean_space(docstring.indentation), - TextRange::at(line.start(), line_indent.text_len()), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + clean_space(docstring.indentation), + TextRange::at(line.start(), line_indent.text_len()), + ))); checker.diagnostics.push(diagnostic); } } @@ -226,18 +237,16 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) { if is_over_indented { for over_indented in over_indented_lines { // We report over-indentation on every line. This isn't great, but - // enables autofix. + // enables fix. let mut diagnostic = Diagnostic::new(OverIndentation, TextRange::empty(over_indented.start())); - if checker.patch(diagnostic.kind.rule()) { - let indent = clean_space(docstring.indentation); - let edit = if indent.is_empty() { - Edit::range_deletion(over_indented) - } else { - Edit::range_replacement(indent, over_indented) - }; - diagnostic.set_fix(Fix::automatic(edit)); - } + let indent = clean_space(docstring.indentation); + let edit = if indent.is_empty() { + Edit::range_deletion(over_indented) + } else { + Edit::range_replacement(indent, over_indented) + }; + diagnostic.set_fix(Fix::safe_edit(edit)); checker.diagnostics.push(diagnostic); } } @@ -248,16 +257,14 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) { if line_indent.len() > docstring.indentation.len() { let mut diagnostic = Diagnostic::new(OverIndentation, TextRange::empty(last.start())); - if checker.patch(diagnostic.kind.rule()) { - let indent = clean_space(docstring.indentation); - let range = TextRange::at(last.start(), line_indent.text_len()); - let edit = if indent.is_empty() { - Edit::range_deletion(range) - } else { - Edit::range_replacement(indent, range) - }; - diagnostic.set_fix(Fix::automatic(edit)); - } + let indent = clean_space(docstring.indentation); + let range = TextRange::at(last.start(), line_indent.text_len()); + let edit = if indent.is_empty() { + Edit::range_deletion(range) + } else { + Edit::range_replacement(indent, range) + }; + diagnostic.set_fix(Fix::safe_edit(edit)); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/multi_line_summary_start.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/multi_line_summary_start.rs index f354a718dd4e8..59b618afe7b20 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/multi_line_summary_start.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/multi_line_summary_start.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::str::{is_triple_quote, leading_quote}; use ruff_python_semantic::Definition; @@ -7,7 +7,7 @@ use ruff_text_size::{Ranged, TextRange, TextSize}; use crate::checkers::ast::Checker; use crate::docstrings::Docstring; -use crate::registry::{AsRule, Rule}; +use crate::registry::Rule; /// ## What it does /// Checks for docstring summary lines that are not positioned on the first @@ -52,13 +52,13 @@ use crate::registry::{AsRule, Rule}; #[violation] pub struct MultiLineSummaryFirstLine; -impl AlwaysAutofixableViolation for MultiLineSummaryFirstLine { +impl AlwaysFixableViolation for MultiLineSummaryFirstLine { #[derive_message_formats] fn message(&self) -> String { format!("Multi-line docstring summary should start at the first line") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove whitespace after opening quotes".to_string() } } @@ -106,13 +106,13 @@ impl AlwaysAutofixableViolation for MultiLineSummaryFirstLine { #[violation] pub struct MultiLineSummarySecondLine; -impl AlwaysAutofixableViolation for MultiLineSummarySecondLine { +impl AlwaysFixableViolation for MultiLineSummarySecondLine { #[derive_message_formats] fn message(&self) -> String { format!("Multi-line docstring summary should start at the second line") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Insert line break and indentation after opening quotes".to_string() } } @@ -137,16 +137,14 @@ pub(crate) fn multi_line_summary_start(checker: &mut Checker, docstring: &Docstr if is_triple_quote(&first_line) { if checker.enabled(Rule::MultiLineSummaryFirstLine) { let mut diagnostic = Diagnostic::new(MultiLineSummaryFirstLine, docstring.range()); - if checker.patch(diagnostic.kind.rule()) { - // Delete until first non-whitespace char. - for line in content_lines { - if let Some(end_column) = line.find(|c: char| !c.is_whitespace()) { - diagnostic.set_fix(Fix::automatic(Edit::deletion( - first_line.end(), - line.start() + TextSize::try_from(end_column).unwrap(), - ))); - break; - } + // Delete until first non-whitespace char. + for line in content_lines { + if let Some(end_column) = line.find(|c: char| !c.is_whitespace()) { + diagnostic.set_fix(Fix::safe_edit(Edit::deletion( + first_line.end(), + line.start() + TextSize::try_from(end_column).unwrap(), + ))); + break; } } checker.diagnostics.push(diagnostic); @@ -163,46 +161,44 @@ pub(crate) fn multi_line_summary_start(checker: &mut Checker, docstring: &Docstr } else { if checker.enabled(Rule::MultiLineSummarySecondLine) { let mut diagnostic = Diagnostic::new(MultiLineSummarySecondLine, docstring.range()); - if checker.patch(diagnostic.kind.rule()) { - let mut indentation = String::from(docstring.indentation); - let mut fixable = true; - if !indentation.chars().all(char::is_whitespace) { - fixable = false; + let mut indentation = String::from(docstring.indentation); + let mut fixable = true; + if !indentation.chars().all(char::is_whitespace) { + fixable = false; - // If the docstring isn't on its own line, look at the statement indentation, - // and add the default indentation to get the "right" level. - if let Definition::Member(member) = &docstring.definition { - let stmt_line_start = checker.locator().line_start(member.start()); - let stmt_indentation = checker - .locator() - .slice(TextRange::new(stmt_line_start, member.start())); + // If the docstring isn't on its own line, look at the statement indentation, + // and add the default indentation to get the "right" level. + if let Definition::Member(member) = &docstring.definition { + let stmt_line_start = checker.locator().line_start(member.start()); + let stmt_indentation = checker + .locator() + .slice(TextRange::new(stmt_line_start, member.start())); - if stmt_indentation.chars().all(char::is_whitespace) { - indentation.clear(); - indentation.push_str(stmt_indentation); - indentation.push_str(checker.stylist().indentation()); - fixable = true; - } - }; - } + if stmt_indentation.chars().all(char::is_whitespace) { + indentation.clear(); + indentation.push_str(stmt_indentation); + indentation.push_str(checker.stylist().indentation()); + fixable = true; + } + }; + } - if fixable { - let prefix = leading_quote(contents).unwrap(); - // Use replacement instead of insert to trim possible whitespace between leading - // quote and text. - let repl = format!( - "{}{}{}", - checker.stylist().line_ending().as_str(), - indentation, - first_line.strip_prefix(prefix).unwrap().trim_start() - ); + if fixable { + let prefix = leading_quote(contents).unwrap(); + // Use replacement instead of insert to trim possible whitespace between leading + // quote and text. + let repl = format!( + "{}{}{}", + checker.stylist().line_ending().as_str(), + indentation, + first_line.strip_prefix(prefix).unwrap().trim_start() + ); - diagnostic.set_fix(Fix::automatic(Edit::replacement( - repl, - body.start(), - first_line.end(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::replacement( + repl, + body.start(), + first_line.end(), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/newline_after_last_paragraph.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/newline_after_last_paragraph.rs index 55b5c2015329d..b318127db94ac 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/newline_after_last_paragraph.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/newline_after_last_paragraph.rs @@ -1,6 +1,6 @@ use ruff_text_size::{TextLen, TextSize}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::docstrings::clean_space; use ruff_source_file::{NewlineWithTrailingNewline, UniversalNewlines}; @@ -8,7 +8,6 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::docstrings::Docstring; -use crate::registry::AsRule; /// ## What it does /// Checks for multi-line docstrings whose closing quotes are not on their @@ -47,13 +46,13 @@ use crate::registry::AsRule; #[violation] pub struct NewLineAfterLastParagraph; -impl AlwaysAutofixableViolation for NewLineAfterLastParagraph { +impl AlwaysFixableViolation for NewLineAfterLastParagraph { #[derive_message_formats] fn message(&self) -> String { format!("Multi-line docstring closing quotes should be on a separate line") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Move closing quotes to new line".to_string() } } @@ -81,27 +80,25 @@ pub(crate) fn newline_after_last_paragraph(checker: &mut Checker, docstring: &Do if last_line != "\"\"\"" && last_line != "'''" { let mut diagnostic = Diagnostic::new(NewLineAfterLastParagraph, docstring.range()); - if checker.patch(diagnostic.kind.rule()) { - // Insert a newline just before the end-quote(s). - let num_trailing_quotes = "'''".text_len(); - let num_trailing_spaces: TextSize = last_line - .chars() - .rev() - .skip(usize::from(num_trailing_quotes)) - .take_while(|c| c.is_whitespace()) - .map(TextLen::text_len) - .sum(); - let content = format!( - "{}{}", - checker.stylist().line_ending().as_str(), - clean_space(docstring.indentation) - ); - diagnostic.set_fix(Fix::automatic(Edit::replacement( - content, - docstring.expr.end() - num_trailing_quotes - num_trailing_spaces, - docstring.expr.end() - num_trailing_quotes, - ))); - } + // Insert a newline just before the end-quote(s). + let num_trailing_quotes = "'''".text_len(); + let num_trailing_spaces: TextSize = last_line + .chars() + .rev() + .skip(usize::from(num_trailing_quotes)) + .take_while(|c| c.is_whitespace()) + .map(TextLen::text_len) + .sum(); + let content = format!( + "{}{}", + checker.stylist().line_ending().as_str(), + clean_space(docstring.indentation) + ); + diagnostic.set_fix(Fix::safe_edit(Edit::replacement( + content, + docstring.expr.end() - num_trailing_quotes - num_trailing_spaces, + docstring.expr.end() - num_trailing_quotes, + ))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/no_surrounding_whitespace.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/no_surrounding_whitespace.rs index f4f4223255146..5c3043848869c 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/no_surrounding_whitespace.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/no_surrounding_whitespace.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_source_file::NewlineWithTrailingNewline; use ruff_text_size::Ranged; @@ -6,7 +6,7 @@ use ruff_text_size::{TextLen, TextRange}; use crate::checkers::ast::Checker; use crate::docstrings::Docstring; -use crate::registry::AsRule; + use crate::rules::pydocstyle::helpers::ends_with_backslash; /// ## What it does @@ -35,14 +35,14 @@ use crate::rules::pydocstyle::helpers::ends_with_backslash; pub struct SurroundingWhitespace; impl Violation for SurroundingWhitespace { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("No whitespaces allowed surrounding docstring text") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Trim surrounding whitespace".to_string()) } } @@ -63,17 +63,14 @@ pub(crate) fn no_surrounding_whitespace(checker: &mut Checker, docstring: &Docst return; } let mut diagnostic = Diagnostic::new(SurroundingWhitespace, docstring.range()); - if checker.patch(diagnostic.kind.rule()) { - let quote = docstring.contents.chars().last().unwrap(); - // If removing whitespace would lead to an invalid string of quote - // characters, avoid applying the fix. - if !trimmed.ends_with(quote) && !trimmed.starts_with(quote) && !ends_with_backslash(trimmed) - { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - trimmed.to_string(), - TextRange::at(body.start(), line.text_len()), - ))); - } + let quote = docstring.contents.chars().last().unwrap(); + // If removing whitespace would lead to an invalid string of quote + // characters, avoid applying the fix. + if !trimmed.ends_with(quote) && !trimmed.starts_with(quote) && !ends_with_backslash(trimmed) { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + trimmed.to_string(), + TextRange::at(body.start(), line.text_len()), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/one_liner.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/one_liner.rs index dea59eae98ce2..eac720d20b020 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/one_liner.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/one_liner.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::str::{leading_quote, trailing_quote}; use ruff_source_file::NewlineWithTrailingNewline; @@ -6,7 +6,6 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::docstrings::Docstring; -use crate::registry::AsRule; /// ## What it does /// Checks for single-line docstrings that are broken across multiple lines. @@ -37,14 +36,14 @@ use crate::registry::AsRule; pub struct FitsOnOneLine; impl Violation for FitsOnOneLine { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("One-line docstring should fit on one line") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Reformat to one line".to_string()) } } @@ -65,24 +64,22 @@ pub(crate) fn one_liner(checker: &mut Checker, docstring: &Docstring) { if non_empty_line_count == 1 && line_count > 1 { let mut diagnostic = Diagnostic::new(FitsOnOneLine, docstring.range()); - if checker.patch(diagnostic.kind.rule()) { - if let (Some(leading), Some(trailing)) = ( - leading_quote(docstring.contents), - trailing_quote(docstring.contents), - ) { - // If removing whitespace would lead to an invalid string of quote - // characters, avoid applying the fix. - let body = docstring.body(); - let trimmed = body.trim(); - if trimmed.chars().rev().take_while(|c| *c == '\\').count() % 2 == 0 - && !trimmed.ends_with(trailing.chars().last().unwrap()) - && !trimmed.starts_with(leading.chars().last().unwrap()) - { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - format!("{leading}{trimmed}{trailing}"), - docstring.range(), - ))); - } + if let (Some(leading), Some(trailing)) = ( + leading_quote(docstring.contents), + trailing_quote(docstring.contents), + ) { + // If removing whitespace would lead to an invalid string of quote + // characters, avoid applying the fix. + let body = docstring.body(); + let trimmed = body.trim(); + if trimmed.chars().rev().take_while(|c| *c == '\\').count() % 2 == 0 + && !trimmed.ends_with(trailing.chars().last().unwrap()) + && !trimmed.starts_with(leading.chars().last().unwrap()) + { + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + format!("{leading}{trimmed}{trailing}"), + docstring.range(), + ))); } } checker.diagnostics.push(diagnostic); diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/sections.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/sections.rs index c075ecacace09..393ce0deacf1b 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/sections.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/sections.rs @@ -3,7 +3,7 @@ use once_cell::sync::Lazy; use regex::Regex; use rustc_hash::FxHashSet; -use ruff_diagnostics::{AlwaysAutofixableViolation, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Violation}; use ruff_diagnostics::{Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::docstrings::{clean_space, leading_space}; @@ -18,7 +18,7 @@ use crate::checkers::ast::Checker; use crate::docstrings::sections::{SectionContext, SectionContexts, SectionKind}; use crate::docstrings::styles::SectionStyle; use crate::docstrings::Docstring; -use crate::registry::{AsRule, Rule}; +use crate::registry::Rule; use crate::rules::pydocstyle::settings::Convention; /// ## What it does @@ -88,14 +88,14 @@ pub struct SectionNotOverIndented { name: String, } -impl AlwaysAutofixableViolation for SectionNotOverIndented { +impl AlwaysFixableViolation for SectionNotOverIndented { #[derive_message_formats] fn message(&self) -> String { let SectionNotOverIndented { name } = self; format!("Section is over-indented (\"{name}\")") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let SectionNotOverIndented { name } = self; format!("Remove over-indentation from \"{name}\"") } @@ -186,14 +186,14 @@ pub struct SectionUnderlineNotOverIndented { name: String, } -impl AlwaysAutofixableViolation for SectionUnderlineNotOverIndented { +impl AlwaysFixableViolation for SectionUnderlineNotOverIndented { #[derive_message_formats] fn message(&self) -> String { let SectionUnderlineNotOverIndented { name } = self; format!("Section underline is over-indented (\"{name}\")") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let SectionUnderlineNotOverIndented { name } = self; format!("Remove over-indentation from \"{name}\" underline") } @@ -265,14 +265,14 @@ pub struct CapitalizeSectionName { name: String, } -impl AlwaysAutofixableViolation for CapitalizeSectionName { +impl AlwaysFixableViolation for CapitalizeSectionName { #[derive_message_formats] fn message(&self) -> String { let CapitalizeSectionName { name } = self; format!("Section name should be properly capitalized (\"{name}\")") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let CapitalizeSectionName { name } = self; format!("Capitalize \"{name}\"") } @@ -361,14 +361,14 @@ pub struct NewLineAfterSectionName { name: String, } -impl AlwaysAutofixableViolation for NewLineAfterSectionName { +impl AlwaysFixableViolation for NewLineAfterSectionName { #[derive_message_formats] fn message(&self) -> String { let NewLineAfterSectionName { name } = self; format!("Section name should end with a newline (\"{name}\")") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let NewLineAfterSectionName { name } = self; format!("Add newline after \"{name}\"") } @@ -457,14 +457,14 @@ pub struct DashedUnderlineAfterSection { name: String, } -impl AlwaysAutofixableViolation for DashedUnderlineAfterSection { +impl AlwaysFixableViolation for DashedUnderlineAfterSection { #[derive_message_formats] fn message(&self) -> String { let DashedUnderlineAfterSection { name } = self; format!("Missing dashed underline after section (\"{name}\")") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let DashedUnderlineAfterSection { name } = self; format!("Add dashed line under \"{name}\"") } @@ -559,14 +559,14 @@ pub struct SectionUnderlineAfterName { name: String, } -impl AlwaysAutofixableViolation for SectionUnderlineAfterName { +impl AlwaysFixableViolation for SectionUnderlineAfterName { #[derive_message_formats] fn message(&self) -> String { let SectionUnderlineAfterName { name } = self; format!("Section underline should be in the line following the section's name (\"{name}\")") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let SectionUnderlineAfterName { name } = self; format!("Add underline to \"{name}\"") } @@ -658,14 +658,14 @@ pub struct SectionUnderlineMatchesSectionLength { name: String, } -impl AlwaysAutofixableViolation for SectionUnderlineMatchesSectionLength { +impl AlwaysFixableViolation for SectionUnderlineMatchesSectionLength { #[derive_message_formats] fn message(&self) -> String { let SectionUnderlineMatchesSectionLength { name } = self; format!("Section underline should match the length of its name (\"{name}\")") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let SectionUnderlineMatchesSectionLength { name } = self; format!("Adjust underline length to match \"{name}\"") } @@ -753,14 +753,14 @@ pub struct NoBlankLineAfterSection { name: String, } -impl AlwaysAutofixableViolation for NoBlankLineAfterSection { +impl AlwaysFixableViolation for NoBlankLineAfterSection { #[derive_message_formats] fn message(&self) -> String { let NoBlankLineAfterSection { name } = self; format!("Missing blank line after section (\"{name}\")") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let NoBlankLineAfterSection { name } = self; format!("Add blank line after \"{name}\"") } @@ -846,14 +846,14 @@ pub struct NoBlankLineBeforeSection { name: String, } -impl AlwaysAutofixableViolation for NoBlankLineBeforeSection { +impl AlwaysFixableViolation for NoBlankLineBeforeSection { #[derive_message_formats] fn message(&self) -> String { let NoBlankLineBeforeSection { name } = self; format!("Missing blank line before section (\"{name}\")") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let NoBlankLineBeforeSection { name } = self; format!("Add blank line before \"{name}\"") } @@ -942,14 +942,14 @@ pub struct BlankLineAfterLastSection { name: String, } -impl AlwaysAutofixableViolation for BlankLineAfterLastSection { +impl AlwaysFixableViolation for BlankLineAfterLastSection { #[derive_message_formats] fn message(&self) -> String { let BlankLineAfterLastSection { name } = self; format!("Missing blank line after last section (\"{name}\")") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let BlankLineAfterLastSection { name } = self; format!("Add blank line after \"{name}\"") } @@ -1109,14 +1109,14 @@ pub struct SectionNameEndsInColon { name: String, } -impl AlwaysAutofixableViolation for SectionNameEndsInColon { +impl AlwaysFixableViolation for SectionNameEndsInColon { #[derive_message_formats] fn message(&self) -> String { let SectionNameEndsInColon { name } = self; format!("Section name should end with a colon (\"{name}\")") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let SectionNameEndsInColon { name } = self; format!("Add colon to \"{name}\"") } @@ -1276,14 +1276,14 @@ pub struct BlankLinesBetweenHeaderAndContent { name: String, } -impl AlwaysAutofixableViolation for BlankLinesBetweenHeaderAndContent { +impl AlwaysFixableViolation for BlankLinesBetweenHeaderAndContent { #[derive_message_formats] fn message(&self) -> String { let BlankLinesBetweenHeaderAndContent { name } = self; format!("No blank lines allowed between a section header and its content (\"{name}\")") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove blank line(s)".to_string() } } @@ -1388,12 +1388,9 @@ fn blanks_and_section_underline( }, docstring.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let range = - TextRange::new(context.following_range().start(), blank_lines_end); - // Delete any blank lines between the header and the underline. - diagnostic.set_fix(Fix::automatic(Edit::range_deletion(range))); - } + let range = TextRange::new(context.following_range().start(), blank_lines_end); + // Delete any blank lines between the header and the underline. + diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(range))); checker.diagnostics.push(diagnostic); } } @@ -1412,20 +1409,18 @@ fn blanks_and_section_underline( }, docstring.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // Replace the existing underline with a line of the appropriate length. - let content = format!( - "{}{}{}", - clean_space(docstring.indentation), - "-".repeat(context.section_name().len()), - checker.stylist().line_ending().as_str() - ); - diagnostic.set_fix(Fix::automatic(Edit::replacement( - content, - blank_lines_end, - non_blank_line.full_end(), - ))); - }; + // Replace the existing underline with a line of the appropriate length. + let content = format!( + "{}{}{}", + clean_space(docstring.indentation), + "-".repeat(context.section_name().len()), + checker.stylist().line_ending().as_str() + ); + diagnostic.set_fix(Fix::safe_edit(Edit::replacement( + content, + blank_lines_end, + non_blank_line.full_end(), + ))); checker.diagnostics.push(diagnostic); } } @@ -1439,19 +1434,17 @@ fn blanks_and_section_underline( }, docstring.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // Replace the existing indentation with whitespace of the appropriate length. - let range = TextRange::at( - blank_lines_end, - leading_space.text_len() + TextSize::from(1), - ); - let contents = clean_space(docstring.indentation); - diagnostic.set_fix(Fix::automatic(if contents.is_empty() { - Edit::range_deletion(range) - } else { - Edit::range_replacement(contents, range) - })); - }; + // Replace the existing indentation with whitespace of the appropriate length. + let range = TextRange::at( + blank_lines_end, + leading_space.text_len() + TextSize::from(1), + ); + let contents = clean_space(docstring.indentation); + diagnostic.set_fix(Fix::safe_edit(if contents.is_empty() { + Edit::range_deletion(range) + } else { + Edit::range_replacement(contents, range) + })); checker.diagnostics.push(diagnostic); } } @@ -1484,13 +1477,11 @@ fn blanks_and_section_underline( }, docstring.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // Delete any blank lines between the header and content. - diagnostic.set_fix(Fix::automatic(Edit::deletion( - line_after_dashes.start(), - blank_lines_after_dashes_end, - ))); - } + // Delete any blank lines between the header and content. + diagnostic.set_fix(Fix::safe_edit(Edit::deletion( + line_after_dashes.start(), + blank_lines_after_dashes_end, + ))); checker.diagnostics.push(diagnostic); } } @@ -1516,31 +1507,29 @@ fn blanks_and_section_underline( }, docstring.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // Add a dashed line (of the appropriate length) under the section header. - let content = format!( - "{}{}{}", - checker.stylist().line_ending().as_str(), - clean_space(docstring.indentation), - "-".repeat(context.section_name().len()), - ); - if equal_line_found - && non_blank_line.trim_whitespace().len() == context.section_name().len() - { - // If an existing underline is an equal sign line of the appropriate length, - // replace it with a dashed line. - diagnostic.set_fix(Fix::automatic(Edit::replacement( - content, - context.summary_range().end(), - non_blank_line.end(), - ))); - } else { - // Otherwise, insert a dashed line after the section header. - diagnostic.set_fix(Fix::automatic(Edit::insertion( - content, - context.summary_range().end(), - ))); - } + // Add a dashed line (of the appropriate length) under the section header. + let content = format!( + "{}{}{}", + checker.stylist().line_ending().as_str(), + clean_space(docstring.indentation), + "-".repeat(context.section_name().len()), + ); + if equal_line_found + && non_blank_line.trim_whitespace().len() == context.section_name().len() + { + // If an existing underline is an equal sign line of the appropriate length, + // replace it with a dashed line. + diagnostic.set_fix(Fix::safe_edit(Edit::replacement( + content, + context.summary_range().end(), + non_blank_line.end(), + ))); + } else { + // Otherwise, insert a dashed line after the section header. + diagnostic.set_fix(Fix::safe_edit(Edit::insertion( + content, + context.summary_range().end(), + ))); } checker.diagnostics.push(diagnostic); } @@ -1552,12 +1541,9 @@ fn blanks_and_section_underline( }, docstring.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let range = - TextRange::new(context.following_range().start(), blank_lines_end); - // Delete any blank lines between the header and content. - diagnostic.set_fix(Fix::automatic(Edit::range_deletion(range))); - } + let range = TextRange::new(context.following_range().start(), blank_lines_end); + // Delete any blank lines between the header and content. + diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(range))); checker.diagnostics.push(diagnostic); } } @@ -1572,20 +1558,18 @@ fn blanks_and_section_underline( }, docstring.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // Add a dashed line (of the appropriate length) under the section header. - let content = format!( - "{}{}{}", - checker.stylist().line_ending().as_str(), - clean_space(docstring.indentation), - "-".repeat(context.section_name().len()), - ); + // Add a dashed line (of the appropriate length) under the section header. + let content = format!( + "{}{}{}", + checker.stylist().line_ending().as_str(), + clean_space(docstring.indentation), + "-".repeat(context.section_name().len()), + ); - diagnostic.set_fix(Fix::automatic(Edit::insertion( - content, - context.summary_range().end(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::insertion( + content, + context.summary_range().end(), + ))); checker.diagnostics.push(diagnostic); } if checker.enabled(Rule::EmptyDocstringSection) { @@ -1614,15 +1598,13 @@ fn common_section( }, docstring.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // Replace the section title with the capitalized variant. This requires - // locating the start and end of the section name. - let section_range = context.section_name_range(); - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - capitalized_section_name.to_string(), - section_range, - ))); - } + // Replace the section title with the capitalized variant. This requires + // locating the start and end of the section name. + let section_range = context.section_name_range(); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + capitalized_section_name.to_string(), + section_range, + ))); checker.diagnostics.push(diagnostic); } } @@ -1636,17 +1618,15 @@ fn common_section( }, docstring.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // Replace the existing indentation with whitespace of the appropriate length. - let content = clean_space(docstring.indentation); - let fix_range = TextRange::at(context.start(), leading_space.text_len()); + // Replace the existing indentation with whitespace of the appropriate length. + let content = clean_space(docstring.indentation); + let fix_range = TextRange::at(context.start(), leading_space.text_len()); - diagnostic.set_fix(Fix::automatic(if content.is_empty() { - Edit::range_deletion(fix_range) - } else { - Edit::range_replacement(content, fix_range) - })); - }; + diagnostic.set_fix(Fix::safe_edit(if content.is_empty() { + Edit::range_deletion(fix_range) + } else { + Edit::range_replacement(content, fix_range) + })); checker.diagnostics.push(diagnostic); } } @@ -1662,13 +1642,11 @@ fn common_section( }, docstring.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // Add a newline at the beginning of the next section. - diagnostic.set_fix(Fix::automatic(Edit::insertion( - line_end.to_string(), - next.start(), - ))); - } + // Add a newline at the beginning of the next section. + diagnostic.set_fix(Fix::safe_edit(Edit::insertion( + line_end.to_string(), + next.start(), + ))); checker.diagnostics.push(diagnostic); } } else { @@ -1679,13 +1657,11 @@ fn common_section( }, docstring.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // Add a newline after the section. - diagnostic.set_fix(Fix::automatic(Edit::insertion( - format!("{}{}", line_end, docstring.indentation), - context.end(), - ))); - } + // Add a newline after the section. + diagnostic.set_fix(Fix::safe_edit(Edit::insertion( + format!("{}{}", line_end, docstring.indentation), + context.end(), + ))); checker.diagnostics.push(diagnostic); } } @@ -1702,13 +1678,11 @@ fn common_section( }, docstring.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // Add a blank line before the section. - diagnostic.set_fix(Fix::automatic(Edit::insertion( - line_end.to_string(), - context.start(), - ))); - } + // Add a blank line before the section. + diagnostic.set_fix(Fix::safe_edit(Edit::insertion( + line_end.to_string(), + context.start(), + ))); checker.diagnostics.push(diagnostic); } } @@ -1898,13 +1872,11 @@ fn numpy_section( }, docstring.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let section_range = context.section_name_range(); - diagnostic.set_fix(Fix::automatic(Edit::range_deletion(TextRange::at( - section_range.end(), - suffix.text_len(), - )))); - } + let section_range = context.section_name_range(); + diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(TextRange::at( + section_range.end(), + suffix.text_len(), + )))); checker.diagnostics.push(diagnostic); } @@ -1934,14 +1906,12 @@ fn google_section( }, docstring.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // Replace the suffix. - let section_name_range = context.section_name_range(); - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - ":".to_string(), - TextRange::at(section_name_range.end(), suffix.text_len()), - ))); - } + // Replace the suffix. + let section_name_range = context.section_name_range(); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + ":".to_string(), + TextRange::at(section_name_range.end(), suffix.text_len()), + ))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/triple_quotes.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/triple_quotes.rs index c8b7d6208a80c..eb7caaec2460c 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/triple_quotes.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/triple_quotes.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_codegen::Quote; use ruff_text_size::Ranged; @@ -37,6 +37,8 @@ pub struct TripleSingleQuotes { } impl Violation for TripleSingleQuotes { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; + #[derive_message_formats] fn message(&self) -> String { let TripleSingleQuotes { expected_quote } = self; @@ -45,12 +47,25 @@ impl Violation for TripleSingleQuotes { Quote::Single => format!(r#"Use triple single quotes `'''`"#), } } + + fn fix_title(&self) -> Option { + let TripleSingleQuotes { expected_quote } = self; + Some(match expected_quote { + Quote::Double => format!("Convert to triple double quotes"), + Quote::Single => format!("Convert to triple single quotes"), + }) + } } /// D300 pub(crate) fn triple_quotes(checker: &mut Checker, docstring: &Docstring) { let leading_quote = docstring.leading_quote(); + let prefixes = docstring + .leading_quote() + .trim_end_matches(|c| c == '\'' || c == '"') + .to_owned(); + let expected_quote = if docstring.body().contains("\"\"\"") { Quote::Single } else { @@ -60,18 +75,38 @@ pub(crate) fn triple_quotes(checker: &mut Checker, docstring: &Docstring) { match expected_quote { Quote::Single => { if !leading_quote.ends_with("'''") { - checker.diagnostics.push(Diagnostic::new( - TripleSingleQuotes { expected_quote }, - docstring.range(), - )); + let mut diagnostic = + Diagnostic::new(TripleSingleQuotes { expected_quote }, docstring.range()); + + if checker.settings.preview.is_enabled() { + let body = docstring.body().as_str(); + if !body.ends_with('\'') { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + format!("{prefixes}'''{body}'''"), + docstring.range(), + ))); + } + } + + checker.diagnostics.push(diagnostic); } } Quote::Double => { if !leading_quote.ends_with("\"\"\"") { - checker.diagnostics.push(Diagnostic::new( - TripleSingleQuotes { expected_quote }, - docstring.range(), - )); + let mut diagnostic = + Diagnostic::new(TripleSingleQuotes { expected_quote }, docstring.range()); + + if checker.settings.preview.is_enabled() { + let body = docstring.body().as_str(); + if !body.ends_with('"') { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + format!("{prefixes}\"\"\"{body}\"\"\""), + docstring.range(), + ))); + } + } + + checker.diagnostics.push(diagnostic); } } } diff --git a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D300_D.py.snap b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D300_D.py.snap index dbf703c165317..6340613a91b53 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D300_D.py.snap +++ b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D300_D.py.snap @@ -8,6 +8,7 @@ D.py:307:5: D300 Use triple double quotes `"""` 307 | r'''Summary.''' | ^^^^^^^^^^^^^^^ D300 | + = help: Convert to triple double quotes D.py:312:5: D300 Use triple double quotes `"""` | @@ -16,6 +17,7 @@ D.py:312:5: D300 Use triple double quotes `"""` 312 | R'''Summary.''' | ^^^^^^^^^^^^^^^ D300 | + = help: Convert to triple double quotes D.py:317:5: D300 Use triple double quotes `"""` | @@ -24,6 +26,7 @@ D.py:317:5: D300 Use triple double quotes `"""` 317 | r'Summary.' | ^^^^^^^^^^^ D300 | + = help: Convert to triple double quotes D.py:322:5: D300 Use triple double quotes `"""` | @@ -32,6 +35,7 @@ D.py:322:5: D300 Use triple double quotes `"""` 322 | R'Summary.' | ^^^^^^^^^^^ D300 | + = help: Convert to triple double quotes D.py:328:5: D300 Use triple double quotes `"""` | @@ -40,6 +44,7 @@ D.py:328:5: D300 Use triple double quotes `"""` 328 | R'Sum\mary.' | ^^^^^^^^^^^^ D300 | + = help: Convert to triple double quotes D.py:645:5: D300 Use triple double quotes `"""` | @@ -51,6 +56,7 @@ D.py:645:5: D300 Use triple double quotes `"""` 647 | 648 | class StatementOnSameLineAsDocstring: | + = help: Convert to triple double quotes D.py:649:5: D300 Use triple double quotes `"""` | @@ -60,6 +66,7 @@ D.py:649:5: D300 Use triple double quotes `"""` 650 | def sort_services(self): 651 | pass | + = help: Convert to triple double quotes D.py:654:5: D300 Use triple double quotes `"""` | @@ -67,6 +74,7 @@ D.py:654:5: D300 Use triple double quotes `"""` 654 | "After this docstring there's another statement on the same line separated by a semicolon."; priorities=1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D300 | + = help: Convert to triple double quotes D.py:658:5: D300 Use triple double quotes `"""` | @@ -76,6 +84,7 @@ D.py:658:5: D300 Use triple double quotes `"""` 659 | def sort_services(self): 660 | pass | + = help: Convert to triple double quotes D.py:664:5: D300 Use triple double quotes `"""` | @@ -85,5 +94,6 @@ D.py:664:5: D300 Use triple double quotes `"""` 665 | | but continuations shouldn't be considered multi-line" | |_________________________________________________________^ D300 | + = help: Convert to triple double quotes diff --git a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D300_D300.py.snap b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D300_D300.py.snap new file mode 100644 index 0000000000000..6f2b1e71b4683 --- /dev/null +++ b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D300_D300.py.snap @@ -0,0 +1,20 @@ +--- +source: crates/ruff_linter/src/rules/pydocstyle/mod.rs +--- +D300.py:6:5: D300 Use triple double quotes `"""` + | +5 | def ends_in_quote(): +6 | 'Sum\\mary."' + | ^^^^^^^^^^^^^ D300 + | + = help: Convert to triple double quotes + +D300.py:10:5: D300 Use triple double quotes `"""` + | + 9 | def contains_quote(): +10 | 'Sum"\\mary.' + | ^^^^^^^^^^^^^ D300 + | + = help: Convert to triple double quotes + + diff --git a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D301_D.py.snap b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D301_D.py.snap index 9c2880c067cbe..640d797182a99 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D301_D.py.snap +++ b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D301_D.py.snap @@ -1,28 +1,23 @@ --- source: crates/ruff_linter/src/rules/pydocstyle/mod.rs --- -D.py:328:5: D301 Use `r"""` if any backslashes in a docstring - | -326 | @expect('D301: Use r""" if any backslashes in a docstring') -327 | def single_quotes_raw_uppercase_backslash(): -328 | R'Sum\mary.' - | ^^^^^^^^^^^^ D301 - | - -D.py:333:5: D301 Use `r"""` if any backslashes in a docstring +D.py:333:5: D301 [*] Use `r"""` if any backslashes in a docstring | 331 | @expect('D301: Use r""" if any backslashes in a docstring') 332 | def double_quotes_backslash(): 333 | """Sum\\mary.""" | ^^^^^^^^^^^^^^^^ D301 | + = help: Add `r` prefix -D.py:338:5: D301 Use `r"""` if any backslashes in a docstring - | -336 | @expect('D301: Use r""" if any backslashes in a docstring') -337 | def double_quotes_backslash_uppercase(): -338 | R"""Sum\\mary.""" - | ^^^^^^^^^^^^^^^^^ D301 - | +ℹ Suggested fix +330 330 | +331 331 | @expect('D301: Use r""" if any backslashes in a docstring') +332 332 | def double_quotes_backslash(): +333 |- """Sum\\mary.""" + 333 |+ r"""Sum\\mary.""" +334 334 | +335 335 | +336 336 | @expect('D301: Use r""" if any backslashes in a docstring') diff --git a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D301_D301.py.snap b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D301_D301.py.snap index 5ee1cedd052d7..f64cbcd59ad57 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D301_D301.py.snap +++ b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D301_D301.py.snap @@ -1,18 +1,20 @@ --- source: crates/ruff_linter/src/rules/pydocstyle/mod.rs --- -D301.py:2:5: D301 Use `r"""` if any backslashes in a docstring +D301.py:2:5: D301 [*] Use `r"""` if any backslashes in a docstring | 1 | def double_quotes_backslash(): 2 | """Sum\\mary.""" | ^^^^^^^^^^^^^^^^ D301 | + = help: Add `r` prefix -D301.py:10:5: D301 Use `r"""` if any backslashes in a docstring - | - 9 | def double_quotes_backslash_uppercase(): -10 | R"""Sum\\mary.""" - | ^^^^^^^^^^^^^^^^^ D301 - | +ℹ Suggested fix +1 1 | def double_quotes_backslash(): +2 |- """Sum\\mary.""" + 2 |+ r"""Sum\\mary.""" +3 3 | +4 4 | +5 5 | def double_quotes_backslash_raw(): diff --git a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__bom.snap b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__bom.snap index 1c7757d4b4b3e..10f9417ddf3e1 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__bom.snap +++ b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__bom.snap @@ -6,5 +6,6 @@ bom.py:1:1: D300 Use triple double quotes `"""` 1 | ''' SAM macro definitions ''' | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D300 | + = help: Convert to triple double quotes diff --git a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__preview__D300_D.py.snap b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__preview__D300_D.py.snap new file mode 100644 index 0000000000000..419c4e237ae64 --- /dev/null +++ b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__preview__D300_D.py.snap @@ -0,0 +1,200 @@ +--- +source: crates/ruff_linter/src/rules/pydocstyle/mod.rs +--- +D.py:307:5: D300 [*] Use triple double quotes `"""` + | +305 | @expect('D300: Use """triple double quotes""" (found \'\'\'-quotes)') +306 | def triple_single_quotes_raw(): +307 | r'''Summary.''' + | ^^^^^^^^^^^^^^^ D300 + | + = help: Convert to triple double quotes + +ℹ Fix +304 304 | +305 305 | @expect('D300: Use """triple double quotes""" (found \'\'\'-quotes)') +306 306 | def triple_single_quotes_raw(): +307 |- r'''Summary.''' + 307 |+ r"""Summary.""" +308 308 | +309 309 | +310 310 | @expect('D300: Use """triple double quotes""" (found \'\'\'-quotes)') + +D.py:312:5: D300 [*] Use triple double quotes `"""` + | +310 | @expect('D300: Use """triple double quotes""" (found \'\'\'-quotes)') +311 | def triple_single_quotes_raw_uppercase(): +312 | R'''Summary.''' + | ^^^^^^^^^^^^^^^ D300 + | + = help: Convert to triple double quotes + +ℹ Fix +309 309 | +310 310 | @expect('D300: Use """triple double quotes""" (found \'\'\'-quotes)') +311 311 | def triple_single_quotes_raw_uppercase(): +312 |- R'''Summary.''' + 312 |+ R"""Summary.""" +313 313 | +314 314 | +315 315 | @expect('D300: Use """triple double quotes""" (found \'-quotes)') + +D.py:317:5: D300 [*] Use triple double quotes `"""` + | +315 | @expect('D300: Use """triple double quotes""" (found \'-quotes)') +316 | def single_quotes_raw(): +317 | r'Summary.' + | ^^^^^^^^^^^ D300 + | + = help: Convert to triple double quotes + +ℹ Fix +314 314 | +315 315 | @expect('D300: Use """triple double quotes""" (found \'-quotes)') +316 316 | def single_quotes_raw(): +317 |- r'Summary.' + 317 |+ r"""Summary.""" +318 318 | +319 319 | +320 320 | @expect('D300: Use """triple double quotes""" (found \'-quotes)') + +D.py:322:5: D300 [*] Use triple double quotes `"""` + | +320 | @expect('D300: Use """triple double quotes""" (found \'-quotes)') +321 | def single_quotes_raw_uppercase(): +322 | R'Summary.' + | ^^^^^^^^^^^ D300 + | + = help: Convert to triple double quotes + +ℹ Fix +319 319 | +320 320 | @expect('D300: Use """triple double quotes""" (found \'-quotes)') +321 321 | def single_quotes_raw_uppercase(): +322 |- R'Summary.' + 322 |+ R"""Summary.""" +323 323 | +324 324 | +325 325 | @expect('D300: Use """triple double quotes""" (found \'-quotes)') + +D.py:328:5: D300 [*] Use triple double quotes `"""` + | +326 | @expect('D301: Use r""" if any backslashes in a docstring') +327 | def single_quotes_raw_uppercase_backslash(): +328 | R'Sum\mary.' + | ^^^^^^^^^^^^ D300 + | + = help: Convert to triple double quotes + +ℹ Fix +325 325 | @expect('D300: Use """triple double quotes""" (found \'-quotes)') +326 326 | @expect('D301: Use r""" if any backslashes in a docstring') +327 327 | def single_quotes_raw_uppercase_backslash(): +328 |- R'Sum\mary.' + 328 |+ R"""Sum\mary.""" +329 329 | +330 330 | +331 331 | @expect('D301: Use r""" if any backslashes in a docstring') + +D.py:645:5: D300 [*] Use triple double quotes `"""` + | +644 | def single_line_docstring_with_an_escaped_backslash(): +645 | "\ + | _____^ +646 | | " + | |_____^ D300 +647 | +648 | class StatementOnSameLineAsDocstring: + | + = help: Convert to triple double quotes + +ℹ Fix +642 642 | +643 643 | +644 644 | def single_line_docstring_with_an_escaped_backslash(): +645 |- "\ +646 |- " + 645 |+ """\ + 646 |+ """ +647 647 | +648 648 | class StatementOnSameLineAsDocstring: +649 649 | "After this docstring there's another statement on the same line separated by a semicolon." ; priorities=1 + +D.py:649:5: D300 [*] Use triple double quotes `"""` + | +648 | class StatementOnSameLineAsDocstring: +649 | "After this docstring there's another statement on the same line separated by a semicolon." ; priorities=1 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D300 +650 | def sort_services(self): +651 | pass + | + = help: Convert to triple double quotes + +ℹ Fix +646 646 | " +647 647 | +648 648 | class StatementOnSameLineAsDocstring: +649 |- "After this docstring there's another statement on the same line separated by a semicolon." ; priorities=1 + 649 |+ """After this docstring there's another statement on the same line separated by a semicolon.""" ; priorities=1 +650 650 | def sort_services(self): +651 651 | pass +652 652 | + +D.py:654:5: D300 [*] Use triple double quotes `"""` + | +653 | class StatementOnSameLineAsDocstring: +654 | "After this docstring there's another statement on the same line separated by a semicolon."; priorities=1 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D300 + | + = help: Convert to triple double quotes + +ℹ Fix +651 651 | pass +652 652 | +653 653 | class StatementOnSameLineAsDocstring: +654 |- "After this docstring there's another statement on the same line separated by a semicolon."; priorities=1 + 654 |+ """After this docstring there's another statement on the same line separated by a semicolon."""; priorities=1 +655 655 | +656 656 | +657 657 | class CommentAfterDocstring: + +D.py:658:5: D300 [*] Use triple double quotes `"""` + | +657 | class CommentAfterDocstring: +658 | "After this docstring there's a comment." # priorities=1 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D300 +659 | def sort_services(self): +660 | pass + | + = help: Convert to triple double quotes + +ℹ Fix +655 655 | +656 656 | +657 657 | class CommentAfterDocstring: +658 |- "After this docstring there's a comment." # priorities=1 + 658 |+ """After this docstring there's a comment.""" # priorities=1 +659 659 | def sort_services(self): +660 660 | pass +661 661 | + +D.py:664:5: D300 [*] Use triple double quotes `"""` + | +663 | def newline_after_closing_quote(self): +664 | "We enforce a newline after the closing quote for a multi-line docstring \ + | _____^ +665 | | but continuations shouldn't be considered multi-line" + | |_________________________________________________________^ D300 + | + = help: Convert to triple double quotes + +ℹ Fix +661 661 | +662 662 | +663 663 | def newline_after_closing_quote(self): +664 |- "We enforce a newline after the closing quote for a multi-line docstring \ +665 |- but continuations shouldn't be considered multi-line" + 664 |+ """We enforce a newline after the closing quote for a multi-line docstring \ + 665 |+ but continuations shouldn't be considered multi-line""" + + diff --git a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__preview__D300_D300.py.snap b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__preview__D300_D300.py.snap new file mode 100644 index 0000000000000..3b1b637e90a4c --- /dev/null +++ b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__preview__D300_D300.py.snap @@ -0,0 +1,27 @@ +--- +source: crates/ruff_linter/src/rules/pydocstyle/mod.rs +--- +D300.py:6:5: D300 Use triple double quotes `"""` + | +5 | def ends_in_quote(): +6 | 'Sum\\mary."' + | ^^^^^^^^^^^^^ D300 + | + = help: Convert to triple double quotes + +D300.py:10:5: D300 [*] Use triple double quotes `"""` + | + 9 | def contains_quote(): +10 | 'Sum"\\mary.' + | ^^^^^^^^^^^^^ D300 + | + = help: Convert to triple double quotes + +ℹ Fix +7 7 | +8 8 | +9 9 | def contains_quote(): +10 |- 'Sum"\\mary.' + 10 |+ """Sum"\\mary.""" + + diff --git a/crates/ruff_linter/src/rules/pyflakes/mod.rs b/crates/ruff_linter/src/rules/pyflakes/mod.rs index 1ce5133933c91..4cb3a9f8953b5 100644 --- a/crates/ruff_linter/src/rules/pyflakes/mod.rs +++ b/crates/ruff_linter/src/rules/pyflakes/mod.rs @@ -50,6 +50,7 @@ mod tests { #[test_case(Rule::UnusedImport, Path::new("F401_16.py"))] #[test_case(Rule::UnusedImport, Path::new("F401_17.py"))] #[test_case(Rule::UnusedImport, Path::new("F401_18.py"))] + #[test_case(Rule::UnusedImport, Path::new("F401_19.py"))] #[test_case(Rule::ImportShadowedByLoopVar, Path::new("F402.py"))] #[test_case(Rule::UndefinedLocalWithImportStar, Path::new("F403.py"))] #[test_case(Rule::LateFutureImport, Path::new("F404.py"))] @@ -133,6 +134,9 @@ mod tests { #[test_case(Rule::UndefinedName, Path::new("F821_15.py"))] #[test_case(Rule::UndefinedName, Path::new("F821_16.py"))] #[test_case(Rule::UndefinedName, Path::new("F821_17.py"))] + #[test_case(Rule::UndefinedName, Path::new("F821_18.py"))] + #[test_case(Rule::UndefinedName, Path::new("F821_19.py"))] + #[test_case(Rule::UndefinedName, Path::new("F821_20.py"))] #[test_case(Rule::UndefinedExport, Path::new("F822_0.py"))] #[test_case(Rule::UndefinedExport, Path::new("F822_1.py"))] #[test_case(Rule::UndefinedExport, Path::new("F822_2.py"))] diff --git a/crates/ruff_linter/src/rules/pyflakes/rules/f_string_missing_placeholders.rs b/crates/ruff_linter/src/rules/pyflakes/rules/f_string_missing_placeholders.rs index 779ed539bb7c1..448959149e826 100644 --- a/crates/ruff_linter/src/rules/pyflakes/rules/f_string_missing_placeholders.rs +++ b/crates/ruff_linter/src/rules/pyflakes/rules/f_string_missing_placeholders.rs @@ -1,12 +1,11 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::{Expr, PySourceType}; -use ruff_python_parser::{lexer, AsMode, StringKind, Tok}; +use ruff_python_ast::{self as ast, Expr, PySourceType}; +use ruff_python_parser::{lexer, AsMode, Tok}; use ruff_source_file::Locator; use ruff_text_size::{Ranged, TextRange, TextSize}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for f-strings that do not contain any placeholder expressions. @@ -36,42 +35,65 @@ use crate::registry::AsRule; #[violation] pub struct FStringMissingPlaceholders; -impl AlwaysAutofixableViolation for FStringMissingPlaceholders { +impl AlwaysFixableViolation for FStringMissingPlaceholders { #[derive_message_formats] fn message(&self) -> String { format!("f-string without any placeholders") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove extraneous `f` prefix".to_string() } } -/// Find f-strings that don't contain any formatted values in an [`FString`]. -fn find_useless_f_strings<'a>( - expr: &'a Expr, +/// Return an iterator containing a two-element tuple for each f-string part +/// in the given [`ExprFString`] expression. +/// +/// The first element of the tuple is the f-string prefix range, and the second +/// element is the entire f-string range. It returns an iterator because of the +/// possibility of multiple f-strings implicitly concatenated together. +/// +/// For example, +/// +/// ```python +/// f"first" rf"second" +/// # ^ ^ (prefix range) +/// # ^^^^^^^^ ^^^^^^^^^^ (token range) +/// ``` +/// +/// would return `[(0..1, 0..8), (10..11, 9..19)]`. +/// +/// This function assumes that the given f-string expression is without any +/// placeholder expressions. +/// +/// [`ExprFString`]: `ruff_python_ast::ExprFString` +fn fstring_prefix_and_tok_range<'a>( + fstring: &'a ast::ExprFString, locator: &'a Locator, source_type: PySourceType, ) -> impl Iterator + 'a { - let contents = locator.slice(expr); - lexer::lex_starts_at(contents, source_type.as_mode(), expr.start()) + let contents = locator.slice(fstring); + let mut current_f_string_start = fstring.start(); + lexer::lex_starts_at(contents, source_type.as_mode(), fstring.start()) .flatten() - .filter_map(|(tok, range)| match tok { - Tok::String { - kind: StringKind::FString | StringKind::RawFString, - .. - } => { - let first_char = locator.slice(TextRange::at(range.start(), TextSize::from(1))); + .filter_map(move |(tok, range)| match tok { + Tok::FStringStart => { + current_f_string_start = range.start(); + None + } + Tok::FStringEnd => { + let first_char = + locator.slice(TextRange::at(current_f_string_start, TextSize::from(1))); // f"..." => f_position = 0 // fr"..." => f_position = 0 // rf"..." => f_position = 1 let f_position = u32::from(!(first_char == "f" || first_char == "F")); Some(( TextRange::at( - range.start() + TextSize::from(f_position), + current_f_string_start + TextSize::from(f_position), TextSize::from(1), ), - range, + TextRange::new(current_f_string_start, range.end()), )) } _ => None, @@ -79,22 +101,17 @@ fn find_useless_f_strings<'a>( } /// F541 -pub(crate) fn f_string_missing_placeholders(expr: &Expr, values: &[Expr], checker: &mut Checker) { - if !values - .iter() - .any(|value| matches!(value, Expr::FormattedValue(_))) - { +pub(crate) fn f_string_missing_placeholders(fstring: &ast::ExprFString, checker: &mut Checker) { + if !fstring.values.iter().any(Expr::is_formatted_value_expr) { for (prefix_range, tok_range) in - find_useless_f_strings(expr, checker.locator(), checker.source_type) + fstring_prefix_and_tok_range(fstring, checker.locator(), checker.source_type) { let mut diagnostic = Diagnostic::new(FStringMissingPlaceholders, tok_range); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(convert_f_string_to_regular_string( - prefix_range, - tok_range, - checker.locator(), - )); - } + diagnostic.set_fix(convert_f_string_to_regular_string( + prefix_range, + tok_range, + checker.locator(), + )); checker.diagnostics.push(diagnostic); } } @@ -131,7 +148,7 @@ fn convert_f_string_to_regular_string( content.insert(0, ' '); } - Fix::automatic(Edit::replacement( + Fix::safe_edit(Edit::replacement( content, prefix_range.start(), tok_range.end(), diff --git a/crates/ruff_linter/src/rules/pyflakes/rules/invalid_literal_comparisons.rs b/crates/ruff_linter/src/rules/pyflakes/rules/invalid_literal_comparisons.rs index c4d0364b28456..1f8e85ad9dd68 100644 --- a/crates/ruff_linter/src/rules/pyflakes/rules/invalid_literal_comparisons.rs +++ b/crates/ruff_linter/src/rules/pyflakes/rules/invalid_literal_comparisons.rs @@ -1,14 +1,13 @@ use log::error; use ruff_python_ast::{CmpOp, Expr}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers; use ruff_python_parser::locate_cmp_ops; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for `is` and `is not` comparisons against constant literals, like @@ -50,7 +49,7 @@ pub struct IsLiteral { cmp_op: IsCmpOp, } -impl AlwaysAutofixableViolation for IsLiteral { +impl AlwaysFixableViolation for IsLiteral { #[derive_message_formats] fn message(&self) -> String { let IsLiteral { cmp_op } = self; @@ -60,7 +59,7 @@ impl AlwaysAutofixableViolation for IsLiteral { } } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let IsLiteral { cmp_op } = self; match cmp_op { IsCmpOp::Is => "Replace `is` with `==`".to_string(), @@ -85,30 +84,26 @@ pub(crate) fn invalid_literal_comparison( || helpers::is_constant_non_singleton(right)) { let mut diagnostic = Diagnostic::new(IsLiteral { cmp_op: op.into() }, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - if lazy_located.is_none() { - lazy_located = Some(locate_cmp_ops(expr, checker.locator().contents())); - } - if let Some(located_op) = - lazy_located.as_ref().and_then(|located| located.get(index)) - { - assert_eq!(located_op.op, *op); - if let Some(content) = match located_op.op { - CmpOp::Is => Some("==".to_string()), - CmpOp::IsNot => Some("!=".to_string()), - node => { - error!("Failed to fix invalid comparison: {node:?}"); - None - } - } { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - content, - located_op.range + expr.start(), - ))); + if lazy_located.is_none() { + lazy_located = Some(locate_cmp_ops(expr, checker.locator().contents())); + } + if let Some(located_op) = lazy_located.as_ref().and_then(|located| located.get(index)) { + assert_eq!(located_op.op, *op); + if let Some(content) = match located_op.op { + CmpOp::Is => Some("==".to_string()), + CmpOp::IsNot => Some("!=".to_string()), + node => { + error!("Failed to fix invalid comparison: {node:?}"); + None } - } else { - error!("Failed to fix invalid comparison due to missing op"); + } { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + content, + located_op.range + expr.start(), + ))); } + } else { + error!("Failed to fix invalid comparison due to missing op"); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyflakes/rules/raise_not_implemented.rs b/crates/ruff_linter/src/rules/pyflakes/rules/raise_not_implemented.rs index 6fad3fde6d869..3a48fe902f77c 100644 --- a/crates/ruff_linter/src/rules/pyflakes/rules/raise_not_implemented.rs +++ b/crates/ruff_linter/src/rules/pyflakes/rules/raise_not_implemented.rs @@ -1,11 +1,10 @@ use ruff_python_ast::{self as ast, Expr}; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for `raise` statements that raise `NotImplemented`. @@ -39,14 +38,14 @@ use crate::registry::AsRule; pub struct RaiseNotImplemented; impl Violation for RaiseNotImplemented { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("`raise NotImplemented` should be `raise NotImplementedError`") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Use `raise NotImplementedError`".to_string()) } } @@ -76,13 +75,11 @@ pub(crate) fn raise_not_implemented(checker: &mut Checker, expr: &Expr) { return; }; let mut diagnostic = Diagnostic::new(RaiseNotImplemented, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - if checker.semantic().is_builtin("NotImplementedError") { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - "NotImplementedError".to_string(), - expr.range(), - ))); - } + if checker.semantic().is_builtin("NotImplementedError") { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "NotImplementedError".to_string(), + expr.range(), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyflakes/rules/repeated_keys.rs b/crates/ruff_linter/src/rules/pyflakes/rules/repeated_keys.rs index 6926d15d675a9..1d8fa4daadbaa 100644 --- a/crates/ruff_linter/src/rules/pyflakes/rules/repeated_keys.rs +++ b/crates/ruff_linter/src/rules/pyflakes/rules/repeated_keys.rs @@ -2,16 +2,16 @@ use std::hash::BuildHasherDefault; use rustc_hash::{FxHashMap, FxHashSet}; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::comparable::ComparableExpr; use ruff_python_ast::parenthesize::parenthesized_range; use ruff_python_ast::{self as ast, Expr}; use ruff_text_size::Ranged; -use crate::autofix::snippet::SourceCodeSnippet; use crate::checkers::ast::Checker; -use crate::registry::{AsRule, Rule}; +use crate::fix::snippet::SourceCodeSnippet; +use crate::registry::Rule; /// ## What it does /// Checks for dictionary literals that associate multiple values with the @@ -49,7 +49,7 @@ pub struct MultiValueRepeatedKeyLiteral { } impl Violation for MultiValueRepeatedKeyLiteral { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -61,7 +61,7 @@ impl Violation for MultiValueRepeatedKeyLiteral { } } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let MultiValueRepeatedKeyLiteral { name } = self; if let Some(name) = name.full_display() { Some(format!("Remove repeated key literal `{name}`")) @@ -106,7 +106,7 @@ pub struct MultiValueRepeatedKeyVariable { } impl Violation for MultiValueRepeatedKeyVariable { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -118,7 +118,7 @@ impl Violation for MultiValueRepeatedKeyVariable { } } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let MultiValueRepeatedKeyVariable { name } = self; if let Some(name) = name.full_display() { Some(format!("Remove repeated key `{name}`")) @@ -157,27 +157,25 @@ pub(crate) fn repeated_keys(checker: &mut Checker, dict: &ast::ExprDict) { }, key.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if !seen_values.insert(comparable_value) { - diagnostic.set_fix(Fix::suggested(Edit::deletion( - parenthesized_range( - (&dict.values[i - 1]).into(), - dict.into(), - checker.indexer().comment_ranges(), - checker.locator().contents(), - ) - .unwrap_or(dict.values[i - 1].range()) - .end(), - parenthesized_range( - (&dict.values[i]).into(), - dict.into(), - checker.indexer().comment_ranges(), - checker.locator().contents(), - ) - .unwrap_or(dict.values[i].range()) - .end(), - ))); - } + if !seen_values.insert(comparable_value) { + diagnostic.set_fix(Fix::unsafe_edit(Edit::deletion( + parenthesized_range( + (&dict.values[i - 1]).into(), + dict.into(), + checker.indexer().comment_ranges(), + checker.locator().contents(), + ) + .unwrap_or(dict.values[i - 1].range()) + .end(), + parenthesized_range( + (&dict.values[i]).into(), + dict.into(), + checker.indexer().comment_ranges(), + checker.locator().contents(), + ) + .unwrap_or(dict.values[i].range()) + .end(), + ))); } checker.diagnostics.push(diagnostic); } @@ -190,28 +188,26 @@ pub(crate) fn repeated_keys(checker: &mut Checker, dict: &ast::ExprDict) { }, key.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let comparable_value: ComparableExpr = (&dict.values[i]).into(); - if !seen_values.insert(comparable_value) { - diagnostic.set_fix(Fix::suggested(Edit::deletion( - parenthesized_range( - (&dict.values[i - 1]).into(), - dict.into(), - checker.indexer().comment_ranges(), - checker.locator().contents(), - ) - .unwrap_or(dict.values[i - 1].range()) - .end(), - parenthesized_range( - (&dict.values[i]).into(), - dict.into(), - checker.indexer().comment_ranges(), - checker.locator().contents(), - ) - .unwrap_or(dict.values[i].range()) - .end(), - ))); - } + let comparable_value: ComparableExpr = (&dict.values[i]).into(); + if !seen_values.insert(comparable_value) { + diagnostic.set_fix(Fix::unsafe_edit(Edit::deletion( + parenthesized_range( + (&dict.values[i - 1]).into(), + dict.into(), + checker.indexer().comment_ranges(), + checker.locator().contents(), + ) + .unwrap_or(dict.values[i - 1].range()) + .end(), + parenthesized_range( + (&dict.values[i]).into(), + dict.into(), + checker.indexer().comment_ranges(), + checker.locator().contents(), + ) + .unwrap_or(dict.values[i].range()) + .end(), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyflakes/rules/strings.rs b/crates/ruff_linter/src/rules/pyflakes/rules/strings.rs index 3d4de1a14808a..317c5692ea289 100644 --- a/crates/ruff_linter/src/rules/pyflakes/rules/strings.rs +++ b/crates/ruff_linter/src/rules/pyflakes/rules/strings.rs @@ -2,13 +2,12 @@ use std::string::ToString; use rustc_hash::FxHashSet; -use ruff_diagnostics::{AlwaysAutofixableViolation, AutofixKind, Diagnostic, Fix, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Constant, Expr, Identifier, Keyword}; use ruff_text_size::{Ranged, TextRange}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; use super::super::cformat::CFormatSummary; use super::super::fixes::{ @@ -145,7 +144,7 @@ pub struct PercentFormatExtraNamedArguments { missing: Vec, } -impl AlwaysAutofixableViolation for PercentFormatExtraNamedArguments { +impl AlwaysFixableViolation for PercentFormatExtraNamedArguments { #[derive_message_formats] fn message(&self) -> String { let PercentFormatExtraNamedArguments { missing } = self; @@ -153,7 +152,7 @@ impl AlwaysAutofixableViolation for PercentFormatExtraNamedArguments { format!("`%`-format string has unused named argument(s): {message}") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let PercentFormatExtraNamedArguments { missing } = self; let message = missing.join(", "); format!("Remove extra named arguments: {message}") @@ -387,7 +386,7 @@ pub struct StringDotFormatExtraNamedArguments { } impl Violation for StringDotFormatExtraNamedArguments { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -396,7 +395,7 @@ impl Violation for StringDotFormatExtraNamedArguments { format!("`.format` call has unused named argument(s): {message}") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let StringDotFormatExtraNamedArguments { missing } = self; let message = missing.join(", "); Some(format!("Remove extra named arguments: {message}")) @@ -428,7 +427,7 @@ pub struct StringDotFormatExtraPositionalArguments { } impl Violation for StringDotFormatExtraPositionalArguments { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -437,7 +436,7 @@ impl Violation for StringDotFormatExtraPositionalArguments { format!("`.format` call has unused arguments at position(s): {message}") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let StringDotFormatExtraPositionalArguments { missing } = self; let message = missing.join(", "); Some(format!( @@ -609,18 +608,16 @@ pub(crate) fn percent_format_extra_named_arguments( PercentFormatExtraNamedArguments { missing: names }, location, ); - if checker.patch(diagnostic.kind.rule()) { - let indexes: Vec = missing.iter().map(|(index, _)| *index).collect(); - diagnostic.try_set_fix(|| { - let edit = remove_unused_format_arguments_from_dict( - &indexes, - dict, - checker.locator(), - checker.stylist(), - )?; - Ok(Fix::automatic(edit)) - }); - } + let indexes: Vec = missing.iter().map(|(index, _)| *index).collect(); + diagnostic.try_set_fix(|| { + let edit = remove_unused_format_arguments_from_dict( + &indexes, + dict, + checker.locator(), + checker.stylist(), + )?; + Ok(Fix::safe_edit(edit)) + }); checker.diagnostics.push(diagnostic); } @@ -776,18 +773,16 @@ pub(crate) fn string_dot_format_extra_named_arguments( StringDotFormatExtraNamedArguments { missing: names }, call.range(), ); - if checker.patch(diagnostic.kind.rule()) { - let indexes: Vec = missing.iter().map(|(index, _)| *index).collect(); - diagnostic.try_set_fix(|| { - let edit = remove_unused_keyword_arguments_from_format_call( - &indexes, - call, - checker.locator(), - checker.stylist(), - )?; - Ok(Fix::automatic(edit)) - }); - } + let indexes: Vec = missing.iter().map(|(index, _)| *index).collect(); + diagnostic.try_set_fix(|| { + let edit = remove_unused_keyword_arguments_from_format_call( + &indexes, + call, + checker.locator(), + checker.stylist(), + )?; + Ok(Fix::safe_edit(edit)) + }); checker.diagnostics.push(diagnostic); } @@ -798,6 +793,31 @@ pub(crate) fn string_dot_format_extra_positional_arguments( summary: &FormatSummary, args: &[Expr], ) { + // We can only fix if the positional arguments we're removing don't require re-indexing + // the format string itself. For example, we can't fix `"{1}{2}".format(0, 1, 2)"`, since + // this requires changing the format string to `"{0}{1}"`. But we can fix + // `"{0}{1}".format(0, 1, 2)`, since this only requires modifying the call arguments. + fn is_contiguous_from_end(indexes: &[usize], target: &[T]) -> bool { + if indexes.is_empty() { + return true; + } + + let mut expected_index = target.len() - 1; + for &index in indexes.iter().rev() { + if index != expected_index { + return false; + } + + if expected_index == 0 { + break; + } + + expected_index -= 1; + } + + true + } + let missing: Vec = args .iter() .enumerate() @@ -820,44 +840,19 @@ pub(crate) fn string_dot_format_extra_positional_arguments( }, call.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // We can only fix if the positional arguments we're removing don't require re-indexing - // the format string itself. For example, we can't fix `"{1}{2}".format(0, 1, 2)"`, since - // this requires changing the format string to `"{0}{1}"`. But we can fix - // `"{0}{1}".format(0, 1, 2)`, since this only requires modifying the call arguments. - fn is_contiguous_from_end(indexes: &[usize], target: &[T]) -> bool { - if indexes.is_empty() { - return true; - } - - let mut expected_index = target.len() - 1; - for &index in indexes.iter().rev() { - if index != expected_index { - return false; - } - - if expected_index == 0 { - break; - } - - expected_index -= 1; - } - true - } - - if is_contiguous_from_end(&missing, args) { - diagnostic.try_set_fix(|| { - let edit = remove_unused_positional_arguments_from_format_call( - &missing, - call, - checker.locator(), - checker.stylist(), - )?; - Ok(Fix::automatic(edit)) - }); - } + if is_contiguous_from_end(&missing, args) { + diagnostic.try_set_fix(|| { + let edit = remove_unused_positional_arguments_from_format_call( + &missing, + call, + checker.locator(), + checker.stylist(), + )?; + Ok(Fix::safe_edit(edit)) + }); } + checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyflakes/rules/unused_import.rs b/crates/ruff_linter/src/rules/pyflakes/rules/unused_import.rs index d9899a483f1cd..158e45183ee5c 100644 --- a/crates/ruff_linter/src/rules/pyflakes/rules/unused_import.rs +++ b/crates/ruff_linter/src/rules/pyflakes/rules/unused_import.rs @@ -3,13 +3,13 @@ use std::borrow::Cow; use anyhow::Result; use rustc_hash::FxHashMap; -use ruff_diagnostics::{AutofixKind, Diagnostic, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_semantic::{AnyImport, Exceptions, Imported, NodeId, Scope}; use ruff_text_size::{Ranged, TextRange}; -use crate::autofix; use crate::checkers::ast::Checker; +use crate::fix; use crate::registry::Rule; #[derive(Debug, Copy, Clone, Eq, PartialEq)] @@ -67,7 +67,7 @@ pub struct UnusedImport { } impl Violation for UnusedImport { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -87,7 +87,7 @@ impl Violation for UnusedImport { } } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let UnusedImport { name, multiple, .. } = self; Some(if *multiple { "Remove unused import".to_string() @@ -154,7 +154,7 @@ pub(crate) fn unused_import(checker: &Checker, scope: &Scope, diagnostics: &mut exceptions.intersects(Exceptions::MODULE_NOT_FOUND_ERROR | Exceptions::IMPORT_ERROR); let multiple = imports.len() > 1; - let fix = if !in_init && !in_except_handler && checker.patch(Rule::UnusedImport) { + let fix = if !in_init && !in_except_handler { fix_imports(checker, node_id, &imports).ok() } else { None @@ -243,7 +243,7 @@ fn fix_imports(checker: &Checker, node_id: NodeId, imports: &[ImportBinding]) -> .map(Imported::member_name) .collect(); - let edit = autofix::edits::remove_unused_imports( + let edit = fix::edits::remove_unused_imports( member_names.iter().map(AsRef::as_ref), statement, parent, @@ -251,7 +251,7 @@ fn fix_imports(checker: &Checker, node_id: NodeId, imports: &[ImportBinding]) -> checker.stylist(), checker.indexer(), )?; - Ok(Fix::automatic(edit).isolate(Checker::isolation( + Ok(Fix::safe_edit(edit).isolate(Checker::isolation( checker.semantic().parent_statement_id(node_id), ))) } diff --git a/crates/ruff_linter/src/rules/pyflakes/rules/unused_variable.rs b/crates/ruff_linter/src/rules/pyflakes/rules/unused_variable.rs index 64aaa16e757dc..b72bb5372f235 100644 --- a/crates/ruff_linter/src/rules/pyflakes/rules/unused_variable.rs +++ b/crates/ruff_linter/src/rules/pyflakes/rules/unused_variable.rs @@ -1,6 +1,6 @@ use itertools::Itertools; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::contains_effect; use ruff_python_ast::parenthesize::parenthesized_range; @@ -10,9 +10,8 @@ use ruff_python_semantic::{Binding, Scope}; use ruff_source_file::Locator; use ruff_text_size::{Ranged, TextRange, TextSize}; -use crate::autofix::edits::delete_stmt; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix::edits::delete_stmt; /// ## What it does /// Checks for the presence of unused variables in function scopes. @@ -48,7 +47,7 @@ pub struct UnusedVariable { } impl Violation for UnusedVariable { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -56,7 +55,7 @@ impl Violation for UnusedVariable { format!("Local variable `{name}` is assigned to but never used") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let UnusedVariable { name } = self; Some(format!("Remove assignment to unused variable `{name}`")) } @@ -237,11 +236,11 @@ fn remove_unused_variable(binding: &Binding, checker: &Checker) -> Option { )? .start(); let edit = Edit::deletion(start, end); - Some(Fix::suggested(edit)) + Some(Fix::unsafe_edit(edit)) } else { // If (e.g.) assigning to a constant (`x = 1`), delete the entire statement. let edit = delete_stmt(statement, parent, checker.locator(), checker.indexer()); - Some(Fix::suggested(edit).isolate(isolation)) + Some(Fix::unsafe_edit(edit).isolate(isolation)) }; } } @@ -265,11 +264,11 @@ fn remove_unused_variable(binding: &Binding, checker: &Checker) -> Option { })? .start(); let edit = Edit::deletion(start, end); - Some(Fix::suggested(edit)) + Some(Fix::unsafe_edit(edit)) } else { // If (e.g.) assigning to a constant (`x = 1`), delete the entire statement. let edit = delete_stmt(statement, parent, checker.locator(), checker.indexer()); - Some(Fix::suggested(edit).isolate(isolation)) + Some(Fix::unsafe_edit(edit).isolate(isolation)) }; } } @@ -300,7 +299,7 @@ fn remove_unused_variable(binding: &Binding, checker: &Checker) -> Option { .start(); let edit = Edit::deletion(start, end); - return Some(Fix::suggested(edit)); + return Some(Fix::unsafe_edit(edit)); } } } @@ -344,10 +343,8 @@ pub(crate) fn unused_variable(checker: &Checker, scope: &Scope, diagnostics: &mu }, binding.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if let Some(fix) = remove_unused_variable(binding, checker) { - diagnostic.set_fix(fix); - } + if let Some(fix) = remove_unused_variable(binding, checker) { + diagnostic.set_fix(fix); } diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F401_F401_19.py.snap b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F401_F401_19.py.snap new file mode 100644 index 0000000000000..d0b409f39ee0b --- /dev/null +++ b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F401_F401_19.py.snap @@ -0,0 +1,4 @@ +--- +source: crates/ruff_linter/src/rules/pyflakes/mod.rs +--- + diff --git a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F541_F541.py.snap b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F541_F541.py.snap index 48e7e646c43c6..3ebd0451427c8 100644 --- a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F541_F541.py.snap +++ b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F541_F541.py.snap @@ -332,7 +332,7 @@ F541.py:40:3: F541 [*] f-string without any placeholders 40 |+"" "" 41 41 | ''f"" 42 42 | (""f""r"") -43 43 | +43 43 | f"{v:{f"0.2f"}}" F541.py:41:3: F541 [*] f-string without any placeholders | @@ -341,6 +341,7 @@ F541.py:41:3: F541 [*] f-string without any placeholders 41 | ''f"" | ^^^ F541 42 | (""f""r"") +43 | f"{v:{f"0.2f"}}" | = help: Remove extraneous `f` prefix @@ -351,8 +352,8 @@ F541.py:41:3: F541 [*] f-string without any placeholders 41 |-''f"" 41 |+''"" 42 42 | (""f""r"") -43 43 | -44 44 | # To be fixed +43 43 | f"{v:{f"0.2f"}}" +44 44 | f"\{{x}}" F541.py:42:4: F541 [*] f-string without any placeholders | @@ -360,8 +361,8 @@ F541.py:42:4: F541 [*] f-string without any placeholders 41 | ''f"" 42 | (""f""r"") | ^^^ F541 -43 | -44 | # To be fixed +43 | f"{v:{f"0.2f"}}" +44 | f"\{{x}}" | = help: Remove extraneous `f` prefix @@ -371,8 +372,41 @@ F541.py:42:4: F541 [*] f-string without any placeholders 41 41 | ''f"" 42 |-(""f""r"") 42 |+("" ""r"") -43 43 | -44 44 | # To be fixed -45 45 | # Error: f-string: single '}' is not allowed at line 41 column 8 +43 43 | f"{v:{f"0.2f"}}" +44 44 | f"\{{x}}" + +F541.py:43:7: F541 [*] f-string without any placeholders + | +41 | ''f"" +42 | (""f""r"") +43 | f"{v:{f"0.2f"}}" + | ^^^^^^^ F541 +44 | f"\{{x}}" + | + = help: Remove extraneous `f` prefix + +ℹ Fix +40 40 | ""f"" +41 41 | ''f"" +42 42 | (""f""r"") +43 |-f"{v:{f"0.2f"}}" + 43 |+f"{v:{"0.2f"}}" +44 44 | f"\{{x}}" + +F541.py:44:1: F541 [*] f-string without any placeholders + | +42 | (""f""r"") +43 | f"{v:{f"0.2f"}}" +44 | f"\{{x}}" + | ^^^^^^^^^ F541 + | + = help: Remove extraneous `f` prefix + +ℹ Fix +41 41 | ''f"" +42 42 | (""f""r"") +43 43 | f"{v:{f"0.2f"}}" +44 |-f"\{{x}}" + 44 |+"\{x}" diff --git a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F632_F632.py.snap b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F632_F632.py.snap index b23df34224d99..c1d0d79dd10cf 100644 --- a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F632_F632.py.snap +++ b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F632_F632.py.snap @@ -171,6 +171,8 @@ F632.py:26:2: F632 [*] Use `!=` to compare constant literals | __^ 27 | | not ''} | |_______^ F632 +28 | +29 | # Regression test for | = help: Replace `is not` with `!=` @@ -181,5 +183,42 @@ F632.py:26:2: F632 [*] Use `!=` to compare constant literals 26 |-{2 is 27 |- not ''} 26 |+{2 != ''} +28 27 | +29 28 | # Regression test for +30 29 | if values[1is not None ] is not '-': + +F632.py:30:4: F632 [*] Use `!=` to compare constant literals + | +29 | # Regression test for +30 | if values[1is not None ] is not '-': + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ F632 +31 | pass + | + = help: Replace `is not` with `!=` + +ℹ Fix +27 27 | not ''} +28 28 | +29 29 | # Regression test for +30 |-if values[1is not None ] is not '-': + 30 |+if values[1is not None ] != '-': +31 31 | pass + +F632.py:30:11: F632 [*] Use `!=` to compare constant literals + | +29 | # Regression test for +30 | if values[1is not None ] is not '-': + | ^^^^^^^^^^^^ F632 +31 | pass + | + = help: Replace `is not` with `!=` + +ℹ Fix +27 27 | not ''} +28 28 | +29 29 | # Regression test for +30 |-if values[1is not None ] is not '-': + 30 |+if values[1!= None ] is not '-': +31 31 | pass diff --git a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F821_F821_18.py.snap b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F821_F821_18.py.snap new file mode 100644 index 0000000000000..d0b409f39ee0b --- /dev/null +++ b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F821_F821_18.py.snap @@ -0,0 +1,4 @@ +--- +source: crates/ruff_linter/src/rules/pyflakes/mod.rs +--- + diff --git a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F821_F821_19.py.snap b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F821_F821_19.py.snap new file mode 100644 index 0000000000000..0461eeea1b703 --- /dev/null +++ b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F821_F821_19.py.snap @@ -0,0 +1,12 @@ +--- +source: crates/ruff_linter/src/rules/pyflakes/mod.rs +--- +F821_19.py:21:7: F821 Undefined name `y` + | +19 | # Error: `y` is not defined. +20 | x: (y := 1) +21 | print(y) + | ^ F821 + | + + diff --git a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F821_F821_20.py.snap b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F821_F821_20.py.snap new file mode 100644 index 0000000000000..143f82be67d7c --- /dev/null +++ b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F821_F821_20.py.snap @@ -0,0 +1,14 @@ +--- +source: crates/ruff_linter/src/rules/pyflakes/mod.rs +--- +F821_20.py:3:24: F821 Undefined name `Record` + | +1 | """Test lazy evaluation of type alias values.""" +2 | +3 | type RecordCallback[R: Record] = Callable[[R], None] + | ^^^^^^ F821 +4 | +5 | from collections.abc import Callable + | + + diff --git a/crates/ruff_linter/src/rules/pygrep_hooks/rules/deprecated_log_warn.rs b/crates/ruff_linter/src/rules/pygrep_hooks/rules/deprecated_log_warn.rs index c91566f365532..547f1aa9f79c5 100644 --- a/crates/ruff_linter/src/rules/pygrep_hooks/rules/deprecated_log_warn.rs +++ b/crates/ruff_linter/src/rules/pygrep_hooks/rules/deprecated_log_warn.rs @@ -1,7 +1,9 @@ -use ruff_python_ast::Expr; +use ruff_python_ast::{self as ast, Expr, ExprCall}; +use ruff_python_semantic::analyze::logging; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_stdlib::logging::LoggingLevel; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -43,14 +45,36 @@ impl Violation for DeprecatedLogWarn { } /// PGH002 -pub(crate) fn deprecated_log_warn(checker: &mut Checker, func: &Expr) { - if checker - .semantic() - .resolve_call_path(func) - .is_some_and(|call_path| matches!(call_path.as_slice(), ["logging", "warn"])) - { - checker - .diagnostics - .push(Diagnostic::new(DeprecatedLogWarn, func.range())); +pub(crate) fn deprecated_log_warn(checker: &mut Checker, call: &ExprCall) { + match call.func.as_ref() { + Expr::Attribute(ast::ExprAttribute { attr, .. }) => { + if !logging::is_logger_candidate( + &call.func, + checker.semantic(), + &checker.settings.logger_objects, + ) { + return; + } + if !matches!( + LoggingLevel::from_attribute(attr.as_str()), + Some(LoggingLevel::Warn) + ) { + return; + } + } + Expr::Name(_) => { + if !checker + .semantic() + .resolve_call_path(call.func.as_ref()) + .is_some_and(|call_path| matches!(call_path.as_slice(), ["logging", "warn"])) + { + return; + } + } + _ => return, } + + checker + .diagnostics + .push(Diagnostic::new(DeprecatedLogWarn, call.func.range())); } diff --git a/crates/ruff_linter/src/rules/pygrep_hooks/snapshots/ruff_linter__rules__pygrep_hooks__tests__PGH002_PGH002_1.py.snap b/crates/ruff_linter/src/rules/pygrep_hooks/snapshots/ruff_linter__rules__pygrep_hooks__tests__PGH002_PGH002_1.py.snap index 7c8d4bc82744a..df73d2858d097 100644 --- a/crates/ruff_linter/src/rules/pygrep_hooks/snapshots/ruff_linter__rules__pygrep_hooks__tests__PGH002_PGH002_1.py.snap +++ b/crates/ruff_linter/src/rules/pygrep_hooks/snapshots/ruff_linter__rules__pygrep_hooks__tests__PGH002_PGH002_1.py.snap @@ -15,6 +15,15 @@ PGH002_1.py:5:1: PGH002 `warn` is deprecated in favor of `warning` 4 | logging.warn("this is not ok") 5 | warn("not ok") | ^^^^ PGH002 +6 | +7 | logger = logging.getLogger(__name__) + | + +PGH002_1.py:8:1: PGH002 `warn` is deprecated in favor of `warning` + | +7 | logger = logging.getLogger(__name__) +8 | logger.warn("this is not ok") + | ^^^^^^^^^^^ PGH002 | diff --git a/crates/ruff_linter/src/rules/pylint/helpers.rs b/crates/ruff_linter/src/rules/pylint/helpers.rs index effffd71fb8b5..7d99ea90422da 100644 --- a/crates/ruff_linter/src/rules/pylint/helpers.rs +++ b/crates/ruff_linter/src/rules/pylint/helpers.rs @@ -22,7 +22,11 @@ pub(super) fn type_param_name(arguments: &Arguments) -> Option<&str> { } } -pub(super) fn in_dunder_init(semantic: &SemanticModel, settings: &LinterSettings) -> bool { +pub(super) fn in_dunder_method( + dunder_name: &str, + semantic: &SemanticModel, + settings: &LinterSettings, +) -> bool { let scope = semantic.current_scope(); let ScopeKind::Function(ast::StmtFunctionDef { name, @@ -32,7 +36,7 @@ pub(super) fn in_dunder_init(semantic: &SemanticModel, settings: &LinterSettings else { return false; }; - if name != "__init__" { + if name != dunder_name { return false; } let Some(parent) = semantic.first_non_type_parent_scope(scope) else { diff --git a/crates/ruff_linter/src/rules/pylint/mod.rs b/crates/ruff_linter/src/rules/pylint/mod.rs index aee24e4e62037..4b3b5afa335e3 100644 --- a/crates/ruff_linter/src/rules/pylint/mod.rs +++ b/crates/ruff_linter/src/rules/pylint/mod.rs @@ -18,6 +18,7 @@ mod tests { use crate::settings::LinterSettings; use crate::test::test_path; + #[test_case(Rule::AndOrTernary, Path::new("and_or_ternary.py"))] #[test_case(Rule::AssertOnStringLiteral, Path::new("assert_on_string_literal.py"))] #[test_case(Rule::AwaitOutsideAsync, Path::new("await_outside_async.py"))] #[test_case( @@ -132,8 +133,15 @@ mod tests { Rule::SubprocessRunWithoutCheck, Path::new("subprocess_run_without_check.py") )] + #[test_case(Rule::UnspecifiedEncoding, Path::new("unspecified_encoding.py"))] #[test_case(Rule::BadDunderMethodName, Path::new("bad_dunder_method_name.py"))] #[test_case(Rule::NoSelfUse, Path::new("no_self_use.py"))] + #[test_case(Rule::MisplacedBareRaise, Path::new("misplaced_bare_raise.py"))] + #[test_case(Rule::LiteralMembership, Path::new("literal_membership.py"))] + #[test_case(Rule::GlobalAtModuleLevel, Path::new("global_at_module_level.py"))] + #[test_case(Rule::UnnecessaryLambda, Path::new("unnecessary_lambda.py"))] + #[test_case(Rule::NonAsciiImportName, Path::new("non_ascii_module_import.py"))] + #[test_case(Rule::NonAsciiName, Path::new("non_ascii_name.py"))] fn rules(rule_code: Rule, path: &Path) -> Result<()> { let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy()); let diagnostics = test_path( @@ -227,6 +235,22 @@ mod tests { Ok(()) } + #[test] + fn max_boolean_expressions() -> Result<()> { + let diagnostics = test_path( + Path::new("pylint/too_many_boolean_expressions.py"), + &LinterSettings { + pylint: pylint::settings::Settings { + max_bool_expr: 5, + ..pylint::settings::Settings::default() + }, + ..LinterSettings::for_rule(Rule::TooManyBooleanExpressions) + }, + )?; + assert_messages!(diagnostics); + Ok(()) + } + #[test] fn max_statements() -> Result<()> { let diagnostics = test_path( diff --git a/crates/ruff_linter/src/rules/pylint/rules/and_or_ternary.rs b/crates/ruff_linter/src/rules/pylint/rules/and_or_ternary.rs new file mode 100644 index 0000000000000..ed7c2ef634a82 --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/rules/and_or_ternary.rs @@ -0,0 +1,133 @@ +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{ + BoolOp, Expr, ExprBoolOp, ExprDictComp, ExprIfExp, ExprListComp, ExprSetComp, +}; +use ruff_text_size::{Ranged, TextRange}; + +use crate::checkers::ast::Checker; +use crate::fix::snippet::SourceCodeSnippet; +use crate::registry::AsRule; + +/// ## What it does +/// Checks for uses of the known pre-Python 2.5 ternary syntax. +/// +/// ## Why is this bad? +/// Prior to the introduction of the if-expression (ternary) operator in Python +/// 2.5, the only way to express a conditional expression was to use the `and` +/// and `or` operators. +/// +/// The if-expression construct is clearer and more explicit, and should be +/// preferred over the use of `and` and `or` for ternary expressions. +/// +/// ## Example +/// ```python +/// x, y = 1, 2 +/// maximum = x >= y and x or y +/// ``` +/// +/// Use instead: +/// ```python +/// x, y = 1, 2 +/// maximum = x if x >= y else y +/// ``` +#[violation] +pub struct AndOrTernary { + ternary: SourceCodeSnippet, +} + +impl Violation for AndOrTernary { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; + + #[derive_message_formats] + fn message(&self) -> String { + if let Some(ternary) = self.ternary.full_display() { + format!("Consider using if-else expression (`{ternary}`)") + } else { + format!("Consider using if-else expression") + } + } + + fn fix_title(&self) -> Option { + Some(format!("Convert to if-else expression")) + } +} + +/// Returns `Some((condition, true_value, false_value))`, if `bool_op` is of the form `condition and true_value or false_value`. +fn parse_and_or_ternary(bool_op: &ExprBoolOp) -> Option<(&Expr, &Expr, &Expr)> { + if bool_op.op != BoolOp::Or { + return None; + } + let [expr, false_value] = bool_op.values.as_slice() else { + return None; + }; + let Some(and_op) = expr.as_bool_op_expr() else { + return None; + }; + if and_op.op != BoolOp::And { + return None; + } + let [condition, true_value] = and_op.values.as_slice() else { + return None; + }; + if false_value.is_bool_op_expr() || true_value.is_bool_op_expr() { + return None; + } + Some((condition, true_value, false_value)) +} + +/// Returns `true` if the expression is used within a comprehension. +fn is_comprehension_if(parent: Option<&Expr>, expr: &ExprBoolOp) -> bool { + let comprehensions = match parent { + Some(Expr::ListComp(ExprListComp { generators, .. })) => generators, + Some(Expr::SetComp(ExprSetComp { generators, .. })) => generators, + Some(Expr::DictComp(ExprDictComp { generators, .. })) => generators, + _ => { + return false; + } + }; + comprehensions + .iter() + .any(|comp| comp.ifs.iter().any(|ifs| ifs.range() == expr.range())) +} + +/// PLR1706 +pub(crate) fn and_or_ternary(checker: &mut Checker, bool_op: &ExprBoolOp) { + if checker.semantic().current_statement().is_if_stmt() { + return; + } + let parent_expr = checker.semantic().current_expression_parent(); + if parent_expr.is_some_and(Expr::is_bool_op_expr) { + return; + } + let Some((condition, true_value, false_value)) = parse_and_or_ternary(bool_op) else { + return; + }; + + let if_expr = Expr::IfExp(ExprIfExp { + test: Box::new(condition.clone()), + body: Box::new(true_value.clone()), + orelse: Box::new(false_value.clone()), + range: TextRange::default(), + }); + + let ternary = if is_comprehension_if(parent_expr, bool_op) { + format!("({})", checker.generator().expr(&if_expr)) + } else { + checker.generator().expr(&if_expr) + }; + + let mut diagnostic = Diagnostic::new( + AndOrTernary { + ternary: SourceCodeSnippet::new(ternary.clone()), + }, + bool_op.range, + ); + if checker.enabled(diagnostic.kind.rule()) { + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + ternary, + bool_op.range, + ))); + } + checker.diagnostics.push(diagnostic); +} diff --git a/crates/ruff_linter/src/rules/pylint/rules/bad_dunder_method_name.rs b/crates/ruff_linter/src/rules/pylint/rules/bad_dunder_method_name.rs index a3c3145798006..838c7ae77c66b 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/bad_dunder_method_name.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/bad_dunder_method_name.rs @@ -54,7 +54,7 @@ pub(crate) fn bad_dunder_method_name(checker: &mut Checker, class_body: &[Stmt]) .iter() .filter_map(ruff_python_ast::Stmt::as_function_def_stmt) .filter(|method| { - if is_known_dunder_method(&method.name) { + if is_known_dunder_method(&method.name) || matches!(method.name.as_str(), "_") { return false; } method.name.starts_with('_') && method.name.ends_with('_') @@ -88,6 +88,7 @@ fn is_known_dunder_method(method: &str) -> bool { | "__attrs_pre_init__" | "__await__" | "__bool__" + | "__buffer__" | "__bytes__" | "__call__" | "__ceil__" @@ -131,6 +132,7 @@ fn is_known_dunder_method(method: &str) -> bool { | "__imatmul__" | "__imod__" | "__imul__" + | "__index__" | "__init__" | "__init_subclass__" | "__instancecheck__" @@ -166,6 +168,7 @@ fn is_known_dunder_method(method: &str) -> bool { | "__rdivmod__" | "__reduce__" | "__reduce_ex__" + | "__release_buffer__" | "__repr__" | "__reversed__" | "__rfloordiv__" @@ -196,5 +199,13 @@ fn is_known_dunder_method(method: &str) -> bool { | "__trunc__" | "__weakref__" | "__xor__" + // Overridable sunder names from the `Enum` class. + // See: https://docs.python.org/3/library/enum.html#supported-sunder-names + | "_name_" + | "_value_" + | "_missing_" + | "_ignore_" + | "_order_" + | "_generate_next_value_" ) } diff --git a/crates/ruff_linter/src/rules/pylint/rules/comparison_with_itself.rs b/crates/ruff_linter/src/rules/pylint/rules/comparison_with_itself.rs index 9132100f0817e..ce02b12fff433 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/comparison_with_itself.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/comparison_with_itself.rs @@ -1,6 +1,6 @@ use itertools::Itertools; -use crate::autofix::snippet::SourceCodeSnippet; +use crate::fix::snippet::SourceCodeSnippet; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{CmpOp, Expr}; diff --git a/crates/ruff_linter/src/rules/pylint/rules/global_at_module_level.rs b/crates/ruff_linter/src/rules/pylint/rules/global_at_module_level.rs new file mode 100644 index 0000000000000..89d7cca946c45 --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/rules/global_at_module_level.rs @@ -0,0 +1,34 @@ +use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::Stmt; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for uses of the `global` keyword at the module level. +/// +/// ## Why is this bad? +/// The `global` keyword is used within functions to indicate that a name +/// refers to a global variable, rather than a local variable. +/// +/// At the module level, all names are global by default, so the `global` +/// keyword is redundant. +#[violation] +pub struct GlobalAtModuleLevel; + +impl Violation for GlobalAtModuleLevel { + #[derive_message_formats] + fn message(&self) -> String { + format!("`global` at module level is redundant") + } +} + +/// PLW0604 +pub(crate) fn global_at_module_level(checker: &mut Checker, stmt: &Stmt) { + if checker.semantic().current_scope().kind.is_module() { + checker + .diagnostics + .push(Diagnostic::new(GlobalAtModuleLevel, stmt.range())); + } +} diff --git a/crates/ruff_linter/src/rules/pylint/rules/invalid_string_characters.rs b/crates/ruff_linter/src/rules/pylint/rules/invalid_string_characters.rs index 2bd640f326c4a..1a0416683c714 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/invalid_string_characters.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/invalid_string_characters.rs @@ -1,9 +1,10 @@ use ruff_text_size::{TextLen, TextRange, TextSize}; -use ruff_diagnostics::AlwaysAutofixableViolation; +use ruff_diagnostics::AlwaysFixableViolation; use ruff_diagnostics::Edit; use ruff_diagnostics::{Diagnostic, DiagnosticKind, Fix}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_parser::Tok; use ruff_source_file::Locator; /// ## What it does @@ -28,13 +29,13 @@ use ruff_source_file::Locator; #[violation] pub struct InvalidCharacterBackspace; -impl AlwaysAutofixableViolation for InvalidCharacterBackspace { +impl AlwaysFixableViolation for InvalidCharacterBackspace { #[derive_message_formats] fn message(&self) -> String { format!("Invalid unescaped character backspace, use \"\\b\" instead") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace with escape sequence".to_string() } } @@ -61,13 +62,13 @@ impl AlwaysAutofixableViolation for InvalidCharacterBackspace { #[violation] pub struct InvalidCharacterSub; -impl AlwaysAutofixableViolation for InvalidCharacterSub { +impl AlwaysFixableViolation for InvalidCharacterSub { #[derive_message_formats] fn message(&self) -> String { format!("Invalid unescaped character SUB, use \"\\x1A\" instead") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace with escape sequence".to_string() } } @@ -94,13 +95,13 @@ impl AlwaysAutofixableViolation for InvalidCharacterSub { #[violation] pub struct InvalidCharacterEsc; -impl AlwaysAutofixableViolation for InvalidCharacterEsc { +impl AlwaysFixableViolation for InvalidCharacterEsc { #[derive_message_formats] fn message(&self) -> String { format!("Invalid unescaped character ESC, use \"\\x1B\" instead") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace with escape sequence".to_string() } } @@ -127,13 +128,13 @@ impl AlwaysAutofixableViolation for InvalidCharacterEsc { #[violation] pub struct InvalidCharacterNul; -impl AlwaysAutofixableViolation for InvalidCharacterNul { +impl AlwaysFixableViolation for InvalidCharacterNul { #[derive_message_formats] fn message(&self) -> String { format!("Invalid unescaped character NUL, use \"\\0\" instead") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace with escape sequence".to_string() } } @@ -159,13 +160,13 @@ impl AlwaysAutofixableViolation for InvalidCharacterNul { #[violation] pub struct InvalidCharacterZeroWidthSpace; -impl AlwaysAutofixableViolation for InvalidCharacterZeroWidthSpace { +impl AlwaysFixableViolation for InvalidCharacterZeroWidthSpace { #[derive_message_formats] fn message(&self) -> String { format!("Invalid unescaped character zero-width-space, use \"\\u200B\" instead") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace with escape sequence".to_string() } } @@ -173,10 +174,16 @@ impl AlwaysAutofixableViolation for InvalidCharacterZeroWidthSpace { /// PLE2510, PLE2512, PLE2513, PLE2514, PLE2515 pub(crate) fn invalid_string_characters( diagnostics: &mut Vec, + tok: &Tok, range: TextRange, locator: &Locator, ) { - let text = locator.slice(range); + let text = match tok { + // We can't use the `value` field since it's decoded and e.g. for f-strings removed a curly + // brace that escaped another curly brace, which would gives us wrong column information. + Tok::String { .. } | Tok::FStringMiddle { .. } => locator.slice(range), + _ => return, + }; for (column, match_) in text.match_indices(&['\x08', '\x1A', '\x1B', '\0', '\u{200b}']) { let c = match_.chars().next().unwrap(); @@ -194,7 +201,7 @@ pub(crate) fn invalid_string_characters( let location = range.start() + TextSize::try_from(column).unwrap(); let range = TextRange::at(location, c.text_len()); - diagnostics.push(Diagnostic::new(rule, range).with_fix(Fix::automatic( + diagnostics.push(Diagnostic::new(rule, range).with_fix(Fix::safe_edit( Edit::range_replacement(replacement.to_string(), range), ))); } diff --git a/crates/ruff_linter/src/rules/pylint/rules/iteration_over_set.rs b/crates/ruff_linter/src/rules/pylint/rules/iteration_over_set.rs index 4501737ef660a..647f0d8c5d3eb 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/iteration_over_set.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/iteration_over_set.rs @@ -1,7 +1,6 @@ -use ruff_python_ast::{self as ast, Expr}; - -use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, Expr}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -30,11 +29,15 @@ use crate::checkers::ast::Checker; #[violation] pub struct IterationOverSet; -impl Violation for IterationOverSet { +impl AlwaysFixableViolation for IterationOverSet { #[derive_message_formats] fn message(&self) -> String { format!("Use a sequence type instead of a `set` when iterating over values") } + + fn fix_title(&self) -> String { + format!("Convert to `tuple`") + } } /// PLC0208 @@ -47,7 +50,16 @@ pub(crate) fn iteration_over_set(checker: &mut Checker, expr: &Expr) { return; } - checker - .diagnostics - .push(Diagnostic::new(IterationOverSet, expr.range())); + let mut diagnostic = Diagnostic::new(IterationOverSet, expr.range()); + + let tuple = if let [elt] = elts.as_slice() { + let elt = checker.locator().slice(elt); + format!("({elt},)") + } else { + let set = checker.locator().slice(expr); + format!("({})", &set[1..set.len() - 1]) + }; + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(tuple, expr.range()))); + + checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pylint/rules/literal_membership.rs b/crates/ruff_linter/src/rules/pylint/rules/literal_membership.rs new file mode 100644 index 0000000000000..44dbe31dfa8ef --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/rules/literal_membership.rs @@ -0,0 +1,68 @@ +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, CmpOp, Expr}; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for membership tests on `list` and `tuple` literals. +/// +/// ## Why is this bad? +/// When testing for membership in a static sequence, prefer a `set` literal +/// over a `list` or `tuple`, as Python optimizes `set` membership tests. +/// +/// ## Example +/// ```python +/// 1 in [1, 2, 3] +/// ``` +/// +/// Use instead: +/// ```python +/// 1 in {1, 2, 3} +/// ``` +/// ## References +/// - [What’s New In Python 3.2](https://docs.python.org/3/whatsnew/3.2.html#optimizations) +#[violation] +pub struct LiteralMembership; + +impl AlwaysFixableViolation for LiteralMembership { + #[derive_message_formats] + fn message(&self) -> String { + format!("Use a `set` literal when testing for membership") + } + + fn fix_title(&self) -> String { + format!("Convert to `set`") + } +} + +/// PLR6201 +pub(crate) fn literal_membership(checker: &mut Checker, compare: &ast::ExprCompare) { + let [op] = compare.ops.as_slice() else { + return; + }; + + if !matches!(op, CmpOp::In | CmpOp::NotIn) { + return; + } + + let [right] = compare.comparators.as_slice() else { + return; + }; + + if !matches!(right, Expr::List(_) | Expr::Tuple(_)) { + return; + } + + let mut diagnostic = Diagnostic::new(LiteralMembership, right.range()); + + let literal = checker.locator().slice(right); + let set = format!("{{{}}}", &literal[1..literal.len() - 1]); + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + set, + right.range(), + ))); + + checker.diagnostics.push(diagnostic); +} diff --git a/crates/ruff_linter/src/rules/pylint/rules/logging.rs b/crates/ruff_linter/src/rules/pylint/rules/logging.rs index ac1f47e68a19d..e101a5e235fc6 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/logging.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/logging.rs @@ -101,14 +101,33 @@ pub(crate) fn logging_call(checker: &mut Checker, call: &ast::ExprCall) { return; } - let Expr::Attribute(ast::ExprAttribute { attr, .. }) = call.func.as_ref() else { - return; + match call.func.as_ref() { + Expr::Attribute(ast::ExprAttribute { attr, .. }) => { + if LoggingLevel::from_attribute(attr).is_none() { + return; + }; + if !logging::is_logger_candidate( + &call.func, + checker.semantic(), + &checker.settings.logger_objects, + ) { + return; + } + } + Expr::Name(_) => { + let Some(call_path) = checker.semantic().resolve_call_path(call.func.as_ref()) else { + return; + }; + let ["logging", attribute] = call_path.as_slice() else { + return; + }; + if LoggingLevel::from_attribute(attribute).is_none() { + return; + }; + } + _ => return, }; - if LoggingLevel::from_attribute(attr.as_str()).is_none() { - return; - } - let Some(Expr::Constant(ast::ExprConstant { value: Constant::Str(ast::StringConstant { value, .. }), .. @@ -117,14 +136,6 @@ pub(crate) fn logging_call(checker: &mut Checker, call: &ast::ExprCall) { return; }; - if !logging::is_logger_candidate( - &call.func, - checker.semantic(), - &checker.settings.logger_objects, - ) { - return; - } - let Ok(summary) = CFormatSummary::try_from(value.as_str()) else { return; }; diff --git a/crates/ruff_linter/src/rules/pylint/rules/magic_value_comparison.rs b/crates/ruff_linter/src/rules/pylint/rules/magic_value_comparison.rs index 256ad1c77efbb..2bc7999066cbf 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/magic_value_comparison.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/magic_value_comparison.rs @@ -1,5 +1,5 @@ use itertools::Itertools; -use ruff_python_ast::{self as ast, Constant, Expr, UnaryOp}; +use ruff_python_ast::{self as ast, Constant, Expr, Int, UnaryOp}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -22,17 +22,23 @@ use crate::rules::pylint::settings::ConstantType; /// /// ## Example /// ```python -/// def calculate_discount(price: float) -> float: -/// return price * (1 - 0.2) +/// def apply_discount(price: float) -> float: +/// if price <= 100: +/// return price / 2 +/// else: +/// return price /// ``` /// /// Use instead: /// ```python -/// DISCOUNT_RATE = 0.2 +/// MAX_DISCOUNT = 100 /// /// -/// def calculate_discount(price: float) -> float: -/// return price * (1 - DISCOUNT_RATE) +/// def apply_discount(price: float) -> float: +/// if price <= MAX_DISCOUNT: +/// return price / 2 +/// else: +/// return price /// ``` /// /// [PEP 8]: https://peps.python.org/pep-0008/#constants @@ -83,7 +89,7 @@ fn is_magic_value(constant: &Constant, allowed_types: &[ConstantType]) -> bool { Constant::Str(ast::StringConstant { value, .. }) => { !matches!(value.as_str(), "" | "__main__") } - Constant::Int(value) => !matches!(value.try_into(), Ok(0 | 1)), + Constant::Int(value) => !matches!(*value, Int::ZERO | Int::ONE), Constant::Bytes(_) => true, Constant::Float(_) => true, Constant::Complex { .. } => true, diff --git a/crates/ruff_linter/src/rules/pylint/rules/manual_import_from.rs b/crates/ruff_linter/src/rules/pylint/rules/manual_import_from.rs index c3c91f08f7e58..4898c9b3100b5 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/manual_import_from.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/manual_import_from.rs @@ -1,11 +1,10 @@ use ruff_python_ast::{self as ast, Alias, Identifier, Stmt}; use ruff_text_size::{Ranged, TextRange}; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for submodule imports that are aliased to the submodule name. @@ -33,7 +32,7 @@ pub struct ManualFromImport { } impl Violation for ManualFromImport { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -41,7 +40,7 @@ impl Violation for ManualFromImport { format!("Use `from {module} import {name}` in lieu of alias") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let ManualFromImport { module, name } = self; Some(format!("Replace with `from {module} import {name}`")) } @@ -71,23 +70,21 @@ pub(crate) fn manual_from_import( }, alias.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if names.len() == 1 { - let node = ast::StmtImportFrom { - module: Some(Identifier::new(module.to_string(), TextRange::default())), - names: vec![Alias { - name: asname.clone(), - asname: None, - range: TextRange::default(), - }], - level: Some(0), + if names.len() == 1 { + let node = ast::StmtImportFrom { + module: Some(Identifier::new(module.to_string(), TextRange::default())), + names: vec![Alias { + name: asname.clone(), + asname: None, range: TextRange::default(), - }; - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - checker.generator().stmt(&node.into()), - stmt.range(), - ))); - } + }], + level: Some(0), + range: TextRange::default(), + }; + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + checker.generator().stmt(&node.into()), + stmt.range(), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pylint/rules/misplaced_bare_raise.rs b/crates/ruff_linter/src/rules/pylint/rules/misplaced_bare_raise.rs new file mode 100644 index 0000000000000..4f2787e57b52b --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/rules/misplaced_bare_raise.rs @@ -0,0 +1,70 @@ +use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast as ast; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; +use crate::rules::pylint::helpers::in_dunder_method; + +/// ## What it does +/// Checks for bare `raise` statements outside of exception handlers. +/// +/// ## Why is this bad? +/// A bare `raise` statement without an exception object will re-raise the last +/// exception that was active in the current scope, and is typically used +/// within an exception handler to re-raise the caught exception. +/// +/// If a bare `raise` is used outside of an exception handler, it will generate +/// an error due to the lack of an active exception. +/// +/// Note that a bare `raise` within a `finally` block will work in some cases +/// (namely, when the exception is raised within the `try` block), but should +/// be avoided as it can lead to confusing behavior. +/// +/// ## Example +/// ```python +/// from typing import Any +/// +/// +/// def is_some(obj: Any) -> bool: +/// if obj is None: +/// raise +/// ``` +/// +/// Use instead: +/// ```python +/// from typing import Any +/// +/// +/// def is_some(obj: Any) -> bool: +/// if obj is None: +/// raise ValueError("`obj` cannot be `None`") +/// ``` +#[violation] +pub struct MisplacedBareRaise; + +impl Violation for MisplacedBareRaise { + #[derive_message_formats] + fn message(&self) -> String { + format!("Bare `raise` statement is not inside an exception handler") + } +} + +/// PLE0704 +pub(crate) fn misplaced_bare_raise(checker: &mut Checker, raise: &ast::StmtRaise) { + if raise.exc.is_some() { + return; + } + + if checker.semantic().in_exception_handler() { + return; + } + + if in_dunder_method("__exit__", checker.semantic(), checker.settings) { + return; + } + + checker + .diagnostics + .push(Diagnostic::new(MisplacedBareRaise, raise.range())); +} diff --git a/crates/ruff_linter/src/rules/pylint/rules/mod.rs b/crates/ruff_linter/src/rules/pylint/rules/mod.rs index 7643b55b52140..ae3676ba3fc5d 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/mod.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/mod.rs @@ -1,3 +1,4 @@ +pub(crate) use and_or_ternary::*; pub(crate) use assert_on_string_literal::*; pub(crate) use await_outside_async::*; pub(crate) use bad_dunder_method_name::*; @@ -13,6 +14,7 @@ pub(crate) use comparison_with_itself::*; pub(crate) use continue_in_finally::*; pub(crate) use duplicate_bases::*; pub(crate) use eq_without_hash::*; +pub(crate) use global_at_module_level::*; pub(crate) use global_statement::*; pub(crate) use global_variable_not_assigned::*; pub(crate) use import_self::*; @@ -23,13 +25,17 @@ pub(crate) use invalid_envvar_value::*; pub(crate) use invalid_str_return::*; pub(crate) use invalid_string_characters::*; pub(crate) use iteration_over_set::*; +pub(crate) use literal_membership::*; pub(crate) use load_before_global_declaration::*; pub(crate) use logging::*; pub(crate) use magic_value_comparison::*; pub(crate) use manual_import_from::*; +pub(crate) use misplaced_bare_raise::*; pub(crate) use named_expr_without_context::*; pub(crate) use nested_min_max::*; pub(crate) use no_self_use::*; +pub(crate) use non_ascii_module_import::*; +pub(crate) use non_ascii_name::*; pub(crate) use nonlocal_without_binding::*; pub(crate) use property_with_parameters::*; pub(crate) use redefined_loop_name::*; @@ -42,6 +48,7 @@ pub(crate) use subprocess_popen_preexec_fn::*; pub(crate) use subprocess_run_without_check::*; pub(crate) use sys_exit_alias::*; pub(crate) use too_many_arguments::*; +pub(crate) use too_many_boolean_expressions::*; pub(crate) use too_many_branches::*; pub(crate) use too_many_public_methods::*; pub(crate) use too_many_return_statements::*; @@ -51,12 +58,15 @@ pub(crate) use type_name_incorrect_variance::*; pub(crate) use type_param_name_mismatch::*; pub(crate) use unexpected_special_method_signature::*; pub(crate) use unnecessary_direct_lambda_call::*; +pub(crate) use unnecessary_lambda::*; +pub(crate) use unspecified_encoding::*; pub(crate) use useless_else_on_loop::*; pub(crate) use useless_import_alias::*; pub(crate) use useless_return::*; pub(crate) use yield_from_in_async_function::*; pub(crate) use yield_in_init::*; +mod and_or_ternary; mod assert_on_string_literal; mod await_outside_async; mod bad_dunder_method_name; @@ -72,6 +82,7 @@ mod comparison_with_itself; mod continue_in_finally; mod duplicate_bases; mod eq_without_hash; +mod global_at_module_level; mod global_statement; mod global_variable_not_assigned; mod import_self; @@ -82,13 +93,17 @@ mod invalid_envvar_value; mod invalid_str_return; mod invalid_string_characters; mod iteration_over_set; +mod literal_membership; mod load_before_global_declaration; mod logging; mod magic_value_comparison; mod manual_import_from; +mod misplaced_bare_raise; mod named_expr_without_context; mod nested_min_max; mod no_self_use; +mod non_ascii_module_import; +mod non_ascii_name; mod nonlocal_without_binding; mod property_with_parameters; mod redefined_loop_name; @@ -101,6 +116,7 @@ mod subprocess_popen_preexec_fn; mod subprocess_run_without_check; mod sys_exit_alias; mod too_many_arguments; +mod too_many_boolean_expressions; mod too_many_branches; mod too_many_public_methods; mod too_many_return_statements; @@ -110,6 +126,8 @@ mod type_name_incorrect_variance; mod type_param_name_mismatch; mod unexpected_special_method_signature; mod unnecessary_direct_lambda_call; +mod unnecessary_lambda; +mod unspecified_encoding; mod useless_else_on_loop; mod useless_import_alias; mod useless_return; diff --git a/crates/ruff_linter/src/rules/pylint/rules/nested_min_max.rs b/crates/ruff_linter/src/rules/pylint/rules/nested_min_max.rs index 7e76598817495..3911b55be2294 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/nested_min_max.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/nested_min_max.rs @@ -1,11 +1,11 @@ use ruff_python_ast::{self as ast, Arguments, Expr, Keyword}; use ruff_text_size::{Ranged, TextRange}; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_semantic::SemanticModel; -use crate::{checkers::ast::Checker, registry::AsRule}; +use crate::checkers::ast::Checker; #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub(crate) enum MinMax { @@ -43,7 +43,7 @@ pub struct NestedMinMax { } impl Violation for NestedMinMax { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] @@ -52,7 +52,7 @@ impl Violation for NestedMinMax { format!("Nested `{func}` calls can be flattened") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let NestedMinMax { func } = self; Some(format!("Flatten nested `{func}` calls")) } @@ -160,22 +160,20 @@ pub(crate) fn nested_min_max( MinMax::try_from_call(func.as_ref(), keywords.as_ref(), checker.semantic()) == Some(min_max) }) { let mut diagnostic = Diagnostic::new(NestedMinMax { func: min_max }, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - if !checker.indexer().has_comments(expr, checker.locator()) { - let flattened_expr = Expr::Call(ast::ExprCall { - func: Box::new(func.clone()), - arguments: Arguments { - args: collect_nested_args(min_max, args, checker.semantic()), - keywords: keywords.to_owned(), - range: TextRange::default(), - }, + if !checker.indexer().has_comments(expr, checker.locator()) { + let flattened_expr = Expr::Call(ast::ExprCall { + func: Box::new(func.clone()), + arguments: Arguments { + args: collect_nested_args(min_max, args, checker.semantic()), + keywords: keywords.to_owned(), range: TextRange::default(), - }); - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.generator().expr(&flattened_expr), - expr.range(), - ))); - } + }, + range: TextRange::default(), + }); + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + checker.generator().expr(&flattened_expr), + expr.range(), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pylint/rules/no_self_use.rs b/crates/ruff_linter/src/rules/pylint/rules/no_self_use.rs index 10734618ef2dd..eed411f123e63 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/no_self_use.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/no_self_use.rs @@ -4,7 +4,7 @@ use ruff_python_ast::call_path::{from_qualified_name, CallPath}; use ruff_python_ast::{self as ast, ParameterWithDefault}; use ruff_python_semantic::{ analyze::{function_type, visibility}, - Scope, ScopeKind, + Scope, ScopeId, ScopeKind, }; use ruff_text_size::Ranged; @@ -15,7 +15,7 @@ use crate::{checkers::ast::Checker, rules::flake8_unused_arguments::helpers}; /// /// ## Why is this bad? /// Unused `self` parameters are usually a sign of a method that could be -/// replaced by a function or a static method. +/// replaced by a function, class method, or static method. /// /// ## Example /// ```python @@ -26,10 +26,8 @@ use crate::{checkers::ast::Checker, rules::flake8_unused_arguments::helpers}; /// /// Use instead: /// ```python -/// class Person: -/// @staticmethod -/// def greeting(): -/// print(f"Greetings friend!") +/// def greeting(): +/// print("Greetings friend!") /// ``` #[violation] pub struct NoSelfUse { @@ -40,12 +38,17 @@ impl Violation for NoSelfUse { #[derive_message_formats] fn message(&self) -> String { let NoSelfUse { method_name } = self; - format!("Method `{method_name}` could be a function or static method") + format!("Method `{method_name}` could be a function, class method, or static method") } } /// PLR6301 -pub(crate) fn no_self_use(checker: &Checker, scope: &Scope, diagnostics: &mut Vec) { +pub(crate) fn no_self_use( + checker: &Checker, + scope_id: ScopeId, + scope: &Scope, + diagnostics: &mut Vec, +) { let Some(parent) = &checker.semantic().first_non_type_parent_scope(scope) else { return; }; @@ -105,11 +108,28 @@ pub(crate) fn no_self_use(checker: &Checker, scope: &Scope, diagnostics: &mut Ve return; }; - if parameter.name.as_str() == "self" - && scope - .get("self") - .map(|binding_id| checker.semantic().binding(binding_id)) - .is_some_and(|binding| binding.kind.is_argument() && !binding.is_used()) + if parameter.name.as_str() != "self" { + return; + } + + // If the method contains a `super` reference, then it should be considered to use self + // implicitly. + if let Some(binding_id) = checker.semantic().global_scope().get("super") { + let binding = checker.semantic().binding(binding_id); + if binding.kind.is_builtin() { + if binding + .references() + .any(|id| checker.semantic().reference(id).scope_id() == scope_id) + { + return; + } + } + } + + if scope + .get("self") + .map(|binding_id| checker.semantic().binding(binding_id)) + .is_some_and(|binding| binding.kind.is_argument() && !binding.is_used()) { diagnostics.push(Diagnostic::new( NoSelfUse { diff --git a/crates/ruff_linter/src/rules/pylint/rules/non_ascii_module_import.rs b/crates/ruff_linter/src/rules/pylint/rules/non_ascii_module_import.rs new file mode 100644 index 0000000000000..577a4b69f19f1 --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/rules/non_ascii_module_import.rs @@ -0,0 +1,92 @@ +use ruff_python_ast::Alias; + +use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for the use of non-ASCII characters in import statements. +/// +/// ## Why is this bad? +/// The use of non-ASCII characters in import statements can cause confusion +/// and compatibility issues (see: [PEP 672]). +/// +/// ## Example +/// ```python +/// import bár +/// ``` +/// +/// Use instead: +/// ```python +/// import bar +/// ``` +/// +/// If the module is third-party, use an ASCII-only alias: +/// ```python +/// import bár as bar +/// ``` +/// +/// [PEP 672]: https://peps.python.org/pep-0672/ +#[violation] +pub struct NonAsciiImportName { + name: String, + kind: Kind, +} + +impl Violation for NonAsciiImportName { + #[derive_message_formats] + fn message(&self) -> String { + let Self { name, kind } = self; + match kind { + Kind::Aliased => { + format!( + "Module alias `{name}` contains a non-ASCII character, use an ASCII-only alias" + ) + } + Kind::Unaliased => { + format!( + "Module name `{name}` contains a non-ASCII character, use an ASCII-only alias" + ) + } + } + } +} + +#[derive(Debug, PartialEq, Eq)] +enum Kind { + /// The import uses a non-ASCII alias (e.g., `import foo as bár`). + Aliased, + /// The imported module is non-ASCII, and could be given an ASCII alias (e.g., `import bár`). + Unaliased, +} + +/// PLC2403 +pub(crate) fn non_ascii_module_import(checker: &mut Checker, alias: &Alias) { + if let Some(asname) = &alias.asname { + if asname.as_str().is_ascii() { + return; + } + + checker.diagnostics.push(Diagnostic::new( + NonAsciiImportName { + name: asname.to_string(), + kind: Kind::Aliased, + }, + asname.range(), + )); + } else { + if alias.name.as_str().is_ascii() { + return; + } + + checker.diagnostics.push(Diagnostic::new( + NonAsciiImportName { + name: alias.name.to_string(), + kind: Kind::Unaliased, + }, + alias.name.range(), + )); + } +} diff --git a/crates/ruff_linter/src/rules/pylint/rules/non_ascii_name.rs b/crates/ruff_linter/src/rules/pylint/rules/non_ascii_name.rs new file mode 100644 index 0000000000000..c3326b9f5f63c --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/rules/non_ascii_name.rs @@ -0,0 +1,116 @@ +use std::fmt; + +use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_semantic::{Binding, BindingKind}; +use ruff_source_file::Locator; +use ruff_text_size::Ranged; + +/// ## What it does +/// Checks for the use of non-ASCII characters in variable names. +/// +/// ## Why is this bad? +/// The use of non-ASCII characters in variable names can cause confusion +/// and compatibility issues (see: [PEP 672]). +/// +/// ## Example +/// ```python +/// ápple_count: int +/// ``` +/// +/// Use instead: +/// ```python +/// apple_count: int +/// ``` +/// +/// [PEP 672]: https://peps.python.org/pep-0672/ +#[violation] +pub struct NonAsciiName { + name: String, + kind: Kind, +} + +impl Violation for NonAsciiName { + #[derive_message_formats] + fn message(&self) -> String { + let Self { name, kind } = self; + format!("{kind} name `{name}` contains a non-ASCII character, consider renaming it") + } +} + +/// PLC2401 +pub(crate) fn non_ascii_name(binding: &Binding, locator: &Locator) -> Option { + let name = binding.name(locator); + if name.is_ascii() { + return None; + } + + let kind = match binding.kind { + BindingKind::Annotation => Kind::Annotation, + BindingKind::Argument => Kind::Argument, + BindingKind::NamedExprAssignment => Kind::NamedExprAssignment, + BindingKind::UnpackedAssignment => Kind::UnpackedAssignment, + BindingKind::Assignment => Kind::Assignment, + BindingKind::TypeParam => Kind::TypeParam, + BindingKind::LoopVar => Kind::LoopVar, + BindingKind::Global => Kind::Global, + BindingKind::Nonlocal(_) => Kind::Nonlocal, + BindingKind::ClassDefinition(_) => Kind::ClassDefinition, + BindingKind::FunctionDefinition(_) => Kind::FunctionDefinition, + BindingKind::BoundException => Kind::BoundException, + + BindingKind::Builtin + | BindingKind::Export(_) + | BindingKind::FutureImport + | BindingKind::Import(_) + | BindingKind::FromImport(_) + | BindingKind::SubmoduleImport(_) + | BindingKind::Deletion + | BindingKind::UnboundException(_) => { + return None; + } + }; + + Some(Diagnostic::new( + NonAsciiName { + name: name.to_string(), + kind, + }, + binding.range(), + )) +} + +#[derive(Debug, PartialEq, Eq)] +enum Kind { + Annotation, + Argument, + NamedExprAssignment, + UnpackedAssignment, + Assignment, + TypeParam, + LoopVar, + Global, + Nonlocal, + ClassDefinition, + FunctionDefinition, + BoundException, +} + +impl fmt::Display for Kind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Kind::Annotation => f.write_str("Annotation"), + Kind::Argument => f.write_str("Argument"), + Kind::NamedExprAssignment => f.write_str("Variable"), + Kind::UnpackedAssignment => f.write_str("Variable"), + Kind::Assignment => f.write_str("Variable"), + Kind::TypeParam => f.write_str("Type parameter"), + Kind::LoopVar => f.write_str("Variable"), + Kind::Global => f.write_str("Global"), + Kind::Nonlocal => f.write_str("Nonlocal"), + Kind::ClassDefinition => f.write_str("Class"), + Kind::FunctionDefinition => f.write_str("Function"), + Kind::BoundException => f.write_str("Exception"), + } + } +} diff --git a/crates/ruff_linter/src/rules/pylint/rules/repeated_equality_comparison.rs b/crates/ruff_linter/src/rules/pylint/rules/repeated_equality_comparison.rs index 67b7c2c069c88..d3077539c8a34 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/repeated_equality_comparison.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/repeated_equality_comparison.rs @@ -4,16 +4,17 @@ use std::ops::Deref; use itertools::{any, Itertools}; use rustc_hash::FxHashMap; -use ruff_diagnostics::{Diagnostic, Violation}; +use ast::ExprContext; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::comparable::ComparableExpr; use ruff_python_ast::hashable::HashableExpr; use ruff_python_ast::{self as ast, BoolOp, CmpOp, Expr}; use ruff_source_file::Locator; -use ruff_text_size::{Ranged, TextSize}; +use ruff_text_size::{Ranged, TextRange, TextSize}; -use crate::autofix::snippet::SourceCodeSnippet; use crate::checkers::ast::Checker; +use crate::fix::snippet::SourceCodeSnippet; /// ## What it does /// Checks for repeated equality comparisons that can rewritten as a membership @@ -48,7 +49,7 @@ pub struct RepeatedEqualityComparison { expression: SourceCodeSnippet, } -impl Violation for RepeatedEqualityComparison { +impl AlwaysFixableViolation for RepeatedEqualityComparison { #[derive_message_formats] fn message(&self) -> String { let RepeatedEqualityComparison { expression } = self; @@ -62,6 +63,10 @@ impl Violation for RepeatedEqualityComparison { ) } } + + fn fix_title(&self) -> String { + format!("Merge multiple comparisons") + } } /// PLR1714 @@ -115,7 +120,7 @@ pub(crate) fn repeated_equality_comparison(checker: &mut Checker, bool_op: &ast: .sorted_by_key(|(_, (start, _))| *start) { if comparators.len() > 1 { - checker.diagnostics.push(Diagnostic::new( + let mut diagnostic = Diagnostic::new( RepeatedEqualityComparison { expression: SourceCodeSnippet::new(merged_membership_test( value.as_expr(), @@ -125,7 +130,26 @@ pub(crate) fn repeated_equality_comparison(checker: &mut Checker, bool_op: &ast: )), }, bool_op.range(), - )); + ); + + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + checker.generator().expr(&Expr::Compare(ast::ExprCompare { + left: Box::new(value.as_expr().clone()), + ops: match bool_op.op { + BoolOp::Or => vec![CmpOp::In], + BoolOp::And => vec![CmpOp::NotIn], + }, + comparators: vec![Expr::Tuple(ast::ExprTuple { + elts: comparators.iter().copied().cloned().collect(), + range: TextRange::default(), + ctx: ExprContext::Load, + })], + range: bool_op.range(), + })), + bool_op.range(), + ))); + + checker.diagnostics.push(diagnostic); } } } diff --git a/crates/ruff_linter/src/rules/pylint/rules/repeated_isinstance_calls.rs b/crates/ruff_linter/src/rules/pylint/rules/repeated_isinstance_calls.rs index 9b7e40a09233c..4ede23df5ca3d 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/repeated_isinstance_calls.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/repeated_isinstance_calls.rs @@ -2,15 +2,15 @@ use itertools::Itertools; use ruff_python_ast::{self as ast, Arguments, BoolOp, Expr}; use rustc_hash::{FxHashMap, FxHashSet}; -use crate::autofix::edits::pad; -use crate::autofix::snippet::SourceCodeSnippet; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use crate::fix::edits::pad; +use crate::fix::snippet::SourceCodeSnippet; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::hashable::HashableExpr; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::settings::types::PythonVersion; /// ## What it does @@ -49,7 +49,7 @@ pub struct RepeatedIsinstanceCalls { expression: SourceCodeSnippet, } -impl AlwaysAutofixableViolation for RepeatedIsinstanceCalls { +impl AlwaysFixableViolation for RepeatedIsinstanceCalls { #[derive_message_formats] fn message(&self) -> String { let RepeatedIsinstanceCalls { expression } = self; @@ -60,7 +60,7 @@ impl AlwaysAutofixableViolation for RepeatedIsinstanceCalls { } } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let RepeatedIsinstanceCalls { expression } = self; if let Some(expression) = expression.full_display() { format!("Replace with `{expression}`") @@ -133,12 +133,10 @@ pub(crate) fn repeated_isinstance_calls( }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - pad(call, expr.range(), checker.locator()), - expr.range(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + pad(call, expr.range(), checker.locator()), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pylint/rules/return_in_init.rs b/crates/ruff_linter/src/rules/pylint/rules/return_in_init.rs index 7e18303678f7a..235752725400b 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/return_in_init.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/return_in_init.rs @@ -6,7 +6,7 @@ use ruff_python_ast::helpers::is_const_none; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::rules::pylint::helpers::in_dunder_init; +use crate::rules::pylint::helpers::in_dunder_method; /// ## What it does /// Checks for `__init__` methods that return values. @@ -58,7 +58,7 @@ pub(crate) fn return_in_init(checker: &mut Checker, stmt: &Stmt) { } } - if in_dunder_init(checker.semantic(), checker.settings) { + if in_dunder_method("__init__", checker.semantic(), checker.settings) { checker .diagnostics .push(Diagnostic::new(ReturnInInit, stmt.range())); diff --git a/crates/ruff_linter/src/rules/pylint/rules/sys_exit_alias.rs b/crates/ruff_linter/src/rules/pylint/rules/sys_exit_alias.rs index 3fe8cacf5036d..894cda0c15467 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/sys_exit_alias.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/sys_exit_alias.rs @@ -1,12 +1,11 @@ use ruff_python_ast::{self as ast, Expr}; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::importer::ImportRequest; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of the `exit()` and `quit()`. @@ -43,7 +42,7 @@ pub struct SysExitAlias { } impl Violation for SysExitAlias { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -51,7 +50,7 @@ impl Violation for SysExitAlias { format!("Use `sys.exit()` instead of `{name}`") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let SysExitAlias { name } = self; Some(format!("Replace `{name}` with `sys.exit()`")) } @@ -77,16 +76,14 @@ pub(crate) fn sys_exit_alias(checker: &mut Checker, func: &Expr) { }, func.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - let (import_edit, binding) = checker.importer().get_or_import_symbol( - &ImportRequest::import("sys", "exit"), - func.start(), - checker.semantic(), - )?; - let reference_edit = Edit::range_replacement(binding, func.range()); - Ok(Fix::suggested_edits(import_edit, [reference_edit])) - }); - } + diagnostic.try_set_fix(|| { + let (import_edit, binding) = checker.importer().get_or_import_symbol( + &ImportRequest::import("sys", "exit"), + func.start(), + checker.semantic(), + )?; + let reference_edit = Edit::range_replacement(binding, func.range()); + Ok(Fix::unsafe_edits(import_edit, [reference_edit])) + }); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pylint/rules/too_many_arguments.rs b/crates/ruff_linter/src/rules/pylint/rules/too_many_arguments.rs index 8948aeb0cc152..5ddd80ecbc37c 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/too_many_arguments.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/too_many_arguments.rs @@ -53,7 +53,7 @@ impl Violation for TooManyArguments { #[derive_message_formats] fn message(&self) -> String { let TooManyArguments { c_args, max_args } = self; - format!("Too many arguments to function call ({c_args} > {max_args})") + format!("Too many arguments in function definition ({c_args} > {max_args})") } } diff --git a/crates/ruff_linter/src/rules/pylint/rules/too_many_boolean_expressions.rs b/crates/ruff_linter/src/rules/pylint/rules/too_many_boolean_expressions.rs new file mode 100644 index 0000000000000..33cead02fc3cf --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/rules/too_many_boolean_expressions.rs @@ -0,0 +1,89 @@ +use ast::{Expr, StmtIf}; +use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast as ast; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for too many Boolean expressions in an `if` statement. +/// +/// By default, this rule allows up to 5 expressions. This can be configured +/// using the [`pylint.max-bool-expr`] option. +/// +/// ## Why is this bad? +/// `if` statements with many Boolean expressions are harder to understand +/// and maintain. Consider assigning the result of the Boolean expression, +/// or any of its sub-expressions, to a variable. +/// +/// ## Example +/// ```python +/// if a and b and c and d and e and f and g and h: +/// ... +/// ``` +/// +/// ## Options +/// - `pylint.max-bool-expr` +#[violation] +pub struct TooManyBooleanExpressions { + expressions: usize, + max_expressions: usize, +} + +impl Violation for TooManyBooleanExpressions { + #[derive_message_formats] + fn message(&self) -> String { + let TooManyBooleanExpressions { + expressions, + max_expressions, + } = self; + format!("Too many Boolean expressions ({expressions} > {max_expressions})") + } +} + +/// PLR0916 +pub(crate) fn too_many_boolean_expressions(checker: &mut Checker, stmt: &StmtIf) { + if let Some(bool_op) = stmt.test.as_bool_op_expr() { + let expressions = count_bools(bool_op); + if expressions > checker.settings.pylint.max_bool_expr { + checker.diagnostics.push(Diagnostic::new( + TooManyBooleanExpressions { + expressions, + max_expressions: checker.settings.pylint.max_bool_expr, + }, + bool_op.range(), + )); + } + } + + for elif in &stmt.elif_else_clauses { + if let Some(bool_op) = elif.test.as_ref().and_then(Expr::as_bool_op_expr) { + let expressions = count_bools(bool_op); + if expressions > checker.settings.pylint.max_bool_expr { + checker.diagnostics.push(Diagnostic::new( + TooManyBooleanExpressions { + expressions, + max_expressions: checker.settings.pylint.max_bool_expr, + }, + bool_op.range(), + )); + } + } + } +} + +/// Count the number of Boolean expressions in a `bool_op` expression. +fn count_bools(bool_op: &ast::ExprBoolOp) -> usize { + bool_op + .values + .iter() + .map(|expr| { + if let Expr::BoolOp(bool_op) = expr { + count_bools(bool_op) + } else { + 1 + } + }) + .sum::() +} diff --git a/crates/ruff_linter/src/rules/pylint/rules/unnecessary_lambda.rs b/crates/ruff_linter/src/rules/pylint/rules/unnecessary_lambda.rs new file mode 100644 index 0000000000000..82e5c8decd46b --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/rules/unnecessary_lambda.rs @@ -0,0 +1,209 @@ +use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::visitor::Visitor; +use ruff_python_ast::{self as ast, visitor, Expr, ExprLambda, Parameter, ParameterWithDefault}; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for `lambda` definitions that consist of a single function call +/// with the same arguments as the `lambda` itself. +/// +/// ## Why is this bad? +/// When a `lambda` is used to wrap a function call, and merely propagates +/// the `lambda` arguments to that function, it can typically be replaced with +/// the function itself, removing a level of indirection. +/// +/// ## Example +/// ```python +/// df.apply(lambda x: str(x)) +/// ``` +/// +/// Use instead: +/// ```python +/// df.apply(str) +/// ``` +#[violation] +pub struct UnnecessaryLambda; + +impl Violation for UnnecessaryLambda { + #[derive_message_formats] + fn message(&self) -> String { + format!("Lambda may be unnecessary; consider inlining inner function") + } +} + +/// PLW0108 +pub(crate) fn unnecessary_lambda(checker: &mut Checker, lambda: &ExprLambda) { + let ExprLambda { + parameters, + body, + range: _, + } = lambda; + + // The lambda should consist of a single function call. + let Expr::Call(ast::ExprCall { + arguments, func, .. + }) = body.as_ref() + else { + return; + }; + + // Ignore call chains. + if let Expr::Attribute(ast::ExprAttribute { value, .. }) = func.as_ref() { + if value.is_call_expr() { + return; + } + } + + // If at least one of the lambda parameters has a default value, abort. We can't know if the + // defaults provided by the lambda are the same as the defaults provided by the inner + // function. + if parameters.as_ref().is_some_and(|parameters| { + parameters + .args + .iter() + .any(|ParameterWithDefault { default, .. }| default.is_some()) + }) { + return; + } + + match parameters.as_ref() { + None => { + if !arguments.is_empty() { + return; + } + } + Some(parameters) => { + // Collect all starred arguments (e.g., `lambda *args: func(*args)`). + let call_varargs: Vec<&Expr> = arguments + .args + .iter() + .filter_map(|arg| { + if let Expr::Starred(ast::ExprStarred { value, .. }) = arg { + Some(value.as_ref()) + } else { + None + } + }) + .collect::>(); + + // Collect all keyword arguments (e.g., `lambda x, y: func(x=x, y=y)`). + let call_kwargs: Vec<&Expr> = arguments + .keywords + .iter() + .map(|kw| &kw.value) + .collect::>(); + + // Collect all positional arguments (e.g., `lambda x, y: func(x, y)`). + let call_posargs: Vec<&Expr> = arguments + .args + .iter() + .filter(|arg| !arg.is_starred_expr()) + .collect::>(); + + // Ex) `lambda **kwargs: func(**kwargs)` + match parameters.kwarg.as_ref() { + None => { + if !call_kwargs.is_empty() { + return; + } + } + Some(kwarg) => { + let [call_kwarg] = &call_kwargs[..] else { + return; + }; + + let Expr::Name(ast::ExprName { id, .. }) = call_kwarg else { + return; + }; + + if id.as_str() != kwarg.name.as_str() { + return; + } + } + } + + // Ex) `lambda *args: func(*args)` + match parameters.vararg.as_ref() { + None => { + if !call_varargs.is_empty() { + return; + } + } + Some(vararg) => { + let [call_vararg] = &call_varargs[..] else { + return; + }; + + let Expr::Name(ast::ExprName { id, .. }) = call_vararg else { + return; + }; + + if id.as_str() != vararg.name.as_str() { + return; + } + } + } + + // Ex) `lambda x, y: func(x, y)` + let lambda_posargs: Vec<&Parameter> = parameters + .args + .iter() + .map(|ParameterWithDefault { parameter, .. }| parameter) + .collect::>(); + if call_posargs.len() != lambda_posargs.len() { + return; + } + for (param, arg) in lambda_posargs.iter().zip(call_posargs.iter()) { + let Expr::Name(ast::ExprName { id, .. }) = arg else { + return; + }; + if id.as_str() != param.name.as_str() { + return; + } + } + } + } + + // The lambda is necessary if it uses one of its parameters _as_ the function call. + // Ex) `lambda x, y: x(y)` + let names = { + let mut finder = NameFinder::default(); + finder.visit_expr(func); + finder.names + }; + + for name in names { + if let Some(binding_id) = checker.semantic().resolve_name(name) { + let binding = checker.semantic().binding(binding_id); + if checker.semantic().is_current_scope(binding.scope) { + return; + } + } + } + + checker + .diagnostics + .push(Diagnostic::new(UnnecessaryLambda, lambda.range())); +} + +/// Identify all `Expr::Name` nodes in an AST. +#[derive(Debug, Default)] +struct NameFinder<'a> { + /// A map from identifier to defining expression. + names: Vec<&'a ast::ExprName>, +} + +impl<'a, 'b> Visitor<'b> for NameFinder<'a> +where + 'b: 'a, +{ + fn visit_expr(&mut self, expr: &'a Expr) { + if let Expr::Name(expr_name) = expr { + self.names.push(expr_name); + } + visitor::walk_expr(self, expr); + } +} diff --git a/crates/ruff_linter/src/rules/pylint/rules/unspecified_encoding.rs b/crates/ruff_linter/src/rules/pylint/rules/unspecified_encoding.rs new file mode 100644 index 0000000000000..8d2b83dddec9d --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/rules/unspecified_encoding.rs @@ -0,0 +1,157 @@ +use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast as ast; +use ruff_python_ast::call_path::{format_call_path, CallPath}; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for uses of `open` and related calls without an explicit `encoding` +/// argument. +/// +/// ## Why is this bad? +/// Using `open` in text mode without an explicit encoding can lead to +/// non-portable code, with differing behavior across platforms. +/// +/// Instead, consider using the `encoding` parameter to enforce a specific +/// encoding. +/// +/// ## Example +/// ```python +/// open("file.txt") +/// ``` +/// +/// Use instead: +/// ```python +/// open("file.txt", encoding="utf-8") +/// ``` +/// +/// ## References +/// - [Python documentation: `open`](https://docs.python.org/3/library/functions.html#open) +#[violation] +pub struct UnspecifiedEncoding { + function_name: String, + mode: Mode, +} + +impl Violation for UnspecifiedEncoding { + #[derive_message_formats] + fn message(&self) -> String { + let UnspecifiedEncoding { + function_name, + mode, + } = self; + + match mode { + Mode::Supported => { + format!("`{function_name}` in text mode without explicit `encoding` argument") + } + Mode::Unsupported => { + format!("`{function_name}` without explicit `encoding` argument") + } + } + } +} + +/// PLW1514 +pub(crate) fn unspecified_encoding(checker: &mut Checker, call: &ast::ExprCall) { + let Some((function_name, mode)) = checker + .semantic() + .resolve_call_path(&call.func) + .filter(|call_path| is_violation(call, call_path)) + .map(|call_path| { + ( + format_call_path(call_path.as_slice()), + Mode::from(&call_path), + ) + }) + else { + return; + }; + + checker.diagnostics.push(Diagnostic::new( + UnspecifiedEncoding { + function_name, + mode, + }, + call.func.range(), + )); +} + +/// Returns `true` if the given expression is a string literal containing a `b` character. +fn is_binary_mode(expr: &ast::Expr) -> Option { + Some(expr.as_constant_expr()?.value.as_str()?.value.contains('b')) +} + +/// Returns `true` if the given call lacks an explicit `encoding`. +fn is_violation(call: &ast::ExprCall, call_path: &CallPath) -> bool { + // If we have something like `*args`, which might contain the encoding argument, abort. + if call + .arguments + .args + .iter() + .any(ruff_python_ast::Expr::is_starred_expr) + { + return false; + } + // If we have something like `**kwargs`, which might contain the encoding argument, abort. + if call + .arguments + .keywords + .iter() + .any(|keyword| keyword.arg.is_none()) + { + return false; + } + match call_path.as_slice() { + ["" | "codecs" | "_io", "open"] => { + if let Some(mode_arg) = call.arguments.find_argument("mode", 1) { + if is_binary_mode(mode_arg).unwrap_or(true) { + // binary mode or unknown mode is no violation + return false; + } + } + // else mode not specified, defaults to text mode + call.arguments.find_argument("encoding", 3).is_none() + } + ["tempfile", "TemporaryFile" | "NamedTemporaryFile" | "SpooledTemporaryFile"] => { + let mode_pos = usize::from(call_path[1] == "SpooledTemporaryFile"); + if let Some(mode_arg) = call.arguments.find_argument("mode", mode_pos) { + if is_binary_mode(mode_arg).unwrap_or(true) { + // binary mode or unknown mode is no violation + return false; + } + } else { + // defaults to binary mode + return false; + } + call.arguments + .find_argument("encoding", mode_pos + 2) + .is_none() + } + ["io" | "_io", "TextIOWrapper"] => call.arguments.find_argument("encoding", 1).is_none(), + _ => false, + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Mode { + /// The call supports a `mode` argument. + Supported, + /// The call does not support a `mode` argument. + Unsupported, +} + +impl From<&CallPath<'_>> for Mode { + fn from(value: &CallPath<'_>) -> Self { + match value.as_slice() { + ["" | "codecs" | "_io", "open"] => Mode::Supported, + ["tempfile", "TemporaryFile" | "NamedTemporaryFile" | "SpooledTemporaryFile"] => { + Mode::Supported + } + ["io" | "_io", "TextIOWrapper"] => Mode::Unsupported, + _ => Mode::Unsupported, + } + } +} diff --git a/crates/ruff_linter/src/rules/pylint/rules/useless_import_alias.rs b/crates/ruff_linter/src/rules/pylint/rules/useless_import_alias.rs index fabdc4e91cc4e..f86314a3a24fd 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/useless_import_alias.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/useless_import_alias.rs @@ -1,11 +1,10 @@ use ruff_python_ast::Alias; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for import aliases that do not rename the original package. @@ -25,13 +24,13 @@ use crate::registry::AsRule; #[violation] pub struct UselessImportAlias; -impl AlwaysAutofixableViolation for UselessImportAlias { +impl AlwaysFixableViolation for UselessImportAlias { #[derive_message_formats] fn message(&self) -> String { format!("Import alias does not rename original package") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove import alias".to_string() } } @@ -49,11 +48,9 @@ pub(crate) fn useless_import_alias(checker: &mut Checker, alias: &Alias) { } let mut diagnostic = Diagnostic::new(UselessImportAlias, alias.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - asname.to_string(), - alias.range(), - ))); - } + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + asname.to_string(), + alias.range(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pylint/rules/useless_return.rs b/crates/ruff_linter/src/rules/pylint/rules/useless_return.rs index 6df823f386ee8..1221cf7eaaee5 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/useless_return.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/useless_return.rs @@ -1,14 +1,13 @@ use ruff_python_ast::{self as ast, Constant, Expr, Stmt}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::{is_const_none, ReturnStatementVisitor}; use ruff_python_ast::statement_visitor::StatementVisitor; use ruff_text_size::Ranged; -use crate::autofix; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix; /// ## What it does /// Checks for functions that end with an unnecessary `return` or @@ -33,13 +32,13 @@ use crate::registry::AsRule; #[violation] pub struct UselessReturn; -impl AlwaysAutofixableViolation for UselessReturn { +impl AlwaysFixableViolation for UselessReturn { #[derive_message_formats] fn message(&self) -> String { format!("Useless `return` statement at end of function") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { format!("Remove useless `return` statement") } } @@ -103,16 +102,9 @@ pub(crate) fn useless_return( } let mut diagnostic = Diagnostic::new(UselessReturn, last_stmt.range()); - if checker.patch(diagnostic.kind.rule()) { - let edit = autofix::edits::delete_stmt( - last_stmt, - Some(stmt), - checker.locator(), - checker.indexer(), - ); - diagnostic.set_fix(Fix::automatic(edit).isolate(Checker::isolation(Some( - checker.semantic().current_statement_id(), - )))); - } + let edit = fix::edits::delete_stmt(last_stmt, Some(stmt), checker.locator(), checker.indexer()); + diagnostic.set_fix(Fix::safe_edit(edit).isolate(Checker::isolation( + checker.semantic().current_statement_id(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pylint/rules/yield_in_init.rs b/crates/ruff_linter/src/rules/pylint/rules/yield_in_init.rs index fb7febaf2de3e..1e98e5d81d7eb 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/yield_in_init.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/yield_in_init.rs @@ -5,7 +5,7 @@ use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::rules::pylint::helpers::in_dunder_init; +use crate::rules::pylint::helpers::in_dunder_method; /// ## What it does /// Checks for `__init__` methods that are turned into generators by the @@ -40,7 +40,7 @@ impl Violation for YieldInInit { /// PLE0100 pub(crate) fn yield_in_init(checker: &mut Checker, expr: &Expr) { - if in_dunder_init(checker.semantic(), checker.settings) { + if in_dunder_method("__init__", checker.semantic(), checker.settings) { checker .diagnostics .push(Diagnostic::new(YieldInInit, expr.range())); diff --git a/crates/ruff_linter/src/rules/pylint/settings.rs b/crates/ruff_linter/src/rules/pylint/settings.rs index e09e4835f8279..93e28b2679521 100644 --- a/crates/ruff_linter/src/rules/pylint/settings.rs +++ b/crates/ruff_linter/src/rules/pylint/settings.rs @@ -15,7 +15,6 @@ pub enum ConstantType { Float, Int, Str, - Tuple, } impl TryFrom<&Constant> for ConstantType { @@ -40,6 +39,7 @@ pub struct Settings { pub allow_magic_value_types: Vec, pub max_args: usize, pub max_returns: usize, + pub max_bool_expr: usize, pub max_branches: usize, pub max_statements: usize, pub max_public_methods: usize, @@ -51,6 +51,7 @@ impl Default for Settings { allow_magic_value_types: vec![ConstantType::Str, ConstantType::Bytes], max_args: 5, max_returns: 6, + max_bool_expr: 5, max_branches: 12, max_statements: 50, max_public_methods: 20, diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLC0208_iteration_over_set.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLC0208_iteration_over_set.py.snap index 9ff95583a05f5..91fa2dc50a1f8 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLC0208_iteration_over_set.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLC0208_iteration_over_set.py.snap @@ -1,53 +1,173 @@ --- source: crates/ruff_linter/src/rules/pylint/mod.rs --- -iteration_over_set.py:3:13: PLC0208 Use a sequence type instead of a `set` when iterating over values +iteration_over_set.py:3:13: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values | 1 | # Errors 2 | -3 | for item in {"apples", "lemons", "water"}: # flags in-line set literals - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLC0208 -4 | print(f"I like {item}.") +3 | for item in {1}: + | ^^^ PLC0208 +4 | print(f"I can count to {item}!") | + = help: Convert to `tuple` + +ℹ Fix +1 1 | # Errors +2 2 | +3 |-for item in {1}: + 3 |+for item in (1,): +4 4 | print(f"I can count to {item}!") +5 5 | +6 6 | for item in {"apples", "lemons", "water"}: # flags in-line set literals -iteration_over_set.py:6:28: PLC0208 Use a sequence type instead of a `set` when iterating over values +iteration_over_set.py:6:13: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values | -4 | print(f"I like {item}.") +4 | print(f"I can count to {item}!") 5 | -6 | numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions - | ^^^^^^^^^ PLC0208 -7 | -8 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions +6 | for item in {"apples", "lemons", "water"}: # flags in-line set literals + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLC0208 +7 | print(f"I like {item}.") | + = help: Convert to `tuple` + +ℹ Fix +3 3 | for item in {1}: +4 4 | print(f"I can count to {item}!") +5 5 | +6 |-for item in {"apples", "lemons", "water"}: # flags in-line set literals + 6 |+for item in ("apples", "lemons", "water"): # flags in-line set literals +7 7 | print(f"I like {item}.") +8 8 | +9 9 | for item in {1,}: + +iteration_over_set.py:9:13: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values + | + 7 | print(f"I like {item}.") + 8 | + 9 | for item in {1,}: + | ^^^^ PLC0208 +10 | print(f"I can count to {item}!") + | + = help: Convert to `tuple` + +ℹ Fix +6 6 | for item in {"apples", "lemons", "water"}: # flags in-line set literals +7 7 | print(f"I like {item}.") +8 8 | +9 |-for item in {1,}: + 9 |+for item in (1,): +10 10 | print(f"I can count to {item}!") +11 11 | +12 12 | for item in { -iteration_over_set.py:8:27: PLC0208 Use a sequence type instead of a `set` when iterating over values +iteration_over_set.py:12:13: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values | - 6 | numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions - 7 | - 8 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions +10 | print(f"I can count to {item}!") +11 | +12 | for item in { + | _____________^ +13 | | "apples", "lemons", "water" +14 | | }: # flags in-line set literals + | |_^ PLC0208 +15 | print(f"I like {item}.") + | + = help: Convert to `tuple` + +ℹ Fix +9 9 | for item in {1,}: +10 10 | print(f"I can count to {item}!") +11 11 | +12 |-for item in { + 12 |+for item in ( +13 13 | "apples", "lemons", "water" +14 |-}: # flags in-line set literals + 14 |+): # flags in-line set literals +15 15 | print(f"I like {item}.") +16 16 | +17 17 | numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions + +iteration_over_set.py:17:28: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values + | +15 | print(f"I like {item}.") +16 | +17 | numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions + | ^^^^^^^^^ PLC0208 +18 | +19 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions + | + = help: Convert to `tuple` + +ℹ Fix +14 14 | }: # flags in-line set literals +15 15 | print(f"I like {item}.") +16 16 | +17 |-numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions + 17 |+numbers_list = [i for i in (1, 2, 3)] # flags sets in list comprehensions +18 18 | +19 19 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions +20 20 | + +iteration_over_set.py:19:27: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values + | +17 | numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions +18 | +19 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions | ^^^^^^^^^ PLC0208 - 9 | -10 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions +20 | +21 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions | + = help: Convert to `tuple` + +ℹ Fix +16 16 | +17 17 | numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions +18 18 | +19 |-numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions + 19 |+numbers_set = {i for i in (1, 2, 3)} # flags sets in set comprehensions +20 20 | +21 21 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions +22 22 | -iteration_over_set.py:10:36: PLC0208 Use a sequence type instead of a `set` when iterating over values +iteration_over_set.py:21:36: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values | - 8 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions - 9 | -10 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions +19 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions +20 | +21 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions | ^^^^^^^^^ PLC0208 -11 | -12 | numbers_gen = (i for i in {1, 2, 3}) # flags sets in generator expressions +22 | +23 | numbers_gen = (i for i in {1, 2, 3}) # flags sets in generator expressions | + = help: Convert to `tuple` -iteration_over_set.py:12:27: PLC0208 Use a sequence type instead of a `set` when iterating over values +ℹ Fix +18 18 | +19 19 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions +20 20 | +21 |-numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions + 21 |+numbers_dict = {str(i): i for i in (1, 2, 3)} # flags sets in dict comprehensions +22 22 | +23 23 | numbers_gen = (i for i in {1, 2, 3}) # flags sets in generator expressions +24 24 | + +iteration_over_set.py:23:27: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values | -10 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions -11 | -12 | numbers_gen = (i for i in {1, 2, 3}) # flags sets in generator expressions +21 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions +22 | +23 | numbers_gen = (i for i in {1, 2, 3}) # flags sets in generator expressions | ^^^^^^^^^ PLC0208 -13 | -14 | # Non-errors +24 | +25 | # Non-errors | + = help: Convert to `tuple` + +ℹ Fix +20 20 | +21 21 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions +22 22 | +23 |-numbers_gen = (i for i in {1, 2, 3}) # flags sets in generator expressions + 23 |+numbers_gen = (i for i in (1, 2, 3)) # flags sets in generator expressions +24 24 | +25 25 | # Non-errors +26 26 | diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLC2401_non_ascii_name.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLC2401_non_ascii_name.py.snap new file mode 100644 index 0000000000000..1ef5432f9575f --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLC2401_non_ascii_name.py.snap @@ -0,0 +1,79 @@ +--- +source: crates/ruff_linter/src/rules/pylint/mod.rs +--- +non_ascii_name.py:1:1: PLC2401 Variable name `ápple_count` contains a non-ASCII character, consider renaming it + | +1 | ápple_count: int = 1 # C2401 + | ^^^^^^^^^^^ PLC2401 +2 | ápple_count += 2 # C2401 +3 | ápple_count = 3 # C2401 + | + +non_ascii_name.py:2:1: PLC2401 Variable name `ápple_count` contains a non-ASCII character, consider renaming it + | +1 | ápple_count: int = 1 # C2401 +2 | ápple_count += 2 # C2401 + | ^^^^^^^^^^^ PLC2401 +3 | ápple_count = 3 # C2401 + | + +non_ascii_name.py:3:1: PLC2401 Variable name `ápple_count` contains a non-ASCII character, consider renaming it + | +1 | ápple_count: int = 1 # C2401 +2 | ápple_count += 2 # C2401 +3 | ápple_count = 3 # C2401 + | ^^^^^^^^^^^ PLC2401 +4 | +5 | (ápple_count for ápple_count in y) + | + +non_ascii_name.py:5:18: PLC2401 Variable name `ápple_count` contains a non-ASCII character, consider renaming it + | +3 | ápple_count = 3 # C2401 +4 | +5 | (ápple_count for ápple_count in y) + | ^^^^^^^^^^^ PLC2401 + | + +non_ascii_name.py:8:10: PLC2401 Argument name `ápple_count` contains a non-ASCII character, consider renaming it + | + 8 | def func(ápple_count): + | ^^^^^^^^^^^ PLC2401 + 9 | global ápple_count +10 | nonlocal ápple_count + | + +non_ascii_name.py:9:12: PLC2401 Global name `ápple_count` contains a non-ASCII character, consider renaming it + | + 8 | def func(ápple_count): + 9 | global ápple_count + | ^^^^^^^^^^^ PLC2401 +10 | nonlocal ápple_count + | + +non_ascii_name.py:13:5: PLC2401 Function name `ápple_count` contains a non-ASCII character, consider renaming it + | +13 | def ápple_count(): + | ^^^^^^^^^^^ PLC2401 +14 | pass + | + +non_ascii_name.py:18:10: PLC2401 Variable name `ápple_count` contains a non-ASCII character, consider renaming it + | +17 | match ápple_count: +18 | case ápple_count: + | ^^^^^^^^^^^ PLC2401 +19 | pass + | + +non_ascii_name.py:21:1: PLC2401 Annotation name `ápple_count` contains a non-ASCII character, consider renaming it + | +19 | pass +20 | +21 | ápple_count: int + | ^^^^^^^^^^^ PLC2401 +22 | +23 | try: + | + + diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLC2403_non_ascii_module_import.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLC2403_non_ascii_module_import.py.snap new file mode 100644 index 0000000000000..31350f4ba9966 --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLC2403_non_ascii_module_import.py.snap @@ -0,0 +1,38 @@ +--- +source: crates/ruff_linter/src/rules/pylint/mod.rs +--- +non_ascii_module_import.py:1:29: PLC2403 Module alias `łos` contains a non-ASCII character, use an ASCII-only alias + | +1 | from os.path import join as łos # Error + | ^^^ PLC2403 +2 | from os.path import join as los # OK + | + +non_ascii_module_import.py:4:24: PLC2403 Module alias `łos` contains a non-ASCII character, use an ASCII-only alias + | +2 | from os.path import join as los # OK +3 | +4 | import os.path.join as łos # Error + | ^^^ PLC2403 +5 | import os.path.join as los # OK + | + +non_ascii_module_import.py:7:8: PLC2403 Module name `os.path.łos` contains a non-ASCII character, use an ASCII-only alias + | +5 | import os.path.join as los # OK +6 | +7 | import os.path.łos # Error (recommend an ASCII alias) + | ^^^^^^^^^^^ PLC2403 +8 | import os.path.los # OK + | + +non_ascii_module_import.py:10:21: PLC2403 Module name `łos` contains a non-ASCII character, use an ASCII-only alias + | + 8 | import os.path.los # OK + 9 | +10 | from os.path import łos # Error (recommend an ASCII alias) + | ^^^ PLC2403 +11 | from os.path import los # OK + | + + diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE0605_invalid_all_format.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE0605_invalid_all_format.py.snap index 9e96d3cb8f868..1768e87240d17 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE0605_invalid_all_format.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE0605_invalid_all_format.py.snap @@ -106,7 +106,27 @@ invalid_all_format.py:21:1: PLE0605 Invalid format for `__all__`, must be `tuple 21 | __all__ = foo["bar"] # [invalid-all-format] | ^^^^^^^ PLE0605 22 | -23 | __all__ = ["Hello"] +23 | __all__ = (foo := bar) # [invalid-all-format] + | + +invalid_all_format.py:23:1: PLE0605 Invalid format for `__all__`, must be `tuple` or `list` + | +21 | __all__ = foo["bar"] # [invalid-all-format] +22 | +23 | __all__ = (foo := bar) # [invalid-all-format] + | ^^^^^^^ PLE0605 +24 | +25 | __all__ = ["Hello"] + | + +invalid_all_format.py:23:12: PLE0605 Invalid format for `__all__`, must be `tuple` or `list` + | +21 | __all__ = foo["bar"] # [invalid-all-format] +22 | +23 | __all__ = (foo := bar) # [invalid-all-format] + | ^^^ PLE0605 +24 | +25 | __all__ = ["Hello"] | diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE0704_misplaced_bare_raise.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE0704_misplaced_bare_raise.py.snap new file mode 100644 index 0000000000000..ce61e96b9c39e --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE0704_misplaced_bare_raise.py.snap @@ -0,0 +1,90 @@ +--- +source: crates/ruff_linter/src/rules/pylint/mod.rs +--- +misplaced_bare_raise.py:30:5: PLE0704 Bare `raise` statement is not inside an exception handler + | +29 | try: +30 | raise # [misplaced-bare-raise] + | ^^^^^ PLE0704 +31 | except Exception: +32 | pass + | + +misplaced_bare_raise.py:36:9: PLE0704 Bare `raise` statement is not inside an exception handler + | +34 | def f(): +35 | try: +36 | raise # [misplaced-bare-raise] + | ^^^^^ PLE0704 +37 | except Exception: +38 | pass + | + +misplaced_bare_raise.py:41:5: PLE0704 Bare `raise` statement is not inside an exception handler + | +40 | def g(): +41 | raise # [misplaced-bare-raise] + | ^^^^^ PLE0704 +42 | +43 | def h(): + | + +misplaced_bare_raise.py:47:17: PLE0704 Bare `raise` statement is not inside an exception handler + | +45 | if True: +46 | def i(): +47 | raise # [misplaced-bare-raise] + | ^^^^^ PLE0704 +48 | except Exception: +49 | pass + | + +misplaced_bare_raise.py:50:5: PLE0704 Bare `raise` statement is not inside an exception handler + | +48 | except Exception: +49 | pass +50 | raise # [misplaced-bare-raise] + | ^^^^^ PLE0704 +51 | +52 | raise # [misplaced-bare-raise] + | + +misplaced_bare_raise.py:52:1: PLE0704 Bare `raise` statement is not inside an exception handler + | +50 | raise # [misplaced-bare-raise] +51 | +52 | raise # [misplaced-bare-raise] + | ^^^^^ PLE0704 +53 | +54 | try: + | + +misplaced_bare_raise.py:58:9: PLE0704 Bare `raise` statement is not inside an exception handler + | +56 | except: +57 | def i(): +58 | raise # [misplaced-bare-raise] + | ^^^^^ PLE0704 +59 | +60 | try: + | + +misplaced_bare_raise.py:64:9: PLE0704 Bare `raise` statement is not inside an exception handler + | +62 | except: +63 | class C: +64 | raise # [misplaced-bare-raise] + | ^^^^^ PLE0704 +65 | +66 | try: + | + +misplaced_bare_raise.py:71:5: PLE0704 Bare `raise` statement is not inside an exception handler + | +69 | pass +70 | finally: +71 | raise # [misplaced-bare-raise] + | ^^^^^ PLE0704 + | + + diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE1205_logging_too_many_args.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE1205_logging_too_many_args.py.snap index cdbccdbd758fa..f202189a23a82 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE1205_logging_too_many_args.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE1205_logging_too_many_args.py.snap @@ -21,4 +21,24 @@ logging_too_many_args.py:5:1: PLE1205 Too many arguments for `logging` format st 7 | logging.warning("Hello %s", "World!") | +logging_too_many_args.py:29:1: PLE1205 Too many arguments for `logging` format string + | +27 | from logging import info, error, warning +28 | +29 | warning("Hello %s", "World!", "again") # [logging-too-many-args] + | ^^^^^^^ PLE1205 +30 | +31 | warning("Hello %s", "World!", "again", something="else") + | + +logging_too_many_args.py:31:1: PLE1205 Too many arguments for `logging` format string + | +29 | warning("Hello %s", "World!", "again") # [logging-too-many-args] +30 | +31 | warning("Hello %s", "World!", "again", something="else") + | ^^^^^^^ PLE1205 +32 | +33 | warning("Hello %s", "World!") + | + diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE1206_logging_too_few_args.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE1206_logging_too_few_args.py.snap index b46b420741c94..abaec32b88bd9 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE1206_logging_too_few_args.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE1206_logging_too_few_args.py.snap @@ -11,4 +11,14 @@ logging_too_few_args.py:3:1: PLE1206 Not enough arguments for `logging` format s 5 | # do not handle calls with kwargs (like pylint) | +logging_too_few_args.py:33:1: PLE1206 Not enough arguments for `logging` format string + | +31 | from logging import error, info, warning +32 | +33 | warning("Hello %s %s", "World!") # [logging-too-few-args] + | ^^^^^^^ PLE1206 +34 | +35 | # do not handle calls with kwargs (like pylint) + | + diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2510_invalid_characters.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2510_invalid_characters.py.snap index 48a360b3c363e..b472b75871aa3 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2510_invalid_characters.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2510_invalid_characters.py.snap @@ -7,8 +7,7 @@ invalid_characters.py:15:6: PLE2510 [*] Invalid unescaped character backspace, u 14 | #foo = 'hi' 15 | b = '' | PLE2510 -16 | -17 | b_ok = '\\b' +16 | b = f'' | = help: Replace with escape sequence @@ -18,8 +17,50 @@ invalid_characters.py:15:6: PLE2510 [*] Invalid unescaped character backspace, u 14 14 | #foo = 'hi' 15 |-b = '' 15 |+b = '\b' -16 16 | -17 17 | b_ok = '\\b' -18 18 | +16 16 | b = f'' +17 17 | +18 18 | b_ok = '\\b' + +invalid_characters.py:16:7: PLE2510 [*] Invalid unescaped character backspace, use "\b" instead + | +14 | #foo = 'hi' +15 | b = '' +16 | b = f'' + | PLE2510 +17 | +18 | b_ok = '\\b' + | + = help: Replace with escape sequence + +ℹ Fix +13 13 | # (Pylint, "C3002") => Rule::UnnecessaryDirectLambdaCall, +14 14 | #foo = 'hi' +15 15 | b = '' +16 |-b = f'' + 16 |+b = f'\b' +17 17 | +18 18 | b_ok = '\\b' +19 19 | b_ok = f'\\b' + +invalid_characters.py:55:21: PLE2510 [*] Invalid unescaped character backspace, use "\b" instead + | +53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +54 | +55 | nested_fstrings = f'{f'{f''}'}' + | PLE2510 +56 | +57 | # https://github.com/astral-sh/ruff/issues/7455#issuecomment-1741998106 + | + = help: Replace with escape sequence + +ℹ Fix +52 52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +53 53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +54 54 | +55 |-nested_fstrings = f'{f'{f''}'}' + 55 |+nested_fstrings = f'\b{f'{f''}'}' +56 56 | +57 57 | # https://github.com/astral-sh/ruff/issues/7455#issuecomment-1741998106 +58 58 | x = f"""}}ab""" diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2512_invalid_characters.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2512_invalid_characters.py.snap index eaab51876b789..aca79fabc8ff7 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2512_invalid_characters.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2512_invalid_characters.py.snap @@ -1,25 +1,84 @@ --- source: crates/ruff_linter/src/rules/pylint/mod.rs --- -invalid_characters.py:21:12: PLE2512 [*] Invalid unescaped character SUB, use "\x1A" instead +invalid_characters.py:24:12: PLE2512 [*] Invalid unescaped character SUB, use "\x1A" instead | -19 | cr_ok = '\\r' -20 | -21 | sub = 'sub ' +22 | cr_ok = f'\\r' +23 | +24 | sub = 'sub ' | PLE2512 -22 | -23 | sub_ok = '\x1a' +25 | sub = f'sub ' | = help: Replace with escape sequence ℹ Fix -18 18 | -19 19 | cr_ok = '\\r' -20 20 | -21 |-sub = 'sub ' - 21 |+sub = 'sub \x1A' -22 22 | -23 23 | sub_ok = '\x1a' -24 24 | +21 21 | cr_ok = '\\r' +22 22 | cr_ok = f'\\r' +23 23 | +24 |-sub = 'sub ' + 24 |+sub = 'sub \x1A' +25 25 | sub = f'sub ' +26 26 | +27 27 | sub_ok = '\x1a' + +invalid_characters.py:25:13: PLE2512 [*] Invalid unescaped character SUB, use "\x1A" instead + | +24 | sub = 'sub ' +25 | sub = f'sub ' + | PLE2512 +26 | +27 | sub_ok = '\x1a' + | + = help: Replace with escape sequence + +ℹ Fix +22 22 | cr_ok = f'\\r' +23 23 | +24 24 | sub = 'sub ' +25 |-sub = f'sub ' + 25 |+sub = f'sub \x1A' +26 26 | +27 27 | sub_ok = '\x1a' +28 28 | sub_ok = f'\x1a' + +invalid_characters.py:55:25: PLE2512 [*] Invalid unescaped character SUB, use "\x1A" instead + | +53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +54 | +55 | nested_fstrings = f'{f'{f''}'}' + | PLE2512 +56 | +57 | # https://github.com/astral-sh/ruff/issues/7455#issuecomment-1741998106 + | + = help: Replace with escape sequence + +ℹ Fix +52 52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +53 53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +54 54 | +55 |-nested_fstrings = f'{f'{f''}'}' + 55 |+nested_fstrings = f'{f'\x1A{f''}'}' +56 56 | +57 57 | # https://github.com/astral-sh/ruff/issues/7455#issuecomment-1741998106 +58 58 | x = f"""}}ab""" + +invalid_characters.py:58:12: PLE2512 [*] Invalid unescaped character SUB, use "\x1A" instead + | +57 | # https://github.com/astral-sh/ruff/issues/7455#issuecomment-1741998106 +58 | x = f"""}}ab""" + | PLE2512 +59 | # https://github.com/astral-sh/ruff/issues/7455#issuecomment-1741998256 +60 | x = f"""}}ab""" + | + = help: Replace with escape sequence + +ℹ Fix +55 55 | nested_fstrings = f'{f'{f''}'}' +56 56 | +57 57 | # https://github.com/astral-sh/ruff/issues/7455#issuecomment-1741998106 +58 |-x = f"""}}ab""" + 58 |+x = f"""}}a\x1Ab""" +59 59 | # https://github.com/astral-sh/ruff/issues/7455#issuecomment-1741998256 +60 60 | x = f"""}}ab""" diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2513_invalid_characters.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2513_invalid_characters.py.snap index ae13f2baba496..87dd00ef5196c 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2513_invalid_characters.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2513_invalid_characters.py.snap @@ -1,25 +1,81 @@ --- source: crates/ruff_linter/src/rules/pylint/mod.rs --- -invalid_characters.py:25:16: PLE2513 [*] Invalid unescaped character ESC, use "\x1B" instead +invalid_characters.py:30:16: PLE2513 [*] Invalid unescaped character ESC, use "\x1B" instead | -23 | sub_ok = '\x1a' -24 | -25 | esc = 'esc esc ' +28 | sub_ok = f'\x1a' +29 | +30 | esc = 'esc esc ' | PLE2513 -26 | -27 | esc_ok = '\x1b' +31 | esc = f'esc esc ' | = help: Replace with escape sequence ℹ Fix -22 22 | -23 23 | sub_ok = '\x1a' -24 24 | -25 |-esc = 'esc esc ' - 25 |+esc = 'esc esc \x1B' -26 26 | -27 27 | esc_ok = '\x1b' -28 28 | +27 27 | sub_ok = '\x1a' +28 28 | sub_ok = f'\x1a' +29 29 | +30 |-esc = 'esc esc ' + 30 |+esc = 'esc esc \x1B' +31 31 | esc = f'esc esc ' +32 32 | +33 33 | esc_ok = '\x1b' + +invalid_characters.py:31:17: PLE2513 [*] Invalid unescaped character ESC, use "\x1B" instead + | +30 | esc = 'esc esc ' +31 | esc = f'esc esc ' + | PLE2513 +32 | +33 | esc_ok = '\x1b' + | + = help: Replace with escape sequence + +ℹ Fix +28 28 | sub_ok = f'\x1a' +29 29 | +30 30 | esc = 'esc esc ' +31 |-esc = f'esc esc ' + 31 |+esc = f'esc esc \x1B' +32 32 | +33 33 | esc_ok = '\x1b' +34 34 | esc_ok = f'\x1b' + +invalid_characters.py:55:29: PLE2513 [*] Invalid unescaped character ESC, use "\x1B" instead + | +53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +54 | +55 | nested_fstrings = f'{f'{f''}'}' + | PLE2513 +56 | +57 | # https://github.com/astral-sh/ruff/issues/7455#issuecomment-1741998106 + | + = help: Replace with escape sequence + +ℹ Fix +52 52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +53 53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +54 54 | +55 |-nested_fstrings = f'{f'{f''}'}' + 55 |+nested_fstrings = f'{f'{f'\x1B'}'}' +56 56 | +57 57 | # https://github.com/astral-sh/ruff/issues/7455#issuecomment-1741998106 +58 58 | x = f"""}}ab""" + +invalid_characters.py:60:12: PLE2513 [*] Invalid unescaped character ESC, use "\x1B" instead + | +58 | x = f"""}}ab""" +59 | # https://github.com/astral-sh/ruff/issues/7455#issuecomment-1741998256 +60 | x = f"""}}ab""" + | PLE2513 + | + = help: Replace with escape sequence + +ℹ Fix +57 57 | # https://github.com/astral-sh/ruff/issues/7455#issuecomment-1741998106 +58 58 | x = f"""}}ab""" +59 59 | # https://github.com/astral-sh/ruff/issues/7455#issuecomment-1741998256 +60 |-x = f"""}}ab""" + 60 |+x = f"""}}a\x1Bb""" diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2514_invalid_characters.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2514_invalid_characters.py.snap index 49a6a4f5186ddf8fba75a4641300b045aa1ad785..0227171c311f933297bc3fe5571b41ba8fb98962 100644 GIT binary patch literal 799 zcmb`E!AiqG5QaVPQ~dN2P}8(cYTH1M3PKSPJXtC0W-Z$jcH3av zcn}Pe!!G}@-+be`F4K9XgbX1RFQxWW6~~J-$x5j_tpuG@x-Hh`%6rM9uF}k^IFzg3-IDN#m&7sPq7QB!VnhxCD&(2Y4iO#&&L6YfG z@`wSbnSX&AS(Rc6$8nfH+8$5L$t38fZ~GGS$4xxmgrs^29p(;VRfo7^46LHM$^!89?R&dBz3`HQFG77z40P ch6*rS6pW1^j({0&0Cb440uTWW=VIgn0LYRka{vGU diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2515_invalid_characters.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2515_invalid_characters.py.snap index 25210fb48e358..7ef2c89169ac7 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2515_invalid_characters.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE2515_invalid_characters.py.snap @@ -1,73 +1,167 @@ --- source: crates/ruff_linter/src/rules/pylint/mod.rs --- -invalid_characters.py:34:13: PLE2515 [*] Invalid unescaped character zero-width-space, use "\u200B" instead +invalid_characters.py:44:13: PLE2515 [*] Invalid unescaped character zero-width-space, use "\u200B" instead | -32 | nul_ok = '\0' -33 | -34 | zwsp = 'zero​width' +42 | nul_ok = f'\0' +43 | +44 | zwsp = 'zero​width' | PLE2515 -35 | -36 | zwsp_ok = '\u200b' +45 | zwsp = f'zero​width' | = help: Replace with escape sequence ℹ Fix -31 31 | -32 32 | nul_ok = '\0' -33 33 | -34 |-zwsp = 'zero​width' - 34 |+zwsp = 'zero\u200bwidth' -35 35 | -36 36 | zwsp_ok = '\u200b' -37 37 | - -invalid_characters.py:38:36: PLE2515 [*] Invalid unescaped character zero-width-space, use "\u200B" instead - | -36 | zwsp_ok = '\u200b' -37 | -38 | zwsp_after_multibyte_character = "ಫ​" +41 41 | nul_ok = '\0' +42 42 | nul_ok = f'\0' +43 43 | +44 |-zwsp = 'zero​width' + 44 |+zwsp = 'zero\u200bwidth' +45 45 | zwsp = f'zero​width' +46 46 | +47 47 | zwsp_ok = '\u200b' + +invalid_characters.py:45:14: PLE2515 [*] Invalid unescaped character zero-width-space, use "\u200B" instead + | +44 | zwsp = 'zero​width' +45 | zwsp = f'zero​width' + | PLE2515 +46 | +47 | zwsp_ok = '\u200b' + | + = help: Replace with escape sequence + +ℹ Fix +42 42 | nul_ok = f'\0' +43 43 | +44 44 | zwsp = 'zero​width' +45 |-zwsp = f'zero​width' + 45 |+zwsp = f'zero\u200bwidth' +46 46 | +47 47 | zwsp_ok = '\u200b' +48 48 | zwsp_ok = f'\u200b' + +invalid_characters.py:50:36: PLE2515 [*] Invalid unescaped character zero-width-space, use "\u200B" instead + | +48 | zwsp_ok = f'\u200b' +49 | +50 | zwsp_after_multibyte_character = "ಫ​" | PLE2515 -39 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +51 | zwsp_after_multibyte_character = f"ಫ​" +52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" + | + = help: Replace with escape sequence + +ℹ Fix +47 47 | zwsp_ok = '\u200b' +48 48 | zwsp_ok = f'\u200b' +49 49 | +50 |-zwsp_after_multibyte_character = "ಫ​" + 50 |+zwsp_after_multibyte_character = "ಫ\u200b" +51 51 | zwsp_after_multibyte_character = f"ಫ​" +52 52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +53 53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" + +invalid_characters.py:51:37: PLE2515 [*] Invalid unescaped character zero-width-space, use "\u200B" instead + | +50 | zwsp_after_multibyte_character = "ಫ​" +51 | zwsp_after_multibyte_character = f"ಫ​" + | PLE2515 +52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" | = help: Replace with escape sequence ℹ Fix -35 35 | -36 36 | zwsp_ok = '\u200b' -37 37 | -38 |-zwsp_after_multibyte_character = "ಫ​" - 38 |+zwsp_after_multibyte_character = "ಫ\u200b" -39 39 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +48 48 | zwsp_ok = f'\u200b' +49 49 | +50 50 | zwsp_after_multibyte_character = "ಫ​" +51 |-zwsp_after_multibyte_character = f"ಫ​" + 51 |+zwsp_after_multibyte_character = f"ಫ\u200b" +52 52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +53 53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +54 54 | -invalid_characters.py:39:60: PLE2515 [*] Invalid unescaped character zero-width-space, use "\u200B" instead +invalid_characters.py:52:60: PLE2515 [*] Invalid unescaped character zero-width-space, use "\u200B" instead | -38 | zwsp_after_multibyte_character = "ಫ​" -39 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +50 | zwsp_after_multibyte_character = "ಫ​" +51 | zwsp_after_multibyte_character = f"ಫ​" +52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" | PLE2515 +53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" | = help: Replace with escape sequence ℹ Fix -36 36 | zwsp_ok = '\u200b' -37 37 | -38 38 | zwsp_after_multibyte_character = "ಫ​" -39 |-zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" - 39 |+zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ \u200b​" +49 49 | +50 50 | zwsp_after_multibyte_character = "ಫ​" +51 51 | zwsp_after_multibyte_character = f"ಫ​" +52 |-zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" + 52 |+zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ \u200b​" +53 53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +54 54 | +55 55 | nested_fstrings = f'{f'{f''}'}' -invalid_characters.py:39:61: PLE2515 [*] Invalid unescaped character zero-width-space, use "\u200B" instead +invalid_characters.py:52:61: PLE2515 [*] Invalid unescaped character zero-width-space, use "\u200B" instead | -38 | zwsp_after_multibyte_character = "ಫ​" -39 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +50 | zwsp_after_multibyte_character = "ಫ​" +51 | zwsp_after_multibyte_character = f"ಫ​" +52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" | PLE2515 +53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" + | + = help: Replace with escape sequence + +ℹ Fix +49 49 | +50 50 | zwsp_after_multibyte_character = "ಫ​" +51 51 | zwsp_after_multibyte_character = f"ಫ​" +52 |-zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" + 52 |+zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​\u200b" +53 53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +54 54 | +55 55 | nested_fstrings = f'{f'{f''}'}' + +invalid_characters.py:53:61: PLE2515 [*] Invalid unescaped character zero-width-space, use "\u200B" instead + | +51 | zwsp_after_multibyte_character = f"ಫ​" +52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" + | PLE2515 +54 | +55 | nested_fstrings = f'{f'{f''}'}' + | + = help: Replace with escape sequence + +ℹ Fix +50 50 | zwsp_after_multibyte_character = "ಫ​" +51 51 | zwsp_after_multibyte_character = f"ಫ​" +52 52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +53 |-zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" + 53 |+zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ \u200b​" +54 54 | +55 55 | nested_fstrings = f'{f'{f''}'}' +56 56 | + +invalid_characters.py:53:62: PLE2515 [*] Invalid unescaped character zero-width-space, use "\u200B" instead + | +51 | zwsp_after_multibyte_character = f"ಫ​" +52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" + | PLE2515 +54 | +55 | nested_fstrings = f'{f'{f''}'}' | = help: Replace with escape sequence ℹ Fix -36 36 | zwsp_ok = '\u200b' -37 37 | -38 38 | zwsp_after_multibyte_character = "ಫ​" -39 |-zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" - 39 |+zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​\u200b" +50 50 | zwsp_after_multibyte_character = "ಫ​" +51 51 | zwsp_after_multibyte_character = f"ಫ​" +52 52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" +53 |-zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​​" + 53 |+zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ ​\u200b" +54 54 | +55 55 | nested_fstrings = f'{f'{f''}'}' +56 56 | diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR0913_too_many_arguments.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR0913_too_many_arguments.py.snap index 6677bf7e05d58..0dd41c50267ba 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR0913_too_many_arguments.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR0913_too_many_arguments.py.snap @@ -1,35 +1,35 @@ --- source: crates/ruff_linter/src/rules/pylint/mod.rs --- -too_many_arguments.py:1:5: PLR0913 Too many arguments to function call (8 > 5) +too_many_arguments.py:1:5: PLR0913 Too many arguments in function definition (8 > 5) | 1 | def f(x, y, z, t, u, v, w, r): # Too many arguments (8/5) | ^ PLR0913 2 | pass | -too_many_arguments.py:17:5: PLR0913 Too many arguments to function call (6 > 5) +too_many_arguments.py:17:5: PLR0913 Too many arguments in function definition (6 > 5) | 17 | def f(x, y, z, u=1, v=1, r=1): # Too many arguments (6/5) | ^ PLR0913 18 | pass | -too_many_arguments.py:25:5: PLR0913 Too many arguments to function call (6 > 5) +too_many_arguments.py:25:5: PLR0913 Too many arguments in function definition (6 > 5) | 25 | def f(x, y, z, /, u, v, w): # Too many arguments (6/5) | ^ PLR0913 26 | pass | -too_many_arguments.py:29:5: PLR0913 Too many arguments to function call (6 > 5) +too_many_arguments.py:29:5: PLR0913 Too many arguments in function definition (6 > 5) | 29 | def f(x, y, z, *, u, v, w): # Too many arguments (6/5) | ^ PLR0913 30 | pass | -too_many_arguments.py:33:5: PLR0913 Too many arguments to function call (9 > 5) +too_many_arguments.py:33:5: PLR0913 Too many arguments in function definition (9 > 5) | 33 | def f(x, y, z, a, b, c, *, u, v, w): # Too many arguments (9/5) | ^ PLR0913 diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1706_and_or_ternary.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1706_and_or_ternary.py.snap new file mode 100644 index 0000000000000..044d05d789a1a --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1706_and_or_ternary.py.snap @@ -0,0 +1,229 @@ +--- +source: crates/ruff_linter/src/rules/pylint/mod.rs +--- +and_or_ternary.py:46:1: PLR1706 [*] Consider using if-else expression (`'a' if 1 < 2 else 'b'`) + | +44 | # Errors +45 | +46 | 1<2 and 'a' or 'b' + | ^^^^^^^^^^^^^^^^^^ PLR1706 +47 | +48 | (lambda x: x+1) and 'a' or 'b' + | + = help: Convert to if-else expression + +ℹ Suggested fix +43 43 | +44 44 | # Errors +45 45 | +46 |-1<2 and 'a' or 'b' + 46 |+'a' if 1 < 2 else 'b' +47 47 | +48 48 | (lambda x: x+1) and 'a' or 'b' +49 49 | + +and_or_ternary.py:48:1: PLR1706 [*] Consider using if-else expression (`'a' if (lambda x: x + 1) else 'b'`) + | +46 | 1<2 and 'a' or 'b' +47 | +48 | (lambda x: x+1) and 'a' or 'b' + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1706 +49 | +50 | 'a' and (lambda x: x+1) or 'orange' + | + = help: Convert to if-else expression + +ℹ Suggested fix +45 45 | +46 46 | 1<2 and 'a' or 'b' +47 47 | +48 |-(lambda x: x+1) and 'a' or 'b' + 48 |+'a' if (lambda x: x + 1) else 'b' +49 49 | +50 50 | 'a' and (lambda x: x+1) or 'orange' +51 51 | + +and_or_ternary.py:50:1: PLR1706 [*] Consider using if-else expression (`(lambda x: x + 1) if 'a' else 'orange'`) + | +48 | (lambda x: x+1) and 'a' or 'b' +49 | +50 | 'a' and (lambda x: x+1) or 'orange' + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1706 +51 | +52 | val = '#0000FF' + | + = help: Convert to if-else expression + +ℹ Suggested fix +47 47 | +48 48 | (lambda x: x+1) and 'a' or 'b' +49 49 | +50 |-'a' and (lambda x: x+1) or 'orange' + 50 |+(lambda x: x + 1) if 'a' else 'orange' +51 51 | +52 52 | val = '#0000FF' +53 53 | (len(val) == 7 and val[0] == "#") or val in {'green'} + +and_or_ternary.py:53:1: PLR1706 [*] Consider using if-else expression + | +52 | val = '#0000FF' +53 | (len(val) == 7 and val[0] == "#") or val in {'green'} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1706 +54 | +55 | marker = 'marker' + | + = help: Convert to if-else expression + +ℹ Suggested fix +50 50 | 'a' and (lambda x: x+1) or 'orange' +51 51 | +52 52 | val = '#0000FF' +53 |-(len(val) == 7 and val[0] == "#") or val in {'green'} + 53 |+val[0] == '#' if len(val) == 7 else val in {'green'} +54 54 | +55 55 | marker = 'marker' +56 56 | isinstance(marker, dict) and 'field' in marker or marker in {} + +and_or_ternary.py:56:1: PLR1706 [*] Consider using if-else expression + | +55 | marker = 'marker' +56 | isinstance(marker, dict) and 'field' in marker or marker in {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1706 +57 | +58 | def has_oranges(oranges, apples=None) -> bool: + | + = help: Convert to if-else expression + +ℹ Suggested fix +53 53 | (len(val) == 7 and val[0] == "#") or val in {'green'} +54 54 | +55 55 | marker = 'marker' +56 |-isinstance(marker, dict) and 'field' in marker or marker in {} + 56 |+'field' in marker if isinstance(marker, dict) else marker in {} +57 57 | +58 58 | def has_oranges(oranges, apples=None) -> bool: +59 59 | return apples and False or oranges + +and_or_ternary.py:59:12: PLR1706 [*] Consider using if-else expression (`False if apples else oranges`) + | +58 | def has_oranges(oranges, apples=None) -> bool: +59 | return apples and False or oranges + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1706 +60 | +61 | [x for x in l if a and b or c] + | + = help: Convert to if-else expression + +ℹ Suggested fix +56 56 | isinstance(marker, dict) and 'field' in marker or marker in {} +57 57 | +58 58 | def has_oranges(oranges, apples=None) -> bool: +59 |- return apples and False or oranges + 59 |+ return False if apples else oranges +60 60 | +61 61 | [x for x in l if a and b or c] +62 62 | + +and_or_ternary.py:61:18: PLR1706 [*] Consider using if-else expression (`(b if a else c)`) + | +59 | return apples and False or oranges +60 | +61 | [x for x in l if a and b or c] + | ^^^^^^^^^^^^ PLR1706 +62 | +63 | {x: y for x in l if a and b or c} + | + = help: Convert to if-else expression + +ℹ Suggested fix +58 58 | def has_oranges(oranges, apples=None) -> bool: +59 59 | return apples and False or oranges +60 60 | +61 |-[x for x in l if a and b or c] + 61 |+[x for x in l if (b if a else c)] +62 62 | +63 63 | {x: y for x in l if a and b or c} +64 64 | + +and_or_ternary.py:63:21: PLR1706 [*] Consider using if-else expression (`(b if a else c)`) + | +61 | [x for x in l if a and b or c] +62 | +63 | {x: y for x in l if a and b or c} + | ^^^^^^^^^^^^ PLR1706 +64 | +65 | {x for x in l if a and b or c} + | + = help: Convert to if-else expression + +ℹ Suggested fix +60 60 | +61 61 | [x for x in l if a and b or c] +62 62 | +63 |-{x: y for x in l if a and b or c} + 63 |+{x: y for x in l if (b if a else c)} +64 64 | +65 65 | {x for x in l if a and b or c} +66 66 | + +and_or_ternary.py:65:18: PLR1706 [*] Consider using if-else expression (`(b if a else c)`) + | +63 | {x: y for x in l if a and b or c} +64 | +65 | {x for x in l if a and b or c} + | ^^^^^^^^^^^^ PLR1706 +66 | +67 | new_list = [ + | + = help: Convert to if-else expression + +ℹ Suggested fix +62 62 | +63 63 | {x: y for x in l if a and b or c} +64 64 | +65 |-{x for x in l if a and b or c} + 65 |+{x for x in l if (b if a else c)} +66 66 | +67 67 | new_list = [ +68 68 | x + +and_or_ternary.py:70:8: PLR1706 [*] Consider using if-else expression (`(b if a else c)`) + | +68 | x +69 | for sublist in all_lists +70 | if a and b or c + | ^^^^^^^^^^^^ PLR1706 +71 | for x in sublist +72 | if (isinstance(operator, list) and x in operator) or x != operator + | + = help: Convert to if-else expression + +ℹ Suggested fix +67 67 | new_list = [ +68 68 | x +69 69 | for sublist in all_lists +70 |- if a and b or c + 70 |+ if (b if a else c) +71 71 | for x in sublist +72 72 | if (isinstance(operator, list) and x in operator) or x != operator +73 73 | ] + +and_or_ternary.py:72:8: PLR1706 [*] Consider using if-else expression + | +70 | if a and b or c +71 | for x in sublist +72 | if (isinstance(operator, list) and x in operator) or x != operator + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR1706 +73 | ] + | + = help: Convert to if-else expression + +ℹ Suggested fix +69 69 | for sublist in all_lists +70 70 | if a and b or c +71 71 | for x in sublist +72 |- if (isinstance(operator, list) and x in operator) or x != operator + 72 |+ if (x in operator if isinstance(operator, list) else x != operator) +73 73 | ] + + diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1714_repeated_equality_comparison.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1714_repeated_equality_comparison.py.snap index 5114033edf124..6d7914a092b50 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1714_repeated_equality_comparison.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1714_repeated_equality_comparison.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pylint/mod.rs --- -repeated_equality_comparison.py:2:1: PLR1714 Consider merging multiple comparisons: `foo in ("a", "b")`. Use a `set` if the elements are hashable. +repeated_equality_comparison.py:2:1: PLR1714 [*] Consider merging multiple comparisons: `foo in ("a", "b")`. Use a `set` if the elements are hashable. | 1 | # Errors. 2 | foo == "a" or foo == "b" @@ -9,8 +9,17 @@ repeated_equality_comparison.py:2:1: PLR1714 Consider merging multiple compariso 3 | 4 | foo != "a" and foo != "b" | + = help: Merge multiple comparisons -repeated_equality_comparison.py:4:1: PLR1714 Consider merging multiple comparisons: `foo not in ("a", "b")`. Use a `set` if the elements are hashable. +ℹ Suggested fix +1 1 | # Errors. +2 |-foo == "a" or foo == "b" + 2 |+foo in ("a", "b") +3 3 | +4 4 | foo != "a" and foo != "b" +5 5 | + +repeated_equality_comparison.py:4:1: PLR1714 [*] Consider merging multiple comparisons: `foo not in ("a", "b")`. Use a `set` if the elements are hashable. | 2 | foo == "a" or foo == "b" 3 | @@ -19,8 +28,19 @@ repeated_equality_comparison.py:4:1: PLR1714 Consider merging multiple compariso 5 | 6 | foo == "a" or foo == "b" or foo == "c" | + = help: Merge multiple comparisons + +ℹ Suggested fix +1 1 | # Errors. +2 2 | foo == "a" or foo == "b" +3 3 | +4 |-foo != "a" and foo != "b" + 4 |+foo not in ("a", "b") +5 5 | +6 6 | foo == "a" or foo == "b" or foo == "c" +7 7 | -repeated_equality_comparison.py:6:1: PLR1714 Consider merging multiple comparisons: `foo in ("a", "b", "c")`. Use a `set` if the elements are hashable. +repeated_equality_comparison.py:6:1: PLR1714 [*] Consider merging multiple comparisons: `foo in ("a", "b", "c")`. Use a `set` if the elements are hashable. | 4 | foo != "a" and foo != "b" 5 | @@ -29,8 +49,19 @@ repeated_equality_comparison.py:6:1: PLR1714 Consider merging multiple compariso 7 | 8 | foo != "a" and foo != "b" and foo != "c" | + = help: Merge multiple comparisons -repeated_equality_comparison.py:8:1: PLR1714 Consider merging multiple comparisons: `foo not in ("a", "b", "c")`. Use a `set` if the elements are hashable. +ℹ Suggested fix +3 3 | +4 4 | foo != "a" and foo != "b" +5 5 | +6 |-foo == "a" or foo == "b" or foo == "c" + 6 |+foo in ("a", "b", "c") +7 7 | +8 8 | foo != "a" and foo != "b" and foo != "c" +9 9 | + +repeated_equality_comparison.py:8:1: PLR1714 [*] Consider merging multiple comparisons: `foo not in ("a", "b", "c")`. Use a `set` if the elements are hashable. | 6 | foo == "a" or foo == "b" or foo == "c" 7 | @@ -39,8 +70,19 @@ repeated_equality_comparison.py:8:1: PLR1714 Consider merging multiple compariso 9 | 10 | foo == a or foo == "b" or foo == 3 # Mixed types. | + = help: Merge multiple comparisons + +ℹ Suggested fix +5 5 | +6 6 | foo == "a" or foo == "b" or foo == "c" +7 7 | +8 |-foo != "a" and foo != "b" and foo != "c" + 8 |+foo not in ("a", "b", "c") +9 9 | +10 10 | foo == a or foo == "b" or foo == 3 # Mixed types. +11 11 | -repeated_equality_comparison.py:10:1: PLR1714 Consider merging multiple comparisons: `foo in (a, "b", 3)`. Use a `set` if the elements are hashable. +repeated_equality_comparison.py:10:1: PLR1714 [*] Consider merging multiple comparisons: `foo in (a, "b", 3)`. Use a `set` if the elements are hashable. | 8 | foo != "a" and foo != "b" and foo != "c" 9 | @@ -49,8 +91,19 @@ repeated_equality_comparison.py:10:1: PLR1714 Consider merging multiple comparis 11 | 12 | "a" == foo or "b" == foo or "c" == foo | + = help: Merge multiple comparisons -repeated_equality_comparison.py:12:1: PLR1714 Consider merging multiple comparisons: `foo in ("a", "b", "c")`. Use a `set` if the elements are hashable. +ℹ Suggested fix +7 7 | +8 8 | foo != "a" and foo != "b" and foo != "c" +9 9 | +10 |-foo == a or foo == "b" or foo == 3 # Mixed types. + 10 |+foo in (a, "b", 3) # Mixed types. +11 11 | +12 12 | "a" == foo or "b" == foo or "c" == foo +13 13 | + +repeated_equality_comparison.py:12:1: PLR1714 [*] Consider merging multiple comparisons: `foo in ("a", "b", "c")`. Use a `set` if the elements are hashable. | 10 | foo == a or foo == "b" or foo == 3 # Mixed types. 11 | @@ -59,8 +112,19 @@ repeated_equality_comparison.py:12:1: PLR1714 Consider merging multiple comparis 13 | 14 | "a" != foo and "b" != foo and "c" != foo | + = help: Merge multiple comparisons + +ℹ Suggested fix +9 9 | +10 10 | foo == a or foo == "b" or foo == 3 # Mixed types. +11 11 | +12 |-"a" == foo or "b" == foo or "c" == foo + 12 |+foo in ("a", "b", "c") +13 13 | +14 14 | "a" != foo and "b" != foo and "c" != foo +15 15 | -repeated_equality_comparison.py:14:1: PLR1714 Consider merging multiple comparisons: `foo not in ("a", "b", "c")`. Use a `set` if the elements are hashable. +repeated_equality_comparison.py:14:1: PLR1714 [*] Consider merging multiple comparisons: `foo not in ("a", "b", "c")`. Use a `set` if the elements are hashable. | 12 | "a" == foo or "b" == foo or "c" == foo 13 | @@ -69,8 +133,19 @@ repeated_equality_comparison.py:14:1: PLR1714 Consider merging multiple comparis 15 | 16 | "a" == foo or foo == "b" or "c" == foo | + = help: Merge multiple comparisons + +ℹ Suggested fix +11 11 | +12 12 | "a" == foo or "b" == foo or "c" == foo +13 13 | +14 |-"a" != foo and "b" != foo and "c" != foo + 14 |+foo not in ("a", "b", "c") +15 15 | +16 16 | "a" == foo or foo == "b" or "c" == foo +17 17 | -repeated_equality_comparison.py:16:1: PLR1714 Consider merging multiple comparisons: `foo in ("a", "b", "c")`. Use a `set` if the elements are hashable. +repeated_equality_comparison.py:16:1: PLR1714 [*] Consider merging multiple comparisons: `foo in ("a", "b", "c")`. Use a `set` if the elements are hashable. | 14 | "a" != foo and "b" != foo and "c" != foo 15 | @@ -79,8 +154,19 @@ repeated_equality_comparison.py:16:1: PLR1714 Consider merging multiple comparis 17 | 18 | foo == bar or baz == foo or qux == foo | + = help: Merge multiple comparisons -repeated_equality_comparison.py:18:1: PLR1714 Consider merging multiple comparisons: `foo in (bar, baz, qux)`. Use a `set` if the elements are hashable. +ℹ Suggested fix +13 13 | +14 14 | "a" != foo and "b" != foo and "c" != foo +15 15 | +16 |-"a" == foo or foo == "b" or "c" == foo + 16 |+foo in ("a", "b", "c") +17 17 | +18 18 | foo == bar or baz == foo or qux == foo +19 19 | + +repeated_equality_comparison.py:18:1: PLR1714 [*] Consider merging multiple comparisons: `foo in (bar, baz, qux)`. Use a `set` if the elements are hashable. | 16 | "a" == foo or foo == "b" or "c" == foo 17 | @@ -89,8 +175,19 @@ repeated_equality_comparison.py:18:1: PLR1714 Consider merging multiple comparis 19 | 20 | foo == "a" or "b" == foo or foo == "c" | + = help: Merge multiple comparisons + +ℹ Suggested fix +15 15 | +16 16 | "a" == foo or foo == "b" or "c" == foo +17 17 | +18 |-foo == bar or baz == foo or qux == foo + 18 |+foo in (bar, baz, qux) +19 19 | +20 20 | foo == "a" or "b" == foo or foo == "c" +21 21 | -repeated_equality_comparison.py:20:1: PLR1714 Consider merging multiple comparisons: `foo in ("a", "b", "c")`. Use a `set` if the elements are hashable. +repeated_equality_comparison.py:20:1: PLR1714 [*] Consider merging multiple comparisons: `foo in ("a", "b", "c")`. Use a `set` if the elements are hashable. | 18 | foo == bar or baz == foo or qux == foo 19 | @@ -99,8 +196,19 @@ repeated_equality_comparison.py:20:1: PLR1714 Consider merging multiple comparis 21 | 22 | foo != "a" and "b" != foo and foo != "c" | + = help: Merge multiple comparisons -repeated_equality_comparison.py:22:1: PLR1714 Consider merging multiple comparisons: `foo not in ("a", "b", "c")`. Use a `set` if the elements are hashable. +ℹ Suggested fix +17 17 | +18 18 | foo == bar or baz == foo or qux == foo +19 19 | +20 |-foo == "a" or "b" == foo or foo == "c" + 20 |+foo in ("a", "b", "c") +21 21 | +22 22 | foo != "a" and "b" != foo and foo != "c" +23 23 | + +repeated_equality_comparison.py:22:1: PLR1714 [*] Consider merging multiple comparisons: `foo not in ("a", "b", "c")`. Use a `set` if the elements are hashable. | 20 | foo == "a" or "b" == foo or foo == "c" 21 | @@ -109,8 +217,19 @@ repeated_equality_comparison.py:22:1: PLR1714 Consider merging multiple comparis 23 | 24 | foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets | + = help: Merge multiple comparisons + +ℹ Suggested fix +19 19 | +20 20 | foo == "a" or "b" == foo or foo == "c" +21 21 | +22 |-foo != "a" and "b" != foo and foo != "c" + 22 |+foo not in ("a", "b", "c") +23 23 | +24 24 | foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets +25 25 | -repeated_equality_comparison.py:24:1: PLR1714 Consider merging multiple comparisons: `foo in ("a", "b")`. Use a `set` if the elements are hashable. +repeated_equality_comparison.py:24:1: PLR1714 [*] Consider merging multiple comparisons: `foo in ("a", "b")`. Use a `set` if the elements are hashable. | 22 | foo != "a" and "b" != foo and foo != "c" 23 | @@ -119,8 +238,19 @@ repeated_equality_comparison.py:24:1: PLR1714 Consider merging multiple comparis 25 | 26 | foo.bar == "a" or foo.bar == "b" # Attributes. | + = help: Merge multiple comparisons -repeated_equality_comparison.py:24:1: PLR1714 Consider merging multiple comparisons: `bar in ("c", "d")`. Use a `set` if the elements are hashable. +ℹ Suggested fix +21 21 | +22 22 | foo != "a" and "b" != foo and foo != "c" +23 23 | +24 |-foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets + 24 |+foo in ("a", "b") # Multiple targets +25 25 | +26 26 | foo.bar == "a" or foo.bar == "b" # Attributes. +27 27 | + +repeated_equality_comparison.py:24:1: PLR1714 [*] Consider merging multiple comparisons: `bar in ("c", "d")`. Use a `set` if the elements are hashable. | 22 | foo != "a" and "b" != foo and foo != "c" 23 | @@ -129,8 +259,19 @@ repeated_equality_comparison.py:24:1: PLR1714 Consider merging multiple comparis 25 | 26 | foo.bar == "a" or foo.bar == "b" # Attributes. | + = help: Merge multiple comparisons + +ℹ Suggested fix +21 21 | +22 22 | foo != "a" and "b" != foo and foo != "c" +23 23 | +24 |-foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets + 24 |+bar in ("c", "d") # Multiple targets +25 25 | +26 26 | foo.bar == "a" or foo.bar == "b" # Attributes. +27 27 | -repeated_equality_comparison.py:26:1: PLR1714 Consider merging multiple comparisons: `foo.bar in ("a", "b")`. Use a `set` if the elements are hashable. +repeated_equality_comparison.py:26:1: PLR1714 [*] Consider merging multiple comparisons: `foo.bar in ("a", "b")`. Use a `set` if the elements are hashable. | 24 | foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets 25 | @@ -139,5 +280,16 @@ repeated_equality_comparison.py:26:1: PLR1714 Consider merging multiple comparis 27 | 28 | # OK | + = help: Merge multiple comparisons + +ℹ Suggested fix +23 23 | +24 24 | foo == "a" or foo == "b" or "c" == bar or "d" == bar # Multiple targets +25 25 | +26 |-foo.bar == "a" or foo.bar == "b" # Attributes. + 26 |+foo.bar in ("a", "b") # Attributes. +27 27 | +28 28 | # OK +29 29 | foo == "a" and foo == "b" and foo == "c" # `and` mixed with `==`. diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR6201_literal_membership.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR6201_literal_membership.py.snap new file mode 100644 index 0000000000000..94506940a6be6 --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR6201_literal_membership.py.snap @@ -0,0 +1,69 @@ +--- +source: crates/ruff_linter/src/rules/pylint/mod.rs +--- +literal_membership.py:2:6: PLR6201 [*] Use a `set` literal when testing for membership + | +1 | # Errors +2 | 1 in [1, 2, 3] + | ^^^^^^^^^ PLR6201 +3 | 1 in (1, 2, 3) +4 | 1 in ( + | + = help: Convert to `set` + +ℹ Suggested fix +1 1 | # Errors +2 |-1 in [1, 2, 3] + 2 |+1 in {1, 2, 3} +3 3 | 1 in (1, 2, 3) +4 4 | 1 in ( +5 5 | 1, 2, 3 + +literal_membership.py:3:6: PLR6201 [*] Use a `set` literal when testing for membership + | +1 | # Errors +2 | 1 in [1, 2, 3] +3 | 1 in (1, 2, 3) + | ^^^^^^^^^ PLR6201 +4 | 1 in ( +5 | 1, 2, 3 + | + = help: Convert to `set` + +ℹ Suggested fix +1 1 | # Errors +2 2 | 1 in [1, 2, 3] +3 |-1 in (1, 2, 3) + 3 |+1 in {1, 2, 3} +4 4 | 1 in ( +5 5 | 1, 2, 3 +6 6 | ) + +literal_membership.py:4:6: PLR6201 [*] Use a `set` literal when testing for membership + | +2 | 1 in [1, 2, 3] +3 | 1 in (1, 2, 3) +4 | 1 in ( + | ______^ +5 | | 1, 2, 3 +6 | | ) + | |_^ PLR6201 +7 | +8 | # OK + | + = help: Convert to `set` + +ℹ Suggested fix +1 1 | # Errors +2 2 | 1 in [1, 2, 3] +3 3 | 1 in (1, 2, 3) +4 |-1 in ( + 4 |+1 in { +5 5 | 1, 2, 3 +6 |-) + 6 |+} +7 7 | +8 8 | # OK +9 9 | fruits = ["cherry", "grapes"] + + diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR6301_no_self_use.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR6301_no_self_use.py.snap index 405976321a990..85675b6d9fa87 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR6301_no_self_use.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR6301_no_self_use.py.snap @@ -1,39 +1,30 @@ --- source: crates/ruff_linter/src/rules/pylint/mod.rs --- -no_self_use.py:5:28: PLR6301 Method `developer_greeting` could be a function or static method +no_self_use.py:7:28: PLR6301 Method `developer_greeting` could be a function, class method, or static method | -4 | class Person: -5 | def developer_greeting(self, name): # [no-self-use] +6 | class Person: +7 | def developer_greeting(self, name): # [no-self-use] | ^^^^ PLR6301 -6 | print(f"Greetings {name}!") +8 | print(f"Greetings {name}!") | -no_self_use.py:8:20: PLR6301 Method `greeting_1` could be a function or static method - | -6 | print(f"Greetings {name}!") -7 | -8 | def greeting_1(self): # [no-self-use] - | ^^^^ PLR6301 -9 | print("Hello!") - | - -no_self_use.py:11:20: PLR6301 Method `greeting_2` could be a function or static method +no_self_use.py:10:20: PLR6301 Method `greeting_1` could be a function, class method, or static method | - 9 | print("Hello!") -10 | -11 | def greeting_2(self): # [no-self-use] + 8 | print(f"Greetings {name}!") + 9 | +10 | def greeting_1(self): # [no-self-use] | ^^^^ PLR6301 -12 | print("Hi!") +11 | print("Hello!") | -no_self_use.py:55:25: PLR6301 Method `abstract_method` could be a function or static method +no_self_use.py:13:20: PLR6301 Method `greeting_2` could be a function, class method, or static method | -53 | class Sub(Base): -54 | @override -55 | def abstract_method(self): - | ^^^^ PLR6301 -56 | print("concrete method") +11 | print("Hello!") +12 | +13 | def greeting_2(self): # [no-self-use] + | ^^^^ PLR6301 +14 | print("Hi!") | diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW0108_unnecessary_lambda.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW0108_unnecessary_lambda.py.snap new file mode 100644 index 0000000000000..c4acb1801dfeb --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW0108_unnecessary_lambda.py.snap @@ -0,0 +1,76 @@ +--- +source: crates/ruff_linter/src/rules/pylint/mod.rs +--- +unnecessary_lambda.py:1:5: PLW0108 Lambda may be unnecessary; consider inlining inner function + | +1 | _ = lambda: print() # [unnecessary-lambda] + | ^^^^^^^^^^^^^^^ PLW0108 +2 | _ = lambda x, y: min(x, y) # [unnecessary-lambda] + | + +unnecessary_lambda.py:2:5: PLW0108 Lambda may be unnecessary; consider inlining inner function + | +1 | _ = lambda: print() # [unnecessary-lambda] +2 | _ = lambda x, y: min(x, y) # [unnecessary-lambda] + | ^^^^^^^^^^^^^^^^^^^^^^ PLW0108 +3 | +4 | _ = lambda *args: f(*args) # [unnecessary-lambda] + | + +unnecessary_lambda.py:4:5: PLW0108 Lambda may be unnecessary; consider inlining inner function + | +2 | _ = lambda x, y: min(x, y) # [unnecessary-lambda] +3 | +4 | _ = lambda *args: f(*args) # [unnecessary-lambda] + | ^^^^^^^^^^^^^^^^^^^^^^ PLW0108 +5 | _ = lambda **kwargs: f(**kwargs) # [unnecessary-lambda] +6 | _ = lambda *args, **kwargs: f(*args, **kwargs) # [unnecessary-lambda] + | + +unnecessary_lambda.py:5:5: PLW0108 Lambda may be unnecessary; consider inlining inner function + | +4 | _ = lambda *args: f(*args) # [unnecessary-lambda] +5 | _ = lambda **kwargs: f(**kwargs) # [unnecessary-lambda] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLW0108 +6 | _ = lambda *args, **kwargs: f(*args, **kwargs) # [unnecessary-lambda] +7 | _ = lambda x, y, z, *args, **kwargs: f(x, y, z, *args, **kwargs) # [unnecessary-lambda] + | + +unnecessary_lambda.py:6:5: PLW0108 Lambda may be unnecessary; consider inlining inner function + | +4 | _ = lambda *args: f(*args) # [unnecessary-lambda] +5 | _ = lambda **kwargs: f(**kwargs) # [unnecessary-lambda] +6 | _ = lambda *args, **kwargs: f(*args, **kwargs) # [unnecessary-lambda] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLW0108 +7 | _ = lambda x, y, z, *args, **kwargs: f(x, y, z, *args, **kwargs) # [unnecessary-lambda] + | + +unnecessary_lambda.py:7:5: PLW0108 Lambda may be unnecessary; consider inlining inner function + | +5 | _ = lambda **kwargs: f(**kwargs) # [unnecessary-lambda] +6 | _ = lambda *args, **kwargs: f(*args, **kwargs) # [unnecessary-lambda] +7 | _ = lambda x, y, z, *args, **kwargs: f(x, y, z, *args, **kwargs) # [unnecessary-lambda] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLW0108 +8 | +9 | _ = lambda x: f(lambda x: x)(x) # [unnecessary-lambda] + | + +unnecessary_lambda.py:9:5: PLW0108 Lambda may be unnecessary; consider inlining inner function + | + 7 | _ = lambda x, y, z, *args, **kwargs: f(x, y, z, *args, **kwargs) # [unnecessary-lambda] + 8 | + 9 | _ = lambda x: f(lambda x: x)(x) # [unnecessary-lambda] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLW0108 +10 | _ = lambda x, y: f(lambda x, y: x + y)(x, y) # [unnecessary-lambda] + | + +unnecessary_lambda.py:10:5: PLW0108 Lambda may be unnecessary; consider inlining inner function + | + 9 | _ = lambda x: f(lambda x: x)(x) # [unnecessary-lambda] +10 | _ = lambda x, y: f(lambda x, y: x + y)(x, y) # [unnecessary-lambda] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLW0108 +11 | +12 | # default value in lambda parameters + | + + diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW0604_global_at_module_level.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW0604_global_at_module_level.py.snap new file mode 100644 index 0000000000000..75c9b9db2aa9a --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW0604_global_at_module_level.py.snap @@ -0,0 +1,21 @@ +--- +source: crates/ruff_linter/src/rules/pylint/mod.rs +--- +global_at_module_level.py:1:1: PLW0604 `global` at module level is redundant + | +1 | global price # W0604 + | ^^^^^^^^^^^^ PLW0604 +2 | +3 | price = 25 + | + +global_at_module_level.py:6:5: PLW0604 `global` at module level is redundant + | +5 | if True: +6 | global X # W0604 + | ^^^^^^^^ PLW0604 +7 | +8 | def no_error(): + | + + diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW1514_unspecified_encoding.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW1514_unspecified_encoding.py.snap new file mode 100644 index 0000000000000..d10f3d3b633fd --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW1514_unspecified_encoding.py.snap @@ -0,0 +1,72 @@ +--- +source: crates/ruff_linter/src/rules/pylint/mod.rs +--- +unspecified_encoding.py:8:1: PLW1514 `open` in text mode without explicit `encoding` argument + | + 7 | # Errors. + 8 | open("test.txt") + | ^^^^ PLW1514 + 9 | io.TextIOWrapper(io.FileIO("test.txt")) +10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) + | + +unspecified_encoding.py:9:1: PLW1514 `io.TextIOWrapper` without explicit `encoding` argument + | + 7 | # Errors. + 8 | open("test.txt") + 9 | io.TextIOWrapper(io.FileIO("test.txt")) + | ^^^^^^^^^^^^^^^^ PLW1514 +10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) +11 | tempfile.NamedTemporaryFile("w") + | + +unspecified_encoding.py:10:1: PLW1514 `io.TextIOWrapper` without explicit `encoding` argument + | + 8 | open("test.txt") + 9 | io.TextIOWrapper(io.FileIO("test.txt")) +10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) + | ^^^^^^^^^^^^^^^^^^ PLW1514 +11 | tempfile.NamedTemporaryFile("w") +12 | tempfile.TemporaryFile("w") + | + +unspecified_encoding.py:11:1: PLW1514 `tempfile.NamedTemporaryFile` in text mode without explicit `encoding` argument + | + 9 | io.TextIOWrapper(io.FileIO("test.txt")) +10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) +11 | tempfile.NamedTemporaryFile("w") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLW1514 +12 | tempfile.TemporaryFile("w") +13 | codecs.open("test.txt") + | + +unspecified_encoding.py:12:1: PLW1514 `tempfile.TemporaryFile` in text mode without explicit `encoding` argument + | +10 | hugo.TextIOWrapper(hugo.FileIO("test.txt")) +11 | tempfile.NamedTemporaryFile("w") +12 | tempfile.TemporaryFile("w") + | ^^^^^^^^^^^^^^^^^^^^^^ PLW1514 +13 | codecs.open("test.txt") +14 | tempfile.SpooledTemporaryFile(0, "w") + | + +unspecified_encoding.py:13:1: PLW1514 `codecs.open` in text mode without explicit `encoding` argument + | +11 | tempfile.NamedTemporaryFile("w") +12 | tempfile.TemporaryFile("w") +13 | codecs.open("test.txt") + | ^^^^^^^^^^^ PLW1514 +14 | tempfile.SpooledTemporaryFile(0, "w") + | + +unspecified_encoding.py:14:1: PLW1514 `tempfile.SpooledTemporaryFile` in text mode without explicit `encoding` argument + | +12 | tempfile.TemporaryFile("w") +13 | codecs.open("test.txt") +14 | tempfile.SpooledTemporaryFile(0, "w") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLW1514 +15 | +16 | # Non-errors. + | + + diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_args.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_args.snap index 48f493fdbb6a5..440f2dafeb402 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_args.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_args.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pylint/mod.rs --- -too_many_arguments_params.py:3:5: PLR0913 Too many arguments to function call (6 > 4) +too_many_arguments_params.py:3:5: PLR0913 Too many arguments in function definition (6 > 4) | 1 | # Too many args (6/4) for max_args=4 2 | # OK for dummy_variable_rgx ~ "skip_.*" @@ -10,7 +10,7 @@ too_many_arguments_params.py:3:5: PLR0913 Too many arguments to function call (6 4 | pass | -too_many_arguments_params.py:9:5: PLR0913 Too many arguments to function call (6 > 4) +too_many_arguments_params.py:9:5: PLR0913 Too many arguments in function definition (6 > 4) | 7 | # Too many args (6/4) for max_args=4 8 | # Too many args (6/5) for dummy_variable_rgx ~ "skip_.*" diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_args_with_dummy_variables.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_args_with_dummy_variables.snap index 12a9a7fdcb563..865d4d0abd262 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_args_with_dummy_variables.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_args_with_dummy_variables.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pylint/mod.rs --- -too_many_arguments_params.py:9:5: PLR0913 Too many arguments to function call (6 > 5) +too_many_arguments_params.py:9:5: PLR0913 Too many arguments in function definition (6 > 5) | 7 | # Too many args (6/4) for max_args=4 8 | # Too many args (6/5) for dummy_variable_rgx ~ "skip_.*" diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_boolean_expressions.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_boolean_expressions.snap new file mode 100644 index 0000000000000..141ee9e4c5c2b --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_boolean_expressions.snap @@ -0,0 +1,214 @@ +--- +source: crates/ruff_linter/src/rules/pylint/mod.rs +--- +too_many_boolean_expressions.py:11:6: PLR0916 Too many Boolean expressions (6 > 5) + | + 9 | elif (a and b) and c and d and e: +10 | ... +11 | elif (a and b) and c and d and e and f: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +12 | ... +13 | elif (a and b) and c and d and e and f and g: + | + +too_many_boolean_expressions.py:13:6: PLR0916 Too many Boolean expressions (7 > 5) + | +11 | elif (a and b) and c and d and e and f: +12 | ... +13 | elif (a and b) and c and d and e and f and g: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +14 | ... +15 | elif (a and b) and c and d and e and f and g and h: + | + +too_many_boolean_expressions.py:15:6: PLR0916 Too many Boolean expressions (8 > 5) + | +13 | elif (a and b) and c and d and e and f and g: +14 | ... +15 | elif (a and b) and c and d and e and f and g and h: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +16 | ... +17 | elif (a and b) and c and d and e and f and g and h and i: + | + +too_many_boolean_expressions.py:17:6: PLR0916 Too many Boolean expressions (9 > 5) + | +15 | elif (a and b) and c and d and e and f and g and h: +16 | ... +17 | elif (a and b) and c and d and e and f and g and h and i: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +18 | ... +19 | elif (a and b) and c and d and e and f and g and h and i and j: + | + +too_many_boolean_expressions.py:19:6: PLR0916 Too many Boolean expressions (10 > 5) + | +17 | elif (a and b) and c and d and e and f and g and h and i: +18 | ... +19 | elif (a and b) and c and d and e and f and g and h and i and j: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +20 | ... +21 | elif (a and b) and c and d and e and f and g and h and i and j and k: + | + +too_many_boolean_expressions.py:21:6: PLR0916 Too many Boolean expressions (11 > 5) + | +19 | elif (a and b) and c and d and e and f and g and h and i and j: +20 | ... +21 | elif (a and b) and c and d and e and f and g and h and i and j and k: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +22 | ... +23 | elif (a and b) and c and d and e and f and g and h and i and j and k and l: + | + +too_many_boolean_expressions.py:23:6: PLR0916 Too many Boolean expressions (12 > 5) + | +21 | elif (a and b) and c and d and e and f and g and h and i and j and k: +22 | ... +23 | elif (a and b) and c and d and e and f and g and h and i and j and k and l: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +24 | ... +25 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m: + | + +too_many_boolean_expressions.py:25:6: PLR0916 Too many Boolean expressions (13 > 5) + | +23 | elif (a and b) and c and d and e and f and g and h and i and j and k and l: +24 | ... +25 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +26 | ... +27 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n: + | + +too_many_boolean_expressions.py:27:6: PLR0916 Too many Boolean expressions (14 > 5) + | +25 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m: +26 | ... +27 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +28 | ... +29 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o: + | + +too_many_boolean_expressions.py:29:6: PLR0916 Too many Boolean expressions (15 > 5) + | +27 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n: +28 | ... +29 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +30 | ... +31 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p: + | + +too_many_boolean_expressions.py:31:6: PLR0916 Too many Boolean expressions (16 > 5) + | +29 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o: +30 | ... +31 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +32 | ... +33 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q: + | + +too_many_boolean_expressions.py:33:6: PLR0916 Too many Boolean expressions (17 > 5) + | +31 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p: +32 | ... +33 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +34 | ... +35 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r: + | + +too_many_boolean_expressions.py:35:6: PLR0916 Too many Boolean expressions (18 > 5) + | +33 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q: +34 | ... +35 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +36 | ... +37 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s: + | + +too_many_boolean_expressions.py:37:6: PLR0916 Too many Boolean expressions (19 > 5) + | +35 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r: +36 | ... +37 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +38 | ... +39 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t: + | + +too_many_boolean_expressions.py:39:6: PLR0916 Too many Boolean expressions (20 > 5) + | +37 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s: +38 | ... +39 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +40 | ... +41 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u: + | + +too_many_boolean_expressions.py:41:6: PLR0916 Too many Boolean expressions (21 > 5) + | +39 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t: +40 | ... +41 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +42 | ... +43 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v: + | + +too_many_boolean_expressions.py:43:6: PLR0916 Too many Boolean expressions (22 > 5) + | +41 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u: +42 | ... +43 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +44 | ... +45 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w: + | + +too_many_boolean_expressions.py:45:6: PLR0916 Too many Boolean expressions (23 > 5) + | +43 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v: +44 | ... +45 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +46 | ... +47 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x: + | + +too_many_boolean_expressions.py:47:6: PLR0916 Too many Boolean expressions (24 > 5) + | +45 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w: +46 | ... +47 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +48 | ... +49 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x and y: + | + +too_many_boolean_expressions.py:49:6: PLR0916 Too many Boolean expressions (25 > 5) + | +47 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x: +48 | ... +49 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x and y: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +50 | ... +51 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x and y and z: + | + +too_many_boolean_expressions.py:51:6: PLR0916 Too many Boolean expressions (26 > 5) + | +49 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x and y: +50 | ... +51 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x and y and z: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +52 | ... +53 | else: + | + + diff --git a/crates/ruff_linter/src/rules/pyupgrade/fixes.rs b/crates/ruff_linter/src/rules/pyupgrade/fixes.rs index 648d644f3c43e..f890fa55cb1ee 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/fixes.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/fixes.rs @@ -5,8 +5,8 @@ use ruff_python_parser::{lexer, Mode, Tok}; use ruff_source_file::Locator; use ruff_text_size::{TextRange, TextSize}; -use crate::autofix::codemods::CodegenStylist; use crate::cst::matchers::{match_function_def, match_indented_block, match_statement}; +use crate::fix::codemods::CodegenStylist; /// Safely adjust the indentation of the indented block at [`TextRange`]. pub(crate) fn adjust_indentation( diff --git a/crates/ruff_linter/src/rules/pyupgrade/helpers.rs b/crates/ruff_linter/src/rules/pyupgrade/helpers.rs index 5a4294590d848..03f48d877aa0d 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/helpers.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/helpers.rs @@ -1,22 +1,21 @@ use once_cell::sync::Lazy; use regex::{Captures, Regex}; +use std::borrow::Cow; static CURLY_BRACES: Lazy = Lazy::new(|| Regex::new(r"(\\N\{[^}]+})|([{}])").unwrap()); -pub(super) fn curly_escape(text: &str) -> String { +pub(super) fn curly_escape(text: &str) -> Cow<'_, str> { // Match all curly braces. This will include named unicode escapes (like // \N{SNOWMAN}), which we _don't_ want to escape, so take care to preserve them. - CURLY_BRACES - .replace_all(text, |caps: &Captures| { - if let Some(match_) = caps.get(1) { - match_.as_str().to_string() + CURLY_BRACES.replace_all(text, |caps: &Captures| { + if let Some(match_) = caps.get(1) { + match_.as_str().to_string() + } else { + if &caps[2] == "{" { + "{{".to_string() } else { - if &caps[2] == "{" { - "{{".to_string() - } else { - "}}".to_string() - } + "}}".to_string() } - }) - .to_string() + } + }) } diff --git a/crates/ruff_linter/src/rules/pyupgrade/mod.rs b/crates/ruff_linter/src/rules/pyupgrade/mod.rs index bff478382baaa..d9ba5d890a2ba 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/mod.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/mod.rs @@ -28,6 +28,7 @@ mod tests { #[test_case(Rule::FString, Path::new("UP032_0.py"))] #[test_case(Rule::FString, Path::new("UP032_1.py"))] #[test_case(Rule::FString, Path::new("UP032_2.py"))] + #[test_case(Rule::FString, Path::new("UP032_3.py"))] #[test_case(Rule::FormatLiterals, Path::new("UP030_0.py"))] #[test_case(Rule::FormatLiterals, Path::new("UP030_1.py"))] #[test_case(Rule::LRUCacheWithMaxsizeNone, Path::new("UP033_0.py"))] @@ -83,6 +84,7 @@ mod tests { #[test_case(Rule::YieldInForLoop, Path::new("UP028_0.py"))] #[test_case(Rule::YieldInForLoop, Path::new("UP028_1.py"))] #[test_case(Rule::NonPEP695TypeAlias, Path::new("UP040.py"))] + #[test_case(Rule::NonPEP695TypeAlias, Path::new("UP040.pyi"))] fn rules(rule_code: Rule, path: &Path) -> Result<()> { let snapshot = path.to_string_lossy().to_string(); let diagnostics = test_path( diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs index 3bb6b2a28ca2f..27e1ef79c0089 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs @@ -1,6 +1,6 @@ use log::debug; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::is_dunder; use ruff_python_ast::{ @@ -12,7 +12,6 @@ use ruff_python_stdlib::identifiers::is_identifier; use ruff_text_size::{Ranged, TextRange}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for `NamedTuple` declarations that use functional syntax. @@ -50,7 +49,7 @@ pub struct ConvertNamedTupleFunctionalToClass { } impl Violation for ConvertNamedTupleFunctionalToClass { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -58,7 +57,7 @@ impl Violation for ConvertNamedTupleFunctionalToClass { format!("Convert `{name}` from `NamedTuple` functional to class syntax") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let ConvertNamedTupleFunctionalToClass { name } = self; Some(format!("Convert `{name}` to class syntax")) @@ -114,17 +113,15 @@ pub(crate) fn convert_named_tuple_functional_to_class( }, stmt.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // TODO(charlie): Preserve indentation, to remove the first-column requirement. - if checker.locator().is_at_start_of_line(stmt.start()) { - diagnostic.set_fix(convert_to_class( - stmt, - typename, - fields, - base_class, - checker.generator(), - )); - } + // TODO(charlie): Preserve indentation, to remove the first-column requirement. + if checker.locator().is_at_start_of_line(stmt.start()) { + diagnostic.set_fix(convert_to_class( + stmt, + typename, + fields, + base_class, + checker.generator(), + )); } checker.diagnostics.push(diagnostic); } @@ -241,7 +238,7 @@ fn convert_to_class( base_class: &Expr, generator: Generator, ) -> Fix { - Fix::suggested(Edit::range_replacement( + Fix::safe_edit(Edit::range_replacement( generator.stmt(&create_class_def_stmt(typename, body, base_class)), stmt.range(), )) diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs index 1ef6f69e84289..462ea9ceab71a 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::is_dunder; use ruff_python_ast::{ @@ -10,7 +10,6 @@ use ruff_python_stdlib::identifiers::is_identifier; use ruff_text_size::{Ranged, TextRange}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for `TypedDict` declarations that use functional syntax. @@ -47,7 +46,7 @@ pub struct ConvertTypedDictFunctionalToClass { } impl Violation for ConvertTypedDictFunctionalToClass { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -55,7 +54,7 @@ impl Violation for ConvertTypedDictFunctionalToClass { format!("Convert `{name}` from `TypedDict` functional to class syntax") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let ConvertTypedDictFunctionalToClass { name } = self; Some(format!("Convert `{name}` to class syntax")) } @@ -84,18 +83,16 @@ pub(crate) fn convert_typed_dict_functional_to_class( }, stmt.range(), ); - if checker.patch(diagnostic.kind.rule()) { - // TODO(charlie): Preserve indentation, to remove the first-column requirement. - if checker.locator().is_at_start_of_line(stmt.start()) { - diagnostic.set_fix(convert_to_class( - stmt, - class_name, - body, - total_keyword, - base_class, - checker.generator(), - )); - } + // TODO(charlie): Preserve indentation, to remove the first-column requirement. + if checker.locator().is_at_start_of_line(stmt.start()) { + diagnostic.set_fix(convert_to_class( + stmt, + class_name, + body, + total_keyword, + base_class, + checker.generator(), + )); } checker.diagnostics.push(diagnostic); } @@ -275,7 +272,7 @@ fn convert_to_class( base_class: &Expr, generator: Generator, ) -> Fix { - Fix::suggested(Edit::range_replacement( + Fix::safe_edit(Edit::range_replacement( generator.stmt(&create_class_def_stmt( class_name, body, diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/datetime_utc_alias.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/datetime_utc_alias.rs index 7c8314083f8b1..c4325f9651a06 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/datetime_utc_alias.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/datetime_utc_alias.rs @@ -1,12 +1,11 @@ use ruff_python_ast::Expr; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::importer::ImportRequest; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of `datetime.timezone.utc`. @@ -38,14 +37,14 @@ use crate::registry::AsRule; pub struct DatetimeTimezoneUTC; impl Violation for DatetimeTimezoneUTC { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Use `datetime.UTC` alias") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Convert to `datetime.UTC` alias".to_string()) } } @@ -58,17 +57,15 @@ pub(crate) fn datetime_utc_alias(checker: &mut Checker, expr: &Expr) { .is_some_and(|call_path| matches!(call_path.as_slice(), ["datetime", "timezone", "utc"])) { let mut diagnostic = Diagnostic::new(DatetimeTimezoneUTC, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - let (import_edit, binding) = checker.importer().get_or_import_symbol( - &ImportRequest::import_from("datetime", "UTC"), - expr.start(), - checker.semantic(), - )?; - let reference_edit = Edit::range_replacement(binding, expr.range()); - Ok(Fix::suggested_edits(import_edit, [reference_edit])) - }); - } + diagnostic.try_set_fix(|| { + let (import_edit, binding) = checker.importer().get_or_import_symbol( + &ImportRequest::import_from("datetime", "UTC"), + expr.start(), + checker.semantic(), + )?; + let reference_edit = Edit::range_replacement(binding, expr.range()); + Ok(Fix::safe_edits(import_edit, [reference_edit])) + }); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_c_element_tree.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_c_element_tree.rs index f3e35e08d573c..55d338c66a301 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_c_element_tree.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_c_element_tree.rs @@ -1,10 +1,9 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Stmt}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of the `xml.etree.cElementTree` module. @@ -28,13 +27,13 @@ use crate::registry::AsRule; #[violation] pub struct DeprecatedCElementTree; -impl AlwaysAutofixableViolation for DeprecatedCElementTree { +impl AlwaysFixableViolation for DeprecatedCElementTree { #[derive_message_formats] fn message(&self) -> String { format!("`cElementTree` is deprecated, use `ElementTree`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace with `ElementTree`".to_string() } } @@ -44,13 +43,11 @@ where T: Ranged, { let mut diagnostic = Diagnostic::new(DeprecatedCElementTree, node.range()); - if checker.patch(diagnostic.kind.rule()) { - let contents = checker.locator().slice(node); - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - contents.replacen("cElementTree", "ElementTree", 1), - node.range(), - ))); - } + let contents = checker.locator().slice(node); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + contents.replacen("cElementTree", "ElementTree", 1), + node.range(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_import.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_import.rs index 6a2f385215b04..01e7e35f6775a 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_import.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_import.rs @@ -1,7 +1,7 @@ use itertools::Itertools; use ruff_python_ast::{Alias, Stmt}; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::whitespace::indentation; use ruff_python_codegen::Stylist; @@ -9,7 +9,7 @@ use ruff_source_file::Locator; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::Rule; + use crate::rules::pyupgrade::fixes; use crate::settings::types::PythonVersion; @@ -66,7 +66,7 @@ pub struct DeprecatedImport { } impl Violation for DeprecatedImport { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -87,7 +87,7 @@ impl Violation for DeprecatedImport { } } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { if let Deprecation::WithoutRename(WithoutRename { target, .. }) = &self.deprecation { Some(format!("Import from `{target}`")) } else { @@ -100,7 +100,13 @@ impl Violation for DeprecatedImport { fn is_relevant_module(module: &str) -> bool { matches!( module, - "collections" | "pipes" | "mypy_extensions" | "typing_extensions" | "typing" | "typing.re" + "collections" + | "pipes" + | "mypy_extensions" + | "typing_extensions" + | "typing" + | "typing.re" + | "backports.strenum" ) } @@ -320,6 +326,8 @@ const TYPING_EXTENSIONS_TO_TYPING_311: &[&str] = &[ "reveal_type", ]; +const BACKPORTS_STR_ENUM_TO_ENUM_311: &[&str] = &["StrEnum"]; + // Python 3.12+ // Members of `typing_extensions` that were moved to `typing`. @@ -482,6 +490,11 @@ impl<'a> ImportReplacer<'a> { operations.push(operation); } } + "backports.strenum" if self.version >= PythonVersion::Py311 => { + if let Some(operation) = self.try_replace(BACKPORTS_STR_ENUM_TO_ENUM_311, "enum") { + operations.push(operation); + } + } _ => {} } operations @@ -630,13 +643,11 @@ pub(crate) fn deprecated_import( }, stmt.range(), ); - if checker.patch(Rule::DeprecatedImport) { - if let Some(content) = fix { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - content, - stmt.range(), - ))); - } + if let Some(content) = fix { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + content, + stmt.range(), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_mock_import.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_mock_import.rs index 2272d6aabaa99..aed0ff290768a 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_mock_import.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_mock_import.rs @@ -6,8 +6,8 @@ use libcst_native::{ use log::error; use ruff_python_ast::{self as ast, Expr, Stmt}; -use crate::autofix::codemods::CodegenStylist; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use crate::fix::codemods::CodegenStylist; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::call_path::collect_call_path; use ruff_python_ast::whitespace::indentation; @@ -17,7 +17,6 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::cst::matchers::{match_import, match_import_from, match_statement}; -use crate::registry::{AsRule, Rule}; #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub(crate) enum MockReference { @@ -52,13 +51,13 @@ pub struct DeprecatedMockImport { reference_type: MockReference, } -impl AlwaysAutofixableViolation for DeprecatedMockImport { +impl AlwaysFixableViolation for DeprecatedMockImport { #[derive_message_formats] fn message(&self) -> String { format!("`mock` is deprecated, use `unittest.mock`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let DeprecatedMockImport { reference_type } = self; match reference_type { MockReference::Import => "Import from `unittest.mock` instead".to_string(), @@ -261,12 +260,10 @@ pub(crate) fn deprecated_mock_attribute(checker: &mut Checker, expr: &Expr) { }, value.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - "mock".to_string(), - value.range(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "mock".to_string(), + value.range(), + ))); checker.diagnostics.push(diagnostic); } } @@ -282,17 +279,13 @@ pub(crate) fn deprecated_mock_import(checker: &mut Checker, stmt: &Stmt) { .any(|name| &name.name == "mock" || &name.name == "mock.mock") { // Generate the fix, if needed, which is shared between all `mock` imports. - let content = if checker.patch(Rule::DeprecatedMockImport) { - if let Some(indent) = indentation(checker.locator(), stmt) { - match format_import(stmt, indent, checker.locator(), checker.stylist()) { - Ok(content) => Some(content), - Err(e) => { - error!("Failed to rewrite `mock` import: {e}"); - None - } + let content = if let Some(indent) = indentation(checker.locator(), stmt) { + match format_import(stmt, indent, checker.locator(), checker.stylist()) { + Ok(content) => Some(content), + Err(e) => { + error!("Failed to rewrite `mock` import: {e}"); + None } - } else { - None } } else { None @@ -308,7 +301,7 @@ pub(crate) fn deprecated_mock_import(checker: &mut Checker, stmt: &Stmt) { name.range(), ); if let Some(content) = content.as_ref() { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( content.clone(), stmt.range(), ))); @@ -334,14 +327,12 @@ pub(crate) fn deprecated_mock_import(checker: &mut Checker, stmt: &Stmt) { }, stmt.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if let Some(indent) = indentation(checker.locator(), stmt) { - diagnostic.try_set_fix(|| { - format_import_from(stmt, indent, checker.locator(), checker.stylist()) - .map(|content| Edit::range_replacement(content, stmt.range())) - .map(Fix::suggested) - }); - } + if let Some(indent) = indentation(checker.locator(), stmt) { + diagnostic.try_set_fix(|| { + format_import_from(stmt, indent, checker.locator(), checker.stylist()) + .map(|content| Edit::range_replacement(content, stmt.range())) + .map(Fix::safe_edit) + }); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_unittest_alias.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_unittest_alias.rs index 3f64f64395b5b..58250d43a2b15 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_unittest_alias.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/deprecated_unittest_alias.rs @@ -2,12 +2,11 @@ use once_cell::sync::Lazy; use ruff_python_ast::{self as ast, Expr}; use rustc_hash::FxHashMap; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of deprecated methods from the `unittest` module. @@ -45,14 +44,14 @@ pub struct DeprecatedUnittestAlias { target: String, } -impl AlwaysAutofixableViolation for DeprecatedUnittestAlias { +impl AlwaysFixableViolation for DeprecatedUnittestAlias { #[derive_message_formats] fn message(&self) -> String { let DeprecatedUnittestAlias { alias, target } = self; format!("`{alias}` is deprecated, use `{target}`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let DeprecatedUnittestAlias { alias, target } = self; format!("Replace `{target}` with `{alias}`") } @@ -99,11 +98,9 @@ pub(crate) fn deprecated_unittest_alias(checker: &mut Checker, expr: &Expr) { }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - format!("self.{target}"), - expr.range(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + format!("self.{target}"), + expr.range(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/extraneous_parentheses.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/extraneous_parentheses.rs index 7e82eaf2b297d..621412d20cabc 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/extraneous_parentheses.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/extraneous_parentheses.rs @@ -2,13 +2,10 @@ use ruff_python_parser::lexer::LexResult; use ruff_python_parser::Tok; use ruff_text_size::{Ranged, TextRange}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_source_file::Locator; -use crate::registry::Rule; -use crate::settings::LinterSettings; - /// ## What it does /// Checks for extraneous parentheses. /// @@ -28,13 +25,13 @@ use crate::settings::LinterSettings; #[violation] pub struct ExtraneousParentheses; -impl AlwaysAutofixableViolation for ExtraneousParentheses { +impl AlwaysFixableViolation for ExtraneousParentheses { #[derive_message_formats] fn message(&self) -> String { format!("Avoid extraneous parentheses") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove extraneous parentheses".to_string() } } @@ -137,7 +134,6 @@ pub(crate) fn extraneous_parentheses( diagnostics: &mut Vec, tokens: &[LexResult], locator: &Locator, - settings: &LinterSettings, ) { let mut i = 0; while i < tokens.len() { @@ -154,15 +150,12 @@ pub(crate) fn extraneous_parentheses( ExtraneousParentheses, TextRange::new(start_range.start(), end_range.end()), ); - if settings.rules.should_fix(Rule::ExtraneousParentheses) { - let contents = - locator.slice(TextRange::new(start_range.start(), end_range.end())); - diagnostic.set_fix(Fix::automatic(Edit::replacement( - contents[1..contents.len() - 1].to_string(), - start_range.start(), - end_range.end(), - ))); - } + let contents = locator.slice(TextRange::new(start_range.start(), end_range.end())); + diagnostic.set_fix(Fix::safe_edit(Edit::replacement( + contents[1..contents.len() - 1].to_string(), + start_range.start(), + end_range.end(), + ))); diagnostics.push(diagnostic); } else { i += 1; diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/f_strings.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/f_strings.rs index 7241591956f84..5fc0ba15a6e8c 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/f_strings.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/f_strings.rs @@ -3,7 +3,7 @@ use std::borrow::Cow; use anyhow::{Context, Result}; use rustc_hash::FxHashMap; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::str::{leading_quote, trailing_quote}; use ruff_python_ast::{self as ast, Constant, Expr, Keyword}; @@ -11,13 +11,12 @@ use ruff_python_literal::format::{ FieldName, FieldNamePart, FieldType, FormatPart, FormatString, FromTemplate, }; use ruff_python_parser::{lexer, Mode, Tok}; - use ruff_source_file::Locator; use ruff_text_size::{Ranged, TextRange}; use crate::checkers::ast::Checker; -use crate::line_width::LineLength; -use crate::registry::AsRule; +use crate::fix::edits::fits_or_shrinks; + use crate::rules::pyflakes::format::FormatSummary; use crate::rules::pyupgrade::helpers::curly_escape; @@ -44,14 +43,14 @@ use crate::rules::pyupgrade::helpers::curly_escape; pub struct FString; impl Violation for FString { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Use f-string instead of `format` call") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Convert to f-string".to_string()) } } @@ -306,7 +305,6 @@ pub(crate) fn f_strings( call: &ast::ExprCall, summary: &FormatSummary, template: &Expr, - line_length: LineLength, ) { if summary.has_nested_parts { return; @@ -329,6 +327,7 @@ pub(crate) fn f_strings( let Some(mut summary) = FormatSummaryValues::try_from_call(call, checker.locator()) else { return; }; + let mut patches: Vec<(TextRange, String)> = vec![]; let mut lex = lexer::lex_starts_at( checker.locator().slice(call.func.range()), @@ -384,22 +383,6 @@ pub(crate) fn f_strings( } contents.push_str(checker.locator().slice(TextRange::new(prev_end, end))); - // Avoid refactors that exceed the line length limit. - let col_offset = template.start() - checker.locator().line_start(template.start()); - if contents.lines().enumerate().any(|(idx, line)| { - // If `template` is a multiline string, `col_offset` should only be applied to the first - // line: - // ``` - // a = """{} -> offset = col_offset (= 4) - // {} -> offset = 0 - // """.format(0, 1) -> offset = 0 - // ``` - let offset = if idx == 0 { col_offset.to_usize() } else { 0 }; - offset + line.chars().count() > line_length.value() as usize - }) { - return; - } - // If necessary, add a space between any leading keyword (`return`, `yield`, `assert`, etc.) // and the string. For example, `return"foo"` is valid, but `returnf"foo"` is not. let existing = checker.locator().slice(TextRange::up_to(call.start())); @@ -411,21 +394,50 @@ pub(crate) fn f_strings( contents.insert(0, ' '); } + // Avoid refactors that exceed the line length limit. + if !fits_or_shrinks( + &contents, + template.into(), + checker.locator(), + checker.settings.pycodestyle.max_line_length, + checker.settings.tab_size, + ) { + return; + } + + // Finally, avoid refactors that would introduce a runtime error. + // For example, Django's `gettext` supports `format`-style arguments, but not f-strings. + // See: https://docs.djangoproject.com/en/4.2/topics/i18n/translation + if checker.semantic().current_expressions().any(|expr| { + expr.as_call_expr().is_some_and(|call| { + checker + .semantic() + .resolve_call_path(call.func.as_ref()) + .map_or(false, |call_path| { + matches!( + call_path.as_slice(), + ["django", "utils", "translation", "gettext" | "gettext_lazy"] + ) + }) + }) + }) { + return; + } + let mut diagnostic = Diagnostic::new(FString, call.range()); - // Avoid autofix if there are comments within the call: + // Avoid fix if there are comments within the call: // ``` // "{}".format( // 0, # 0 // ) // ``` - if checker.patch(diagnostic.kind.rule()) - && !checker - .indexer() - .comment_ranges() - .intersects(call.arguments.range()) + if !checker + .indexer() + .comment_ranges() + .intersects(call.arguments.range()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( contents, call.range(), ))); diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/format_literals.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/format_literals.rs index cf689fef3cf96..ab6753f0c8ad3 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/format_literals.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/format_literals.rs @@ -3,19 +3,19 @@ use libcst_native::{Arg, Expression}; use once_cell::sync::Lazy; use regex::Regex; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Expr}; use ruff_python_codegen::Stylist; use ruff_source_file::Locator; use ruff_text_size::Ranged; -use crate::autofix::codemods::CodegenStylist; use crate::checkers::ast::Checker; use crate::cst::matchers::{ match_attribute, match_call_mut, match_expression, transform_expression_text, }; -use crate::registry::AsRule; +use crate::fix::codemods::CodegenStylist; + use crate::rules::pyflakes::format::FormatSummary; /// ## What it does @@ -46,14 +46,14 @@ use crate::rules::pyflakes::format::FormatSummary; pub struct FormatLiterals; impl Violation for FormatLiterals { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Use implicit references for positional format fields") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Remove explicit positional indices".to_string()) } } @@ -113,12 +113,10 @@ pub(crate) fn format_literals( }; let mut diagnostic = Diagnostic::new(FormatLiterals, call.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - generate_call(call, arguments, checker.locator(), checker.stylist()) - .map(|suggestion| Fix::suggested(Edit::range_replacement(suggestion, call.range()))) - }); - } + diagnostic.try_set_fix(|| { + generate_call(call, arguments, checker.locator(), checker.stylist()) + .map(|suggestion| Fix::unsafe_edit(Edit::range_replacement(suggestion, call.range()))) + }); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs index accf01c3fc463..837a7bafdfdc1 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs @@ -1,13 +1,12 @@ use ruff_python_ast::{self as ast, Arguments, Decorator, Expr, Keyword}; use ruff_text_size::{Ranged, TextRange}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::is_const_none; use crate::checkers::ast::Checker; use crate::importer::ImportRequest; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of `functools.lru_cache` that set `maxsize=None`. @@ -45,13 +44,13 @@ use crate::registry::AsRule; #[violation] pub struct LRUCacheWithMaxsizeNone; -impl AlwaysAutofixableViolation for LRUCacheWithMaxsizeNone { +impl AlwaysFixableViolation for LRUCacheWithMaxsizeNone { #[derive_message_formats] fn message(&self) -> String { format!("Use `@functools.cache` instead of `@functools.lru_cache(maxsize=None)`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Rewrite with `@functools.cache".to_string() } } @@ -91,18 +90,16 @@ pub(crate) fn lru_cache_with_maxsize_none(checker: &mut Checker, decorator_list: LRUCacheWithMaxsizeNone, TextRange::new(func.end(), decorator.end()), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - let (import_edit, binding) = checker.importer().get_or_import_symbol( - &ImportRequest::import("functools", "cache"), - decorator.start(), - checker.semantic(), - )?; - let reference_edit = - Edit::range_replacement(binding, decorator.expression.range()); - Ok(Fix::automatic_edits(import_edit, [reference_edit])) - }); - } + diagnostic.try_set_fix(|| { + let (import_edit, binding) = checker.importer().get_or_import_symbol( + &ImportRequest::import("functools", "cache"), + decorator.start(), + checker.semantic(), + )?; + let reference_edit = + Edit::range_replacement(binding, decorator.expression.range()); + Ok(Fix::safe_edits(import_edit, [reference_edit])) + }); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/lru_cache_without_parameters.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/lru_cache_without_parameters.rs index 7553ca937a0e3..00c53bfc61303 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/lru_cache_without_parameters.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/lru_cache_without_parameters.rs @@ -1,10 +1,9 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Decorator, Expr}; use ruff_text_size::{Ranged, TextRange}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for unnecessary parentheses on `functools.lru_cache` decorators. @@ -42,13 +41,13 @@ use crate::registry::AsRule; #[violation] pub struct LRUCacheWithoutParameters; -impl AlwaysAutofixableViolation for LRUCacheWithoutParameters { +impl AlwaysFixableViolation for LRUCacheWithoutParameters { #[derive_message_formats] fn message(&self) -> String { format!("Unnecessary parentheses to `functools.lru_cache`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove unnecessary parentheses".to_string() } } @@ -77,9 +76,7 @@ pub(crate) fn lru_cache_without_parameters(checker: &mut Checker, decorator_list LRUCacheWithoutParameters, TextRange::new(func.end(), decorator.end()), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::range_deletion(arguments.range()))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(arguments.range()))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/native_literals.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/native_literals.rs index 18b9670acb7be..7f672851442aa 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/native_literals.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/native_literals.rs @@ -1,15 +1,12 @@ use std::fmt; use std::str::FromStr; -use num_bigint::BigInt; - -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Constant, Expr}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; #[derive(Debug, PartialEq, Eq, Copy, Clone)] enum LiteralType { @@ -47,7 +44,7 @@ impl From for Constant { value: Vec::new(), implicit_concatenated: false, }), - LiteralType::Int => Constant::Int(BigInt::from(0)), + LiteralType::Int => Constant::Int(0.into()), LiteralType::Float => Constant::Float(0.0), LiteralType::Bool => Constant::Bool(false), } @@ -109,21 +106,21 @@ pub struct NativeLiterals { literal_type: LiteralType, } -impl AlwaysAutofixableViolation for NativeLiterals { +impl AlwaysFixableViolation for NativeLiterals { #[derive_message_formats] fn message(&self) -> String { let NativeLiterals { literal_type } = self; format!("Unnecessary `{literal_type}` call (rewrite as a literal)") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let NativeLiterals { literal_type } = self; match literal_type { - LiteralType::Str => "Replace with empty string".to_string(), - LiteralType::Bytes => "Replace with empty bytes".to_string(), - LiteralType::Int => "Replace with 0".to_string(), - LiteralType::Float => "Replace with 0.0".to_string(), - LiteralType::Bool => "Replace with `False`".to_string(), + LiteralType::Str => "Replace with string literal".to_string(), + LiteralType::Bytes => "Replace with bytes literal".to_string(), + LiteralType::Int => "Replace with integer literal".to_string(), + LiteralType::Float => "Replace with float literal".to_string(), + LiteralType::Bool => "Replace with boolean literal".to_string(), } } } @@ -184,14 +181,12 @@ pub(crate) fn native_literals( return; } - if checker.patch(diagnostic.kind.rule()) { - let constant = Constant::from(literal_type); - let content = checker.generator().constant(&constant); - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - content, - call.range(), - ))); - } + let constant = Constant::from(literal_type); + let content = checker.generator().constant(&constant); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + content, + call.range(), + ))); checker.diagnostics.push(diagnostic); } Some(arg) => { @@ -224,12 +219,10 @@ pub(crate) fn native_literals( }; let mut diagnostic = Diagnostic::new(NativeLiterals { literal_type }, call.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - content, - call.range(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + content, + call.range(), + ))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/open_alias.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/open_alias.rs index 7b93725354b7c..1809b4cea46ed 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/open_alias.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/open_alias.rs @@ -1,11 +1,10 @@ use ruff_python_ast::Expr; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of `io.open`. @@ -34,14 +33,14 @@ use crate::registry::AsRule; pub struct OpenAlias; impl Violation for OpenAlias { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Use builtin `open`") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Replace with builtin `open`".to_string()) } } @@ -54,13 +53,11 @@ pub(crate) fn open_alias(checker: &mut Checker, expr: &Expr, func: &Expr) { .is_some_and(|call_path| matches!(call_path.as_slice(), ["io", "open"])) { let mut diagnostic = Diagnostic::new(OpenAlias, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - if checker.semantic().is_builtin("open") { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - "open".to_string(), - func.range(), - ))); - } + if checker.semantic().is_builtin("open") { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "open".to_string(), + func.range(), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/os_error_alias.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/os_error_alias.rs index b8295556195a2..8477e775b7649 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/os_error_alias.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/os_error_alias.rs @@ -1,14 +1,13 @@ use ruff_python_ast::{self as ast, ExceptHandler, Expr, ExprContext}; use ruff_text_size::{Ranged, TextRange}; -use crate::autofix::edits::pad; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use crate::fix::edits::pad; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::call_path::compose_call_path; use ruff_python_semantic::SemanticModel; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of exceptions that alias `OSError`. @@ -40,13 +39,13 @@ pub struct OSErrorAlias { name: Option, } -impl AlwaysAutofixableViolation for OSErrorAlias { +impl AlwaysFixableViolation for OSErrorAlias { #[derive_message_formats] fn message(&self) -> String { format!("Replace aliased errors with `OSError`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let OSErrorAlias { name } = self; match name { None => "Replace with builtin `OSError`".to_string(), @@ -81,13 +80,11 @@ fn atom_diagnostic(checker: &mut Checker, target: &Expr) { }, target.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if checker.semantic().is_builtin("OSError") { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - "OSError".to_string(), - target.range(), - ))); - } + if checker.semantic().is_builtin("OSError") { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "OSError".to_string(), + target.range(), + ))); } checker.diagnostics.push(diagnostic); } @@ -95,51 +92,49 @@ fn atom_diagnostic(checker: &mut Checker, target: &Expr) { /// Create a [`Diagnostic`] for a tuple of expressions. fn tuple_diagnostic(checker: &mut Checker, tuple: &ast::ExprTuple, aliases: &[&Expr]) { let mut diagnostic = Diagnostic::new(OSErrorAlias { name: None }, tuple.range()); - if checker.patch(diagnostic.kind.rule()) { - if checker.semantic().is_builtin("OSError") { - // Filter out any `OSErrors` aliases. - let mut remaining: Vec = tuple - .elts - .iter() - .filter_map(|elt| { - if aliases.contains(&elt) { - None - } else { - Some(elt.clone()) - } - }) - .collect(); + if checker.semantic().is_builtin("OSError") { + // Filter out any `OSErrors` aliases. + let mut remaining: Vec = tuple + .elts + .iter() + .filter_map(|elt| { + if aliases.contains(&elt) { + None + } else { + Some(elt.clone()) + } + }) + .collect(); - // If `OSError` itself isn't already in the tuple, add it. - if tuple - .elts - .iter() - .all(|elt| !is_os_error(elt, checker.semantic())) - { - let node = ast::ExprName { - id: "OSError".into(), - ctx: ExprContext::Load, - range: TextRange::default(), - }; - remaining.insert(0, node.into()); - } + // If `OSError` itself isn't already in the tuple, add it. + if tuple + .elts + .iter() + .all(|elt| !is_os_error(elt, checker.semantic())) + { + let node = ast::ExprName { + id: "OSError".into(), + ctx: ExprContext::Load, + range: TextRange::default(), + }; + remaining.insert(0, node.into()); + } - let content = if remaining.len() == 1 { - "OSError".to_string() - } else { - let node = ast::ExprTuple { - elts: remaining, - ctx: ExprContext::Load, - range: TextRange::default(), - }; - format!("({})", checker.generator().expr(&node.into())) + let content = if remaining.len() == 1 { + "OSError".to_string() + } else { + let node = ast::ExprTuple { + elts: remaining, + ctx: ExprContext::Load, + range: TextRange::default(), }; + format!("({})", checker.generator().expr(&node.into())) + }; - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - pad(content, tuple.range(), checker.locator()), - tuple.range(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + pad(content, tuple.range(), checker.locator()), + tuple.range(), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/outdated_version_block.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/outdated_version_block.rs index 3fdcd57245df8..1b4b02177bddc 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/outdated_version_block.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/outdated_version_block.rs @@ -1,17 +1,17 @@ use std::cmp::Ordering; -use num_bigint::{BigInt, Sign}; - -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use anyhow::Result; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::helpers::map_subscript; use ruff_python_ast::stmt_if::{if_elif_branches, BranchKind, IfElifBranch}; use ruff_python_ast::whitespace::indentation; -use ruff_python_ast::{self as ast, CmpOp, Constant, ElifElseClause, Expr, StmtIf}; +use ruff_python_ast::{self as ast, CmpOp, Constant, ElifElseClause, Expr, Int, StmtIf}; use ruff_text_size::{Ranged, TextLen, TextRange}; -use crate::autofix::edits::delete_stmt; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix::edits::delete_stmt; + use crate::rules::pyupgrade::fixes::adjust_indentation; use crate::settings::types::PythonVersion; @@ -47,19 +47,37 @@ use crate::settings::types::PythonVersion; /// ## References /// - [Python documentation: `sys.version_info`](https://docs.python.org/3/library/sys.html#sys.version_info) #[violation] -pub struct OutdatedVersionBlock; +pub struct OutdatedVersionBlock { + reason: Reason, +} + +impl Violation for OutdatedVersionBlock { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; -impl AlwaysAutofixableViolation for OutdatedVersionBlock { #[derive_message_formats] fn message(&self) -> String { - format!("Version block is outdated for minimum Python version") + let OutdatedVersionBlock { reason } = self; + match reason { + Reason::Outdated => format!("Version block is outdated for minimum Python version"), + Reason::Invalid => format!("Version specifier is invalid"), + } } - fn autofix_title(&self) -> String { - "Remove outdated version block".to_string() + fn fix_title(&self) -> Option { + let OutdatedVersionBlock { reason } = self; + match reason { + Reason::Outdated => Some("Remove outdated version block".to_string()), + Reason::Invalid => None, + } } } +#[derive(Debug, PartialEq, Eq)] +enum Reason { + Outdated, + Invalid, +} + /// UP036 pub(crate) fn outdated_version_block(checker: &mut Checker, stmt_if: &StmtIf) { for branch in if_elif_branches(stmt_if) { @@ -77,9 +95,10 @@ pub(crate) fn outdated_version_block(checker: &mut Checker, stmt_if: &StmtIf) { continue; }; + // Detect `sys.version_info`, along with slices (like `sys.version_info[:2]`). if !checker .semantic() - .resolve_call_path(left) + .resolve_call_path(map_subscript(left)) .is_some_and(|call_path| matches!(call_path.as_slice(), ["sys", "version_info"])) { continue; @@ -87,65 +106,85 @@ pub(crate) fn outdated_version_block(checker: &mut Checker, stmt_if: &StmtIf) { match comparison { Expr::Tuple(ast::ExprTuple { elts, .. }) => match op { - CmpOp::Lt | CmpOp::LtE => { - let version = extract_version(elts); + CmpOp::Lt | CmpOp::LtE | CmpOp::Gt | CmpOp::GtE => { + let Some(version) = extract_version(elts) else { + return; + }; let target = checker.settings.target_version; - if compare_version(&version, target, op == &CmpOp::LtE) { - let mut diagnostic = - Diagnostic::new(OutdatedVersionBlock, branch.test.range()); - if checker.patch(diagnostic.kind.rule()) { - if let Some(fix) = fix_always_false_branch(checker, stmt_if, &branch) { + match version_always_less_than( + &version, + target, + // `x <= y` and `x > y` are cases where `x == y` will not stop the comparison + // from always evaluating to true or false respectively + op.is_lt_e() || op.is_gt(), + ) { + Ok(false) => {} + Ok(true) => { + let mut diagnostic = Diagnostic::new( + OutdatedVersionBlock { + reason: Reason::Outdated, + }, + branch.test.range(), + ); + if let Some(fix) = if op.is_lt() || op.is_lt_e() { + fix_always_false_branch(checker, stmt_if, &branch) + } else { + fix_always_true_branch(checker, stmt_if, &branch) + } { diagnostic.set_fix(fix); } + checker.diagnostics.push(diagnostic); } - checker.diagnostics.push(diagnostic); - } - } - CmpOp::Gt | CmpOp::GtE => { - let version = extract_version(elts); - let target = checker.settings.target_version; - if compare_version(&version, target, op == &CmpOp::GtE) { - let mut diagnostic = - Diagnostic::new(OutdatedVersionBlock, branch.test.range()); - if checker.patch(diagnostic.kind.rule()) { - if let Some(fix) = fix_always_true_branch(checker, stmt_if, &branch) { - diagnostic.set_fix(fix); - } + Err(_) => { + checker.diagnostics.push(Diagnostic::new( + OutdatedVersionBlock { + reason: Reason::Invalid, + }, + comparison.range(), + )); } - checker.diagnostics.push(diagnostic); } } _ => {} }, Expr::Constant(ast::ExprConstant { - value: Constant::Int(number), + value: Constant::Int(int), .. }) => { if op == &CmpOp::Eq { - match bigint_to_u32(number) { - 2 => { - let mut diagnostic = - Diagnostic::new(OutdatedVersionBlock, branch.test.range()); - if checker.patch(diagnostic.kind.rule()) { - if let Some(fix) = - fix_always_false_branch(checker, stmt_if, &branch) - { - diagnostic.set_fix(fix); - } + match int.as_u8() { + Some(2) => { + let mut diagnostic = Diagnostic::new( + OutdatedVersionBlock { + reason: Reason::Outdated, + }, + branch.test.range(), + ); + if let Some(fix) = fix_always_false_branch(checker, stmt_if, &branch) { + diagnostic.set_fix(fix); } checker.diagnostics.push(diagnostic); } - 3 => { - let mut diagnostic = - Diagnostic::new(OutdatedVersionBlock, branch.test.range()); - if checker.patch(diagnostic.kind.rule()) { - if let Some(fix) = fix_always_true_branch(checker, stmt_if, &branch) - { - diagnostic.set_fix(fix); - } + Some(3) => { + let mut diagnostic = Diagnostic::new( + OutdatedVersionBlock { + reason: Reason::Outdated, + }, + branch.test.range(), + ); + if let Some(fix) = fix_always_true_branch(checker, stmt_if, &branch) { + diagnostic.set_fix(fix); } checker.diagnostics.push(diagnostic); } + None => { + checker.diagnostics.push(Diagnostic::new( + OutdatedVersionBlock { + reason: Reason::Invalid, + }, + comparison.range(), + )); + } _ => {} } } @@ -155,32 +194,43 @@ pub(crate) fn outdated_version_block(checker: &mut Checker, stmt_if: &StmtIf) { } } -/// Returns true if the `target_version` is always less than the [`PythonVersion`]. -fn compare_version(target_version: &[u32], py_version: PythonVersion, or_equal: bool) -> bool { - let mut target_version_iter = target_version.iter(); +/// Returns true if the `check_version` is always less than the [`PythonVersion`]. +fn version_always_less_than( + check_version: &[Int], + py_version: PythonVersion, + or_equal: bool, +) -> Result { + let mut check_version_iter = check_version.iter(); - let Some(if_major) = target_version_iter.next() else { - return false; + let Some(if_major) = check_version_iter.next() else { + return Ok(false); + }; + let Some(if_major) = if_major.as_u8() else { + return Err(anyhow::anyhow!("invalid major version: {if_major}")); }; let (py_major, py_minor) = py_version.as_tuple(); - match if_major.cmp(&py_major.into()) { - Ordering::Less => true, - Ordering::Greater => false, + match if_major.cmp(&py_major) { + Ordering::Less => Ok(true), + Ordering::Greater => Ok(false), Ordering::Equal => { - let Some(if_minor) = target_version_iter.next() else { - return true; + let Some(if_minor) = check_version_iter.next() else { + return Ok(true); }; - if or_equal { + let Some(if_minor) = if_minor.as_u8() else { + return Err(anyhow::anyhow!("invalid minor version: {if_minor}")); + }; + + Ok(if or_equal { // Ex) `sys.version_info <= 3.8`. If Python 3.8 is the minimum supported version, // the condition won't always evaluate to `false`, so we want to return `false`. - *if_minor < py_minor.into() + if_minor < py_minor } else { // Ex) `sys.version_info < 3.8`. If Python 3.8 is the minimum supported version, // the condition _will_ always evaluate to `false`, so we want to return `true`. - *if_minor <= py_minor.into() - } + if_minor <= py_minor + }) } } } @@ -208,7 +258,7 @@ fn fix_always_false_branch( let stmt = checker.semantic().current_statement(); let parent = checker.semantic().current_statement_parent(); let edit = delete_stmt(stmt, parent, checker.locator(), checker.indexer()); - Some(Fix::suggested(edit)) + Some(Fix::unsafe_edit(edit)) } // If we have an `if` and an `elif`, turn the `elif` into an `if` Some(ElifElseClause { @@ -217,11 +267,13 @@ fn fix_always_false_branch( .. }) => { debug_assert!( - &checker.locator().contents()[TextRange::at(range.start(), "elif".text_len())] + checker + .locator() + .slice(TextRange::at(range.start(), "elif".text_len())) == "elif" ); let end_location = range.start() + ("elif".text_len() - "if".text_len()); - Some(Fix::suggested(Edit::deletion( + Some(Fix::unsafe_edit(Edit::deletion( stmt_if.start(), end_location, ))) @@ -234,7 +286,7 @@ fn fix_always_false_branch( let end = body.last()?; if indentation(checker.locator(), start).is_none() { // Inline `else` block (e.g., `else: x = 1`). - Some(Fix::suggested(Edit::range_replacement( + Some(Fix::unsafe_edit(Edit::range_replacement( checker .locator() .slice(TextRange::new(start.start(), end.end())) @@ -256,7 +308,7 @@ fn fix_always_false_branch( .ok() }) .map(|contents| { - Fix::suggested(Edit::replacement( + Fix::unsafe_edit(Edit::replacement( contents, checker.locator().line_start(stmt_if.start()), stmt_if.end(), @@ -283,7 +335,7 @@ fn fix_always_false_branch( .iter() .map(Ranged::start) .find(|start| *start > branch.start()); - Some(Fix::suggested(Edit::deletion( + Some(Fix::unsafe_edit(Edit::deletion( branch.start(), next_start.unwrap_or(branch.end()), ))) @@ -311,7 +363,7 @@ fn fix_always_true_branch( let end = branch.body.last()?; if indentation(checker.locator(), start).is_none() { // Inline `if` block (e.g., `if ...: x = 1`). - Some(Fix::suggested(Edit::range_replacement( + Some(Fix::unsafe_edit(Edit::range_replacement( checker .locator() .slice(TextRange::new(start.start(), end.end())) @@ -330,7 +382,7 @@ fn fix_always_true_branch( .ok() }) .map(|contents| { - Fix::suggested(Edit::replacement( + Fix::unsafe_edit(Edit::replacement( contents, checker.locator().line_start(stmt_if.start()), stmt_if.end(), @@ -345,7 +397,7 @@ fn fix_always_true_branch( let text = checker .locator() .slice(TextRange::new(branch.test.end(), end.end())); - Some(Fix::suggested(Edit::range_replacement( + Some(Fix::unsafe_edit(Edit::range_replacement( format!("else{text}"), TextRange::new(branch.start(), stmt_if.end()), ))) @@ -353,31 +405,20 @@ fn fix_always_true_branch( } } -/// Converts a `BigInt` to a `u32`. If the number is negative, it will return 0. -fn bigint_to_u32(number: &BigInt) -> u32 { - let the_number = number.to_u32_digits(); - match the_number.0 { - Sign::Minus | Sign::NoSign => 0, - Sign::Plus => *the_number.1.first().unwrap(), - } -} - -/// Gets the version from the tuple -fn extract_version(elts: &[Expr]) -> Vec { - let mut version: Vec = vec![]; +/// Return the version tuple as a sequence of [`Int`] values. +fn extract_version(elts: &[Expr]) -> Option> { + let mut version: Vec = vec![]; for elt in elts { - if let Expr::Constant(ast::ExprConstant { - value: Constant::Int(item), + let Expr::Constant(ast::ExprConstant { + value: Constant::Int(int), .. }) = &elt - { - let number = bigint_to_u32(item); - version.push(number); - } else { - return version; - } + else { + return None; + }; + version.push(int.clone()); } - version + Some(version) } #[cfg(test)] @@ -386,23 +427,26 @@ mod tests { use super::*; - #[test_case(PythonVersion::Py37, &[2], true, true; "compare-2.0")] - #[test_case(PythonVersion::Py37, &[2, 0], true, true; "compare-2.0-whole")] - #[test_case(PythonVersion::Py37, &[3], true, true; "compare-3.0")] - #[test_case(PythonVersion::Py37, &[3, 0], true, true; "compare-3.0-whole")] - #[test_case(PythonVersion::Py37, &[3, 1], true, true; "compare-3.1")] - #[test_case(PythonVersion::Py37, &[3, 5], true, true; "compare-3.5")] - #[test_case(PythonVersion::Py37, &[3, 7], true, false; "compare-3.7")] - #[test_case(PythonVersion::Py37, &[3, 7], false, true; "compare-3.7-not-equal")] - #[test_case(PythonVersion::Py37, &[3, 8], false , false; "compare-3.8")] - #[test_case(PythonVersion::Py310, &[3,9], true, true; "compare-3.9")] - #[test_case(PythonVersion::Py310, &[3, 11], true, false; "compare-3.11")] + #[test_case(PythonVersion::Py37, & [2], true, true; "compare-2.0")] + #[test_case(PythonVersion::Py37, & [2, 0], true, true; "compare-2.0-whole")] + #[test_case(PythonVersion::Py37, & [3], true, true; "compare-3.0")] + #[test_case(PythonVersion::Py37, & [3, 0], true, true; "compare-3.0-whole")] + #[test_case(PythonVersion::Py37, & [3, 1], true, true; "compare-3.1")] + #[test_case(PythonVersion::Py37, & [3, 5], true, true; "compare-3.5")] + #[test_case(PythonVersion::Py37, & [3, 7], true, false; "compare-3.7")] + #[test_case(PythonVersion::Py37, & [3, 7], false, true; "compare-3.7-not-equal")] + #[test_case(PythonVersion::Py37, & [3, 8], false, false; "compare-3.8")] + #[test_case(PythonVersion::Py310, & [3, 9], true, true; "compare-3.9")] + #[test_case(PythonVersion::Py310, & [3, 11], true, false; "compare-3.11")] fn test_compare_version( version: PythonVersion, - version_vec: &[u32], + target_versions: &[u8], or_equal: bool, expected: bool, - ) { - assert_eq!(compare_version(version_vec, version, or_equal), expected); + ) -> Result<()> { + let target_versions: Vec<_> = target_versions.iter().map(|int| Int::from(*int)).collect(); + let actual = version_always_less_than(&target_versions, version, or_equal)?; + assert_eq!(actual, expected); + Ok(()) } } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/printf_string_formatting.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/printf_string_formatting.rs index 1d78d2a38b090..6f46f1fb9d917 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/printf_string_formatting.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/printf_string_formatting.rs @@ -1,6 +1,7 @@ +use std::borrow::Cow; use std::str::FromStr; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::str::{leading_quote, trailing_quote}; use ruff_python_ast::whitespace::indentation; @@ -15,7 +16,7 @@ use ruff_source_file::Locator; use ruff_text_size::{Ranged, TextRange}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::pyupgrade::helpers::curly_escape; /// ## What it does @@ -27,6 +28,30 @@ use crate::rules::pyupgrade::helpers::curly_escape; /// the newer `str.format` and f-strings constructs over `printf`-style string /// formatting. /// +/// ## Known problems +/// This rule is unable to detect cases in which the format string contains +/// a single, generic format specifier (e.g. `%s`), and the right-hand side +/// is an ambiguous expression. +/// +/// For example, given: +/// ```python +/// "%s" % value +/// ``` +/// +/// `value` could be a single-element tuple, _or_ it could be a single value. +/// Both of these would resolve to the same formatted string when using +/// `printf`-style formatting, but _not_ when using f-strings: +/// +/// ```python +/// value = 1 +/// print("%s" % value) # "1" +/// print("{}".format(value)) # "1" +/// +/// value = (1,) +/// print("%s" % value) # "1" +/// print("{}".format(value)) # "(1,)" +/// ``` +/// /// ## Example /// ```python /// "%s, %s" % ("Hello", "World") # "Hello, World" @@ -44,14 +69,14 @@ use crate::rules::pyupgrade::helpers::curly_escape; pub struct PrintfStringFormatting; impl Violation for PrintfStringFormatting { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Use format specifiers instead of percent format") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Replace with format specifiers".to_string()) } } @@ -81,7 +106,7 @@ fn simplify_conversion_flag(flags: CConversionFlags) -> String { } /// Convert a [`PercentFormat`] struct into a `String`. -fn handle_part(part: &CFormatPart) -> String { +fn handle_part(part: &CFormatPart) -> Cow<'_, str> { match part { CFormatPart::Literal(item) => curly_escape(item), CFormatPart::Spec(spec) => { @@ -90,7 +115,7 @@ fn handle_part(part: &CFormatPart) -> String { // TODO(charlie): What case is this? if spec.format_char == '%' { format_string.push('%'); - return format_string; + return Cow::Owned(format_string); } format_string.push('{'); @@ -147,26 +172,25 @@ fn handle_part(part: &CFormatPart) -> String { format_string.push(spec.format_char); } format_string.push('}'); - format_string + Cow::Owned(format_string) } } } /// Convert a [`CFormatString`] into a `String`. fn percent_to_format(format_string: &CFormatString) -> String { - let mut contents = String::new(); - for (.., format_part) in format_string.iter() { - contents.push_str(&handle_part(format_part)); - } - contents + format_string + .iter() + .map(|(_, part)| handle_part(part)) + .collect() } /// If a tuple has one argument, remove the comma; otherwise, return it as-is. -fn clean_params_tuple(right: &Expr, locator: &Locator) -> String { - let mut contents = locator.slice(right).to_string(); +fn clean_params_tuple<'a>(right: &Expr, locator: &Locator<'a>) -> Cow<'a, str> { if let Expr::Tuple(ast::ExprTuple { elts, .. }) = &right { if elts.len() == 1 { if !locator.contains_line_break(right.range()) { + let mut contents = locator.slice(right).to_string(); for (i, character) in contents.chars().rev().enumerate() { if character == ',' { let correct_index = contents.len() - i - 1; @@ -174,10 +198,12 @@ fn clean_params_tuple(right: &Expr, locator: &Locator) -> String { break; } } + return Cow::Owned(contents); } } } - contents + + Cow::Borrowed(locator.slice(right)) } /// Converts a dictionary to a function call while preserving as much styling as @@ -395,16 +421,16 @@ pub(crate) fn printf_string_formatting(checker: &mut Checker, expr: &Expr, right // Parse the parameters. let params_string = match right { Expr::Constant(_) | Expr::FString(_) => { - format!("({})", checker.locator().slice(right)) + Cow::Owned(format!("({})", checker.locator().slice(right))) } Expr::Name(_) | Expr::Attribute(_) | Expr::Subscript(_) | Expr::Call(_) => { if num_keyword_arguments > 0 { // If we have _any_ named fields, assume the right-hand side is a mapping. - format!("(**{})", checker.locator().slice(right)) + Cow::Owned(format!("(**{})", checker.locator().slice(right))) } else if num_positional_arguments > 1 { // If we have multiple fields, but no named fields, assume the right-hand side is a // tuple. - format!("(*{})", checker.locator().slice(right)) + Cow::Owned(format!("(*{})", checker.locator().slice(right))) } else { // Otherwise, if we have a single field, we can't make any assumptions about the // right-hand side. It _could_ be a tuple, but it could also be a single value, @@ -420,13 +446,12 @@ pub(crate) fn printf_string_formatting(checker: &mut Checker, expr: &Expr, right } Expr::Tuple(_) => clean_params_tuple(right, checker.locator()), Expr::Dict(_) => { - if let Some(params_string) = + let Some(params_string) = clean_params_dictionary(right, checker.locator(), checker.stylist()) - { - params_string - } else { + else { return; - } + }; + Cow::Owned(params_string) } _ => return, }; @@ -465,16 +490,14 @@ pub(crate) fn printf_string_formatting(checker: &mut Checker, expr: &Expr, right contents.push_str(&format!(".format{params_string}")); let mut diagnostic = Diagnostic::new(PrintfStringFormatting, expr.range()); - // Avoid autofix if there are comments within the right-hand side: + // Avoid fix if there are comments within the right-hand side: // ``` // "%s" % ( // 0, # 0 // ) // ``` - if checker.patch(diagnostic.kind.rule()) - && !checker.indexer().comment_ranges().intersects(right.range()) - { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( + if !checker.indexer().comment_ranges().intersects(right.range()) { + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( contents, expr.range(), ))); diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/quoted_annotation.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/quoted_annotation.rs index 749e3011f5061..2a94d946a3baf 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/quoted_annotation.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/quoted_annotation.rs @@ -1,10 +1,9 @@ use ruff_text_size::TextRange; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use crate::checkers::ast::Checker; -use crate::registry::Rule; /// ## What it does /// Checks for the presence of unnecessary quotes in type annotations. @@ -39,13 +38,13 @@ use crate::registry::Rule; #[violation] pub struct QuotedAnnotation; -impl AlwaysAutofixableViolation for QuotedAnnotation { +impl AlwaysFixableViolation for QuotedAnnotation { #[derive_message_formats] fn message(&self) -> String { format!("Remove quotes from type annotation") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove quotes".to_string() } } @@ -53,11 +52,9 @@ impl AlwaysAutofixableViolation for QuotedAnnotation { /// UP037 pub(crate) fn quoted_annotation(checker: &mut Checker, annotation: &str, range: TextRange) { let mut diagnostic = Diagnostic::new(QuotedAnnotation, range); - if checker.patch(Rule::QuotedAnnotation) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - annotation.to_string(), - range, - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + annotation.to_string(), + range, + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/redundant_open_modes.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/redundant_open_modes.rs index cb6b496cc3077..52356297c7caf 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/redundant_open_modes.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/redundant_open_modes.rs @@ -2,7 +2,7 @@ use std::str::FromStr; use anyhow::{anyhow, Result}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Constant, Expr, PySourceType}; use ruff_python_parser::{lexer, AsMode}; @@ -11,7 +11,6 @@ use ruff_source_file::Locator; use ruff_text_size::{Ranged, TextSize}; use crate::checkers::ast::Checker; -use crate::registry::Rule; /// ## What it does /// Checks for redundant `open` mode parameters. @@ -39,7 +38,7 @@ pub struct RedundantOpenModes { replacement: Option, } -impl AlwaysAutofixableViolation for RedundantOpenModes { +impl AlwaysFixableViolation for RedundantOpenModes { #[derive_message_formats] fn message(&self) -> String { let RedundantOpenModes { replacement } = self; @@ -51,7 +50,7 @@ impl AlwaysAutofixableViolation for RedundantOpenModes { } } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let RedundantOpenModes { replacement } = self; match replacement { None => "Remove open mode parameters".to_string(), @@ -87,7 +86,6 @@ pub(crate) fn redundant_open_modes(checker: &mut Checker, call: &ast::ExprCall) &keyword.value, mode.replacement_value(), checker.locator(), - checker.patch(Rule::RedundantOpenModes), checker.source_type, )); } @@ -107,7 +105,6 @@ pub(crate) fn redundant_open_modes(checker: &mut Checker, call: &ast::ExprCall) mode_param, mode.replacement_value(), checker.locator(), - checker.patch(Rule::RedundantOpenModes), checker.source_type, )); } @@ -174,7 +171,6 @@ fn create_check( mode_param: &Expr, replacement_value: Option<&str>, locator: &Locator, - patch: bool, source_type: PySourceType, ) -> Diagnostic { let mut diagnostic = Diagnostic::new( @@ -183,18 +179,18 @@ fn create_check( }, expr.range(), ); - if patch { - if let Some(content) = replacement_value { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - content.to_string(), - mode_param.range(), - ))); - } else { - diagnostic.try_set_fix(|| { - create_remove_param_fix(locator, expr, mode_param, source_type).map(Fix::automatic) - }); - } + + if let Some(content) = replacement_value { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + content.to_string(), + mode_param.range(), + ))); + } else { + diagnostic.try_set_fix(|| { + create_remove_param_fix(locator, expr, mode_param, source_type).map(Fix::safe_edit) + }); } + diagnostic } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/replace_stdout_stderr.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/replace_stdout_stderr.rs index 67ddaa118f2f3..ff08e4e85160a 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/replace_stdout_stderr.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/replace_stdout_stderr.rs @@ -1,13 +1,12 @@ use anyhow::Result; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Keyword}; use ruff_text_size::Ranged; -use crate::autofix::edits::{remove_argument, Parentheses}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix::edits::{remove_argument, Parentheses}; /// ## What it does /// Checks for uses of `subprocess.run` that send `stdout` and `stderr` to a @@ -40,14 +39,14 @@ use crate::registry::AsRule; pub struct ReplaceStdoutStderr; impl Violation for ReplaceStdoutStderr { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Sending `stdout` and `stderr` to `PIPE` is deprecated, use `capture_output`") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Replace with `capture_output` keyword argument".to_string()) } } @@ -81,12 +80,9 @@ pub(crate) fn replace_stdout_stderr(checker: &mut Checker, call: &ast::ExprCall) } let mut diagnostic = Diagnostic::new(ReplaceStdoutStderr, call.range()); - if checker.patch(diagnostic.kind.rule()) { - if call.arguments.find_keyword("capture_output").is_none() { - diagnostic.try_set_fix(|| { - generate_fix(stdout, stderr, call, checker.locator().contents()) - }); - } + if call.arguments.find_keyword("capture_output").is_none() { + diagnostic + .try_set_fix(|| generate_fix(stdout, stderr, call, checker.locator().contents())); } checker.diagnostics.push(diagnostic); } @@ -105,7 +101,7 @@ fn generate_fix( (stderr, stdout) }; // Replace one argument with `capture_output=True`, and remove the other. - Ok(Fix::suggested_edits( + Ok(Fix::unsafe_edits( Edit::range_replacement("capture_output=True".to_string(), first.range()), [remove_argument( second, diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/replace_universal_newlines.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/replace_universal_newlines.rs index 6f82e5940fec4..9e97481dba1f6 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/replace_universal_newlines.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/replace_universal_newlines.rs @@ -1,11 +1,10 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast as ast; use ruff_text_size::Ranged; -use crate::autofix::edits::{remove_argument, Parentheses}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix::edits::{remove_argument, Parentheses}; /// ## What it does /// Checks for uses of `subprocess.run` that set the `universal_newlines` @@ -37,13 +36,13 @@ use crate::registry::AsRule; #[violation] pub struct ReplaceUniversalNewlines; -impl AlwaysAutofixableViolation for ReplaceUniversalNewlines { +impl AlwaysFixableViolation for ReplaceUniversalNewlines { #[derive_message_formats] fn message(&self) -> String { format!("`universal_newlines` is deprecated, use `text`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace with `text` keyword argument".to_string() } } @@ -65,23 +64,21 @@ pub(crate) fn replace_universal_newlines(checker: &mut Checker, call: &ast::Expr let mut diagnostic = Diagnostic::new(ReplaceUniversalNewlines, arg.range()); - if checker.patch(diagnostic.kind.rule()) { - if call.arguments.find_keyword("text").is_some() { - diagnostic.try_set_fix(|| { - remove_argument( - kwarg, - &call.arguments, - Parentheses::Preserve, - checker.locator().contents(), - ) - .map(Fix::suggested) - }); - } else { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - "text".to_string(), - arg.range(), - ))); - } + if call.arguments.find_keyword("text").is_some() { + diagnostic.try_set_fix(|| { + remove_argument( + kwarg, + &call.arguments, + Parentheses::Preserve, + checker.locator().contents(), + ) + .map(Fix::safe_edit) + }); + } else { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "text".to_string(), + arg.range(), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/super_call_with_parameters.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/super_call_with_parameters.rs index b118baa3859ed..c8af446f4adcf 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/super_call_with_parameters.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/super_call_with_parameters.rs @@ -1,10 +1,9 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Expr, Parameter, ParameterWithDefault, Stmt}; use ruff_text_size::{Ranged, TextSize}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for `super` calls that pass redundant arguments. @@ -47,13 +46,13 @@ use crate::registry::AsRule; #[violation] pub struct SuperCallWithParameters; -impl AlwaysAutofixableViolation for SuperCallWithParameters { +impl AlwaysFixableViolation for SuperCallWithParameters { #[derive_message_formats] fn message(&self) -> String { format!("Use `super()` instead of `super(__class__, self)`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove `__super__` parameters".to_string() } } @@ -128,12 +127,10 @@ pub(crate) fn super_call_with_parameters(checker: &mut Checker, call: &ast::Expr drop(parents); let mut diagnostic = Diagnostic::new(SuperCallWithParameters, call.arguments.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::deletion( - call.arguments.start() + TextSize::new(1), - call.arguments.end() - TextSize::new(1), - ))); - } + diagnostic.set_fix(Fix::unsafe_edit(Edit::deletion( + call.arguments.start() + TextSize::new(1), + call.arguments.end() - TextSize::new(1), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/type_of_primitive.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/type_of_primitive.rs index 61e1643ce73d2..f65ce23ff29d8 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/type_of_primitive.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/type_of_primitive.rs @@ -1,12 +1,11 @@ use ruff_python_ast::{self as ast, Expr}; -use crate::autofix::edits::pad; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use crate::fix::edits::pad; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; use super::super::types::Primitive; @@ -37,7 +36,7 @@ pub struct TypeOfPrimitive { } impl Violation for TypeOfPrimitive { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -45,7 +44,7 @@ impl Violation for TypeOfPrimitive { format!("Use `{}` instead of `type(...)`", primitive.builtin()) } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let TypeOfPrimitive { primitive } = self; Some(format!( "Replace `type(...)` with `{}`", @@ -73,14 +72,12 @@ pub(crate) fn type_of_primitive(checker: &mut Checker, expr: &Expr, func: &Expr, return; }; let mut diagnostic = Diagnostic::new(TypeOfPrimitive { primitive }, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - let builtin = primitive.builtin(); - if checker.semantic().is_builtin(&builtin) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - pad(primitive.builtin(), expr.range(), checker.locator()), - expr.range(), - ))); - } + let builtin = primitive.builtin(); + if checker.semantic().is_builtin(&builtin) { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + pad(primitive.builtin(), expr.range(), checker.locator()), + expr.range(), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/typing_text_str_alias.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/typing_text_str_alias.rs index fe749515c776b..86d9e6b28bf99 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/typing_text_str_alias.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/typing_text_str_alias.rs @@ -1,11 +1,10 @@ use ruff_python_ast::Expr; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of `typing.Text`. @@ -33,14 +32,14 @@ use crate::registry::AsRule; pub struct TypingTextStrAlias; impl Violation for TypingTextStrAlias { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("`typing.Text` is deprecated, use `str`") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Replace with `str`".to_string()) } } @@ -53,13 +52,11 @@ pub(crate) fn typing_text_str_alias(checker: &mut Checker, expr: &Expr) { .is_some_and(|call_path| matches!(call_path.as_slice(), ["typing", "Text"])) { let mut diagnostic = Diagnostic::new(TypingTextStrAlias, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - if checker.semantic().is_builtin("str") { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - "str".to_string(), - expr.range(), - ))); - } + if checker.semantic().is_builtin("str") { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + "str".to_string(), + expr.range(), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/unicode_kind_prefix.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/unicode_kind_prefix.rs index 887b98cb300c1..20fcbf08a5913 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/unicode_kind_prefix.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/unicode_kind_prefix.rs @@ -1,10 +1,9 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::Expr; use ruff_text_size::{Ranged, TextRange, TextSize}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of the Unicode kind prefix (`u`) in strings. @@ -28,13 +27,13 @@ use crate::registry::AsRule; #[violation] pub struct UnicodeKindPrefix; -impl AlwaysAutofixableViolation for UnicodeKindPrefix { +impl AlwaysFixableViolation for UnicodeKindPrefix { #[derive_message_formats] fn message(&self) -> String { format!("Remove unicode literals from strings") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove unicode prefix".to_string() } } @@ -43,12 +42,10 @@ impl AlwaysAutofixableViolation for UnicodeKindPrefix { pub(crate) fn unicode_kind_prefix(checker: &mut Checker, expr: &Expr, is_unicode: bool) { if is_unicode { let mut diagnostic = Diagnostic::new(UnicodeKindPrefix, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::range_deletion(TextRange::at( - expr.start(), - TextSize::from(1), - )))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(TextRange::at( + expr.start(), + TextSize::from(1), + )))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_builtin_import.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_builtin_import.rs index 6a1f0553d18d1..ccb7d12c353c6 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_builtin_import.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_builtin_import.rs @@ -1,13 +1,12 @@ use itertools::Itertools; use ruff_python_ast::{Alias, Stmt}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; -use crate::autofix; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix; /// ## What it does /// Checks for unnecessary imports of builtins. @@ -35,7 +34,7 @@ pub struct UnnecessaryBuiltinImport { pub names: Vec, } -impl AlwaysAutofixableViolation for UnnecessaryBuiltinImport { +impl AlwaysFixableViolation for UnnecessaryBuiltinImport { #[derive_message_formats] fn message(&self) -> String { let UnnecessaryBuiltinImport { names } = self; @@ -48,7 +47,7 @@ impl AlwaysAutofixableViolation for UnnecessaryBuiltinImport { } } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove unnecessary builtin import".to_string() } } @@ -121,25 +120,23 @@ pub(crate) fn unnecessary_builtin_import( }, stmt.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - let statement = checker.semantic().current_statement(); - let parent = checker.semantic().current_statement_parent(); - let edit = autofix::edits::remove_unused_imports( - unused_imports - .iter() - .map(|alias| &alias.name) - .map(ruff_python_ast::Identifier::as_str), - statement, - parent, - checker.locator(), - checker.stylist(), - checker.indexer(), - )?; - Ok(Fix::suggested(edit).isolate(Checker::isolation( - checker.semantic().current_statement_parent_id(), - ))) - }); - } + diagnostic.try_set_fix(|| { + let statement = checker.semantic().current_statement(); + let parent = checker.semantic().current_statement_parent(); + let edit = fix::edits::remove_unused_imports( + unused_imports + .iter() + .map(|alias| &alias.name) + .map(ruff_python_ast::Identifier::as_str), + statement, + parent, + checker.locator(), + checker.stylist(), + checker.indexer(), + )?; + Ok(Fix::unsafe_edit(edit).isolate(Checker::isolation( + checker.semantic().current_statement_parent_id(), + ))) + }); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_class_parentheses.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_class_parentheses.rs index 989cdb67304cf..fdb3612d2b62f 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_class_parentheses.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_class_parentheses.rs @@ -1,10 +1,9 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for class definitions that include unnecessary parentheses after @@ -28,13 +27,13 @@ use crate::registry::AsRule; #[violation] pub struct UnnecessaryClassParentheses; -impl AlwaysAutofixableViolation for UnnecessaryClassParentheses { +impl AlwaysFixableViolation for UnnecessaryClassParentheses { #[derive_message_formats] fn message(&self) -> String { format!("Unnecessary parentheses after class definition") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove parentheses".to_string() } } @@ -50,11 +49,9 @@ pub(crate) fn unnecessary_class_parentheses(checker: &mut Checker, class_def: &a } let mut diagnostic = Diagnostic::new(UnnecessaryClassParentheses, arguments.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::deletion( - arguments.start(), - arguments.end(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::deletion( + arguments.start(), + arguments.end(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_coding_comment.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_coding_comment.rs index d80d72e599215..46ed24c176ccd 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_coding_comment.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_coding_comment.rs @@ -1,15 +1,12 @@ use once_cell::sync::Lazy; use regex::Regex; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_index::Indexer; use ruff_source_file::Locator; use ruff_text_size::{Ranged, TextRange}; -use crate::registry::AsRule; -use crate::settings::LinterSettings; - /// ## What it does /// Checks for unnecessary UTF-8 encoding declarations. /// @@ -32,13 +29,13 @@ use crate::settings::LinterSettings; #[violation] pub struct UTF8EncodingDeclaration; -impl AlwaysAutofixableViolation for UTF8EncodingDeclaration { +impl AlwaysFixableViolation for UTF8EncodingDeclaration { #[derive_message_formats] fn message(&self) -> String { format!("UTF-8 encoding declaration is unnecessary") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove unnecessary coding comment".to_string() } } @@ -52,7 +49,6 @@ pub(crate) fn unnecessary_coding_comment( diagnostics: &mut Vec, locator: &Locator, indexer: &Indexer, - settings: &LinterSettings, ) { // The coding comment must be on one of the first two lines. Since each comment spans at least // one line, we only need to check the first two comments at most. @@ -91,12 +87,10 @@ pub(crate) fn unnecessary_coding_comment( } let mut diagnostic = Diagnostic::new(UTF8EncodingDeclaration, *comment_range); - if settings.rules.should_fix(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::automatic(Edit::deletion( - line_range.start(), - line_range.end(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::deletion( + line_range.start(), + line_range.end(), + ))); diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_encode_utf8.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_encode_utf8.rs index 16c81e65feff9..9cc79ce4dab73 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_encode_utf8.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_encode_utf8.rs @@ -1,19 +1,12 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Arguments, Constant, Expr, Keyword, PySourceType}; use ruff_python_parser::{lexer, AsMode, Tok}; use ruff_source_file::Locator; use ruff_text_size::{Ranged, TextRange}; -use crate::autofix::edits::{pad, remove_argument, Parentheses}; use crate::checkers::ast::Checker; -use crate::registry::Rule; - -#[derive(Debug, PartialEq, Eq)] -pub(crate) enum Reason { - BytesLiteral, - DefaultArgument, -} +use crate::fix::edits::{pad, remove_argument, Parentheses}; /// ## What it does /// Checks for unnecessary calls to `encode` as UTF-8. @@ -39,7 +32,7 @@ pub struct UnnecessaryEncodeUTF8 { reason: Reason, } -impl AlwaysAutofixableViolation for UnnecessaryEncodeUTF8 { +impl AlwaysFixableViolation for UnnecessaryEncodeUTF8 { #[derive_message_formats] fn message(&self) -> String { match self.reason { @@ -48,7 +41,7 @@ impl AlwaysAutofixableViolation for UnnecessaryEncodeUTF8 { } } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { match self.reason { Reason::BytesLiteral => "Rewrite as bytes literal".to_string(), Reason::DefaultArgument => "Remove unnecessary `encoding` argument".to_string(), @@ -56,6 +49,12 @@ impl AlwaysAutofixableViolation for UnnecessaryEncodeUTF8 { } } +#[derive(Debug, PartialEq, Eq)] +enum Reason { + BytesLiteral, + DefaultArgument, +} + const UTF8_LITERALS: &[&str] = &["utf-8", "utf8", "utf_8", "u8", "utf", "cp65001"]; fn match_encoded_variable(func: &Expr) -> Option<&Expr> { @@ -151,7 +150,7 @@ fn replace_with_bytes_literal( prev = range.end(); } - Fix::automatic(Edit::range_replacement( + Fix::safe_edit(Edit::range_replacement( pad(replacement, call.range(), locator), call.range(), )) @@ -177,13 +176,11 @@ pub(crate) fn unnecessary_encode_utf8(checker: &mut Checker, call: &ast::ExprCal }, call.range(), ); - if checker.patch(Rule::UnnecessaryEncodeUTF8) { - diagnostic.set_fix(replace_with_bytes_literal( - checker.locator(), - call, - checker.source_type, - )); - } + diagnostic.set_fix(replace_with_bytes_literal( + checker.locator(), + call, + checker.source_type, + )); checker.diagnostics.push(diagnostic); } else if let EncodingArg::Keyword(kwarg) = encoding_arg { // Ex) Convert `"unicode text©".encode(encoding="utf-8")` to @@ -194,17 +191,15 @@ pub(crate) fn unnecessary_encode_utf8(checker: &mut Checker, call: &ast::ExprCal }, call.range(), ); - if checker.patch(Rule::UnnecessaryEncodeUTF8) { - diagnostic.try_set_fix(|| { - remove_argument( - kwarg, - &call.arguments, - Parentheses::Preserve, - checker.locator().contents(), - ) - .map(Fix::automatic) - }); - } + diagnostic.try_set_fix(|| { + remove_argument( + kwarg, + &call.arguments, + Parentheses::Preserve, + checker.locator().contents(), + ) + .map(Fix::safe_edit) + }); checker.diagnostics.push(diagnostic); } else if let EncodingArg::Positional(arg) = encoding_arg { // Ex) Convert `"unicode text©".encode("utf-8")` to `"unicode text©".encode()`. @@ -214,17 +209,15 @@ pub(crate) fn unnecessary_encode_utf8(checker: &mut Checker, call: &ast::ExprCal }, call.range(), ); - if checker.patch(Rule::UnnecessaryEncodeUTF8) { - diagnostic.try_set_fix(|| { - remove_argument( - arg, - &call.arguments, - Parentheses::Preserve, - checker.locator().contents(), - ) - .map(Fix::automatic) - }); - } + diagnostic.try_set_fix(|| { + remove_argument( + arg, + &call.arguments, + Parentheses::Preserve, + checker.locator().contents(), + ) + .map(Fix::safe_edit) + }); checker.diagnostics.push(diagnostic); } } @@ -241,17 +234,15 @@ pub(crate) fn unnecessary_encode_utf8(checker: &mut Checker, call: &ast::ExprCal }, call.range(), ); - if checker.patch(Rule::UnnecessaryEncodeUTF8) { - diagnostic.try_set_fix(|| { - remove_argument( - kwarg, - &call.arguments, - Parentheses::Preserve, - checker.locator().contents(), - ) - .map(Fix::automatic) - }); - } + diagnostic.try_set_fix(|| { + remove_argument( + kwarg, + &call.arguments, + Parentheses::Preserve, + checker.locator().contents(), + ) + .map(Fix::safe_edit) + }); checker.diagnostics.push(diagnostic); } else if let EncodingArg::Positional(arg) = encoding_arg { // Ex) Convert `f"unicode text©".encode("utf-8")` to `f"unicode text©".encode()`. @@ -261,17 +252,15 @@ pub(crate) fn unnecessary_encode_utf8(checker: &mut Checker, call: &ast::ExprCal }, call.range(), ); - if checker.patch(Rule::UnnecessaryEncodeUTF8) { - diagnostic.try_set_fix(|| { - remove_argument( - arg, - &call.arguments, - Parentheses::Preserve, - checker.locator().contents(), - ) - .map(Fix::automatic) - }); - } + diagnostic.try_set_fix(|| { + remove_argument( + arg, + &call.arguments, + Parentheses::Preserve, + checker.locator().contents(), + ) + .map(Fix::safe_edit) + }); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_future_import.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_future_import.rs index 4a7a432ce1579..c713a04673d31 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_future_import.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_future_import.rs @@ -1,13 +1,12 @@ use itertools::Itertools; use ruff_python_ast::{Alias, Stmt}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; -use crate::autofix; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix; /// ## What it does /// Checks for unnecessary `__future__` imports. @@ -41,7 +40,7 @@ pub struct UnnecessaryFutureImport { pub names: Vec, } -impl AlwaysAutofixableViolation for UnnecessaryFutureImport { +impl AlwaysFixableViolation for UnnecessaryFutureImport { #[derive_message_formats] fn message(&self) -> String { let UnnecessaryFutureImport { names } = self; @@ -54,7 +53,7 @@ impl AlwaysAutofixableViolation for UnnecessaryFutureImport { } } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove unnecessary `__future__` import".to_string() } } @@ -110,25 +109,23 @@ pub(crate) fn unnecessary_future_import(checker: &mut Checker, stmt: &Stmt, name stmt.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - let statement = checker.semantic().current_statement(); - let parent = checker.semantic().current_statement_parent(); - let edit = autofix::edits::remove_unused_imports( - unused_imports - .iter() - .map(|alias| &alias.name) - .map(ruff_python_ast::Identifier::as_str), - statement, - parent, - checker.locator(), - checker.stylist(), - checker.indexer(), - )?; - Ok(Fix::suggested(edit).isolate(Checker::isolation( - checker.semantic().current_statement_parent_id(), - ))) - }); - } + diagnostic.try_set_fix(|| { + let statement = checker.semantic().current_statement(); + let parent = checker.semantic().current_statement_parent(); + let edit = fix::edits::remove_unused_imports( + unused_imports + .iter() + .map(|alias| &alias.name) + .map(ruff_python_ast::Identifier::as_str), + statement, + parent, + checker.locator(), + checker.stylist(), + checker.indexer(), + )?; + Ok(Fix::safe_edit(edit).isolate(Checker::isolation( + checker.semantic().current_statement_parent_id(), + ))) + }); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/unpacked_list_comprehension.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/unpacked_list_comprehension.rs index ab910d634a919..383b28114ec21 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/unpacked_list_comprehension.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/unpacked_list_comprehension.rs @@ -1,12 +1,11 @@ use ruff_python_ast::{self as ast, Expr}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::any_over_expr; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for list comprehensions that are immediately unpacked. @@ -32,13 +31,13 @@ use crate::registry::AsRule; #[violation] pub struct UnpackedListComprehension; -impl AlwaysAutofixableViolation for UnpackedListComprehension { +impl AlwaysFixableViolation for UnpackedListComprehension { #[derive_message_formats] fn message(&self) -> String { format!("Replace unpacked list comprehension with a generator expression") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace with generator expression".to_string() } } @@ -67,18 +66,16 @@ pub(crate) fn unpacked_list_comprehension(checker: &mut Checker, targets: &[Expr } let mut diagnostic = Diagnostic::new(UnpackedListComprehension, value.range()); - if checker.patch(diagnostic.kind.rule()) { - let existing = checker.locator().slice(value); + let existing = checker.locator().slice(value); - let mut content = String::with_capacity(existing.len()); - content.push('('); - content.push_str(&existing[1..existing.len() - 1]); - content.push(')'); - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - content, - value.range(), - ))); - } + let mut content = String::with_capacity(existing.len()); + content.push('('); + content.push_str(&existing[1..existing.len() - 1]); + content.push(')'); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + content, + value.range(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep585_annotation.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep585_annotation.rs index aaeef4bba0ffb..3b91cd6504a0b 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep585_annotation.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep585_annotation.rs @@ -1,6 +1,6 @@ use ruff_python_ast::Expr; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::call_path::compose_call_path; use ruff_python_semantic::analyze::typing::ModuleMember; @@ -8,7 +8,6 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::importer::ImportRequest; -use crate::registry::AsRule; /// ## What it does /// Checks for the use of generics that can be replaced with standard library @@ -56,7 +55,7 @@ pub struct NonPEP585Annotation { } impl Violation for NonPEP585Annotation { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -64,7 +63,7 @@ impl Violation for NonPEP585Annotation { format!("Use `{to}` instead of `{from}` for type annotation") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let NonPEP585Annotation { to, .. } = self; Some(format!("Replace with `{to}`")) } @@ -86,31 +85,29 @@ pub(crate) fn use_pep585_annotation( }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if !checker.semantic().in_complex_string_type_definition() { - match replacement { - ModuleMember::BuiltIn(name) => { - // Built-in type, like `list`. - if checker.semantic().is_builtin(name) { - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - (*name).to_string(), - expr.range(), - ))); - } - } - ModuleMember::Member(module, member) => { - // Imported type, like `collections.deque`. - diagnostic.try_set_fix(|| { - let (import_edit, binding) = checker.importer().get_or_import_symbol( - &ImportRequest::import_from(module, member), - expr.start(), - checker.semantic(), - )?; - let reference_edit = Edit::range_replacement(binding, expr.range()); - Ok(Fix::suggested_edits(import_edit, [reference_edit])) - }); + if !checker.semantic().in_complex_string_type_definition() { + match replacement { + ModuleMember::BuiltIn(name) => { + // Built-in type, like `list`. + if checker.semantic().is_builtin(name) { + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + (*name).to_string(), + expr.range(), + ))); } } + ModuleMember::Member(module, member) => { + // Imported type, like `collections.deque`. + diagnostic.try_set_fix(|| { + let (import_edit, binding) = checker.importer().get_or_import_symbol( + &ImportRequest::import_from(module, member), + expr.start(), + checker.semantic(), + )?; + let reference_edit = Edit::range_replacement(binding, expr.range()); + Ok(Fix::unsafe_edits(import_edit, [reference_edit])) + }); + } } } checker.diagnostics.push(diagnostic); diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep604_annotation.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep604_annotation.rs index c1fbbfa6cec22..3e3666d39a27f 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep604_annotation.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep604_annotation.rs @@ -1,12 +1,11 @@ -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Constant, Expr, ExprContext, Operator}; use ruff_python_semantic::analyze::typing::Pep604Operator; use ruff_text_size::{Ranged, TextRange}; -use crate::autofix::edits::pad; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix::edits::pad; /// ## What it does /// Check for type annotations that can be rewritten based on [PEP 604] syntax. @@ -45,14 +44,14 @@ use crate::registry::AsRule; pub struct NonPEP604Annotation; impl Violation for NonPEP604Annotation { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Use `X | Y` for type annotations") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Convert to `X | Y`".to_string()) } } @@ -73,13 +72,13 @@ pub(crate) fn use_pep604_annotation( match operator { Pep604Operator::Optional => { let mut diagnostic = Diagnostic::new(NonPEP604Annotation, expr.range()); - if fixable && checker.patch(diagnostic.kind.rule()) { + if fixable { match slice { Expr::Tuple(_) => { // Invalid type annotation. } _ => { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( pad( checker.generator().expr(&optional(slice)), expr.range(), @@ -94,13 +93,13 @@ pub(crate) fn use_pep604_annotation( } Pep604Operator::Union => { let mut diagnostic = Diagnostic::new(NonPEP604Annotation, expr.range()); - if fixable && checker.patch(diagnostic.kind.rule()) { + if fixable { match slice { Expr::Slice(_) => { // Invalid type annotation. } Expr::Tuple(ast::ExprTuple { elts, .. }) => { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( pad( checker.generator().expr(&union(elts)), expr.range(), @@ -111,7 +110,7 @@ pub(crate) fn use_pep604_annotation( } _ => { // Single argument. - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( pad( checker.locator().slice(slice).to_string(), expr.range(), diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep604_isinstance.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep604_isinstance.rs index 3da0483432a2b..550987f839932 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep604_isinstance.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep604_isinstance.rs @@ -1,12 +1,11 @@ use std::fmt; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Expr, Operator}; use ruff_text_size::{Ranged, TextRange}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub(crate) enum CallKind { @@ -39,9 +38,13 @@ impl CallKind { /// /// ## Why is this bad? /// Since Python 3.10, `isinstance` and `issubclass` can be passed a -/// `|`-separated union of types, which is more concise and consistent +/// `|`-separated union of types, which is consistent /// with the union operator introduced in [PEP 604]. /// +/// Note that this results in slower code. Ignore this rule if the +/// performance of an `isinstance` or `issubclass` check is a +/// concern, e.g., in a hot loop. +/// /// ## Example /// ```python /// isinstance(x, (int, float)) @@ -65,13 +68,13 @@ pub struct NonPEP604Isinstance { kind: CallKind, } -impl AlwaysAutofixableViolation for NonPEP604Isinstance { +impl AlwaysFixableViolation for NonPEP604Isinstance { #[derive_message_formats] fn message(&self) -> String { format!("Use `X | Y` in `{}` call instead of `(X, Y)`", self.kind) } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Convert to `X | Y`".to_string() } } @@ -116,12 +119,10 @@ pub(crate) fn use_pep604_isinstance( } let mut diagnostic = Diagnostic::new(NonPEP604Isinstance { kind }, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - checker.generator().expr(&union(elts)), - types.range(), - ))); - } + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + checker.generator().expr(&union(elts)), + types.range(), + ))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep695_type_alias.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep695_type_alias.rs index bd649693e8853..4e81b2e961deb 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep695_type_alias.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/use_pep695_type_alias.rs @@ -1,5 +1,5 @@ use ast::{Constant, ExprCall, ExprConstant}; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{ self as ast, @@ -11,7 +11,7 @@ use ruff_python_semantic::SemanticModel; use ruff_text_size::{Ranged, TextRange}; use crate::checkers::ast::Checker; -use crate::{registry::AsRule, settings::types::PythonVersion}; +use crate::settings::types::PythonVersion; /// ## What it does /// Checks for use of `TypeAlias` annotation for declaring type aliases. @@ -49,7 +49,7 @@ pub struct NonPEP695TypeAlias { } impl Violation for NonPEP695TypeAlias { - const AUTOFIX: AutofixKind = AutofixKind::Always; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Always; #[derive_message_formats] fn message(&self) -> String { @@ -57,7 +57,7 @@ impl Violation for NonPEP695TypeAlias { format!("Type alias `{name}` uses `TypeAlias` annotation instead of the `type` keyword") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Use the `type` keyword".to_string()) } } @@ -94,54 +94,60 @@ pub(crate) fn non_pep695_type_alias(checker: &mut Checker, stmt: &StmtAnnAssign) // TODO(zanie): We should check for generic type variables used in the value and define them // as type params instead let mut diagnostic = Diagnostic::new(NonPEP695TypeAlias { name: name.clone() }, stmt.range()); - if checker.patch(diagnostic.kind.rule()) { - let mut visitor = TypeVarReferenceVisitor { - vars: vec![], - semantic: checker.semantic(), - }; - visitor.visit_expr(value); - - let type_params = if visitor.vars.is_empty() { - None - } else { - Some(ast::TypeParams { - range: TextRange::default(), - type_params: visitor - .vars - .into_iter() - .map(|TypeVar { name, restriction }| { - TypeParam::TypeVar(TypeParamTypeVar { - range: TextRange::default(), - name: Identifier::new(name.id.clone(), TextRange::default()), - bound: match restriction { - Some(TypeVarRestriction::Bound(bound)) => { - Some(Box::new(bound.clone())) - } - Some(TypeVarRestriction::Constraint(constraints)) => { - Some(Box::new(Expr::Tuple(ast::ExprTuple { - range: TextRange::default(), - elts: constraints.into_iter().cloned().collect(), - ctx: ast::ExprContext::Load, - }))) - } - None => None, - }, - }) + let mut visitor = TypeVarReferenceVisitor { + vars: vec![], + semantic: checker.semantic(), + }; + visitor.visit_expr(value); + + let type_params = if visitor.vars.is_empty() { + None + } else { + Some(ast::TypeParams { + range: TextRange::default(), + type_params: visitor + .vars + .into_iter() + .map(|TypeVar { name, restriction }| { + TypeParam::TypeVar(TypeParamTypeVar { + range: TextRange::default(), + name: Identifier::new(name.id.clone(), TextRange::default()), + bound: match restriction { + Some(TypeVarRestriction::Bound(bound)) => Some(Box::new(bound.clone())), + Some(TypeVarRestriction::Constraint(constraints)) => { + Some(Box::new(Expr::Tuple(ast::ExprTuple { + range: TextRange::default(), + elts: constraints.into_iter().cloned().collect(), + ctx: ast::ExprContext::Load, + }))) + } + None => None, + }, }) - .collect(), - }) - }; - - diagnostic.set_fix(Fix::automatic(Edit::range_replacement( - checker.generator().stmt(&Stmt::from(StmtTypeAlias { - range: TextRange::default(), - name: target.clone(), - type_params, - value: value.clone(), - })), - stmt.range(), - ))); - } + }) + .collect(), + }) + }; + + let edit = Edit::range_replacement( + checker.generator().stmt(&Stmt::from(StmtTypeAlias { + range: TextRange::default(), + name: target.clone(), + type_params, + value: value.clone(), + })), + stmt.range(), + ); + + // The fix is only safe in a type stub because new-style aliases have different runtime behavior + // See https://github.com/astral-sh/ruff/issues/6434 + let fix = if checker.source_type.is_stub() { + Fix::safe_edit(edit) + } else { + Fix::unsafe_edit(edit) + }; + + diagnostic.set_fix(fix); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/useless_metaclass_type.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/useless_metaclass_type.rs index f089ae91ab4df..612c94644cd8a 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/useless_metaclass_type.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/useless_metaclass_type.rs @@ -1,12 +1,11 @@ use ruff_python_ast::{self as ast, Expr, Stmt}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_text_size::Ranged; -use crate::autofix; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix; /// ## What it does /// Checks for the use of `__metaclass__ = type` in class definitions. @@ -31,13 +30,13 @@ use crate::registry::AsRule; #[violation] pub struct UselessMetaclassType; -impl AlwaysAutofixableViolation for UselessMetaclassType { +impl AlwaysFixableViolation for UselessMetaclassType { #[derive_message_formats] fn message(&self) -> String { format!("`__metaclass__ = type` is implied") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove `__metaclass__ = type`".to_string() } } @@ -63,13 +62,11 @@ pub(crate) fn useless_metaclass_type( } let mut diagnostic = Diagnostic::new(UselessMetaclassType, stmt.range()); - if checker.patch(diagnostic.kind.rule()) { - let stmt = checker.semantic().current_statement(); - let parent = checker.semantic().current_statement_parent(); - let edit = autofix::edits::delete_stmt(stmt, parent, checker.locator(), checker.indexer()); - diagnostic.set_fix(Fix::automatic(edit).isolate(Checker::isolation( - checker.semantic().current_statement_parent_id(), - ))); - } + let stmt = checker.semantic().current_statement(); + let parent = checker.semantic().current_statement_parent(); + let edit = fix::edits::delete_stmt(stmt, parent, checker.locator(), checker.indexer()); + diagnostic.set_fix(Fix::safe_edit(edit).isolate(Checker::isolation( + checker.semantic().current_statement_parent_id(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/useless_object_inheritance.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/useless_object_inheritance.rs index a3a6093deed08..83f9a417e8c6c 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/useless_object_inheritance.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/useless_object_inheritance.rs @@ -1,11 +1,10 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Expr}; use ruff_text_size::Ranged; -use crate::autofix::edits::{remove_argument, Parentheses}; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix::edits::{remove_argument, Parentheses}; /// ## What it does /// Checks for classes that inherit from `object`. @@ -33,14 +32,14 @@ pub struct UselessObjectInheritance { name: String, } -impl AlwaysAutofixableViolation for UselessObjectInheritance { +impl AlwaysFixableViolation for UselessObjectInheritance { #[derive_message_formats] fn message(&self) -> String { let UselessObjectInheritance { name } = self; format!("Class `{name}` inherits from `object`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove `object` inheritance".to_string() } } @@ -68,17 +67,15 @@ pub(crate) fn useless_object_inheritance(checker: &mut Checker, class_def: &ast: }, base.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - remove_argument( - base, - arguments, - Parentheses::Remove, - checker.locator().contents(), - ) - .map(Fix::automatic) - }); - } + diagnostic.try_set_fix(|| { + remove_argument( + base, + arguments, + Parentheses::Remove, + checker.locator().contents(), + ) + .map(Fix::safe_edit) + }); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/yield_in_for_loop.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/yield_in_for_loop.rs index c9558966e5b42..6325cc9fd2b2f 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/yield_in_for_loop.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/yield_in_for_loop.rs @@ -1,11 +1,10 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::parenthesize::parenthesized_range; use ruff_python_ast::{self as ast, Expr, Stmt}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for `for` loops that can be replaced with `yield from` expressions. @@ -31,13 +30,13 @@ use crate::registry::AsRule; #[violation] pub struct YieldInForLoop; -impl AlwaysAutofixableViolation for YieldInForLoop { +impl AlwaysFixableViolation for YieldInForLoop { #[derive_message_formats] fn message(&self) -> String { format!("Replace `yield` over `for` loop with `yield from`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace with `yield from`".to_string() } } @@ -103,22 +102,20 @@ pub(crate) fn yield_in_for_loop(checker: &mut Checker, stmt_for: &ast::StmtFor) } let mut diagnostic = Diagnostic::new(YieldInForLoop, stmt_for.range()); - if checker.patch(diagnostic.kind.rule()) { - let contents = checker.locator().slice( - parenthesized_range( - iter.as_ref().into(), - stmt_for.into(), - checker.indexer().comment_ranges(), - checker.locator().contents(), - ) - .unwrap_or(iter.range()), - ); - let contents = format!("yield from {contents}"); - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - contents, - stmt_for.range(), - ))); - } + let contents = checker.locator().slice( + parenthesized_range( + iter.as_ref().into(), + stmt_for.into(), + checker.indexer().comment_ranges(), + checker.locator().contents(), + ) + .unwrap_or(iter.range()), + ); + let contents = format!("yield from {contents}"); + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + contents, + stmt_for.range(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP005.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP005.py.snap index eb262e352161d..bd754f91c77e8 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP005.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP005.py.snap @@ -12,7 +12,7 @@ UP005.py:6:9: UP005 [*] `assertEquals` is deprecated, use `assertEqual` | = help: Replace `assertEqual` with `assertEquals` -ℹ Suggested fix +ℹ Fix 3 3 | 4 4 | class Suite(unittest.TestCase): 5 5 | def test(self) -> None: @@ -33,7 +33,7 @@ UP005.py:7:9: UP005 [*] `assertEquals` is deprecated, use `assertEqual` | = help: Replace `assertEqual` with `assertEquals` -ℹ Suggested fix +ℹ Fix 4 4 | class Suite(unittest.TestCase): 5 5 | def test(self) -> None: 6 6 | self.assertEquals (1, 2) @@ -53,7 +53,7 @@ UP005.py:9:9: UP005 [*] `failUnlessAlmostEqual` is deprecated, use `assertAlmost | = help: Replace `assertAlmostEqual` with `failUnlessAlmostEqual` -ℹ Suggested fix +ℹ Fix 6 6 | self.assertEquals (1, 2) 7 7 | self.assertEquals(1, 2) 8 8 | self.assertEqual(3, 4) @@ -70,7 +70,7 @@ UP005.py:10:9: UP005 [*] `assertNotRegexpMatches` is deprecated, use `assertNotR | = help: Replace `assertNotRegex` with `assertNotRegexpMatches` -ℹ Suggested fix +ℹ Fix 7 7 | self.assertEquals(1, 2) 8 8 | self.assertEqual(3, 4) 9 9 | self.failUnlessAlmostEqual(1, 1.1) diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP010.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP010.py.snap index e6ec10b65009f..550b7a024b8bb 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP010.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP010.py.snap @@ -10,7 +10,7 @@ UP010.py:1:1: UP010 [*] Unnecessary `__future__` imports `generators`, `nested_s | = help: Remove unnecessary `future` import -ℹ Suggested fix +ℹ Fix 1 |-from __future__ import nested_scopes, generators 2 1 | from __future__ import with_statement, unicode_literals 3 2 | from __future__ import absolute_import, division @@ -26,7 +26,7 @@ UP010.py:2:1: UP010 [*] Unnecessary `__future__` imports `unicode_literals`, `wi | = help: Remove unnecessary `future` import -ℹ Suggested fix +ℹ Fix 1 1 | from __future__ import nested_scopes, generators 2 |-from __future__ import with_statement, unicode_literals 3 2 | from __future__ import absolute_import, division @@ -44,7 +44,7 @@ UP010.py:3:1: UP010 [*] Unnecessary `__future__` imports `absolute_import`, `div | = help: Remove unnecessary `future` import -ℹ Suggested fix +ℹ Fix 1 1 | from __future__ import nested_scopes, generators 2 2 | from __future__ import with_statement, unicode_literals 3 |-from __future__ import absolute_import, division @@ -63,7 +63,7 @@ UP010.py:4:1: UP010 [*] Unnecessary `__future__` import `generator_stop` for tar | = help: Remove unnecessary `future` import -ℹ Suggested fix +ℹ Fix 1 1 | from __future__ import nested_scopes, generators 2 2 | from __future__ import with_statement, unicode_literals 3 3 | from __future__ import absolute_import, division @@ -82,7 +82,7 @@ UP010.py:5:1: UP010 [*] Unnecessary `__future__` imports `generator_stop`, `prin | = help: Remove unnecessary `future` import -ℹ Suggested fix +ℹ Fix 2 2 | from __future__ import with_statement, unicode_literals 3 3 | from __future__ import absolute_import, division 4 4 | from __future__ import generator_stop @@ -102,7 +102,7 @@ UP010.py:6:1: UP010 [*] Unnecessary `__future__` import `generators` for target | = help: Remove unnecessary `future` import -ℹ Suggested fix +ℹ Fix 3 3 | from __future__ import absolute_import, division 4 4 | from __future__ import generator_stop 5 5 | from __future__ import print_function, generator_stop @@ -121,7 +121,7 @@ UP010.py:9:5: UP010 [*] Unnecessary `__future__` import `generator_stop` for tar | = help: Remove unnecessary `future` import -ℹ Suggested fix +ℹ Fix 6 6 | from __future__ import invalid_module, generators 7 7 | 8 8 | if True: @@ -141,7 +141,7 @@ UP010.py:10:5: UP010 [*] Unnecessary `__future__` import `generators` for target | = help: Remove unnecessary `future` import -ℹ Suggested fix +ℹ Fix 7 7 | 8 8 | if True: 9 9 | from __future__ import generator_stop @@ -159,7 +159,7 @@ UP010.py:13:5: UP010 [*] Unnecessary `__future__` import `generator_stop` for ta | = help: Remove unnecessary `future` import -ℹ Suggested fix +ℹ Fix 10 10 | from __future__ import generators 11 11 | 12 12 | if True: @@ -175,7 +175,7 @@ UP010.py:14:5: UP010 [*] Unnecessary `__future__` import `generators` for target | = help: Remove unnecessary `future` import -ℹ Suggested fix +ℹ Fix 11 11 | 12 12 | if True: 13 13 | from __future__ import generator_stop diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP013.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP013.py.snap index 7f6103fcdb116..d7a6da069656f 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP013.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP013.py.snap @@ -11,7 +11,7 @@ UP013.py:5:1: UP013 [*] Convert `MyType` from `TypedDict` functional to class sy | = help: Convert `MyType` to class syntax -ℹ Suggested fix +ℹ Fix 2 2 | import typing 3 3 | 4 4 | # dict literal @@ -33,7 +33,7 @@ UP013.py:8:1: UP013 [*] Convert `MyType` from `TypedDict` functional to class sy | = help: Convert `MyType` to class syntax -ℹ Suggested fix +ℹ Fix 5 5 | MyType = TypedDict("MyType", {"a": int, "b": str}) 6 6 | 7 7 | # dict call @@ -55,7 +55,7 @@ UP013.py:11:1: UP013 [*] Convert `MyType` from `TypedDict` functional to class s | = help: Convert `MyType` to class syntax -ℹ Suggested fix +ℹ Fix 8 8 | MyType = TypedDict("MyType", dict(a=int, b=str)) 9 9 | 10 10 | # kwargs @@ -77,7 +77,7 @@ UP013.py:14:1: UP013 [*] Convert `MyType` from `TypedDict` functional to class s | = help: Convert `MyType` to class syntax -ℹ Suggested fix +ℹ Fix 11 11 | MyType = TypedDict("MyType", a=int, b=str) 12 12 | 13 13 | # Empty TypedDict @@ -97,7 +97,7 @@ UP013.py:17:1: UP013 [*] Convert `MyType` from `TypedDict` functional to class s | = help: Convert `MyType` to class syntax -ℹ Suggested fix +ℹ Fix 14 14 | MyType = TypedDict("MyType") 15 15 | 16 16 | # Literal values @@ -119,7 +119,7 @@ UP013.py:18:1: UP013 [*] Convert `MyType` from `TypedDict` functional to class s | = help: Convert `MyType` to class syntax -ℹ Suggested fix +ℹ Fix 15 15 | 16 16 | # Literal values 17 17 | MyType = TypedDict("MyType", {"a": "hello"}) @@ -140,7 +140,7 @@ UP013.py:21:1: UP013 [*] Convert `MyType` from `TypedDict` functional to class s | = help: Convert `MyType` to class syntax -ℹ Suggested fix +ℹ Fix 18 18 | MyType = TypedDict("MyType", a="hello") 19 19 | 20 20 | # NotRequired @@ -161,7 +161,7 @@ UP013.py:24:1: UP013 [*] Convert `MyType` from `TypedDict` functional to class s | = help: Convert `MyType` to class syntax -ℹ Suggested fix +ℹ Fix 21 21 | MyType = TypedDict("MyType", {"a": NotRequired[dict]}) 22 22 | 23 23 | # total @@ -183,7 +183,7 @@ UP013.py:27:1: UP013 [*] Convert `MyType` from `TypedDict` functional to class s | = help: Convert `MyType` to class syntax -ℹ Suggested fix +ℹ Fix 24 24 | MyType = TypedDict("MyType", {"x": int, "y": int}, total=False) 25 25 | 26 26 | # using Literal type @@ -204,7 +204,7 @@ UP013.py:30:1: UP013 [*] Convert `MyType` from `TypedDict` functional to class s | = help: Convert `MyType` to class syntax -ℹ Suggested fix +ℹ Fix 27 27 | MyType = TypedDict("MyType", {"key": Literal["value"]}) 28 28 | 29 29 | # using namespace TypedDict @@ -225,7 +225,7 @@ UP013.py:40:1: UP013 [*] Convert `MyType` from `TypedDict` functional to class s | = help: Convert `MyType` to class syntax -ℹ Suggested fix +ℹ Fix 37 37 | MyType = TypedDict("MyType", {"a": int, "b": str, **c}) 38 38 | 39 39 | # Empty dict literal @@ -244,7 +244,7 @@ UP013.py:43:1: UP013 [*] Convert `MyType` from `TypedDict` functional to class s | = help: Convert `MyType` to class syntax -ℹ Suggested fix +ℹ Fix 40 40 | MyType = TypedDict("MyType", {}) 41 41 | 42 42 | # Empty dict call diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP014.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP014.py.snap index f7e9dd895e627..a65fcacbad104 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP014.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP014.py.snap @@ -11,7 +11,7 @@ UP014.py:5:1: UP014 [*] Convert `MyType` from `NamedTuple` functional to class s | = help: Convert `MyType` to class syntax -ℹ Suggested fix +ℹ Fix 2 2 | import typing 3 3 | 4 4 | # with complex annotations @@ -33,7 +33,7 @@ UP014.py:8:1: UP014 [*] Convert `MyType` from `NamedTuple` functional to class s | = help: Convert `MyType` to class syntax -ℹ Suggested fix +ℹ Fix 5 5 | MyType = NamedTuple("MyType", [("a", int), ("b", tuple[str, ...])]) 6 6 | 7 7 | # with namespace @@ -55,7 +55,7 @@ UP014.py:14:1: UP014 [*] Convert `MyType` from `NamedTuple` functional to class | = help: Convert `MyType` to class syntax -ℹ Suggested fix +ℹ Fix 11 11 | MyType = NamedTuple("MyType", [("x-y", int), ("b", tuple[str, ...])]) 12 12 | 13 13 | # no fields @@ -76,7 +76,7 @@ UP014.py:17:1: UP014 [*] Convert `MyType` from `NamedTuple` functional to class | = help: Convert `MyType` to class syntax -ℹ Suggested fix +ℹ Fix 14 14 | MyType = typing.NamedTuple("MyType") 15 15 | 16 16 | # empty fields @@ -97,7 +97,7 @@ UP014.py:20:1: UP014 [*] Convert `MyType` from `NamedTuple` functional to class | = help: Convert `MyType` to class syntax -ℹ Suggested fix +ℹ Fix 17 17 | MyType = typing.NamedTuple("MyType", []) 18 18 | 19 19 | # keywords diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP015.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP015.py.snap index ad12951ee80af..44722257a9522 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP015.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP015.py.snap @@ -733,16 +733,16 @@ UP015.py:59:6: UP015 [*] Unnecessary open mode parameters, use ""rb"" 59 |+with open(mode="rb", name="foo") as f: 60 60 | pass 61 61 | -62 62 | open(file="foo", mode='U', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +62 62 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) UP015.py:62:1: UP015 [*] Unnecessary open mode parameters | 60 | pass 61 | -62 | open(file="foo", mode='U', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 -63 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') -64 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) +62 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +63 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') +64 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) | = help: Remove open mode parameters @@ -750,151 +750,151 @@ UP015.py:62:1: UP015 [*] Unnecessary open mode parameters 59 59 | with open(mode="Ub", name="foo") as f: 60 60 | pass 61 61 | -62 |-open(file="foo", mode='U', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) - 62 |+open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -63 63 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') -64 64 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) -65 65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +62 |-open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + 62 |+open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +63 63 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') +64 64 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) +65 65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) UP015.py:63:1: UP015 [*] Unnecessary open mode parameters | -62 | open(file="foo", mode='U', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -63 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 -64 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) -65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +62 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +63 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +64 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) +65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) | = help: Remove open mode parameters ℹ Fix 60 60 | pass 61 61 | -62 62 | open(file="foo", mode='U', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -63 |-open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') - 63 |+open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -64 64 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) -65 65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +62 62 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +63 |-open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') + 63 |+open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +64 64 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) +65 65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 66 66 | UP015.py:64:1: UP015 [*] Unnecessary open mode parameters | -62 | open(file="foo", mode='U', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -63 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') -64 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 -65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +62 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +63 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') +64 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) | = help: Remove open mode parameters ℹ Fix 61 61 | -62 62 | open(file="foo", mode='U', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -63 63 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') -64 |-open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) - 64 |+open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -65 65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +62 62 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +63 63 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') +64 |-open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) + 64 |+open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +65 65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 66 66 | -67 67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +67 67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) UP015.py:65:1: UP015 [*] Unnecessary open mode parameters | -63 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') -64 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) -65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +63 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') +64 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) +65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 66 | -67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) | = help: Remove open mode parameters ℹ Fix -62 62 | open(file="foo", mode='U', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -63 63 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') -64 64 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) -65 |-open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) - 65 |+open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +62 62 | open(file="foo", mode='U', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +63 63 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='U') +64 64 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) +65 |-open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + 65 |+open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 66 66 | -67 67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -68 68 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') +67 67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +68 68 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') UP015.py:67:1: UP015 [*] Unnecessary open mode parameters, use ""rb"" | -65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 66 | -67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 -68 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') -69 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) +67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +68 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') +69 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) | = help: Replace with ""rb"" ℹ Fix -64 64 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) -65 65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +64 64 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='U', newline=None, closefd=True, opener=None) +65 65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 66 66 | -67 |-open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) - 67 |+open(file="foo", mode="rb", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -68 68 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') -69 69 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) -70 70 | open(mode='Ub', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +67 |-open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + 67 |+open(file="foo", mode="rb", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +68 68 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') +69 69 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) +70 70 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) UP015.py:68:1: UP015 [*] Unnecessary open mode parameters, use ""rb"" | -67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -68 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 -69 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) -70 | open(mode='Ub', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +68 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +69 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) +70 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) | = help: Replace with ""rb"" ℹ Fix -65 65 | open(mode='U', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +65 65 | open(mode='U', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 66 66 | -67 67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -68 |-open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') - 68 |+open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode="rb") -69 69 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) -70 70 | open(mode='Ub', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +67 67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +68 |-open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') + 68 |+open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode="rb") +69 69 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) +70 70 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 71 71 | UP015.py:69:1: UP015 [*] Unnecessary open mode parameters, use ""rb"" | -67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -68 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') -69 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 -70 | open(mode='Ub', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +68 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') +69 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +70 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) | = help: Replace with ""rb"" ℹ Fix 66 66 | -67 67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -68 68 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') -69 |-open(file="foo", buffering=- 1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) - 69 |+open(file="foo", buffering=- 1, encoding=None, errors=None, mode="rb", newline=None, closefd=True, opener=None) -70 70 | open(mode='Ub', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +67 67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +68 68 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') +69 |-open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) + 69 |+open(file="foo", buffering=-1, encoding=None, errors=None, mode="rb", newline=None, closefd=True, opener=None) +70 70 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 71 71 | 72 72 | open = 1 UP015.py:70:1: UP015 [*] Unnecessary open mode parameters, use ""rb"" | -68 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') -69 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) -70 | open(mode='Ub', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +68 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') +69 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) +70 | open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 71 | 72 | open = 1 | = help: Replace with ""rb"" ℹ Fix -67 67 | open(file="foo", mode='Ub', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -68 68 | open(file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') -69 69 | open(file="foo", buffering=- 1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) -70 |-open(mode='Ub', file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) - 70 |+open(mode="rb", file="foo", buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +67 67 | open(file="foo", mode='Ub', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) +68 68 | open(file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None, mode='Ub') +69 69 | open(file="foo", buffering=-1, encoding=None, errors=None, mode='Ub', newline=None, closefd=True, opener=None) +70 |-open(mode='Ub', file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) + 70 |+open(mode="rb", file="foo", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 71 71 | 72 72 | open = 1 73 73 | open("foo", "U") diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP018.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP018.py.snap index a43a4e9b9f22d..cdd56ab5c14e8 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP018.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP018.py.snap @@ -9,7 +9,7 @@ UP018.py:37:1: UP018 [*] Unnecessary `str` call (rewrite as a literal) 38 | str("foo") 39 | str(""" | - = help: Replace with empty string + = help: Replace with string literal ℹ Fix 34 34 | int().denominator @@ -30,7 +30,7 @@ UP018.py:38:1: UP018 [*] Unnecessary `str` call (rewrite as a literal) 39 | str(""" 40 | foo""") | - = help: Replace with empty string + = help: Replace with string literal ℹ Fix 35 35 | @@ -52,7 +52,7 @@ UP018.py:39:1: UP018 [*] Unnecessary `str` call (rewrite as a literal) 41 | bytes() 42 | bytes(b"foo") | - = help: Replace with empty string + = help: Replace with string literal ℹ Fix 36 36 | # These become string or byte literals @@ -75,7 +75,7 @@ UP018.py:41:1: UP018 [*] Unnecessary `bytes` call (rewrite as a literal) 42 | bytes(b"foo") 43 | bytes(b""" | - = help: Replace with empty bytes + = help: Replace with bytes literal ℹ Fix 38 38 | str("foo") @@ -96,7 +96,7 @@ UP018.py:42:1: UP018 [*] Unnecessary `bytes` call (rewrite as a literal) 43 | bytes(b""" 44 | foo""") | - = help: Replace with empty bytes + = help: Replace with bytes literal ℹ Fix 39 39 | str(""" @@ -118,7 +118,7 @@ UP018.py:43:1: UP018 [*] Unnecessary `bytes` call (rewrite as a literal) 45 | f"{str()}" 46 | int() | - = help: Replace with empty bytes + = help: Replace with bytes literal ℹ Fix 40 40 | foo""") @@ -141,7 +141,7 @@ UP018.py:45:4: UP018 [*] Unnecessary `str` call (rewrite as a literal) 46 | int() 47 | int(1) | - = help: Replace with empty string + = help: Replace with string literal ℹ Fix 42 42 | bytes(b"foo") @@ -162,7 +162,7 @@ UP018.py:46:1: UP018 [*] Unnecessary `int` call (rewrite as a literal) 47 | int(1) 48 | float() | - = help: Replace with 0 + = help: Replace with integer literal ℹ Fix 43 43 | bytes(b""" @@ -183,7 +183,7 @@ UP018.py:47:1: UP018 [*] Unnecessary `int` call (rewrite as a literal) 48 | float() 49 | float(1.0) | - = help: Replace with 0 + = help: Replace with integer literal ℹ Fix 44 44 | foo""") @@ -204,7 +204,7 @@ UP018.py:48:1: UP018 [*] Unnecessary `float` call (rewrite as a literal) 49 | float(1.0) 50 | bool() | - = help: Replace with 0.0 + = help: Replace with float literal ℹ Fix 45 45 | f"{str()}" @@ -225,7 +225,7 @@ UP018.py:49:1: UP018 [*] Unnecessary `float` call (rewrite as a literal) 50 | bool() 51 | bool(True) | - = help: Replace with 0.0 + = help: Replace with float literal ℹ Fix 46 46 | int() @@ -246,7 +246,7 @@ UP018.py:50:1: UP018 [*] Unnecessary `bool` call (rewrite as a literal) 51 | bool(True) 52 | bool(False) | - = help: Replace with `False` + = help: Replace with boolean literal ℹ Fix 47 47 | int(1) @@ -266,7 +266,7 @@ UP018.py:51:1: UP018 [*] Unnecessary `bool` call (rewrite as a literal) | ^^^^^^^^^^ UP018 52 | bool(False) | - = help: Replace with `False` + = help: Replace with boolean literal ℹ Fix 48 48 | float() @@ -287,7 +287,7 @@ UP018.py:52:1: UP018 [*] Unnecessary `bool` call (rewrite as a literal) 53 | 54 | # These become a literal but retain parentheses | - = help: Replace with `False` + = help: Replace with boolean literal ℹ Fix 49 49 | float(1.0) @@ -305,7 +305,7 @@ UP018.py:55:1: UP018 [*] Unnecessary `int` call (rewrite as a literal) 55 | int(1).denominator | ^^^^^^ UP018 | - = help: Replace with 0 + = help: Replace with integer literal ℹ Fix 52 52 | bool(False) diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP020.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP020.py.snap index 6638a8cc904a7..af6064528b3f9 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP020.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP020.py.snap @@ -11,7 +11,7 @@ UP020.py:3:6: UP020 [*] Use builtin `open` | = help: Replace with builtin `open` -ℹ Suggested fix +ℹ Fix 1 1 | import io 2 2 | 3 |-with io.open("f.txt", mode="r", buffering=-1, **kwargs) as f: diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP021.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP021.py.snap index 484e53f1d84aa..4b22f871e8e15 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP021.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP021.py.snap @@ -11,7 +11,7 @@ UP021.py:5:25: UP021 [*] `universal_newlines` is deprecated, use `text` | = help: Replace with `text` keyword argument -ℹ Suggested fix +ℹ Fix 2 2 | from subprocess import run 3 3 | 4 4 | # Errors @@ -31,7 +31,7 @@ UP021.py:6:25: UP021 [*] `universal_newlines` is deprecated, use `text` | = help: Replace with `text` keyword argument -ℹ Suggested fix +ℹ Fix 3 3 | 4 4 | # Errors 5 5 | subprocess.run(["foo"], universal_newlines=True, check=True) @@ -52,7 +52,7 @@ UP021.py:7:14: UP021 [*] `universal_newlines` is deprecated, use `text` | = help: Replace with `text` keyword argument -ℹ Suggested fix +ℹ Fix 4 4 | # Errors 5 5 | subprocess.run(["foo"], universal_newlines=True, check=True) 6 6 | subprocess.run(["foo"], universal_newlines=True, text=True) diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP023.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP023.py.snap index 6944c7925b175..3fa00d5ac3949 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP023.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP023.py.snap @@ -10,7 +10,7 @@ UP023.py:2:1: UP023 [*] `cElementTree` is deprecated, use `ElementTree` | = help: Replace with `ElementTree` -ℹ Suggested fix +ℹ Fix 1 1 | # These two imports have something after cElementTree, so they should be fixed. 2 |-from xml.etree.cElementTree import XML, Element, SubElement 2 |+from xml.etree.ElementTree import XML, Element, SubElement @@ -29,7 +29,7 @@ UP023.py:3:8: UP023 [*] `cElementTree` is deprecated, use `ElementTree` | = help: Replace with `ElementTree` -ℹ Suggested fix +ℹ Fix 1 1 | # These two imports have something after cElementTree, so they should be fixed. 2 2 | from xml.etree.cElementTree import XML, Element, SubElement 3 |-import xml.etree.cElementTree as ET @@ -47,7 +47,7 @@ UP023.py:6:1: UP023 [*] `cElementTree` is deprecated, use `ElementTree` | = help: Replace with `ElementTree` -ℹ Suggested fix +ℹ Fix 3 3 | import xml.etree.cElementTree as ET 4 4 | 5 5 | # Weird spacing should not cause issues. @@ -68,7 +68,7 @@ UP023.py:7:11: UP023 [*] `cElementTree` is deprecated, use `ElementTree` | = help: Replace with `ElementTree` -ℹ Suggested fix +ℹ Fix 4 4 | 5 5 | # Weird spacing should not cause issues. 6 6 | from xml.etree.cElementTree import XML @@ -92,7 +92,7 @@ UP023.py:10:1: UP023 [*] `cElementTree` is deprecated, use `ElementTree` | = help: Replace with `ElementTree` -ℹ Suggested fix +ℹ Fix 7 7 | import xml.etree.cElementTree as ET 8 8 | 9 9 | # Multi line imports should also work fine. @@ -112,7 +112,7 @@ UP023.py:16:12: UP023 [*] `cElementTree` is deprecated, use `ElementTree` | = help: Replace with `ElementTree` -ℹ Suggested fix +ℹ Fix 13 13 | SubElement, 14 14 | ) 15 15 | if True: @@ -133,7 +133,7 @@ UP023.py:17:27: UP023 [*] `cElementTree` is deprecated, use `ElementTree` | = help: Replace with `ElementTree` -ℹ Suggested fix +ℹ Fix 14 14 | ) 15 15 | if True: 16 16 | import xml.etree.cElementTree as ET @@ -154,7 +154,7 @@ UP023.py:19:23: UP023 [*] `cElementTree` is deprecated, use `ElementTree` | = help: Replace with `ElementTree` -ℹ Suggested fix +ℹ Fix 16 16 | import xml.etree.cElementTree as ET 17 17 | from xml.etree import cElementTree as CET 18 18 | @@ -175,7 +175,7 @@ UP023.py:21:20: UP023 [*] `cElementTree` is deprecated, use `ElementTree` | = help: Replace with `ElementTree` -ℹ Suggested fix +ℹ Fix 18 18 | 19 19 | from xml.etree import cElementTree as ET 20 20 | @@ -195,7 +195,7 @@ UP023.py:24:32: UP023 [*] `cElementTree` is deprecated, use `ElementTree` | = help: Replace with `ElementTree` -ℹ Suggested fix +ℹ Fix 21 21 | import contextlib, xml.etree.cElementTree as ET 22 22 | 23 23 | # This should fix the second, but not the first invocation. diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP026.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP026.py.snap index fb8ecac7ec0a9..ea0077ed90226 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP026.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP026.py.snap @@ -12,7 +12,7 @@ UP026.py:3:12: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 1 1 | # Error (`from unittest import mock`) 2 2 | if True: 3 |- import mock @@ -32,7 +32,7 @@ UP026.py:7:12: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 4 4 | 5 5 | # Error (`from unittest import mock`) 6 6 | if True: @@ -54,7 +54,7 @@ UP026.py:11:5: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 8 8 | 9 9 | # Error (`from unittest.mock import *`) 10 10 | if True: @@ -74,7 +74,7 @@ UP026.py:14:8: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 11 11 | from mock import * 12 12 | 13 13 | # Error (`from unittest import mock`) @@ -94,7 +94,7 @@ UP026.py:17:20: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 14 14 | import mock.mock 15 15 | 16 16 | # Error (`from unittest import mock`) @@ -114,7 +114,7 @@ UP026.py:20:8: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 17 17 | import contextlib, mock, sys 18 18 | 19 19 | # Error (`from unittest import mock`) @@ -135,7 +135,7 @@ UP026.py:24:1: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 21 21 | x = "This code should be preserved one line below the mock" 22 22 | 23 23 | # Error (`from unittest import mock`) @@ -160,7 +160,7 @@ UP026.py:27:1: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 24 24 | from mock import mock 25 25 | 26 26 | # Error (keep trailing comma) @@ -192,7 +192,7 @@ UP026.py:33:1: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 30 30 | b, 31 31 | c, 32 32 | ) @@ -223,7 +223,7 @@ UP026.py:41:1: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 38 38 | ) 39 39 | 40 40 | # Error (avoid trailing comma) @@ -255,7 +255,7 @@ UP026.py:47:1: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 44 44 | b, 45 45 | c 46 46 | ) @@ -282,7 +282,7 @@ UP026.py:53:1: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 50 50 | c, 51 51 | mock 52 52 | ) @@ -304,7 +304,7 @@ UP026.py:54:1: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 51 51 | mock 52 52 | ) 53 53 | from mock import mock, a, b, c @@ -332,7 +332,7 @@ UP026.py:58:9: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 55 55 | 56 56 | if True: 57 57 | if False: @@ -358,7 +358,7 @@ UP026.py:69:8: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 66 66 | import os, io 67 67 | 68 68 | # Error (`from unittest import mock`) @@ -379,7 +379,7 @@ UP026.py:69:14: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 66 66 | import os, io 67 67 | 68 68 | # Error (`from unittest import mock`) @@ -400,7 +400,7 @@ UP026.py:72:8: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 69 69 | import mock, mock 70 70 | 71 71 | # Error (`from unittest import mock as foo`) @@ -420,7 +420,7 @@ UP026.py:75:1: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 72 72 | import mock as foo 73 73 | 74 74 | # Error (`from unittest import mock as foo`) @@ -441,7 +441,7 @@ UP026.py:79:12: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 76 76 | 77 77 | if True: 78 78 | # This should yield multiple, aliased imports. @@ -464,7 +464,7 @@ UP026.py:79:25: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 76 76 | 77 77 | if True: 78 78 | # This should yield multiple, aliased imports. @@ -487,7 +487,7 @@ UP026.py:79:38: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 76 76 | 77 77 | if True: 78 78 | # This should yield multiple, aliased imports. @@ -509,7 +509,7 @@ UP026.py:82:12: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 79 79 | import mock as foo, mock as bar, mock 80 80 | 81 81 | # This should yield multiple, aliased imports, and preserve `os`. @@ -532,7 +532,7 @@ UP026.py:82:25: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 79 79 | import mock as foo, mock as bar, mock 80 80 | 81 81 | # This should yield multiple, aliased imports, and preserve `os`. @@ -555,7 +555,7 @@ UP026.py:82:38: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 79 79 | import mock as foo, mock as bar, mock 80 80 | 81 81 | # This should yield multiple, aliased imports, and preserve `os`. @@ -577,7 +577,7 @@ UP026.py:86:5: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Import from `unittest.mock` instead -ℹ Suggested fix +ℹ Fix 83 83 | 84 84 | if True: 85 85 | # This should yield multiple, aliased imports. @@ -597,7 +597,7 @@ UP026.py:93:5: UP026 [*] `mock` is deprecated, use `unittest.mock` | = help: Replace `mock.mock` with `mock` -ℹ Suggested fix +ℹ Fix 90 90 | x = mock.Mock() 91 91 | 92 92 | # Error (`mock.Mock()`). diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP027.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP027.py.snap index db56ed7f7d593..5d5bf30550a17 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP027.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP027.py.snap @@ -11,7 +11,7 @@ UP027.py:2:17: UP027 [*] Replace unpacked list comprehension with a generator ex | = help: Replace with generator expression -ℹ Suggested fix +ℹ Fix 1 1 | # Should change 2 |-foo, bar, baz = [fn(x) for x in items] 2 |+foo, bar, baz = (fn(x) for x in items) @@ -30,7 +30,7 @@ UP027.py:4:16: UP027 [*] Replace unpacked list comprehension with a generator ex | = help: Replace with generator expression -ℹ Suggested fix +ℹ Fix 1 1 | # Should change 2 2 | foo, bar, baz = [fn(x) for x in items] 3 3 | @@ -51,7 +51,7 @@ UP027.py:6:26: UP027 [*] Replace unpacked list comprehension with a generator ex | = help: Replace with generator expression -ℹ Suggested fix +ℹ Fix 3 3 | 4 4 | foo, bar, baz =[fn(x) for x in items] 5 5 | @@ -72,7 +72,7 @@ UP027.py:8:17: UP027 [*] Replace unpacked list comprehension with a generator ex | = help: Replace with generator expression -ℹ Suggested fix +ℹ Fix 5 5 | 6 6 | foo, bar, baz = [fn(x) for x in items] 7 7 | @@ -97,7 +97,7 @@ UP027.py:10:17: UP027 [*] Replace unpacked list comprehension with a generator e | = help: Replace with generator expression -ℹ Suggested fix +ℹ Fix 7 7 | 8 8 | foo, bar, baz = [[i for i in fn(x)] for x in items] 9 9 | diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_0.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_0.py.snap index 8771bfd691ac2..b056d14717377 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_0.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_0.py.snap @@ -12,7 +12,7 @@ UP032_0.py:5:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 2 2 | # Errors 3 3 | ### 4 4 | @@ -33,7 +33,7 @@ UP032_0.py:7:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 4 4 | 5 5 | "{} {}".format(a, b) 6 6 | @@ -54,7 +54,7 @@ UP032_0.py:9:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 6 6 | 7 7 | "{1} {0}".format(a, b) 8 8 | @@ -75,7 +75,7 @@ UP032_0.py:11:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 8 8 | 9 9 | "{0} {1} {0}".format(a, b) 10 10 | @@ -96,7 +96,7 @@ UP032_0.py:13:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 10 10 | 11 11 | "{x.y}".format(x=z) 12 12 | @@ -117,7 +117,7 @@ UP032_0.py:15:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 12 12 | 13 13 | "{x} {y} {x}".format(x=a, y=b) 14 14 | @@ -138,7 +138,7 @@ UP032_0.py:17:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 14 14 | 15 15 | "{.x} {.y}".format(a, b) 16 16 | @@ -159,7 +159,7 @@ UP032_0.py:19:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 16 16 | 17 17 | "{} {}".format(a.b, c.d) 18 18 | @@ -180,7 +180,7 @@ UP032_0.py:21:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 18 18 | 19 19 | "{}".format(a()) 20 20 | @@ -201,7 +201,7 @@ UP032_0.py:23:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 20 20 | 21 21 | "{}".format(a.b()) 22 22 | @@ -222,7 +222,7 @@ UP032_0.py:25:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 22 22 | 23 23 | "{}".format(a.b().c()) 24 24 | @@ -243,7 +243,7 @@ UP032_0.py:27:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 24 24 | 25 25 | "hello {}!".format(name) 26 26 | @@ -264,7 +264,7 @@ UP032_0.py:29:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 26 26 | 27 27 | "{}{b}{}".format(a, c, b=b) 28 28 | @@ -285,7 +285,7 @@ UP032_0.py:31:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 28 28 | 29 29 | "{}".format(0x0) 30 30 | @@ -306,7 +306,7 @@ UP032_0.py:33:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 30 30 | 31 31 | "{} {}".format(a, b) 32 32 | @@ -327,7 +327,7 @@ UP032_0.py:35:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 32 32 | 33 33 | """{} {}""".format(a, b) 34 34 | @@ -348,7 +348,7 @@ UP032_0.py:37:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 34 34 | 35 35 | "foo{}".format(1) 36 36 | @@ -369,7 +369,7 @@ UP032_0.py:39:5: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 36 36 | 37 37 | r"foo{}".format(1) 38 38 | @@ -390,7 +390,7 @@ UP032_0.py:41:7: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 38 38 | 39 39 | x = "{a}".format(a=1) 40 40 | @@ -411,7 +411,7 @@ UP032_0.py:43:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 40 40 | 41 41 | print("foo {} ".format(x)) 42 42 | @@ -432,7 +432,7 @@ UP032_0.py:45:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 42 42 | 43 43 | "{a[b]}".format(a=a) 44 44 | @@ -453,7 +453,7 @@ UP032_0.py:47:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 44 44 | 45 45 | "{a.a[b]}".format(a=a) 46 46 | @@ -474,7 +474,7 @@ UP032_0.py:49:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 46 46 | 47 47 | "{}{{}}{}".format(escaped, y) 48 48 | @@ -495,7 +495,7 @@ UP032_0.py:51:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 48 48 | 49 49 | "{}".format(a) 50 50 | @@ -516,7 +516,7 @@ UP032_0.py:53:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 50 50 | 51 51 | '({}={{0!e}})'.format(a) 52 52 | @@ -537,7 +537,7 @@ UP032_0.py:55:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 52 52 | 53 53 | "{[b]}".format(a) 54 54 | @@ -558,7 +558,7 @@ UP032_0.py:57:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 54 54 | 55 55 | '{[b]}'.format(a) 56 56 | @@ -579,7 +579,7 @@ UP032_0.py:59:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 56 56 | 57 57 | """{[b]}""".format(a) 58 58 | @@ -602,7 +602,7 @@ UP032_0.py:61:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 58 58 | 59 59 | '''{[b]}'''.format(a) 60 60 | @@ -627,7 +627,7 @@ UP032_0.py:65:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 62 62 | 1 63 63 | ) 64 64 | @@ -652,7 +652,7 @@ UP032_0.py:69:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 66 66 | 1111111111111111111111111111111111111111111111111111111111111111111111111, 67 67 | ) 68 68 | @@ -681,7 +681,7 @@ UP032_0.py:73:85: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 70 70 | {} 71 71 | """.format(1) 72 72 | @@ -708,7 +708,7 @@ UP032_0.py:79:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 76 76 | 111111 77 77 | ) 78 78 | @@ -732,7 +732,7 @@ UP032_0.py:81:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 79 79 | "{a}" "{b}".format(a=1, b=1) 80 80 | 81 81 | ( @@ -762,7 +762,7 @@ UP032_0.py:86:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 84 84 | ).format(a=1, b=1) 85 85 | 86 86 | ( @@ -795,7 +795,7 @@ UP032_0.py:94:5: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 93 93 | ( 94 94 | ( 95 95 | # comment @@ -824,7 +824,7 @@ UP032_0.py:104:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 102 102 | ) 103 103 | 104 104 | ( @@ -845,7 +845,7 @@ UP032_0.py:111:11: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 108 108 | 109 109 | 110 110 | def d(osname, version, release): @@ -863,7 +863,7 @@ UP032_0.py:115:10: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 112 112 | 113 113 | 114 114 | def e(): @@ -880,7 +880,7 @@ UP032_0.py:118:7: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 115 115 | yield"{}".format(1) 116 116 | 117 117 | @@ -898,7 +898,7 @@ UP032_0.py:122:12: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 119 119 | 120 120 | 121 121 | async def c(): @@ -916,7 +916,7 @@ UP032_0.py:126:12: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 123 123 | 124 124 | 125 125 | async def c(): @@ -935,7 +935,7 @@ UP032_0.py:129:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 126 126 | return "{}".format(1 + await 3) 127 127 | 128 128 | @@ -956,4 +956,20 @@ UP032_0.py:202:1: UP032 Use f-string instead of `format` call | = help: Convert to f-string +UP032_0.py:209:1: UP032 [*] Use f-string instead of `format` call + | +207 | # The fixed string will exceed the line length, but it's still smaller than the +208 | # existing line length, so it's fine. +209 | "".format(self.internal_ids, self.external_ids, self.properties, self.tags, self.others) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP032 + | + = help: Convert to f-string + +ℹ Fix +206 206 | +207 207 | # The fixed string will exceed the line length, but it's still smaller than the +208 208 | # existing line length, so it's fine. +209 |-"".format(self.internal_ids, self.external_ids, self.properties, self.tags, self.others) + 209 |+f"" + diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_1.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_1.py.snap index 1d879bf62a1ec..7e4e03882598d 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_1.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_1.py.snap @@ -8,7 +8,7 @@ UP032_1.py:1:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 1 |-"{} {}".format(a, b) # Intentionally at start-of-file, to ensure graceful handling. 1 |+f"{a} {b}" # Intentionally at start-of-file, to ensure graceful handling. diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_2.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_2.py.snap index 5751783cf76ab..abbe906198203 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_2.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_2.py.snap @@ -11,7 +11,7 @@ UP032_2.py:2:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 1 1 | # Errors 2 |-"{.real}".format(1) 2 |+f"{(1).real}" @@ -29,7 +29,7 @@ UP032_2.py:3:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 1 1 | # Errors 2 2 | "{.real}".format(1) 3 |-"{0.real}".format(1) @@ -49,7 +49,7 @@ UP032_2.py:4:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 1 1 | # Errors 2 2 | "{.real}".format(1) 3 3 | "{0.real}".format(1) @@ -70,7 +70,7 @@ UP032_2.py:6:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 3 3 | "{0.real}".format(1) 4 4 | "{a.real}".format(a=1) 5 5 | @@ -89,7 +89,7 @@ UP032_2.py:7:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 4 4 | "{a.real}".format(a=1) 5 5 | 6 6 | "{.real}".format(1.0) @@ -110,7 +110,7 @@ UP032_2.py:8:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 5 5 | 6 6 | "{.real}".format(1.0) 7 7 | "{0.real}".format(1.0) @@ -131,7 +131,7 @@ UP032_2.py:10:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 7 7 | "{0.real}".format(1.0) 8 8 | "{a.real}".format(a=1.0) 9 9 | @@ -150,7 +150,7 @@ UP032_2.py:11:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 8 8 | "{a.real}".format(a=1.0) 9 9 | 10 10 | "{.real}".format(1j) @@ -171,7 +171,7 @@ UP032_2.py:12:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 9 9 | 10 10 | "{.real}".format(1j) 11 11 | "{0.real}".format(1j) @@ -192,7 +192,7 @@ UP032_2.py:14:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 11 11 | "{0.real}".format(1j) 12 12 | "{a.real}".format(a=1j) 13 13 | @@ -211,7 +211,7 @@ UP032_2.py:15:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 12 12 | "{a.real}".format(a=1j) 13 13 | 14 14 | "{.real}".format(0b01) @@ -232,7 +232,7 @@ UP032_2.py:16:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 13 13 | 14 14 | "{.real}".format(0b01) 15 15 | "{0.real}".format(0b01) @@ -253,7 +253,7 @@ UP032_2.py:18:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 15 15 | "{0.real}".format(0b01) 16 16 | "{a.real}".format(a=0b01) 17 17 | @@ -273,7 +273,7 @@ UP032_2.py:19:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 16 16 | "{a.real}".format(a=0b01) 17 17 | 18 18 | "{}".format(1 + 2) @@ -294,7 +294,7 @@ UP032_2.py:20:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 17 17 | 18 18 | "{}".format(1 + 2) 19 19 | "{}".format([1, 2]) @@ -314,7 +314,7 @@ UP032_2.py:21:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 18 18 | "{}".format(1 + 2) 19 19 | "{}".format([1, 2]) 20 20 | "{}".format({1, 2}) @@ -335,7 +335,7 @@ UP032_2.py:22:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 19 19 | "{}".format([1, 2]) 20 20 | "{}".format({1, 2}) 21 21 | "{}".format({1: 2, 3: 4}) @@ -356,7 +356,7 @@ UP032_2.py:24:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 21 21 | "{}".format({1: 2, 3: 4}) 22 22 | "{}".format((i for i in range(2))) 23 23 | @@ -376,7 +376,7 @@ UP032_2.py:25:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 22 22 | "{}".format((i for i in range(2))) 23 23 | 24 24 | "{.real}".format(1 + 2) @@ -397,7 +397,7 @@ UP032_2.py:26:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 23 23 | 24 24 | "{.real}".format(1 + 2) 25 25 | "{.real}".format([1, 2]) @@ -416,7 +416,7 @@ UP032_2.py:27:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 24 24 | "{.real}".format(1 + 2) 25 25 | "{.real}".format([1, 2]) 26 26 | "{.real}".format({1, 2}) @@ -433,7 +433,7 @@ UP032_2.py:28:1: UP032 [*] Use f-string instead of `format` call | = help: Convert to f-string -ℹ Suggested fix +ℹ Fix 25 25 | "{.real}".format([1, 2]) 26 26 | "{.real}".format({1, 2}) 27 27 | "{.real}".format({1: 2, 3: 4}) diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_3.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_3.py.snap new file mode 100644 index 0000000000000..2bacb5d540775 --- /dev/null +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP032_3.py.snap @@ -0,0 +1,4 @@ +--- +source: crates/ruff_linter/src/rules/pyupgrade/mod.rs +--- + diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP035.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP035.py.snap index 4f8c750737ee2..ecbb716bafc33 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP035.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP035.py.snap @@ -11,7 +11,7 @@ UP035.py:2:1: UP035 [*] Import from `collections.abc` instead: `Mapping` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 1 1 | # UP035 2 |-from collections import Mapping 2 |+from collections.abc import Mapping @@ -30,7 +30,7 @@ UP035.py:4:1: UP035 [*] Import from `collections.abc` instead: `Mapping` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 1 1 | # UP035 2 2 | from collections import Mapping 3 3 | @@ -51,7 +51,7 @@ UP035.py:6:1: UP035 [*] Import from `collections.abc` instead: `Mapping`, `Seque | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 3 3 | 4 4 | from collections import Mapping as MAP 5 5 | @@ -72,7 +72,7 @@ UP035.py:8:1: UP035 [*] Import from `collections.abc` instead: `Mapping` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 5 5 | 6 6 | from collections import Mapping, Sequence 7 7 | @@ -94,7 +94,7 @@ UP035.py:10:1: UP035 [*] Import from `collections.abc` instead: `Mapping` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 7 7 | 8 8 | from collections import Counter, Mapping 9 9 | @@ -117,7 +117,7 @@ UP035.py:12:1: UP035 [*] Import from `collections.abc` instead: `Mapping` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 9 9 | 10 10 | from collections import (Counter, Mapping) 11 11 | @@ -141,7 +141,7 @@ UP035.py:15:1: UP035 [*] Import from `collections.abc` instead: `Mapping` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 12 12 | from collections import (Counter, 13 13 | Mapping) 14 14 | @@ -164,7 +164,7 @@ UP035.py:18:1: UP035 [*] Import from `collections.abc` instead: `Mapping`, `Sequ | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 15 15 | from collections import Counter, \ 16 16 | Mapping 17 17 | @@ -186,7 +186,7 @@ UP035.py:20:1: UP035 [*] Import from `collections.abc` instead: `Mapping` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 17 17 | 18 18 | from collections import Counter, Mapping, Sequence 19 19 | @@ -207,7 +207,7 @@ UP035.py:23:5: UP035 [*] Import from `collections.abc` instead: `Mapping` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 20 20 | from collections import Mapping as mapping, Counter 21 21 | 22 22 | if True: @@ -229,7 +229,7 @@ UP035.py:28:5: UP035 [*] Import from `collections.abc` instead: `Mapping` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 25 25 | if True: 26 26 | if True: 27 27 | pass @@ -251,7 +251,7 @@ UP035.py:30:10: UP035 [*] Import from `collections.abc` instead: `Mapping` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 27 27 | pass 28 28 | from collections import Mapping, Counter 29 29 | @@ -270,7 +270,7 @@ UP035.py:33:1: UP035 [*] Import from `collections.abc` instead: `Mapping` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 30 30 | if True: from collections import Mapping 31 31 | 32 32 | import os @@ -297,7 +297,7 @@ UP035.py:37:5: UP035 [*] Import from `collections.abc` instead: `Mapping`, `Call | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 35 35 | 36 36 | if True: 37 37 | from collections import ( @@ -322,7 +322,7 @@ UP035.py:44:1: UP035 [*] Import from `collections.abc` instead: `Callable` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 41 41 | Good, 42 42 | ) 43 43 | @@ -344,7 +344,7 @@ UP035.py:44:1: UP035 [*] Import from `collections` instead: `OrderedDict` | = help: Import from `collections` -ℹ Suggested fix +ℹ Fix 41 41 | Good, 42 42 | ) 43 43 | @@ -366,7 +366,7 @@ UP035.py:44:1: UP035 [*] Import from `re` instead: `Match`, `Pattern` | = help: Import from `re` -ℹ Suggested fix +ℹ Fix 41 41 | Good, 42 42 | ) 43 43 | @@ -440,7 +440,7 @@ UP035.py:51:1: UP035 [*] Import from `collections` instead: `OrderedDict` | = help: Import from `collections` -ℹ Suggested fix +ℹ Fix 48 48 | 49 49 | # Bad imports from PYI027 that are now handled by PYI022 (UP035) 50 50 | from typing import ContextManager @@ -461,7 +461,7 @@ UP035.py:52:1: UP035 [*] Import from `typing` instead: `OrderedDict` | = help: Import from `typing` -ℹ Suggested fix +ℹ Fix 49 49 | # Bad imports from PYI027 that are now handled by PYI022 (UP035) 50 50 | from typing import ContextManager 51 51 | from typing import OrderedDict @@ -482,7 +482,7 @@ UP035.py:53:1: UP035 [*] Import from `collections.abc` instead: `Callable` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 50 50 | from typing import ContextManager 51 51 | from typing import OrderedDict 52 52 | from typing_extensions import OrderedDict @@ -503,7 +503,7 @@ UP035.py:54:1: UP035 [*] Import from `collections.abc` instead: `ByteString` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 51 51 | from typing import OrderedDict 52 52 | from typing_extensions import OrderedDict 53 53 | from typing import Callable @@ -524,7 +524,7 @@ UP035.py:55:1: UP035 [*] Import from `collections.abc` instead: `Container` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 52 52 | from typing_extensions import OrderedDict 53 53 | from typing import Callable 54 54 | from typing import ByteString @@ -545,7 +545,7 @@ UP035.py:56:1: UP035 [*] Import from `collections.abc` instead: `Hashable` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 53 53 | from typing import Callable 54 54 | from typing import ByteString 55 55 | from typing import Container @@ -566,7 +566,7 @@ UP035.py:57:1: UP035 [*] Import from `collections.abc` instead: `ItemsView` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 54 54 | from typing import ByteString 55 55 | from typing import Container 56 56 | from typing import Hashable @@ -587,7 +587,7 @@ UP035.py:58:1: UP035 [*] Import from `collections.abc` instead: `Iterable` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 55 55 | from typing import Container 56 56 | from typing import Hashable 57 57 | from typing import ItemsView @@ -608,7 +608,7 @@ UP035.py:59:1: UP035 [*] Import from `collections.abc` instead: `Iterator` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 56 56 | from typing import Hashable 57 57 | from typing import ItemsView 58 58 | from typing import Iterable @@ -629,7 +629,7 @@ UP035.py:60:1: UP035 [*] Import from `collections.abc` instead: `KeysView` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 57 57 | from typing import ItemsView 58 58 | from typing import Iterable 59 59 | from typing import Iterator @@ -650,7 +650,7 @@ UP035.py:61:1: UP035 [*] Import from `collections.abc` instead: `Mapping` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 58 58 | from typing import Iterable 59 59 | from typing import Iterator 60 60 | from typing import KeysView @@ -671,7 +671,7 @@ UP035.py:62:1: UP035 [*] Import from `collections.abc` instead: `MappingView` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 59 59 | from typing import Iterator 60 60 | from typing import KeysView 61 61 | from typing import Mapping @@ -692,7 +692,7 @@ UP035.py:63:1: UP035 [*] Import from `collections.abc` instead: `MutableMapping` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 60 60 | from typing import KeysView 61 61 | from typing import Mapping 62 62 | from typing import MappingView @@ -713,7 +713,7 @@ UP035.py:64:1: UP035 [*] Import from `collections.abc` instead: `MutableSequence | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 61 61 | from typing import Mapping 62 62 | from typing import MappingView 63 63 | from typing import MutableMapping @@ -734,7 +734,7 @@ UP035.py:65:1: UP035 [*] Import from `collections.abc` instead: `MutableSet` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 62 62 | from typing import MappingView 63 63 | from typing import MutableMapping 64 64 | from typing import MutableSequence @@ -755,7 +755,7 @@ UP035.py:66:1: UP035 [*] Import from `collections.abc` instead: `Sequence` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 63 63 | from typing import MutableMapping 64 64 | from typing import MutableSequence 65 65 | from typing import MutableSet @@ -776,7 +776,7 @@ UP035.py:67:1: UP035 [*] Import from `collections.abc` instead: `Sized` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 64 64 | from typing import MutableSequence 65 65 | from typing import MutableSet 66 66 | from typing import Sequence @@ -797,7 +797,7 @@ UP035.py:68:1: UP035 [*] Import from `collections.abc` instead: `ValuesView` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 65 65 | from typing import MutableSet 66 66 | from typing import Sequence 67 67 | from typing import Sized @@ -818,7 +818,7 @@ UP035.py:69:1: UP035 [*] Import from `collections.abc` instead: `Awaitable` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 66 66 | from typing import Sequence 67 67 | from typing import Sized 68 68 | from typing import ValuesView @@ -839,7 +839,7 @@ UP035.py:70:1: UP035 [*] Import from `collections.abc` instead: `AsyncIterator` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 67 67 | from typing import Sized 68 68 | from typing import ValuesView 69 69 | from typing import Awaitable @@ -860,7 +860,7 @@ UP035.py:71:1: UP035 [*] Import from `collections.abc` instead: `AsyncIterable` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 68 68 | from typing import ValuesView 69 69 | from typing import Awaitable 70 70 | from typing import AsyncIterator @@ -881,7 +881,7 @@ UP035.py:72:1: UP035 [*] Import from `collections.abc` instead: `Coroutine` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 69 69 | from typing import Awaitable 70 70 | from typing import AsyncIterator 71 71 | from typing import AsyncIterable @@ -902,7 +902,7 @@ UP035.py:73:1: UP035 [*] Import from `collections.abc` instead: `Collection` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 70 70 | from typing import AsyncIterator 71 71 | from typing import AsyncIterable 72 72 | from typing import Coroutine @@ -923,7 +923,7 @@ UP035.py:74:1: UP035 [*] Import from `collections.abc` instead: `AsyncGenerator` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 71 71 | from typing import AsyncIterable 72 72 | from typing import Coroutine 73 73 | from typing import Collection @@ -944,7 +944,7 @@ UP035.py:75:1: UP035 [*] Import from `collections.abc` instead: `Reversible` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 72 72 | from typing import Coroutine 73 73 | from typing import Collection 74 74 | from typing import AsyncGenerator @@ -965,7 +965,7 @@ UP035.py:76:1: UP035 [*] Import from `collections.abc` instead: `Generator` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 73 73 | from typing import Collection 74 74 | from typing import AsyncGenerator 75 75 | from typing import Reversible @@ -985,7 +985,7 @@ UP035.py:77:1: UP035 [*] Import from `collections.abc` instead: `Callable` | = help: Import from `collections.abc` -ℹ Suggested fix +ℹ Fix 74 74 | from typing import AsyncGenerator 75 75 | from typing import Reversible 76 76 | from typing import Generator @@ -997,37 +997,57 @@ UP035.py:77:1: UP035 [*] Import from `collections.abc` instead: `Callable` UP035.py:87:1: UP035 [*] Import from `typing` instead: `NamedTuple` | -86 | # Ok: `typing_extensions` contains backported improvements. +86 | # OK: `typing_extensions` contains backported improvements. 87 | from typing_extensions import NamedTuple | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP035 88 | -89 | # Ok: `typing_extensions` supports `frozen_default` (backported from 3.12). +89 | # OK: `typing_extensions` supports `frozen_default` (backported from 3.12). | = help: Import from `typing` -ℹ Suggested fix +ℹ Fix 84 84 | from typing_extensions import SupportsIndex 85 85 | -86 86 | # Ok: `typing_extensions` contains backported improvements. +86 86 | # OK: `typing_extensions` contains backported improvements. 87 |-from typing_extensions import NamedTuple 87 |+from typing import NamedTuple 88 88 | -89 89 | # Ok: `typing_extensions` supports `frozen_default` (backported from 3.12). +89 89 | # OK: `typing_extensions` supports `frozen_default` (backported from 3.12). 90 90 | from typing_extensions import dataclass_transform UP035.py:90:1: UP035 [*] Import from `typing` instead: `dataclass_transform` | -89 | # Ok: `typing_extensions` supports `frozen_default` (backported from 3.12). +89 | # OK: `typing_extensions` supports `frozen_default` (backported from 3.12). 90 | from typing_extensions import dataclass_transform | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP035 +91 | +92 | # UP035 | = help: Import from `typing` -ℹ Suggested fix +ℹ Fix 87 87 | from typing_extensions import NamedTuple 88 88 | -89 89 | # Ok: `typing_extensions` supports `frozen_default` (backported from 3.12). +89 89 | # OK: `typing_extensions` supports `frozen_default` (backported from 3.12). 90 |-from typing_extensions import dataclass_transform 90 |+from typing import dataclass_transform +91 91 | +92 92 | # UP035 +93 93 | from backports.strenum import StrEnum + +UP035.py:93:1: UP035 [*] Import from `enum` instead: `StrEnum` + | +92 | # UP035 +93 | from backports.strenum import StrEnum + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP035 + | + = help: Import from `enum` + +ℹ Fix +90 90 | from typing_extensions import dataclass_transform +91 91 | +92 92 | # UP035 +93 |-from backports.strenum import StrEnum + 93 |+from enum import StrEnum diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP036_0.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP036_0.py.snap index 8c181b6544a1a..19e79910ff9c6 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP036_0.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP036_0.py.snap @@ -685,4 +685,93 @@ UP036_0.py:182:4: UP036 [*] Version block is outdated for minimum Python version 185 183 | if sys.version_info <= (3,12): 186 184 | print("py3") +UP036_0.py:191:24: UP036 Version specifier is invalid + | +189 | print("py3") +190 | +191 | if sys.version_info == 10000000: + | ^^^^^^^^ UP036 +192 | print("py3") + | + +UP036_0.py:194:23: UP036 Version specifier is invalid + | +192 | print("py3") +193 | +194 | if sys.version_info < (3,10000000): + | ^^^^^^^^^^^^ UP036 +195 | print("py3") + | + +UP036_0.py:197:24: UP036 Version specifier is invalid + | +195 | print("py3") +196 | +197 | if sys.version_info <= (3,10000000): + | ^^^^^^^^^^^^ UP036 +198 | print("py3") + | + +UP036_0.py:203:4: UP036 [*] Version block is outdated for minimum Python version + | +201 | print("py3") +202 | +203 | if sys.version_info >= (3,12): + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ UP036 +204 | print("py3") + | + = help: Remove outdated version block + +ℹ Suggested fix +200 200 | if sys.version_info > (3,12): +201 201 | print("py3") +202 202 | +203 |-if sys.version_info >= (3,12): +204 |- print("py3") + 203 |+print("py3") +205 204 | +206 205 | # Slices on `sys.version_info` should be treated equivalently. +207 206 | if sys.version_info[:2] >= (3,0): + +UP036_0.py:207:4: UP036 [*] Version block is outdated for minimum Python version + | +206 | # Slices on `sys.version_info` should be treated equivalently. +207 | if sys.version_info[:2] >= (3,0): + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP036 +208 | print("py3") + | + = help: Remove outdated version block + +ℹ Suggested fix +204 204 | print("py3") +205 205 | +206 206 | # Slices on `sys.version_info` should be treated equivalently. +207 |-if sys.version_info[:2] >= (3,0): +208 |- print("py3") + 207 |+print("py3") +209 208 | +210 209 | if sys.version_info[:3] >= (3,0): +211 210 | print("py3") + +UP036_0.py:210:4: UP036 [*] Version block is outdated for minimum Python version + | +208 | print("py3") +209 | +210 | if sys.version_info[:3] >= (3,0): + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP036 +211 | print("py3") + | + = help: Remove outdated version block + +ℹ Suggested fix +207 207 | if sys.version_info[:2] >= (3,0): +208 208 | print("py3") +209 209 | +210 |-if sys.version_info[:3] >= (3,0): +211 |- print("py3") + 210 |+print("py3") +212 211 | +213 212 | if sys.version_info[:2] > (3,13): +214 213 | print("py3") + diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP040.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP040.py.snap index 955401aad3aa3..d470fe80ff81e 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP040.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP040.py.snap @@ -10,7 +10,7 @@ UP040.py:5:1: UP040 [*] Type alias `x` uses `TypeAlias` annotation instead of th | = help: Use the `type` keyword -ℹ Fix +ℹ Suggested fix 2 2 | from typing import TypeAlias 3 3 | 4 4 | # UP040 @@ -31,7 +31,7 @@ UP040.py:6:1: UP040 [*] Type alias `x` uses `TypeAlias` annotation instead of th | = help: Use the `type` keyword -ℹ Fix +ℹ Suggested fix 3 3 | 4 4 | # UP040 5 5 | x: typing.TypeAlias = int @@ -52,7 +52,7 @@ UP040.py:10:1: UP040 [*] Type alias `x` uses `TypeAlias` annotation instead of t | = help: Use the `type` keyword -ℹ Fix +ℹ Suggested fix 7 7 | 8 8 | # UP040 simple generic 9 9 | T = typing.TypeVar["T"] @@ -73,7 +73,7 @@ UP040.py:14:1: UP040 [*] Type alias `x` uses `TypeAlias` annotation instead of t | = help: Use the `type` keyword -ℹ Fix +ℹ Suggested fix 11 11 | 12 12 | # UP040 call style generic 13 13 | T = typing.TypeVar("T") @@ -94,7 +94,7 @@ UP040.py:18:1: UP040 [*] Type alias `x` uses `TypeAlias` annotation instead of t | = help: Use the `type` keyword -ℹ Fix +ℹ Suggested fix 15 15 | 16 16 | # UP040 bounded generic 17 17 | T = typing.TypeVar("T", bound=int) @@ -115,7 +115,7 @@ UP040.py:22:1: UP040 [*] Type alias `x` uses `TypeAlias` annotation instead of t | = help: Use the `type` keyword -ℹ Fix +ℹ Suggested fix 19 19 | 20 20 | # UP040 constrained generic 21 21 | T = typing.TypeVar("T", int, str) @@ -136,7 +136,7 @@ UP040.py:26:1: UP040 [*] Type alias `x` uses `TypeAlias` annotation instead of t | = help: Use the `type` keyword -ℹ Fix +ℹ Suggested fix 23 23 | 24 24 | # UP040 contravariant generic 25 25 | T = typing.TypeVar("T", contravariant=True) @@ -157,7 +157,7 @@ UP040.py:30:1: UP040 [*] Type alias `x` uses `TypeAlias` annotation instead of t | = help: Use the `type` keyword -ℹ Fix +ℹ Suggested fix 27 27 | 28 28 | # UP040 covariant generic 29 29 | T = typing.TypeVar("T", covariant=True) @@ -178,7 +178,7 @@ UP040.py:36:5: UP040 [*] Type alias `x` uses `TypeAlias` annotation instead of t | = help: Use the `type` keyword -ℹ Fix +ℹ Suggested fix 33 33 | T = typing.TypeVar["T"] 34 34 | class Foo: 35 35 | # reference to global variable @@ -199,7 +199,7 @@ UP040.py:40:5: UP040 [*] Type alias `y` uses `TypeAlias` annotation instead of t | = help: Use the `type` keyword -ℹ Fix +ℹ Suggested fix 37 37 | 38 38 | # reference to class variable 39 39 | TCLS = typing.TypeVar["TCLS"] @@ -220,7 +220,7 @@ UP040.py:44:1: UP040 [*] Type alias `x` uses `TypeAlias` annotation instead of t | = help: Use the `type` keyword -ℹ Fix +ℹ Suggested fix 41 41 | 42 42 | # UP040 wont add generics in fix 43 43 | T = typing.TypeVar(*args) diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP040.pyi.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP040.pyi.snap new file mode 100644 index 0000000000000..cc46a87dbcc8e --- /dev/null +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP040.pyi.snap @@ -0,0 +1,38 @@ +--- +source: crates/ruff_linter/src/rules/pyupgrade/mod.rs +--- +UP040.pyi:6:1: UP040 [*] Type alias `x` uses `TypeAlias` annotation instead of the `type` keyword + | +4 | # UP040 +5 | # Fixes in type stub files should be safe to apply unlike in regular code where runtime behavior could change +6 | x: typing.TypeAlias = int + | ^^^^^^^^^^^^^^^^^^^^^^^^^ UP040 +7 | x: TypeAlias = int + | + = help: Use the `type` keyword + +ℹ Fix +3 3 | +4 4 | # UP040 +5 5 | # Fixes in type stub files should be safe to apply unlike in regular code where runtime behavior could change +6 |-x: typing.TypeAlias = int + 6 |+type x = int +7 7 | x: TypeAlias = int + +UP040.pyi:7:1: UP040 [*] Type alias `x` uses `TypeAlias` annotation instead of the `type` keyword + | +5 | # Fixes in type stub files should be safe to apply unlike in regular code where runtime behavior could change +6 | x: typing.TypeAlias = int +7 | x: TypeAlias = int + | ^^^^^^^^^^^^^^^^^^ UP040 + | + = help: Use the `type` keyword + +ℹ Fix +4 4 | # UP040 +5 5 | # Fixes in type stub files should be safe to apply unlike in regular code where runtime behavior could change +6 6 | x: typing.TypeAlias = int +7 |-x: TypeAlias = int + 7 |+type x = int + + diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__datetime_utc_alias_py311.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__datetime_utc_alias_py311.snap index 3cde3025383da..d2c709fd20b5d 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__datetime_utc_alias_py311.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__datetime_utc_alias_py311.snap @@ -10,7 +10,7 @@ UP017.py:7:7: UP017 [*] Use `datetime.UTC` alias | = help: Convert to `datetime.UTC` alias -ℹ Suggested fix +ℹ Fix 4 4 | from datetime import timezone as tz 5 5 | 6 6 | print(datetime.timezone(-1)) @@ -31,7 +31,7 @@ UP017.py:8:7: UP017 [*] Use `datetime.UTC` alias | = help: Convert to `datetime.UTC` alias -ℹ Suggested fix +ℹ Fix 5 5 | 6 6 | print(datetime.timezone(-1)) 7 7 | print(timezone.utc) @@ -51,7 +51,7 @@ UP017.py:10:7: UP017 [*] Use `datetime.UTC` alias | = help: Convert to `datetime.UTC` alias -ℹ Suggested fix +ℹ Fix 7 7 | print(timezone.utc) 8 8 | print(tz.utc) 9 9 | @@ -67,7 +67,7 @@ UP017.py:11:7: UP017 [*] Use `datetime.UTC` alias | = help: Convert to `datetime.UTC` alias -ℹ Suggested fix +ℹ Fix 8 8 | print(tz.utc) 9 9 | 10 10 | print(datetime.timezone.utc) diff --git a/crates/ruff_linter/src/rules/refurb/mod.rs b/crates/ruff_linter/src/rules/refurb/mod.rs index 587b0f85fae6b..fe50c29bcd7e3 100644 --- a/crates/ruff_linter/src/rules/refurb/mod.rs +++ b/crates/ruff_linter/src/rules/refurb/mod.rs @@ -14,6 +14,7 @@ mod tests { use crate::test::test_path; use crate::{assert_messages, settings}; + #[test_case(Rule::ReadWholeFile, Path::new("FURB101.py"))] #[test_case(Rule::RepeatedAppend, Path::new("FURB113.py"))] #[test_case(Rule::DeleteFullSlice, Path::new("FURB131.py"))] #[test_case(Rule::CheckAndRemoveFromSet, Path::new("FURB132.py"))] @@ -21,6 +22,8 @@ mod tests { #[test_case(Rule::SliceCopy, Path::new("FURB145.py"))] #[test_case(Rule::UnnecessaryEnumerate, Path::new("FURB148.py"))] #[test_case(Rule::PrintEmptyString, Path::new("FURB105.py"))] + #[test_case(Rule::ImplicitCwd, Path::new("FURB177.py"))] + #[test_case(Rule::SingleItemMembershipTest, Path::new("FURB171.py"))] fn rules(rule_code: Rule, path: &Path) -> Result<()> { let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy()); let diagnostics = test_path( diff --git a/crates/ruff_linter/src/rules/refurb/rules/check_and_remove_from_set.rs b/crates/ruff_linter/src/rules/refurb/rules/check_and_remove_from_set.rs index fd2d46028957e..083c9a05e0963 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/check_and_remove_from_set.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/check_and_remove_from_set.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::comparable::ComparableExpr; use ruff_python_ast::helpers::contains_effect; @@ -7,9 +7,8 @@ use ruff_python_codegen::Generator; use ruff_python_semantic::analyze::typing::is_set; use ruff_text_size::{Ranged, TextRange}; -use crate::autofix::snippet::SourceCodeSnippet; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix::snippet::SourceCodeSnippet; /// ## What it does /// Checks for uses of `set.remove` that can be replaced with `set.discard`. @@ -54,14 +53,14 @@ impl CheckAndRemoveFromSet { } } -impl AlwaysAutofixableViolation for CheckAndRemoveFromSet { +impl AlwaysFixableViolation for CheckAndRemoveFromSet { #[derive_message_formats] fn message(&self) -> String { let suggestion = self.suggestion(); format!("Use `{suggestion}` instead of check and `remove`") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let suggestion = self.suggestion(); format!("Replace with `{suggestion}`") } @@ -112,13 +111,11 @@ pub(crate) fn check_and_remove_from_set(checker: &mut Checker, if_stmt: &ast::St }, if_stmt.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::replacement( - make_suggestion(check_set, check_element, checker.generator()), - if_stmt.start(), - if_stmt.end(), - ))); - } + diagnostic.set_fix(Fix::unsafe_edit(Edit::replacement( + make_suggestion(check_set, check_element, checker.generator()), + if_stmt.start(), + if_stmt.end(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/refurb/rules/delete_full_slice.rs b/crates/ruff_linter/src/rules/refurb/rules/delete_full_slice.rs index e84b081761e56..c7ce2b218c003 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/delete_full_slice.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/delete_full_slice.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Expr}; use ruff_python_semantic::analyze::typing::{is_dict, is_list}; @@ -6,7 +6,7 @@ use ruff_python_semantic::{Binding, SemanticModel}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::refurb::helpers::generate_method_call; /// ## What it does @@ -47,14 +47,14 @@ use crate::rules::refurb::helpers::generate_method_call; pub struct DeleteFullSlice; impl Violation for DeleteFullSlice { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Prefer `clear` over deleting a full slice") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Replace with `clear()`".to_string()) } } @@ -69,9 +69,9 @@ pub(crate) fn delete_full_slice(checker: &mut Checker, delete: &ast::StmtDelete) let mut diagnostic = Diagnostic::new(DeleteFullSlice, delete.range); // Fix is only supported for single-target deletions. - if checker.patch(diagnostic.kind.rule()) && delete.targets.len() == 1 { + if delete.targets.len() == 1 { let replacement = generate_method_call(name, "clear", checker.generator()); - diagnostic.set_fix(Fix::suggested(Edit::replacement( + diagnostic.set_fix(Fix::unsafe_edit(Edit::replacement( replacement, delete.start(), delete.end(), diff --git a/crates/ruff_linter/src/rules/refurb/rules/implicit_cwd.rs b/crates/ruff_linter/src/rules/refurb/rules/implicit_cwd.rs new file mode 100644 index 0000000000000..a4cf83d55783f --- /dev/null +++ b/crates/ruff_linter/src/rules/refurb/rules/implicit_cwd.rs @@ -0,0 +1,106 @@ +use ruff_diagnostics::{Diagnostic, Edit, Fix, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, Constant, Expr, ExprAttribute, ExprCall}; +use ruff_text_size::Ranged; + +use crate::{checkers::ast::Checker, importer::ImportRequest}; + +/// ## What it does +/// Checks for current-directory lookups using `Path().resolve()`. +/// +/// ## Why is this bad? +/// When looking up the current directory, prefer `Path.cwd()` over +/// `Path().resolve()`, as `Path.cwd()` is more explicit in its intent. +/// +/// ## Example +/// ```python +/// cwd = Path().resolve() +/// ``` +/// +/// Use instead: +/// ```python +/// cwd = Path.cwd() +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.cwd`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.cwd) + +#[violation] +pub struct ImplicitCwd; + +impl Violation for ImplicitCwd { + #[derive_message_formats] + fn message(&self) -> String { + format!("Prefer `Path.cwd()` over `Path().resolve()` for current-directory lookups") + } +} + +/// FURB177 +pub(crate) fn no_implicit_cwd(checker: &mut Checker, call: &ExprCall) { + if !call.arguments.is_empty() { + return; + } + + let Expr::Attribute(ExprAttribute { attr, value, .. }) = call.func.as_ref() else { + return; + }; + + if attr != "resolve" { + return; + } + + let Expr::Call(ExprCall { + func, arguments, .. + }) = value.as_ref() + else { + return; + }; + + // Match on arguments, but ignore keyword arguments. `Path()` accepts keyword arguments, but + // ignores them. See: https://github.com/python/cpython/issues/98094. + match arguments.args.as_slice() { + // Ex) `Path().resolve()` + [] => {} + // Ex) `Path(".").resolve()` + [arg] => { + let Expr::Constant(ast::ExprConstant { + value: Constant::Str(str), + .. + }) = arg + else { + return; + }; + if !matches!(str.value.as_str(), "" | ".") { + return; + } + } + // Ex) `Path("foo", "bar").resolve()` + _ => return, + } + + if !checker + .semantic() + .resolve_call_path(func) + .is_some_and(|call_path| matches!(call_path.as_slice(), ["pathlib", "Path"])) + { + return; + } + + let mut diagnostic = Diagnostic::new(ImplicitCwd, call.range()); + + diagnostic.try_set_fix(|| { + let (import_edit, binding) = checker.importer().get_or_import_symbol( + &ImportRequest::import("pathlib", "Path"), + call.start(), + checker.semantic(), + )?; + Ok(Fix::unsafe_edits( + Edit::range_replacement(format!("{binding}.cwd()"), call.range()), + [import_edit], + )) + }); + + checker + .diagnostics + .push(Diagnostic::new(ImplicitCwd, call.range())); +} diff --git a/crates/ruff_linter/src/rules/refurb/rules/mod.rs b/crates/ruff_linter/src/rules/refurb/rules/mod.rs index a3277d79f4667..096ebc10b68d6 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/mod.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/mod.rs @@ -1,15 +1,21 @@ pub(crate) use check_and_remove_from_set::*; pub(crate) use delete_full_slice::*; +pub(crate) use implicit_cwd::*; pub(crate) use print_empty_string::*; +pub(crate) use read_whole_file::*; pub(crate) use reimplemented_starmap::*; pub(crate) use repeated_append::*; +pub(crate) use single_item_membership_test::*; pub(crate) use slice_copy::*; pub(crate) use unnecessary_enumerate::*; mod check_and_remove_from_set; mod delete_full_slice; +mod implicit_cwd; mod print_empty_string; +mod read_whole_file; mod reimplemented_starmap; mod repeated_append; +mod single_item_membership_test; mod slice_copy; mod unnecessary_enumerate; diff --git a/crates/ruff_linter/src/rules/refurb/rules/print_empty_string.rs b/crates/ruff_linter/src/rules/refurb/rules/print_empty_string.rs index be131ed09360a..42bc08d5f225a 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/print_empty_string.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/print_empty_string.rs @@ -1,20 +1,23 @@ -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Constant, Expr}; use ruff_python_codegen::Generator; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does -/// Checks for `print` calls with an empty string as the only positional -/// argument. +/// Checks for `print` calls with unnecessary empty strings as positional +/// arguments and unnecessary `sep` keyword arguments. /// /// ## Why is this bad? /// Prefer calling `print` without any positional arguments, which is /// equivalent and more concise. /// +/// Similarly, when printing one or fewer items, the `sep` keyword argument, +/// (used to define the string that separates the `print` arguments) can be +/// omitted, as it's redundant when there are no items to separate. +/// /// ## Example /// ```python /// print("") @@ -43,7 +46,7 @@ enum Reason { } impl Violation for PrintEmptyString { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -55,7 +58,7 @@ impl Violation for PrintEmptyString { } } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let PrintEmptyString { reason } = self; match reason { Reason::EmptyArgument => Some("Remove empty string".to_string()), @@ -77,9 +80,6 @@ pub(crate) fn print_empty_string(checker: &mut Checker, call: &ast::ExprCall) { } match &call.arguments.args.as_slice() { - // Ex) `print(*args)` or `print(*args, sep="\t")` - [arg] if arg.is_starred_expr() => {} - // Ex) `print("")` or `print("", sep="\t")` [arg] if is_empty_string(arg) => { let reason = if call.arguments.find_keyword("sep").is_some() { @@ -90,17 +90,19 @@ pub(crate) fn print_empty_string(checker: &mut Checker, call: &ast::ExprCall) { let mut diagnostic = Diagnostic::new(PrintEmptyString { reason }, call.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::replacement( - generate_suggestion(call, Separator::Remove, checker.generator()), - call.start(), - call.end(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::replacement( + generate_suggestion(call, Separator::Remove, checker.generator()), + call.start(), + call.end(), + ))); checker.diagnostics.push(diagnostic); } + [arg] if arg.is_starred_expr() => { + // If there's a starred argument, we can't remove the empty string. + } + // Ex) `print(sep="\t")` or `print(obj, sep="\t")` [] | [_] => { // If there's a `sep` argument, remove it, regardless of what it is. @@ -112,13 +114,11 @@ pub(crate) fn print_empty_string(checker: &mut Checker, call: &ast::ExprCall) { call.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::replacement( - generate_suggestion(call, Separator::Remove, checker.generator()), - call.start(), - call.end(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::replacement( + generate_suggestion(call, Separator::Remove, checker.generator()), + call.start(), + call.end(), + ))); checker.diagnostics.push(diagnostic); } @@ -177,13 +177,11 @@ pub(crate) fn print_empty_string(checker: &mut Checker, call: &ast::ExprCall) { call.range(), ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::replacement( - generate_suggestion(call, separator, checker.generator()), - call.start(), - call.end(), - ))); - } + diagnostic.set_fix(Fix::safe_edit(Edit::replacement( + generate_suggestion(call, separator, checker.generator()), + call.start(), + call.end(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/refurb/rules/read_whole_file.rs b/crates/ruff_linter/src/rules/refurb/rules/read_whole_file.rs new file mode 100644 index 0000000000000..49a6bce3f3246 --- /dev/null +++ b/crates/ruff_linter/src/rules/refurb/rules/read_whole_file.rs @@ -0,0 +1,336 @@ +use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::visitor::{self, Visitor}; +use ruff_python_ast::{self as ast, Expr}; +use ruff_python_codegen::Generator; +use ruff_python_semantic::{BindingId, ResolvedReference, SemanticModel}; +use ruff_text_size::{Ranged, TextRange}; + +use crate::checkers::ast::Checker; +use crate::fix::snippet::SourceCodeSnippet; + +/// ## What it does +/// Checks for uses of `open` and `read` that can be replaced by `pathlib` +/// methods, like `Path.read_text` and `Path.read_bytes`. +/// +/// ## Why is this bad? +/// When reading the entire contents of a file into a variable, it's simpler +/// and more concise to use `pathlib` methods like `Path.read_text` and +/// `Path.read_bytes` instead of `open` and `read` calls via `with` statements. +/// +/// ## Example +/// ```python +/// with open(filename) as f: +/// contents = f.read() +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// contents = Path(filename).read_text() +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.read_bytes`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.read_bytes) +/// - [Python documentation: `Path.read_text`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.read_text) +#[violation] +pub struct ReadWholeFile { + filename: SourceCodeSnippet, + suggestion: SourceCodeSnippet, +} + +impl Violation for ReadWholeFile { + #[derive_message_formats] + fn message(&self) -> String { + let filename = self.filename.truncated_display(); + let suggestion = self.suggestion.truncated_display(); + format!("`open` and `read` should be replaced by `Path({filename}).{suggestion}`") + } +} + +/// FURB101 +pub(crate) fn read_whole_file(checker: &mut Checker, with: &ast::StmtWith) { + // `async` check here is more of a precaution. + if with.is_async || !checker.semantic().is_builtin("open") { + return; + } + + // First we go through all the items in the statement and find all `open` operations. + let candidates = find_file_opens(with, checker.semantic()); + if candidates.is_empty() { + return; + } + + // Then we need to match each `open` operation with exactly one `read` call. + let matches = { + let mut matcher = ReadMatcher::new(candidates); + visitor::walk_body(&mut matcher, &with.body); + matcher.into_matches() + }; + + // All the matched operations should be reported. + let diagnostics: Vec = matches + .iter() + .map(|open| { + Diagnostic::new( + ReadWholeFile { + filename: SourceCodeSnippet::from_str(&checker.generator().expr(open.filename)), + suggestion: make_suggestion(open, checker.generator()), + }, + open.item.range(), + ) + }) + .collect(); + checker.diagnostics.extend(diagnostics); +} + +#[derive(Debug)] +enum ReadMode { + /// "r" -> `read_text` + Text, + /// "rb" -> `read_bytes` + Bytes, +} + +/// A grab bag struct that joins together every piece of information we need to track +/// about a file open operation. +#[derive(Debug)] +struct FileOpen<'a> { + /// With item where the open happens, we use it for the reporting range. + item: &'a ast::WithItem, + /// Filename expression used as the first argument in `open`, we use it in the diagnostic message. + filename: &'a Expr, + /// The type of read to choose `read_text` or `read_bytes`. + mode: ReadMode, + /// Keywords that can be used in the new read call. + keywords: Vec<&'a ast::Keyword>, + /// We only check `open` operations whose file handles are used exactly once. + reference: &'a ResolvedReference, +} + +impl<'a> FileOpen<'a> { + /// Determine whether an expression is a reference to the file handle, by comparing + /// their ranges. If two expressions have the same range, they must be the same expression. + fn is_ref(&self, expr: &Expr) -> bool { + expr.range() == self.reference.range() + } +} + +/// Find and return all `open` operations in the given `with` statement. +fn find_file_opens<'a>( + with: &'a ast::StmtWith, + semantic: &'a SemanticModel<'a>, +) -> Vec> { + with.items + .iter() + .filter_map(|item| find_file_open(item, with, semantic)) + .collect() +} + +/// Find `open` operation in the given `with` item. +fn find_file_open<'a>( + item: &'a ast::WithItem, + with: &'a ast::StmtWith, + semantic: &'a SemanticModel<'a>, +) -> Option> { + // We want to match `open(...) as var`. + let ast::ExprCall { + func, + arguments: ast::Arguments { args, keywords, .. }, + .. + } = item.context_expr.as_call_expr()?; + + if func.as_name_expr()?.id != "open" { + return None; + } + + let var = item.optional_vars.as_deref()?.as_name_expr()?; + + // Ignore calls with `*args` and `**kwargs`. In the exact case of `open(*filename, mode="r")`, + // it could be a match; but in all other cases, the call _could_ contain unsupported keyword + // arguments, like `buffering`. + if args.iter().any(Expr::is_starred_expr) + || keywords.iter().any(|keyword| keyword.arg.is_none()) + { + return None; + } + + // Match positional arguments, get filename and read mode. + let (filename, pos_mode) = match_open_args(args)?; + + // Match keyword arguments, get keyword arguments to forward and possibly read mode. + let (keywords, kw_mode) = match_open_keywords(keywords)?; + + // `pos_mode` could've been assigned default value corresponding to "r", while + // keyword mode should override that. + let mode = kw_mode.unwrap_or(pos_mode); + + // Now we need to find what is this variable bound to... + let scope = semantic.current_scope(); + let bindings: Vec = scope.get_all(var.id.as_str()).collect(); + + let binding = bindings + .iter() + .map(|x| semantic.binding(*x)) + // We might have many bindings with the same name, but we only care + // for the one we are looking at right now. + .find(|binding| binding.range() == var.range())?; + + // Since many references can share the same binding, we can limit our attention span + // exclusively to the body of the current `with` statement. + let references: Vec<&ResolvedReference> = binding + .references + .iter() + .map(|id| semantic.reference(*id)) + .filter(|reference| with.range().contains_range(reference.range())) + .collect(); + + // And even with all these restrictions, if the file handle gets used not exactly once, + // it doesn't fit the bill. + let [reference] = references.as_slice() else { + return None; + }; + + Some(FileOpen { + item, + filename, + mode, + keywords, + reference, + }) +} + +/// Match positional arguments. Return expression for the file name and read mode. +fn match_open_args(args: &[Expr]) -> Option<(&Expr, ReadMode)> { + match args { + [filename] => Some((filename, ReadMode::Text)), + [filename, mode_literal] => match_open_mode(mode_literal).map(|mode| (filename, mode)), + // The third positional argument is `buffering` and `read_text` doesn't support it. + _ => None, + } +} + +/// Match keyword arguments. Return keyword arguments to forward and read mode. +fn match_open_keywords( + keywords: &[ast::Keyword], +) -> Option<(Vec<&ast::Keyword>, Option)> { + let mut result: Vec<&ast::Keyword> = vec![]; + let mut mode: Option = None; + + for keyword in keywords { + match keyword.arg.as_ref()?.as_str() { + "encoding" | "errors" => result.push(keyword), + + // This might look bizarre, - why do we re-wrap this optional? + // + // The answer is quite simple, in the result of the current function + // mode being `None` is a possible and correct option meaning that there + // was NO "mode" keyword argument. + // + // The result of `match_open_mode` on the other hand is None + // in the cases when the mode is not compatible with `read_text`/`read_bytes`. + // + // So, here we return None from this whole function if the mode + // is incompatible. + "mode" => mode = Some(match_open_mode(&keyword.value)?), + + // All other keywords cannot be directly forwarded. + _ => return None, + }; + } + Some((result, mode)) +} + +/// Match open mode to see if it is supported. +fn match_open_mode(mode: &Expr) -> Option { + let ast::StringConstant { + value, + implicit_concatenated: false, + .. + } = mode.as_constant_expr()?.value.as_str()? + else { + return None; + }; + match value.as_str() { + "r" => Some(ReadMode::Text), + "rb" => Some(ReadMode::Bytes), + _ => None, + } +} + +/// AST visitor that matches `open` operations with the corresponding `read` calls. +#[derive(Debug)] +struct ReadMatcher<'a> { + candidates: Vec>, + matches: Vec>, +} + +impl<'a> ReadMatcher<'a> { + fn new(candidates: Vec>) -> Self { + Self { + candidates, + matches: vec![], + } + } + + fn into_matches(self) -> Vec> { + self.matches + } +} + +impl<'a> Visitor<'a> for ReadMatcher<'a> { + fn visit_expr(&mut self, expr: &'a Expr) { + if let Some(read_from) = match_read_call(expr) { + if let Some(open) = self + .candidates + .iter() + .position(|open| open.is_ref(read_from)) + { + self.matches.push(self.candidates.remove(open)); + } + return; + } + visitor::walk_expr(self, expr); + } +} + +/// Match `x.read()` expression and return expression `x` on success. +fn match_read_call(expr: &Expr) -> Option<&Expr> { + let call = expr.as_call_expr()?; + let attr = call.func.as_attribute_expr()?; + let method_name = &attr.attr; + + if method_name != "read" + || !attr.value.is_name_expr() + || !call.arguments.args.is_empty() + || !call.arguments.keywords.is_empty() + { + return None; + } + + Some(attr.value.as_ref()) +} + +/// Construct the replacement suggestion call. +fn make_suggestion(open: &FileOpen<'_>, generator: Generator) -> SourceCodeSnippet { + let method_name = match open.mode { + ReadMode::Text => "read_text", + ReadMode::Bytes => "read_bytes", + }; + let name = ast::ExprName { + id: method_name.to_string(), + ctx: ast::ExprContext::Load, + range: TextRange::default(), + }; + let call = ast::ExprCall { + func: Box::new(name.into()), + arguments: ast::Arguments { + args: vec![], + keywords: open.keywords.iter().copied().cloned().collect(), + range: TextRange::default(), + }, + range: TextRange::default(), + }; + SourceCodeSnippet::from_str(&generator.expr(&call.into())) +} diff --git a/crates/ruff_linter/src/rules/refurb/rules/reimplemented_starmap.rs b/crates/ruff_linter/src/rules/refurb/rules/reimplemented_starmap.rs index f8994b4cb995a..8f380a187b952 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/reimplemented_starmap.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/reimplemented_starmap.rs @@ -1,5 +1,5 @@ use anyhow::{bail, Result}; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::comparable::ComparableExpr; use ruff_python_ast::{self as ast, Expr}; @@ -7,7 +7,6 @@ use ruff_text_size::{Ranged, TextRange}; use crate::checkers::ast::Checker; use crate::importer::ImportRequest; -use crate::registry::AsRule; /// ## What it does /// Checks for generator expressions, list and set comprehensions that can @@ -17,7 +16,14 @@ use crate::registry::AsRule; /// When unpacking values from iterators to pass them directly to /// a function, prefer `itertools.starmap`. /// -/// Using `itertools.starmap` is more concise and readable. +/// Using `itertools.starmap` is more concise and readable. Furthermore, it is +/// more efficient than generator expressions, and in some versions of Python, +/// it is more efficient than comprehensions. +/// +/// ## Known problems +/// Since Python 3.12, `itertools.starmap` is less efficient than +/// comprehensions ([#7771]). This is due to [PEP 709], which made +/// comprehensions faster. /// /// ## Example /// ```python @@ -53,18 +59,21 @@ use crate::registry::AsRule; /// /// ## References /// - [Python documentation: `itertools.starmap`](https://docs.python.org/3/library/itertools.html#itertools.starmap) +/// +/// [PEP 709]: https://peps.python.org/pep-0709/ +/// [#7771]: https://github.com/astral-sh/ruff/issues/7771 #[violation] pub struct ReimplementedStarmap; impl Violation for ReimplementedStarmap { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Use `itertools.starmap` instead of the generator") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some(format!("Replace with `itertools.starmap`")) } } @@ -82,7 +91,7 @@ pub(crate) fn reimplemented_starmap(checker: &mut Checker, target: &StarmapCandi // ``` // // `x, y, z, ...` are what we call `elts` for short. - let Some((elts, iter)) = match_comprehension(comprehension) else { + let Some(value) = match_comprehension_target(comprehension) else { return; }; @@ -99,40 +108,55 @@ pub(crate) fn reimplemented_starmap(checker: &mut Checker, target: &StarmapCandi return; }; - // Here we want to check that `args` and `elts` are the same (same length, same elements, - // same order). - if elts.len() != args.len() - || !std::iter::zip(elts, args) - .all(|(x, y)| ComparableExpr::from(x) == ComparableExpr::from(y)) - { - return; + match value { + // Ex) `f(*x) for x in iter` + ComprehensionTarget::Name(name) => { + let [arg] = args else { + return; + }; + + let Expr::Starred(ast::ExprStarred { value, .. }) = arg else { + return; + }; + + if ComparableExpr::from(value.as_ref()) != ComparableExpr::from(name) { + return; + } + } + // Ex) `f(x, y, z) for x, y, z in iter` + ComprehensionTarget::Tuple(tuple) => { + if tuple.elts.len() != args.len() + || !std::iter::zip(&tuple.elts, args) + .all(|(x, y)| ComparableExpr::from(x) == ComparableExpr::from(y)) + { + return; + } + } } let mut diagnostic = Diagnostic::new(ReimplementedStarmap, target.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - // Try importing `starmap` from `itertools`. - // - // It is not required to be `itertools.starmap`, though. The user might've already - // imported it. Maybe even under a different name. So, we should use that name - // for fix construction. - let (import_edit, starmap_name) = checker.importer().get_or_import_symbol( - &ImportRequest::import_from("itertools", "starmap"), - target.start(), - checker.semantic(), - )?; - // The actual fix suggestion depends on what type of expression we were looking at. - // - // - For generator expressions, we use `starmap` call directly. - // - For list and set comprehensions, we'd want to wrap it with `list` and `set` - // correspondingly. - let main_edit = Edit::range_replacement( - target.try_make_suggestion(starmap_name, iter, func, checker)?, - target.range(), - ); - Ok(Fix::suggested_edits(import_edit, [main_edit])) - }); - } + diagnostic.try_set_fix(|| { + // Try importing `starmap` from `itertools`. + // + // It is not required to be `itertools.starmap`, though. The user might've already + // imported it. Maybe even under a different name. So, we should use that name + // for fix construction. + let (import_edit, starmap_name) = checker.importer().get_or_import_symbol( + &ImportRequest::import_from("itertools", "starmap"), + target.start(), + checker.semantic(), + )?; + // The actual fix suggestion depends on what type of expression we were looking at. + // + // - For generator expressions, we use `starmap` call directly. + // - For list and set comprehensions, we'd want to wrap it with `list` and `set` + // correspondingly. + let main_edit = Edit::range_replacement( + target.try_make_suggestion(starmap_name, &comprehension.iter, func, checker)?, + target.range(), + ); + Ok(Fix::safe_edits(import_edit, [main_edit])) + }); checker.diagnostics.push(diagnostic); } @@ -252,7 +276,7 @@ fn try_construct_call( // We can only do our fix if `builtin` identifier is still bound to // the built-in type. if !checker.semantic().is_builtin(builtin) { - bail!(format!("Can't use built-in `{builtin}` constructor")) + bail!("Can't use built-in `{builtin}` constructor") } // In general, we replace: @@ -306,14 +330,24 @@ fn wrap_with_call_to(call: ast::ExprCall, func_name: &str) -> ast::ExprCall { } } -/// Match that the given comprehension is `(x, y, z, ...) in iter`. -fn match_comprehension(comprehension: &ast::Comprehension) -> Option<(&[Expr], &Expr)> { +#[derive(Debug)] +enum ComprehensionTarget<'a> { + /// E.g., `(x, y, z, ...)` in `(x, y, z, ...) in iter`. + Tuple(&'a ast::ExprTuple), + /// E.g., `x` in `x in iter`. + Name(&'a ast::ExprName), +} + +/// Extract the target from the comprehension (e.g., `(x, y, z)` in `(x, y, z, ...) in iter`). +fn match_comprehension_target(comprehension: &ast::Comprehension) -> Option { if comprehension.is_async || !comprehension.ifs.is_empty() { return None; } - - let ast::ExprTuple { elts, .. } = comprehension.target.as_tuple_expr()?; - Some((elts, &comprehension.iter)) + match &comprehension.target { + Expr::Tuple(tuple) => Some(ComprehensionTarget::Tuple(tuple)), + Expr::Name(name) => Some(ComprehensionTarget::Name(name)), + _ => None, + } } /// Match that the given expression is `func(x, y, z, ...)`. diff --git a/crates/ruff_linter/src/rules/refurb/rules/repeated_append.rs b/crates/ruff_linter/src/rules/refurb/rules/repeated_append.rs index 90737de73979b..7ca2ab2accae4 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/repeated_append.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/repeated_append.rs @@ -1,7 +1,7 @@ use rustc_hash::FxHashMap; use ast::traversal; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Expr, Stmt}; use ruff_python_codegen::Generator; @@ -9,9 +9,8 @@ use ruff_python_semantic::analyze::typing::is_list; use ruff_python_semantic::{Binding, BindingId, DefinitionId, SemanticModel}; use ruff_text_size::{Ranged, TextRange}; -use crate::autofix::snippet::SourceCodeSnippet; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix::snippet::SourceCodeSnippet; /// ## What it does /// Checks for consecutive calls to `append`. @@ -60,7 +59,7 @@ impl RepeatedAppend { } impl Violation for RepeatedAppend { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -69,7 +68,7 @@ impl Violation for RepeatedAppend { format!("Use `{suggestion}` instead of repeatedly calling `{name}.append()`") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let suggestion = self.suggestion(); Some(format!("Replace with `{suggestion}`")) } @@ -107,8 +106,8 @@ pub(crate) fn repeated_append(checker: &mut Checker, stmt: &Stmt) { // We only suggest a fix when all appends in a group are clumped together. If they're // non-consecutive, fixing them is much more difficult. - if checker.patch(diagnostic.kind.rule()) && group.is_consecutive { - diagnostic.set_fix(Fix::suggested(Edit::replacement( + if group.is_consecutive { + diagnostic.set_fix(Fix::unsafe_edit(Edit::replacement( replacement, group.start(), group.end(), diff --git a/crates/ruff_linter/src/rules/refurb/rules/single_item_membership_test.rs b/crates/ruff_linter/src/rules/refurb/rules/single_item_membership_test.rs new file mode 100644 index 0000000000000..8e828942bf3aa --- /dev/null +++ b/crates/ruff_linter/src/rules/refurb/rules/single_item_membership_test.rs @@ -0,0 +1,129 @@ +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::helpers::generate_comparison; +use ruff_python_ast::ExprConstant; +use ruff_python_ast::{CmpOp, Constant, Expr}; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; +use crate::fix::edits::pad; + +/// ## What it does +/// Checks for membership tests against single-item containers. +/// +/// ## Why is this bad? +/// Performing a membership test against a container (like a `list` or `set`) +/// with a single item is less readable and less efficient than comparing +/// against the item directly. +/// +/// ## Example +/// ```python +/// 1 in [1] +/// ``` +/// +/// Use instead: +/// ```python +/// 1 == 1 +/// ``` +/// +/// ## References +/// - [Python documentation: Comparisons](https://docs.python.org/3/reference/expressions.html#comparisons) +/// - [Python documentation: Membership test operations](https://docs.python.org/3/reference/expressions.html#membership-test-operations) +#[violation] +pub struct SingleItemMembershipTest { + membership_test: MembershipTest, +} + +impl Violation for SingleItemMembershipTest { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; + + #[derive_message_formats] + fn message(&self) -> String { + format!("Membership test against single-item container") + } + + fn fix_title(&self) -> Option { + let SingleItemMembershipTest { membership_test } = self; + match membership_test { + MembershipTest::In => Some("Convert to equality test".to_string()), + MembershipTest::NotIn => Some("Convert to inequality test".to_string()), + } + } +} + +/// FURB171 +pub(crate) fn single_item_membership_test( + checker: &mut Checker, + expr: &Expr, + left: &Expr, + ops: &[CmpOp], + comparators: &[Expr], +) { + let ([op], [right]) = (ops, comparators) else { + return; + }; + + // Ensure that the comparison is a membership test. + let membership_test = match op { + CmpOp::In => MembershipTest::In, + CmpOp::NotIn => MembershipTest::NotIn, + _ => return, + }; + + // Check if the right-hand side is a single-item object. + let Some(item) = single_item(right) else { + return; + }; + + let mut diagnostic = + Diagnostic::new(SingleItemMembershipTest { membership_test }, expr.range()); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + pad( + generate_comparison( + left, + &[membership_test.replacement_op()], + &[item.clone()], + expr.into(), + checker.indexer().comment_ranges(), + checker.locator(), + ), + expr.range(), + checker.locator(), + ), + expr.range(), + ))); + checker.diagnostics.push(diagnostic); +} + +/// Return the single item wrapped in Some if the expression contains a single +/// item, otherwise return None. +fn single_item(expr: &Expr) -> Option<&Expr> { + match expr { + Expr::List(list) if list.elts.len() == 1 => Some(&list.elts[0]), + Expr::Tuple(tuple) if tuple.elts.len() == 1 => Some(&tuple.elts[0]), + Expr::Set(set) if set.elts.len() == 1 => Some(&set.elts[0]), + string_expr @ Expr::Constant(ExprConstant { + value: Constant::Str(string), + .. + }) if string.chars().count() == 1 => Some(string_expr), + _ => None, + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum MembershipTest { + /// Ex) `1 in [1]` + In, + /// Ex) `1 not in [1]` + NotIn, +} + +impl MembershipTest { + /// Returns the replacement comparison operator for this membership test. + fn replacement_op(self) -> CmpOp { + match self { + MembershipTest::In => CmpOp::Eq, + MembershipTest::NotIn => CmpOp::NotEq, + } + } +} diff --git a/crates/ruff_linter/src/rules/refurb/rules/slice_copy.rs b/crates/ruff_linter/src/rules/refurb/rules/slice_copy.rs index 348c7772766f9..3d4e6a203d8a1 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/slice_copy.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/slice_copy.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Expr}; use ruff_python_semantic::analyze::typing::is_list; @@ -6,7 +6,7 @@ use ruff_python_semantic::{Binding, SemanticModel}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; + use crate::rules::refurb::helpers::generate_method_call; /// ## What it does @@ -39,14 +39,14 @@ use crate::rules::refurb::helpers::generate_method_call; pub struct SliceCopy; impl Violation for SliceCopy { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("Prefer `copy` method over slicing") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { Some("Replace with `copy()`".to_string()) } } @@ -61,14 +61,12 @@ pub(crate) fn slice_copy(checker: &mut Checker, subscript: &ast::ExprSubscript) return; }; let mut diagnostic = Diagnostic::new(SliceCopy, subscript.range()); - if checker.patch(diagnostic.kind.rule()) { - let replacement = generate_method_call(name, "copy", checker.generator()); - diagnostic.set_fix(Fix::suggested(Edit::replacement( - replacement, - subscript.start(), - subscript.end(), - ))); - } + let replacement = generate_method_call(name, "copy", checker.generator()); + diagnostic.set_fix(Fix::safe_edit(Edit::replacement( + replacement, + subscript.start(), + subscript.end(), + ))); checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/refurb/rules/unnecessary_enumerate.rs b/crates/ruff_linter/src/rules/refurb/rules/unnecessary_enumerate.rs index a8a6fceffd198..b5652ec02b0be 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/unnecessary_enumerate.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/unnecessary_enumerate.rs @@ -1,17 +1,16 @@ use std::fmt; -use num_traits::Zero; - -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast as ast; -use ruff_python_ast::{Arguments, Constant, Expr}; +use ruff_python_ast::{Arguments, Constant, Expr, Int}; use ruff_python_codegen::Generator; +use ruff_python_semantic::analyze::typing::{is_dict, is_list, is_set, is_tuple}; +use ruff_python_semantic::Binding; use ruff_text_size::{Ranged, TextRange}; -use crate::autofix::edits::pad; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix::edits::pad; /// ## What it does /// Checks for uses of `enumerate` that discard either the index or the value @@ -25,6 +24,16 @@ use crate::registry::AsRule; /// `range(len(...))` or the sequence itself, respectively, instead. This is /// more efficient and communicates the intent of the code more clearly. /// +/// ## Known problems +/// This rule is prone to false negatives due to type inference limitations; +/// namely, it will only suggest a fix using the `len` builtin function if the +/// sequence passed to `enumerate` is an instantiated as a list, set, dict, or +/// tuple literal, or annotated as such with a type annotation. +/// +/// The `len` builtin function is not defined for all object types (such as +/// generators), and so refactoring to use `len` over `enumerate` is not always +/// safe. +/// /// ## Example /// ```python /// for index, _ in enumerate(sequence): @@ -53,7 +62,7 @@ pub struct UnnecessaryEnumerate { } impl Violation for UnnecessaryEnumerate { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -68,7 +77,7 @@ impl Violation for UnnecessaryEnumerate { } } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let UnnecessaryEnumerate { subset } = self; match subset { EnumerateSubset::Indices => Some("Replace with `range(len(...))`".to_string()), @@ -129,22 +138,40 @@ pub(crate) fn unnecessary_enumerate(checker: &mut Checker, stmt_for: &ast::StmtF ); // The index is unused, so replace with `for value in sequence`. - if checker.patch(diagnostic.kind.rule()) { - let replace_iter = Edit::range_replacement(sequence.into(), stmt_for.iter.range()); - let replace_target = Edit::range_replacement( - pad( - checker.locator().slice(value).to_string(), - stmt_for.target.range(), - checker.locator(), - ), + let replace_iter = Edit::range_replacement(sequence.into(), stmt_for.iter.range()); + let replace_target = Edit::range_replacement( + pad( + checker.locator().slice(value).to_string(), stmt_for.target.range(), - ); - diagnostic.set_fix(Fix::suggested_edits(replace_iter, [replace_target])); - } + checker.locator(), + ), + stmt_for.target.range(), + ); + diagnostic.set_fix(Fix::unsafe_edits(replace_iter, [replace_target])); checker.diagnostics.push(diagnostic); } (false, true) => { + // Ensure the sequence object works with `len`. If it doesn't, the + // fix is unclear. + let scope = checker.semantic().current_scope(); + let bindings: Vec<&Binding> = scope + .get_all(sequence) + .map(|binding_id| checker.semantic().binding(binding_id)) + .collect(); + let [binding] = bindings.as_slice() else { + return; + }; + // This will lead to a lot of false negatives, but it is the best + // we can do with the current type inference. + if !is_list(binding, checker.semantic()) + && !is_dict(binding, checker.semantic()) + && !is_set(binding, checker.semantic()) + && !is_tuple(binding, checker.semantic()) + { + return; + } + // The value is unused, so replace with `for index in range(len(sequence))`. let mut diagnostic = Diagnostic::new( UnnecessaryEnumerate { @@ -152,23 +179,18 @@ pub(crate) fn unnecessary_enumerate(checker: &mut Checker, stmt_for: &ast::StmtF }, func.range(), ); - if checker.patch(diagnostic.kind.rule()) - && checker.semantic().is_builtin("range") - && checker.semantic().is_builtin("len") - { + if checker.semantic().is_builtin("range") && checker.semantic().is_builtin("len") { // If the `start` argument is set to something other than the `range` default, // there's no clear fix. let start = arguments.find_argument("start", 1); if start.map_or(true, |start| { - if let Expr::Constant(ast::ExprConstant { - value: Constant::Int(value), - .. - }) = start - { - value.is_zero() - } else { - false - } + matches!( + start, + Expr::Constant(ast::ExprConstant { + value: Constant::Int(Int::ZERO), + .. + }) + ) }) { let replace_iter = Edit::range_replacement( generate_range_len_call(sequence, checker.generator()), @@ -184,7 +206,7 @@ pub(crate) fn unnecessary_enumerate(checker: &mut Checker, stmt_for: &ast::StmtF stmt_for.target.range(), ); - diagnostic.set_fix(Fix::suggested_edits(replace_iter, [replace_target])); + diagnostic.set_fix(Fix::unsafe_edits(replace_iter, [replace_target])); } } checker.diagnostics.push(diagnostic); diff --git a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB101_FURB101.py.snap b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB101_FURB101.py.snap new file mode 100644 index 0000000000000..6b3595549841c --- /dev/null +++ b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB101_FURB101.py.snap @@ -0,0 +1,96 @@ +--- +source: crates/ruff_linter/src/rules/refurb/mod.rs +--- +FURB101.py:12:6: FURB101 `open` and `read` should be replaced by `Path("file.txt").read_text()` + | +11 | # FURB101 +12 | with open("file.txt") as f: + | ^^^^^^^^^^^^^^^^^^^^^ FURB101 +13 | x = f.read() + | + +FURB101.py:16:6: FURB101 `open` and `read` should be replaced by `Path("file.txt").read_bytes()` + | +15 | # FURB101 +16 | with open("file.txt", "rb") as f: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB101 +17 | x = f.read() + | + +FURB101.py:20:6: FURB101 `open` and `read` should be replaced by `Path("file.txt").read_bytes()` + | +19 | # FURB101 +20 | with open("file.txt", mode="rb") as f: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB101 +21 | x = f.read() + | + +FURB101.py:24:6: FURB101 `open` and `read` should be replaced by `Path("file.txt").read_text(encoding="utf8")` + | +23 | # FURB101 +24 | with open("file.txt", encoding="utf8") as f: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB101 +25 | x = f.read() + | + +FURB101.py:28:6: FURB101 `open` and `read` should be replaced by `Path("file.txt").read_text(errors="ignore")` + | +27 | # FURB101 +28 | with open("file.txt", errors="ignore") as f: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB101 +29 | x = f.read() + | + +FURB101.py:32:6: FURB101 `open` and `read` should be replaced by `Path("file.txt").read_bytes(errors="ignore")` + | +31 | # FURB101 +32 | with open("file.txt", errors="ignore", mode="rb") as f: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB101 +33 | x = f.read() + | + +FURB101.py:36:6: FURB101 `open` and `read` should be replaced by `Path("file.txt").read_text()` + | +35 | # FURB101 +36 | with open("file.txt", mode="r") as f: # noqa: FURB120 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB101 +37 | x = f.read() + | + +FURB101.py:40:6: FURB101 `open` and `read` should be replaced by `Path(foo()).read_bytes()` + | +39 | # FURB101 +40 | with open(foo(), "rb") as f: + | ^^^^^^^^^^^^^^^^^^^^^^ FURB101 +41 | # The body of `with` is non-trivial, but the recommendation holds. +42 | bar("pre") + | + +FURB101.py:48:6: FURB101 `open` and `read` should be replaced by `Path("a.txt").read_text()` + | +47 | # FURB101 +48 | with open("a.txt") as a, open("b.txt", "rb") as b: + | ^^^^^^^^^^^^^^^^^^ FURB101 +49 | x = a.read() +50 | y = b.read() + | + +FURB101.py:48:26: FURB101 `open` and `read` should be replaced by `Path("b.txt").read_bytes()` + | +47 | # FURB101 +48 | with open("a.txt") as a, open("b.txt", "rb") as b: + | ^^^^^^^^^^^^^^^^^^^^^^^^ FURB101 +49 | x = a.read() +50 | y = b.read() + | + +FURB101.py:53:18: FURB101 `open` and `read` should be replaced by `Path("file.txt").read_text()` + | +52 | # FURB101 +53 | with foo() as a, open("file.txt") as b, foo() as c: + | ^^^^^^^^^^^^^^^^^^^^^ FURB101 +54 | # We have other things in here, multiple with items, but +55 | # the user reads the whole file and that bit they can replace. + | + + diff --git a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB105_FURB105.py.snap b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB105_FURB105.py.snap index ebec270762c4c..666614e28fc4a 100644 --- a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB105_FURB105.py.snap +++ b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB105_FURB105.py.snap @@ -12,7 +12,7 @@ FURB105.py:3:1: FURB105 [*] Unnecessary empty string passed to `print` | = help: Remove empty string -ℹ Suggested fix +ℹ Fix 1 1 | # Errors. 2 2 | 3 |-print("") @@ -31,7 +31,7 @@ FURB105.py:4:1: FURB105 [*] Unnecessary empty string and separator passed to `pr | = help: Remove empty string and separator -ℹ Suggested fix +ℹ Fix 1 1 | # Errors. 2 2 | 3 3 | print("") @@ -52,7 +52,7 @@ FURB105.py:5:1: FURB105 [*] Unnecessary empty string passed to `print` | = help: Remove empty string -ℹ Suggested fix +ℹ Fix 2 2 | 3 3 | print("") 4 4 | print("", sep=",") @@ -73,7 +73,7 @@ FURB105.py:6:1: FURB105 [*] Unnecessary empty string and separator passed to `pr | = help: Remove empty string and separator -ℹ Suggested fix +ℹ Fix 3 3 | print("") 4 4 | print("", sep=",") 5 5 | print("", end="bar") @@ -94,7 +94,7 @@ FURB105.py:7:1: FURB105 [*] Unnecessary separator passed to `print` | = help: Remove separator -ℹ Suggested fix +ℹ Fix 4 4 | print("", sep=",") 5 5 | print("", end="bar") 6 6 | print("", sep=",", end="bar") @@ -115,7 +115,7 @@ FURB105.py:8:1: FURB105 [*] Unnecessary empty string and separator passed to `pr | = help: Remove empty string and separator -ℹ Suggested fix +ℹ Fix 5 5 | print("", end="bar") 6 6 | print("", sep=",", end="bar") 7 7 | print(sep="") @@ -136,7 +136,7 @@ FURB105.py:9:1: FURB105 [*] Unnecessary empty string and separator passed to `pr | = help: Remove empty string and separator -ℹ Suggested fix +ℹ Fix 6 6 | print("", sep=",", end="bar") 7 7 | print(sep="") 8 8 | print("", sep="") @@ -157,7 +157,7 @@ FURB105.py:10:1: FURB105 [*] Unnecessary empty string and separator passed to `p | = help: Remove empty string and separator -ℹ Suggested fix +ℹ Fix 7 7 | print(sep="") 8 8 | print("", sep="") 9 9 | print("", "", sep="") @@ -178,7 +178,7 @@ FURB105.py:11:1: FURB105 [*] Unnecessary empty string and separator passed to `p | = help: Remove empty string and separator -ℹ Suggested fix +ℹ Fix 8 8 | print("", sep="") 9 9 | print("", "", sep="") 10 10 | print("", "", sep="", end="") @@ -199,7 +199,7 @@ FURB105.py:12:1: FURB105 [*] Unnecessary empty string and separator passed to `p | = help: Remove empty string and separator -ℹ Suggested fix +ℹ Fix 9 9 | print("", "", sep="") 10 10 | print("", "", sep="", end="") 11 11 | print("", "", sep="", end="bar") @@ -220,7 +220,7 @@ FURB105.py:13:1: FURB105 [*] Unnecessary separator passed to `print` | = help: Remove separator -ℹ Suggested fix +ℹ Fix 10 10 | print("", "", sep="", end="") 11 11 | print("", "", sep="", end="bar") 12 12 | print("", sep="", end="bar") @@ -241,7 +241,7 @@ FURB105.py:14:1: FURB105 [*] Unnecessary empty string and separator passed to `p | = help: Remove empty string and separator -ℹ Suggested fix +ℹ Fix 11 11 | print("", "", sep="", end="bar") 12 12 | print("", sep="", end="bar") 13 13 | print(sep="", end="bar") @@ -262,7 +262,7 @@ FURB105.py:15:1: FURB105 [*] Unnecessary empty string and separator passed to `p | = help: Remove empty string and separator -ℹ Suggested fix +ℹ Fix 12 12 | print("", sep="", end="bar") 13 13 | print(sep="", end="bar") 14 14 | print("", "foo", sep="") @@ -283,7 +283,7 @@ FURB105.py:16:1: FURB105 [*] Unnecessary empty string passed to `print` | = help: Remove empty string -ℹ Suggested fix +ℹ Fix 13 13 | print(sep="", end="bar") 14 14 | print("", "foo", sep="") 15 15 | print("foo", "", sep="") @@ -304,7 +304,7 @@ FURB105.py:18:1: FURB105 [*] Unnecessary empty string passed to `print` | = help: Remove empty string -ℹ Suggested fix +ℹ Fix 15 15 | print("foo", "", sep="") 16 16 | print("foo", "", "bar", sep="") 17 17 | print("", *args) @@ -324,7 +324,7 @@ FURB105.py:19:1: FURB105 [*] Unnecessary empty string passed to `print` | = help: Remove empty string -ℹ Suggested fix +ℹ Fix 16 16 | print("foo", "", "bar", sep="") 17 17 | print("", *args) 18 18 | print("", *args, sep="") @@ -345,7 +345,7 @@ FURB105.py:20:1: FURB105 [*] Unnecessary separator passed to `print` | = help: Remove separator -ℹ Suggested fix +ℹ Fix 17 17 | print("", *args) 18 18 | print("", *args, sep="") 19 19 | print("", **kwargs) diff --git a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB140_FURB140.py.snap b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB140_FURB140.py.snap index 1e7691809d56d..84f88f6d4d575 100644 --- a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB140_FURB140.py.snap +++ b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB140_FURB140.py.snap @@ -11,7 +11,7 @@ FURB140.py:7:1: FURB140 [*] Use `itertools.starmap` instead of the generator | = help: Replace with `itertools.starmap` -ℹ Suggested fix +ℹ Fix 1 |+from itertools import starmap 1 2 | def zipped(): 2 3 | return zip([1, 2, 3], "ABC") @@ -35,7 +35,7 @@ FURB140.py:10:1: FURB140 [*] Use `itertools.starmap` instead of the generator | = help: Replace with `itertools.starmap` -ℹ Suggested fix +ℹ Fix 1 |+from itertools import starmap 1 2 | def zipped(): 2 3 | return zip([1, 2, 3], "ABC") @@ -58,7 +58,7 @@ FURB140.py:13:1: FURB140 [*] Use `itertools.starmap` instead of the generator | = help: Replace with `itertools.starmap` -ℹ Suggested fix +ℹ Fix 1 |+from itertools import starmap 1 2 | def zipped(): 2 3 | return zip([1, 2, 3], "ABC") @@ -83,7 +83,7 @@ FURB140.py:19:1: FURB140 [*] Use `itertools.starmap` instead of the generator | = help: Replace with `itertools.starmap` -ℹ Suggested fix +ℹ Fix 16 16 | from itertools import starmap as sm 17 17 | 18 18 | # FURB140 @@ -103,7 +103,7 @@ FURB140.py:22:1: FURB140 [*] Use `itertools.starmap` instead of the generator | = help: Replace with `itertools.starmap` -ℹ Suggested fix +ℹ Fix 19 19 | [print(x, y) for x, y in zipped()] 20 20 | 21 21 | # FURB140 @@ -119,18 +119,80 @@ FURB140.py:25:1: FURB140 [*] Use `itertools.starmap` instead of the generator 25 | {print(x, y) for x, y in zipped()} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB140 26 | -27 | # Non-errors. +27 | # FURB140 (check it still flags starred arguments). | = help: Replace with `itertools.starmap` -ℹ Suggested fix +ℹ Fix 22 22 | (print(x, y) for x, y in zipped()) 23 23 | 24 24 | # FURB140 25 |-{print(x, y) for x, y in zipped()} 25 |+set(sm(print, zipped())) 26 26 | -27 27 | # Non-errors. -28 28 | +27 27 | # FURB140 (check it still flags starred arguments). +28 28 | # See https://github.com/astral-sh/ruff/issues/7636 + +FURB140.py:29:1: FURB140 [*] Use `itertools.starmap` instead of the generator + | +27 | # FURB140 (check it still flags starred arguments). +28 | # See https://github.com/astral-sh/ruff/issues/7636 +29 | [foo(*t) for t in [(85, 60), (100, 80)]] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB140 +30 | (foo(*t) for t in [(85, 60), (100, 80)]) +31 | {foo(*t) for t in [(85, 60), (100, 80)]} + | + = help: Replace with `itertools.starmap` + +ℹ Fix +26 26 | +27 27 | # FURB140 (check it still flags starred arguments). +28 28 | # See https://github.com/astral-sh/ruff/issues/7636 +29 |-[foo(*t) for t in [(85, 60), (100, 80)]] + 29 |+list(sm(foo, [(85, 60), (100, 80)])) +30 30 | (foo(*t) for t in [(85, 60), (100, 80)]) +31 31 | {foo(*t) for t in [(85, 60), (100, 80)]} +32 32 | + +FURB140.py:30:1: FURB140 [*] Use `itertools.starmap` instead of the generator + | +28 | # See https://github.com/astral-sh/ruff/issues/7636 +29 | [foo(*t) for t in [(85, 60), (100, 80)]] +30 | (foo(*t) for t in [(85, 60), (100, 80)]) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB140 +31 | {foo(*t) for t in [(85, 60), (100, 80)]} + | + = help: Replace with `itertools.starmap` + +ℹ Fix +27 27 | # FURB140 (check it still flags starred arguments). +28 28 | # See https://github.com/astral-sh/ruff/issues/7636 +29 29 | [foo(*t) for t in [(85, 60), (100, 80)]] +30 |-(foo(*t) for t in [(85, 60), (100, 80)]) + 30 |+sm(foo, [(85, 60), (100, 80)]) +31 31 | {foo(*t) for t in [(85, 60), (100, 80)]} +32 32 | +33 33 | # Non-errors. + +FURB140.py:31:1: FURB140 [*] Use `itertools.starmap` instead of the generator + | +29 | [foo(*t) for t in [(85, 60), (100, 80)]] +30 | (foo(*t) for t in [(85, 60), (100, 80)]) +31 | {foo(*t) for t in [(85, 60), (100, 80)]} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB140 +32 | +33 | # Non-errors. + | + = help: Replace with `itertools.starmap` + +ℹ Fix +28 28 | # See https://github.com/astral-sh/ruff/issues/7636 +29 29 | [foo(*t) for t in [(85, 60), (100, 80)]] +30 30 | (foo(*t) for t in [(85, 60), (100, 80)]) +31 |-{foo(*t) for t in [(85, 60), (100, 80)]} + 31 |+set(sm(foo, [(85, 60), (100, 80)])) +32 32 | +33 33 | # Non-errors. +34 34 | diff --git a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB145_FURB145.py.snap b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB145_FURB145.py.snap index 742f089ebf25d..58da9fd51a914 100644 --- a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB145_FURB145.py.snap +++ b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB145_FURB145.py.snap @@ -11,7 +11,7 @@ FURB145.py:4:5: FURB145 [*] Prefer `copy` method over slicing | = help: Replace with `copy()` -ℹ Suggested fix +ℹ Fix 1 1 | l = [1, 2, 3, 4, 5] 2 2 | 3 3 | # Errors. @@ -32,7 +32,7 @@ FURB145.py:5:11: FURB145 [*] Prefer `copy` method over slicing | = help: Replace with `copy()` -ℹ Suggested fix +ℹ Fix 2 2 | 3 3 | # Errors. 4 4 | a = l[:] @@ -53,7 +53,7 @@ FURB145.py:6:8: FURB145 [*] Prefer `copy` method over slicing | = help: Replace with `copy()` -ℹ Suggested fix +ℹ Fix 3 3 | # Errors. 4 4 | a = l[:] 5 5 | b, c = 1, l[:] @@ -74,7 +74,7 @@ FURB145.py:7:5: FURB145 [*] Prefer `copy` method over slicing | = help: Replace with `copy()` -ℹ Suggested fix +ℹ Fix 4 4 | a = l[:] 5 5 | b, c = 1, l[:] 6 6 | d, e = l[:], 1 @@ -94,7 +94,7 @@ FURB145.py:8:1: FURB145 [*] Prefer `copy` method over slicing | = help: Replace with `copy()` -ℹ Suggested fix +ℹ Fix 5 5 | b, c = 1, l[:] 6 6 | d, e = l[:], 1 7 7 | m = l[::] @@ -115,7 +115,7 @@ FURB145.py:9:7: FURB145 [*] Prefer `copy` method over slicing | = help: Replace with `copy()` -ℹ Suggested fix +ℹ Fix 6 6 | d, e = l[:], 1 7 7 | m = l[::] 8 8 | l[:] diff --git a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB148_FURB148.py.snap b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB148_FURB148.py.snap index 198097f8fea36..a64560382bb59 100644 --- a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB148_FURB148.py.snap +++ b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB148_FURB148.py.snap @@ -1,323 +1,443 @@ --- source: crates/ruff_linter/src/rules/refurb/mod.rs --- -FURB148.py:4:17: FURB148 [*] `enumerate` value is unused, use `for x in range(len(y))` instead - | -3 | # Errors -4 | for index, _ in enumerate(books): - | ^^^^^^^^^ FURB148 -5 | print(index) - | - = help: Replace with `range(len(...))` +FURB148.py:14:17: FURB148 [*] `enumerate` value is unused, use `for x in range(len(y))` instead + | +13 | # Errors +14 | for index, _ in enumerate(books): + | ^^^^^^^^^ FURB148 +15 | print(index) + | + = help: Replace with `range(len(...))` ℹ Suggested fix -1 1 | books = ["Dune", "Foundation", "Neuromancer"] -2 2 | -3 3 | # Errors -4 |-for index, _ in enumerate(books): - 4 |+for index in range(len(books)): -5 5 | print(index) -6 6 | -7 7 | for index, _ in enumerate(books, start=0): - -FURB148.py:7:17: FURB148 [*] `enumerate` value is unused, use `for x in range(len(y))` instead - | -5 | print(index) -6 | -7 | for index, _ in enumerate(books, start=0): - | ^^^^^^^^^ FURB148 -8 | print(index) - | - = help: Replace with `range(len(...))` +11 11 | books_tuple = ("Dune", "Foundation", "Neuromancer") +12 12 | +13 13 | # Errors +14 |-for index, _ in enumerate(books): + 14 |+for index in range(len(books)): +15 15 | print(index) +16 16 | +17 17 | for index, _ in enumerate(books, start=0): + +FURB148.py:17:17: FURB148 [*] `enumerate` value is unused, use `for x in range(len(y))` instead + | +15 | print(index) +16 | +17 | for index, _ in enumerate(books, start=0): + | ^^^^^^^^^ FURB148 +18 | print(index) + | + = help: Replace with `range(len(...))` ℹ Suggested fix -4 4 | for index, _ in enumerate(books): -5 5 | print(index) -6 6 | -7 |-for index, _ in enumerate(books, start=0): - 7 |+for index in range(len(books)): -8 8 | print(index) -9 9 | -10 10 | for index, _ in enumerate(books, 0): - -FURB148.py:10:17: FURB148 [*] `enumerate` value is unused, use `for x in range(len(y))` instead - | - 8 | print(index) - 9 | -10 | for index, _ in enumerate(books, 0): +14 14 | for index, _ in enumerate(books): +15 15 | print(index) +16 16 | +17 |-for index, _ in enumerate(books, start=0): + 17 |+for index in range(len(books)): +18 18 | print(index) +19 19 | +20 20 | for index, _ in enumerate(books, 0): + +FURB148.py:20:17: FURB148 [*] `enumerate` value is unused, use `for x in range(len(y))` instead + | +18 | print(index) +19 | +20 | for index, _ in enumerate(books, 0): | ^^^^^^^^^ FURB148 -11 | print(index) +21 | print(index) | = help: Replace with `range(len(...))` ℹ Suggested fix -7 7 | for index, _ in enumerate(books, start=0): -8 8 | print(index) -9 9 | -10 |-for index, _ in enumerate(books, 0): - 10 |+for index in range(len(books)): -11 11 | print(index) -12 12 | -13 13 | for index, _ in enumerate(books, start=1): - -FURB148.py:13:17: FURB148 `enumerate` value is unused, use `for x in range(len(y))` instead - | -11 | print(index) -12 | -13 | for index, _ in enumerate(books, start=1): +17 17 | for index, _ in enumerate(books, start=0): +18 18 | print(index) +19 19 | +20 |-for index, _ in enumerate(books, 0): + 20 |+for index in range(len(books)): +21 21 | print(index) +22 22 | +23 23 | for index, _ in enumerate(books, start=1): + +FURB148.py:23:17: FURB148 `enumerate` value is unused, use `for x in range(len(y))` instead + | +21 | print(index) +22 | +23 | for index, _ in enumerate(books, start=1): | ^^^^^^^^^ FURB148 -14 | print(index) +24 | print(index) | = help: Replace with `range(len(...))` -FURB148.py:16:17: FURB148 `enumerate` value is unused, use `for x in range(len(y))` instead +FURB148.py:26:17: FURB148 `enumerate` value is unused, use `for x in range(len(y))` instead | -14 | print(index) -15 | -16 | for index, _ in enumerate(books, 1): +24 | print(index) +25 | +26 | for index, _ in enumerate(books, 1): | ^^^^^^^^^ FURB148 -17 | print(index) +27 | print(index) | = help: Replace with `range(len(...))` -FURB148.py:19:17: FURB148 `enumerate` value is unused, use `for x in range(len(y))` instead +FURB148.py:29:17: FURB148 `enumerate` value is unused, use `for x in range(len(y))` instead | -17 | print(index) -18 | -19 | for index, _ in enumerate(books, start=x): +27 | print(index) +28 | +29 | for index, _ in enumerate(books, start=x): | ^^^^^^^^^ FURB148 -20 | print(book) +30 | print(book) | = help: Replace with `range(len(...))` -FURB148.py:22:17: FURB148 `enumerate` value is unused, use `for x in range(len(y))` instead +FURB148.py:32:17: FURB148 `enumerate` value is unused, use `for x in range(len(y))` instead | -20 | print(book) -21 | -22 | for index, _ in enumerate(books, x): +30 | print(book) +31 | +32 | for index, _ in enumerate(books, x): | ^^^^^^^^^ FURB148 -23 | print(book) +33 | print(book) | = help: Replace with `range(len(...))` -FURB148.py:25:16: FURB148 [*] `enumerate` index is unused, use `for x in y` instead +FURB148.py:35:16: FURB148 [*] `enumerate` index is unused, use `for x in y` instead | -23 | print(book) -24 | -25 | for _, book in enumerate(books): +33 | print(book) +34 | +35 | for _, book in enumerate(books): | ^^^^^^^^^ FURB148 -26 | print(book) +36 | print(book) | = help: Remove `enumerate` ℹ Suggested fix -22 22 | for index, _ in enumerate(books, x): -23 23 | print(book) -24 24 | -25 |-for _, book in enumerate(books): - 25 |+for book in books: -26 26 | print(book) -27 27 | -28 28 | for _, book in enumerate(books, start=0): - -FURB148.py:28:16: FURB148 [*] `enumerate` index is unused, use `for x in y` instead - | -26 | print(book) -27 | -28 | for _, book in enumerate(books, start=0): +32 32 | for index, _ in enumerate(books, x): +33 33 | print(book) +34 34 | +35 |-for _, book in enumerate(books): + 35 |+for book in books: +36 36 | print(book) +37 37 | +38 38 | for _, book in enumerate(books, start=0): + +FURB148.py:38:16: FURB148 [*] `enumerate` index is unused, use `for x in y` instead + | +36 | print(book) +37 | +38 | for _, book in enumerate(books, start=0): | ^^^^^^^^^ FURB148 -29 | print(book) +39 | print(book) | = help: Remove `enumerate` ℹ Suggested fix -25 25 | for _, book in enumerate(books): -26 26 | print(book) -27 27 | -28 |-for _, book in enumerate(books, start=0): - 28 |+for book in books: -29 29 | print(book) -30 30 | -31 31 | for _, book in enumerate(books, 0): - -FURB148.py:31:16: FURB148 [*] `enumerate` index is unused, use `for x in y` instead - | -29 | print(book) -30 | -31 | for _, book in enumerate(books, 0): +35 35 | for _, book in enumerate(books): +36 36 | print(book) +37 37 | +38 |-for _, book in enumerate(books, start=0): + 38 |+for book in books: +39 39 | print(book) +40 40 | +41 41 | for _, book in enumerate(books, 0): + +FURB148.py:41:16: FURB148 [*] `enumerate` index is unused, use `for x in y` instead + | +39 | print(book) +40 | +41 | for _, book in enumerate(books, 0): | ^^^^^^^^^ FURB148 -32 | print(book) +42 | print(book) | = help: Remove `enumerate` ℹ Suggested fix -28 28 | for _, book in enumerate(books, start=0): -29 29 | print(book) -30 30 | -31 |-for _, book in enumerate(books, 0): - 31 |+for book in books: -32 32 | print(book) -33 33 | -34 34 | for _, book in enumerate(books, start=1): - -FURB148.py:34:16: FURB148 [*] `enumerate` index is unused, use `for x in y` instead - | -32 | print(book) -33 | -34 | for _, book in enumerate(books, start=1): +38 38 | for _, book in enumerate(books, start=0): +39 39 | print(book) +40 40 | +41 |-for _, book in enumerate(books, 0): + 41 |+for book in books: +42 42 | print(book) +43 43 | +44 44 | for _, book in enumerate(books, start=1): + +FURB148.py:44:16: FURB148 [*] `enumerate` index is unused, use `for x in y` instead + | +42 | print(book) +43 | +44 | for _, book in enumerate(books, start=1): | ^^^^^^^^^ FURB148 -35 | print(book) +45 | print(book) | = help: Remove `enumerate` ℹ Suggested fix -31 31 | for _, book in enumerate(books, 0): -32 32 | print(book) -33 33 | -34 |-for _, book in enumerate(books, start=1): - 34 |+for book in books: -35 35 | print(book) -36 36 | -37 37 | for _, book in enumerate(books, 1): - -FURB148.py:37:16: FURB148 [*] `enumerate` index is unused, use `for x in y` instead - | -35 | print(book) -36 | -37 | for _, book in enumerate(books, 1): +41 41 | for _, book in enumerate(books, 0): +42 42 | print(book) +43 43 | +44 |-for _, book in enumerate(books, start=1): + 44 |+for book in books: +45 45 | print(book) +46 46 | +47 47 | for _, book in enumerate(books, 1): + +FURB148.py:47:16: FURB148 [*] `enumerate` index is unused, use `for x in y` instead + | +45 | print(book) +46 | +47 | for _, book in enumerate(books, 1): | ^^^^^^^^^ FURB148 -38 | print(book) +48 | print(book) | = help: Remove `enumerate` ℹ Suggested fix -34 34 | for _, book in enumerate(books, start=1): -35 35 | print(book) -36 36 | -37 |-for _, book in enumerate(books, 1): - 37 |+for book in books: -38 38 | print(book) -39 39 | -40 40 | for _, book in enumerate(books, start=x): - -FURB148.py:40:16: FURB148 [*] `enumerate` index is unused, use `for x in y` instead - | -38 | print(book) -39 | -40 | for _, book in enumerate(books, start=x): +44 44 | for _, book in enumerate(books, start=1): +45 45 | print(book) +46 46 | +47 |-for _, book in enumerate(books, 1): + 47 |+for book in books: +48 48 | print(book) +49 49 | +50 50 | for _, book in enumerate(books, start=x): + +FURB148.py:50:16: FURB148 [*] `enumerate` index is unused, use `for x in y` instead + | +48 | print(book) +49 | +50 | for _, book in enumerate(books, start=x): | ^^^^^^^^^ FURB148 -41 | print(book) +51 | print(book) | = help: Remove `enumerate` ℹ Suggested fix -37 37 | for _, book in enumerate(books, 1): -38 38 | print(book) -39 39 | -40 |-for _, book in enumerate(books, start=x): - 40 |+for book in books: -41 41 | print(book) -42 42 | -43 43 | for _, book in enumerate(books, x): - -FURB148.py:43:16: FURB148 [*] `enumerate` index is unused, use `for x in y` instead - | -41 | print(book) -42 | -43 | for _, book in enumerate(books, x): +47 47 | for _, book in enumerate(books, 1): +48 48 | print(book) +49 49 | +50 |-for _, book in enumerate(books, start=x): + 50 |+for book in books: +51 51 | print(book) +52 52 | +53 53 | for _, book in enumerate(books, x): + +FURB148.py:53:16: FURB148 [*] `enumerate` index is unused, use `for x in y` instead + | +51 | print(book) +52 | +53 | for _, book in enumerate(books, x): | ^^^^^^^^^ FURB148 -44 | print(book) +54 | print(book) | = help: Remove `enumerate` ℹ Suggested fix -40 40 | for _, book in enumerate(books, start=x): -41 41 | print(book) -42 42 | -43 |-for _, book in enumerate(books, x): - 43 |+for book in books: -44 44 | print(book) -45 45 | -46 46 | for index, (_, _) in enumerate(books): - -FURB148.py:46:22: FURB148 [*] `enumerate` value is unused, use `for x in range(len(y))` instead - | -44 | print(book) -45 | -46 | for index, (_, _) in enumerate(books): +50 50 | for _, book in enumerate(books, start=x): +51 51 | print(book) +52 52 | +53 |-for _, book in enumerate(books, x): + 53 |+for book in books: +54 54 | print(book) +55 55 | +56 56 | for index, (_, _) in enumerate(books): + +FURB148.py:56:22: FURB148 [*] `enumerate` value is unused, use `for x in range(len(y))` instead + | +54 | print(book) +55 | +56 | for index, (_, _) in enumerate(books): | ^^^^^^^^^ FURB148 -47 | print(index) +57 | print(index) | = help: Replace with `range(len(...))` ℹ Suggested fix -43 43 | for _, book in enumerate(books, x): -44 44 | print(book) -45 45 | -46 |-for index, (_, _) in enumerate(books): - 46 |+for index in range(len(books)): -47 47 | print(index) -48 48 | -49 49 | for (_, _), book in enumerate(books): - -FURB148.py:49:21: FURB148 [*] `enumerate` index is unused, use `for x in y` instead - | -47 | print(index) -48 | -49 | for (_, _), book in enumerate(books): +53 53 | for _, book in enumerate(books, x): +54 54 | print(book) +55 55 | +56 |-for index, (_, _) in enumerate(books): + 56 |+for index in range(len(books)): +57 57 | print(index) +58 58 | +59 59 | for (_, _), book in enumerate(books): + +FURB148.py:59:21: FURB148 [*] `enumerate` index is unused, use `for x in y` instead + | +57 | print(index) +58 | +59 | for (_, _), book in enumerate(books): | ^^^^^^^^^ FURB148 -50 | print(book) +60 | print(book) | = help: Remove `enumerate` ℹ Suggested fix -46 46 | for index, (_, _) in enumerate(books): -47 47 | print(index) -48 48 | -49 |-for (_, _), book in enumerate(books): - 49 |+for book in books: -50 50 | print(book) -51 51 | -52 52 | for(index, _)in enumerate(books): - -FURB148.py:52:17: FURB148 [*] `enumerate` value is unused, use `for x in range(len(y))` instead - | -50 | print(book) -51 | -52 | for(index, _)in enumerate(books): +56 56 | for index, (_, _) in enumerate(books): +57 57 | print(index) +58 58 | +59 |-for (_, _), book in enumerate(books): + 59 |+for book in books: +60 60 | print(book) +61 61 | +62 62 | for(index, _)in enumerate(books): + +FURB148.py:62:17: FURB148 [*] `enumerate` value is unused, use `for x in range(len(y))` instead + | +60 | print(book) +61 | +62 | for(index, _)in enumerate(books): | ^^^^^^^^^ FURB148 -53 | print(index) +63 | print(index) | = help: Replace with `range(len(...))` ℹ Suggested fix -49 49 | for (_, _), book in enumerate(books): -50 50 | print(book) -51 51 | -52 |-for(index, _)in enumerate(books): - 52 |+for index in range(len(books)): -53 53 | print(index) -54 54 | -55 55 | for(index), _ in enumerate(books): - -FURB148.py:55:18: FURB148 [*] `enumerate` value is unused, use `for x in range(len(y))` instead - | -53 | print(index) -54 | -55 | for(index), _ in enumerate(books): +59 59 | for (_, _), book in enumerate(books): +60 60 | print(book) +61 61 | +62 |-for(index, _)in enumerate(books): + 62 |+for index in range(len(books)): +63 63 | print(index) +64 64 | +65 65 | for(index), _ in enumerate(books): + +FURB148.py:65:18: FURB148 [*] `enumerate` value is unused, use `for x in range(len(y))` instead + | +63 | print(index) +64 | +65 | for(index), _ in enumerate(books): | ^^^^^^^^^ FURB148 -56 | print(index) +66 | print(index) | = help: Replace with `range(len(...))` ℹ Suggested fix -52 52 | for(index, _)in enumerate(books): -53 53 | print(index) -54 54 | -55 |-for(index), _ in enumerate(books): - 55 |+for index in range(len(books)): -56 56 | print(index) -57 57 | -58 58 | # OK +62 62 | for(index, _)in enumerate(books): +63 63 | print(index) +64 64 | +65 |-for(index), _ in enumerate(books): + 65 |+for index in range(len(books)): +66 66 | print(index) +67 67 | +68 68 | for index, _ in enumerate(books_and_authors): + +FURB148.py:68:17: FURB148 [*] `enumerate` value is unused, use `for x in range(len(y))` instead + | +66 | print(index) +67 | +68 | for index, _ in enumerate(books_and_authors): + | ^^^^^^^^^ FURB148 +69 | print(index) + | + = help: Replace with `range(len(...))` + +ℹ Suggested fix +65 65 | for(index), _ in enumerate(books): +66 66 | print(index) +67 67 | +68 |-for index, _ in enumerate(books_and_authors): + 68 |+for index in range(len(books_and_authors)): +69 69 | print(index) +70 70 | +71 71 | for _, book in enumerate(books_and_authors): + +FURB148.py:71:16: FURB148 [*] `enumerate` index is unused, use `for x in y` instead + | +69 | print(index) +70 | +71 | for _, book in enumerate(books_and_authors): + | ^^^^^^^^^ FURB148 +72 | print(book) + | + = help: Remove `enumerate` + +ℹ Suggested fix +68 68 | for index, _ in enumerate(books_and_authors): +69 69 | print(index) +70 70 | +71 |-for _, book in enumerate(books_and_authors): + 71 |+for book in books_and_authors: +72 72 | print(book) +73 73 | +74 74 | for index, _ in enumerate(books_set): + +FURB148.py:74:17: FURB148 [*] `enumerate` value is unused, use `for x in range(len(y))` instead + | +72 | print(book) +73 | +74 | for index, _ in enumerate(books_set): + | ^^^^^^^^^ FURB148 +75 | print(index) + | + = help: Replace with `range(len(...))` + +ℹ Suggested fix +71 71 | for _, book in enumerate(books_and_authors): +72 72 | print(book) +73 73 | +74 |-for index, _ in enumerate(books_set): + 74 |+for index in range(len(books_set)): +75 75 | print(index) +76 76 | +77 77 | for _, book in enumerate(books_set): + +FURB148.py:77:16: FURB148 [*] `enumerate` index is unused, use `for x in y` instead + | +75 | print(index) +76 | +77 | for _, book in enumerate(books_set): + | ^^^^^^^^^ FURB148 +78 | print(book) + | + = help: Remove `enumerate` + +ℹ Suggested fix +74 74 | for index, _ in enumerate(books_set): +75 75 | print(index) +76 76 | +77 |-for _, book in enumerate(books_set): + 77 |+for book in books_set: +78 78 | print(book) +79 79 | +80 80 | for index, _ in enumerate(books_tuple): + +FURB148.py:80:17: FURB148 [*] `enumerate` value is unused, use `for x in range(len(y))` instead + | +78 | print(book) +79 | +80 | for index, _ in enumerate(books_tuple): + | ^^^^^^^^^ FURB148 +81 | print(index) + | + = help: Replace with `range(len(...))` + +ℹ Suggested fix +77 77 | for _, book in enumerate(books_set): +78 78 | print(book) +79 79 | +80 |-for index, _ in enumerate(books_tuple): + 80 |+for index in range(len(books_tuple)): +81 81 | print(index) +82 82 | +83 83 | for _, book in enumerate(books_tuple): + +FURB148.py:83:16: FURB148 [*] `enumerate` index is unused, use `for x in y` instead + | +81 | print(index) +82 | +83 | for _, book in enumerate(books_tuple): + | ^^^^^^^^^ FURB148 +84 | print(book) + | + = help: Remove `enumerate` + +ℹ Suggested fix +80 80 | for index, _ in enumerate(books_tuple): +81 81 | print(index) +82 82 | +83 |-for _, book in enumerate(books_tuple): + 83 |+for book in books_tuple: +84 84 | print(book) +85 85 | +86 86 | # OK diff --git a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB171_FURB171.py.snap b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB171_FURB171.py.snap new file mode 100644 index 0000000000000..e1e847ad8d53b --- /dev/null +++ b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB171_FURB171.py.snap @@ -0,0 +1,123 @@ +--- +source: crates/ruff_linter/src/rules/refurb/mod.rs +--- +FURB171.py:3:4: FURB171 [*] Membership test against single-item container + | +1 | # Errors. +2 | +3 | if 1 in (1,): + | ^^^^^^^^^ FURB171 +4 | print("Single-element tuple") + | + = help: Convert to equality test + +ℹ Fix +1 1 | # Errors. +2 2 | +3 |-if 1 in (1,): + 3 |+if 1 == 1: +4 4 | print("Single-element tuple") +5 5 | +6 6 | if 1 in [1]: + +FURB171.py:6:4: FURB171 [*] Membership test against single-item container + | +4 | print("Single-element tuple") +5 | +6 | if 1 in [1]: + | ^^^^^^^^ FURB171 +7 | print("Single-element list") + | + = help: Convert to equality test + +ℹ Fix +3 3 | if 1 in (1,): +4 4 | print("Single-element tuple") +5 5 | +6 |-if 1 in [1]: + 6 |+if 1 == 1: +7 7 | print("Single-element list") +8 8 | +9 9 | if 1 in {1}: + +FURB171.py:9:4: FURB171 [*] Membership test against single-item container + | + 7 | print("Single-element list") + 8 | + 9 | if 1 in {1}: + | ^^^^^^^^ FURB171 +10 | print("Single-element set") + | + = help: Convert to equality test + +ℹ Fix +6 6 | if 1 in [1]: +7 7 | print("Single-element list") +8 8 | +9 |-if 1 in {1}: + 9 |+if 1 == 1: +10 10 | print("Single-element set") +11 11 | +12 12 | if "a" in "a": + +FURB171.py:12:4: FURB171 [*] Membership test against single-item container + | +10 | print("Single-element set") +11 | +12 | if "a" in "a": + | ^^^^^^^^^^ FURB171 +13 | print("Single-element string") + | + = help: Convert to equality test + +ℹ Fix +9 9 | if 1 in {1}: +10 10 | print("Single-element set") +11 11 | +12 |-if "a" in "a": + 12 |+if "a" == "a": +13 13 | print("Single-element string") +14 14 | +15 15 | if 1 not in (1,): + +FURB171.py:15:4: FURB171 [*] Membership test against single-item container + | +13 | print("Single-element string") +14 | +15 | if 1 not in (1,): + | ^^^^^^^^^^^^^ FURB171 +16 | print("Check `not in` membership test") + | + = help: Convert to inequality test + +ℹ Fix +12 12 | if "a" in "a": +13 13 | print("Single-element string") +14 14 | +15 |-if 1 not in (1,): + 15 |+if 1 != 1: +16 16 | print("Check `not in` membership test") +17 17 | +18 18 | if not 1 in (1,): + +FURB171.py:18:8: FURB171 [*] Membership test against single-item container + | +16 | print("Check `not in` membership test") +17 | +18 | if not 1 in (1,): + | ^^^^^^^^^ FURB171 +19 | print("Check the negated membership test") + | + = help: Convert to equality test + +ℹ Fix +15 15 | if 1 not in (1,): +16 16 | print("Check `not in` membership test") +17 17 | +18 |-if not 1 in (1,): + 18 |+if not 1 == 1: +19 19 | print("Check the negated membership test") +20 20 | +21 21 | # Non-errors. + + diff --git a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB177_FURB177.py.snap b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB177_FURB177.py.snap new file mode 100644 index 0000000000000..369b9a893a49d --- /dev/null +++ b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB177_FURB177.py.snap @@ -0,0 +1,94 @@ +--- +source: crates/ruff_linter/src/rules/refurb/mod.rs +--- +FURB177.py:5:5: FURB177 Prefer `Path.cwd()` over `Path().resolve()` for current-directory lookups + | +4 | # Errors +5 | _ = Path().resolve() + | ^^^^^^^^^^^^^^^^ FURB177 +6 | _ = pathlib.Path().resolve() + | + +FURB177.py:6:5: FURB177 Prefer `Path.cwd()` over `Path().resolve()` for current-directory lookups + | +4 | # Errors +5 | _ = Path().resolve() +6 | _ = pathlib.Path().resolve() + | ^^^^^^^^^^^^^^^^^^^^^^^^ FURB177 +7 | +8 | _ = Path("").resolve() + | + +FURB177.py:8:5: FURB177 Prefer `Path.cwd()` over `Path().resolve()` for current-directory lookups + | +6 | _ = pathlib.Path().resolve() +7 | +8 | _ = Path("").resolve() + | ^^^^^^^^^^^^^^^^^^ FURB177 +9 | _ = pathlib.Path("").resolve() + | + +FURB177.py:9:5: FURB177 Prefer `Path.cwd()` over `Path().resolve()` for current-directory lookups + | + 8 | _ = Path("").resolve() + 9 | _ = pathlib.Path("").resolve() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB177 +10 | +11 | _ = Path(".").resolve() + | + +FURB177.py:11:5: FURB177 Prefer `Path.cwd()` over `Path().resolve()` for current-directory lookups + | + 9 | _ = pathlib.Path("").resolve() +10 | +11 | _ = Path(".").resolve() + | ^^^^^^^^^^^^^^^^^^^ FURB177 +12 | _ = pathlib.Path(".").resolve() + | + +FURB177.py:12:5: FURB177 Prefer `Path.cwd()` over `Path().resolve()` for current-directory lookups + | +11 | _ = Path(".").resolve() +12 | _ = pathlib.Path(".").resolve() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB177 +13 | +14 | _ = Path("", **kwargs).resolve() + | + +FURB177.py:14:5: FURB177 Prefer `Path.cwd()` over `Path().resolve()` for current-directory lookups + | +12 | _ = pathlib.Path(".").resolve() +13 | +14 | _ = Path("", **kwargs).resolve() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB177 +15 | _ = pathlib.Path("", **kwargs).resolve() + | + +FURB177.py:15:5: FURB177 Prefer `Path.cwd()` over `Path().resolve()` for current-directory lookups + | +14 | _ = Path("", **kwargs).resolve() +15 | _ = pathlib.Path("", **kwargs).resolve() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB177 +16 | +17 | _ = Path(".", **kwargs).resolve() + | + +FURB177.py:17:5: FURB177 Prefer `Path.cwd()` over `Path().resolve()` for current-directory lookups + | +15 | _ = pathlib.Path("", **kwargs).resolve() +16 | +17 | _ = Path(".", **kwargs).resolve() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB177 +18 | _ = pathlib.Path(".", **kwargs).resolve() + | + +FURB177.py:18:5: FURB177 Prefer `Path.cwd()` over `Path().resolve()` for current-directory lookups + | +17 | _ = Path(".", **kwargs).resolve() +18 | _ = pathlib.Path(".", **kwargs).resolve() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB177 +19 | +20 | # OK + | + + diff --git a/crates/ruff_linter/src/rules/ruff/mod.rs b/crates/ruff_linter/src/rules/ruff/mod.rs index 722caa0bf72c5..6e89cc19c82eb 100644 --- a/crates/ruff_linter/src/rules/ruff/mod.rs +++ b/crates/ruff_linter/src/rules/ruff/mod.rs @@ -40,7 +40,10 @@ mod tests { feature = "unreachable-code", test_case(Rule::UnreachableCode, Path::new("RUF014.py")) )] - #[test_case(Rule::QuadraticListSummation, Path::new("RUF017.py"))] + #[test_case(Rule::QuadraticListSummation, Path::new("RUF017_1.py"))] + #[test_case(Rule::QuadraticListSummation, Path::new("RUF017_0.py"))] + #[test_case(Rule::AssignmentInAssert, Path::new("RUF018.py"))] + #[test_case(Rule::UnnecessaryKeyCheck, Path::new("RUF019.py"))] fn rules(rule_code: Rule, path: &Path) -> Result<()> { let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy()); let diagnostics = test_path( @@ -103,7 +106,26 @@ mod tests { let diagnostics = test_path( Path::new("ruff/RUF100_0.py"), &settings::LinterSettings { - external: FxHashSet::from_iter(vec!["V101".to_string()]), + external: vec!["V101".to_string()], + ..settings::LinterSettings::for_rules(vec![ + Rule::UnusedNOQA, + Rule::LineTooLong, + Rule::UnusedImport, + Rule::UnusedVariable, + Rule::TabIndentation, + ]) + }, + )?; + assert_messages!(diagnostics); + Ok(()) + } + + #[test] + fn ruf100_0_prefix() -> Result<()> { + let diagnostics = test_path( + Path::new("ruff/RUF100_0.py"), + &settings::LinterSettings { + external: vec!["V".to_string()], ..settings::LinterSettings::for_rules(vec![ Rule::UnusedNOQA, Rule::LineTooLong, diff --git a/crates/ruff_linter/src/rules/ruff/rules/ambiguous_unicode_character.rs b/crates/ruff_linter/src/rules/ruff/rules/ambiguous_unicode_character.rs index f105e3754dc7d..5ebe88a11c775 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/ambiguous_unicode_character.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/ambiguous_unicode_character.rs @@ -123,6 +123,7 @@ impl Violation for AmbiguousUnicodeCharacterComment { } } +/// RUF001, RUF002, RUF003 pub(crate) fn ambiguous_unicode_character( diagnostics: &mut Vec, locator: &Locator, diff --git a/crates/ruff_linter/src/rules/ruff/rules/assignment_in_assert.rs b/crates/ruff_linter/src/rules/ruff/rules/assignment_in_assert.rs new file mode 100644 index 0000000000000..05761fe9967df --- /dev/null +++ b/crates/ruff_linter/src/rules/ruff/rules/assignment_in_assert.rs @@ -0,0 +1,53 @@ +use ruff_python_ast::Expr; + +use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for named assignment expressions (e.g., `x := 0`) in `assert` +/// statements. +/// +/// ## Why is this bad? +/// Named assignment expressions (also known as "walrus operators") are used to +/// assign a value to a variable as part of a larger expression. +/// +/// Named assignments are syntactically valid in `assert` statements. However, +/// when the Python interpreter is run under the `-O` flag, `assert` statements +/// are not executed. In this case, the named assignment will also be ignored, +/// which may result in unexpected behavior (e.g., undefined variable +/// accesses). +/// +/// ## Examples +/// ```python +/// assert (x := 0) == 0 +/// ``` +/// +/// Use instead: +/// ```python +/// x = 0 +/// assert x == 0 +/// ``` +/// +/// ## References +/// - [Python documentation: `-O`](https://docs.python.org/3/using/cmdline.html#cmdoption-O) +#[violation] +pub struct AssignmentInAssert; + +impl Violation for AssignmentInAssert { + #[derive_message_formats] + fn message(&self) -> String { + format!("Avoid assignment expressions in `assert` statements") + } +} + +/// RUF018 +pub(crate) fn assignment_in_assert(checker: &mut Checker, value: &Expr) { + if checker.semantic().current_statement().is_assert_stmt() { + checker + .diagnostics + .push(Diagnostic::new(AssignmentInAssert, value.range())); + } +} diff --git a/crates/ruff_linter/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff_linter/src/rules/ruff/rules/collection_literal_concatenation.rs index 012fab42a3659..263ff68dc9258 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -1,11 +1,10 @@ -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Expr, ExprContext, Operator}; use ruff_text_size::{Ranged, TextRange}; -use crate::autofix::snippet::SourceCodeSnippet; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix::snippet::SourceCodeSnippet; /// ## What it does /// Checks for uses of the `+` operator to concatenate collections. @@ -43,7 +42,7 @@ pub struct CollectionLiteralConcatenation { } impl Violation for CollectionLiteralConcatenation { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { @@ -55,7 +54,7 @@ impl Violation for CollectionLiteralConcatenation { } } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let CollectionLiteralConcatenation { expression } = self; if let Some(expression) = expression.full_display() { Some(format!("Replace with `{expression}`")) @@ -198,15 +197,13 @@ pub(crate) fn collection_literal_concatenation(checker: &mut Checker, expr: &Exp }, expr.range(), ); - if checker.patch(diagnostic.kind.rule()) { - if !checker.indexer().has_comments(expr, checker.locator()) { - // This suggestion could be unsafe if the non-literal expression in the - // expression has overridden the `__add__` (or `__radd__`) magic methods. - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - contents, - expr.range(), - ))); - } + if !checker.indexer().has_comments(expr, checker.locator()) { + // This suggestion could be unsafe if the non-literal expression in the + // expression has overridden the `__add__` (or `__radd__`) magic methods. + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + contents, + expr.range(), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/ruff/rules/explicit_f_string_type_conversion.rs b/crates/ruff_linter/src/rules/ruff/rules/explicit_f_string_type_conversion.rs index 11302f4ba295d..1931270157b1a 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/explicit_f_string_type_conversion.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/explicit_f_string_type_conversion.rs @@ -3,7 +3,7 @@ use libcst_native::{ ConcatenatedString, Expression, FormattedStringContent, FormattedStringExpression, }; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::{self as ast, Arguments, Expr}; use ruff_python_codegen::Stylist; @@ -12,7 +12,6 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::cst::matchers::{match_call_mut, match_name, transform_expression}; -use crate::registry::AsRule; /// ## What it does /// Checks for uses of `str()`, `repr()`, and `ascii()` as explicit type @@ -41,13 +40,13 @@ use crate::registry::AsRule; #[violation] pub struct ExplicitFStringTypeConversion; -impl AlwaysAutofixableViolation for ExplicitFStringTypeConversion { +impl AlwaysFixableViolation for ExplicitFStringTypeConversion { #[derive_message_formats] fn message(&self) -> String { format!("Use explicit conversion flag") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Replace with conversion flag".to_string() } } @@ -123,11 +122,9 @@ pub(crate) fn explicit_f_string_type_conversion( } let mut diagnostic = Diagnostic::new(ExplicitFStringTypeConversion, value.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - convert_call_to_conversion_flag(expr, index, checker.locator(), checker.stylist()) - }); - } + diagnostic.try_set_fix(|| { + convert_call_to_conversion_flag(expr, index, checker.locator(), checker.stylist()) + }); checker.diagnostics.push(diagnostic); } } @@ -160,7 +157,7 @@ fn convert_call_to_conversion_flag( formatted_string_expression.expression = call.args[0].value.clone(); Ok(expression) }) - .map(|output| Fix::automatic(Edit::range_replacement(output, expr.range()))) + .map(|output| Fix::safe_edit(Edit::range_replacement(output, expr.range()))) } /// Return the [`FormattedStringContent`] at the given index in an f-string or implicit diff --git a/crates/ruff_linter/src/rules/ruff/rules/helpers.rs b/crates/ruff_linter/src/rules/ruff/rules/helpers.rs index 8ccb070376904..78caf8d18fb5d 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/helpers.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/helpers.rs @@ -49,8 +49,14 @@ pub(super) fn is_dataclass(class_def: &ast::StmtClassDef, semantic: &SemanticMod }) } -/// Returns `true` if the given class is a Pydantic `BaseModel` or `BaseSettings` subclass. -pub(super) fn is_pydantic_model(class_def: &ast::StmtClassDef, semantic: &SemanticModel) -> bool { +/// Returns `true` if the given class has "default copy" semantics. +/// +/// For example, Pydantic `BaseModel` and `BaseSettings` subclassses copy attribute defaults on +/// instance creation. As such, the use of mutable default values is safe for such classes. +pub(super) fn has_default_copy_semantics( + class_def: &ast::StmtClassDef, + semantic: &SemanticModel, +) -> bool { let Some(Arguments { args: bases, .. }) = class_def.arguments.as_deref() else { return false; }; @@ -59,7 +65,7 @@ pub(super) fn is_pydantic_model(class_def: &ast::StmtClassDef, semantic: &Semant semantic.resolve_call_path(expr).is_some_and(|call_path| { matches!( call_path.as_slice(), - ["pydantic", "BaseModel" | "BaseSettings"] + ["pydantic", "BaseModel" | "BaseSettings"] | ["msgspec", "Struct"] ) }) }) diff --git a/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs b/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs index 1a87b6471c435..287ee0fbc1052 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs @@ -2,7 +2,7 @@ use std::fmt; use anyhow::Result; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::is_const_none; use ruff_python_ast::{self as ast, Constant, Expr, Operator, ParameterWithDefault, Parameters}; @@ -11,7 +11,7 @@ use ruff_text_size::{Ranged, TextRange}; use crate::checkers::ast::Checker; use crate::importer::ImportRequest; -use crate::registry::AsRule; + use crate::settings::types::PythonVersion; use super::super::typing::type_hint_explicitly_allows_none; @@ -80,14 +80,14 @@ pub struct ImplicitOptional { } impl Violation for ImplicitOptional { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes; #[derive_message_formats] fn message(&self) -> String { format!("PEP 484 prohibits implicit `Optional`") } - fn autofix_title(&self) -> Option { + fn fix_title(&self) -> Option { let ImplicitOptional { conversion_type } = self; Some(format!("Convert to `{conversion_type}`")) } @@ -134,7 +134,7 @@ fn generate_fix(checker: &Checker, conversion_type: ConversionType, expr: &Expr) range: TextRange::default(), }); let content = checker.generator().expr(&new_expr); - Ok(Fix::suggested(Edit::range_replacement( + Ok(Fix::unsafe_edit(Edit::range_replacement( content, expr.range(), ))) @@ -156,7 +156,7 @@ fn generate_fix(checker: &Checker, conversion_type: ConversionType, expr: &Expr) ctx: ast::ExprContext::Load, }); let content = checker.generator().expr(&new_expr); - Ok(Fix::suggested_edits( + Ok(Fix::unsafe_edits( Edit::range_replacement(content, expr.range()), [import_edit], )) @@ -205,10 +205,8 @@ pub(crate) fn implicit_optional(checker: &mut Checker, parameters: &Parameters) let mut diagnostic = Diagnostic::new(ImplicitOptional { conversion_type }, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - if kind.is_simple() { - diagnostic.try_set_fix(|| generate_fix(checker, conversion_type, expr)); - } + if kind.is_simple() { + diagnostic.try_set_fix(|| generate_fix(checker, conversion_type, expr)); } checker.diagnostics.push(diagnostic); } @@ -226,9 +224,7 @@ pub(crate) fn implicit_optional(checker: &mut Checker, parameters: &Parameters) let mut diagnostic = Diagnostic::new(ImplicitOptional { conversion_type }, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| generate_fix(checker, conversion_type, expr)); - } + diagnostic.try_set_fix(|| generate_fix(checker, conversion_type, expr)); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/ruff/rules/invalid_pyproject_toml.rs b/crates/ruff_linter/src/rules/ruff/rules/invalid_pyproject_toml.rs index fc5482b9c24e2..8d34ea57481d9 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/invalid_pyproject_toml.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/invalid_pyproject_toml.rs @@ -1,4 +1,4 @@ -use ruff_diagnostics::{AutofixKind, Violation}; +use ruff_diagnostics::{FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; /// ## What it does @@ -36,7 +36,7 @@ pub struct InvalidPyprojectToml { } impl Violation for InvalidPyprojectToml { - const AUTOFIX: AutofixKind = AutofixKind::None; + const FIX_AVAILABILITY: FixAvailability = FixAvailability::None; #[derive_message_formats] fn message(&self) -> String { diff --git a/crates/ruff_linter/src/rules/ruff/rules/mod.rs b/crates/ruff_linter/src/rules/ruff/rules/mod.rs index 8ffa324791c30..eddad40cd5419 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/mod.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/mod.rs @@ -1,4 +1,5 @@ pub(crate) use ambiguous_unicode_character::*; +pub(crate) use assignment_in_assert::*; pub(crate) use asyncio_dangling_task::*; pub(crate) use collection_literal_concatenation::*; pub(crate) use explicit_f_string_type_conversion::*; @@ -11,11 +12,13 @@ pub(crate) use mutable_dataclass_default::*; pub(crate) use pairwise_over_zipped::*; pub(crate) use static_key_dict_comprehension::*; pub(crate) use unnecessary_iterable_allocation_for_first_element::*; +pub(crate) use unnecessary_key_check::*; #[cfg(feature = "unreachable-code")] pub(crate) use unreachable::*; pub(crate) use unused_noqa::*; mod ambiguous_unicode_character; +mod assignment_in_assert; mod asyncio_dangling_task; mod collection_literal_concatenation; mod confusables; @@ -30,6 +33,7 @@ mod mutable_dataclass_default; mod pairwise_over_zipped; mod static_key_dict_comprehension; mod unnecessary_iterable_allocation_for_first_element; +mod unnecessary_key_check; #[cfg(feature = "unreachable-code")] pub(crate) mod unreachable; mod unused_noqa; diff --git a/crates/ruff_linter/src/rules/ruff/rules/mutable_class_default.rs b/crates/ruff_linter/src/rules/ruff/rules/mutable_class_default.rs index 85ac38c5fd208..da1e2837512a4 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/mutable_class_default.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/mutable_class_default.rs @@ -7,7 +7,7 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::rules::ruff::rules::helpers::{ - is_class_var_annotation, is_dataclass, is_final_annotation, is_pydantic_model, + has_default_copy_semantics, is_class_var_annotation, is_dataclass, is_final_annotation, is_special_attribute, }; @@ -64,8 +64,8 @@ pub(crate) fn mutable_class_default(checker: &mut Checker, class_def: &ast::Stmt && !is_immutable_annotation(annotation, checker.semantic(), &[]) && !is_dataclass(class_def, checker.semantic()) { - // Avoid Pydantic models, which end up copying defaults on instance creation. - if is_pydantic_model(class_def, checker.semantic()) { + // Avoid, e.g., Pydantic and msgspec models, which end up copying defaults on instance creation. + if has_default_copy_semantics(class_def, checker.semantic()) { return; } @@ -78,8 +78,8 @@ pub(crate) fn mutable_class_default(checker: &mut Checker, class_def: &ast::Stmt if !targets.iter().all(is_special_attribute) && is_mutable_expr(value, checker.semantic()) { - // Avoid Pydantic models, which end up copying defaults on instance creation. - if is_pydantic_model(class_def, checker.semantic()) { + // Avoid, e.g., Pydantic and msgspec models, which end up copying defaults on instance creation. + if has_default_copy_semantics(class_def, checker.semantic()) { return; } diff --git a/crates/ruff_linter/src/rules/ruff/rules/pairwise_over_zipped.rs b/crates/ruff_linter/src/rules/ruff/rules/pairwise_over_zipped.rs index cd366d64fad3f..c6f1de26f1f83 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/pairwise_over_zipped.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/pairwise_over_zipped.rs @@ -1,8 +1,6 @@ -use num_traits::ToPrimitive; -use ruff_python_ast::{self as ast, Constant, Expr, UnaryOp}; - use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast, Constant, Expr, Int}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -45,26 +43,17 @@ impl Violation for PairwiseOverZipped { #[derive(Debug)] struct SliceInfo { - arg_name: String, - slice_start: Option, -} - -impl SliceInfo { - pub(crate) fn new(arg_name: String, slice_start: Option) -> Self { - Self { - arg_name, - slice_start, - } - } + id: String, + slice_start: Option, } -/// Return the argument name, lower bound, and upper bound for an expression, if it's a slice. +/// Return the argument name, lower bound, and upper bound for an expression, if it's a slice. fn match_slice_info(expr: &Expr) -> Option { let Expr::Subscript(ast::ExprSubscript { value, slice, .. }) = expr else { return None; }; - let Expr::Name(ast::ExprName { id: arg_id, .. }) = value.as_ref() else { + let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() else { return None; }; @@ -74,44 +63,40 @@ fn match_slice_info(expr: &Expr) -> Option { // Avoid false positives for slices with a step. if let Some(step) = step { - if let Some(step) = to_bound(step) { - if step != 1 { - return None; - } - } else { + if !matches!( + step.as_ref(), + Expr::Constant(ast::ExprConstant { + value: Constant::Int(Int::ONE), + .. + }) + ) { return None; } } - Some(SliceInfo::new( - arg_id.to_string(), - lower.as_ref().and_then(|expr| to_bound(expr)), - )) -} - -fn to_bound(expr: &Expr) -> Option { - match expr { - Expr::Constant(ast::ExprConstant { - value: Constant::Int(value), - .. - }) => value.to_i64(), - Expr::UnaryOp(ast::ExprUnaryOp { - op: UnaryOp::USub | UnaryOp::Invert, - operand, + // If the slice start is a non-constant, we can't be sure that it's successive. + let slice_start = if let Some(lower) = lower.as_ref() { + let Expr::Constant(ast::ExprConstant { + value: Constant::Int(int), range: _, - }) => { - if let Expr::Constant(ast::ExprConstant { - value: Constant::Int(value), - .. - }) = operand.as_ref() - { - value.to_i64().map(|v| -v) - } else { - None - } - } - _ => None, - } + }) = lower.as_ref() + else { + return None; + }; + + let Some(slice_start) = int.as_i32() else { + return None; + }; + + Some(slice_start) + } else { + None + }; + + Some(SliceInfo { + id: id.to_string(), + slice_start, + }) } /// RUF007 @@ -121,9 +106,9 @@ pub(crate) fn pairwise_over_zipped(checker: &mut Checker, func: &Expr, args: &[E }; // Require exactly two positional arguments. - if args.len() != 2 { + let [first, second] = args else { return; - } + }; // Require the function to be the builtin `zip`. if !(id == "zip" && checker.semantic().is_builtin(id)) { @@ -132,25 +117,28 @@ pub(crate) fn pairwise_over_zipped(checker: &mut Checker, func: &Expr, args: &[E // Allow the first argument to be a `Name` or `Subscript`. let Some(first_arg_info) = ({ - if let Expr::Name(ast::ExprName { id, .. }) = &args[0] { - Some(SliceInfo::new(id.to_string(), None)) + if let Expr::Name(ast::ExprName { id, .. }) = first { + Some(SliceInfo { + id: id.to_string(), + slice_start: None, + }) } else { - match_slice_info(&args[0]) + match_slice_info(first) } }) else { return; }; // Require second argument to be a `Subscript`. - if !args[1].is_subscript_expr() { + if !second.is_subscript_expr() { return; } - let Some(second_arg_info) = match_slice_info(&args[1]) else { + let Some(second_arg_info) = match_slice_info(second) else { return; }; // Verify that the arguments match the same name. - if first_arg_info.arg_name != second_arg_info.arg_name { + if first_arg_info.id != second_arg_info.id { return; } diff --git a/crates/ruff_linter/src/rules/ruff/rules/quadratic_list_summation.rs b/crates/ruff_linter/src/rules/ruff/rules/quadratic_list_summation.rs index 1d85555132c8f..67de3f48eeff5 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/quadratic_list_summation.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/quadratic_list_summation.rs @@ -1,14 +1,16 @@ use anyhow::Result; use itertools::Itertools; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::parenthesize::parenthesized_range; +use ruff_python_ast::AstNode; use ruff_python_ast::{self as ast, Arguments, Expr}; use ruff_python_semantic::SemanticModel; use ruff_text_size::Ranged; +use crate::checkers::ast::Checker; use crate::importer::ImportRequest; -use crate::{checkers::ast::Checker, registry::Rule}; /// ## What it does /// Checks for the use of `sum()` to flatten lists of lists, which has @@ -48,13 +50,13 @@ use crate::{checkers::ast::Checker, registry::Rule}; #[violation] pub struct QuadraticListSummation; -impl AlwaysAutofixableViolation for QuadraticListSummation { +impl AlwaysFixableViolation for QuadraticListSummation { #[derive_message_formats] fn message(&self) -> String { format!("Avoid quadratic list summation") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { format!("Replace with `functools.reduce`") } } @@ -80,9 +82,7 @@ pub(crate) fn quadratic_list_summation(checker: &mut Checker, call: &ast::ExprCa }; let mut diagnostic = Diagnostic::new(QuadraticListSummation, *range); - if checker.patch(Rule::QuadraticListSummation) { - diagnostic.try_set_fix(|| convert_to_reduce(iterable, call, checker)); - } + diagnostic.try_set_fix(|| convert_to_reduce(iterable, call, checker)); checker.diagnostics.push(diagnostic); } @@ -100,9 +100,17 @@ fn convert_to_reduce(iterable: &Expr, call: &ast::ExprCall, checker: &Checker) - checker.semantic(), )?; - let iterable = checker.locator().slice(iterable); - - Ok(Fix::suggested_edits( + let iterable = checker.locator().slice( + parenthesized_range( + iterable.into(), + call.arguments.as_any_node_ref(), + checker.indexer().comment_ranges(), + checker.locator().contents(), + ) + .unwrap_or(iterable.range()), + ); + + Ok(Fix::unsafe_edits( Edit::range_replacement( format!("{reduce_binding}({iadd_binding}, {iterable}, [])"), call.range(), diff --git a/crates/ruff_linter/src/rules/ruff/rules/static_key_dict_comprehension.rs b/crates/ruff_linter/src/rules/ruff/rules/static_key_dict_comprehension.rs index f119eaacd44b3..460495e262ea6 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/static_key_dict_comprehension.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/static_key_dict_comprehension.rs @@ -1,6 +1,6 @@ use ruff_python_ast::Expr; -use crate::autofix::snippet::SourceCodeSnippet; +use crate::fix::snippet::SourceCodeSnippet; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::is_constant; diff --git a/crates/ruff_linter/src/rules/ruff/rules/unnecessary_iterable_allocation_for_first_element.rs b/crates/ruff_linter/src/rules/ruff/rules/unnecessary_iterable_allocation_for_first_element.rs index fe574e09a633d..fc5b0a88b2ee5 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/unnecessary_iterable_allocation_for_first_element.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/unnecessary_iterable_allocation_for_first_element.rs @@ -1,16 +1,14 @@ use std::borrow::Cow; -use num_traits::Zero; - -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::{self as ast, Arguments, Comprehension, Constant, Expr}; +use ruff_python_ast::{self as ast, Arguments, Comprehension, Constant, Expr, Int}; use ruff_python_semantic::SemanticModel; +use ruff_python_stdlib::builtins::is_iterator; use ruff_text_size::{Ranged, TextRange, TextSize}; -use crate::autofix::snippet::SourceCodeSnippet; use crate::checkers::ast::Checker; -use crate::registry::AsRule; +use crate::fix::snippet::SourceCodeSnippet; /// ## What it does /// Checks for uses of `list(...)[0]` that can be replaced with @@ -50,7 +48,7 @@ pub(crate) struct UnnecessaryIterableAllocationForFirstElement { iterable: SourceCodeSnippet, } -impl AlwaysAutofixableViolation for UnnecessaryIterableAllocationForFirstElement { +impl AlwaysFixableViolation for UnnecessaryIterableAllocationForFirstElement { #[derive_message_formats] fn message(&self) -> String { let UnnecessaryIterableAllocationForFirstElement { iterable } = self; @@ -58,7 +56,7 @@ impl AlwaysAutofixableViolation for UnnecessaryIterableAllocationForFirstElement format!("Prefer `next({iterable})` over single element slice") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { let UnnecessaryIterableAllocationForFirstElement { iterable } = self; let iterable = iterable.truncated_display(); format!("Replace with `next({iterable})`") @@ -98,27 +96,23 @@ pub(crate) fn unnecessary_iterable_allocation_for_first_element( *range, ); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - format!("next({iterable})"), - *range, - ))); - } + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + format!("next({iterable})"), + *range, + ))); checker.diagnostics.push(diagnostic); } /// Check that the slice [`Expr`] is a slice of the first element (e.g., `x[0]`). fn is_head_slice(expr: &Expr) -> bool { - if let Expr::Constant(ast::ExprConstant { - value: Constant::Int(value), - .. - }) = expr - { - value.is_zero() - } else { - false - } + matches!( + expr, + Expr::Constant(ast::ExprConstant { + value: Constant::Int(Int::ZERO), + .. + }) + ) } #[derive(Debug)] @@ -189,6 +183,10 @@ fn match_iteration_target(expr: &Expr, semantic: &SemanticModel) -> Option IterationTarget { + range: arg.range(), + iterable: is_func_builtin_iterator(func, semantic), + }, _ => IterationTarget { range: arg.range(), iterable: false, @@ -213,7 +211,24 @@ fn match_iteration_target(expr: &Expr, semantic: &SemanticModel) -> Option { + let [elt] = elts.as_slice() else { + return None; + }; + let Expr::Starred(ast::ExprStarred { value, .. }) = elt else { + return None; + }; + let iterable = if value.is_call_expr() { + is_func_builtin_iterator(&value.as_call_expr()?.func, semantic) + } else { + false + }; + IterationTarget { + range: value.range(), + iterable, + } + } _ => return None, }; @@ -244,3 +259,10 @@ fn match_simple_comprehension(elt: &Expr, generators: &[Comprehension]) -> Optio Some(generator.iter.range()) } + +/// Returns `true` if the function is a builtin iterator. +fn is_func_builtin_iterator(func: &Expr, semantic: &SemanticModel) -> bool { + func.as_name_expr().map_or(false, |func_name| { + is_iterator(func_name.id.as_str()) && semantic.is_builtin(func_name.id.as_str()) + }) +} diff --git a/crates/ruff_linter/src/rules/ruff/rules/unnecessary_key_check.rs b/crates/ruff_linter/src/rules/ruff/rules/unnecessary_key_check.rs new file mode 100644 index 0000000000000..8636619dacf50 --- /dev/null +++ b/crates/ruff_linter/src/rules/ruff/rules/unnecessary_key_check.rs @@ -0,0 +1,131 @@ +use ruff_python_ast::comparable::ComparableExpr; +use ruff_python_ast::{self as ast, BoolOp, CmpOp, Expr}; + +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::helpers::contains_effect; +use ruff_python_ast::parenthesize::parenthesized_range; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for unnecessary key checks prior to accessing a dictionary. +/// +/// ## Why is this bad? +/// When working with dictionaries, the `get` can be used to access a value +/// without having to check if the dictionary contains the relevant key, +/// returning `None` if the key is not present. +/// +/// ## Examples +/// ```python +/// if "key" in dct and dct["key"]: +/// ... +/// ``` +/// +/// Use instead: +/// ```python +/// if dct.get("key"): +/// ... +/// ``` +#[violation] +pub struct UnnecessaryKeyCheck; + +impl AlwaysFixableViolation for UnnecessaryKeyCheck { + #[derive_message_formats] + fn message(&self) -> String { + format!("Unnecessary key check before dictionary access") + } + + fn fix_title(&self) -> String { + format!("Replace with `dict.get`") + } +} + +/// RUF019 +pub(crate) fn unnecessary_key_check(checker: &mut Checker, expr: &Expr) { + if !checker.semantic().in_boolean_test() { + return; + } + + let Expr::BoolOp(ast::ExprBoolOp { + op: BoolOp::And, + values, + .. + }) = expr + else { + return; + }; + + let [left, right] = values.as_slice() else { + return; + }; + + // Left should be, e.g., `key in dct`. + let Expr::Compare(ast::ExprCompare { + left: key_left, + ops, + comparators, + .. + }) = left + else { + return; + }; + + if !matches!(ops.as_slice(), [CmpOp::In]) { + return; + } + + let [obj_left] = comparators.as_slice() else { + return; + }; + + // Right should be, e.g., `dct[key]`. + let Expr::Subscript(ast::ExprSubscript { + value: obj_right, + slice: key_right, + .. + }) = right + else { + return; + }; + + if ComparableExpr::from(obj_left) != ComparableExpr::from(obj_right) + || ComparableExpr::from(key_left) != ComparableExpr::from(key_right) + { + return; + } + + if contains_effect(obj_left, |id| checker.semantic().is_builtin(id)) + || contains_effect(key_left, |id| checker.semantic().is_builtin(id)) + { + return; + } + + let mut diagnostic = Diagnostic::new(UnnecessaryKeyCheck, expr.range()); + diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( + format!( + "{}.get({})", + checker.locator().slice( + parenthesized_range( + obj_right.into(), + right.into(), + checker.indexer().comment_ranges(), + checker.locator().contents(), + ) + .unwrap_or(obj_right.range()) + ), + checker.locator().slice( + parenthesized_range( + key_right.into(), + right.into(), + checker.indexer().comment_ranges(), + checker.locator().contents(), + ) + .unwrap_or(key_right.range()) + ), + ), + expr.range(), + ))); + checker.diagnostics.push(diagnostic); +} diff --git a/crates/ruff_linter/src/rules/ruff/rules/unused_noqa.rs b/crates/ruff_linter/src/rules/ruff/rules/unused_noqa.rs index 877983cb9a76a..828c02a8c3b57 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/unused_noqa.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/unused_noqa.rs @@ -1,6 +1,6 @@ use itertools::Itertools; -use ruff_diagnostics::AlwaysAutofixableViolation; +use ruff_diagnostics::AlwaysFixableViolation; use ruff_macros::{derive_message_formats, violation}; #[derive(Debug, PartialEq, Eq)] @@ -35,14 +35,17 @@ pub struct UnusedCodes { /// foo.bar() /// ``` /// +/// ## Options +/// - `external` +/// /// ## References -/// - [Automatic `noqa` management](https://docs.astral.sh/ruff/configuration/#automatic-noqa-management) +/// - [Ruff error suppression](https://docs.astral.sh/ruff/linter/#error-suppression) #[violation] pub struct UnusedNOQA { pub codes: Option, } -impl AlwaysAutofixableViolation for UnusedNOQA { +impl AlwaysFixableViolation for UnusedNOQA { #[derive_message_formats] fn message(&self) -> String { let UnusedNOQA { codes } = self; @@ -89,7 +92,7 @@ impl AlwaysAutofixableViolation for UnusedNOQA { } } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { "Remove unused `noqa` directive".to_string() } } diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF015_RUF015.py.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF015_RUF015.py.snap index 6e7933a411626..81c22a35feddd 100644 --- a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF015_RUF015.py.snap +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF015_RUF015.py.snap @@ -183,7 +183,7 @@ RUF015.py:38:1: RUF015 [*] Prefer `next(iter(range(10)))` over single element sl 38 |+next(iter(range(10))) 39 39 | list(x.y)[0] 40 40 | list(x["y"])[0] -41 41 | +41 41 | [*range(10)][0] RUF015.py:39:1: RUF015 [*] Prefer `next(iter(x.y))` over single element slice | @@ -192,6 +192,7 @@ RUF015.py:39:1: RUF015 [*] Prefer `next(iter(x.y))` over single element slice 39 | list(x.y)[0] | ^^^^^^^^^^^^ RUF015 40 | list(x["y"])[0] +41 | [*range(10)][0] | = help: Replace with `next(iter(x.y))` @@ -202,8 +203,8 @@ RUF015.py:39:1: RUF015 [*] Prefer `next(iter(x.y))` over single element slice 39 |-list(x.y)[0] 39 |+next(iter(x.y)) 40 40 | list(x["y"])[0] -41 41 | -42 42 | # RUF015 (multi-line) +41 41 | [*range(10)][0] +42 42 | [*x["y"]][0] RUF015.py:40:1: RUF015 [*] Prefer `next(iter(x["y"]))` over single element slice | @@ -211,8 +212,8 @@ RUF015.py:40:1: RUF015 [*] Prefer `next(iter(x["y"]))` over single element slice 39 | list(x.y)[0] 40 | list(x["y"])[0] | ^^^^^^^^^^^^^^^ RUF015 -41 | -42 | # RUF015 (multi-line) +41 | [*range(10)][0] +42 | [*x["y"]][0] | = help: Replace with `next(iter(x["y"]))` @@ -222,33 +223,201 @@ RUF015.py:40:1: RUF015 [*] Prefer `next(iter(x["y"]))` over single element slice 39 39 | list(x.y)[0] 40 |-list(x["y"])[0] 40 |+next(iter(x["y"])) -41 41 | -42 42 | # RUF015 (multi-line) -43 43 | revision_heads_map_ast = [ +41 41 | [*range(10)][0] +42 42 | [*x["y"]][0] +43 43 | [*x.y][0] -RUF015.py:43:26: RUF015 [*] Prefer `next(...)` over single element slice +RUF015.py:41:1: RUF015 [*] Prefer `next(iter(range(10)))` over single element slice | -42 | # RUF015 (multi-line) -43 | revision_heads_map_ast = [ - | __________________________^ -44 | | a -45 | | for a in revision_heads_map_ast_obj.body -46 | | if isinstance(a, ast.Assign) and a.targets[0].id == "REVISION_HEADS_MAP" +39 | list(x.y)[0] +40 | list(x["y"])[0] +41 | [*range(10)][0] + | ^^^^^^^^^^^^^^^ RUF015 +42 | [*x["y"]][0] +43 | [*x.y][0] + | + = help: Replace with `next(iter(range(10)))` + +ℹ Suggested fix +38 38 | list(range(10))[0] +39 39 | list(x.y)[0] +40 40 | list(x["y"])[0] +41 |-[*range(10)][0] + 41 |+next(iter(range(10))) +42 42 | [*x["y"]][0] +43 43 | [*x.y][0] +44 44 | [* x.y][0] + +RUF015.py:42:1: RUF015 [*] Prefer `next(iter(x["y"]))` over single element slice + | +40 | list(x["y"])[0] +41 | [*range(10)][0] +42 | [*x["y"]][0] + | ^^^^^^^^^^^^ RUF015 +43 | [*x.y][0] +44 | [* x.y][0] + | + = help: Replace with `next(iter(x["y"]))` + +ℹ Suggested fix +39 39 | list(x.y)[0] +40 40 | list(x["y"])[0] +41 41 | [*range(10)][0] +42 |-[*x["y"]][0] + 42 |+next(iter(x["y"])) +43 43 | [*x.y][0] +44 44 | [* x.y][0] +45 45 | [ + +RUF015.py:43:1: RUF015 [*] Prefer `next(iter(x.y))` over single element slice + | +41 | [*range(10)][0] +42 | [*x["y"]][0] +43 | [*x.y][0] + | ^^^^^^^^^ RUF015 +44 | [* x.y][0] +45 | [ + | + = help: Replace with `next(iter(x.y))` + +ℹ Suggested fix +40 40 | list(x["y"])[0] +41 41 | [*range(10)][0] +42 42 | [*x["y"]][0] +43 |-[*x.y][0] + 43 |+next(iter(x.y)) +44 44 | [* x.y][0] +45 45 | [ +46 46 | *x.y + +RUF015.py:44:1: RUF015 [*] Prefer `next(iter(x.y))` over single element slice + | +42 | [*x["y"]][0] +43 | [*x.y][0] +44 | [* x.y][0] + | ^^^^^^^^^^ RUF015 +45 | [ +46 | *x.y + | + = help: Replace with `next(iter(x.y))` + +ℹ Suggested fix +41 41 | [*range(10)][0] +42 42 | [*x["y"]][0] +43 43 | [*x.y][0] +44 |-[* x.y][0] + 44 |+next(iter(x.y)) +45 45 | [ +46 46 | *x.y +47 47 | ][0] + +RUF015.py:45:1: RUF015 [*] Prefer `next(iter(x.y))` over single element slice + | +43 | [*x.y][0] +44 | [* x.y][0] +45 | / [ +46 | | *x.y 47 | | ][0] | |____^ RUF015 +48 | +49 | # RUF015 (multi-line) | - = help: Replace with `next(...)` + = help: Replace with `next(iter(x.y))` ℹ Suggested fix -40 40 | list(x["y"])[0] -41 41 | -42 42 | # RUF015 (multi-line) -43 |-revision_heads_map_ast = [ - 43 |+revision_heads_map_ast = next( -44 44 | a -45 45 | for a in revision_heads_map_ast_obj.body -46 46 | if isinstance(a, ast.Assign) and a.targets[0].id == "REVISION_HEADS_MAP" +42 42 | [*x["y"]][0] +43 43 | [*x.y][0] +44 44 | [* x.y][0] +45 |-[ +46 |- *x.y 47 |-][0] - 47 |+) + 45 |+next(iter(x.y)) +48 46 | +49 47 | # RUF015 (multi-line) +50 48 | revision_heads_map_ast = [ + +RUF015.py:50:26: RUF015 [*] Prefer `next(...)` over single element slice + | +49 | # RUF015 (multi-line) +50 | revision_heads_map_ast = [ + | __________________________^ +51 | | a +52 | | for a in revision_heads_map_ast_obj.body +53 | | if isinstance(a, ast.Assign) and a.targets[0].id == "REVISION_HEADS_MAP" +54 | | ][0] + | |____^ RUF015 +55 | +56 | # RUF015 (zip) + | + = help: Replace with `next(...)` + +ℹ Suggested fix +47 47 | ][0] +48 48 | +49 49 | # RUF015 (multi-line) +50 |-revision_heads_map_ast = [ + 50 |+revision_heads_map_ast = next( +51 51 | a +52 52 | for a in revision_heads_map_ast_obj.body +53 53 | if isinstance(a, ast.Assign) and a.targets[0].id == "REVISION_HEADS_MAP" +54 |-][0] + 54 |+) +55 55 | +56 56 | # RUF015 (zip) +57 57 | list(zip(x, y))[0] + +RUF015.py:57:1: RUF015 [*] Prefer `next(zip(x, y))` over single element slice + | +56 | # RUF015 (zip) +57 | list(zip(x, y))[0] + | ^^^^^^^^^^^^^^^^^^ RUF015 +58 | [*zip(x, y)][0] + | + = help: Replace with `next(zip(x, y))` + +ℹ Suggested fix +54 54 | ][0] +55 55 | +56 56 | # RUF015 (zip) +57 |-list(zip(x, y))[0] + 57 |+next(zip(x, y)) +58 58 | [*zip(x, y)][0] +59 59 | +60 60 | + +RUF015.py:58:1: RUF015 [*] Prefer `next(zip(x, y))` over single element slice + | +56 | # RUF015 (zip) +57 | list(zip(x, y))[0] +58 | [*zip(x, y)][0] + | ^^^^^^^^^^^^^^^ RUF015 + | + = help: Replace with `next(zip(x, y))` + +ℹ Suggested fix +55 55 | +56 56 | # RUF015 (zip) +57 57 | list(zip(x, y))[0] +58 |-[*zip(x, y)][0] + 58 |+next(zip(x, y)) +59 59 | +60 60 | +61 61 | def test(): + +RUF015.py:63:5: RUF015 [*] Prefer `next(iter(zip(x, y)))` over single element slice + | +61 | def test(): +62 | zip = list # Overwrite the builtin zip +63 | list(zip(x, y))[0] + | ^^^^^^^^^^^^^^^^^^ RUF015 + | + = help: Replace with `next(iter(zip(x, y)))` + +ℹ Suggested fix +60 60 | +61 61 | def test(): +62 62 | zip = list # Overwrite the builtin zip +63 |- list(zip(x, y))[0] + 63 |+ next(iter(zip(x, y))) diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF017_RUF017.py.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF017_RUF017_0.py.snap similarity index 74% rename from crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF017_RUF017.py.snap rename to crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF017_RUF017_0.py.snap index 17f12d211c0ac..3d30ebbcbbbe6 100644 --- a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF017_RUF017.py.snap +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF017_RUF017_0.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/ruff/mod.rs --- -RUF017.py:5:1: RUF017 [*] Avoid quadratic list summation +RUF017_0.py:5:1: RUF017 [*] Avoid quadratic list summation | 4 | # RUF017 5 | sum([x, y], start=[]) @@ -24,7 +24,7 @@ RUF017.py:5:1: RUF017 [*] Avoid quadratic list summation 7 9 | sum([[1, 2, 3], [4, 5, 6]], start=[]) 8 10 | sum([[1, 2, 3], [4, 5, 6]], []) -RUF017.py:6:1: RUF017 [*] Avoid quadratic list summation +RUF017_0.py:6:1: RUF017 [*] Avoid quadratic list summation | 4 | # RUF017 5 | sum([x, y], start=[]) @@ -49,7 +49,7 @@ RUF017.py:6:1: RUF017 [*] Avoid quadratic list summation 8 10 | sum([[1, 2, 3], [4, 5, 6]], []) 9 11 | sum([[1, 2, 3], [4, 5, 6]], -RUF017.py:7:1: RUF017 [*] Avoid quadratic list summation +RUF017_0.py:7:1: RUF017 [*] Avoid quadratic list summation | 5 | sum([x, y], start=[]) 6 | sum([x, y], []) @@ -75,7 +75,7 @@ RUF017.py:7:1: RUF017 [*] Avoid quadratic list summation 9 11 | sum([[1, 2, 3], [4, 5, 6]], 10 12 | []) -RUF017.py:8:1: RUF017 [*] Avoid quadratic list summation +RUF017_0.py:8:1: RUF017 [*] Avoid quadratic list summation | 6 | sum([x, y], []) 7 | sum([[1, 2, 3], [4, 5, 6]], start=[]) @@ -102,7 +102,7 @@ RUF017.py:8:1: RUF017 [*] Avoid quadratic list summation 10 12 | []) 11 13 | -RUF017.py:9:1: RUF017 [*] Avoid quadratic list summation +RUF017_0.py:9:1: RUF017 [*] Avoid quadratic list summation | 7 | sum([[1, 2, 3], [4, 5, 6]], start=[]) 8 | sum([[1, 2, 3], [4, 5, 6]], []) @@ -131,7 +131,7 @@ RUF017.py:9:1: RUF017 [*] Avoid quadratic list summation 12 13 | # OK 13 14 | sum([x, y]) -RUF017.py:21:5: RUF017 [*] Avoid quadratic list summation +RUF017_0.py:21:5: RUF017 [*] Avoid quadratic list summation | 19 | import functools, operator 20 | @@ -146,5 +146,30 @@ RUF017.py:21:5: RUF017 [*] Avoid quadratic list summation 20 20 | 21 |- sum([x, y], []) 21 |+ functools.reduce(operator.iadd, [x, y], []) +22 22 | +23 23 | +24 24 | # Regression test for: https://github.com/astral-sh/ruff/issues/7718 + +RUF017_0.py:26:5: RUF017 [*] Avoid quadratic list summation + | +24 | # Regression test for: https://github.com/astral-sh/ruff/issues/7718 +25 | def func(): +26 | sum((factor.dims for factor in bases), []) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF017 + | + = help: Replace with `functools.reduce` + +ℹ Suggested fix + 1 |+import functools + 2 |+import operator +1 3 | x = [1, 2, 3] +2 4 | y = [4, 5, 6] +3 5 | +-------------------------------------------------------------------------------- +23 25 | +24 26 | # Regression test for: https://github.com/astral-sh/ruff/issues/7718 +25 27 | def func(): +26 |- sum((factor.dims for factor in bases), []) + 28 |+ functools.reduce(operator.iadd, (factor.dims for factor in bases), []) diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF017_RUF017_1.py.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF017_RUF017_1.py.snap new file mode 100644 index 0000000000000..65bb00fdeb0d0 --- /dev/null +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF017_RUF017_1.py.snap @@ -0,0 +1,17 @@ +--- +source: crates/ruff_linter/src/rules/ruff/mod.rs +--- +RUF017_1.py:1:1: RUF017 [*] Avoid quadratic list summation + | +1 | sum((factor.dims for factor in bases), []) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF017 + | + = help: Replace with `functools.reduce` + +ℹ Suggested fix +1 |-sum((factor.dims for factor in bases), []) + 1 |+import functools + 2 |+import operator + 3 |+functools.reduce(operator.iadd, (factor.dims for factor in bases), []) + + diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF018_RUF018.py.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF018_RUF018.py.snap new file mode 100644 index 0000000000000..d4ceedb6246cf --- /dev/null +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF018_RUF018.py.snap @@ -0,0 +1,22 @@ +--- +source: crates/ruff_linter/src/rules/ruff/mod.rs +--- +RUF018.py:2:9: RUF018 Avoid assignment expressions in `assert` statements + | +1 | # RUF018 +2 | assert (x := 0) == 0 + | ^^^^^^ RUF018 +3 | assert x, (y := "error") + | + +RUF018.py:3:12: RUF018 Avoid assignment expressions in `assert` statements + | +1 | # RUF018 +2 | assert (x := 0) == 0 +3 | assert x, (y := "error") + | ^^^^^^^^^^^^ RUF018 +4 | +5 | # OK + | + + diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF019_RUF019.py.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF019_RUF019.py.snap new file mode 100644 index 0000000000000..db7aa2a866b17 --- /dev/null +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF019_RUF019.py.snap @@ -0,0 +1,82 @@ +--- +source: crates/ruff_linter/src/rules/ruff/mod.rs +--- +RUF019.py:3:4: RUF019 [*] Unnecessary key check before dictionary access + | +1 | d = {} +2 | # RUF019 +3 | if "k" in d and d["k"]: + | ^^^^^^^^^^^^^^^^^^^ RUF019 +4 | pass + | + = help: Replace with `dict.get` + +ℹ Fix +1 1 | d = {} +2 2 | # RUF019 +3 |-if "k" in d and d["k"]: + 3 |+if d.get("k"): +4 4 | pass +5 5 | +6 6 | k = "k" + +RUF019.py:7:4: RUF019 [*] Unnecessary key check before dictionary access + | +6 | k = "k" +7 | if k in d and d[k]: + | ^^^^^^^^^^^^^^^ RUF019 +8 | pass + | + = help: Replace with `dict.get` + +ℹ Fix +4 4 | pass +5 5 | +6 6 | k = "k" +7 |-if k in d and d[k]: + 7 |+if d.get(k): +8 8 | pass +9 9 | +10 10 | if (k) in d and d[k]: + +RUF019.py:10:4: RUF019 [*] Unnecessary key check before dictionary access + | + 8 | pass + 9 | +10 | if (k) in d and d[k]: + | ^^^^^^^^^^^^^^^^^ RUF019 +11 | pass + | + = help: Replace with `dict.get` + +ℹ Fix +7 7 | if k in d and d[k]: +8 8 | pass +9 9 | +10 |-if (k) in d and d[k]: + 10 |+if d.get(k): +11 11 | pass +12 12 | +13 13 | if k in d and d[(k)]: + +RUF019.py:13:4: RUF019 [*] Unnecessary key check before dictionary access + | +11 | pass +12 | +13 | if k in d and d[(k)]: + | ^^^^^^^^^^^^^^^^^ RUF019 +14 | pass + | + = help: Replace with `dict.get` + +ℹ Fix +10 10 | if (k) in d and d[k]: +11 11 | pass +12 12 | +13 |-if k in d and d[(k)]: + 13 |+if d.get((k)): +14 14 | pass +15 15 | +16 16 | # OK + + diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__confusables.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__confusables.snap index db682dfb23d67..541fc82af67a1 100644 --- a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__confusables.snap +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__confusables.snap @@ -49,6 +49,8 @@ confusables.py:31:6: RUF001 String contains ambiguous `Р` (CYRILLIC CAPITAL LET 30 | # boundary" (whitespace) that it itself ambiguous. 31 | x = "Р усский" | ^ RUF001 +32 | +33 | # Same test cases as above but using f-strings instead: | confusables.py:31:7: RUF001 String contains ambiguous ` ` (EN QUAD). Did you mean ` ` (SPACE)? @@ -57,6 +59,100 @@ confusables.py:31:7: RUF001 String contains ambiguous ` ` (EN QUAD). Did you m 30 | # boundary" (whitespace) that it itself ambiguous. 31 | x = "Р усский" | ^ RUF001 +32 | +33 | # Same test cases as above but using f-strings instead: + | + +confusables.py:34:7: RUF001 String contains ambiguous `𝐁` (MATHEMATICAL BOLD CAPITAL B). Did you mean `B` (LATIN CAPITAL LETTER B)? + | +33 | # Same test cases as above but using f-strings instead: +34 | x = f"𝐁ad string" + | ^ RUF001 +35 | x = f"−" +36 | x = f"Русский" + | + +confusables.py:37:11: RUF001 String contains ambiguous `α` (GREEK SMALL LETTER ALPHA). Did you mean `a` (LATIN SMALL LETTER A)? + | +35 | x = f"−" +36 | x = f"Русский" +37 | x = f"βα Bαd" + | ^ RUF001 +38 | x = f"Р усский" + | + +confusables.py:38:7: RUF001 String contains ambiguous `Р` (CYRILLIC CAPITAL LETTER ER). Did you mean `P` (LATIN CAPITAL LETTER P)? + | +36 | x = f"Русский" +37 | x = f"βα Bαd" +38 | x = f"Р усский" + | ^ RUF001 +39 | +40 | # Nested f-strings + | + +confusables.py:38:8: RUF001 String contains ambiguous ` ` (EN QUAD). Did you mean ` ` (SPACE)? + | +36 | x = f"Русский" +37 | x = f"βα Bαd" +38 | x = f"Р усский" + | ^ RUF001 +39 | +40 | # Nested f-strings + | + +confusables.py:41:7: RUF001 String contains ambiguous `𝐁` (MATHEMATICAL BOLD CAPITAL B). Did you mean `B` (LATIN CAPITAL LETTER B)? + | +40 | # Nested f-strings +41 | x = f"𝐁ad string {f" {f"Р усский"}"}" + | ^ RUF001 +42 | +43 | # Comments inside f-strings + | + +confusables.py:41:21: RUF001 String contains ambiguous ` ` (EN QUAD). Did you mean ` ` (SPACE)? + | +40 | # Nested f-strings +41 | x = f"𝐁ad string {f" {f"Р усский"}"}" + | ^ RUF001 +42 | +43 | # Comments inside f-strings + | + +confusables.py:41:25: RUF001 String contains ambiguous `Р` (CYRILLIC CAPITAL LETTER ER). Did you mean `P` (LATIN CAPITAL LETTER P)? + | +40 | # Nested f-strings +41 | x = f"𝐁ad string {f" {f"Р усский"}"}" + | ^ RUF001 +42 | +43 | # Comments inside f-strings + | + +confusables.py:41:26: RUF001 String contains ambiguous ` ` (EN QUAD). Did you mean ` ` (SPACE)? + | +40 | # Nested f-strings +41 | x = f"𝐁ad string {f" {f"Р усский"}"}" + | ^ RUF001 +42 | +43 | # Comments inside f-strings + | + +confusables.py:44:68: RUF003 Comment contains ambiguous `)` (FULLWIDTH RIGHT PARENTHESIS). Did you mean `)` (RIGHT PARENTHESIS)? + | +43 | # Comments inside f-strings +44 | x = f"string { # And here's a comment with an unusual parenthesis: ) + | ^^ RUF003 +45 | # And here's a comment with a greek alpha: ∗ +46 | foo # And here's a comment with an unusual punctuation mark: ᜵ + | + +confusables.py:46:62: RUF003 Comment contains ambiguous `᜵` (PHILIPPINE SINGLE PUNCTUATION). Did you mean `/` (SOLIDUS)? + | +44 | x = f"string { # And here's a comment with an unusual parenthesis: ) +45 | # And here's a comment with a greek alpha: ∗ +46 | foo # And here's a comment with an unusual punctuation mark: ᜵ + | ^ RUF003 +47 | }" | diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_0.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_0.snap index ab6ee7ff6f167..911789f49f078 100644 --- a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_0.snap +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_0.snap @@ -10,7 +10,7 @@ RUF100_0.py:9:12: RUF100 [*] Unused blanket `noqa` directive | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 6 6 | b = 2 # noqa: F841 7 7 | 8 8 | # Invalid @@ -30,7 +30,7 @@ RUF100_0.py:13:12: RUF100 [*] Unused `noqa` directive (unused: `E501`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 10 10 | print(c) 11 11 | 12 12 | # Invalid @@ -50,7 +50,7 @@ RUF100_0.py:16:12: RUF100 [*] Unused `noqa` directive (unused: `F841`, `E501`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 13 13 | d = 1 # noqa: E501 14 14 | 15 15 | # Invalid @@ -70,7 +70,7 @@ RUF100_0.py:19:12: RUF100 [*] Unused `noqa` directive (unused: `F841`, `W191`; n | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 16 16 | d = 1 # noqa: F841, E501 17 17 | 18 18 | # Invalid (and unimplemented or not enabled) @@ -86,182 +86,202 @@ RUF100_0.py:22:12: RUF100 [*] Unused `noqa` directive (unused: `F841`) 22 | d = 1 # noqa: F841, V101 | ^^^^^^^^^^^^^^^^^^ RUF100 23 | -24 | # fmt: off +24 | # Invalid (but external) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 19 19 | d = 1 # noqa: F841, W191, F821 20 20 | 21 21 | # Invalid (but external) 22 |- d = 1 # noqa: F841, V101 22 |+ d = 1 # noqa: V101 23 23 | -24 24 | # fmt: off -25 25 | # Invalid - no space before # +24 24 | # Invalid (but external) +25 25 | d = 1 # noqa: V500 -RUF100_0.py:26:10: RUF100 [*] Unused `noqa` directive (unused: `E501`) +RUF100_0.py:25:12: RUF100 [*] Unused `noqa` directive (unknown: `V500`) | -24 | # fmt: off -25 | # Invalid - no space before # -26 | d = 1# noqa: E501 - | ^^^^^^^^^^^^ RUF100 -27 | -28 | # Invalid - many spaces before # +24 | # Invalid (but external) +25 | d = 1 # noqa: V500 + | ^^^^^^^^^^^^ RUF100 +26 | +27 | # fmt: off | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix +22 22 | d = 1 # noqa: F841, V101 23 23 | -24 24 | # fmt: off -25 25 | # Invalid - no space before # -26 |- d = 1# noqa: E501 - 26 |+ d = 1 -27 27 | -28 28 | # Invalid - many spaces before # -29 29 | d = 1 # noqa: E501 +24 24 | # Invalid (but external) +25 |- d = 1 # noqa: V500 + 25 |+ d = 1 +26 26 | +27 27 | # fmt: off +28 28 | # Invalid - no space before # + +RUF100_0.py:29:10: RUF100 [*] Unused `noqa` directive (unused: `E501`) + | +27 | # fmt: off +28 | # Invalid - no space before # +29 | d = 1# noqa: E501 + | ^^^^^^^^^^^^ RUF100 +30 | +31 | # Invalid - many spaces before # + | + = help: Remove unused `noqa` directive -RUF100_0.py:29:5: F841 [*] Local variable `d` is assigned to but never used +ℹ Fix +26 26 | +27 27 | # fmt: off +28 28 | # Invalid - no space before # +29 |- d = 1# noqa: E501 + 29 |+ d = 1 +30 30 | +31 31 | # Invalid - many spaces before # +32 32 | d = 1 # noqa: E501 + +RUF100_0.py:32:5: F841 [*] Local variable `d` is assigned to but never used | -28 | # Invalid - many spaces before # -29 | d = 1 # noqa: E501 +31 | # Invalid - many spaces before # +32 | d = 1 # noqa: E501 | ^ F841 -30 | # fmt: on +33 | # fmt: on | = help: Remove assignment to unused variable `d` ℹ Suggested fix -26 26 | d = 1# noqa: E501 -27 27 | -28 28 | # Invalid - many spaces before # -29 |- d = 1 # noqa: E501 -30 29 | # fmt: on -31 30 | -32 31 | +29 29 | d = 1# noqa: E501 +30 30 | +31 31 | # Invalid - many spaces before # +32 |- d = 1 # noqa: E501 +33 32 | # fmt: on +34 33 | +35 34 | -RUF100_0.py:29:33: RUF100 [*] Unused `noqa` directive (unused: `E501`) +RUF100_0.py:32:33: RUF100 [*] Unused `noqa` directive (unused: `E501`) | -28 | # Invalid - many spaces before # -29 | d = 1 # noqa: E501 +31 | # Invalid - many spaces before # +32 | d = 1 # noqa: E501 | ^^^^^^^^^^^^ RUF100 -30 | # fmt: on +33 | # fmt: on | = help: Remove unused `noqa` directive -ℹ Suggested fix -26 26 | d = 1# noqa: E501 -27 27 | -28 28 | # Invalid - many spaces before # -29 |- d = 1 # noqa: E501 - 29 |+ d = 1 -30 30 | # fmt: on -31 31 | -32 32 | +ℹ Fix +29 29 | d = 1# noqa: E501 +30 30 | +31 31 | # Invalid - many spaces before # +32 |- d = 1 # noqa: E501 + 32 |+ d = 1 +33 33 | # fmt: on +34 34 | +35 35 | -RUF100_0.py:55:6: RUF100 [*] Unused `noqa` directive (unused: `F841`) +RUF100_0.py:58:6: RUF100 [*] Unused `noqa` directive (unused: `F841`) | -54 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. -55 | """ # noqa: E501, F841 +57 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +58 | """ # noqa: E501, F841 | ^^^^^^^^^^^^^^^^^^ RUF100 -56 | -57 | # Invalid +59 | +60 | # Invalid | = help: Remove unused `noqa` directive -ℹ Suggested fix -52 52 | https://github.com/PyCQA/pycodestyle/pull/258/files#diff-841c622497a8033d10152bfdfb15b20b92437ecdea21a260944ea86b77b51533 -53 53 | -54 54 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. -55 |-""" # noqa: E501, F841 - 55 |+""" # noqa: E501 +ℹ Fix +55 55 | https://github.com/PyCQA/pycodestyle/pull/258/files#diff-841c622497a8033d10152bfdfb15b20b92437ecdea21a260944ea86b77b51533 56 56 | -57 57 | # Invalid -58 58 | _ = """Lorem ipsum dolor sit amet. +57 57 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +58 |-""" # noqa: E501, F841 + 58 |+""" # noqa: E501 +59 59 | +60 60 | # Invalid +61 61 | _ = """Lorem ipsum dolor sit amet. -RUF100_0.py:63:6: RUF100 [*] Unused `noqa` directive (unused: `E501`) +RUF100_0.py:66:6: RUF100 [*] Unused `noqa` directive (unused: `E501`) | -62 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor. -63 | """ # noqa: E501 +65 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor. +66 | """ # noqa: E501 | ^^^^^^^^^^^^ RUF100 -64 | -65 | # Invalid +67 | +68 | # Invalid | = help: Remove unused `noqa` directive -ℹ Suggested fix -60 60 | https://github.com/PyCQA/pycodestyle/pull/258/files#diff-841c622497a8033d10152bfdfb15b20b92437ecdea21a260944ea86b77b51533 -61 61 | -62 62 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor. -63 |-""" # noqa: E501 - 63 |+""" +ℹ Fix +63 63 | https://github.com/PyCQA/pycodestyle/pull/258/files#diff-841c622497a8033d10152bfdfb15b20b92437ecdea21a260944ea86b77b51533 64 64 | -65 65 | # Invalid -66 66 | _ = """Lorem ipsum dolor sit amet. +65 65 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor. +66 |-""" # noqa: E501 + 66 |+""" +67 67 | +68 68 | # Invalid +69 69 | _ = """Lorem ipsum dolor sit amet. -RUF100_0.py:71:6: RUF100 [*] Unused blanket `noqa` directive +RUF100_0.py:74:6: RUF100 [*] Unused blanket `noqa` directive | -70 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor. -71 | """ # noqa +73 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor. +74 | """ # noqa | ^^^^^^ RUF100 -72 | -73 | # Valid +75 | +76 | # Valid | = help: Remove unused `noqa` directive -ℹ Suggested fix -68 68 | https://github.com/PyCQA/pycodestyle/pull/258/files#diff-841c622497a8033d10152bfdfb15b20b92437ecdea21a260944ea86b77b51533 -69 69 | -70 70 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor. -71 |-""" # noqa - 71 |+""" +ℹ Fix +71 71 | https://github.com/PyCQA/pycodestyle/pull/258/files#diff-841c622497a8033d10152bfdfb15b20b92437ecdea21a260944ea86b77b51533 72 72 | -73 73 | # Valid -74 74 | # this is a veryyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy long comment # noqa: E501 +73 73 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor. +74 |-""" # noqa + 74 |+""" +75 75 | +76 76 | # Valid +77 77 | # this is a veryyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy long comment # noqa: E501 -RUF100_0.py:85:8: F401 [*] `shelve` imported but unused +RUF100_0.py:88:8: F401 [*] `shelve` imported but unused | -83 | import collections # noqa -84 | import os # noqa: F401, RUF100 -85 | import shelve # noqa: RUF100 +86 | import collections # noqa +87 | import os # noqa: F401, RUF100 +88 | import shelve # noqa: RUF100 | ^^^^^^ F401 -86 | import sys # noqa: F401, RUF100 +89 | import sys # noqa: F401, RUF100 | = help: Remove unused import: `shelve` ℹ Fix -82 82 | -83 83 | import collections # noqa -84 84 | import os # noqa: F401, RUF100 -85 |-import shelve # noqa: RUF100 -86 85 | import sys # noqa: F401, RUF100 -87 86 | -88 87 | print(sys.path) +85 85 | +86 86 | import collections # noqa +87 87 | import os # noqa: F401, RUF100 +88 |-import shelve # noqa: RUF100 +89 88 | import sys # noqa: F401, RUF100 +90 89 | +91 90 | print(sys.path) -RUF100_0.py:90:89: E501 Line too long (103 > 88 characters) +RUF100_0.py:93:89: E501 Line too long (89 > 88) | -88 | print(sys.path) -89 | -90 | "shape: (6,)\nSeries: '' [duration[μs]]\n[\n\t0µs\n\t1µs\n\t2µs\n\t3µs\n\t4µs\n\t5µs\n]" # noqa: F401 - | ^^^^^^^^^^^^^^^ E501 +91 | print(sys.path) +92 | +93 | "shape: (6,)\nSeries: '' [duration[μs]]\n[\n\t0µs\n\t1µs\n\t2µs\n\t3µs\n\t4µs\n\t5µs\n]" # noqa: F401 + | ^ E501 | -RUF100_0.py:90:92: RUF100 [*] Unused `noqa` directive (unused: `F401`) +RUF100_0.py:93:92: RUF100 [*] Unused `noqa` directive (unused: `F401`) | -88 | print(sys.path) -89 | -90 | "shape: (6,)\nSeries: '' [duration[μs]]\n[\n\t0µs\n\t1µs\n\t2µs\n\t3µs\n\t4µs\n\t5µs\n]" # noqa: F401 +91 | print(sys.path) +92 | +93 | "shape: (6,)\nSeries: '' [duration[μs]]\n[\n\t0µs\n\t1µs\n\t2µs\n\t3µs\n\t4µs\n\t5µs\n]" # noqa: F401 | ^^^^^^^^^^^^ RUF100 | = help: Remove unused `noqa` directive -ℹ Suggested fix -87 87 | -88 88 | print(sys.path) -89 89 | -90 |-"shape: (6,)\nSeries: '' [duration[μs]]\n[\n\t0µs\n\t1µs\n\t2µs\n\t3µs\n\t4µs\n\t5µs\n]" # noqa: F401 - 90 |+"shape: (6,)\nSeries: '' [duration[μs]]\n[\n\t0µs\n\t1µs\n\t2µs\n\t3µs\n\t4µs\n\t5µs\n]" -91 91 | +ℹ Fix +90 90 | +91 91 | print(sys.path) 92 92 | -93 93 | def f(): +93 |-"shape: (6,)\nSeries: '' [duration[μs]]\n[\n\t0µs\n\t1µs\n\t2µs\n\t3µs\n\t4µs\n\t5µs\n]" # noqa: F401 + 93 |+"shape: (6,)\nSeries: '' [duration[μs]]\n[\n\t0µs\n\t1µs\n\t2µs\n\t3µs\n\t4µs\n\t5µs\n]" +94 94 | +95 95 | +96 96 | def f(): diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_0_prefix.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_0_prefix.snap new file mode 100644 index 0000000000000..926354aa430d6 --- /dev/null +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_0_prefix.snap @@ -0,0 +1,267 @@ +--- +source: crates/ruff_linter/src/rules/ruff/mod.rs +--- +RUF100_0.py:9:12: RUF100 [*] Unused blanket `noqa` directive + | + 8 | # Invalid + 9 | c = 1 # noqa + | ^^^^^^ RUF100 +10 | print(c) + | + = help: Remove unused `noqa` directive + +ℹ Fix +6 6 | b = 2 # noqa: F841 +7 7 | +8 8 | # Invalid +9 |- c = 1 # noqa + 9 |+ c = 1 +10 10 | print(c) +11 11 | +12 12 | # Invalid + +RUF100_0.py:13:12: RUF100 [*] Unused `noqa` directive (unused: `E501`) + | +12 | # Invalid +13 | d = 1 # noqa: E501 + | ^^^^^^^^^^^^ RUF100 +14 | +15 | # Invalid + | + = help: Remove unused `noqa` directive + +ℹ Fix +10 10 | print(c) +11 11 | +12 12 | # Invalid +13 |- d = 1 # noqa: E501 + 13 |+ d = 1 +14 14 | +15 15 | # Invalid +16 16 | d = 1 # noqa: F841, E501 + +RUF100_0.py:16:12: RUF100 [*] Unused `noqa` directive (unused: `F841`, `E501`) + | +15 | # Invalid +16 | d = 1 # noqa: F841, E501 + | ^^^^^^^^^^^^^^^^^^ RUF100 +17 | +18 | # Invalid (and unimplemented or not enabled) + | + = help: Remove unused `noqa` directive + +ℹ Fix +13 13 | d = 1 # noqa: E501 +14 14 | +15 15 | # Invalid +16 |- d = 1 # noqa: F841, E501 + 16 |+ d = 1 +17 17 | +18 18 | # Invalid (and unimplemented or not enabled) +19 19 | d = 1 # noqa: F841, W191, F821 + +RUF100_0.py:19:12: RUF100 [*] Unused `noqa` directive (unused: `F841`, `W191`; non-enabled: `F821`) + | +18 | # Invalid (and unimplemented or not enabled) +19 | d = 1 # noqa: F841, W191, F821 + | ^^^^^^^^^^^^^^^^^^^^^^^^ RUF100 +20 | +21 | # Invalid (but external) + | + = help: Remove unused `noqa` directive + +ℹ Fix +16 16 | d = 1 # noqa: F841, E501 +17 17 | +18 18 | # Invalid (and unimplemented or not enabled) +19 |- d = 1 # noqa: F841, W191, F821 + 19 |+ d = 1 +20 20 | +21 21 | # Invalid (but external) +22 22 | d = 1 # noqa: F841, V101 + +RUF100_0.py:22:12: RUF100 [*] Unused `noqa` directive (unused: `F841`) + | +21 | # Invalid (but external) +22 | d = 1 # noqa: F841, V101 + | ^^^^^^^^^^^^^^^^^^ RUF100 +23 | +24 | # Invalid (but external) + | + = help: Remove unused `noqa` directive + +ℹ Fix +19 19 | d = 1 # noqa: F841, W191, F821 +20 20 | +21 21 | # Invalid (but external) +22 |- d = 1 # noqa: F841, V101 + 22 |+ d = 1 # noqa: V101 +23 23 | +24 24 | # Invalid (but external) +25 25 | d = 1 # noqa: V500 + +RUF100_0.py:29:10: RUF100 [*] Unused `noqa` directive (unused: `E501`) + | +27 | # fmt: off +28 | # Invalid - no space before # +29 | d = 1# noqa: E501 + | ^^^^^^^^^^^^ RUF100 +30 | +31 | # Invalid - many spaces before # + | + = help: Remove unused `noqa` directive + +ℹ Fix +26 26 | +27 27 | # fmt: off +28 28 | # Invalid - no space before # +29 |- d = 1# noqa: E501 + 29 |+ d = 1 +30 30 | +31 31 | # Invalid - many spaces before # +32 32 | d = 1 # noqa: E501 + +RUF100_0.py:32:5: F841 [*] Local variable `d` is assigned to but never used + | +31 | # Invalid - many spaces before # +32 | d = 1 # noqa: E501 + | ^ F841 +33 | # fmt: on + | + = help: Remove assignment to unused variable `d` + +ℹ Suggested fix +29 29 | d = 1# noqa: E501 +30 30 | +31 31 | # Invalid - many spaces before # +32 |- d = 1 # noqa: E501 +33 32 | # fmt: on +34 33 | +35 34 | + +RUF100_0.py:32:33: RUF100 [*] Unused `noqa` directive (unused: `E501`) + | +31 | # Invalid - many spaces before # +32 | d = 1 # noqa: E501 + | ^^^^^^^^^^^^ RUF100 +33 | # fmt: on + | + = help: Remove unused `noqa` directive + +ℹ Fix +29 29 | d = 1# noqa: E501 +30 30 | +31 31 | # Invalid - many spaces before # +32 |- d = 1 # noqa: E501 + 32 |+ d = 1 +33 33 | # fmt: on +34 34 | +35 35 | + +RUF100_0.py:58:6: RUF100 [*] Unused `noqa` directive (unused: `F841`) + | +57 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +58 | """ # noqa: E501, F841 + | ^^^^^^^^^^^^^^^^^^ RUF100 +59 | +60 | # Invalid + | + = help: Remove unused `noqa` directive + +ℹ Fix +55 55 | https://github.com/PyCQA/pycodestyle/pull/258/files#diff-841c622497a8033d10152bfdfb15b20b92437ecdea21a260944ea86b77b51533 +56 56 | +57 57 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +58 |-""" # noqa: E501, F841 + 58 |+""" # noqa: E501 +59 59 | +60 60 | # Invalid +61 61 | _ = """Lorem ipsum dolor sit amet. + +RUF100_0.py:66:6: RUF100 [*] Unused `noqa` directive (unused: `E501`) + | +65 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor. +66 | """ # noqa: E501 + | ^^^^^^^^^^^^ RUF100 +67 | +68 | # Invalid + | + = help: Remove unused `noqa` directive + +ℹ Fix +63 63 | https://github.com/PyCQA/pycodestyle/pull/258/files#diff-841c622497a8033d10152bfdfb15b20b92437ecdea21a260944ea86b77b51533 +64 64 | +65 65 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor. +66 |-""" # noqa: E501 + 66 |+""" +67 67 | +68 68 | # Invalid +69 69 | _ = """Lorem ipsum dolor sit amet. + +RUF100_0.py:74:6: RUF100 [*] Unused blanket `noqa` directive + | +73 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor. +74 | """ # noqa + | ^^^^^^ RUF100 +75 | +76 | # Valid + | + = help: Remove unused `noqa` directive + +ℹ Fix +71 71 | https://github.com/PyCQA/pycodestyle/pull/258/files#diff-841c622497a8033d10152bfdfb15b20b92437ecdea21a260944ea86b77b51533 +72 72 | +73 73 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor. +74 |-""" # noqa + 74 |+""" +75 75 | +76 76 | # Valid +77 77 | # this is a veryyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy long comment # noqa: E501 + +RUF100_0.py:88:8: F401 [*] `shelve` imported but unused + | +86 | import collections # noqa +87 | import os # noqa: F401, RUF100 +88 | import shelve # noqa: RUF100 + | ^^^^^^ F401 +89 | import sys # noqa: F401, RUF100 + | + = help: Remove unused import: `shelve` + +ℹ Fix +85 85 | +86 86 | import collections # noqa +87 87 | import os # noqa: F401, RUF100 +88 |-import shelve # noqa: RUF100 +89 88 | import sys # noqa: F401, RUF100 +90 89 | +91 90 | print(sys.path) + +RUF100_0.py:93:89: E501 Line too long (89 > 88) + | +91 | print(sys.path) +92 | +93 | "shape: (6,)\nSeries: '' [duration[μs]]\n[\n\t0µs\n\t1µs\n\t2µs\n\t3µs\n\t4µs\n\t5µs\n]" # noqa: F401 + | ^ E501 + | + +RUF100_0.py:93:92: RUF100 [*] Unused `noqa` directive (unused: `F401`) + | +91 | print(sys.path) +92 | +93 | "shape: (6,)\nSeries: '' [duration[μs]]\n[\n\t0µs\n\t1µs\n\t2µs\n\t3µs\n\t4µs\n\t5µs\n]" # noqa: F401 + | ^^^^^^^^^^^^ RUF100 + | + = help: Remove unused `noqa` directive + +ℹ Fix +90 90 | +91 91 | print(sys.path) +92 92 | +93 |-"shape: (6,)\nSeries: '' [duration[μs]]\n[\n\t0µs\n\t1µs\n\t2µs\n\t3µs\n\t4µs\n\t5µs\n]" # noqa: F401 + 93 |+"shape: (6,)\nSeries: '' [duration[μs]]\n[\n\t0µs\n\t1µs\n\t2µs\n\t3µs\n\t4µs\n\t5µs\n]" +94 94 | +95 95 | +96 96 | def f(): + + diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_1.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_1.snap index 288d46d007d67..27bf0677ed7ee 100644 --- a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_1.snap +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_1.snap @@ -32,7 +32,7 @@ RUF100_1.py:52:20: RUF100 [*] Unused `noqa` directive (unused: `F401`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 49 49 | def f(): 50 50 | # This should ignore the error, but the inner noqa should be marked as unused. 51 51 | from typing import ( # noqa: F401 @@ -52,7 +52,7 @@ RUF100_1.py:59:20: RUF100 [*] Unused `noqa` directive (unused: `F401`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 56 56 | def f(): 57 57 | # This should ignore the error, but the inner noqa should be marked as unused. 58 58 | from typing import ( # noqa @@ -72,7 +72,7 @@ RUF100_1.py:66:16: RUF100 [*] Unused `noqa` directive (non-enabled: `F501`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 63 63 | def f(): 64 64 | # This should ignore the error, but mark F501 as unused. 65 65 | from typing import ( # noqa: F401 @@ -93,7 +93,7 @@ RUF100_1.py:72:27: RUF100 [*] Unused `noqa` directive (non-enabled: `F501`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 69 69 | 70 70 | def f(): 71 71 | # This should ignore the error, but mark F501 as unused. @@ -144,7 +144,7 @@ RUF100_1.py:89:55: RUF100 [*] Unused `noqa` directive (non-enabled: `F501`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 86 86 | 87 87 | def f(): 88 88 | # This should mark F501 as unused. diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_2.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_2.snap index 3de393b1c95a4..86c963c5785cc 100644 --- a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_2.snap +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_2.snap @@ -8,7 +8,7 @@ RUF100_2.py:1:19: RUF100 [*] Unused `noqa` directive (unused: `F401`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 1 |-import itertools # noqa: F401 1 |+import itertools diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_3.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_3.snap index f7c08b2403df8..24844b54a9907 100644 --- a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_3.snap +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_3.snap @@ -10,7 +10,7 @@ RUF100_3.py:1:1: RUF100 [*] Unused blanket `noqa` directive | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 1 |-# noqa 2 1 | # noqa # comment 3 2 | print() # noqa @@ -26,7 +26,7 @@ RUF100_3.py:2:1: RUF100 [*] Unused blanket `noqa` directive | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 1 1 | # noqa 2 |-# noqa # comment 2 |+# comment @@ -45,7 +45,7 @@ RUF100_3.py:3:10: RUF100 [*] Unused blanket `noqa` directive | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 1 1 | # noqa 2 2 | # noqa # comment 3 |-print() # noqa @@ -65,7 +65,7 @@ RUF100_3.py:4:10: RUF100 [*] Unused blanket `noqa` directive | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 1 1 | # noqa 2 2 | # noqa # comment 3 3 | print() # noqa @@ -86,7 +86,7 @@ RUF100_3.py:5:10: RUF100 [*] Unused blanket `noqa` directive | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 2 2 | # noqa # comment 3 3 | print() # noqa 4 4 | print() # noqa # comment @@ -107,7 +107,7 @@ RUF100_3.py:6:10: RUF100 [*] Unused blanket `noqa` directive | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 3 3 | print() # noqa 4 4 | print() # noqa # comment 5 5 | print() # noqa # comment @@ -128,7 +128,7 @@ RUF100_3.py:7:10: RUF100 [*] Unused blanket `noqa` directive | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 4 4 | print() # noqa # comment 5 5 | print() # noqa # comment 6 6 | print() # noqa comment @@ -149,7 +149,7 @@ RUF100_3.py:14:1: RUF100 [*] Unused `noqa` directive (unused: `E501`, `F821`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 11 11 | print(a) # noqa comment 12 12 | print(a) # noqa comment 13 13 | @@ -168,7 +168,7 @@ RUF100_3.py:15:1: RUF100 [*] Unused `noqa` directive (unused: `E501`, `F821`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 12 12 | print(a) # noqa comment 13 13 | 14 14 | # noqa: E501, F821 @@ -189,7 +189,7 @@ RUF100_3.py:16:10: RUF100 [*] Unused `noqa` directive (unused: `E501`, `F821`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 13 13 | 14 14 | # noqa: E501, F821 15 15 | # noqa: E501, F821 # comment @@ -210,7 +210,7 @@ RUF100_3.py:17:10: RUF100 [*] Unused `noqa` directive (unused: `E501`, `F821`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 14 14 | # noqa: E501, F821 15 15 | # noqa: E501, F821 # comment 16 16 | print() # noqa: E501, F821 @@ -231,7 +231,7 @@ RUF100_3.py:18:10: RUF100 [*] Unused `noqa` directive (unused: `E501`, `F821`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 15 15 | # noqa: E501, F821 # comment 16 16 | print() # noqa: E501, F821 17 17 | print() # noqa: E501, F821 # comment @@ -252,7 +252,7 @@ RUF100_3.py:19:10: RUF100 [*] Unused `noqa` directive (unused: `E501`, `F821`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 16 16 | print() # noqa: E501, F821 17 17 | print() # noqa: E501, F821 # comment 18 18 | print() # noqa: E501, F821 # comment @@ -273,7 +273,7 @@ RUF100_3.py:20:10: RUF100 [*] Unused `noqa` directive (unused: `E501`, `F821`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 17 17 | print() # noqa: E501, F821 # comment 18 18 | print() # noqa: E501, F821 # comment 19 19 | print() # noqa: E501, F821 comment @@ -294,7 +294,7 @@ RUF100_3.py:21:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 18 18 | print() # noqa: E501, F821 # comment 19 19 | print() # noqa: E501, F821 comment 20 20 | print() # noqa: E501, F821 comment @@ -315,7 +315,7 @@ RUF100_3.py:22:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 19 19 | print() # noqa: E501, F821 comment 20 20 | print() # noqa: E501, F821 comment 21 21 | print(a) # noqa: E501, F821 @@ -336,7 +336,7 @@ RUF100_3.py:23:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 20 20 | print() # noqa: E501, F821 comment 21 21 | print(a) # noqa: E501, F821 22 22 | print(a) # noqa: E501, F821 # comment @@ -355,7 +355,7 @@ RUF100_3.py:24:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 21 21 | print(a) # noqa: E501, F821 22 22 | print(a) # noqa: E501, F821 # comment 23 23 | print(a) # noqa: E501, F821 # comment @@ -372,7 +372,7 @@ RUF100_3.py:25:11: RUF100 [*] Unused `noqa` directive (unused: `E501`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 22 22 | print(a) # noqa: E501, F821 # comment 23 23 | print(a) # noqa: E501, F821 # comment 24 24 | print(a) # noqa: E501, F821 comment diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_5.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_5.snap index 0808aaab058fe..f1fc6f88b72e0 100644 --- a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_5.snap +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruf100_5.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/ruff/mod.rs --- -RUF100_5.py:7:5: ERA001 [*] Found commented-out code +RUF100_5.py:7:5: ERA001 Found commented-out code | 5 | # "key1": 123, # noqa: ERA001 6 | # "key2": 456, # noqa @@ -20,7 +20,7 @@ RUF100_5.py:7:5: ERA001 [*] Found commented-out code 9 8 | 10 9 | -RUF100_5.py:11:1: ERA001 [*] Found commented-out code +RUF100_5.py:11:1: ERA001 Found commented-out code | 11 | #import os # noqa: E501 | ^^^^^^^^^^^^^^^^^^^^^^^^ ERA001 @@ -40,7 +40,7 @@ RUF100_5.py:11:13: RUF100 [*] Unused `noqa` directive (unused: `E501`) | = help: Remove unused `noqa` directive -ℹ Suggested fix +ℹ Fix 8 8 | } 9 9 | 10 10 | diff --git a/crates/ruff_linter/src/rules/tryceratops/helpers.rs b/crates/ruff_linter/src/rules/tryceratops/helpers.rs index 6a765ec0e3263..0e707c1e3924e 100644 --- a/crates/ruff_linter/src/rules/tryceratops/helpers.rs +++ b/crates/ruff_linter/src/rules/tryceratops/helpers.rs @@ -1,15 +1,15 @@ -use ruff_python_ast::{self as ast, Expr}; - use ruff_python_ast::visitor; use ruff_python_ast::visitor::Visitor; +use ruff_python_ast::{self as ast, Expr}; use ruff_python_semantic::analyze::logging; use ruff_python_semantic::SemanticModel; +use ruff_python_stdlib::logging::LoggingLevel; /// Collect `logging`-like calls from an AST. pub(super) struct LoggerCandidateVisitor<'a, 'b> { semantic: &'a SemanticModel<'b>, logger_objects: &'a [String], - pub(super) calls: Vec<&'b ast::ExprCall>, + pub(super) calls: Vec<(&'b ast::ExprCall, LoggingLevel)>, } impl<'a, 'b> LoggerCandidateVisitor<'a, 'b> { @@ -25,8 +25,27 @@ impl<'a, 'b> LoggerCandidateVisitor<'a, 'b> { impl<'a, 'b> Visitor<'b> for LoggerCandidateVisitor<'a, 'b> { fn visit_expr(&mut self, expr: &'b Expr) { if let Expr::Call(call) = expr { - if logging::is_logger_candidate(&call.func, self.semantic, self.logger_objects) { - self.calls.push(call); + match call.func.as_ref() { + Expr::Attribute(ast::ExprAttribute { attr, .. }) => { + if logging::is_logger_candidate(&call.func, self.semantic, self.logger_objects) + { + if let Some(logging_level) = LoggingLevel::from_attribute(attr) { + self.calls.push((call, logging_level)); + }; + } + } + Expr::Name(_) => { + if let Some(call_path) = self.semantic.resolve_call_path(call.func.as_ref()) { + if let ["logging", attribute] = call_path.as_slice() { + if let Some(logging_level) = LoggingLevel::from_attribute(attribute) { + { + self.calls.push((call, logging_level)); + } + } + } + } + } + _ => {} } } visitor::walk_expr(self, expr); diff --git a/crates/ruff_linter/src/rules/tryceratops/rules/error_instead_of_exception.rs b/crates/ruff_linter/src/rules/tryceratops/rules/error_instead_of_exception.rs index 2d0404a50406a..fda19f79e8b58 100644 --- a/crates/ruff_linter/src/rules/tryceratops/rules/error_instead_of_exception.rs +++ b/crates/ruff_linter/src/rules/tryceratops/rules/error_instead_of_exception.rs @@ -1,9 +1,9 @@ -use ruff_python_ast::{self as ast, ExceptHandler, Expr}; - use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::visitor::Visitor; +use ruff_python_ast::{self as ast, ExceptHandler}; use ruff_python_semantic::analyze::logging::exc_info; +use ruff_python_stdlib::logging::LoggingLevel; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -64,14 +64,12 @@ pub(crate) fn error_instead_of_exception(checker: &mut Checker, handlers: &[Exce visitor.visit_body(body); visitor.calls }; - for expr in calls { - if let Expr::Attribute(ast::ExprAttribute { attr, .. }) = expr.func.as_ref() { - if attr == "error" { - if exc_info(&expr.arguments, checker.semantic()).is_none() { - checker - .diagnostics - .push(Diagnostic::new(ErrorInsteadOfException, expr.range())); - } + for (expr, logging_level) in calls { + if matches!(logging_level, LoggingLevel::Error) { + if exc_info(&expr.arguments, checker.semantic()).is_none() { + checker + .diagnostics + .push(Diagnostic::new(ErrorInsteadOfException, expr.range())); } } } diff --git a/crates/ruff_linter/src/rules/tryceratops/rules/verbose_log_message.rs b/crates/ruff_linter/src/rules/tryceratops/rules/verbose_log_message.rs index 4ddf0009b5892..8b3fad0f082d9 100644 --- a/crates/ruff_linter/src/rules/tryceratops/rules/verbose_log_message.rs +++ b/crates/ruff_linter/src/rules/tryceratops/rules/verbose_log_message.rs @@ -4,6 +4,7 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::visitor; use ruff_python_ast::visitor::Visitor; +use ruff_python_stdlib::logging::LoggingLevel; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -74,25 +75,23 @@ pub(crate) fn verbose_log_message(checker: &mut Checker, handlers: &[ExceptHandl visitor.calls }; - for expr in calls { - if let Expr::Attribute(ast::ExprAttribute { attr, .. }) = expr.func.as_ref() { - if attr == "exception" { - // Collect all referenced names in the `logging.exception` call. - let names: Vec<&ast::ExprName> = { - let mut names = Vec::new(); - for arg in &expr.arguments.args { - let mut visitor = NameVisitor::default(); - visitor.visit_expr(arg); - names.extend(visitor.names); - } - names - }; - for expr in names { - if expr.id == target.as_str() { - checker - .diagnostics - .push(Diagnostic::new(VerboseLogMessage, expr.range())); - } + for (expr, logging_level) in calls { + if matches!(logging_level, LoggingLevel::Exception) { + // Collect all referenced names in the `logging.exception` call. + let names: Vec<&ast::ExprName> = { + let mut names = Vec::new(); + for arg in &expr.arguments.args { + let mut visitor = NameVisitor::default(); + visitor.visit_expr(arg); + names.extend(visitor.names); + } + names + }; + for expr in names { + if expr.id == target.as_str() { + checker + .diagnostics + .push(Diagnostic::new(VerboseLogMessage, expr.range())); } } } diff --git a/crates/ruff_linter/src/rules/tryceratops/rules/verbose_raise.rs b/crates/ruff_linter/src/rules/tryceratops/rules/verbose_raise.rs index 10c11798700cb..bfe623a0a0381 100644 --- a/crates/ruff_linter/src/rules/tryceratops/rules/verbose_raise.rs +++ b/crates/ruff_linter/src/rules/tryceratops/rules/verbose_raise.rs @@ -1,12 +1,11 @@ use ruff_python_ast::{self as ast, ExceptHandler, Expr, Stmt}; -use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; +use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::statement_visitor::{walk_stmt, StatementVisitor}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; -use crate::registry::AsRule; /// ## What it does /// Checks for needless exception names in `raise` statements. @@ -35,13 +34,13 @@ use crate::registry::AsRule; #[violation] pub struct VerboseRaise; -impl AlwaysAutofixableViolation for VerboseRaise { +impl AlwaysFixableViolation for VerboseRaise { #[derive_message_formats] fn message(&self) -> String { format!("Use `raise` without specifying exception name") } - fn autofix_title(&self) -> String { + fn fix_title(&self) -> String { format!("Remove exception name") } } @@ -96,12 +95,10 @@ pub(crate) fn verbose_raise(checker: &mut Checker, handlers: &[ExceptHandler]) { if let Expr::Name(ast::ExprName { id, .. }) = exc.as_ref() { if id == exception_name.as_str() { let mut diagnostic = Diagnostic::new(VerboseRaise, exc.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Fix::suggested(Edit::range_replacement( - "raise".to_string(), - raise.range(), - ))); - } + diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement( + "raise".to_string(), + raise.range(), + ))); checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/tryceratops/snapshots/ruff_linter__rules__tryceratops__tests__error-instead-of-exception_TRY400.py.snap b/crates/ruff_linter/src/rules/tryceratops/snapshots/ruff_linter__rules__tryceratops__tests__error-instead-of-exception_TRY400.py.snap index 4eb4aad7a1767..35b36493ec3a9 100644 --- a/crates/ruff_linter/src/rules/tryceratops/snapshots/ruff_linter__rules__tryceratops__tests__error-instead-of-exception_TRY400.py.snap +++ b/crates/ruff_linter/src/rules/tryceratops/snapshots/ruff_linter__rules__tryceratops__tests__error-instead-of-exception_TRY400.py.snap @@ -69,4 +69,21 @@ TRY400.py:49:13: TRY400 Use `logging.exception` instead of `logging.error` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400 | +TRY400.py:87:9: TRY400 Use `logging.exception` instead of `logging.error` + | +85 | a = 1 +86 | except Exception: +87 | error("Context message here") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400 +88 | +89 | if True: + | + +TRY400.py:90:13: TRY400 Use `logging.exception` instead of `logging.error` + | +89 | if True: +90 | error("Context message here") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400 + | + diff --git a/crates/ruff_linter/src/rules/tryceratops/snapshots/ruff_linter__rules__tryceratops__tests__verbose-log-message_TRY401.py.snap b/crates/ruff_linter/src/rules/tryceratops/snapshots/ruff_linter__rules__tryceratops__tests__verbose-log-message_TRY401.py.snap index 7143686b8708c..3681b880d1f06 100644 --- a/crates/ruff_linter/src/rules/tryceratops/snapshots/ruff_linter__rules__tryceratops__tests__verbose-log-message_TRY401.py.snap +++ b/crates/ruff_linter/src/rules/tryceratops/snapshots/ruff_linter__rules__tryceratops__tests__verbose-log-message_TRY401.py.snap @@ -89,4 +89,92 @@ TRY401.py:53:47: TRY401 Redundant exception object included in `logging.exceptio | ^^ TRY401 | +TRY401.py:77:38: TRY401 Redundant exception object included in `logging.exception` call + | +75 | finish() +76 | except Exception as ex: +77 | exception(f"Found an error: {ex}") # TRY401 + | ^^ TRY401 + | + +TRY401.py:88:46: TRY401 Redundant exception object included in `logging.exception` call + | +86 | if True is False: +87 | for i in range(10): +88 | exception(f"Found an error: {bad} {good}") # TRY401 + | ^^^ TRY401 +89 | except IndexError as bad: +90 | exception(f"Found an error: {bad} {bad}") # TRY401 + | + +TRY401.py:90:38: TRY401 Redundant exception object included in `logging.exception` call + | +88 | exception(f"Found an error: {bad} {good}") # TRY401 +89 | except IndexError as bad: +90 | exception(f"Found an error: {bad} {bad}") # TRY401 + | ^^^ TRY401 +91 | except Exception as bad: +92 | exception(f"Found an error: {bad}") # TRY401 + | + +TRY401.py:90:44: TRY401 Redundant exception object included in `logging.exception` call + | +88 | exception(f"Found an error: {bad} {good}") # TRY401 +89 | except IndexError as bad: +90 | exception(f"Found an error: {bad} {bad}") # TRY401 + | ^^^ TRY401 +91 | except Exception as bad: +92 | exception(f"Found an error: {bad}") # TRY401 + | + +TRY401.py:92:38: TRY401 Redundant exception object included in `logging.exception` call + | +90 | exception(f"Found an error: {bad} {bad}") # TRY401 +91 | except Exception as bad: +92 | exception(f"Found an error: {bad}") # TRY401 + | ^^^ TRY401 +93 | exception(f"Found an error: {bad}") # TRY401 + | + +TRY401.py:93:38: TRY401 Redundant exception object included in `logging.exception` call + | +91 | except Exception as bad: +92 | exception(f"Found an error: {bad}") # TRY401 +93 | exception(f"Found an error: {bad}") # TRY401 + | ^^^ TRY401 +94 | +95 | if True: + | + +TRY401.py:96:42: TRY401 Redundant exception object included in `logging.exception` call + | +95 | if True: +96 | exception(f"Found an error: {bad}") # TRY401 + | ^^^ TRY401 + | + +TRY401.py:103:40: TRY401 Redundant exception object included in `logging.exception` call + | +101 | ... +102 | except Exception as ex: +103 | exception(f"Logging an error: {ex}") # TRY401 + | ^^ TRY401 + | + +TRY401.py:110:46: TRY401 Redundant exception object included in `logging.exception` call + | +108 | ... +109 | except Exception as ex: +110 | exception("Logging an error: " + str(ex)) # TRY401 + | ^^ TRY401 + | + +TRY401.py:117:40: TRY401 Redundant exception object included in `logging.exception` call + | +115 | ... +116 | except Exception as ex: +117 | exception("Logging an error:", ex) # TRY401 + | ^^ TRY401 + | + diff --git a/crates/ruff_linter/src/settings/defaults.rs b/crates/ruff_linter/src/settings/defaults.rs deleted file mode 100644 index 8b137891791fe..0000000000000 --- a/crates/ruff_linter/src/settings/defaults.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/crates/ruff_linter/src/settings/mod.rs b/crates/ruff_linter/src/settings/mod.rs index 6ced3e3be0608..6f36a5280c871 100644 --- a/crates/ruff_linter/src/settings/mod.rs +++ b/crates/ruff_linter/src/settings/mod.rs @@ -2,7 +2,6 @@ //! command-line options. Structure is optimized for internal usage, as opposed //! to external visibility or parsing. -use std::collections::HashSet; use std::path::{Path, PathBuf}; use anyhow::Result; @@ -15,6 +14,7 @@ use rustc_hash::FxHashSet; use crate::codes::RuleCodePrefix; use ruff_macros::CacheKey; +use crate::line_width::LineLength; use crate::registry::{Linter, Rule, RuleSet}; use crate::rules::{ flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins, flake8_comprehensions, @@ -23,13 +23,14 @@ use crate::rules::{ flake8_tidy_imports, flake8_type_checking, flake8_unused_arguments, isort, mccabe, pep8_naming, pycodestyle, pydocstyle, pyflakes, pylint, pyupgrade, }; -use crate::settings::types::{PerFileIgnore, PythonVersion}; +use crate::settings::types::{FilePatternSet, PerFileIgnore, PythonVersion}; use crate::{codes, RuleSelector}; -use super::line_width::{LineLength, TabSize}; +use super::line_width::IndentWidth; use self::rule_table::RuleTable; use self::types::PreviewMode; +use crate::rule_selector::PreviewOptions; pub mod flags; pub mod rule_table; @@ -37,27 +38,32 @@ pub mod types; #[derive(Debug, CacheKey)] pub struct LinterSettings { + pub exclude: FilePatternSet, pub project_root: PathBuf, pub rules: RuleTable, pub per_file_ignores: Vec<(GlobMatcher, GlobMatcher, RuleSet)>, + pub extend_unsafe_fixes: RuleSet, + pub extend_safe_fixes: RuleSet, pub target_version: PythonVersion, pub preview: PreviewMode, + pub explicit_preview_rules: bool, // Rule-specific settings pub allowed_confusables: FxHashSet, pub builtins: Vec, pub dummy_variable_rgx: Regex, - pub external: FxHashSet, + pub external: Vec, pub ignore_init_module_imports: bool, - pub line_length: LineLength, pub logger_objects: Vec, pub namespace_packages: Vec, pub src: Vec, - pub tab_size: TabSize, + pub tab_size: IndentWidth, + pub line_length: LineLength, pub task_tags: Vec, pub typing_modules: Vec, + // Plugins pub flake8_annotations: flake8_annotations::settings::Settings, pub flake8_bandit: flake8_bandit::settings::Settings, @@ -85,12 +91,21 @@ pub struct LinterSettings { pub pyupgrade: pyupgrade::settings::Settings, } -pub const PREFIXES: &[RuleSelector] = &[ +pub const DEFAULT_SELECTORS: &[RuleSelector] = &[ + RuleSelector::Linter(Linter::Pyflakes), + // Only include pycodestyle rules that do not overlap with the formatter RuleSelector::Prefix { - prefix: RuleCodePrefix::Pycodestyle(codes::Pycodestyle::E), + prefix: RuleCodePrefix::Pycodestyle(codes::Pycodestyle::E4), + redirected_from: None, + }, + RuleSelector::Prefix { + prefix: RuleCodePrefix::Pycodestyle(codes::Pycodestyle::E7), + redirected_from: None, + }, + RuleSelector::Prefix { + prefix: RuleCodePrefix::Pycodestyle(codes::Pycodestyle::E9), redirected_from: None, }, - RuleSelector::Linter(Linter::Pyflakes), ]; pub const TASK_TAGS: &[&str] = &["TODO", "FIXME", "XXX"]; @@ -117,11 +132,12 @@ impl LinterSettings { pub fn new(project_root: &Path) -> Self { Self { + exclude: FilePatternSet::default(), target_version: PythonVersion::default(), project_root: project_root.to_path_buf(), - rules: PREFIXES + rules: DEFAULT_SELECTORS .iter() - .flat_map(|selector| selector.rules(PreviewMode::default())) + .flat_map(|selector| selector.rules(&PreviewOptions::default())) .collect(), allowed_confusables: FxHashSet::from_iter([]), @@ -129,17 +145,19 @@ impl LinterSettings { builtins: vec![], dummy_variable_rgx: DUMMY_VARIABLE_RGX.clone(), - external: HashSet::default(), + external: vec![], ignore_init_module_imports: false, - line_length: LineLength::default(), logger_objects: vec![], namespace_packages: vec![], per_file_ignores: vec![], + extend_safe_fixes: RuleSet::empty(), + extend_unsafe_fixes: RuleSet::empty(), src: vec![path_dedot::CWD.clone()], // Needs duplicating - tab_size: TabSize::default(), + tab_size: IndentWidth::default(), + line_length: LineLength::default(), task_tags: TASK_TAGS.iter().map(ToString::to_string).collect(), typing_modules: vec![], @@ -168,6 +186,7 @@ impl LinterSettings { pylint: pylint::settings::Settings::default(), pyupgrade: pyupgrade::settings::Settings::default(), preview: PreviewMode::default(), + explicit_preview_rules: false, } } diff --git a/crates/ruff_linter/src/settings/rule_table.rs b/crates/ruff_linter/src/settings/rule_table.rs index 16438adf94bd5..25e8c13ea5ecf 100644 --- a/crates/ruff_linter/src/settings/rule_table.rs +++ b/crates/ruff_linter/src/settings/rule_table.rs @@ -5,10 +5,10 @@ use ruff_macros::CacheKey; use crate::registry::{Rule, RuleSet, RuleSetIterator}; /// A table to keep track of which rules are enabled -/// and Whether they should be autofixed. +/// and Whether they should be fixed. #[derive(Debug, CacheKey, Default)] pub struct RuleTable { - /// Maps rule codes to a boolean indicating if the rule should be autofixed. + /// Maps rule codes to a boolean indicating if the rule should be fixed. enabled: RuleSet, should_fix: RuleSet, } @@ -34,7 +34,7 @@ impl RuleTable { self.enabled.intersects(&RuleSet::from_rules(rules)) } - /// Returns whether violations of the given rule should be autofixed. + /// Returns whether violations of the given rule should be fixed. #[inline] pub const fn should_fix(&self, rule: Rule) -> bool { self.should_fix.contains(rule) diff --git a/crates/ruff_linter/src/settings/types.rs b/crates/ruff_linter/src/settings/types.rs index 1f5c073918164..f74bbc3555d05 100644 --- a/crates/ruff_linter/src/settings/types.rs +++ b/crates/ruff_linter/src/settings/types.rs @@ -7,6 +7,7 @@ use std::string::ToString; use anyhow::{bail, Result}; use globset::{Glob, GlobSet, GlobSetBuilder}; use pep440_rs::{Version as Pep440Version, VersionSpecifiers}; +use ruff_diagnostics::Applicability; use serde::{de, Deserialize, Deserializer, Serialize}; use strum::IntoEnumIterator; use strum_macros::EnumIter; @@ -90,9 +91,16 @@ impl PythonVersion { } minimum_version } + + /// Return `true` if the current version supports [PEP 701]. + /// + /// [PEP 701]: https://peps.python.org/pep-0701/ + pub fn supports_pep701(self) -> bool { + self >= Self::Py312 + } } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, CacheKey, is_macro::Is)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, CacheKey, is_macro::Is)] pub enum PreviewMode { #[default] Disabled, @@ -109,6 +117,32 @@ impl From for PreviewMode { } } +#[derive(Debug, Copy, Clone, CacheKey, Default, PartialEq, Eq, is_macro::Is)] +pub enum UnsafeFixes { + #[default] + Disabled, + Enabled, +} + +impl From for UnsafeFixes { + fn from(version: bool) -> Self { + if version { + UnsafeFixes::Enabled + } else { + UnsafeFixes::Disabled + } + } +} + +impl UnsafeFixes { + pub fn required_applicability(&self) -> Applicability { + match self { + Self::Enabled => Applicability::Unsafe, + Self::Disabled => Applicability::Safe, + } + } +} + #[derive(Debug, Clone, CacheKey, PartialEq, PartialOrd, Eq, Ord)] pub enum FilePattern { Builtin(&'static str), diff --git a/crates/ruff_linter/src/source_kind.rs b/crates/ruff_linter/src/source_kind.rs index 501d417366613..892eb5b595467 100644 --- a/crates/ruff_linter/src/source_kind.rs +++ b/crates/ruff_linter/src/source_kind.rs @@ -1,5 +1,16 @@ +use std::io; +use std::io::Write; +use std::path::Path; + +use anyhow::Result; +use similar::TextDiff; +use thiserror::Error; + use ruff_diagnostics::SourceMap; -use ruff_notebook::Notebook; +use ruff_notebook::{Cell, Notebook, NotebookError}; +use ruff_python_ast::PySourceType; + +use crate::fs; #[derive(Clone, Debug, PartialEq, is_macro::Is)] pub enum SourceKind { @@ -22,10 +33,141 @@ impl SourceKind { } } + /// Returns the Python source code for this source kind. pub fn source_code(&self) -> &str { match self { SourceKind::Python(source) => source, SourceKind::IpyNotebook(notebook) => notebook.source_code(), } } + + /// Read the [`SourceKind`] from the given path. Returns `None` if the source is not a Python + /// source file. + pub fn from_path(path: &Path, source_type: PySourceType) -> Result, SourceError> { + if source_type.is_ipynb() { + let notebook = Notebook::from_path(path)?; + Ok(notebook + .is_python_notebook() + .then_some(Self::IpyNotebook(notebook))) + } else { + let contents = std::fs::read_to_string(path)?; + Ok(Some(Self::Python(contents))) + } + } + + /// Read the [`SourceKind`] from the given source code. Returns `None` if the source is not + /// Python source code. + pub fn from_source_code( + source_code: String, + source_type: PySourceType, + ) -> Result, SourceError> { + if source_type.is_ipynb() { + let notebook = Notebook::from_source_code(&source_code)?; + Ok(notebook + .is_python_notebook() + .then_some(Self::IpyNotebook(notebook))) + } else { + Ok(Some(Self::Python(source_code))) + } + } + + /// Write the transformed source file to the given writer. + /// + /// For Jupyter notebooks, this will write out the notebook as JSON. + pub fn write(&self, writer: &mut dyn Write) -> Result<(), SourceError> { + match self { + SourceKind::Python(source) => { + writer.write_all(source.as_bytes())?; + Ok(()) + } + SourceKind::IpyNotebook(notebook) => { + notebook.write(writer)?; + Ok(()) + } + } + } + + /// Write a diff of the transformed source file to `stdout`. + pub fn diff( + &self, + other: &Self, + path: Option<&Path>, + writer: &mut dyn Write, + ) -> io::Result<()> { + match (self, other) { + (SourceKind::Python(src), SourceKind::Python(dst)) => { + let text_diff = TextDiff::from_lines(src, dst); + let mut unified_diff = text_diff.unified_diff(); + + if let Some(path) = path { + unified_diff.header(&fs::relativize_path(path), &fs::relativize_path(path)); + } + + unified_diff.to_writer(&mut *writer)?; + + writer.write_all(b"\n")?; + writer.flush()?; + + Ok(()) + } + (SourceKind::IpyNotebook(src), SourceKind::IpyNotebook(dst)) => { + // Cell indices are 1-based. + for ((idx, src_cell), dst_cell) in + (1u32..).zip(src.cells().iter()).zip(dst.cells().iter()) + { + let (Cell::Code(src_cell), Cell::Code(dst_cell)) = (src_cell, dst_cell) else { + continue; + }; + + let src_source_code = src_cell.source.to_string(); + let dst_source_code = dst_cell.source.to_string(); + + let text_diff = TextDiff::from_lines(&src_source_code, &dst_source_code); + let mut unified_diff = text_diff.unified_diff(); + + // Jupyter notebook cells don't necessarily have a newline + // at the end. For example, + // + // ```python + // print("hello") + // ``` + // + // For a cell containing the above code, there'll only be one line, + // and it won't have a newline at the end. If it did, there'd be + // two lines, and the second line would be empty: + // + // ```python + // print("hello") + // + // ``` + unified_diff.missing_newline_hint(false); + + if let Some(path) = path { + unified_diff.header( + &format!("{}:cell {}", &fs::relativize_path(path), idx), + &format!("{}:cell {}", &fs::relativize_path(path), idx), + ); + } else { + unified_diff.header(&format!("cell {idx}"), &format!("cell {idx}")); + }; + + unified_diff.to_writer(&mut *writer)?; + } + + writer.write_all(b"\n")?; + writer.flush()?; + + Ok(()) + } + _ => panic!("cannot diff Python source code with Jupyter notebook source code"), + } + } +} + +#[derive(Error, Debug)] +pub enum SourceError { + #[error(transparent)] + Io(#[from] io::Error), + #[error(transparent)] + Notebook(#[from] NotebookError), } diff --git a/crates/ruff_linter/src/test.rs b/crates/ruff_linter/src/test.rs index 2924814c08542..27c94224d9d92 100644 --- a/crates/ruff_linter/src/test.rs +++ b/crates/ruff_linter/src/test.rs @@ -9,7 +9,7 @@ use anyhow::Result; use itertools::Itertools; use rustc_hash::FxHashMap; -use ruff_diagnostics::{AutofixKind, Diagnostic}; +use ruff_diagnostics::{Diagnostic, FixAvailability}; use ruff_python_ast::PySourceType; use ruff_python_codegen::Stylist; use ruff_python_index::Indexer; @@ -19,13 +19,14 @@ use ruff_python_trivia::textwrap::dedent; use ruff_source_file::{Locator, SourceFileBuilder}; use ruff_text_size::Ranged; -use crate::autofix::{fix_file, FixResult}; use crate::directives; +use crate::fix::{fix_file, FixResult}; use crate::linter::{check_path, LinterResult}; use crate::message::{Emitter, EmitterContext, Message, TextEmitter}; use crate::packaging::detect_package_root; use crate::registry::AsRule; use crate::rules::pycodestyle::rules::syntax_error; +use crate::settings::types::UnsafeFixes; use crate::settings::{flags, LinterSettings}; use crate::source_kind::SourceKind; use ruff_notebook::Notebook; @@ -102,7 +103,7 @@ pub(crate) fn max_iterations() -> usize { } /// A convenient wrapper around [`check_path`], that additionally -/// asserts that autofixes converge after a fixed number of iterations. +/// asserts that fixes converge after a fixed number of iterations. pub(crate) fn test_contents<'a>( source_kind: &'a SourceKind, path: &Path, @@ -140,7 +141,7 @@ pub(crate) fn test_contents<'a>( let source_has_errors = error.is_some(); - // Detect autofixes that don't converge after multiple iterations. + // Detect fixes that don't converge after multiple iterations. let mut iterations = 0; let mut transformed = Cow::Borrowed(source_kind); @@ -155,8 +156,11 @@ pub(crate) fn test_contents<'a>( code: fixed_contents, source_map, .. - }) = fix_file(&diagnostics, &Locator::new(transformed.source_code())) - { + }) = fix_file( + &diagnostics, + &Locator::new(transformed.source_code()), + UnsafeFixes::Enabled, + ) { if iterations < max_iterations() { iterations += 1; } else { @@ -197,7 +201,7 @@ pub(crate) fn test_contents<'a>( &directives, settings, flags::Noqa::Enabled, - source_kind, + &transformed, source_type, ); @@ -238,20 +242,20 @@ Source with applied fixes: let rule = diagnostic.kind.rule(); let fixable = diagnostic.fix.is_some(); - match (fixable, rule.autofixable()) { - (true, AutofixKind::Sometimes | AutofixKind::Always) - | (false, AutofixKind::None | AutofixKind::Sometimes) => { + match (fixable, rule.fixable()) { + (true, FixAvailability::Sometimes | FixAvailability::Always) + | (false, FixAvailability::None | FixAvailability::Sometimes) => { // Ok } - (true, AutofixKind::None) => { - panic!("Rule {rule:?} is marked as non-fixable but it created a fix. Change the `Violation::AUTOFIX` to either `AutofixKind::Sometimes` or `AutofixKind::Always`"); + (true, FixAvailability::None) => { + panic!("Rule {rule:?} is marked as non-fixable but it created a fix. Change the `Violation::FIX_AVAILABILITY` to either `FixAvailability::Sometimes` or `FixAvailability::Always`"); }, - (false, AutofixKind::Always) => { - panic!("Rule {rule:?} is marked to always-fixable but the diagnostic has no fix. Either ensure you always emit a fix or change `Violation::AUTOFIX` to either `AutofixKind::Sometimes` or `AutofixKind::None") + (false, FixAvailability::Always) => { + panic!("Rule {rule:?} is marked to always-fixable but the diagnostic has no fix. Either ensure you always emit a fix or change `Violation::FIX_AVAILABILITY` to either `FixAvailability::Sometimes` or `FixAvailability::None") } } - assert!(!(fixable && diagnostic.kind.suggestion.is_none()), "Diagnostic emitted by {rule:?} is fixable but `Violation::autofix_title` returns `None`.`"); + assert!(!(fixable && diagnostic.kind.suggestion.is_none()), "Diagnostic emitted by {rule:?} is fixable but `Violation::fix_title` returns `None`.`"); // Not strictly necessary but adds some coverage for this code path let noqa = directives.noqa_line_for.resolve(diagnostic.start()); @@ -294,6 +298,7 @@ pub(crate) fn print_jupyter_messages( .with_show_fix_status(true) .with_show_fix_diff(true) .with_show_source(true) + .with_unsafe_fixes(UnsafeFixes::Enabled) .emit( &mut output, messages, @@ -314,6 +319,7 @@ pub(crate) fn print_messages(messages: &[Message]) -> String { .with_show_fix_status(true) .with_show_fix_diff(true) .with_show_source(true) + .with_unsafe_fixes(UnsafeFixes::Enabled) .emit( &mut output, messages, diff --git a/crates/ruff_macros/src/cache_key.rs b/crates/ruff_macros/src/cache_key.rs index 4093b96a3f549..6519982950a7d 100644 --- a/crates/ruff_macros/src/cache_key.rs +++ b/crates/ruff_macros/src/cache_key.rs @@ -101,6 +101,7 @@ pub(crate) fn derive_cache_key(item: &DeriveInput) -> syn::Result { let (impl_generics, ty_generics, where_clause) = &item.generics.split_for_impl(); Ok(quote!( + #[automatically_derived] impl #impl_generics ruff_cache::CacheKey for #name #ty_generics #where_clause { fn cache_key(&self, key: &mut ruff_cache::CacheKeyHasher) { use std::hash::Hasher; diff --git a/crates/ruff_macros/src/combine_options.rs b/crates/ruff_macros/src/combine_options.rs index b6a940b72d1b8..05b2395e072bf 100644 --- a/crates/ruff_macros/src/combine_options.rs +++ b/crates/ruff_macros/src/combine_options.rs @@ -16,8 +16,10 @@ pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result, _>>()?; Ok(quote! { + #[automatically_derived] impl crate::configuration::CombinePluginOptions for #ident { fn combine(self, other: Self) -> Self { + #[allow(deprecated)] Self { #( #output diff --git a/crates/ruff_macros/src/config.rs b/crates/ruff_macros/src/config.rs index 5e48b2f5bfd62..b069dfc063c96 100644 --- a/crates/ruff_macros/src/config.rs +++ b/crates/ruff_macros/src/config.rs @@ -1,15 +1,15 @@ -use ruff_python_trivia::textwrap::dedent; - +use proc_macro2::{TokenStream, TokenTree}; use quote::{quote, quote_spanned}; -use syn::parse::{Parse, ParseStream}; +use syn::meta::ParseNestedMeta; use syn::spanned::Spanned; -use syn::token::Comma; use syn::{ AngleBracketedGenericArguments, Attribute, Data, DataStruct, DeriveInput, ExprLit, Field, - Fields, Lit, LitStr, Path, PathArguments, PathSegment, Token, Type, TypePath, + Fields, Lit, LitStr, Meta, Path, PathArguments, PathSegment, Type, TypePath, }; -pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result { +use ruff_python_trivia::textwrap::dedent; + +pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result { let DeriveInput { ident, data, @@ -25,34 +25,39 @@ pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result = field - .attrs - .iter() - .filter(|attr| attr.path().is_ident("doc")) - .collect(); - - if docs.is_empty() { - return Err(syn::Error::new( - field.span(), - "Missing documentation for field", - )); - } - if let Some(attr) = field .attrs .iter() .find(|attr| attr.path().is_ident("option")) { - output.push(handle_option(field, attr, docs)?); - }; - - if field + output.push(handle_option(field, attr)?); + } else if field .attrs .iter() .any(|attr| attr.path().is_ident("option_group")) { output.push(handle_option_group(field)?); - }; + } else if let Some(serde) = field + .attrs + .iter() + .find(|attr| attr.path().is_ident("serde")) + { + // If a field has the `serde(flatten)` attribute, flatten the options into the parent + // by calling `Type::record` instead of `visitor.visit_set` + if let (Type::Path(ty), Meta::List(list)) = (&field.ty, &serde.meta) { + for token in list.tokens.clone() { + if let TokenTree::Ident(ident) = token { + if ident == "flatten" { + let ty_name = ty.path.require_ident()?; + output.push(quote_spanned!( + ident.span() => (#ty_name::record(visit)) + )); + break; + } + } + } + } + } } let docs: Vec<&Attribute> = struct_attributes @@ -82,6 +87,7 @@ pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result syn::Result { /// Parse an `#[option(doc="...", default="...", value_type="...", /// example="...")]` attribute and return data in the form of an `OptionField`. -fn handle_option( - field: &Field, - attr: &Attribute, - docs: Vec<&Attribute>, -) -> syn::Result { +fn handle_option(field: &Field, attr: &Attribute) -> syn::Result { + let docs: Vec<&Attribute> = field + .attrs + .iter() + .filter(|attr| attr.path().is_ident("doc")) + .collect(); + + if docs.is_empty() { + return Err(syn::Error::new( + field.span(), + "Missing documentation for field", + )); + } + // Convert the list of `doc` attributes into a single string. let doc = dedent( &docs @@ -175,9 +190,30 @@ fn handle_option( default, value_type, example, - } = attr.parse_args::()?; + } = parse_field_attributes(attr)?; let kebab_name = LitStr::new(&ident.to_string().replace('_', "-"), ident.span()); + let deprecated = if let Some(deprecated) = field + .attrs + .iter() + .find(|attr| attr.path().is_ident("deprecated")) + { + fn quote_option(option: Option) -> TokenStream { + match option { + None => quote!(None), + Some(value) => quote!(Some(#value)), + } + } + + let deprecated = parse_deprecated_attribute(deprecated)?; + let note = quote_option(deprecated.note); + let since = quote_option(deprecated.since); + + quote!(Some(crate::options_base::Deprecated { since: #since, message: #note })) + } else { + quote!(None) + }; + Ok(quote_spanned!( ident.span() => { visit.record_field(#kebab_name, crate::options_base::OptionField{ @@ -185,6 +221,7 @@ fn handle_option( default: &#default, value_type: &#value_type, example: &#example, + deprecated: #deprecated }) } )) @@ -197,39 +234,109 @@ struct FieldAttributes { example: String, } -impl Parse for FieldAttributes { - fn parse(input: ParseStream) -> syn::Result { - let default = _parse_key_value(input, "default")?; - input.parse::()?; - let value_type = _parse_key_value(input, "value_type")?; - input.parse::()?; - let example = _parse_key_value(input, "example")?; - if !input.is_empty() { - input.parse::()?; +fn parse_field_attributes(attribute: &Attribute) -> syn::Result { + let mut default = None; + let mut value_type = None; + let mut example = None; + + attribute.parse_nested_meta(|meta| { + if meta.path.is_ident("default") { + default = Some(get_string_literal(&meta, "default", "option")?.value()); + } else if meta.path.is_ident("value_type") { + value_type = Some(get_string_literal(&meta, "value_type", "option")?.value()); + } else if meta.path.is_ident("example") { + let example_text = get_string_literal(&meta, "value_type", "option")?.value(); + example = Some(dedent(&example_text).trim_matches('\n').to_string()); + } else { + return Err(syn::Error::new( + meta.path.span(), + format!( + "Deprecated meta {:?} is not supported by ruff's option macro.", + meta.path.get_ident() + ), + )); } - Ok(Self { - default, - value_type, - example: dedent(&example).trim_matches('\n').to_string(), - }) - } + Ok(()) + })?; + + let Some(default) = default else { + return Err(syn::Error::new(attribute.span(), "Mandatory `default` field is missing in `#[option]` attribute. Specify the default using `#[option(default=\"..\")]`.")); + }; + + let Some(value_type) = value_type else { + return Err(syn::Error::new(attribute.span(), "Mandatory `value_type` field is missing in `#[option]` attribute. Specify the value type using `#[option(value_type=\"..\")]`.")); + }; + + let Some(example) = example else { + return Err(syn::Error::new(attribute.span(), "Mandatory `example` field is missing in `#[option]` attribute. Add an example using `#[option(example=\"..\")]`.")); + }; + + Ok(FieldAttributes { + default, + value_type, + example, + }) } -fn _parse_key_value(input: ParseStream, name: &str) -> syn::Result { - let ident: proc_macro2::Ident = input.parse()?; - if ident != name { - return Err(syn::Error::new( - ident.span(), - format!("Expected `{name}` name"), - )); +fn parse_deprecated_attribute(attribute: &Attribute) -> syn::Result { + let mut deprecated = DeprecatedAttribute::default(); + attribute.parse_nested_meta(|meta| { + if meta.path.is_ident("note") { + deprecated.note = Some(get_string_literal(&meta, "note", "deprecated")?.value()); + } else if meta.path.is_ident("since") { + deprecated.since = Some(get_string_literal(&meta, "since", "deprecated")?.value()); + } else { + return Err(syn::Error::new( + meta.path.span(), + format!( + "Deprecated meta {:?} is not supported by ruff's option macro.", + meta.path.get_ident() + ), + )); + } + + Ok(()) + })?; + + Ok(deprecated) +} + +fn get_string_literal( + meta: &ParseNestedMeta, + meta_name: &str, + attribute_name: &str, +) -> syn::Result { + let expr: syn::Expr = meta.value()?.parse()?; + + let mut value = &expr; + while let syn::Expr::Group(e) = value { + value = &e.expr; } - input.parse::()?; - let value: Lit = input.parse()?; + if let syn::Expr::Lit(ExprLit { + lit: Lit::Str(lit), .. + }) = value + { + let suffix = lit.suffix(); + if !suffix.is_empty() { + return Err(syn::Error::new( + lit.span(), + format!("unexpected suffix `{suffix}` on string literal"), + )); + } - match &value { - Lit::Str(v) => Ok(v.value()), - _ => Err(syn::Error::new(value.span(), "Expected literal string")), + Ok(lit.clone()) + } else { + Err(syn::Error::new( + expr.span(), + format!("expected {attribute_name} attribute to be a string: `{meta_name} = \"...\"`"), + )) } } + +#[derive(Default, Debug)] +struct DeprecatedAttribute { + since: Option, + note: Option, +} diff --git a/crates/ruff_macros/src/lib.rs b/crates/ruff_macros/src/lib.rs index 7efedaabadb09..ed9e77508f493 100644 --- a/crates/ruff_macros/src/lib.rs +++ b/crates/ruff_macros/src/lib.rs @@ -15,8 +15,8 @@ mod rule_code_prefix; mod rule_namespace; mod violation; -#[proc_macro_derive(ConfigurationOptions, attributes(option, doc, option_group))] -pub fn derive_config(input: TokenStream) -> TokenStream { +#[proc_macro_derive(OptionsMetadata, attributes(option, doc, option_group))] +pub fn derive_options_metadata(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); config::derive_impl(input) diff --git a/crates/ruff_macros/src/map_codes.rs b/crates/ruff_macros/src/map_codes.rs index 8575ebc1338c2..3a68af8e25258 100644 --- a/crates/ruff_macros/src/map_codes.rs +++ b/crates/ruff_macros/src/map_codes.rs @@ -58,7 +58,7 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result { }; // Map from: linter (e.g., `Flake8Bugbear`) to rule code (e.g.,`"002"`) to rule data (e.g., - // `(Rule::UnaryPrefixIncrement, RuleGroup::Unspecified, vec![])`). + // `(Rule::UnaryPrefixIncrement, RuleGroup::Stable, vec![])`). let mut linter_to_rules: BTreeMap> = BTreeMap::new(); for arm in arms { @@ -388,7 +388,7 @@ fn generate_iter_impl( fn register_rules<'a>(input: impl Iterator) -> TokenStream { let mut rule_variants = quote!(); let mut rule_message_formats_match_arms = quote!(); - let mut rule_autofixable_match_arms = quote!(); + let mut rule_fixable_match_arms = quote!(); let mut rule_explanation_match_arms = quote!(); let mut from_impls_for_diagnostic_kind = quote!(); @@ -404,8 +404,8 @@ fn register_rules<'a>(input: impl Iterator) -> TokenStream { // Apply the `attrs` to each arm, like `[cfg(feature = "foo")]`. rule_message_formats_match_arms .extend(quote! {#(#attrs)* Self::#name => <#path as ruff_diagnostics::Violation>::message_formats(),}); - rule_autofixable_match_arms.extend( - quote! {#(#attrs)* Self::#name => <#path as ruff_diagnostics::Violation>::AUTOFIX,}, + rule_fixable_match_arms.extend( + quote! {#(#attrs)* Self::#name => <#path as ruff_diagnostics::Violation>::FIX_AVAILABILITY,}, ); rule_explanation_match_arms .extend(quote! {#(#attrs)* Self::#name => #path::explanation(),}); @@ -416,6 +416,8 @@ fn register_rules<'a>(input: impl Iterator) -> TokenStream { } quote! { + use ruff_diagnostics::Violation; + #[derive( EnumIter, Debug, @@ -445,9 +447,9 @@ fn register_rules<'a>(input: impl Iterator) -> TokenStream { match self { #rule_explanation_match_arms } } - /// Returns the autofix status of this rule. - pub const fn autofixable(&self) -> ruff_diagnostics::AutofixKind { - match self { #rule_autofixable_match_arms } + /// Returns the fix status of this rule. + pub const fn fixable(&self) -> ruff_diagnostics::FixAvailability { + match self { #rule_fixable_match_arms } } } diff --git a/crates/ruff_macros/src/rule_namespace.rs b/crates/ruff_macros/src/rule_namespace.rs index 79ae54c19d1aa..8d573d84b43c4 100644 --- a/crates/ruff_macros/src/rule_namespace.rs +++ b/crates/ruff_macros/src/rule_namespace.rs @@ -111,6 +111,7 @@ pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result Option<(Self, &str)> { #if_statements diff --git a/crates/ruff_macros/src/violation.rs b/crates/ruff_macros/src/violation.rs index 8356d0d56ce7e..028a5e5a41330 100644 --- a/crates/ruff_macros/src/violation.rs +++ b/crates/ruff_macros/src/violation.rs @@ -53,13 +53,14 @@ pub(crate) fn violation(violation: &ItemStruct) -> Result { #[derive(Debug, PartialEq, Eq)] #violation + #[automatically_derived] impl From<#ident> for ruff_diagnostics::DiagnosticKind { fn from(value: #ident) -> Self { use ruff_diagnostics::Violation; Self { body: Violation::message(&value), - suggestion: Violation::autofix_title(&value), + suggestion: Violation::fix_title(&value), name: stringify!(#ident).to_string(), } } @@ -76,13 +77,14 @@ pub(crate) fn violation(violation: &ItemStruct) -> Result { } } + #[automatically_derived] impl From<#ident> for ruff_diagnostics::DiagnosticKind { fn from(value: #ident) -> Self { use ruff_diagnostics::Violation; Self { body: Violation::message(&value), - suggestion: Violation::autofix_title(&value), + suggestion: Violation::fix_title(&value), name: stringify!(#ident).to_string(), } } diff --git a/crates/ruff_notebook/Cargo.toml b/crates/ruff_notebook/Cargo.toml index 7b3dfde8f6a6b..1ef679bbead56 100644 --- a/crates/ruff_notebook/Cargo.toml +++ b/crates/ruff_notebook/Cargo.toml @@ -14,7 +14,7 @@ license = { workspace = true } [dependencies] ruff_diagnostics = { path = "../ruff_diagnostics" } -ruff_source_file = { path = "../ruff_source_file" } +ruff_source_file = { path = "../ruff_source_file", features = ["serde"] } ruff_text_size = { path = "../ruff_text_size" } anyhow = { workspace = true } @@ -22,7 +22,7 @@ itertools = { workspace = true } once_cell = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } -serde_with = { version = "3.0.0", default-features = false, features = ["macros"] } +serde_with = { version = "3.4.0", default-features = false, features = ["macros"] } thiserror = { workspace = true } uuid = { workspace = true } diff --git a/crates/ruff_notebook/src/index.rs b/crates/ruff_notebook/src/index.rs index 23259468ee56f..9912b94e6225e 100644 --- a/crates/ruff_notebook/src/index.rs +++ b/crates/ruff_notebook/src/index.rs @@ -1,5 +1,7 @@ use serde::{Deserialize, Serialize}; +use ruff_source_file::{OneIndexed, SourceLocation}; + /// Jupyter Notebook indexing table /// /// When we lint a jupyter notebook, we have to translate the row/column based on @@ -7,20 +9,40 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub struct NotebookIndex { /// Enter a row (1-based), get back the cell (1-based) - pub(super) row_to_cell: Vec, + pub(super) row_to_cell: Vec, /// Enter a row (1-based), get back the row in cell (1-based) - pub(super) row_to_row_in_cell: Vec, + pub(super) row_to_row_in_cell: Vec, } impl NotebookIndex { + pub fn new(row_to_cell: Vec, row_to_row_in_cell: Vec) -> Self { + Self { + row_to_cell, + row_to_row_in_cell, + } + } + /// Returns the cell number (1-based) for the given row (1-based). - pub fn cell(&self, row: usize) -> Option { - self.row_to_cell.get(row).copied() + pub fn cell(&self, row: OneIndexed) -> Option { + self.row_to_cell.get(row.to_zero_indexed()).copied() } /// Returns the row number (1-based) in the cell (1-based) for the /// given row (1-based). - pub fn cell_row(&self, row: usize) -> Option { - self.row_to_row_in_cell.get(row).copied() + pub fn cell_row(&self, row: OneIndexed) -> Option { + self.row_to_row_in_cell.get(row.to_zero_indexed()).copied() + } + + /// Translates the given source location based on the indexing table. + /// + /// This will translate the row/column in the concatenated source code + /// to the row/column in the Jupyter Notebook. + pub fn translate_location(&self, source_location: &SourceLocation) -> SourceLocation { + SourceLocation { + row: self + .cell_row(source_location.row) + .unwrap_or(OneIndexed::MIN), + column: source_location.column, + } } } diff --git a/crates/ruff_notebook/src/notebook.rs b/crates/ruff_notebook/src/notebook.rs index 66b91199a449a..611b90cbee2e1 100644 --- a/crates/ruff_notebook/src/notebook.rs +++ b/crates/ruff_notebook/src/notebook.rs @@ -13,7 +13,7 @@ use thiserror::Error; use uuid::Uuid; use ruff_diagnostics::{SourceMap, SourceMarker}; -use ruff_source_file::{NewlineWithTrailingNewline, UniversalNewlineIterator}; +use ruff_source_file::{NewlineWithTrailingNewline, OneIndexed, UniversalNewlineIterator}; use ruff_text_size::TextSize; use crate::index::NotebookIndex; @@ -149,7 +149,7 @@ impl Notebook { { let trailing_newline = reader.seek(SeekFrom::End(-1)).is_ok_and(|_| { let mut buf = [0; 1]; - reader.read_exact(&mut buf).is_ok_and(|_| buf[0] == b'\n') + reader.read_exact(&mut buf).is_ok_and(|()| buf[0] == b'\n') }); reader.rewind()?; let mut raw_notebook: RawNotebook = match serde_json::from_reader(reader.by_ref()) { @@ -179,7 +179,7 @@ impl Notebook { .iter() .enumerate() .filter(|(_, cell)| cell.is_valid_code_cell()) - .map(|(idx, _)| u32::try_from(idx).unwrap()) + .map(|(cell_index, _)| u32::try_from(cell_index).unwrap()) .collect::>(); let mut contents = Vec::with_capacity(valid_code_cells.len()); @@ -321,16 +321,16 @@ impl Notebook { /// The index building is expensive as it needs to go through the content of /// every valid code cell. fn build_index(&self) -> NotebookIndex { - let mut row_to_cell = vec![0]; - let mut row_to_row_in_cell = vec![0]; + let mut row_to_cell = Vec::new(); + let mut row_to_row_in_cell = Vec::new(); - for &idx in &self.valid_code_cells { - let line_count = match &self.raw.cells[idx as usize].source() { + for &cell_index in &self.valid_code_cells { + let line_count = match &self.raw.cells[cell_index as usize].source() { SourceValue::String(string) => { if string.is_empty() { 1 } else { - u32::try_from(NewlineWithTrailingNewline::from(string).count()).unwrap() + NewlineWithTrailingNewline::from(string).count() } } SourceValue::StringArray(string_array) => { @@ -339,12 +339,14 @@ impl Notebook { } else { let trailing_newline = usize::from(string_array.last().is_some_and(|s| s.ends_with('\n'))); - u32::try_from(string_array.len() + trailing_newline).unwrap() + string_array.len() + trailing_newline } } }; - row_to_cell.extend(iter::repeat(idx + 1).take(line_count as usize)); - row_to_row_in_cell.extend(1..=line_count); + row_to_cell.extend( + iter::repeat(OneIndexed::from_zero_indexed(cell_index as usize)).take(line_count), + ); + row_to_row_in_cell.extend((0..line_count).map(OneIndexed::from_zero_indexed)); } NotebookIndex { @@ -363,12 +365,21 @@ impl Notebook { /// Return the Jupyter notebook index. /// /// The index is built only once when required. This is only used to - /// report diagnostics, so by that time all of the autofixes must have + /// report diagnostics, so by that time all of the fixes must have /// been applied if `--fix` was passed. pub fn index(&self) -> &NotebookIndex { self.index.get_or_init(|| self.build_index()) } + /// Return the Jupyter notebook index, consuming the notebook. + /// + /// The index is built only once when required. This is only used to + /// report diagnostics, so by that time all of the fixes must have + /// been applied if `--fix` was passed. + pub fn into_index(mut self) -> NotebookIndex { + self.index.take().unwrap_or_else(|| self.build_index()) + } + /// Return the cell offsets for the concatenated source code corresponding /// the Jupyter notebook. pub fn cell_offsets(&self) -> &[TextSize] { @@ -405,11 +416,13 @@ impl Notebook { } /// Write the notebook back to the given [`Write`] implementor. - pub fn write(&self, writer: &mut dyn Write) -> anyhow::Result<()> { + pub fn write(&self, writer: &mut dyn Write) -> Result<(), NotebookError> { // https://github.com/psf/black/blob/69ca0a4c7a365c5f5eea519a90980bab72cab764/src/black/__init__.py#LL1041 let formatter = serde_json::ser::PrettyFormatter::with_indent(b" "); let mut serializer = serde_json::Serializer::with_formatter(writer, formatter); - SortAlphabetically(&self.raw).serialize(&mut serializer)?; + SortAlphabetically(&self.raw) + .serialize(&mut serializer) + .map_err(NotebookError::Json)?; if self.trailing_newline { writeln!(serializer.into_inner())?; } @@ -424,6 +437,8 @@ mod tests { use anyhow::Result; use test_case::test_case; + use ruff_source_file::OneIndexed; + use crate::{Cell, Notebook, NotebookError, NotebookIndex}; /// Construct a path to a Jupyter notebook in the `resources/test/fixtures/jupyter` directory. @@ -503,8 +518,40 @@ print("after empty cells") assert_eq!( notebook.index(), &NotebookIndex { - row_to_cell: vec![0, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 5, 7, 7, 8], - row_to_row_in_cell: vec![0, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 1, 1, 2, 1], + row_to_cell: vec![ + OneIndexed::from_zero_indexed(0), + OneIndexed::from_zero_indexed(0), + OneIndexed::from_zero_indexed(0), + OneIndexed::from_zero_indexed(0), + OneIndexed::from_zero_indexed(0), + OneIndexed::from_zero_indexed(0), + OneIndexed::from_zero_indexed(2), + OneIndexed::from_zero_indexed(2), + OneIndexed::from_zero_indexed(2), + OneIndexed::from_zero_indexed(2), + OneIndexed::from_zero_indexed(2), + OneIndexed::from_zero_indexed(4), + OneIndexed::from_zero_indexed(6), + OneIndexed::from_zero_indexed(6), + OneIndexed::from_zero_indexed(7) + ], + row_to_row_in_cell: vec![ + OneIndexed::from_zero_indexed(0), + OneIndexed::from_zero_indexed(1), + OneIndexed::from_zero_indexed(2), + OneIndexed::from_zero_indexed(3), + OneIndexed::from_zero_indexed(4), + OneIndexed::from_zero_indexed(5), + OneIndexed::from_zero_indexed(0), + OneIndexed::from_zero_indexed(1), + OneIndexed::from_zero_indexed(2), + OneIndexed::from_zero_indexed(3), + OneIndexed::from_zero_indexed(4), + OneIndexed::from_zero_indexed(0), + OneIndexed::from_zero_indexed(0), + OneIndexed::from_zero_indexed(1), + OneIndexed::from_zero_indexed(0) + ], } ); assert_eq!( diff --git a/crates/ruff_python_ast/Cargo.toml b/crates/ruff_python_ast/Cargo.toml index b98a00ca23be9..c35a54bb5a58f 100644 --- a/crates/ruff_python_ast/Cargo.toml +++ b/crates/ruff_python_ast/Cargo.toml @@ -21,8 +21,6 @@ bitflags = { workspace = true } is-macro = { workspace = true } itertools = { workspace = true } memchr = { workspace = true } -num-bigint = { workspace = true } -num-traits = { workspace = true } once_cell = { workspace = true } rustc-hash = { workspace = true } serde = { workspace = true, optional = true } diff --git a/crates/ruff_python_ast/src/all.rs b/crates/ruff_python_ast/src/all.rs index 3f738984b55c8..bd0bd66d04a7f 100644 --- a/crates/ruff_python_ast/src/all.rs +++ b/crates/ruff_python_ast/src/all.rs @@ -81,17 +81,21 @@ where | Expr::Tuple(ast::ExprTuple { elts, .. }) => { return (Some(elts), DunderAllFlags::empty()); } - Expr::ListComp(_) | Expr::SetComp(_) | Expr::GeneratorExp(_) => { - // Allow comprehensions, even though we can't statically analyze - // them. + _ => { + // We can't analyze other expressions, but they must be + // valid, since the `list` or `tuple` call will ultimately + // evaluate to a list or tuple. return (None, DunderAllFlags::empty()); } - _ => {} } } } } } + Expr::NamedExpr(ast::ExprNamedExpr { value, .. }) => { + // Allow, e.g., `__all__ += (value := ["A", "B"])`. + return extract_elts(value, is_builtin); + } _ => {} } (None, DunderAllFlags::INVALID_FORMAT) diff --git a/crates/ruff_python_ast/src/comparable.rs b/crates/ruff_python_ast/src/comparable.rs index a3bfd8eea2cc7..bcf097924f8ac 100644 --- a/crates/ruff_python_ast/src/comparable.rs +++ b/crates/ruff_python_ast/src/comparable.rs @@ -15,8 +15,6 @@ //! an implicit concatenation of string literals, as these expressions are considered to //! have the same shape in that they evaluate to the same value. -use num_bigint::BigInt; - use crate as ast; #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)] @@ -334,8 +332,7 @@ pub enum ComparableConstant<'a> { Bool(&'a bool), Str { value: &'a str, unicode: bool }, Bytes(&'a [u8]), - Int(&'a BigInt), - Tuple(Vec>), + Int(&'a ast::Int), Float(u64), Complex { real: u64, imag: u64 }, Ellipsis, @@ -929,11 +926,7 @@ impl<'a> From<&'a ast::Expr> for ComparableExpr<'a> { }) => Self::Starred(ExprStarred { value: value.into(), }), - ast::Expr::Name(ast::ExprName { - id, - ctx: _, - range: _, - }) => Self::Name(ExprName { id: id.as_str() }), + ast::Expr::Name(name) => name.into(), ast::Expr::List(ast::ExprList { elts, ctx: _, @@ -970,6 +963,14 @@ impl<'a> From<&'a ast::Expr> for ComparableExpr<'a> { } } +impl<'a> From<&'a ast::ExprName> for ComparableExpr<'a> { + fn from(expr: &'a ast::ExprName) -> Self { + Self::Name(ExprName { + id: expr.id.as_str(), + }) + } +} + #[derive(Debug, PartialEq, Eq, Hash)] pub struct StmtFunctionDef<'a> { is_async: bool, diff --git a/crates/ruff_python_ast/src/expression.rs b/crates/ruff_python_ast/src/expression.rs index 562c68495281d..041c0a0e4ea05 100644 --- a/crates/ruff_python_ast/src/expression.rs +++ b/crates/ruff_python_ast/src/expression.rs @@ -1,6 +1,6 @@ use ruff_text_size::{Ranged, TextRange}; -use crate::node::AnyNodeRef; +use crate::AnyNodeRef; use crate::{self as ast, Expr}; /// Unowned pendant to [`ast::Expr`] that stores a reference instead of a owned value. diff --git a/crates/ruff_python_ast/src/helpers.rs b/crates/ruff_python_ast/src/helpers.rs index 9e9ce3179cd75..4bd66427f8311 100644 --- a/crates/ruff_python_ast/src/helpers.rs +++ b/crates/ruff_python_ast/src/helpers.rs @@ -1,15 +1,19 @@ use std::borrow::Cow; use std::path::Path; -use num_traits::Zero; +use ruff_python_trivia::CommentRanges; +use ruff_source_file::Locator; use smallvec::SmallVec; use ruff_text_size::{Ranged, TextRange}; use crate::call_path::CallPath; +use crate::parenthesize::parenthesized_range; use crate::statement_visitor::{walk_body, walk_stmt, StatementVisitor}; +use crate::AnyNodeRef; use crate::{ - self as ast, Arguments, Constant, ExceptHandler, Expr, MatchCase, Pattern, Stmt, TypeParam, + self as ast, Arguments, CmpOp, Constant, ExceptHandler, Expr, MatchCase, Pattern, Stmt, + TypeParam, }; /// Return `true` if the `Stmt` is a compound statement (as opposed to a simple statement). @@ -1073,7 +1077,7 @@ impl Truthiness { Constant::None => Some(false), Constant::Str(ast::StringConstant { value, .. }) => Some(!value.is_empty()), Constant::Bytes(bytes) => Some(!bytes.is_empty()), - Constant::Int(int) => Some(!int.is_zero()), + Constant::Int(int) => Some(*int != 0), Constant::Float(float) => Some(*float != 0.0), Constant::Complex { real, imag } => Some(*real != 0.0 || *imag != 0.0), Constant::Ellipsis => Some(true), @@ -1130,6 +1134,58 @@ impl Truthiness { } } +pub fn generate_comparison( + left: &Expr, + ops: &[CmpOp], + comparators: &[Expr], + parent: AnyNodeRef, + comment_ranges: &CommentRanges, + locator: &Locator, +) -> String { + let start = left.start(); + let end = comparators.last().map_or_else(|| left.end(), Ranged::end); + let mut contents = String::with_capacity(usize::from(end - start)); + + // Add the left side of the comparison. + contents.push_str( + locator.slice( + parenthesized_range(left.into(), parent, comment_ranges, locator.contents()) + .unwrap_or(left.range()), + ), + ); + + for (op, comparator) in ops.iter().zip(comparators) { + // Add the operator. + contents.push_str(match op { + CmpOp::Eq => " == ", + CmpOp::NotEq => " != ", + CmpOp::Lt => " < ", + CmpOp::LtE => " <= ", + CmpOp::Gt => " > ", + CmpOp::GtE => " >= ", + CmpOp::In => " in ", + CmpOp::NotIn => " not in ", + CmpOp::Is => " is ", + CmpOp::IsNot => " is not ", + }); + + // Add the right side of the comparison. + contents.push_str( + locator.slice( + parenthesized_range( + comparator.into(), + parent, + comment_ranges, + locator.contents(), + ) + .unwrap_or(comparator.range()), + ), + ); + } + + contents +} + #[cfg(test)] mod tests { use std::borrow::Cow; @@ -1140,7 +1196,7 @@ mod tests { use crate::helpers::{any_over_stmt, any_over_type_param, resolve_imported_module_path}; use crate::{ - Constant, Expr, ExprConstant, ExprContext, ExprName, Identifier, Stmt, StmtTypeAlias, + Constant, Expr, ExprConstant, ExprContext, ExprName, Identifier, Int, Stmt, StmtTypeAlias, TypeParam, TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple, TypeParams, }; @@ -1240,7 +1296,7 @@ mod tests { assert!(!any_over_type_param(&type_var_no_bound, &|_expr| true)); let bound = Expr::Constant(ExprConstant { - value: Constant::Int(1.into()), + value: Constant::Int(Int::ONE), range: TextRange::default(), }); diff --git a/crates/ruff_python_ast/src/int.rs b/crates/ruff_python_ast/src/int.rs new file mode 100644 index 0000000000000..166ee5562f568 --- /dev/null +++ b/crates/ruff_python_ast/src/int.rs @@ -0,0 +1,235 @@ +use std::fmt::Debug; +use std::str::FromStr; + +/// A Python integer literal. Represents both small (fits in an `i64`) and large integers. +#[derive(Clone, PartialEq, Eq, Hash)] +pub struct Int(Number); + +impl FromStr for Int { + type Err = std::num::ParseIntError; + + /// Parse an [`Int`] from a string. + fn from_str(s: &str) -> Result { + match s.parse::() { + Ok(value) => Ok(Int::small(value)), + Err(err) => { + if matches!( + err.kind(), + std::num::IntErrorKind::PosOverflow | std::num::IntErrorKind::NegOverflow + ) { + Ok(Int::big(s)) + } else { + Err(err) + } + } + } + } +} + +impl Int { + pub const ZERO: Int = Int(Number::Small(0)); + pub const ONE: Int = Int(Number::Small(1)); + + /// Create an [`Int`] to represent a value that can be represented as an `i64`. + fn small(value: i64) -> Self { + Self(Number::Small(value)) + } + + /// Create an [`Int`] to represent a value that cannot be represented as an `i64`. + fn big(value: impl Into>) -> Self { + Self(Number::Big(value.into())) + } + + /// Parse an [`Int`] from a string with a given radix, like `0x95D`. + /// + /// Takes, as input, the numerical portion (`95D`), the parsed base (`16`), and the entire + /// token (`0x95D`). + pub fn from_str_radix( + number: &str, + radix: u32, + token: &str, + ) -> Result { + match i64::from_str_radix(number, radix) { + Ok(value) => Ok(Int::small(value)), + Err(err) => { + if matches!( + err.kind(), + std::num::IntErrorKind::PosOverflow | std::num::IntErrorKind::NegOverflow + ) { + Ok(Int::big(token)) + } else { + Err(err) + } + } + } + } + + /// Return the [`Int`] as an u8, if it can be represented as that data type. + pub fn as_u8(&self) -> Option { + match &self.0 { + Number::Small(small) => u8::try_from(*small).ok(), + Number::Big(_) => None, + } + } + + /// Return the [`Int`] as an u16, if it can be represented as that data type. + pub fn as_u16(&self) -> Option { + match &self.0 { + Number::Small(small) => u16::try_from(*small).ok(), + Number::Big(_) => None, + } + } + + /// Return the [`Int`] as an u32, if it can be represented as that data type. + pub fn as_u32(&self) -> Option { + match &self.0 { + Number::Small(small) => u32::try_from(*small).ok(), + Number::Big(_) => None, + } + } + + /// Return the [`Int`] as an i8, if it can be represented as that data type. + pub fn as_i8(&self) -> Option { + match &self.0 { + Number::Small(small) => i8::try_from(*small).ok(), + Number::Big(_) => None, + } + } + + /// Return the [`Int`] as an i16, if it can be represented as that data type. + pub fn as_i16(&self) -> Option { + match &self.0 { + Number::Small(small) => i16::try_from(*small).ok(), + Number::Big(_) => None, + } + } + + /// Return the [`Int`] as an i32, if it can be represented as that data type. + pub fn as_i32(&self) -> Option { + match &self.0 { + Number::Small(small) => i32::try_from(*small).ok(), + Number::Big(_) => None, + } + } + + /// Return the [`Int`] as an i64, if it can be represented as that data type. + pub const fn as_i64(&self) -> Option { + match &self.0 { + Number::Small(small) => Some(*small), + Number::Big(_) => None, + } + } +} + +impl std::fmt::Display for Int { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl Debug for Int { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self, f) + } +} + +impl PartialEq for Int { + fn eq(&self, other: &u8) -> bool { + self.as_u8() == Some(*other) + } +} + +impl PartialEq for Int { + fn eq(&self, other: &u16) -> bool { + self.as_u16() == Some(*other) + } +} + +impl PartialEq for Int { + fn eq(&self, other: &u32) -> bool { + self.as_u32() == Some(*other) + } +} + +impl PartialEq for Int { + fn eq(&self, other: &i8) -> bool { + self.as_i8() == Some(*other) + } +} + +impl PartialEq for Int { + fn eq(&self, other: &i16) -> bool { + self.as_i16() == Some(*other) + } +} + +impl PartialEq for Int { + fn eq(&self, other: &i32) -> bool { + self.as_i32() == Some(*other) + } +} + +impl PartialEq for Int { + fn eq(&self, other: &i64) -> bool { + self.as_i64() == Some(*other) + } +} + +impl From for Int { + fn from(value: u8) -> Self { + Self::small(i64::from(value)) + } +} + +impl From for Int { + fn from(value: u16) -> Self { + Self::small(i64::from(value)) + } +} + +impl From for Int { + fn from(value: u32) -> Self { + Self::small(i64::from(value)) + } +} + +impl From for Int { + fn from(value: i8) -> Self { + Self::small(i64::from(value)) + } +} + +impl From for Int { + fn from(value: i16) -> Self { + Self::small(i64::from(value)) + } +} + +impl From for Int { + fn from(value: i32) -> Self { + Self::small(i64::from(value)) + } +} + +impl From for Int { + fn from(value: i64) -> Self { + Self::small(value) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +enum Number { + /// A "small" number that can be represented as an `i64`. + Small(i64), + /// A "large" number that cannot be represented as an `i64`. + Big(Box), +} + +impl std::fmt::Display for Number { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Number::Small(value) => write!(f, "{value}"), + Number::Big(value) => write!(f, "{value}"), + } + } +} diff --git a/crates/ruff_python_ast/src/lib.rs b/crates/ruff_python_ast/src/lib.rs index f5e95ef2440c3..210e287eed372 100644 --- a/crates/ruff_python_ast/src/lib.rs +++ b/crates/ruff_python_ast/src/lib.rs @@ -1,6 +1,8 @@ use std::path::Path; pub use expression::*; +pub use int::*; +pub use node::{AnyNode, AnyNodeRef, AstNode, NodeKind}; pub use nodes::*; pub mod all; @@ -12,7 +14,8 @@ pub mod hashable; pub mod helpers; pub mod identifier; pub mod imports; -pub mod node; +mod int; +mod node; mod nodes; pub mod parenthesize; pub mod relocate; @@ -39,13 +42,13 @@ impl Default for SourceType { } } -impl From<&Path> for SourceType { - fn from(path: &Path) -> Self { - match path.file_name() { +impl> From

for SourceType { + fn from(path: P) -> Self { + match path.as_ref().file_name() { Some(filename) if filename == "pyproject.toml" => Self::Toml(TomlSourceType::Pyproject), Some(filename) if filename == "Pipfile" => Self::Toml(TomlSourceType::Pipfile), Some(filename) if filename == "poetry.lock" => Self::Toml(TomlSourceType::Poetry), - _ => match path.extension() { + _ => match path.as_ref().extension() { Some(ext) if ext == "toml" => Self::Toml(TomlSourceType::Unrecognized), _ => Self::Python(PySourceType::from(path)), }, @@ -77,9 +80,9 @@ pub enum PySourceType { Ipynb, } -impl From<&Path> for PySourceType { - fn from(path: &Path) -> Self { - match path.extension() { +impl> From

for PySourceType { + fn from(path: P) -> Self { + match path.as_ref().extension() { Some(ext) if ext == "py" => PySourceType::Python, Some(ext) if ext == "pyi" => PySourceType::Stub, Some(ext) if ext == "ipynb" => PySourceType::Ipynb, diff --git a/crates/ruff_python_ast/src/node.rs b/crates/ruff_python_ast/src/node.rs index 35cfb9147cd81..17725fe0d65ae 100644 --- a/crates/ruff_python_ast/src/node.rs +++ b/crates/ruff_python_ast/src/node.rs @@ -4817,7 +4817,7 @@ pub enum AnyNodeRef<'a> { ElifElseClause(&'a ast::ElifElseClause), } -impl AnyNodeRef<'_> { +impl<'a> AnyNodeRef<'a> { pub fn as_ptr(&self) -> NonNull<()> { match self { AnyNodeRef::ModModule(node) => NonNull::from(*node).cast(), @@ -5456,9 +5456,9 @@ impl AnyNodeRef<'_> { ) } - pub fn visit_preorder<'a, V>(&'a self, visitor: &mut V) + pub fn visit_preorder<'b, V>(&'b self, visitor: &mut V) where - V: PreorderVisitor<'a> + ?Sized, + V: PreorderVisitor<'b> + ?Sized, { match self { AnyNodeRef::ModModule(node) => node.visit_preorder(visitor), @@ -5544,6 +5544,66 @@ impl AnyNodeRef<'_> { AnyNodeRef::ElifElseClause(node) => node.visit_preorder(visitor), } } + + /// The last child of the last branch, if the node has multiple branches. + pub fn last_child_in_body(&self) -> Option> { + let body = match self { + AnyNodeRef::StmtFunctionDef(ast::StmtFunctionDef { body, .. }) + | AnyNodeRef::StmtClassDef(ast::StmtClassDef { body, .. }) + | AnyNodeRef::StmtWith(ast::StmtWith { body, .. }) + | AnyNodeRef::MatchCase(MatchCase { body, .. }) + | AnyNodeRef::ExceptHandlerExceptHandler(ast::ExceptHandlerExceptHandler { + body, + .. + }) + | AnyNodeRef::ElifElseClause(ast::ElifElseClause { body, .. }) => body, + AnyNodeRef::StmtIf(ast::StmtIf { + body, + elif_else_clauses, + .. + }) => elif_else_clauses.last().map_or(body, |clause| &clause.body), + + AnyNodeRef::StmtFor(ast::StmtFor { body, orelse, .. }) + | AnyNodeRef::StmtWhile(ast::StmtWhile { body, orelse, .. }) => { + if orelse.is_empty() { + body + } else { + orelse + } + } + + AnyNodeRef::StmtMatch(ast::StmtMatch { cases, .. }) => { + return cases.last().map(AnyNodeRef::from); + } + + AnyNodeRef::StmtTry(ast::StmtTry { + body, + handlers, + orelse, + finalbody, + .. + }) => { + if finalbody.is_empty() { + if orelse.is_empty() { + if handlers.is_empty() { + body + } else { + return handlers.last().map(AnyNodeRef::from); + } + } else { + orelse + } + } else { + finalbody + } + } + + // Not a node that contains an indented child node. + _ => return None, + }; + + body.last().map(AnyNodeRef::from) + } } impl<'a> From<&'a ast::ModModule> for AnyNodeRef<'a> { diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index ad42a51428d2b..172ba5a93b90f 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -1,12 +1,12 @@ #![allow(clippy::derive_partial_eq_without_eq)] use itertools::Itertools; + use std::fmt; use std::fmt::Debug; use std::ops::Deref; -use num_bigint::BigInt; - +use crate::int; use ruff_text_size::{Ranged, TextRange, TextSize}; /// See also [mod](https://docs.python.org/3/library/ast.html#ast.mod) @@ -2584,7 +2584,7 @@ pub enum Constant { Bool(bool), Str(StringConstant), Bytes(BytesConstant), - Int(BigInt), + Int(int::Int), Float(f64), Complex { real: f64, imag: f64 }, Ellipsis, @@ -2600,6 +2600,14 @@ impl Constant { _ => false, } } + + /// Returns `true` if the constant is a string constant that is a unicode string (i.e., `u"..."`). + pub fn is_unicode_string(&self) -> bool { + match self { + Constant::Str(value) => value.unicode, + _ => false, + } + } } #[derive(Clone, Debug, PartialEq, Eq)] @@ -2620,6 +2628,16 @@ impl Deref for StringConstant { } } +impl From for StringConstant { + fn from(value: String) -> StringConstant { + Self { + value, + unicode: false, + implicit_concatenated: false, + } + } +} + #[derive(Clone, Debug, PartialEq, Eq)] pub struct BytesConstant { /// The bytes value as resolved by the parser (i.e., without quotes, or escape sequences, or @@ -2636,6 +2654,15 @@ impl Deref for BytesConstant { } } +impl From> for BytesConstant { + fn from(value: Vec) -> BytesConstant { + Self { + value, + implicit_concatenated: false, + } + } +} + impl From> for Constant { fn from(value: Vec) -> Constant { Self::Bytes(BytesConstant { @@ -3207,6 +3234,12 @@ pub struct ParenthesizedExpr { /// The underlying expression. pub expr: Expr, } +impl ParenthesizedExpr { + /// Returns `true` if the expression is may be parenthesized. + pub fn is_parenthesized(&self) -> bool { + self.range != self.expr.range() + } +} impl Ranged for ParenthesizedExpr { fn range(&self) -> TextRange { self.range diff --git a/crates/ruff_python_ast/src/parenthesize.rs b/crates/ruff_python_ast/src/parenthesize.rs index 8c6b441a989a4..36ec307d73bfc 100644 --- a/crates/ruff_python_ast/src/parenthesize.rs +++ b/crates/ruff_python_ast/src/parenthesize.rs @@ -1,38 +1,47 @@ use ruff_python_trivia::{BackwardsTokenizer, CommentRanges, SimpleTokenKind, SimpleTokenizer}; use ruff_text_size::{Ranged, TextLen, TextRange}; -use crate::node::AnyNodeRef; +use crate::AnyNodeRef; use crate::ExpressionRef; -/// Returns the [`TextRange`] of a given expression including parentheses, if the expression is -/// parenthesized; or `None`, if the expression is not parenthesized. -pub fn parenthesized_range( - expr: ExpressionRef, - parent: AnyNodeRef, - comment_ranges: &CommentRanges, - source: &str, -) -> Option { - // If the parent is a node that brings its own parentheses, exclude the closing parenthesis - // from our search range. Otherwise, we risk matching on calls, like `func(x)`, for which - // the open and close parentheses are part of the `Arguments` node. - // - // There are a few other nodes that may have their own parentheses, but are fine to exclude: - // - `Parameters`: The parameters to a function definition. Any expressions would represent - // default arguments, and so must be preceded by _at least_ the parameter name. As such, - // we won't mistake any parentheses for the opening and closing parentheses on the - // `Parameters` node itself. - // - `Tuple`: The elements of a tuple. The only risk is a single-element tuple (e.g., `(x,)`), - // which must have a trailing comma anyway. - let exclusive_parent_end = if parent.is_arguments() { - parent.end() - ")".text_len() +/// Returns an iterator over the ranges of the optional parentheses surrounding an expression. +/// +/// E.g. for `((f()))` with `f()` as expression, the iterator returns the ranges (1, 6) and (0, 7). +/// +/// Note that without a parent the range can be inaccurate, e.g. `f(a)` we falsely return a set of +/// parentheses around `a` even if the parentheses actually belong to `f`. That is why you should +/// generally prefer [`parenthesized_range`]. +pub fn parentheses_iterator<'a>( + expr: ExpressionRef<'a>, + parent: Option, + comment_ranges: &'a CommentRanges, + source: &'a str, +) -> impl Iterator + 'a { + let right_tokenizer = if let Some(parent) = parent { + // If the parent is a node that brings its own parentheses, exclude the closing parenthesis + // from our search range. Otherwise, we risk matching on calls, like `func(x)`, for which + // the open and close parentheses are part of the `Arguments` node. + // + // There are a few other nodes that may have their own parentheses, but are fine to exclude: + // - `Parameters`: The parameters to a function definition. Any expressions would represent + // default arguments, and so must be preceded by _at least_ the parameter name. As such, + // we won't mistake any parentheses for the opening and closing parentheses on the + // `Parameters` node itself. + // - `Tuple`: The elements of a tuple. The only risk is a single-element tuple (e.g., `(x,)`), + // which must have a trailing comma anyway. + let exclusive_parent_end = if parent.is_arguments() { + parent.end() - ")".text_len() + } else { + parent.end() + }; + SimpleTokenizer::new(source, TextRange::new(expr.end(), exclusive_parent_end)) } else { - parent.end() + SimpleTokenizer::starts_at(expr.end(), source) }; - let right_tokenizer = - SimpleTokenizer::new(source, TextRange::new(expr.end(), exclusive_parent_end)) - .skip_trivia() - .take_while(|token| token.kind == SimpleTokenKind::RParen); + let right_tokenizer = right_tokenizer + .skip_trivia() + .take_while(|token| token.kind == SimpleTokenKind::RParen); let left_tokenizer = BackwardsTokenizer::up_to(expr.start(), source, comment_ranges) .skip_trivia() @@ -43,6 +52,16 @@ pub fn parenthesized_range( // the `right_tokenizer` is exhausted. right_tokenizer .zip(left_tokenizer) - .last() .map(|(right, left)| TextRange::new(left.start(), right.end())) } + +/// Returns the [`TextRange`] of a given expression including parentheses, if the expression is +/// parenthesized; or `None`, if the expression is not parenthesized. +pub fn parenthesized_range( + expr: ExpressionRef, + parent: AnyNodeRef, + comment_ranges: &CommentRanges, + source: &str, +) -> Option { + parentheses_iterator(expr, Some(parent), comment_ranges, source).last() +} diff --git a/crates/ruff_python_ast/src/visitor/preorder.rs b/crates/ruff_python_ast/src/visitor/preorder.rs index 6a64d1daa3a87..9f69e219ed376 100644 --- a/crates/ruff_python_ast/src/visitor/preorder.rs +++ b/crates/ruff_python_ast/src/visitor/preorder.rs @@ -1,10 +1,10 @@ -use crate::node::{AnyNodeRef, AstNode}; use crate::{ Alias, Arguments, BoolOp, CmpOp, Comprehension, Constant, Decorator, ElifElseClause, ExceptHandler, Expr, Keyword, MatchCase, Mod, Operator, Parameter, ParameterWithDefault, Parameters, Pattern, PatternArguments, PatternKeyword, Stmt, TypeParam, TypeParams, UnaryOp, WithItem, }; +use crate::{AnyNodeRef, AstNode}; /// Visitor that traverses all nodes recursively in pre-order. pub trait PreorderVisitor<'a> { diff --git a/crates/ruff_python_ast/tests/preorder.rs b/crates/ruff_python_ast/tests/preorder.rs index 8c6cba2f30250..0f41fa1e27994 100644 --- a/crates/ruff_python_ast/tests/preorder.rs +++ b/crates/ruff_python_ast/tests/preorder.rs @@ -2,12 +2,12 @@ use std::fmt::{Debug, Write}; use insta::assert_snapshot; -use ruff_python_ast::node::AnyNodeRef; use ruff_python_ast::visitor::preorder::{ walk_alias, walk_comprehension, walk_except_handler, walk_expr, walk_keyword, walk_match_case, walk_module, walk_parameter, walk_parameters, walk_pattern, walk_stmt, walk_type_param, walk_with_item, PreorderVisitor, }; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{ Alias, BoolOp, CmpOp, Comprehension, Constant, ExceptHandler, Expr, Keyword, MatchCase, Mod, Operator, Parameter, Parameters, Pattern, Stmt, TypeParam, UnaryOp, WithItem, @@ -130,7 +130,7 @@ fn function_type_parameters() { fn trace_preorder_visitation(source: &str) -> String { let tokens = lex(source, Mode::Module); - let parsed = parse_tokens(tokens, Mode::Module, "test.py").unwrap(); + let parsed = parse_tokens(tokens, source, Mode::Module, "test.py").unwrap(); let mut visitor = RecordVisitor::default(); visitor.visit_mod(&parsed); diff --git a/crates/ruff_python_ast/tests/visitor.rs b/crates/ruff_python_ast/tests/visitor.rs index b44cf55ce0324..0765f5e7d63b5 100644 --- a/crates/ruff_python_ast/tests/visitor.rs +++ b/crates/ruff_python_ast/tests/visitor.rs @@ -5,12 +5,12 @@ use ruff_python_ast as ast; use ruff_python_parser::lexer::lex; use ruff_python_parser::{parse_tokens, Mode}; -use ruff_python_ast::node::AnyNodeRef; use ruff_python_ast::visitor::{ walk_alias, walk_comprehension, walk_except_handler, walk_expr, walk_keyword, walk_match_case, walk_parameter, walk_parameters, walk_pattern, walk_stmt, walk_type_param, walk_with_item, Visitor, }; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{ Alias, BoolOp, CmpOp, Comprehension, ExceptHandler, Expr, Keyword, MatchCase, Operator, Parameter, Parameters, Pattern, Stmt, TypeParam, UnaryOp, WithItem, @@ -131,7 +131,7 @@ fn function_type_parameters() { fn trace_visitation(source: &str) -> String { let tokens = lex(source, Mode::Module); - let parsed = parse_tokens(tokens, Mode::Module, "test.py").unwrap(); + let parsed = parse_tokens(tokens, source, Mode::Module, "test.py").unwrap(); let mut visitor = RecordVisitor::default(); walk_module(&mut visitor, &parsed); diff --git a/crates/ruff_python_codegen/src/stylist.rs b/crates/ruff_python_codegen/src/stylist.rs index 4e4f92227b812..1c3740bbcef76 100644 --- a/crates/ruff_python_codegen/src/stylist.rs +++ b/crates/ruff_python_codegen/src/stylist.rs @@ -55,6 +55,9 @@ fn detect_quote(tokens: &[LexResult], locator: &Locator) -> Quote { triple_quoted: false, .. } => Some(*range), + // No need to check if it's triple-quoted as f-strings cannot be used + // as docstrings. + Tok::FStringStart => Some(*range), _ => None, }); @@ -275,6 +278,14 @@ class FormFeedIndent: Quote::Single ); + let contents = r#"x = f'1'"#; + let locator = Locator::new(contents); + let tokens: Vec<_> = lex(contents, Mode::Module).collect(); + assert_eq!( + Stylist::from_tokens(&tokens, &locator).quote(), + Quote::Single + ); + let contents = r#"x = "1""#; let locator = Locator::new(contents); let tokens: Vec<_> = lex(contents, Mode::Module).collect(); @@ -283,6 +294,14 @@ class FormFeedIndent: Quote::Double ); + let contents = r#"x = f"1""#; + let locator = Locator::new(contents); + let tokens: Vec<_> = lex(contents, Mode::Module).collect(); + assert_eq!( + Stylist::from_tokens(&tokens, &locator).quote(), + Quote::Double + ); + let contents = r#"s = "It's done.""#; let locator = Locator::new(contents); let tokens: Vec<_> = lex(contents, Mode::Module).collect(); @@ -328,6 +347,41 @@ a = "v" Stylist::from_tokens(&tokens, &locator).quote(), Quote::Double ); + + // Detect from f-string appearing after docstring + let contents = r#" +"""Module docstring.""" + +a = f'v' +"#; + let locator = Locator::new(contents); + let tokens: Vec<_> = lex(contents, Mode::Module).collect(); + assert_eq!( + Stylist::from_tokens(&tokens, &locator).quote(), + Quote::Single + ); + + let contents = r#" +'''Module docstring.''' + +a = f"v" +"#; + let locator = Locator::new(contents); + let tokens: Vec<_> = lex(contents, Mode::Module).collect(); + assert_eq!( + Stylist::from_tokens(&tokens, &locator).quote(), + Quote::Double + ); + + let contents = r#" +f'''Module docstring.''' +"#; + let locator = Locator::new(contents); + let tokens: Vec<_> = lex(contents, Mode::Module).collect(); + assert_eq!( + Stylist::from_tokens(&tokens, &locator).quote(), + Quote::Single + ); } #[test] diff --git a/crates/ruff_python_formatter/Cargo.toml b/crates/ruff_python_formatter/Cargo.toml index 75782a5d25ba8..14e2ed5c846d1 100644 --- a/crates/ruff_python_formatter/Cargo.toml +++ b/crates/ruff_python_formatter/Cargo.toml @@ -38,7 +38,7 @@ tracing = { workspace = true } unicode-width = { workspace = true } [dev-dependencies] -ruff_formatter = { path = "../ruff_formatter", features = ["serde"] } +ruff_formatter = { path = "../ruff_formatter" } insta = { workspace = true, features = ["glob"] } serde = { workspace = true } @@ -52,6 +52,6 @@ test = true required-features = ["serde"] [features] +default = ["serde"] serde = ["dep:serde", "ruff_formatter/serde", "ruff_source_file/serde", "ruff_python_ast/serde"] schemars = ["dep:schemars", "ruff_formatter/schemars"] -default = [] diff --git a/crates/ruff_python_formatter/README.md b/crates/ruff_python_formatter/README.md index 688a784042136..4d52242e08b63 100644 --- a/crates/ruff_python_formatter/README.md +++ b/crates/ruff_python_formatter/README.md @@ -1,14 +1,7 @@ # Ruff Formatter The Ruff formatter is an extremely fast Python code formatter that ships as part of the `ruff` -CLI (as of Ruff v0.0.289). - -The formatter is currently in an **Alpha** state. The Alpha is primarily intended for -experimentation: our focus is on collecting feedback that we can address prior to a production-ready -Beta release later this year. (While we're using the formatter in production on our own projects, -the CLI, configuration options, and code style may change arbitrarily between the Alpha and Beta.) - -[_We'd love to hear your feedback._](https://github.com/astral-sh/ruff/discussions/7310) +CLI. ## Goals @@ -30,7 +23,7 @@ For details, see [Black compatibility](#black-compatibility). ## Getting started -The Ruff formatter shipped in an Alpha state as part of Ruff v0.0.289. +The Ruff formatter is available in Beta as of Ruff v0.1.2. ### CLI @@ -46,41 +39,48 @@ Arguments: [FILES]... List of files or directories to format Options: - --check Avoid writing any formatted files back; instead, exit with a non-zero status code if any files would have been modified, and zero otherwise - --config Path to the `pyproject.toml` or `ruff.toml` file to use for configuration - -h, --help Print help - -File selection: - --respect-gitignore Respect file exclusions via `.gitignore` and other standard ignore files - --force-exclude Enforce exclusions, even for paths passed to Ruff directly on the command-line + --check + Avoid writing any formatted files back; instead, exit with a non-zero status code if any files would have been modified, and zero otherwise + --diff + Avoid writing any formatted files back; instead, exit with a non-zero status code and the difference between the current file and how the formatted file would look like + --config + Path to the `pyproject.toml` or `ruff.toml` file to use for configuration + --target-version + The minimum Python version that should be supported [possible values: py37, py38, py39, py310, py311, py312] + --preview + Enable preview mode; enables unstable formatting. Use `--no-preview` to disable + -h, --help + Print help Miscellaneous: + -n, --no-cache Disable cache reads + --cache-dir Path to the cache directory [env: RUFF_CACHE_DIR=] --isolated Ignore all configuration files --stdin-filename The name of the file when passing it through stdin +File selection: + --respect-gitignore Respect file exclusions via `.gitignore` and other standard ignore files. Use `--no-respect-gitignore` to disable + --exclude List of paths, used to omit files and/or directories from analysis + --force-exclude Enforce exclusions, even for paths passed to Ruff directly on the command-line. Use `--no-force-exclude` to disable + Log levels: -v, --verbose Enable verbose logging -q, --quiet Print diagnostics, but nothing else -s, --silent Disable all logging (but still exit with status code "1" upon detecting diagnostics) ``` -Note: `ruff format` is currently hidden by default and will not be visible when running -`ruff --help`. - Similar to Black, running `ruff format /path/to/file.py` will format the given file or directory in-place, while `ruff format --check /path/to/file.py` will avoid writing any formatted files back, instead exiting with a non-zero status code if any files are not already formatted. ### VS Code -As of `v2023.36.0`, the [Ruff VS Code extension](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff) -ships with support for the Ruff formatter. To enable formatting capabilities, set the -`ruff.enableExperimentalFormatter` setting to `true` in your `settings.json`, and mark the Ruff +As of `v2023.44.0`, the [Ruff VS Code extension](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff) +ships with full support for the Ruff formatter. To enable formatting capabilities, mark the Ruff extension as your default Python formatter: ```json { - "ruff.enableExperimentalFormatter": true, "[python]": { "editor.defaultFormatter": "charliermarsh.ruff" } @@ -92,7 +92,6 @@ on-save by adding `"editor.formatOnSave": true` to your `settings.json`: ```json { - "ruff.enableExperimentalFormatter": true, "[python]": { "editor.defaultFormatter": "charliermarsh.ruff", "editor.formatOnSave": true @@ -102,19 +101,27 @@ on-save by adding `"editor.formatOnSave": true` to your `settings.json`: ### Configuration -The Ruff formatter respects Ruff's [`line-length`](https://docs.astral.sh/ruff/settings/#line-length) -setting, which can be provided via a `pyproject.toml` or `ruff.toml` file, or on the CLI, as in: +The Ruff formatter allows configuration of [indent style](https://docs.astral.sh/ruff/settings/#format-indent-style), +[line ending](https://docs.astral.sh/ruff/settings/#format-line-ending), [quote style](https://docs.astral.sh/ruff/settings/#format-quote-style), +and [magic trailing comma behavior](https://docs.astral.sh/ruff/settings/#format-skip-magic-trailing-comma). +Like the linter, the Ruff formatter reads configuration via `pyproject.toml` or `ruff.toml` files, +as in: -```console -ruff format --line-length 100 /path/to/file.py +```toml +[tool.ruff.format] +# Use tabs instead of 4 space indentation. +indent-style = "tab" + +# Prefer single quotes over double quotes. +quote-style = "single" ``` -In future releases, the Ruff formatter will likely support configuration of: +The Ruff formatter also respects Ruff's [`line-length`](https://docs.astral.sh/ruff/settings/#line-length) +setting, which also can be provided via a `pyproject.toml` or `ruff.toml` file. -- Quote style (single vs. double). -- Line endings (LF vs. CRLF). -- Indentation (tabs vs. spaces). -- Tab width. +```toml +line-length = 80 +``` ### Excluding code from formatting @@ -167,7 +174,7 @@ original intent, at the cost of retaining additional vertical space. This deviation only impacts unformatted code, in that Ruff's output should not deviate for code that has already been formatted by Black. -### Pragma comments are ignored when computing line width +#### Pragma comments are ignored when computing line width Pragma comments (`# type`, `# noqa`, `# pyright`, `# pylint`, etc.) are ignored when computing the width of a line. This prevents Ruff from moving pragma comments around, thereby modifying their meaning and behavior: @@ -200,14 +207,14 @@ on both `first()` and `second()`: ] ``` -### Line width vs. line length +#### Line width vs. line length Ruff uses the Unicode width of a line to determine if a line fits. Black's stable style uses character width, while Black's preview style uses Unicode width for strings ([#3445](https://github.com/psf/black/pull/3445)), and character width for all other tokens. Ruff's behavior is closer to Black's preview style than Black's stable style, although Ruff _also_ uses Unicode width for identifiers and comments. -### Walruses in slice expressions +#### Walruses in slice expressions Black avoids inserting space around `:=` operators within slices. For example, the following adheres to Black stable style: @@ -232,7 +239,7 @@ x[y := 1] This will likely be incorporated into Black's preview style ([#3823](https://github.com/psf/black/pull/3823)). -### `global` and `nonlocal` names are broken across multiple lines by continuations +#### `global` and `nonlocal` names are broken across multiple lines by continuations If a `global` or `nonlocal` statement includes multiple names, and exceeds the configured line width, Ruff will break them across multiple lines using continuations: @@ -250,7 +257,7 @@ global \ analyze_size_model ``` -### Newlines are inserted after all class docstrings +#### Newlines are inserted after all class docstrings Black typically enforces a single newline after a class docstring. However, it does not apply such formatting if the docstring is single-quoted rather than triple-quoted, while Ruff enforces a @@ -280,7 +287,7 @@ class IntFromGeom(GEOSFuncFactory): errcheck = staticmethod(check_minus_one) ``` -### Trailing own-line comments on imports are not moved to the next line +#### Trailing own-line comments on imports are not moved to the next line Black enforces a single empty line between an import and a trailing own-line comment. Ruff leaves such comments in-place: @@ -306,7 +313,7 @@ import os import sys ``` -### Parentheses around awaited collections are not preserved +#### Parentheses around awaited collections are not preserved Black preserves parentheses around awaited collections: @@ -323,3 +330,319 @@ await [1, 2, 3] This is more consistent to the formatting of other awaited expressions: Ruff and Black both remove parentheses around, e.g., `await (1)`, only retaining them when syntactically required, as in, e.g., `await (x := 1)`. + +#### Implicit string concatenations in attribute accesses ([#7052](https://github.com/astral-sh/ruff/issues/7052)) + +Given the following unformatted code: + +```python +print("aaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaa".format(bbbbbbbbbbbbbbbbbb + bbbbbbbbbbbbbbbbbb)) +``` + +Internally, Black's logic will first expand the outermost `print` call: + +```python +print( + "aaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaa".format(bbbbbbbbbbbbbbbbbb + bbbbbbbbbbbbbbbbbb) +) +``` + +Since the argument is _still_ too long, Black will then split on the operator with the highest split +precedence. In this case, Black splits on the implicit string concatenation, to produce the +following Black-formatted code: + +```python +print( + "aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa".format(bbbbbbbbbbbbbbbbbb + bbbbbbbbbbbbbbbbbb) +) +``` + +Ruff gives implicit concatenations a "lower" priority when breaking lines. As a result, Ruff +would instead format the above as: + +```python +print( + "aaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaa".format( + bbbbbbbbbbbbbbbbbb + bbbbbbbbbbbbbbbbbb + ) +) +``` + +In general, Black splits implicit string concatenations over multiple lines more often than Ruff, +even if those concatenations _can_ fit on a single line. Ruff instead avoids splitting such +concatenations unless doing so is necessary to fit within the configured line width. + +#### Own-line comments on expressions don't cause the expression to expand ([#7314](https://github.com/astral-sh/ruff/issues/7314)) + +Given an expression like: + +```python +( + # A comment in the middle + some_example_var and some_example_var not in some_example_var +) +``` + +Black associates the comment with `some_example_var`, thus splitting it over two lines: + +```python +( + # A comment in the middle + some_example_var + and some_example_var not in some_example_var +) +``` + +Ruff will instead associate the comment with the entire boolean expression, thus preserving the +initial formatting: + +```python +( + # A comment in the middle + some_example_var and some_example_var not in some_example_var +) +``` + +#### Tuples are parenthesized when expanded ([#7317](https://github.com/astral-sh/ruff/issues/7317)) + +Ruff tends towards parenthesizing tuples (with a few exceptions), while Black tends to remove tuple +parentheses more often. + +In particular, Ruff will always insert parentheses around tuples that expand over multiple lines: + +```python +# Input +(a, b), (c, d,) + +# Black +(a, b), ( + c, + d, +) + +# Ruff +( + (a, b), + ( + c, + d, + ), +) +``` + +There's one exception here. In `for` loops, both Ruff and Black will avoid inserting unnecessary +parentheses: + +```python +# Input +for a, f(b,) in c: + pass + +# Black +for a, f( + b, +) in c: + pass + +# Ruff +for a, f( + b, +) in c: + pass +``` + +#### Single-element tuples are always parenthesized + +Ruff always inserts parentheses around single-element tuples, while Black will omit them in some +cases: + +```python +# Input +(a, b), + +# Black +(a, b), + +# Ruff +((a, b),) +``` + +Adding parentheses around single-element tuples adds visual distinction and helps avoid "accidental" +tuples created by extraneous trailing commas (see, e.g., [#17181](https://github.com/django/django/pull/17181)). + +#### Trailing commas are inserted when expanding a function definition with a single argument ([#7323](https://github.com/astral-sh/ruff/issues/7323)) + +When a function definition with a single argument is expanded over multiple lines, Black +will add a trailing comma in some cases, depending on whether the argument includes a type +annotation and/or a default value. + +For example, Black will add a trailing comma to the first and second function definitions below, +but not the third: + +```python +def func( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, +) -> None: + ... + + +def func( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=1, +) -> None: + ... + + +def func( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: Argument( + "network_messages.pickle", + help="The path of the pickle file that will contain the network messages", + ) = 1 +) -> None: + ... +``` + +Ruff will instead insert a trailing comma in all such cases for consistency. + +#### Parentheses around call-chain assignment values are not preserved ([#7320](https://github.com/astral-sh/ruff/issues/7320)) + +Given: + +```python +def update_emission_strength(): + ( + get_rgbw_emission_node_tree(self) + .nodes["Emission"] + .inputs["Strength"] + .default_value + ) = (self.emission_strength * 2) +``` + +Black will preserve the parentheses in `(self.emission_strength * 2)`, whereas Ruff will remove +them. + +Both Black and Ruff remove such parentheses in simpler assignments, like: + +```python +# Input +def update_emission_strength(): + value = (self.emission_strength * 2) + +# Black +def update_emission_strength(): + value = self.emission_strength * 2 + +# Ruff +def update_emission_strength(): + value = self.emission_strength * 2 +``` + +#### Call chain calls break differently ([#7051](https://github.com/astral-sh/ruff/issues/7051)) + +Black occasionally breaks call chains differently than Ruff; in particular, Black occasionally +expands the arguments for the last call in the chain, as in: + +```python +# Input +df.drop( + columns=["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"] +).drop_duplicates().rename( + columns={ + "a": "a", + } +).to_csv(path / "aaaaaa.csv", index=False) + +# Black +df.drop( + columns=["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"] +).drop_duplicates().rename( + columns={ + "a": "a", + } +).to_csv( + path / "aaaaaa.csv", index=False +) + +# Ruff +df.drop( + columns=["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"] +).drop_duplicates().rename( + columns={ + "a": "a", + } +).to_csv(path / "aaaaaa.csv", index=False) +``` + +Ruff will only expand the arguments if doing so is necessary to fit within the configured line +width. + +Note that Black does not apply this last-call argument breaking universally. For example, both +Black and Ruff will format the following identically: + +```python +# Input +df.drop( + columns=["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"] +).drop_duplicates(a).rename( + columns={ + "a": "a", + } +).to_csv( + path / "aaaaaa.csv", index=False +).other(a) + +# Black +df.drop(columns=["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]).drop_duplicates(a).rename( + columns={ + "a": "a", + } +).to_csv(path / "aaaaaa.csv", index=False).other(a) + +# Ruff +df.drop(columns=["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]).drop_duplicates(a).rename( + columns={ + "a": "a", + } +).to_csv(path / "aaaaaa.csv", index=False).other(a) +``` + +#### Expressions with (non-pragma) trailing comments are split more often ([#7823](https://github.com/astral-sh/ruff/issues/7823)) + +Both Ruff and Black will break the following expression over multiple lines, since it then allows +the expression to fit within the configured line width: + +```python +# Input +some_long_variable_name = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + +# Black +some_long_variable_name = ( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +) + +# Ruff +some_long_variable_name = ( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +) +``` + +However, if the expression ends in a trailing comment, Black will avoid wrapping the expression +in some cases, while Ruff will wrap as long as it allows the expanded lines to fit within the line +length limit: + +```python +# Input +some_long_variable_name = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # a trailing comment + +# Black +some_long_variable_name = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # a trailing comment + +# Ruff +some_long_variable_name = ( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +) # a trailing comment +``` + +Doing so leads to fewer overlong lines while retaining the comment's intent. As pragma comments +(like `# noqa` and `# type: ignore`) are ignored when computing line width, this behavior only +applies to non-pragma comments. diff --git a/crates/ruff_python_formatter/generate.py b/crates/ruff_python_formatter/generate.py index 14d8befca62e7..52c256dd17767 100755 --- a/crates/ruff_python_formatter/generate.py +++ b/crates/ruff_python_formatter/generate.py @@ -1,6 +1,6 @@ #! /usr/bin/python -"""See Docs.md""" +"""See CONTRIBUTING.md""" # %% diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/force_pyi.py b/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/force_pyi.py index 9c8c40cc96239..edc7495e66308 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/force_pyi.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/force_pyi.py @@ -1,3 +1,4 @@ +# flags: --pyi from typing import Union @bird diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/string_quotes.py b/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/string_quotes.py index 86c68e531abf7..9e6b78b05ba6c 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/string_quotes.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/string_quotes.py @@ -1,4 +1,5 @@ '''''' + '\'' '"' "'" diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/string_quotes.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/string_quotes.py.expect index dce6105acfb8b..641b20c8e4dc6 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/string_quotes.py.expect +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/miscellaneous/string_quotes.py.expect @@ -1,4 +1,5 @@ """""" + "'" '"' "'" diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/raw_docstring.py b/crates/ruff_python_formatter/resources/test/fixtures/black/raw_docstring.py new file mode 100644 index 0000000000000..bfde79202aade --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/raw_docstring.py @@ -0,0 +1,16 @@ +# flags: --preview --skip-string-normalization +class C: + + r"""Raw""" + +def f(): + + r"""Raw""" + +class SingleQuotes: + + + r'''Raw''' + +class UpperCaseR: + R"""Raw""" diff --git a/crates/ruff_python_formatter/resources/test/fixtures/black/raw_docstring.py.expect b/crates/ruff_python_formatter/resources/test/fixtures/black/raw_docstring.py.expect new file mode 100644 index 0000000000000..5be480f7f0e89 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/black/raw_docstring.py.expect @@ -0,0 +1,14 @@ +class C: + r"""Raw""" + + +def f(): + r"""Raw""" + + +class SingleQuotes: + r'''Raw''' + + +class UpperCaseR: + R"""Raw""" diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/binary.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/binary.py index f043808439c88..5d91dc500a930 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/binary.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/binary.py @@ -75,7 +75,7 @@ dddddddddddddddddddd, eeeeeeeeee, ] & aaaaaaaaaaaaaaaaaaaaaaaaaa: - ... + pass if [ aaaaaaaaaaaaa, @@ -84,7 +84,7 @@ dddddddddddddddddddd, eeeeeeeeee, ] & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: - ... + pass # Right only can break if aaaaaaaaaaaaaaaaaaaaaaaaaa & [ @@ -94,7 +94,7 @@ dddddddddddddddddddd, eeeeeeeeee, ]: - ... + pass if aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa & [ aaaaaaaaaaaaa, @@ -103,7 +103,7 @@ dddddddddddddddddddd, eeeeeeeeee, ]: - ... + pass # Left or right can break @@ -114,7 +114,7 @@ dddddddddddddddddddd, eeeeeeeeee, ]: - ... + pass if [ aaaaaaaaaaaaa, @@ -123,7 +123,7 @@ dddddddddddddddddddd, eeeeeeeeee, ] & [2222, 333]: - ... + pass if [ aaaaaaaaaaaaa, @@ -132,7 +132,7 @@ dddddddddddddddddddd, eeeeeeeeee, ] & [fffffffffffffffff, gggggggggggggggggggg, hhhhhhhhhhhhhhhhhhhhh, iiiiiiiiiiiiiiii, jjjjjjjjjjjjj]: - ... + pass if ( # comment @@ -152,7 +152,7 @@ ]: pass - ... + pass # Nesting if (aaaa + b) & [ @@ -162,7 +162,7 @@ iiiiiiiiiiiiiiii, jjjjjjjjjjjjj, ]: - ... + pass if [ fffffffffffffffff, @@ -171,7 +171,7 @@ iiiiiiiiiiiiiiii, jjjjjjjjjjjjj, ] & (a + b): - ... + pass if [ @@ -185,7 +185,7 @@ a + b ): - ... + pass if ( [ @@ -199,7 +199,7 @@ # comment a + b ): - ... + pass # Unstable formatting in https://github.com/realtyem/synapse-unraid/blob/unraid_develop/synapse/handlers/presence.py diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/binary_pow_spacing.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/binary_pow_spacing.py new file mode 100644 index 0000000000000..1f7c1c2542592 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/binary_pow_spacing.py @@ -0,0 +1,10 @@ +# No spacing +5 ** 5 +5.0 ** 5.0 +1e5 ** 2e5 +True ** True +False ** False +None ** None + +# Space +"a" ** "b" diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/boolean_operation.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/boolean_operation.py index 0293ff7da61f2..8a8d2149ce5a9 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/boolean_operation.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/boolean_operation.py @@ -16,7 +16,7 @@ and self._returncode and self._proc.poll() ): - ... + pass if ( aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -26,14 +26,14 @@ and aaaaaaaaaaaaaaaaaaaaaaaaaa and aaaaaaaaaaaaaaaaaaaaaaaaaaaa ): - ... + pass if ( aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaas and aaaaaaaaaaaaaaaaa ): - ... + pass if [2222, 333] and [ @@ -43,7 +43,7 @@ dddddddddddddddddddd, eeeeeeeeee, ]: - ... + pass if [ aaaaaaaaaaaaa, diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/fstring.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/fstring.py index f808f11e9421a..017d243f1f08e 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/fstring.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/fstring.py @@ -57,3 +57,8 @@ ), 2 ) + +# https://github.com/astral-sh/ruff/issues/6841 +x = f'''a{""}b''' +y = f'''c{1}d"""e''' +z = f'''a{""}b''' f'''c{1}d"""e''' diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/list_comp.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/list_comp.py index f2d8757c28a3c..85038eb74e045 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/list_comp.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/list_comp.py @@ -95,3 +95,13 @@ x for (x, y,) in z if head_name ] + +[ + 1 for components in # pylint: disable=undefined-loop-variable + b + # integer 1 may only have decimal 01-09 + c # negative decimal +] + +# Parenthesized targets and iterators. +[x for (x) in y] +[x for x in (y)] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/number.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/number.py new file mode 100644 index 0000000000000..afed916b61aa5 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/number.py @@ -0,0 +1,7 @@ +.1 +1. +1E+1 +1E-1 +1.E+1 +1.0E+1 +1.1E+1 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/slice.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/slice.py index 11642b624bcd1..30e436943ac0a 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/slice.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/slice.py @@ -65,7 +65,7 @@ # Spacing around the colon(s) def a(): - ... + pass e00 = "e"[:] e01 = "e"[:1] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/unary.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/unary.py index e191045bac448..5c8ab8d8b31ab 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/unary.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/unary.py @@ -137,20 +137,20 @@ a: pass -# Regression: https://github.com/astral-sh/ruff/issues/5338 +# Regression test for: https://github.com/astral-sh/ruff/issues/5338 if a and not aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: - ... + pass if ( not # comment a): - ... + pass if ( not # comment a): - ... + pass # Regression test for: https://github.com/astral-sh/ruff/issues/7423 if True: @@ -161,3 +161,35 @@ + "WARNING: Removing listed files. Do you really want to continue. yes/n)? " ): pass + +# Regression test for: https://github.com/astral-sh/ruff/issues/7448 +x = ( + # a + not # b + # c + ( # d + # e + True + ) +) + +# Regression test for: https://github.com/astral-sh/ruff/issues/8090 +if "root" not in ( + long_tree_name_tree.split("/")[0] + for long_tree_name_tree in really_really_long_variable_name +): + msg = "Could not find root. Please try a different forest." + raise ValueError(msg) + +# Regression for https://github.com/astral-sh/ruff/issues/8183 +def foo(): + while ( + not (aaaaaaaaaaaaaaaaaaaaa(bbbbbbbb, ccccccc)) and dddddddddd < eeeeeeeeeeeeeee + ): + pass + +def foo(): + while ( + not (aaaaaaaaaaaaaaaaaaaaa[bbbbbbbb, ccccccc]) and dddddddddd < eeeeeeeeeeeeeee + ): + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/unsplittable.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/unsplittable.py index b5f2c161c867d..415f38fcc3134 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/unsplittable.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/unsplittable.py @@ -51,7 +51,7 @@ for converter in connection.ops.get_db_converters( expression ) + expression.get_db_converters(connection): - ... + pass aaa = ( diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/fmt_on_off/fmt_off_unclosed_deep_nested_trailing_comment.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/fmt_on_off/fmt_off_unclosed_deep_nested_trailing_comment.py new file mode 100644 index 0000000000000..5072697b47331 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/fmt_on_off/fmt_off_unclosed_deep_nested_trailing_comment.py @@ -0,0 +1,8 @@ +# Regression test for https://github.com/astral-sh/ruff/issues/8211 + +# fmt: off +from dataclasses import dataclass + +if True: + if False: + x: int # Optional[int] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/fmt_on_off/fmt_off_unclosed_trailing_comment.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/fmt_on_off/fmt_off_unclosed_trailing_comment.py new file mode 100644 index 0000000000000..44d0bb09f73f8 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/fmt_on_off/fmt_off_unclosed_trailing_comment.py @@ -0,0 +1,8 @@ +# Regression test for https://github.com/astral-sh/ruff/issues/8211 + +# fmt: off +from dataclasses import dataclass + +@dataclass +class A: + x: int # Optional[int] diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/fmt_skip/decorators.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/fmt_skip/decorators.py index 98e3bedc6b94f..051eb28362a88 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/fmt_skip/decorators.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/fmt_skip/decorators.py @@ -17,3 +17,16 @@ class Test: def test(): pass + +# Regression test for https://github.com/astral-sh/ruff/issues/7735 +@decorator1 +@decorator2 +class Foo: # fmt: skip + pass + + +# Regression test for https://github.com/astral-sh/ruff/issues/7735 +@decorator1 +@decorator2 +def foo(): # fmt: skip + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/form_feed.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/form_feed.py new file mode 100644 index 0000000000000..311d12f477910 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/form_feed.py @@ -0,0 +1,6 @@ +# Regression test for: https://github.com/astral-sh/ruff/issues/7624 +if symbol is not None: + request["market"] = market["id"] + # "remaining_volume": "0.0", +else: + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/newlines.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/newlines.py index 0d33408ecbf4d..e684befc4bb3d 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/newlines.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/newlines.py @@ -1,6 +1,7 @@ ### # Blank lines around functions ### +import sys x = 1 @@ -159,3 +160,97 @@ def f(): # comment x = 1 + + +def f(): + if True: + + def double(s): + return s + s + print("below function") + if True: + + class A: + x = 1 + print("below class") + if True: + + def double(s): + return s + s + # + print("below comment function") + if True: + + class A: + x = 1 + # + print("below comment class") + if True: + + def double(s): + return s + s + # + print("below comment function 2") + if True: + + def double(s): + return s + s + # + def outer(): + def inner(): + pass + print("below nested functions") + +if True: + + def double(s): + return s + s +print("below function") +if True: + + class A: + x = 1 +print("below class") +def outer(): + def inner(): + pass +print("below nested functions") + + +class Path: + if sys.version_info >= (3, 11): + def joinpath(self): ... + + # The .open method comes from pathlib.pyi and should be kept in sync. + @overload + def open(self): ... + + + + +def fakehttp(): + + class FakeHTTPConnection: + if mock_close: + def close(self): + pass + FakeHTTPConnection.fakedata = fakedata + + + + + +if True: + if False: + def x(): + def y(): + pass + #comment + print() + + +# NOTE: Please keep this the last block in this file. This tests that we don't insert +# empty line(s) at the end of the file due to nested function +if True: + def nested_trailing_function(): + pass \ No newline at end of file diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/parentheses/expression_parentheses_comments.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/parentheses/expression_parentheses_comments.py new file mode 100644 index 0000000000000..c86279119fd41 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/parentheses/expression_parentheses_comments.py @@ -0,0 +1,113 @@ +list_with_parenthesized_elements1 = [ + # comment leading outer + ( + # comment leading inner + 1 + 2 # comment trailing inner + ) # comment trailing outer +] + +list_with_parenthesized_elements2 = [ + # leading outer + (1 + 2) +] +list_with_parenthesized_elements3 = [ + # leading outer + (1 + 2) # trailing outer +] +list_with_parenthesized_elements4 = [ + # leading outer + (1 + 2), # trailing outer +] +list_with_parenthesized_elements5 = [ + (1), # trailing outer + (2), # trailing outer +] + +nested_parentheses1 = ( + ( + ( + 1 + ) # i + ) # j +) # k +nested_parentheses2 = [ + ( + ( + ( + 1 + ) # i + # i2 + ) # j + # j2 + ) # k + # k2 +] +nested_parentheses3 = ( + ( # a + ( # b + 1 + ) # i + ) # j +) # k +nested_parentheses4 = [ + # a + ( # b + # c + ( # d + # e + ( #f + 1 + ) # i + # i2 + ) # j + # j2 + ) # k + # k2 +] + + +x = ( + # unary comment + not + # in-between comment + ( + # leading inner + "a" + ), + not # in-between comment + ( + # leading inner + "b" + ), + not + ( # in-between comment + # leading inner + "c" + ), + # 1 + not # 2 + ( # 3 + # 4 + "d" + ) +) + +if ( + # unary comment + not + # in-between comment + ( + # leading inner + 1 + ) +): + pass + +# Make sure we keep a inside the parentheses +# https://github.com/astral-sh/ruff/issues/7892 +x = ( + # a + ( # b + 1 + ) +) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assign_breaking.options.json b/crates/ruff_python_formatter/resources/test/fixtures/ruff/preview.options.json similarity index 100% rename from crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assign_breaking.options.json rename to crates/ruff_python_formatter/resources/test/fixtures/ruff/preview.options.json diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assign_breaking.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/preview.py similarity index 62% rename from crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assign_breaking.py rename to crates/ruff_python_formatter/resources/test/fixtures/ruff/preview.py index 6ea46a0efe403..111dc0cf5e63c 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assign_breaking.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/preview.py @@ -1,7 +1,39 @@ -# Below is black stable style -# In preview style, black always breaks the right side first +""" +Black's `Preview.module_docstring_newlines` +""" +first_stmt_after_module_level_docstring = 1 -if True: + +class CachedRepository: + # Black's `Preview.dummy_implementations` + def get_release_info(self): ... + + +def raw_docstring(): + + r"""Black's `Preview.accept_raw_docstrings` + a + b + """ + pass + + +def reference_docstring_newlines(): + + """A regular docstring for comparison + a + b + """ + pass + + +class RemoveNewlineBeforeClassDocstring: + + """Black's `Preview.no_blank_line_before_class_docstring`""" + + +def f(): + """Black's `Preview.prefer_splitting_right_hand_side_of_assignments`""" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ] = cccccccc.ccccccccccccc.cccccccc diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ann_assign.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ann_assign.py index b965199c98260..2e4da78295556 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ann_assign.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ann_assign.py @@ -1,6 +1,21 @@ # Regression test: Don't forget the parentheses in the value when breaking aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int = a + 1 * a +bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = ( + Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb() +) + +bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: ( + Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +)= Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb() + +JSONSerializable: TypeAlias = ( + "str | int | float | bool | None | list | tuple | JSONMapping" +) + +JSONSerializable: str | int | float | bool | None | list | tuple | JSONMapping = {1, 2, 3, 4} + +JSONSerializable: str | int | float | bool | None | list | tuple | JSONMapping = aaaaaaaaaaaaaaaa # Regression test: Don't forget the parentheses in the annotation when breaking class DefaultRunner: diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/class_definition.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/class_definition.py index 296b4a79add90..73b8fe1b12cbc 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/class_definition.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/class_definition.py @@ -1,3 +1,5 @@ +# comment + class Test( Aaaaaaaaaaaaaaaaa, Bbbbbbbbbbbbbbbb, diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/for.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/for.py index 868db10fc6ed7..e134c7e669a74 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/for.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/for.py @@ -15,23 +15,23 @@ pass else: - ... + pass for ( x, y, ) in z: # comment - ... + pass # remove brackets around x,y but keep them around z,w for (x, y) in (z, w): - ... + pass # type comment for x in (): # type: int - ... + pass # Tuple parentheses for iterable. for x in 1, 2, 3: diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/function.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/function.py index a036d614f5eeb..98eb09eefafcb 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/function.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/function.py @@ -384,3 +384,29 @@ def test(): #comment except ImportError: pass + +# https://github.com/astral-sh/ruff/issues/7603 +def default_arg_comments( + a: str = #a + "a", + b: str = + #b + "b", + c: str =( #c + "c" + ), + d: str =( + #d + "d" + ) +): + print(a, b, c, d) + +def default_arg_comments2(# + x: int#= + = # + # + 123# + # +): + print(x) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/if.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/if.py index 553b1db45904c..063ef5fd9605d 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/if.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/if.py @@ -19,12 +19,12 @@ if x == y: if y == z: - ... + pass if a == b: - ... + pass else: # trailing comment - ... + pass # trailing else comment @@ -34,11 +34,11 @@ 2222222222222222222222, 3333333333 ]: - ... + pass else: - ... + pass # Regression test: Don't drop the trailing comment by associating it with the elif # instead of the else. @@ -207,6 +207,31 @@ def f(): else: pass +if True: + if True: + pass + else: + pass + # a + + # b + # c + +else: + pass + +if True: + if True: + pass + else: + pass + + # b + # c + +else: + pass + # Regression test for: https://github.com/astral-sh/ruff/issues/7602 if True: diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/import.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/import.py index 04bb263eaf9c2..656ca27768fdf 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/import.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/import.py @@ -2,6 +2,15 @@ from a import aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa, aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa from a import aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa as dfgsdfgsd, aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa as sdkjflsdjlahlfd +# Continuations. +import foo\ + .bar + +from foo\ + .bar import baz + +import tqdm . tqdm + # At the top-level, force one empty line after an import, but allow up to two empty # lines. import os @@ -65,3 +74,14 @@ def func(): logger = logging.getLogger("FastProject") + +# Regression test for: https://github.com/astral-sh/ruff/issues/7604 +import os +# comment + +# comment + + +# comment +x = 1 + diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/import_from.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/import_from.py index 43376564abd0b..879fe9aeffb03 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/import_from.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/import_from.py @@ -35,3 +35,5 @@ ( # comment bar, ) + +from tqdm . auto import tqdm diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/match.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/match.py index 7b6db24c03314..3d9855a154738 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/match.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/match.py @@ -206,9 +206,9 @@ def foo(): case ( True # trailing ): - ... + pass case False: - ... + pass match foo: @@ -406,39 +406,39 @@ def foo(): case Point2D( # own line ): - ... + pass case ( Point2D # own line () ): - ... + pass case Point2D( # end of line line ): - ... + pass case Point2D( # end of line 0, 0 ): - ... + pass case Point2D(0, 0): - ... + pass case Point2D( ( # end of line # own line 0 ), 0): - ... + pass case Point3D(x=0, y=0, z=000000000000000000000000000000000000000000000000000000000000000000000000000000000): - ... + pass case Bar(0, a=None, b="hello"): - ... + pass case FooBar(# leading # leading @@ -449,7 +449,7 @@ def foo(): # trailing # trailing ): - ... + pass case A( b # b @@ -481,23 +481,100 @@ def foo(): # own line 4 c # trailing 5 ): - ... + pass case ( (a) | # trailing ( b ) ): - ... + pass case (a|b|c): - ... + pass case foo | bar | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh: - ... + pass case ( # end of line a | b # own line ): - ... + pass + + +# Single-element tuples. +match pattern: + case (a,): + pass + + case (a, b): + pass + + case (a, b,): + pass + + case a,: + pass + + case a, b: + pass + + case a, b,: + pass + + case (a, # comment + ): + pass + + case (a, b # comment + ): + pass + + case (a, b, # comment + ): + pass + + case ( # comment + a, + ): + pass + + case ( # comment + a, b + ): + pass + + case ( # comment + a, b, + ): + pass + + case ( + # comment + a,): + pass + + case ( + # comment + a, b): + pass + + case ( + # comment + a, b,): + pass + +# Tuple subject. +match n % 3, n % 5: + case 0, 0: + # n is divisible by both 3 and 5 + print("FizzBuzz") + case 0, _: + # n is divisible by 3, but not 5 + print("Fizz") + case _, 0: + # n is divisible by 5, but not 3 + print("Buzz") + case _: + print(n) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/try.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/try.py index bb61b909a248c..a5cdf3ec9fbdf 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/try.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/try.py @@ -1,72 +1,72 @@ try: - ... + pass except: - ... + pass try: - ... + pass except (KeyError): # should remove brackets and be a single line - ... + pass try: # try - ... + pass # end of body # before except except (Exception, ValueError) as exc: # except line - ... + pass # before except 2 except KeyError as key: # except line 2 - ... + pass # in body 2 # before else else: - ... + pass # before finally finally: - ... + pass # with line breaks try: # try - ... + pass # end of body # before except except (Exception, ValueError) as exc: # except line - ... + pass # before except 2 except KeyError as key: # except line 2 - ... + pass # in body 2 # before else else: - ... + pass # before finally finally: - ... + pass # with line breaks try: - ... + pass except: - ... + pass try: - ... + pass except (Exception, Exception, Exception, Exception, Exception, Exception, Exception) as exc: # splits exception over multiple lines - ... + pass try: - ... + pass except: a = 10 # trailing comment1 b = 11 # trailing comment2 @@ -74,21 +74,21 @@ # try/except*, mostly the same as try try: # try - ... + pass # end of body # before except except* (Exception, ValueError) as exc: # except line - ... + pass # before except 2 except* KeyError as key: # except line 2 - ... + pass # in body 2 # before else else: - ... + pass # before finally finally: - ... + pass # try and try star are statements with body # Minimized from https://github.com/python/cpython/blob/99b00efd5edfd5b26bf9e2a35cbfc96277fdcbb1/Lib/getpass.py#L68-L91 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/type_alias.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/type_alias.py index c50a35a0440e3..8e29cd3730c9c 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/type_alias.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/type_alias.py @@ -81,6 +81,10 @@ D, # trailing comment # leading close bracket comment ] = int # trailing value comment +type type_params_single_comment[ # trailing open bracket comment + A, + B +] = int type type_params_all_kinds[type_var, *type_var_tuple, **param_spec] = int # type variable bounds diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/while.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/while.py index 79c0d09c8c491..a09f26b550733 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/while.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/while.py @@ -15,7 +15,7 @@ pass else: - ... + pass while ( some_condition(unformatted, args) and anotherCondition or aThirdCondition diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/with.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/with.py index 03ab7a0a3b8ff..4dc166009a363 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/with.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/with.py @@ -1,16 +1,16 @@ with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: - ... + pass # trailing with a, a: # after colon - ... + pass # trailing with ( aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, ): - ... + pass # trailing @@ -19,7 +19,7 @@ , # comma b # c ): # colon - ... + pass with ( @@ -30,7 +30,7 @@ , # comma c # c ): # colon - ... # body + pass # body # body trailing own with ( @@ -42,14 +42,14 @@ with (a,): # magic trailing comma - ... + pass with (a): # should remove brackets - ... + pass with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as c: - ... + pass # currently unparsable by black: https://github.com/psf/black/issues/3678 @@ -60,45 +60,41 @@ with ( # leading comment - a) as b: ... + a) as b: pass with ( # leading comment a as b -): ... +): pass with ( a as b # trailing comment -): ... +): pass with ( a as ( # leading comment b ) -): ... +): pass with ( a as ( b # trailing comment ) -): ... - -with (a # trailing same line comment - # trailing own line comment - ) as b: ... +): pass with ( a # trailing same line comment # trailing own line comment as b -): ... +): pass with (a # trailing same line comment # trailing own line comment -) as b: ... +) as b: pass with ( (a @@ -106,7 +102,41 @@ ) as # trailing as same line comment b # trailing b same line comment -): ... +): pass + +with ( + # comment + a +): + pass + +with ( + a # comment +): + pass + +with ( + a + # comment +): + pass + +with ( + # comment + a as b +): + pass + +with ( + a as b # comment +): + pass + +with ( + a as b + # comment +): + pass with ( [ @@ -123,7 +153,7 @@ CtxManager2() as example2, CtxManager2() as example2, ): - ... + pass with [ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", @@ -131,7 +161,7 @@ "cccccccccccccccccccccccccccccccccccccccccc", dddddddddddddddddddddddddddddddd, ] as example1, aaaaaaaaaaaaaaaaaaaaaaaaaa * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb * cccccccccccccccccccccccccccc + ddddddddddddddddd as example2, CtxManager222222222222222() as example2: - ... + pass # Comments on open parentheses with ( # comment @@ -139,7 +169,7 @@ CtxManager2() as example2, CtxManager3() as example3, ): - ... + pass with ( # outer comment ( # inner comment @@ -148,25 +178,25 @@ CtxManager2() as example2, CtxManager3() as example3, ): - ... + pass with ( # outer comment CtxManager() ) as example: - ... + pass with ( # outer comment CtxManager() ) as example, ( # inner comment CtxManager2() ) as example2: - ... + pass with ( # outer comment CtxManager1(), CtxManager2(), ) as example: - ... + pass with ( # outer comment ( # inner comment @@ -174,7 +204,7 @@ ), CtxManager2(), ) as example: - ... + pass # Breaking of with items. with (test # bar @@ -254,3 +284,22 @@ with (foo() as bar, baz() as bop): pass + +if True: + with ( + anyio.CancelScope(shield=True) + if get_running_loop() + else contextlib.nullcontext() + ): + pass + +if True: + with ( + anyio.CancelScope(shield=True) + and B and [aaaaaaaa, bbbbbbbbbbbbb, cccccccccc, dddddddddddd, eeeeeeeeeeeee] + ): + pass + +if True: + with anyio.CancelScope(shield=True) if get_running_loop() else contextlib.nullcontext(): + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/trailing_comments.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/trailing_comments.py index 86c33a0f4ed79..3e7002456cf6f 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/trailing_comments.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/trailing_comments.py @@ -1,5 +1,6 @@ # Pragma reserved width fixtures i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # noqa: This shouldn't break +i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # NoQA: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # type: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # pyright: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # pylint: This shouldn't break @@ -9,6 +10,7 @@ # Pragma fixtures for non-breaking space (lead by NBSP) i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # noqa: This shouldn't break +i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # NoQA: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # type: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # pyright: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # pylint: This shouldn't break diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/trivia.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/trivia.py index fcf6002e3fc7d..f4e54bd66da3f 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/trivia.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/trivia.py @@ -17,7 +17,7 @@ def a(self): c = 30 while a == 10: - ... + print(a) # trailing comment with one line before @@ -26,7 +26,7 @@ def a(self): d = 40 while b == 20: - ... + print(b) # no empty line before e = 50 # one empty line before diff --git a/crates/ruff_python_formatter/src/builders.rs b/crates/ruff_python_formatter/src/builders.rs index fa4e30ea79e1b..581fdc5194a66 100644 --- a/crates/ruff_python_formatter/src/builders.rs +++ b/crates/ruff_python_formatter/src/builders.rs @@ -150,7 +150,7 @@ impl<'fmt, 'ast, 'buf> JoinCommaSeparatedBuilder<'fmt, 'ast, 'buf> { N: Ranged, Separator: Format>, { - self.result = self.result.and_then(|_| { + self.result = self.result.and_then(|()| { if self.entries.is_one_or_more() { write!(self.fmt, [token(","), separator])?; } @@ -190,7 +190,7 @@ impl<'fmt, 'ast, 'buf> JoinCommaSeparatedBuilder<'fmt, 'ast, 'buf> { } pub(crate) fn finish(&mut self) -> FormatResult<()> { - self.result.and_then(|_| { + self.result.and_then(|()| { if let Some(last_end) = self.entries.position() { let magic_trailing_comma = has_magic_trailing_comma( TextRange::new(last_end, self.sequence_end), diff --git a/crates/ruff_python_formatter/src/cli.rs b/crates/ruff_python_formatter/src/cli.rs index 6b79bacdbdf9a..57c73abb6b536 100644 --- a/crates/ruff_python_formatter/src/cli.rs +++ b/crates/ruff_python_formatter/src/cli.rs @@ -2,17 +2,17 @@ use std::path::{Path, PathBuf}; -use anyhow::{bail, Context, Result}; +use anyhow::{format_err, Context, Result}; use clap::{command, Parser, ValueEnum}; use ruff_formatter::SourceCode; -use ruff_python_index::CommentRangesBuilder; -use ruff_python_parser::lexer::lex; -use ruff_python_parser::{parse_tokens, Mode}; +use ruff_python_ast::PySourceType; +use ruff_python_index::tokens_and_ranges; +use ruff_python_parser::{parse_ok_tokens, AsMode}; use ruff_text_size::Ranged; use crate::comments::collect_comments; -use crate::{format_node, PyFormatOptions}; +use crate::{format_module_ast, PreviewMode, PyFormatOptions}; #[derive(ValueEnum, Clone, Debug)] pub enum Emit { @@ -24,6 +24,7 @@ pub enum Emit { #[derive(Parser)] #[command(author, version, about, long_about = None)] +#[allow(clippy::struct_excessive_bools)] // It's only the dev cli anyways pub struct Cli { /// Python files to format. If there are none, stdin will be used. `-` as stdin is not supported pub files: Vec, @@ -34,41 +35,37 @@ pub struct Cli { #[clap(long)] pub check: bool, #[clap(long)] + pub preview: bool, + #[clap(long)] pub print_ir: bool, #[clap(long)] pub print_comments: bool, } -pub fn format_and_debug_print(input: &str, cli: &Cli, source_type: &Path) -> Result { - let mut tokens = Vec::new(); - let mut comment_ranges = CommentRangesBuilder::default(); - - for result in lex(input, Mode::Module) { - let (token, range) = match result { - Ok((token, range)) => (token, range), - Err(err) => bail!("Source contains syntax errors {err:?}"), - }; - - comment_ranges.visit_token(&token, range); - tokens.push(Ok((token, range))); - } - - let comment_ranges = comment_ranges.finish(); +pub fn format_and_debug_print(source: &str, cli: &Cli, source_path: &Path) -> Result { + let source_type = PySourceType::from(source_path); + let (tokens, comment_ranges) = tokens_and_ranges(source, source_type) + .map_err(|err| format_err!("Source contains syntax errors {err:?}"))?; // Parse the AST. - let python_ast = - parse_tokens(tokens, Mode::Module, "").context("Syntax error in input")?; + let module = parse_ok_tokens(tokens, source, source_type.as_mode(), "") + .context("Syntax error in input")?; + + let options = PyFormatOptions::from_extension(source_path).with_preview(if cli.preview { + PreviewMode::Enabled + } else { + PreviewMode::Disabled + }); - let options = PyFormatOptions::from_extension(source_type); - let formatted = format_node(&python_ast, &comment_ranges, input, options) + let source_code = SourceCode::new(source); + let formatted = format_module_ast(&module, &comment_ranges, source, options) .context("Failed to format node")?; if cli.print_ir { - println!("{}", formatted.document().display(SourceCode::new(input))); + println!("{}", formatted.document().display(source_code)); } if cli.print_comments { // Print preceding, following and enclosing nodes - let source_code = SourceCode::new(input); - let decorated_comments = collect_comments(&python_ast, source_code, &comment_ranges); + let decorated_comments = collect_comments(&module, source_code, &comment_ranges); if !decorated_comments.is_empty() { println!("# Comment decoration: Range, Preceding, Following, Enclosing, Comment"); } @@ -86,13 +83,10 @@ pub fn format_and_debug_print(input: &str, cli: &Cli, source_type: &Path) -> Res comment.enclosing_node().kind(), comment.enclosing_node().range() ), - comment.slice().text(SourceCode::new(input)), + comment.slice().text(source_code), ); } - println!( - "{:#?}", - formatted.context().comments().debug(SourceCode::new(input)) - ); + println!("{:#?}", formatted.context().comments().debug(source_code)); } Ok(formatted .print() diff --git a/crates/ruff_python_formatter/src/comments/debug.rs b/crates/ruff_python_formatter/src/comments/debug.rs index 0d9057b85a9c0..6f12bf690c2ee 100644 --- a/crates/ruff_python_formatter/src/comments/debug.rs +++ b/crates/ruff_python_formatter/src/comments/debug.rs @@ -180,7 +180,7 @@ mod tests { use insta::assert_debug_snapshot; use ruff_formatter::SourceCode; - use ruff_python_ast::node::AnyNode; + use ruff_python_ast::AnyNode; use ruff_python_ast::{StmtBreak, StmtContinue}; use ruff_python_trivia::CommentRanges; use ruff_text_size::{TextRange, TextSize}; diff --git a/crates/ruff_python_formatter/src/comments/format.rs b/crates/ruff_python_formatter/src/comments/format.rs index a2dbfd601a16e..a492ef1012373 100644 --- a/crates/ruff_python_formatter/src/comments/format.rs +++ b/crates/ruff_python_formatter/src/comments/format.rs @@ -1,9 +1,11 @@ use std::borrow::Cow; use ruff_formatter::{format_args, write, FormatError, FormatOptions, SourceCode}; -use ruff_python_ast::node::{AnyNodeRef, AstNode}; use ruff_python_ast::PySourceType; -use ruff_python_trivia::{lines_after, lines_before}; +use ruff_python_ast::{AnyNodeRef, AstNode}; +use ruff_python_trivia::{ + is_pragma_comment, lines_after, lines_after_ignoring_trivia, lines_before, +}; use ruff_text_size::{Ranged, TextLen, TextRange}; use crate::comments::{CommentLinePosition, SourceComment}; @@ -96,16 +98,32 @@ impl Format> for FormatLeadingAlternateBranchComments<'_> { write!(f, [leading_comments(self.comments)])?; } else if let Some(last_preceding) = self.last_node { - // The leading comments formatting ensures that it preserves the right amount of lines after - // We need to take care of this ourselves, if there's no leading `else` comment. - let end = if let Some(last_trailing) = - f.context().comments().trailing(last_preceding).last() - { - last_trailing.end() - } else { - last_preceding.end() - }; - write!(f, [empty_lines(lines_after(end, f.context().source()))])?; + // The leading comments formatting ensures that it preserves the right amount of lines + // after We need to take care of this ourselves, if there's no leading `else` comment. + // Since the `last_node` could be a compound node, we need to skip _all_ trivia. + // + // For example, here, when formatting the `if` statement, the `last_node` (the `while`) + // would end at the end of `pass`, but we want to skip _all_ comments: + // ```python + // if True: + // while True: + // pass + // # comment + // + // # comment + // else: + // ... + // ``` + // + // `lines_after_ignoring_trivia` is safe here, as we _know_ that the `else` doesn't + // have any leading comments. + write!( + f, + [empty_lines(lines_after_ignoring_trivia( + last_preceding.end(), + f.context().source() + ))] + )?; } Ok(()) @@ -354,17 +372,8 @@ impl Format> for FormatTrailingEndOfLineComment<'_> { let normalized_comment = normalize_comment(self.comment, source)?; - // Trim the normalized comment to detect excluded pragmas (strips NBSP). - let trimmed = strip_comment_prefix(&normalized_comment)?.trim_start(); - - let is_pragma = if let Some((maybe_pragma, _)) = trimmed.split_once(':') { - matches!(maybe_pragma, "noqa" | "type" | "pyright" | "pylint") - } else { - trimmed.starts_with("noqa") - }; - // Don't reserve width for excluded pragma comments. - let reserved_width = if is_pragma { + let reserved_width = if is_pragma_comment(&normalized_comment) { 0 } else { // Start with 2 because of the two leading spaces. @@ -434,12 +443,15 @@ impl Format> for FormatNormalizedComment<'_> { } } -/// A helper for normalizing comments efficiently. +/// A helper for normalizing comments by: +/// * Trimming any trailing whitespace. +/// * Adding a leading space after the `#`, if necessary. /// -/// * Return as fast as possible without making unnecessary allocations. -/// * Trim any trailing whitespace. -/// * Normalize for a leading '# '. -/// * Retain non-breaking spaces for 'type:' pragmas by leading with '# \u{A0}'. +/// For example: +/// * `#comment` is normalized to `# comment`. +/// * `# comment ` is normalized to `# comment`. +/// * `# comment` is left as-is. +/// * `#!comment` is left as-is. fn normalize_comment<'a>( comment: &'a SourceComment, source: SourceCode<'a>, @@ -455,16 +467,16 @@ fn normalize_comment<'a>( return Ok(Cow::Borrowed("#")); } - // Fast path for correctly formatted comments: - // * Start with a `# '. - // * Have no trailing whitespace. + // Fast path for correctly formatted comments: if the comment starts with a space, or any + // of the allowed characters, then it's included verbatim (apart for trimming any trailing + // whitespace). if content.starts_with([' ', '!', ':', '#', '\'']) { return Ok(Cow::Borrowed(trimmed)); } + // Otherwise, we need to normalize the comment by adding a space after the `#`. if content.starts_with('\u{A0}') { let trimmed = content.trim_start_matches('\u{A0}'); - if trimmed.trim_start().starts_with("type:") { // Black adds a space before the non-breaking space if part of a type pragma. Ok(Cow::Owned(std::format!("# {content}"))) @@ -495,13 +507,12 @@ fn strip_comment_prefix(comment_text: &str) -> FormatResult<&str> { /// /// For example, given: /// ```python -/// def func(): +/// class Class: /// ... /// # comment /// ``` /// /// This builder will insert two empty lines before the comment. -/// ``` pub(crate) fn empty_lines_before_trailing_comments<'a>( f: &PyFormatter, comments: &'a [SourceComment], @@ -543,3 +554,69 @@ impl Format> for FormatEmptyLinesBeforeTrailingComments<'_> Ok(()) } } + +/// Format the empty lines between a node and its leading comments. +/// +/// For example, given: +/// ```python +/// # comment +/// +/// class Class: +/// ... +/// ``` +/// +/// While `leading_comments` will preserve the existing empty line, this builder will insert an +/// additional empty line before the comment. +pub(crate) fn empty_lines_after_leading_comments<'a>( + f: &PyFormatter, + comments: &'a [SourceComment], +) -> FormatEmptyLinesAfterLeadingComments<'a> { + // Black has different rules for stub vs. non-stub and top level vs. indented + let empty_lines = match (f.options().source_type(), f.context().node_level()) { + (PySourceType::Stub, NodeLevel::TopLevel) => 1, + (PySourceType::Stub, _) => 0, + (_, NodeLevel::TopLevel) => 2, + (_, _) => 1, + }; + + FormatEmptyLinesAfterLeadingComments { + comments, + empty_lines, + } +} + +#[derive(Copy, Clone, Debug)] +pub(crate) struct FormatEmptyLinesAfterLeadingComments<'a> { + /// The leading comments of the node. + comments: &'a [SourceComment], + /// The expected number of empty lines after the leading comments. + empty_lines: u32, +} + +impl Format> for FormatEmptyLinesAfterLeadingComments<'_> { + fn fmt(&self, f: &mut Formatter) -> FormatResult<()> { + if let Some(comment) = self + .comments + .iter() + .rev() + .find(|comment| comment.line_position().is_own_line()) + { + let actual = lines_after(comment.end(), f.context().source()).saturating_sub(1); + // If there are no empty lines, keep the comment tight to the node. + if actual == 0 { + return Ok(()); + } + + // If there are more than enough empty lines already, `leading_comments` will + // trim them as necessary. + if actual >= self.empty_lines { + return Ok(()); + } + + for _ in actual..self.empty_lines { + write!(f, [empty_line()])?; + } + } + Ok(()) + } +} diff --git a/crates/ruff_python_formatter/src/comments/mod.rs b/crates/ruff_python_formatter/src/comments/mod.rs index 35beb9244706f..48733c652a90f 100644 --- a/crates/ruff_python_formatter/src/comments/mod.rs +++ b/crates/ruff_python_formatter/src/comments/mod.rs @@ -96,8 +96,8 @@ pub(crate) use format::{ leading_alternate_branch_comments, leading_comments, leading_node_comments, trailing_comments, }; use ruff_formatter::{SourceCode, SourceCodeSlice}; -use ruff_python_ast::node::AnyNodeRef; use ruff_python_ast::visitor::preorder::{PreorderVisitor, TraversalSignal}; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::Mod; use ruff_python_trivia::{CommentRanges, PythonWhitespace}; use ruff_source_file::Locator; @@ -548,10 +548,10 @@ mod tests { use insta::assert_debug_snapshot; use ruff_formatter::SourceCode; - use ruff_python_ast::Mod; - use ruff_python_index::CommentRangesBuilder; - use ruff_python_parser::lexer::lex; - use ruff_python_parser::{parse_tokens, Mode}; + use ruff_python_ast::{Mod, PySourceType}; + use ruff_python_index::tokens_and_ranges; + + use ruff_python_parser::{parse_ok_tokens, AsMode}; use ruff_python_trivia::CommentRanges; use crate::comments::Comments; @@ -563,19 +563,12 @@ mod tests { } impl<'a> CommentsTestCase<'a> { - fn from_code(code: &'a str) -> Self { - let source_code = SourceCode::new(code); - let tokens: Vec<_> = lex(code, Mode::Module).collect(); - - let mut comment_ranges = CommentRangesBuilder::default(); - - for (token, range) in tokens.iter().flatten() { - comment_ranges.visit_token(token, *range); - } - - let comment_ranges = comment_ranges.finish(); - - let parsed = parse_tokens(tokens, Mode::Module, "test.py") + fn from_code(source: &'a str) -> Self { + let source_code = SourceCode::new(source); + let source_type = PySourceType::Python; + let (tokens, comment_ranges) = + tokens_and_ranges(source, source_type).expect("Expect source to be valid Python"); + let parsed = parse_ok_tokens(tokens, source, source_type.as_mode(), "test.py") .expect("Expect source to be valid Python"); CommentsTestCase { diff --git a/crates/ruff_python_formatter/src/comments/node_key.rs b/crates/ruff_python_formatter/src/comments/node_key.rs index eb026ca82d42c..5c38ac10e5f9f 100644 --- a/crates/ruff_python_formatter/src/comments/node_key.rs +++ b/crates/ruff_python_formatter/src/comments/node_key.rs @@ -1,4 +1,4 @@ -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use std::fmt::{Debug, Formatter}; use std::hash::{Hash, Hasher}; @@ -52,7 +52,7 @@ impl<'a> From> for NodeRefEqualityKey<'a> { #[cfg(test)] mod tests { use crate::comments::node_key::NodeRefEqualityKey; - use ruff_python_ast::node::AnyNodeRef; + use ruff_python_ast::AnyNodeRef; use ruff_python_ast::StmtContinue; use ruff_text_size::TextRange; use std::collections::hash_map::DefaultHasher; diff --git a/crates/ruff_python_formatter/src/comments/placement.rs b/crates/ruff_python_formatter/src/comments/placement.rs index bd67a0771a704..acb8b9db00bb2 100644 --- a/crates/ruff_python_formatter/src/comments/placement.rs +++ b/crates/ruff_python_formatter/src/comments/placement.rs @@ -1,7 +1,7 @@ use std::cmp::Ordering; -use ruff_python_ast::node::AnyNodeRef; use ruff_python_ast::whitespace::indentation; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{self as ast, Comprehension, Expr, MatchCase, ModModule, Parameters}; use ruff_python_trivia::{ find_only_token_in_range, indentation_at_offset, BackwardsTokenizer, CommentRanges, @@ -347,9 +347,9 @@ fn handle_end_of_line_comment_around_body<'a>( // ``` // The first earlier branch filters out ambiguities e.g. around try-except-finally. if let Some(preceding) = comment.preceding_node() { - if let Some(last_child) = last_child_in_body(preceding) { + if let Some(last_child) = preceding.last_child_in_body() { let innermost_child = - std::iter::successors(Some(last_child), |parent| last_child_in_body(*parent)) + std::iter::successors(Some(last_child), AnyNodeRef::last_child_in_body) .last() .unwrap_or(last_child); return CommentPlacement::trailing(innermost_child, comment); @@ -670,7 +670,7 @@ fn handle_own_line_comment_after_branch<'a>( preceding: AnyNodeRef<'a>, locator: &Locator, ) -> CommentPlacement<'a> { - let Some(last_child) = last_child_in_body(preceding) else { + let Some(last_child) = preceding.last_child_in_body() else { return CommentPlacement::Default(comment); }; @@ -734,7 +734,7 @@ fn handle_own_line_comment_after_branch<'a>( return CommentPlacement::trailing(last_child_in_parent, comment); } Ordering::Greater => { - if let Some(nested_child) = last_child_in_body(last_child_in_parent) { + if let Some(nested_child) = last_child_in_parent.last_child_in_body() { // The comment belongs to the inner block. parent = Some(last_child_in_parent); last_child_in_parent = nested_child; @@ -1878,8 +1878,7 @@ fn handle_lambda_comment<'a>( CommentPlacement::Default(comment) } -/// Attach trailing end-of-line comments on the operator as dangling comments on the enclosing -/// node. +/// Move comment between a unary op and its operand before the unary op by marking them as trailing. /// /// For example, given: /// ```python @@ -1896,26 +1895,27 @@ fn handle_unary_op_comment<'a>( unary_op: &'a ast::ExprUnaryOp, locator: &Locator, ) -> CommentPlacement<'a> { - if comment.line_position().is_own_line() { - return CommentPlacement::Default(comment); - } - - if comment.start() > unary_op.operand.start() { - return CommentPlacement::Default(comment); - } - - let tokenizer = SimpleTokenizer::new( + let mut tokenizer = SimpleTokenizer::new( locator.contents(), - TextRange::new(comment.start(), unary_op.operand.start()), - ); - if tokenizer - .skip_trivia() - .any(|token| token.kind == SimpleTokenKind::LParen) - { - return CommentPlacement::Default(comment); + TextRange::new(unary_op.start(), unary_op.operand.start()), + ) + .skip_trivia(); + let op_token = tokenizer.next(); + debug_assert!(op_token.is_some_and(|token| matches!( + token.kind, + SimpleTokenKind::Tilde + | SimpleTokenKind::Not + | SimpleTokenKind::Plus + | SimpleTokenKind::Minus + ))); + let up_to = tokenizer + .find(|token| token.kind == SimpleTokenKind::LParen) + .map_or(unary_op.operand.start(), |lparen| lparen.start()); + if comment.end() < up_to { + CommentPlacement::leading(unary_op, comment) + } else { + CommentPlacement::Default(comment) } - - CommentPlacement::dangling(comment.enclosing_node(), comment) } /// Attach an end-of-line comment immediately following an open bracket as a dangling comment on @@ -2083,7 +2083,7 @@ fn handle_comprehension_comment<'a>( CommentPlacement::Default(comment) } else { // after the `for` - CommentPlacement::dangling(comment.enclosing_node(), comment) + CommentPlacement::dangling(comprehension, comment) }; } @@ -2106,7 +2106,7 @@ fn handle_comprehension_comment<'a>( // attach as dangling comments on the target // (to be rendered as leading on the "in") return if is_own_line { - CommentPlacement::dangling(comment.enclosing_node(), comment) + CommentPlacement::dangling(comprehension, comment) } else { // correctly trailing on the target CommentPlacement::Default(comment) @@ -2126,7 +2126,7 @@ fn handle_comprehension_comment<'a>( CommentPlacement::Default(comment) } else { // after the `in` but same line, turn into trailing on the `in` token - CommentPlacement::dangling(&comprehension.iter, comment) + CommentPlacement::dangling(comprehension, comment) }; } @@ -2157,10 +2157,10 @@ fn handle_comprehension_comment<'a>( ); if is_own_line { if last_end < comment.start() && comment.start() < if_token.start() { - return CommentPlacement::dangling(if_node, comment); + return CommentPlacement::dangling(comprehension, comment); } } else if if_token.start() < comment.start() && comment.start() < if_node.start() { - return CommentPlacement::dangling(if_node, comment); + return CommentPlacement::dangling(comprehension, comment); } last_end = if_node.end(); } @@ -2176,65 +2176,6 @@ where right.is_some_and(|right| left.ptr_eq(right.into())) } -/// The last child of the last branch, if the node has multiple branches. -fn last_child_in_body(node: AnyNodeRef) -> Option { - let body = match node { - AnyNodeRef::StmtFunctionDef(ast::StmtFunctionDef { body, .. }) - | AnyNodeRef::StmtClassDef(ast::StmtClassDef { body, .. }) - | AnyNodeRef::StmtWith(ast::StmtWith { body, .. }) - | AnyNodeRef::MatchCase(MatchCase { body, .. }) - | AnyNodeRef::ExceptHandlerExceptHandler(ast::ExceptHandlerExceptHandler { - body, .. - }) - | AnyNodeRef::ElifElseClause(ast::ElifElseClause { body, .. }) => body, - AnyNodeRef::StmtIf(ast::StmtIf { - body, - elif_else_clauses, - .. - }) => elif_else_clauses.last().map_or(body, |clause| &clause.body), - - AnyNodeRef::StmtFor(ast::StmtFor { body, orelse, .. }) - | AnyNodeRef::StmtWhile(ast::StmtWhile { body, orelse, .. }) => { - if orelse.is_empty() { - body - } else { - orelse - } - } - - AnyNodeRef::StmtMatch(ast::StmtMatch { cases, .. }) => { - return cases.last().map(AnyNodeRef::from); - } - - AnyNodeRef::StmtTry(ast::StmtTry { - body, - handlers, - orelse, - finalbody, - .. - }) => { - if finalbody.is_empty() { - if orelse.is_empty() { - if handlers.is_empty() { - body - } else { - return handlers.last().map(AnyNodeRef::from); - } - } else { - orelse - } - } else { - finalbody - } - } - - // Not a node that contains an indented child node. - _ => return None, - }; - - body.last().map(AnyNodeRef::from) -} - /// Returns `true` if `statement` is the first statement in an alternate `body` (e.g. the else of an if statement) fn is_first_statement_in_alternate_body(statement: AnyNodeRef, has_body: AnyNodeRef) -> bool { match has_body { diff --git a/crates/ruff_python_formatter/src/comments/visitor.rs b/crates/ruff_python_formatter/src/comments/visitor.rs index 91819acc391d3..b9788be8d23e4 100644 --- a/crates/ruff_python_formatter/src/comments/visitor.rs +++ b/crates/ruff_python_formatter/src/comments/visitor.rs @@ -2,7 +2,7 @@ use std::fmt::Debug; use std::iter::Peekable; use ruff_formatter::{SourceCode, SourceCodeSlice}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{Mod, Stmt}; // The interface is designed to only export the members relevant for iterating nodes in // pre-order. diff --git a/crates/ruff_python_formatter/src/expression/binary_like.rs b/crates/ruff_python_formatter/src/expression/binary_like.rs index 8e4ab0f93b0fd..cc72f346d0805 100644 --- a/crates/ruff_python_formatter/src/expression/binary_like.rs +++ b/crates/ruff_python_formatter/src/expression/binary_like.rs @@ -506,7 +506,12 @@ const fn is_simple_power_operand(expr: &Expr) -> bool { op: UnaryOp::Not, .. }) => false, Expr::Constant(ExprConstant { - value: Constant::Complex { .. } | Constant::Float(_) | Constant::Int(_), + value: + Constant::Complex { .. } + | Constant::Float(_) + | Constant::Int(_) + | Constant::None + | Constant::Bool(_), .. }) => true, Expr::Name(_) => true, diff --git a/crates/ruff_python_formatter/src/expression/expr_attribute.rs b/crates/ruff_python_formatter/src/expression/expr_attribute.rs index c9cc463beaf9b..5535cebe88878 100644 --- a/crates/ruff_python_formatter/src/expression/expr_attribute.rs +++ b/crates/ruff_python_formatter/src/expression/expr_attribute.rs @@ -1,5 +1,5 @@ use ruff_formatter::{write, FormatRuleWithOptions}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{Constant, Expr, ExprAttribute, ExprConstant}; use ruff_python_trivia::{find_only_token_in_range, SimpleTokenKind}; use ruff_text_size::{Ranged, TextRange}; @@ -38,14 +38,13 @@ impl FormatNodeRule for FormatExprAttribute { let format_inner = format_with(|f: &mut PyFormatter| { let parenthesize_value = - // If the value is an integer, we need to parenthesize it to avoid a syntax error. - matches!( - value.as_ref(), - Expr::Constant(ExprConstant { - value: Constant::Int(_) | Constant::Float(_), - .. - }) - ) || is_expression_parenthesized(value.into(), f.context().comments().ranges(), f.context().source()); + is_base_ten_number_literal(value.as_ref(), f.context().source()) || { + is_expression_parenthesized( + value.into(), + f.context().comments().ranges(), + f.context().source(), + ) + }; if call_chain_layout == CallChainLayout::Fluent { if parenthesize_value { @@ -164,3 +163,23 @@ impl NeedsParentheses for ExprAttribute { } } } + +// Non Hex, octal or binary number literals need parentheses to disambiguate the attribute `.` from +// a decimal point. Floating point numbers don't strictly need parentheses but it reads better (rather than 0.0.test()). +fn is_base_ten_number_literal(expr: &Expr, source: &str) -> bool { + if let Some(ExprConstant { value, range }) = expr.as_constant_expr() { + match value { + Constant::Float(_) => true, + Constant::Int(_) => { + let text = &source[*range]; + !matches!( + text.as_bytes().get(0..2), + Some([b'0', b'x' | b'X' | b'o' | b'O' | b'b' | b'B']) + ) + } + _ => false, + } + } else { + false + } +} diff --git a/crates/ruff_python_formatter/src/expression/expr_await.rs b/crates/ruff_python_formatter/src/expression/expr_await.rs index 91627848befdd..da408023106e6 100644 --- a/crates/ruff_python_formatter/src/expression/expr_await.rs +++ b/crates/ruff_python_formatter/src/expression/expr_await.rs @@ -1,5 +1,5 @@ use ruff_formatter::write; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::ExprAwait; use crate::expression::maybe_parenthesize_expression; diff --git a/crates/ruff_python_formatter/src/expression/expr_bin_op.rs b/crates/ruff_python_formatter/src/expression/expr_bin_op.rs index 5402b3e5f52be..4d5ea27354ae5 100644 --- a/crates/ruff_python_formatter/src/expression/expr_bin_op.rs +++ b/crates/ruff_python_formatter/src/expression/expr_bin_op.rs @@ -1,4 +1,4 @@ -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{Expr, ExprBinOp}; use crate::comments::SourceComment; diff --git a/crates/ruff_python_formatter/src/expression/expr_bool_op.rs b/crates/ruff_python_formatter/src/expression/expr_bool_op.rs index 674cfa933436c..63c0b4e3e0640 100644 --- a/crates/ruff_python_formatter/src/expression/expr_bool_op.rs +++ b/crates/ruff_python_formatter/src/expression/expr_bool_op.rs @@ -1,5 +1,5 @@ use ruff_formatter::{FormatOwnedWithRule, FormatRefWithRule}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{BoolOp, ExprBoolOp}; use crate::expression::binary_like::BinaryLike; diff --git a/crates/ruff_python_formatter/src/expression/expr_call.rs b/crates/ruff_python_formatter/src/expression/expr_call.rs index 842d59062c2d4..47cd6502558e0 100644 --- a/crates/ruff_python_formatter/src/expression/expr_call.rs +++ b/crates/ruff_python_formatter/src/expression/expr_call.rs @@ -1,5 +1,5 @@ use ruff_formatter::FormatRuleWithOptions; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{Expr, ExprCall}; use crate::comments::{dangling_comments, SourceComment}; diff --git a/crates/ruff_python_formatter/src/expression/expr_compare.rs b/crates/ruff_python_formatter/src/expression/expr_compare.rs index e3c75e8891b47..e4f638831cc3e 100644 --- a/crates/ruff_python_formatter/src/expression/expr_compare.rs +++ b/crates/ruff_python_formatter/src/expression/expr_compare.rs @@ -1,5 +1,5 @@ use ruff_formatter::{FormatOwnedWithRule, FormatRefWithRule}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{CmpOp, Expr, ExprCompare}; use crate::comments::SourceComment; @@ -20,10 +20,11 @@ impl FormatNodeRule for FormatExprCompare { fn fmt_dangling_comments( &self, - _dangling_comments: &[SourceComment], + dangling_comments: &[SourceComment], _f: &mut PyFormatter, ) -> FormatResult<()> { // Node can not have dangling comments + debug_assert!(dangling_comments.is_empty()); Ok(()) } } diff --git a/crates/ruff_python_formatter/src/expression/expr_constant.rs b/crates/ruff_python_formatter/src/expression/expr_constant.rs index 580c63d773754..f9dda6c555f62 100644 --- a/crates/ruff_python_formatter/src/expression/expr_constant.rs +++ b/crates/ruff_python_formatter/src/expression/expr_constant.rs @@ -1,5 +1,5 @@ use ruff_formatter::FormatRuleWithOptions; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{Constant, ExprConstant}; use ruff_text_size::{Ranged, TextLen, TextRange}; diff --git a/crates/ruff_python_formatter/src/expression/expr_dict.rs b/crates/ruff_python_formatter/src/expression/expr_dict.rs index 351505fe3ab4c..43ff4830beea2 100644 --- a/crates/ruff_python_formatter/src/expression/expr_dict.rs +++ b/crates/ruff_python_formatter/src/expression/expr_dict.rs @@ -1,5 +1,5 @@ use ruff_formatter::{format_args, write}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{Expr, ExprDict}; use ruff_text_size::{Ranged, TextRange}; diff --git a/crates/ruff_python_formatter/src/expression/expr_dict_comp.rs b/crates/ruff_python_formatter/src/expression/expr_dict_comp.rs index 33c3450af8127..605f6f5d34009 100644 --- a/crates/ruff_python_formatter/src/expression/expr_dict_comp.rs +++ b/crates/ruff_python_formatter/src/expression/expr_dict_comp.rs @@ -1,9 +1,9 @@ use ruff_formatter::write; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::ExprDictComp; use ruff_text_size::Ranged; -use crate::comments::dangling_comments; +use crate::comments::{dangling_comments, SourceComment}; use crate::expression::parentheses::{parenthesized, NeedsParentheses, OptionalParentheses}; use crate::prelude::*; @@ -58,6 +58,15 @@ impl FormatNodeRule for FormatExprDictComp { .with_dangling_comments(open_parenthesis_comments)] ) } + + fn fmt_dangling_comments( + &self, + _dangling_node_comments: &[SourceComment], + _f: &mut PyFormatter, + ) -> FormatResult<()> { + // Handled as part of `fmt_fields` + Ok(()) + } } impl NeedsParentheses for ExprDictComp { diff --git a/crates/ruff_python_formatter/src/expression/expr_f_string.rs b/crates/ruff_python_formatter/src/expression/expr_f_string.rs index fc12c2c5c0fd4..51beb4dbb8f4a 100644 --- a/crates/ruff_python_formatter/src/expression/expr_f_string.rs +++ b/crates/ruff_python_formatter/src/expression/expr_f_string.rs @@ -1,7 +1,8 @@ use memchr::memchr2; +use crate::comments::SourceComment; use ruff_formatter::FormatResult; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::ExprFString; use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses}; @@ -16,6 +17,15 @@ impl FormatNodeRule for FormatExprFString { fn fmt_fields(&self, item: &ExprFString, f: &mut PyFormatter) -> FormatResult<()> { FormatString::new(&AnyString::FString(item)).fmt(f) } + + fn fmt_dangling_comments( + &self, + _dangling_node_comments: &[SourceComment], + _f: &mut PyFormatter, + ) -> FormatResult<()> { + // Handled as part of `fmt_fields` + Ok(()) + } } impl NeedsParentheses for ExprFString { diff --git a/crates/ruff_python_formatter/src/expression/expr_formatted_value.rs b/crates/ruff_python_formatter/src/expression/expr_formatted_value.rs index 5133cb86e5845..a1939891a30a1 100644 --- a/crates/ruff_python_formatter/src/expression/expr_formatted_value.rs +++ b/crates/ruff_python_formatter/src/expression/expr_formatted_value.rs @@ -1,4 +1,4 @@ -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::ExprFormattedValue; use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses}; diff --git a/crates/ruff_python_formatter/src/expression/expr_generator_exp.rs b/crates/ruff_python_formatter/src/expression/expr_generator_exp.rs index 5ac878a1876ac..4d3de0402e907 100644 --- a/crates/ruff_python_formatter/src/expression/expr_generator_exp.rs +++ b/crates/ruff_python_formatter/src/expression/expr_generator_exp.rs @@ -1,5 +1,5 @@ use ruff_formatter::{format_args, write, FormatRuleWithOptions}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::ExprGeneratorExp; use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer}; use ruff_text_size::{Ranged, TextRange}; diff --git a/crates/ruff_python_formatter/src/expression/expr_if_exp.rs b/crates/ruff_python_formatter/src/expression/expr_if_exp.rs index 78853d40d33dc..5244e18d49f6b 100644 --- a/crates/ruff_python_formatter/src/expression/expr_if_exp.rs +++ b/crates/ruff_python_formatter/src/expression/expr_if_exp.rs @@ -1,5 +1,5 @@ use ruff_formatter::{write, FormatRuleWithOptions}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{Expr, ExprIfExp}; use crate::comments::leading_comments; diff --git a/crates/ruff_python_formatter/src/expression/expr_ipy_escape_command.rs b/crates/ruff_python_formatter/src/expression/expr_ipy_escape_command.rs index 7e084055ac7a7..c60fc633927c1 100644 --- a/crates/ruff_python_formatter/src/expression/expr_ipy_escape_command.rs +++ b/crates/ruff_python_formatter/src/expression/expr_ipy_escape_command.rs @@ -1,6 +1,7 @@ use ruff_python_ast::ExprIpyEscapeCommand; use ruff_text_size::Ranged; +use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses}; use crate::prelude::*; #[derive(Default)] @@ -11,3 +12,13 @@ impl FormatNodeRule for FormatExprIpyEscapeCommand { source_text_slice(item.range()).fmt(f) } } + +impl NeedsParentheses for ExprIpyEscapeCommand { + fn needs_parentheses( + &self, + _parent: ruff_python_ast::AnyNodeRef, + _context: &PyFormatContext, + ) -> OptionalParentheses { + OptionalParentheses::Never + } +} diff --git a/crates/ruff_python_formatter/src/expression/expr_lambda.rs b/crates/ruff_python_formatter/src/expression/expr_lambda.rs index 9e1e7f94020d0..f2487fd6a488a 100644 --- a/crates/ruff_python_formatter/src/expression/expr_lambda.rs +++ b/crates/ruff_python_formatter/src/expression/expr_lambda.rs @@ -1,5 +1,5 @@ use ruff_formatter::write; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::ExprLambda; use ruff_text_size::Ranged; diff --git a/crates/ruff_python_formatter/src/expression/expr_list.rs b/crates/ruff_python_formatter/src/expression/expr_list.rs index e7e522a84c2bf..6f5d70e81294e 100644 --- a/crates/ruff_python_formatter/src/expression/expr_list.rs +++ b/crates/ruff_python_formatter/src/expression/expr_list.rs @@ -1,5 +1,5 @@ use ruff_formatter::prelude::format_with; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::ExprList; use ruff_text_size::Ranged; diff --git a/crates/ruff_python_formatter/src/expression/expr_list_comp.rs b/crates/ruff_python_formatter/src/expression/expr_list_comp.rs index 48aa12d0be66c..3b2d709607640 100644 --- a/crates/ruff_python_formatter/src/expression/expr_list_comp.rs +++ b/crates/ruff_python_formatter/src/expression/expr_list_comp.rs @@ -1,5 +1,5 @@ use ruff_formatter::{format_args, write, FormatResult}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::ExprListComp; use crate::comments::SourceComment; diff --git a/crates/ruff_python_formatter/src/expression/expr_name.rs b/crates/ruff_python_formatter/src/expression/expr_name.rs index 244943eacf552..afe165e07acad 100644 --- a/crates/ruff_python_formatter/src/expression/expr_name.rs +++ b/crates/ruff_python_formatter/src/expression/expr_name.rs @@ -1,5 +1,5 @@ use ruff_formatter::{write, FormatContext}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::ExprName; use crate::comments::SourceComment; @@ -26,10 +26,11 @@ impl FormatNodeRule for FormatExprName { fn fmt_dangling_comments( &self, - _dangling_comments: &[SourceComment], + dangling_comments: &[SourceComment], _f: &mut PyFormatter, ) -> FormatResult<()> { // Node cannot have dangling comments + debug_assert!(dangling_comments.is_empty()); Ok(()) } } diff --git a/crates/ruff_python_formatter/src/expression/expr_named_expr.rs b/crates/ruff_python_formatter/src/expression/expr_named_expr.rs index 1b0cd194e8608..3fe831c3a0b9a 100644 --- a/crates/ruff_python_formatter/src/expression/expr_named_expr.rs +++ b/crates/ruff_python_formatter/src/expression/expr_named_expr.rs @@ -1,5 +1,5 @@ use ruff_formatter::{format_args, write}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::ExprNamedExpr; use crate::comments::{dangling_comments, SourceComment}; diff --git a/crates/ruff_python_formatter/src/expression/expr_set.rs b/crates/ruff_python_formatter/src/expression/expr_set.rs index 109227c5d1a4f..db5e25a0540ea 100644 --- a/crates/ruff_python_formatter/src/expression/expr_set.rs +++ b/crates/ruff_python_formatter/src/expression/expr_set.rs @@ -1,4 +1,4 @@ -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::ExprSet; use ruff_text_size::Ranged; diff --git a/crates/ruff_python_formatter/src/expression/expr_set_comp.rs b/crates/ruff_python_formatter/src/expression/expr_set_comp.rs index 6d91be7115059..0a09c60377ae2 100644 --- a/crates/ruff_python_formatter/src/expression/expr_set_comp.rs +++ b/crates/ruff_python_formatter/src/expression/expr_set_comp.rs @@ -1,5 +1,5 @@ use ruff_formatter::{format_args, write, Buffer, FormatResult}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::ExprSetComp; use crate::comments::SourceComment; diff --git a/crates/ruff_python_formatter/src/expression/expr_slice.rs b/crates/ruff_python_formatter/src/expression/expr_slice.rs index c8177e9f8019a..5837a22605aeb 100644 --- a/crates/ruff_python_formatter/src/expression/expr_slice.rs +++ b/crates/ruff_python_formatter/src/expression/expr_slice.rs @@ -1,5 +1,5 @@ use ruff_formatter::{write, FormatError}; -use ruff_python_ast::node::{AnyNodeRef, AstNode}; +use ruff_python_ast::{AnyNodeRef, AstNode}; use ruff_python_ast::{Expr, ExprSlice, ExprUnaryOp, UnaryOp}; use ruff_python_trivia::{SimpleToken, SimpleTokenKind, SimpleTokenizer}; use ruff_text_size::{Ranged, TextRange}; @@ -146,6 +146,15 @@ impl FormatNodeRule for FormatExprSlice { } Ok(()) } + + fn fmt_dangling_comments( + &self, + _dangling_node_comments: &[SourceComment], + _f: &mut PyFormatter, + ) -> FormatResult<()> { + // Handled as part of `fmt_fields` + Ok(()) + } } /// We're in a slice, so we know there's a first colon, but with have to look into the source diff --git a/crates/ruff_python_formatter/src/expression/expr_starred.rs b/crates/ruff_python_formatter/src/expression/expr_starred.rs index da3e5e208caec..16136417f3a12 100644 --- a/crates/ruff_python_formatter/src/expression/expr_starred.rs +++ b/crates/ruff_python_formatter/src/expression/expr_starred.rs @@ -1,5 +1,5 @@ use ruff_formatter::write; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::ExprStarred; use crate::comments::{dangling_comments, SourceComment}; diff --git a/crates/ruff_python_formatter/src/expression/expr_subscript.rs b/crates/ruff_python_formatter/src/expression/expr_subscript.rs index 1397973d1be57..75a7b16f6e3e0 100644 --- a/crates/ruff_python_formatter/src/expression/expr_subscript.rs +++ b/crates/ruff_python_formatter/src/expression/expr_subscript.rs @@ -1,5 +1,5 @@ use ruff_formatter::{write, FormatRuleWithOptions}; -use ruff_python_ast::node::{AnyNodeRef, AstNode}; +use ruff_python_ast::{AnyNodeRef, AstNode}; use ruff_python_ast::{Expr, ExprSubscript}; use crate::comments::SourceComment; diff --git a/crates/ruff_python_formatter/src/expression/expr_tuple.rs b/crates/ruff_python_formatter/src/expression/expr_tuple.rs index abddb2ac35519..65184d7ccbc34 100644 --- a/crates/ruff_python_formatter/src/expression/expr_tuple.rs +++ b/crates/ruff_python_formatter/src/expression/expr_tuple.rs @@ -1,5 +1,5 @@ use ruff_formatter::{format_args, write, FormatRuleWithOptions}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::ExprTuple; use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer}; use ruff_text_size::{Ranged, TextRange}; @@ -224,7 +224,7 @@ impl NeedsParentheses for ExprTuple { /// Return `true` if a tuple is parenthesized in the source code. pub(crate) fn is_tuple_parenthesized(tuple: &ExprTuple, source: &str) -> bool { let Some(elt) = tuple.elts.first() else { - return false; + return true; }; // Count the number of open parentheses between the start of the tuple and the first element. diff --git a/crates/ruff_python_formatter/src/expression/expr_unary_op.rs b/crates/ruff_python_formatter/src/expression/expr_unary_op.rs index 62646e2da8a15..b81b2f7cb65a5 100644 --- a/crates/ruff_python_formatter/src/expression/expr_unary_op.rs +++ b/crates/ruff_python_formatter/src/expression/expr_unary_op.rs @@ -1,10 +1,10 @@ -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::ExprUnaryOp; use ruff_python_ast::UnaryOp; use crate::comments::{trailing_comments, SourceComment}; use crate::expression::parentheses::{ - is_expression_parenthesized, NeedsParentheses, OptionalParentheses, + is_expression_parenthesized, NeedsParentheses, OptionalParentheses, Parentheses, }; use crate::prelude::*; @@ -57,7 +57,14 @@ impl FormatNodeRule for FormatExprUnaryOp { space().fmt(f)?; } - operand.format().fmt(f) + if operand + .as_bin_op_expr() + .is_some_and(|bin_op| bin_op.op.is_pow()) + { + operand.format().with_options(Parentheses::Always).fmt(f) + } else { + operand.format().fmt(f) + } } fn fmt_dangling_comments( diff --git a/crates/ruff_python_formatter/src/expression/expr_yield.rs b/crates/ruff_python_formatter/src/expression/expr_yield.rs index 11765d6184bf0..20e274ec21d92 100644 --- a/crates/ruff_python_formatter/src/expression/expr_yield.rs +++ b/crates/ruff_python_formatter/src/expression/expr_yield.rs @@ -1,5 +1,5 @@ use ruff_formatter::write; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{Expr, ExprYield, ExprYieldFrom}; use ruff_text_size::{Ranged, TextRange}; diff --git a/crates/ruff_python_formatter/src/expression/expr_yield_from.rs b/crates/ruff_python_formatter/src/expression/expr_yield_from.rs index b3194a58a7ab3..d459617f7e2ed 100644 --- a/crates/ruff_python_formatter/src/expression/expr_yield_from.rs +++ b/crates/ruff_python_formatter/src/expression/expr_yield_from.rs @@ -1,4 +1,4 @@ -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::ExprYieldFrom; use crate::expression::expr_yield::AnyExpressionYield; diff --git a/crates/ruff_python_formatter/src/expression/mod.rs b/crates/ruff_python_formatter/src/expression/mod.rs index 6cae0c2973f3c..c7dae45612333 100644 --- a/crates/ruff_python_formatter/src/expression/mod.rs +++ b/crates/ruff_python_formatter/src/expression/mod.rs @@ -1,19 +1,21 @@ use std::cmp::Ordering; - -use itertools::Itertools; +use std::slice; use ruff_formatter::{ write, FormatOwnedWithRule, FormatRefWithRule, FormatRule, FormatRuleWithOptions, }; use ruff_python_ast as ast; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::parenthesize::parentheses_iterator; use ruff_python_ast::visitor::preorder::{walk_expr, PreorderVisitor}; -use ruff_python_ast::{Constant, Expr, ExpressionRef, Operator}; +use ruff_python_ast::{AnyNodeRef, Constant, Expr, ExpressionRef, Operator}; use ruff_python_trivia::CommentRanges; +use ruff_text_size::Ranged; use crate::builders::parenthesize_if_expands; -use crate::comments::leading_comments; +use crate::comments::{leading_comments, trailing_comments, LeadingDanglingTrailingComments}; use crate::context::{NodeLevel, WithNodeLevel}; +use crate::expression::expr_generator_exp::is_generator_parenthesized; +use crate::expression::expr_tuple::is_tuple_parenthesized; use crate::expression::parentheses::{ is_expression_parenthesized, optional_parentheses, parenthesized, NeedsParentheses, OptionalParentheses, Parentheses, Parenthesize, @@ -102,7 +104,6 @@ impl FormatRule> for FormatExpr { Expr::Slice(expr) => expr.format().fmt(f), Expr::IpyEscapeCommand(expr) => expr.format().fmt(f), }); - let parenthesize = match parentheses { Parentheses::Preserve => is_expression_parenthesized( expression.into(), @@ -113,32 +114,13 @@ impl FormatRule> for FormatExpr { // Fluent style means we already have parentheses Parentheses::Never => false, }; - if parenthesize { - // Any comments on the open parenthesis of a `node`. - // - // For example, `# comment` in: - // ```python - // ( # comment - // foo.bar - // ) - // ``` - let comments = f.context().comments().clone(); - let leading = comments.leading(expression); - if let Some((index, open_parenthesis_comment)) = leading - .iter() - .find_position(|comment| comment.line_position().is_end_of_line()) - { - write!( - f, - [ - leading_comments(&leading[..index]), - parenthesized("(", &format_expr, ")") - .with_dangling_comments(std::slice::from_ref(open_parenthesis_comment)) - ] - ) - } else { + let comment = f.context().comments().clone(); + let node_comments = comment.leading_dangling_trailing(expression); + if !node_comments.has_leading() && !node_comments.has_trailing() { parenthesized("(", &format_expr, ")").fmt(f) + } else { + format_with_parentheses_comments(expression, &node_comments, f) } } else { let level = match f.context().node_level() { @@ -155,6 +137,185 @@ impl FormatRule> for FormatExpr { } } +/// The comments below are trailing on the addition, but it's also outside the +/// parentheses +/// ```python +/// x = [ +/// # comment leading +/// (1 + 2) # comment trailing +/// ] +/// ``` +/// as opposed to +/// ```python +/// x = [( +/// # comment leading +/// 1 + 2 # comment trailing +/// )] +/// ``` +/// , where the comments are inside the parentheses. That is also affects list +/// formatting, where we want to avoid moving the comments after the comma inside +/// the parentheses: +/// ```python +/// data = [ +/// ( +/// b"\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00" +/// b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +/// ), # Point (0 0) +/// ] +/// ``` +/// We could mark those comments as trailing in list but it's easier to handle +/// them here too. +/// +/// So given +/// ```python +/// x = [ +/// # comment leading outer +/// ( +/// # comment leading inner +/// 1 + 2 # comment trailing inner +/// ) # comment trailing outer +/// ] +/// ``` +/// we want to keep the inner an outer comments outside the parentheses and the inner ones inside. +/// This is independent of whether they are own line or end-of-line comments, though end-of-line +/// comments can become own line comments when we discard nested parentheses. +/// +/// Style decision: When there are multiple nested parentheses around an expression, we consider the +/// outermost parentheses the relevant ones and discard the others. +fn format_with_parentheses_comments( + expression: &Expr, + node_comments: &LeadingDanglingTrailingComments, + f: &mut PyFormatter, +) -> FormatResult<()> { + // First part: Split the comments + + // TODO(konstin): We don't have the parent, which is a problem: + // ```python + // f( + // # a + // (a) + // ) + // ``` + // gets formatted as + // ```python + // f( + // ( + // # a + // a + // ) + // ) + // ``` + let range_with_parens = parentheses_iterator( + expression.into(), + None, + f.context().comments().ranges(), + f.context().source(), + ) + .last(); + + let (leading_split, trailing_split) = if let Some(range_with_parens) = range_with_parens { + let leading_split = node_comments + .leading + .partition_point(|comment| comment.start() < range_with_parens.start()); + let trailing_split = node_comments + .trailing + .partition_point(|comment| comment.start() < range_with_parens.end()); + (leading_split, trailing_split) + } else { + (0, node_comments.trailing.len()) + }; + + let (leading_outer, leading_inner) = node_comments.leading.split_at(leading_split); + let (trailing_inner, trailing_outer) = node_comments.trailing.split_at(trailing_split); + + // Preserve an opening parentheses comment + // ```python + // a = ( # opening parentheses comment + // # leading inner + // 1 + // ) + // ``` + let (parentheses_comment, leading_inner) = match leading_inner.split_first() { + Some((first, rest)) if first.line_position().is_end_of_line() => { + (slice::from_ref(first), rest) + } + _ => (Default::default(), node_comments.leading), + }; + + // Second Part: Format + + // The code order is a bit strange here, we format: + // * outer leading comment + // * opening parenthesis + // * opening parenthesis comment + // * inner leading comments + // * the expression itself + // * inner trailing comments + // * the closing parenthesis + // * outer trailing comments + + let fmt_fields = format_with(|f| match expression { + Expr::BoolOp(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::NamedExpr(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::BinOp(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::UnaryOp(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::Lambda(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::IfExp(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::Dict(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::Set(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::ListComp(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::SetComp(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::DictComp(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::GeneratorExp(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::Await(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::Yield(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::YieldFrom(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::Compare(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::Call(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::FormattedValue(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::FString(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::Constant(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::Attribute(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::Subscript(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::Starred(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::Name(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::List(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::Tuple(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::Slice(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + Expr::IpyEscapeCommand(expr) => FormatNodeRule::fmt_fields(expr.format().rule(), expr, f), + }); + + leading_comments(leading_outer).fmt(f)?; + + // Custom FormatNodeRule::fmt variant that only formats the inner comments + let format_node_rule_fmt = format_with(|f| { + // No need to handle suppression comments, those are statement only + leading_comments(leading_inner).fmt(f)?; + + let is_source_map_enabled = f.options().source_map_generation().is_enabled(); + + if is_source_map_enabled { + source_position(expression.start()).fmt(f)?; + } + + fmt_fields.fmt(f)?; + + if is_source_map_enabled { + source_position(expression.end()).fmt(f)?; + } + + trailing_comments(trailing_inner).fmt(f) + }); + + // The actual parenthesized formatting + parenthesized("(", &format_node_rule_fmt, ")") + .with_dangling_comments(parentheses_comment) + .fmt(f)?; + trailing_comments(trailing_outer).fmt(f)?; + + Ok(()) +} + /// Wraps an expression in an optional parentheses except if its [`NeedsParentheses::needs_parentheses`] implementation /// indicates that it is okay to omit the parentheses. For example, parentheses can always be omitted for lists, /// because they already bring their own parentheses. @@ -187,7 +348,6 @@ impl Format> for MaybeParenthesizeExpression<'_> { parenthesize, } = self; - let comments = f.context().comments(); let preserve_parentheses = parenthesize.is_optional() && is_expression_parenthesized( (*expression).into(), @@ -195,14 +355,20 @@ impl Format> for MaybeParenthesizeExpression<'_> { f.context().source(), ); - let node_comments = comments.leading_dangling_trailing(*expression); + // If we want to preserve parentheses, short-circuit. + if preserve_parentheses { + return expression.format().with_options(Parentheses::Always).fmt(f); + } - let has_comments = node_comments.has_leading() || node_comments.has_trailing_own_line(); + let node_comments = f + .context() + .comments() + .leading_dangling_trailing(*expression); // If the expression has comments, we always want to preserve the parentheses. This also // ensures that we correctly handle parenthesized comments, and don't need to worry about // them in the implementation below. - if preserve_parentheses || has_comments { + if node_comments.has_leading() || node_comments.has_trailing_own_line() { return expression.format().with_options(Parentheses::Always).fmt(f); } @@ -252,11 +418,9 @@ impl Format> for MaybeParenthesizeExpression<'_> { // The group id is necessary because the nested expressions may reference it. let group_id = f.group_id("optional_parentheses"); let f = &mut WithNodeLevel::new(NodeLevel::Expression(Some(group_id)), f); - ruff_formatter::prelude::best_fit_parenthesize( - &expression.format().with_options(Parentheses::Never), - ) - .with_group_id(Some(group_id)) - .fmt(f) + best_fit_parenthesize(&expression.format().with_options(Parentheses::Never)) + .with_group_id(Some(group_id)) + .fmt(f) } } }, @@ -312,7 +476,7 @@ impl NeedsParentheses for Expr { Expr::List(expr) => expr.needs_parentheses(parent, context), Expr::Tuple(expr) => expr.needs_parentheses(parent, context), Expr::Slice(expr) => expr.needs_parentheses(parent, context), - Expr::IpyEscapeCommand(_) => todo!(), + Expr::IpyEscapeCommand(expr) => expr.needs_parentheses(parent, context), } } } @@ -348,7 +512,7 @@ fn can_omit_optional_parentheses(expr: &Expr, context: &PyFormatContext) -> bool if visitor.max_precedence == OperatorPrecedence::None { true - } else if visitor.pax_precedence_count > 1 { + } else if visitor.max_precedence_count > 1 { false } else if visitor.max_precedence == OperatorPrecedence::Attribute { true @@ -358,30 +522,34 @@ fn can_omit_optional_parentheses(expr: &Expr, context: &PyFormatContext) -> bool } else { fn is_parenthesized(expr: &Expr, context: &PyFormatContext) -> bool { // Don't break subscripts except in parenthesized context. It looks weird. - !matches!(expr, Expr::Subscript(_)) + !expr.is_subscript_expr() && has_parentheses(expr, context).is_some_and(OwnParentheses::is_non_empty) } - // Only use the layout if the first or last expression has parentheses of some sort, and + // Only use the layout if the first expression starts with parentheses + // or the last expression ends with parentheses of some sort, and // those parentheses are non-empty. - let first_parenthesized = visitor - .first - .is_some_and(|first| is_parenthesized(first, context)); - let last_parenthesized = visitor + if visitor .last - .is_some_and(|last| is_parenthesized(last, context)); - - first_parenthesized || last_parenthesized + .is_some_and(|last| is_parenthesized(last, context)) + { + true + } else { + visitor + .first + .expression() + .is_some_and(|first| is_parenthesized(first, context)) + } } } #[derive(Clone, Debug)] struct CanOmitOptionalParenthesesVisitor<'input> { max_precedence: OperatorPrecedence, - pax_precedence_count: u32, + max_precedence_count: u32, any_parenthesized_expressions: bool, last: Option<&'input Expr>, - first: Option<&'input Expr>, + first: First<'input>, context: &'input PyFormatContext<'input>, } @@ -390,10 +558,10 @@ impl<'input> CanOmitOptionalParenthesesVisitor<'input> { Self { context, max_precedence: OperatorPrecedence::None, - pax_precedence_count: 0, + max_precedence_count: 0, any_parenthesized_expressions: false, last: None, - first: None, + first: First::None, } } @@ -404,11 +572,11 @@ impl<'input> CanOmitOptionalParenthesesVisitor<'input> { fn update_max_precedence_with_count(&mut self, precedence: OperatorPrecedence, count: u32) { match self.max_precedence.cmp(&precedence) { Ordering::Less => { - self.pax_precedence_count = count; + self.max_precedence_count = count; self.max_precedence = precedence; } Ordering::Equal => { - self.pax_precedence_count += count; + self.max_precedence_count += count; } Ordering::Greater => {} } @@ -419,7 +587,6 @@ impl<'input> CanOmitOptionalParenthesesVisitor<'input> { match expr { Expr::Dict(_) | Expr::List(_) - | Expr::Tuple(_) | Expr::Set(_) | Expr::ListComp(_) | Expr::SetComp(_) @@ -428,6 +595,21 @@ impl<'input> CanOmitOptionalParenthesesVisitor<'input> { // The values are always parenthesized, don't visit. return; } + + Expr::Tuple(tuple) if is_tuple_parenthesized(tuple, self.context.source()) => { + self.any_parenthesized_expressions = true; + // The values are always parenthesized, don't visit. + return; + } + + Expr::GeneratorExp(generator) + if is_generator_parenthesized(generator, self.context.source()) => + { + self.any_parenthesized_expressions = true; + // The values are always parenthesized, don't visit. + return; + } + // It's impossible for a file smaller or equal to 4GB to contain more than 2^32 comparisons // because each comparison requires a left operand, and `n` `operands` and right sides. #[allow(clippy::cast_possible_truncation)] @@ -492,6 +674,7 @@ impl<'input> CanOmitOptionalParenthesesVisitor<'input> { if op.is_invert() { self.update_max_precedence(OperatorPrecedence::BitwiseInversion); } + self.first.set_if_none(First::Token); } // `[a, b].test.test[300].dot` @@ -528,19 +711,25 @@ impl<'input> CanOmitOptionalParenthesesVisitor<'input> { self.update_max_precedence(OperatorPrecedence::String); } - Expr::NamedExpr(_) - | Expr::GeneratorExp(_) - | Expr::Lambda(_) + // Expressions with sub expressions but a preceding token + // Mark this expression as first expression and not the sub expression. + Expr::Lambda(_) | Expr::Await(_) | Expr::Yield(_) | Expr::YieldFrom(_) + | Expr::Starred(_) => { + self.first.set_if_none(First::Token); + } + + Expr::Tuple(_) + | Expr::NamedExpr(_) + | Expr::GeneratorExp(_) | Expr::FormattedValue(_) | Expr::FString(_) | Expr::Constant(_) - | Expr::Starred(_) | Expr::Name(_) - | Expr::Slice(_) => {} - Expr::IpyEscapeCommand(_) => todo!(), + | Expr::Slice(_) + | Expr::IpyEscapeCommand(_) => {} }; walk_expr(self, expr); @@ -562,8 +751,32 @@ impl<'input> PreorderVisitor<'input> for CanOmitOptionalParenthesesVisitor<'inpu self.visit_subexpression(expr); } - if self.first.is_none() { - self.first = Some(expr); + self.first.set_if_none(First::Expression(expr)); + } +} + +#[derive(Copy, Clone, Debug)] +enum First<'a> { + None, + + /// Expression starts with a non-parentheses token. E.g. `not a` + Token, + + Expression(&'a Expr), +} + +impl<'a> First<'a> { + #[inline] + fn set_if_none(&mut self, first: First<'a>) { + if matches!(self, First::None) { + *self = first; + } + } + + fn expression(self) -> Option<&'a Expr> { + match self { + First::None | First::Token => None, + First::Expression(expr) => Some(expr), } } } @@ -752,10 +965,14 @@ pub(crate) fn has_own_parentheses( Some(OwnParentheses::NonEmpty) } + Expr::GeneratorExp(generator) + if is_generator_parenthesized(generator, context.source()) => + { + Some(OwnParentheses::NonEmpty) + } + // These expressions must contain _some_ child or trivia token in order to be non-empty. - Expr::List(ast::ExprList { elts, .. }) - | Expr::Set(ast::ExprSet { elts, .. }) - | Expr::Tuple(ast::ExprTuple { elts, .. }) => { + Expr::List(ast::ExprList { elts, .. }) | Expr::Set(ast::ExprSet { elts, .. }) => { if !elts.is_empty() || context.comments().has_dangling(AnyNodeRef::from(expr)) { Some(OwnParentheses::NonEmpty) } else { @@ -763,6 +980,14 @@ pub(crate) fn has_own_parentheses( } } + Expr::Tuple(tuple) if is_tuple_parenthesized(tuple, context.source()) => { + if !tuple.elts.is_empty() || context.comments().has_dangling(AnyNodeRef::from(expr)) { + Some(OwnParentheses::NonEmpty) + } else { + Some(OwnParentheses::Empty) + } + } + Expr::Dict(ast::ExprDict { keys, .. }) => { if !keys.is_empty() || context.comments().has_dangling(AnyNodeRef::from(expr)) { Some(OwnParentheses::NonEmpty) diff --git a/crates/ruff_python_formatter/src/expression/number.rs b/crates/ruff_python_formatter/src/expression/number.rs index 130640f48ff1a..7583bfd5cf0a2 100644 --- a/crates/ruff_python_formatter/src/expression/number.rs +++ b/crates/ruff_python_formatter/src/expression/number.rs @@ -142,7 +142,7 @@ fn normalize_floating_number(input: &str) -> Cow { let mut chars = input.char_indices(); - let fraction_ends_with_dot = if let Some((index, '.')) = chars.next() { + let mut prev_char_is_dot = if let Some((index, '.')) = chars.next() { // Add a leading `0` if `input` starts with `.`. output.push('0'); output.push('.'); @@ -155,8 +155,8 @@ fn normalize_floating_number(input: &str) -> Cow { loop { match chars.next() { Some((index, c @ ('e' | 'E'))) => { - if fraction_ends_with_dot { - // Add `0` if fraction part ends with `.`. + if prev_char_is_dot { + // Add `0` if the `e` immediately follows a `.` (e.g., `1.e1`). output.push_str(&input[last_index..index]); output.push('0'); last_index = index; @@ -177,9 +177,12 @@ fn normalize_floating_number(input: &str) -> Cow { break; } - Some(_) => continue, + Some((_index, c)) => { + prev_char_is_dot = c == '.'; + continue; + } None => { - if input.ends_with('.') { + if prev_char_is_dot { // Add `0` if fraction part ends with `.`. output.push_str(&input[last_index..]); output.push('0'); diff --git a/crates/ruff_python_formatter/src/expression/parentheses.rs b/crates/ruff_python_formatter/src/expression/parentheses.rs index 005b3efa052c5..e68a5a473e9a2 100644 --- a/crates/ruff_python_formatter/src/expression/parentheses.rs +++ b/crates/ruff_python_formatter/src/expression/parentheses.rs @@ -1,6 +1,6 @@ use ruff_formatter::prelude::tag::Condition; use ruff_formatter::{format_args, write, Argument, Arguments}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::ExpressionRef; use ruff_python_trivia::CommentRanges; use ruff_python_trivia::{ diff --git a/crates/ruff_python_formatter/src/expression/string.rs b/crates/ruff_python_formatter/src/expression/string.rs index 3bd7bdb12982b..b6f7da74554bb 100644 --- a/crates/ruff_python_formatter/src/expression/string.rs +++ b/crates/ruff_python_formatter/src/expression/string.rs @@ -3,7 +3,7 @@ use std::borrow::Cow; use bitflags::bitflags; use ruff_formatter::{format_args, write, FormatError}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{self as ast, Constant, ExprConstant, ExprFString, ExpressionRef}; use ruff_python_parser::lexer::{lex_starts_at, LexicalError, LexicalErrorType}; use ruff_python_parser::{Mode, Tok}; @@ -48,10 +48,19 @@ impl<'a> AnyString<'a> { match self { Self::Constant(_) => Quoting::CanChange, Self::FString(f_string) => { + let unprefixed = locator + .slice(f_string.range) + .trim_start_matches(|c| c != '"' && c != '\''); + let triple_quoted = + unprefixed.starts_with(r#"""""#) || unprefixed.starts_with(r#"'''"#); if f_string.values.iter().any(|value| match value { Expr::FormattedValue(ast::ExprFormattedValue { range, .. }) => { let string_content = locator.slice(*range); - string_content.contains(['"', '\'']) + if triple_quoted { + string_content.contains(r#"""""#) || string_content.contains("'''") + } else { + string_content.contains(['"', '\'']) + } } _ => false, }) { @@ -139,7 +148,7 @@ impl<'a> FormatString<'a> { impl<'a> Format> for FormatString<'a> { fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> { let locator = f.context().locator(); - match self.layout { + let result = match self.layout { StringLayout::Default => { if self.string.is_implicit_concatenated() { in_parentheses_only_group(&FormatStringContinuation::new(self.string)).fmt(f) @@ -162,8 +171,74 @@ impl<'a> Format> for FormatString<'a> { StringLayout::ImplicitConcatenatedStringInBinaryLike => { FormatStringContinuation::new(self.string).fmt(f) } + }; + // TODO(dhruvmanila): With PEP 701, comments can be inside f-strings. + // This is to mark all of those comments as formatted but we need to + // figure out how to handle them. Note that this needs to be done only + // after the f-string is formatted, so only for all the non-formatted + // comments. + if let AnyString::FString(fstring) = self.string { + let comments = f.context().comments(); + fstring.values.iter().for_each(|value| { + comments.mark_verbatim_node_comments_formatted(value.into()); + }); + } + result + } +} + +/// A builder for the f-string range. +/// +/// For now, this is limited to the outermost f-string and doesn't support +/// nested f-strings. +#[derive(Debug, Default)] +struct FStringRangeBuilder { + start_location: TextSize, + end_location: TextSize, + nesting: u32, +} + +impl FStringRangeBuilder { + fn visit_token(&mut self, token: &Tok, range: TextRange) { + match token { + Tok::FStringStart => { + if self.nesting == 0 { + self.start_location = range.start(); + } + self.nesting += 1; + } + Tok::FStringEnd => { + // We can assume that this will never overflow because we know + // that the program once parsed to a valid AST which means that + // the start and end tokens for f-strings are balanced. + self.nesting -= 1; + if self.nesting == 0 { + self.end_location = range.end(); + } + } + _ => {} } } + + /// Returns `true` if the lexer is currently inside of a f-string. + /// + /// It'll return `false` once the `FStringEnd` token for the outermost + /// f-string is visited. + const fn in_fstring(&self) -> bool { + self.nesting > 0 + } + + /// Returns the complete range of the previously visited f-string. + /// + /// This method should only be called once the lexer is outside of any + /// f-string otherwise it might return an invalid range. + /// + /// It doesn't consume the builder because there can be multiple f-strings + /// throughout the source code. + fn finish(&self) -> TextRange { + debug_assert!(!self.in_fstring()); + TextRange::new(self.start_location, self.end_location) + } } struct FormatStringContinuation<'a> { @@ -195,6 +270,10 @@ impl Format> for FormatStringContinuation<'_> { // because this is a black preview style. let lexer = lex_starts_at(string_content, Mode::Expression, string_range.start()); + // The lexer emits multiple tokens for a single f-string literal. Each token + // will have it's own range but we require the complete range of the f-string. + let mut fstring_range_builder = FStringRangeBuilder::default(); + let mut joiner = f.join_with(in_parentheses_only_soft_line_break_or_space()); for token in lexer { @@ -226,8 +305,31 @@ impl Format> for FormatStringContinuation<'_> { } }; + fstring_range_builder.visit_token(&token, token_range); + + // We need to ignore all the tokens within the f-string as there can + // be `String` tokens inside it as well. For example, + // + // ```python + // f"foo {'bar'} foo" + // # ^^^^^ + // # Ignore any logic for this `String` token + // ``` + // + // Here, we're interested in the complete f-string, not the individual + // tokens inside it. + if fstring_range_builder.in_fstring() { + continue; + } + match token { - Tok::String { .. } => { + Tok::String { .. } | Tok::FStringEnd => { + let token_range = if token.is_f_string_end() { + fstring_range_builder.finish() + } else { + token_range + }; + // ```python // ( // "a" @@ -323,32 +425,36 @@ impl StringPart { self, quoting: Quoting, locator: &'a Locator, - quote_style: QuoteStyle, + configured_style: QuoteStyle, ) -> NormalizedString<'a> { + // Per PEP 8 and PEP 257, always prefer double quotes for docstrings and triple-quoted + // strings. (We assume docstrings are always triple-quoted.) + let preferred_style = if self.quotes.triple { + QuoteStyle::Double + } else { + configured_style + }; + let raw_content = locator.slice(self.content_range); - let preferred_quotes = match quoting { + let quotes = match quoting { Quoting::Preserve => self.quotes, Quoting::CanChange => { if self.prefix.is_raw_string() { - preferred_quotes_raw(raw_content, self.quotes, quote_style) + choose_quotes_raw(raw_content, self.quotes, preferred_style) } else { - preferred_quotes(raw_content, self.quotes, quote_style) + choose_quotes(raw_content, self.quotes, preferred_style) } } }; - let normalized = normalize_string( - locator.slice(self.content_range), - preferred_quotes, - self.prefix.is_raw_string(), - ); + let normalized = normalize_string(locator.slice(self.content_range), quotes, self.prefix); NormalizedString { prefix: self.prefix, content_range: self.content_range, text: normalized, - quotes: preferred_quotes, + quotes, } } } @@ -434,6 +540,10 @@ impl StringPrefix { pub(super) const fn is_raw_string(self) -> bool { self.contains(StringPrefix::RAW) || self.contains(StringPrefix::RAW_UPPER) } + + pub(super) const fn is_fstring(self) -> bool { + self.contains(StringPrefix::F_STRING) + } } impl Format> for StringPrefix { @@ -460,16 +570,17 @@ impl Format> for StringPrefix { } } -/// Detects the preferred quotes for raw string `input`. -/// The configured quote style is preferred unless `input` contains unescaped quotes of the -/// configured style. For example, `r"foo"` is preferred over `r'foo'` if the configured -/// quote style is double quotes. -fn preferred_quotes_raw( +/// Choose the appropriate quote style for a raw string. +/// +/// The preferred quote style is chosen unless the string contains unescaped quotes of the +/// preferred style. For example, `r"foo"` is chosen over `r'foo'` if the preferred quote +/// style is double quotes. +fn choose_quotes_raw( input: &str, quotes: StringQuotes, - configured_style: QuoteStyle, + preferred_style: QuoteStyle, ) -> StringQuotes { - let configured_quote_char = configured_style.as_char(); + let preferred_quote_char = preferred_style.as_char(); let mut chars = input.chars().peekable(); let contains_unescaped_configured_quotes = loop { match chars.next() { @@ -478,7 +589,7 @@ fn preferred_quotes_raw( chars.next(); } // `"` or `'` - Some(c) if c == configured_quote_char => { + Some(c) if c == preferred_quote_char => { if !quotes.triple { break true; } @@ -487,13 +598,13 @@ fn preferred_quotes_raw( // We can't turn `r'''\""'''` into `r"""\"""""`, this would confuse the parser // about where the closing triple quotes start None => break true, - Some(next) if *next == configured_quote_char => { + Some(next) if *next == preferred_quote_char => { // `""` or `''` chars.next(); // We can't turn `r'''""'''` into `r""""""""`, nor can we have // `"""` or `'''` respectively inside the string - if chars.peek().is_none() || chars.peek() == Some(&configured_quote_char) { + if chars.peek().is_none() || chars.peek() == Some(&preferred_quote_char) { break true; } } @@ -510,26 +621,27 @@ fn preferred_quotes_raw( style: if contains_unescaped_configured_quotes { quotes.style } else { - configured_style + preferred_style }, } } -/// Detects the preferred quotes for `input`. -/// * single quoted strings: The preferred quote style is the one that requires less escape sequences. -/// * triple quoted strings: Use double quotes except the string contains a sequence of `"""`. -fn preferred_quotes( - input: &str, - quotes: StringQuotes, - configured_style: QuoteStyle, -) -> StringQuotes { - let preferred_style = if quotes.triple { +/// Choose the appropriate quote style for a string. +/// +/// For single quoted strings, the preferred quote style is used, unless the alternative quote style +/// would require fewer escapes. +/// +/// For triple quoted strings, the preferred quote style is always used, unless the string contains +/// a triplet of the quote character (e.g., if double quotes are preferred, double quotes will be +/// used unless the string contains `"""`). +fn choose_quotes(input: &str, quotes: StringQuotes, preferred_style: QuoteStyle) -> StringQuotes { + let style = if quotes.triple { // True if the string contains a triple quote sequence of the configured quote style. let mut uses_triple_quotes = false; let mut chars = input.chars().peekable(); while let Some(c) = chars.next() { - let configured_quote_char = configured_style.as_char(); + let preferred_quote_char = preferred_style.as_char(); match c { '\\' => { if matches!(chars.peek(), Some('"' | '\\')) { @@ -537,14 +649,14 @@ fn preferred_quotes( } } // `"` or `'` - c if c == configured_quote_char => { + c if c == preferred_quote_char => { match chars.peek().copied() { - Some(c) if c == configured_quote_char => { + Some(c) if c == preferred_quote_char => { // `""` or `''` chars.next(); match chars.peek().copied() { - Some(c) if c == configured_quote_char => { + Some(c) if c == preferred_quote_char => { // `"""` or `'''` chars.next(); uses_triple_quotes = true; @@ -579,7 +691,7 @@ fn preferred_quotes( // Keep the existing quote style. quotes.style } else { - configured_style + preferred_style } } else { let mut single_quotes = 0u32; @@ -599,7 +711,7 @@ fn preferred_quotes( } } - match configured_style { + match preferred_style { QuoteStyle::Single => { if single_quotes > double_quotes { QuoteStyle::Double @@ -619,7 +731,7 @@ fn preferred_quotes( StringQuotes { triple: quotes.triple, - style: preferred_style, + style, } } @@ -668,10 +780,10 @@ impl Format> for StringQuotes { } /// Adds the necessary quote escapes and removes unnecessary escape sequences when quoting `input` -/// with the provided `style`. +/// with the provided [`StringQuotes`] style. /// /// Returns the normalized string and whether it contains new lines. -fn normalize_string(input: &str, quotes: StringQuotes, is_raw: bool) -> Cow { +fn normalize_string(input: &str, quotes: StringQuotes, prefix: StringPrefix) -> Cow { // The normalized string if `input` is not yet normalized. // `output` must remain empty if `input` is already normalized. let mut output = String::new(); @@ -683,14 +795,30 @@ fn normalize_string(input: &str, quotes: StringQuotes, is_raw: bool) -> Cow let preferred_quote = style.as_char(); let opposite_quote = style.invert().as_char(); - let mut chars = input.char_indices(); + let mut chars = input.char_indices().peekable(); + + let is_raw = prefix.is_raw_string(); + let is_fstring = prefix.is_fstring(); + let mut formatted_value_nesting = 0u32; while let Some((index, c)) = chars.next() { + if is_fstring && matches!(c, '{' | '}') { + if chars.peek().copied().is_some_and(|(_, next)| next == c) { + // Skip over the second character of the double braces + chars.next(); + } else if c == '{' { + formatted_value_nesting += 1; + } else { + // Safe to assume that `c == '}'` here because of the matched pattern above + formatted_value_nesting = formatted_value_nesting.saturating_sub(1); + } + continue; + } if c == '\r' { output.push_str(&input[last_index..index]); // Skip over the '\r' character, keep the `\n` - if input.as_bytes().get(index + 1).copied() == Some(b'\n') { + if chars.peek().copied().is_some_and(|(_, next)| next == '\n') { chars.next(); } // Replace the `\r` with a `\n` @@ -701,9 +829,9 @@ fn normalize_string(input: &str, quotes: StringQuotes, is_raw: bool) -> Cow last_index = index + '\r'.len_utf8(); } else if !quotes.triple && !is_raw { if c == '\\' { - if let Some(next) = input.as_bytes().get(index + 1).copied().map(char::from) { + if let Some((_, next)) = chars.peek().copied() { #[allow(clippy::if_same_then_else)] - if next == opposite_quote { + if next == opposite_quote && formatted_value_nesting == 0 { // Remove the escape by ending before the backslash and starting again with the quote chars.next(); output.push_str(&input[last_index..index]); @@ -716,7 +844,7 @@ fn normalize_string(input: &str, quotes: StringQuotes, is_raw: bool) -> Cow chars.next(); } } - } else if c == preferred_quote { + } else if c == preferred_quote && formatted_value_nesting == 0 { // Escape the quote output.push_str(&input[last_index..index]); output.push('\\'); diff --git a/crates/ruff_python_formatter/src/lib.rs b/crates/ruff_python_formatter/src/lib.rs index 5ba8e3dde0278..7697789fe072c 100644 --- a/crates/ruff_python_formatter/src/lib.rs +++ b/crates/ruff_python_formatter/src/lib.rs @@ -3,11 +3,11 @@ use tracing::Level; use ruff_formatter::prelude::*; use ruff_formatter::{format, FormatError, Formatted, PrintError, Printed, SourceCode}; -use ruff_python_ast::node::AstNode; +use ruff_python_ast::AstNode; use ruff_python_ast::Mod; -use ruff_python_index::CommentRangesBuilder; -use ruff_python_parser::lexer::{lex, LexicalError}; -use ruff_python_parser::{parse_tokens, Mode, ParseError}; +use ruff_python_index::tokens_and_ranges; +use ruff_python_parser::lexer::LexicalError; +use ruff_python_parser::{parse_ok_tokens, AsMode, ParseError}; use ruff_python_trivia::CommentRanges; use ruff_source_file::Locator; @@ -60,7 +60,6 @@ where } self.fmt_fields(node, f)?; - self.fmt_dangling_comments(node_comments.dangling, f)?; if is_source_map_enabled { source_position(node.end()).fmt(f)?; @@ -85,6 +84,11 @@ where dangling_node_comments: &[SourceComment], f: &mut PyFormatter, ) -> FormatResult<()> { + debug_assert!( + dangling_node_comments.is_empty(), + "The node has dangling comments that need to be formatted manually. Add the special dangling comments handling to `fmt_fields` and override `fmt_dangling_comments` with an empty implementation that returns `Ok(())`." + ); + dangling_comments(dangling_node_comments).fmt(f) } @@ -121,61 +125,45 @@ impl From for FormatModuleError { } } -#[tracing::instrument(level = Level::TRACE, skip_all)] -pub fn format_module( - contents: &str, +#[tracing::instrument(name = "format", level = Level::TRACE, skip_all)] +pub fn format_module_source( + source: &str, options: PyFormatOptions, ) -> Result { - // Tokenize once - let mut tokens = Vec::new(); - let mut comment_ranges = CommentRangesBuilder::default(); - - for result in lex(contents, Mode::Module) { - let (token, range) = result?; - - comment_ranges.visit_token(&token, range); - tokens.push(Ok((token, range))); - } - - let comment_ranges = comment_ranges.finish(); - - // Parse the AST. - let python_ast = parse_tokens(tokens, Mode::Module, "")?; - - let formatted = format_node(&python_ast, &comment_ranges, contents, options)?; - + let source_type = options.source_type(); + let (tokens, comment_ranges) = tokens_and_ranges(source, source_type)?; + let module = parse_ok_tokens(tokens, source, source_type.as_mode(), "")?; + let formatted = format_module_ast(&module, &comment_ranges, source, options)?; Ok(formatted.print()?) } -pub fn format_node<'a>( - root: &'a Mod, +pub fn format_module_ast<'a>( + module: &'a Mod, comment_ranges: &'a CommentRanges, source: &'a str, options: PyFormatOptions, ) -> FormatResult>> { - let comments = Comments::from_ast(root, SourceCode::new(source), comment_ranges); - + let source_code = SourceCode::new(source); + let comments = Comments::from_ast(module, source_code, comment_ranges); let locator = Locator::new(source); let formatted = format!( PyFormatContext::new(options, locator.contents(), comments), - [root.format()] + [module.format()] )?; formatted .context() .comments() - .assert_all_formatted(SourceCode::new(source)); + .assert_all_formatted(source_code); Ok(formatted) } /// Public function for generating a printable string of the debug comments. -pub fn pretty_comments(root: &Mod, comment_ranges: &CommentRanges, source: &str) -> String { - let comments = Comments::from_ast(root, SourceCode::new(source), comment_ranges); +pub fn pretty_comments(module: &Mod, comment_ranges: &CommentRanges, source: &str) -> String { + let source_code = SourceCode::new(source); + let comments = Comments::from_ast(module, source_code, comment_ranges); - std::format!( - "{comments:#?}", - comments = comments.debug(SourceCode::new(source)) - ) + std::format!("{comments:#?}", comments = comments.debug(source_code)) } #[cfg(test)] @@ -185,11 +173,12 @@ mod tests { use anyhow::Result; use insta::assert_snapshot; - use ruff_python_index::CommentRangesBuilder; - use ruff_python_parser::lexer::lex; - use ruff_python_parser::{parse_tokens, Mode}; + use ruff_python_ast::PySourceType; + use ruff_python_index::tokens_and_ranges; - use crate::{format_module, format_node, PyFormatOptions}; + use ruff_python_parser::{parse_ok_tokens, AsMode}; + + use crate::{format_module_ast, format_module_source, PyFormatOptions}; /// Very basic test intentionally kept very similar to the CLI #[test] @@ -205,7 +194,7 @@ if True: pass # trailing "#; - let actual = format_module(input, PyFormatOptions::default())? + let actual = format_module_source(input, PyFormatOptions::default())? .as_code() .to_string(); assert_eq!(expected, actual); @@ -216,7 +205,7 @@ if True: #[ignore] #[test] fn quick_test() { - let src = r#" + let source = r#" def main() -> None: if True: some_very_long_variable_name_abcdefghijk = Foo() @@ -226,23 +215,14 @@ def main() -> None: ] "#; - // Tokenize once - let mut tokens = Vec::new(); - let mut comment_ranges = CommentRangesBuilder::default(); - - for result in lex(src, Mode::Module) { - let (token, range) = result.unwrap(); - comment_ranges.visit_token(&token, range); - tokens.push(Ok((token, range))); - } - - let comment_ranges = comment_ranges.finish(); + let source_type = PySourceType::Python; + let (tokens, comment_ranges) = tokens_and_ranges(source, source_type).unwrap(); // Parse the AST. let source_path = "code_inline.py"; - let python_ast = parse_tokens(tokens, Mode::Module, source_path).unwrap(); + let module = parse_ok_tokens(tokens, source, source_type.as_mode(), source_path).unwrap(); let options = PyFormatOptions::from_extension(Path::new(source_path)); - let formatted = format_node(&python_ast, &comment_ranges, src, options).unwrap(); + let formatted = format_module_ast(&module, &comment_ranges, source, options).unwrap(); // Uncomment the `dbg` to print the IR. // Use `dbg_write!(f, []) instead of `write!(f, [])` in your formatting code to print some IR diff --git a/crates/ruff_python_formatter/src/main.rs b/crates/ruff_python_formatter/src/main.rs index ba74dd06c3692..248ee5fa54a7b 100644 --- a/crates/ruff_python_formatter/src/main.rs +++ b/crates/ruff_python_formatter/src/main.rs @@ -25,11 +25,11 @@ fn main() -> Result<()> { cli.emit ); } - let input = read_from_stdin()?; + let source = read_from_stdin()?; // It seems reasonable to give this a dummy name - let formatted = format_and_debug_print(&input, &cli, Path::new("stdin.py"))?; + let formatted = format_and_debug_print(&source, &cli, Path::new("stdin.py"))?; if cli.check { - if formatted == input { + if formatted == source { return Ok(()); } bail!("Content not correctly formatted") @@ -37,9 +37,9 @@ fn main() -> Result<()> { stdout().lock().write_all(formatted.as_bytes())?; } else { for file in &cli.files { - let input = fs::read_to_string(file) + let source = fs::read_to_string(file) .with_context(|| format!("Could not read {}: ", file.display()))?; - let formatted = format_and_debug_print(&input, &cli, file)?; + let formatted = format_and_debug_print(&source, &cli, file)?; match cli.emit { Some(Emit::Stdout) => stdout().lock().write_all(formatted.as_bytes())?, None | Some(Emit::Files) => { diff --git a/crates/ruff_python_formatter/src/module/mod_module.rs b/crates/ruff_python_formatter/src/module/mod_module.rs index 304c885d41f01..c42f79a1c1905 100644 --- a/crates/ruff_python_formatter/src/module/mod_module.rs +++ b/crates/ruff_python_formatter/src/module/mod_module.rs @@ -37,10 +37,11 @@ impl FormatNodeRule for FormatModModule { fn fmt_dangling_comments( &self, - _dangling_comments: &[SourceComment], + dangling_comments: &[SourceComment], _f: &mut PyFormatter, ) -> FormatResult<()> { - // Handled as part of `fmt_fields` + // Node can't have dangling comments. + debug_assert!(dangling_comments.is_empty()); Ok(()) } } diff --git a/crates/ruff_python_formatter/src/options.rs b/crates/ruff_python_formatter/src/options.rs index c6eec75310ccf..b39c7b6ff79c6 100644 --- a/crates/ruff_python_formatter/src/options.rs +++ b/crates/ruff_python_formatter/src/options.rs @@ -250,6 +250,10 @@ impl MagicTrailingComma { pub const fn is_respect(self) -> bool { matches!(self, Self::Respect) } + + pub const fn is_ignore(self) -> bool { + matches!(self, Self::Ignore) + } } impl FromStr for MagicTrailingComma { diff --git a/crates/ruff_python_formatter/src/other/alias.rs b/crates/ruff_python_formatter/src/other/alias.rs index 0020c872cc454..f8532d22d4b20 100644 --- a/crates/ruff_python_formatter/src/other/alias.rs +++ b/crates/ruff_python_formatter/src/other/alias.rs @@ -1,6 +1,7 @@ use ruff_formatter::write; use ruff_python_ast::Alias; +use crate::other::identifier::DotDelimitedIdentifier; use crate::prelude::*; #[derive(Default)] @@ -13,7 +14,7 @@ impl FormatNodeRule for FormatAlias { name, asname, } = item; - name.format().fmt(f)?; + DotDelimitedIdentifier::new(name).fmt(f)?; if let Some(asname) = asname { write!(f, [space(), token("as"), space(), asname.format()])?; } diff --git a/crates/ruff_python_formatter/src/other/comprehension.rs b/crates/ruff_python_formatter/src/other/comprehension.rs index 788e782ab7a6f..423c4f1348fd2 100644 --- a/crates/ruff_python_formatter/src/other/comprehension.rs +++ b/crates/ruff_python_formatter/src/other/comprehension.rs @@ -1,6 +1,7 @@ use ruff_formatter::{format_args, write, Buffer, FormatResult}; use ruff_python_ast::{Comprehension, Expr}; -use ruff_text_size::Ranged; +use ruff_python_trivia::{find_only_token_in_range, SimpleTokenKind}; +use ruff_text_size::{Ranged, TextRange}; use crate::comments::{leading_comments, trailing_comments, SourceComment}; use crate::expression::expr_tuple::TupleParentheses; @@ -37,11 +38,22 @@ impl FormatNodeRule for FormatComprehension { let comments = f.context().comments().clone(); let dangling_item_comments = comments.dangling(item); - let (before_target_comments, before_in_comments) = dangling_item_comments.split_at( + let (before_target_comments, dangling_comments) = dangling_item_comments.split_at( dangling_item_comments.partition_point(|comment| comment.end() < target.start()), ); - let trailing_in_comments = comments.dangling(iter); + let in_token = find_only_token_in_range( + TextRange::new(target.end(), iter.start()), + SimpleTokenKind::In, + f.context().source(), + ); + + let (before_in_comments, dangling_comments) = dangling_comments.split_at( + dangling_comments.partition_point(|comment| comment.end() < in_token.start()), + ); + + let (trailing_in_comments, dangling_if_comments) = dangling_comments + .split_at(dangling_comments.partition_point(|comment| comment.start() < iter.start())); let in_spacer = format_with(|f| { if before_in_comments.is_empty() { @@ -66,17 +78,23 @@ impl FormatNodeRule for FormatComprehension { iter.format(), ] )?; + if !ifs.is_empty() { let joined = format_with(|f| { let mut joiner = f.join_with(soft_line_break_or_space()); + let mut dangling_if_comments = dangling_if_comments; + for if_case in ifs { - let dangling_if_comments = comments.dangling(if_case); + let (if_comments, rest) = dangling_if_comments.split_at( + dangling_if_comments + .partition_point(|comment| comment.start() < if_case.start()), + ); + + let (own_line_if_comments, end_of_line_if_comments) = if_comments.split_at( + if_comments + .partition_point(|comment| comment.line_position().is_own_line()), + ); - let (own_line_if_comments, end_of_line_if_comments) = dangling_if_comments - .split_at( - dangling_if_comments - .partition_point(|comment| comment.line_position().is_own_line()), - ); joiner.entry(&format_args!( leading_comments(own_line_if_comments), token("if"), @@ -84,7 +102,12 @@ impl FormatNodeRule for FormatComprehension { Spacer(if_case), if_case.format(), )); + + dangling_if_comments = rest; } + + debug_assert!(dangling_if_comments.is_empty()); + joiner.finish() }); diff --git a/crates/ruff_python_formatter/src/other/identifier.rs b/crates/ruff_python_formatter/src/other/identifier.rs index ae3dd98f67000..cc62f25947fff 100644 --- a/crates/ruff_python_formatter/src/other/identifier.rs +++ b/crates/ruff_python_formatter/src/other/identifier.rs @@ -1,5 +1,6 @@ use ruff_formatter::{FormatOwnedWithRule, FormatRefWithRule}; use ruff_python_ast::Identifier; +use ruff_python_trivia::is_python_whitespace; use ruff_text_size::Ranged; use crate::prelude::*; @@ -27,3 +28,55 @@ impl<'ast> IntoFormat> for Identifier { FormatOwnedWithRule::new(self, FormatIdentifier) } } + +/// A formatter for a dot-delimited identifier, as seen in import statements: +/// ```python +/// import foo.bar +/// from tqdm . auto import tqdm +/// ``` +/// +/// Dot-delimited identifiers can contain newlines via continuations (backslashes) after the +/// dot-delimited segment, as in: +/// ```python +/// import foo\ +/// .bar +/// ``` +/// +/// While identifiers can typically be formatted via verbatim source code slices, dot-delimited +/// identifiers with newlines must be formatted via `text`. This struct implements both the fast +/// and slow paths for such identifiers. +#[derive(Debug)] +pub(crate) struct DotDelimitedIdentifier<'a>(&'a Identifier); + +impl<'a> DotDelimitedIdentifier<'a> { + pub(crate) fn new(identifier: &'a Identifier) -> Self { + Self(identifier) + } +} + +impl Format> for DotDelimitedIdentifier<'_> { + fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> { + // An import identifier can contain whitespace around the dots: + // ```python + // import importlib . metadata + // ``` + // It can also contain newlines by inserting continuations (backslashes) after + // a dot-delimited segment, as in: + // ```python + // import foo\ + // .bar + // ``` + if f.context().source()[self.0.range()] + .chars() + .any(|c| is_python_whitespace(c) || matches!(c, '\n' | '\r' | '\\')) + { + let no_whitespace: String = f.context().source()[self.0.range()] + .chars() + .filter(|c| !is_python_whitespace(*c) && !matches!(c, '\n' | '\r' | '\\')) + .collect(); + text(&no_whitespace, Some(self.0.start())).fmt(f) + } else { + source_text_slice(self.0.range()).fmt(f) + } + } +} diff --git a/crates/ruff_python_formatter/src/other/match_case.rs b/crates/ruff_python_formatter/src/other/match_case.rs index 0b965583d5e3d..785ab73f502b1 100644 --- a/crates/ruff_python_formatter/src/other/match_case.rs +++ b/crates/ruff_python_formatter/src/other/match_case.rs @@ -1,5 +1,5 @@ use ruff_formatter::write; -use ruff_python_ast::node::AstNode; +use ruff_python_ast::AstNode; use ruff_python_ast::MatchCase; use crate::builders::parenthesize_if_expands; diff --git a/crates/ruff_python_formatter/src/other/parameter_with_default.rs b/crates/ruff_python_formatter/src/other/parameter_with_default.rs index 7afcb1b31a959..a434c7586f333 100644 --- a/crates/ruff_python_formatter/src/other/parameter_with_default.rs +++ b/crates/ruff_python_formatter/src/other/parameter_with_default.rs @@ -1,5 +1,7 @@ use ruff_formatter::write; use ruff_python_ast::ParameterWithDefault; +use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer}; +use ruff_text_size::{Ranged, TextRange}; use crate::prelude::*; @@ -18,7 +20,51 @@ impl FormatNodeRule for FormatParameterWithDefault { if let Some(default) = default { let space = parameter.annotation.is_some().then_some(space()); - write!(f, [space, token("="), space, group(&default.format())])?; + // ```python + // def f( + // a = # parameter trailing comment; needs line break + // 1, + // b = + // # default leading comment; needs line break + // 2, + // c = ( # the default leading can only be end-of-line with parentheses; no line break + // 3 + // ), + // d = ( + // # own line leading comment with parentheses; no line break + // 4 + // ) + // ) + // ``` + let needs_line_break_trailing = f.context().comments().has_trailing(parameter); + let default_first_comment = f.context().comments().leading(default.as_ref()).first(); + let needs_line_break_leading = default_first_comment.is_some_and(|default_leading_comment| { + let mut tokenizer = SimpleTokenizer::new( + f.context().source(), + TextRange::new(parameter.end(), default_leading_comment.start()), + ) + .skip_trivia() + .skip_while(|token| token.kind == SimpleTokenKind::RParen); + let equals = tokenizer.next(); + debug_assert!(equals.is_some_and(|token| token.kind == SimpleTokenKind::Equals)); + let lparens = tokenizer.next(); + debug_assert!(lparens + .as_ref() + .map_or(true, |token| token.kind == SimpleTokenKind::LParen)); + lparens.is_none() + }); + let needs_line_break = needs_line_break_trailing || needs_line_break_leading; + + write!( + f, + [ + space, + token("="), + (!needs_line_break).then_some(space), + needs_line_break.then_some(hard_line_break()), + group(&default.format()) + ] + )?; } Ok(()) diff --git a/crates/ruff_python_formatter/src/other/parameters.rs b/crates/ruff_python_formatter/src/other/parameters.rs index 2194a579f4d26..5e67e579de728 100644 --- a/crates/ruff_python_formatter/src/other/parameters.rs +++ b/crates/ruff_python_formatter/src/other/parameters.rs @@ -1,8 +1,8 @@ use std::usize; use ruff_formatter::{format_args, write, FormatRuleWithOptions}; -use ruff_python_ast::node::{AnyNodeRef, AstNode}; use ruff_python_ast::Parameters; +use ruff_python_ast::{AnyNodeRef, AstNode}; use ruff_python_trivia::{SimpleToken, SimpleTokenKind, SimpleTokenizer}; use ruff_text_size::{Ranged, TextRange, TextSize}; diff --git a/crates/ruff_python_formatter/src/other/with_item.rs b/crates/ruff_python_formatter/src/other/with_item.rs index 0559e4a993d9a..59a7918777134 100644 --- a/crates/ruff_python_formatter/src/other/with_item.rs +++ b/crates/ruff_python_formatter/src/other/with_item.rs @@ -1,9 +1,12 @@ use ruff_formatter::write; + use ruff_python_ast::WithItem; use crate::comments::SourceComment; use crate::expression::maybe_parenthesize_expression; -use crate::expression::parentheses::{parenthesized, Parentheses, Parenthesize}; +use crate::expression::parentheses::{ + is_expression_parenthesized, parenthesized, Parentheses, Parenthesize, +}; use crate::prelude::*; #[derive(Default)] @@ -20,12 +23,24 @@ impl FormatNodeRule for FormatWithItem { let comments = f.context().comments().clone(); let trailing_as_comments = comments.dangling(item); + // Prefer keeping parentheses for already parenthesized expressions over + // parenthesizing other nodes. + let parenthesize = if is_expression_parenthesized( + context_expr.into(), + f.context().comments().ranges(), + f.context().source(), + ) { + Parenthesize::IfBreaks + } else { + Parenthesize::IfRequired + }; + write!( f, [maybe_parenthesize_expression( context_expr, item, - Parenthesize::IfRequired + parenthesize )] )?; diff --git a/crates/ruff_python_formatter/src/pattern/mod.rs b/crates/ruff_python_formatter/src/pattern/mod.rs index 50d1f99fb24d5..36d927be2a594 100644 --- a/crates/ruff_python_formatter/src/pattern/mod.rs +++ b/crates/ruff_python_formatter/src/pattern/mod.rs @@ -1,5 +1,5 @@ use ruff_formatter::{FormatOwnedWithRule, FormatRefWithRule, FormatRule, FormatRuleWithOptions}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::Pattern; use ruff_python_trivia::CommentRanges; use ruff_python_trivia::{ diff --git a/crates/ruff_python_formatter/src/pattern/pattern_arguments.rs b/crates/ruff_python_formatter/src/pattern/pattern_arguments.rs index 8dd05a91f50b5..cdcb482943ea0 100644 --- a/crates/ruff_python_formatter/src/pattern/pattern_arguments.rs +++ b/crates/ruff_python_formatter/src/pattern/pattern_arguments.rs @@ -1,5 +1,5 @@ use ruff_formatter::write; -use ruff_python_ast::node::AstNode; +use ruff_python_ast::AstNode; use ruff_python_ast::{Pattern, PatternArguments}; use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer}; use ruff_text_size::{Ranged, TextRange, TextSize}; diff --git a/crates/ruff_python_formatter/src/pattern/pattern_match_as.rs b/crates/ruff_python_formatter/src/pattern/pattern_match_as.rs index 921e548ac0b07..d9db505418e1d 100644 --- a/crates/ruff_python_formatter/src/pattern/pattern_match_as.rs +++ b/crates/ruff_python_formatter/src/pattern/pattern_match_as.rs @@ -1,5 +1,5 @@ use ruff_formatter::write; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::PatternMatchAs; use crate::comments::{dangling_comments, SourceComment}; diff --git a/crates/ruff_python_formatter/src/pattern/pattern_match_class.rs b/crates/ruff_python_formatter/src/pattern/pattern_match_class.rs index 69cbf4e774781..c6253e96c3e60 100644 --- a/crates/ruff_python_formatter/src/pattern/pattern_match_class.rs +++ b/crates/ruff_python_formatter/src/pattern/pattern_match_class.rs @@ -1,5 +1,5 @@ use ruff_formatter::write; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::PatternMatchClass; use crate::comments::{dangling_comments, SourceComment}; diff --git a/crates/ruff_python_formatter/src/pattern/pattern_match_mapping.rs b/crates/ruff_python_formatter/src/pattern/pattern_match_mapping.rs index 1145f64bdd532..1cd449c4e6825 100644 --- a/crates/ruff_python_formatter/src/pattern/pattern_match_mapping.rs +++ b/crates/ruff_python_formatter/src/pattern/pattern_match_mapping.rs @@ -1,5 +1,5 @@ use ruff_formatter::{format_args, write}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::PatternMatchMapping; use ruff_python_ast::{Expr, Identifier, Pattern}; use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer}; diff --git a/crates/ruff_python_formatter/src/pattern/pattern_match_or.rs b/crates/ruff_python_formatter/src/pattern/pattern_match_or.rs index 4de2af6c3ebe9..91e141dcc790a 100644 --- a/crates/ruff_python_formatter/src/pattern/pattern_match_or.rs +++ b/crates/ruff_python_formatter/src/pattern/pattern_match_or.rs @@ -1,5 +1,5 @@ use ruff_formatter::write; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::PatternMatchOr; use crate::comments::leading_comments; diff --git a/crates/ruff_python_formatter/src/pattern/pattern_match_sequence.rs b/crates/ruff_python_formatter/src/pattern/pattern_match_sequence.rs index 7d8cea85f1011..56e9d1c8a76ff 100644 --- a/crates/ruff_python_formatter/src/pattern/pattern_match_sequence.rs +++ b/crates/ruff_python_formatter/src/pattern/pattern_match_sequence.rs @@ -1,5 +1,6 @@ -use ruff_formatter::{Format, FormatResult}; -use ruff_python_ast::node::AnyNodeRef; +use crate::comments::SourceComment; +use ruff_formatter::{format_args, Format, FormatResult}; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::PatternMatchSequence; use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer}; use ruff_text_size::{Ranged, TextRange}; @@ -20,14 +21,26 @@ impl FormatNodeRule for FormatPatternMatchSequence { let dangling = comments.dangling(item); let sequence_type = SequenceType::from_pattern(item, f.context().source()); - if patterns.is_empty() { - return match sequence_type { - SequenceType::List => empty_parenthesized("[", dangling, "]").fmt(f), - SequenceType::Tuple | SequenceType::TupleNoParens => { - empty_parenthesized("(", dangling, ")").fmt(f) - } - }; + + match (patterns.as_slice(), sequence_type) { + // If the sequence is empty, format the empty parentheses, along with any dangling + // comments. + ([], SequenceType::Tuple | SequenceType::TupleNoParens) => { + return empty_parenthesized("(", dangling, ")").fmt(f) + } + ([], SequenceType::List) => return empty_parenthesized("[", dangling, "]").fmt(f), + + // A single-element tuple should always be parenthesized, and the trailing comma + // should never cause it to expand. + ([elt], SequenceType::Tuple | SequenceType::TupleNoParens) => { + return parenthesized("(", &format_args![elt.format(), token(",")], ")") + .with_dangling_comments(dangling) + .fmt(f) + } + + _ => {} } + let items = format_with(|f| { f.join_comma_separated(range.end()) .nodes(patterns.iter()) @@ -43,6 +56,15 @@ impl FormatNodeRule for FormatPatternMatchSequence { SequenceType::TupleNoParens => optional_parentheses(&items).fmt(f), } } + + fn fmt_dangling_comments( + &self, + _dangling_node_comments: &[SourceComment], + _f: &mut PyFormatter, + ) -> FormatResult<()> { + // Handled as part of `fmt_fields` + Ok(()) + } } impl NeedsParentheses for PatternMatchSequence { diff --git a/crates/ruff_python_formatter/src/pattern/pattern_match_singleton.rs b/crates/ruff_python_formatter/src/pattern/pattern_match_singleton.rs index f1aabfddc33f4..0fa9a8af6800a 100644 --- a/crates/ruff_python_formatter/src/pattern/pattern_match_singleton.rs +++ b/crates/ruff_python_formatter/src/pattern/pattern_match_singleton.rs @@ -1,4 +1,4 @@ -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{Constant, PatternMatchSingleton}; use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses}; diff --git a/crates/ruff_python_formatter/src/pattern/pattern_match_star.rs b/crates/ruff_python_formatter/src/pattern/pattern_match_star.rs index c8a88fe77353e..e608e65c14e98 100644 --- a/crates/ruff_python_formatter/src/pattern/pattern_match_star.rs +++ b/crates/ruff_python_formatter/src/pattern/pattern_match_star.rs @@ -1,5 +1,5 @@ use ruff_formatter::write; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::PatternMatchStar; use crate::comments::{dangling_comments, SourceComment}; diff --git a/crates/ruff_python_formatter/src/pattern/pattern_match_value.rs b/crates/ruff_python_formatter/src/pattern/pattern_match_value.rs index e513ef2fcfe6c..0e9db27b15877 100644 --- a/crates/ruff_python_formatter/src/pattern/pattern_match_value.rs +++ b/crates/ruff_python_formatter/src/pattern/pattern_match_value.rs @@ -1,4 +1,4 @@ -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::PatternMatchValue; use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses, Parentheses}; diff --git a/crates/ruff_python_formatter/src/statement/clause.rs b/crates/ruff_python_formatter/src/statement/clause.rs index 449b64e299644..4afe4358ecf49 100644 --- a/crates/ruff_python_formatter/src/statement/clause.rs +++ b/crates/ruff_python_formatter/src/statement/clause.rs @@ -1,5 +1,5 @@ use ruff_formatter::{write, Argument, Arguments, FormatError}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{ ElifElseClause, ExceptHandlerExceptHandler, MatchCase, StmtClassDef, StmtFor, StmtFunctionDef, StmtIf, StmtMatch, StmtTry, StmtWhile, StmtWith, Suite, @@ -203,15 +203,23 @@ impl<'a> ClauseHeader<'a> { fn first_keyword_range(self, source: &str) -> FormatResult { match self { ClauseHeader::Class(header) => { - find_keyword(header.start(), SimpleTokenKind::Class, source) + let start_position = header + .decorator_list + .last() + .map_or_else(|| header.start(), Ranged::end); + find_keyword(start_position, SimpleTokenKind::Class, source) } ClauseHeader::Function(header) => { + let start_position = header + .decorator_list + .last() + .map_or_else(|| header.start(), Ranged::end); let keyword = if header.is_async { SimpleTokenKind::Async } else { SimpleTokenKind::Def }; - find_keyword(header.start(), keyword, source) + find_keyword(start_position, keyword, source) } ClauseHeader::If(header) => find_keyword(header.start(), SimpleTokenKind::If, source), ClauseHeader::ElifElse(ElifElseClause { @@ -383,7 +391,9 @@ pub(crate) fn clause_body<'a>( impl Format> for FormatClauseBody<'_> { fn fmt(&self, f: &mut Formatter>) -> FormatResult<()> { - if f.options().source_type().is_stub() + // In stable, stubs are only collapsed in stub files, in preview this is consistently + // applied everywhere + if (f.options().source_type().is_stub() || f.options().preview().is_enabled()) && contains_only_an_ellipsis(self.body, f.context().comments()) && self.trailing_comments.is_empty() { diff --git a/crates/ruff_python_formatter/src/statement/stmt_ann_assign.rs b/crates/ruff_python_formatter/src/statement/stmt_ann_assign.rs index a29798d4c3316..f22457cc4b56a 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_ann_assign.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_ann_assign.rs @@ -21,12 +21,7 @@ impl FormatNodeRule for FormatStmtAnnAssign { write!( f, - [ - target.format(), - token(":"), - space(), - maybe_parenthesize_expression(annotation, item, Parenthesize::IfBreaks) - ] + [target.format(), token(":"), space(), annotation.format(),] )?; if let Some(value) = value { diff --git a/crates/ruff_python_formatter/src/statement/stmt_class_def.rs b/crates/ruff_python_formatter/src/statement/stmt_class_def.rs index 231320eac75f4..8c1d1c3944033 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_class_def.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_class_def.rs @@ -1,9 +1,11 @@ use ruff_formatter::write; use ruff_python_ast::{Decorator, StmtClassDef}; -use ruff_python_trivia::lines_after_ignoring_trivia; +use ruff_python_trivia::lines_after_ignoring_end_of_line_trivia; use ruff_text_size::Ranged; -use crate::comments::format::empty_lines_before_trailing_comments; +use crate::comments::format::{ + empty_lines_after_leading_comments, empty_lines_before_trailing_comments, +}; use crate::comments::{leading_comments, trailing_comments, SourceComment}; use crate::prelude::*; use crate::statement::clause::{clause_body, clause_header, ClauseHeader}; @@ -32,6 +34,29 @@ impl FormatNodeRule for FormatStmtClassDef { let (leading_definition_comments, trailing_definition_comments) = dangling_comments.split_at(trailing_definition_comments_start); + // If the class contains leading comments, insert newlines before them. + // For example, given: + // ```python + // # comment + // + // class Class: + // ... + // ``` + // + // At the top-level in a non-stub file, reformat as: + // ```python + // # comment + // + // + // class Class: + // ... + // ``` + // Note that this is only really relevant for the specific case in which there's a single + // newline between the comment and the node, but we _require_ two newlines. If there are + // _no_ newlines between the comment and the node, we don't insert _any_ newlines; if there + // are more than two, then `leading_comments` will preserve the correct number of newlines. + empty_lines_after_leading_comments(f, comments.leading(item)).fmt(f)?; + write!( f, [ @@ -158,13 +183,15 @@ impl Format> for FormatDecorators<'_> { // Write any leading definition comments (between last decorator and the header) // while maintaining the right amount of empty lines between the comment // and the last decorator. - let leading_line = - if lines_after_ignoring_trivia(last_decorator.end(), f.context().source()) <= 1 - { - hard_line_break() - } else { - empty_line() - }; + let leading_line = if lines_after_ignoring_end_of_line_trivia( + last_decorator.end(), + f.context().source(), + ) <= 1 + { + hard_line_break() + } else { + empty_line() + }; write!( f, diff --git a/crates/ruff_python_formatter/src/statement/stmt_function_def.rs b/crates/ruff_python_formatter/src/statement/stmt_function_def.rs index e55c5e3aa6e2c..5ad5f2f53904e 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_function_def.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_function_def.rs @@ -1,7 +1,9 @@ use ruff_formatter::write; use ruff_python_ast::StmtFunctionDef; -use crate::comments::format::empty_lines_before_trailing_comments; +use crate::comments::format::{ + empty_lines_after_leading_comments, empty_lines_before_trailing_comments, +}; use crate::comments::SourceComment; use crate::expression::maybe_parenthesize_expression; use crate::expression::parentheses::{Parentheses, Parenthesize}; @@ -30,6 +32,29 @@ impl FormatNodeRule for FormatStmtFunctionDef { let (leading_definition_comments, trailing_definition_comments) = dangling_comments.split_at(trailing_definition_comments_start); + // If the class contains leading comments, insert newlines before them. + // For example, given: + // ```python + // # comment + // + // def func(): + // ... + // ``` + // + // At the top-level in a non-stub file, reformat as: + // ```python + // # comment + // + // + // def func(): + // ... + // ``` + // Note that this is only really relevant for the specific case in which there's a single + // newline between the comment and the node, but we _require_ two newlines. If there are + // _no_ newlines between the comment and the node, we don't insert _any_ newlines; if there + // are more than two, then `leading_comments` will preserve the correct number of newlines. + empty_lines_after_leading_comments(f, comments.leading(item)).fmt(f)?; + write!( f, [ diff --git a/crates/ruff_python_formatter/src/statement/stmt_global.rs b/crates/ruff_python_formatter/src/statement/stmt_global.rs index 731630a3d8e00..dac5c0b520c0d 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_global.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_global.rs @@ -1,5 +1,5 @@ use ruff_formatter::{format_args, write}; -use ruff_python_ast::node::AstNode; +use ruff_python_ast::AstNode; use ruff_python_ast::StmtGlobal; use crate::comments::{SourceComment, SuppressionKind}; diff --git a/crates/ruff_python_formatter/src/statement/stmt_if.rs b/crates/ruff_python_formatter/src/statement/stmt_if.rs index e5852db8d0dc5..5c6fabea10edd 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_if.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_if.rs @@ -1,5 +1,5 @@ use ruff_formatter::{format_args, write}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{ElifElseClause, StmtIf}; use crate::comments::SourceComment; diff --git a/crates/ruff_python_formatter/src/statement/stmt_import_from.rs b/crates/ruff_python_formatter/src/statement/stmt_import_from.rs index 660cc1883b0f1..e0535268a002e 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_import_from.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_import_from.rs @@ -1,11 +1,12 @@ use ruff_formatter::write; -use ruff_python_ast::node::AstNode; +use ruff_python_ast::AstNode; use ruff_python_ast::StmtImportFrom; use ruff_text_size::Ranged; use crate::builders::{parenthesize_if_expands, PyFormatterExtensions, TrailingComma}; use crate::comments::{SourceComment, SuppressionKind}; use crate::expression::parentheses::parenthesized; +use crate::other::identifier::DotDelimitedIdentifier; use crate::prelude::*; #[derive(Default)] @@ -20,17 +21,18 @@ impl FormatNodeRule for FormatStmtImportFrom { range: _, } = item; - let level_str = level - .map(|level| ".".repeat(level as usize)) - .unwrap_or(String::default()); - write!( f, [ token("from"), space(), - text(&level_str, None), - module.as_ref().map(AsFormat::format), + format_with(|f| { + for _ in 0..level.unwrap_or(0) { + token(".").fmt(f)?; + } + Ok(()) + }), + module.as_ref().map(DotDelimitedIdentifier::new), space(), token("import"), space(), diff --git a/crates/ruff_python_formatter/src/statement/stmt_nonlocal.rs b/crates/ruff_python_formatter/src/statement/stmt_nonlocal.rs index 5be0c7c9eb17d..e39965e5b1c12 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_nonlocal.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_nonlocal.rs @@ -1,5 +1,5 @@ use ruff_formatter::{format_args, write}; -use ruff_python_ast::node::AstNode; +use ruff_python_ast::AstNode; use ruff_python_ast::StmtNonlocal; use crate::comments::{SourceComment, SuppressionKind}; diff --git a/crates/ruff_python_formatter/src/statement/stmt_while.rs b/crates/ruff_python_formatter/src/statement/stmt_while.rs index 88a9af9831fdc..8372cd6062e36 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_while.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_while.rs @@ -1,5 +1,5 @@ use ruff_formatter::{format_args, write}; -use ruff_python_ast::node::AstNode; +use ruff_python_ast::AstNode; use ruff_python_ast::{Stmt, StmtWhile}; use ruff_text_size::Ranged; diff --git a/crates/ruff_python_formatter/src/statement/stmt_with.rs b/crates/ruff_python_formatter/src/statement/stmt_with.rs index 9aa5e54bda32e..af2389279b559 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_with.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_with.rs @@ -1,5 +1,5 @@ use ruff_formatter::{format_args, write, FormatError}; -use ruff_python_ast::node::AstNode; +use ruff_python_ast::AstNode; use ruff_python_ast::StmtWith; use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer}; use ruff_text_size::{Ranged, TextRange}; @@ -84,9 +84,9 @@ impl FormatNodeRule for FormatStmtWith { })) .fmt(f)?; } else if let [item] = item.items.as_slice() { - // This is similar to `maybe_parenthesize_expression`, but we're not dealing with an - // expression here, it's a `WithItem`. - if comments.has_leading(item) || comments.has_trailing_own_line(item) { + // This is similar to `maybe_parenthesize_expression`, but we're not + // dealing with an expression here, it's a `WithItem`. + if comments.has_leading(item) || comments.has_trailing(item) { optional_parentheses(&item.format()).fmt(f)?; } else { item.format().fmt(f)?; diff --git a/crates/ruff_python_formatter/src/statement/suite.rs b/crates/ruff_python_formatter/src/statement/suite.rs index eae1d849e21eb..be22098eee650 100644 --- a/crates/ruff_python_formatter/src/statement/suite.rs +++ b/crates/ruff_python_formatter/src/statement/suite.rs @@ -1,8 +1,8 @@ use ruff_formatter::{write, FormatOwnedWithRule, FormatRefWithRule, FormatRuleWithOptions}; use ruff_python_ast::helpers::is_compound_statement; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::{self as ast, Constant, Expr, ExprConstant, PySourceType, Stmt, Suite}; -use ruff_python_trivia::{lines_after, lines_after_ignoring_trivia, lines_before}; +use ruff_python_trivia::{lines_after, lines_after_ignoring_end_of_line_trivia, lines_before}; use ruff_text_size::{Ranged, TextRange}; use crate::comments::{ @@ -19,7 +19,7 @@ use crate::verbatim::{ }; /// Level at which the [`Suite`] appears in the source code. -#[derive(Copy, Clone, Debug, Default)] +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] pub enum SuiteKind { /// Statements at the module level / top level TopLevel, @@ -123,7 +123,7 @@ impl FormatRule> for FormatSuite { let first_comments = comments.leading_dangling_trailing(first); - let (mut preceding, mut after_class_docstring) = if first_comments + let (mut preceding, mut empty_line_after_docstring) = if first_comments .leading .iter() .any(|comment| comment.is_suppression_off_comment(source)) @@ -143,11 +143,24 @@ impl FormatRule> for FormatSuite { ) } else { first.fmt(f)?; - ( - first.statement(), - matches!(first, SuiteChildStatement::Docstring(_)) - && matches!(self.kind, SuiteKind::Class), - ) + + #[allow(clippy::if_same_then_else)] + let empty_line_after_docstring = if matches!(first, SuiteChildStatement::Docstring(_)) + && self.kind == SuiteKind::Class + { + true + } else if f.options().preview().is_enabled() + && self.kind == SuiteKind::TopLevel + && DocstringStmt::try_from_statement(first.statement()).is_some() + { + // Only in preview mode, insert a newline after a module level docstring, but treat + // it as a docstring otherwise. See: https://github.com/psf/black/pull/3932. + true + } else { + false + }; + + (first.statement(), empty_line_after_docstring) }; let mut preceding_comments = comments.leading_dangling_trailing(preceding); @@ -155,13 +168,65 @@ impl FormatRule> for FormatSuite { while let Some(following) = iter.next() { let following_comments = comments.leading_dangling_trailing(following); + let needs_empty_lines = if is_class_or_function_definition(following) { + // Here we insert empty lines even if the preceding has a trailing own line comment + true + } else { + // Find nested class or function definitions that need an empty line after them. + // + // ```python + // def f(): + // if True: + // + // def double(s): + // return s + s + // + // print("below function") + // ``` + std::iter::successors( + Some(AnyNodeRef::from(preceding)), + AnyNodeRef::last_child_in_body, + ) + .take_while(|last_child| + // If there is a comment between preceding and following the empty lines were + // inserted before the comment by preceding and there are no extra empty lines + // after the comment. + // ```python + // class Test: + // def a(self): + // pass + // # trailing comment + // + // + // # two lines before, one line after + // + // c = 30 + // ```` + // This also includes nested class/function definitions, so we stop recursing + // once we see a node with a trailing own line comment: + // ```python + // def f(): + // if True: + // + // def double(s): + // return s + s + // + // # nested trailing own line comment + // print("below function with trailing own line comment") + // ``` + !comments.has_trailing_own_line(*last_child)) + .any(|last_child| { + matches!( + last_child, + AnyNodeRef::StmtFunctionDef(_) | AnyNodeRef::StmtClassDef(_) + ) + }) + }; + // Add empty lines before and after a function or class definition. If the preceding // node is a function or class, and contains trailing comments, then the statement // itself will add the requisite empty lines when formatting its comments. - if (is_class_or_function_definition(preceding) - && !preceding_comments.has_trailing_own_line()) - || is_class_or_function_definition(following) - { + if needs_empty_lines { if source_type.is_stub() { stub_file_empty_lines( self.kind, @@ -251,7 +316,7 @@ impl FormatRule> for FormatSuite { } }, } - } else if after_class_docstring { + } else if empty_line_after_docstring { // Enforce an empty line after a class docstring, e.g., these are both stable // formatting: // ```python @@ -274,29 +339,20 @@ impl FormatRule> for FormatSuite { // * [`NodeLevel::CompoundStatement`]: Up to one empty line // * [`NodeLevel::Expression`]: No empty lines - let count_lines = |offset| { - // It's necessary to skip any trailing line comment because RustPython doesn't include trailing comments - // in the node's range - // ```python - // a # The range of `a` ends right before this comment - // - // b - // ``` - // - // Simply using `lines_after` doesn't work if a statement has a trailing comment because - // it then counts the lines between the statement and the trailing comment, which is - // always 0. This is why it skips any trailing trivia (trivia that's on the same line) - // and counts the lines after. - lines_after(offset, source) - }; - + // It's necessary to skip any trailing line comment because our parser doesn't + // include trailing comments in the node's range: + // ```python + // a # The range of `a` ends right before this comment + // + // b + // ``` let end = preceding_comments .trailing .last() .map_or(preceding.end(), |comment| comment.slice().end()); match node_level { - NodeLevel::TopLevel => match count_lines(end) { + NodeLevel::TopLevel => match lines_after(end, source) { 0 | 1 => hard_line_break().fmt(f)?, 2 => empty_line().fmt(f)?, _ => match source_type { @@ -308,7 +364,7 @@ impl FormatRule> for FormatSuite { } }, }, - NodeLevel::CompoundStatement => match count_lines(end) { + NodeLevel::CompoundStatement => match lines_after(end, source) { 0 | 1 => hard_line_break().fmt(f)?, _ => empty_line().fmt(f)?, }, @@ -346,7 +402,7 @@ impl FormatRule> for FormatSuite { preceding_comments = following_comments; } - after_class_docstring = false; + empty_line_after_docstring = false; } Ok(()) @@ -379,7 +435,9 @@ fn stub_file_empty_lines( } } SuiteKind::Class | SuiteKind::Other | SuiteKind::Function => { - if empty_line_condition && lines_after_ignoring_trivia(preceding.end(), source) > 1 { + if empty_line_condition + && lines_after_ignoring_end_of_line_trivia(preceding.end(), source) > 1 + { empty_line().fmt(f) } else { hard_line_break().fmt(f) @@ -491,7 +549,7 @@ impl<'ast> IntoFormat> for Suite { } /// A statement representing a docstring. -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub(crate) struct DocstringStmt<'a>(&'a Stmt); impl<'a> DocstringStmt<'a> { @@ -502,9 +560,11 @@ impl<'a> DocstringStmt<'a> { }; if let Expr::Constant(ExprConstant { value, .. }) = value.as_ref() { - if !value.is_implicit_concatenated() { - return Some(DocstringStmt(stmt)); - } + return match value { + Constant::Str(value) if !value.implicit_concatenated => Some(DocstringStmt(stmt)), + Constant::Bytes(value) if !value.implicit_concatenated => Some(DocstringStmt(stmt)), + _ => None, + }; } None @@ -544,7 +604,7 @@ impl Format> for DocstringStmt<'_> { } /// A Child of a suite. -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub(crate) enum SuiteChildStatement<'a> { /// A docstring documenting a class or function definition. Docstring(DocstringStmt<'a>), diff --git a/crates/ruff_python_formatter/src/type_param/type_params.rs b/crates/ruff_python_formatter/src/type_param/type_params.rs index cac5b8b33f577..8e40495e4a0c5 100644 --- a/crates/ruff_python_formatter/src/type_param/type_params.rs +++ b/crates/ruff_python_formatter/src/type_param/type_params.rs @@ -1,11 +1,10 @@ -use ruff_formatter::write; use ruff_formatter::FormatResult; -use ruff_python_ast::node::AstNode; +use ruff_python_ast::AstNode; use ruff_python_ast::TypeParams; use ruff_text_size::Ranged; use crate::builders::PyFormatterExtensions; -use crate::comments::{trailing_comments, SourceComment}; +use crate::comments::SourceComment; use crate::expression::parentheses::parenthesized; use crate::prelude::*; @@ -24,7 +23,6 @@ impl FormatNodeRule for FormatTypeParams { // ] = ... let comments = f.context().comments().clone(); let dangling_comments = comments.dangling(item.as_any_node_ref()); - write!(f, [trailing_comments(dangling_comments)])?; let items = format_with(|f| { f.join_comma_separated(item.end()) @@ -32,7 +30,9 @@ impl FormatNodeRule for FormatTypeParams { .finish() }); - parenthesized("[", &items, "]").fmt(f) + parenthesized("[", &items, "]") + .with_dangling_comments(dangling_comments) + .fmt(f) } fn fmt_dangling_comments( diff --git a/crates/ruff_python_formatter/src/verbatim.rs b/crates/ruff_python_formatter/src/verbatim.rs index deaa8cf4c5a0e..4e2a532ce0f07 100644 --- a/crates/ruff_python_formatter/src/verbatim.rs +++ b/crates/ruff_python_formatter/src/verbatim.rs @@ -4,7 +4,7 @@ use std::iter::FusedIterator; use unicode_width::UnicodeWidthStr; use ruff_formatter::{write, FormatError}; -use ruff_python_ast::node::AnyNodeRef; +use ruff_python_ast::AnyNodeRef; use ruff_python_ast::Stmt; use ruff_python_parser::lexer::{lex_starts_at, LexResult}; use ruff_python_parser::{Mode, Tok}; @@ -327,7 +327,7 @@ fn write_suppressed_statements<'a>( for range in CommentRangeIter::in_suppression(comments.trailing(statement), source) { match range { - // All leading comments are suppressed + // All trailing comments are suppressed // ```python // statement // # suppressed @@ -394,10 +394,14 @@ fn write_suppressed_statements<'a>( statement = SuiteChildStatement::Other(next_statement); leading_node_comments = comments.leading(next_statement); } else { - let end = comments - .trailing(statement) - .last() - .map_or(statement.end(), Ranged::end); + let mut nodes = + std::iter::successors(Some(AnyNodeRef::from(statement.statement())), |statement| { + statement.last_child_in_body() + }); + + let end = nodes + .find_map(|statement| comments.trailing(statement).last().map(Ranged::end)) + .unwrap_or(statement.end()); FormatVerbatimStatementRange { verbatim_range: TextRange::new(format_off_comment.end(), end), diff --git a/crates/ruff_python_formatter/tests/fixtures.rs b/crates/ruff_python_formatter/tests/fixtures.rs index 1df67cfb978e9..604d79bbaee9f 100644 --- a/crates/ruff_python_formatter/tests/fixtures.rs +++ b/crates/ruff_python_formatter/tests/fixtures.rs @@ -1,5 +1,5 @@ use ruff_formatter::FormatOptions; -use ruff_python_formatter::{format_module, PyFormatOptions}; +use ruff_python_formatter::{format_module_source, PreviewMode, PyFormatOptions}; use similar::TextDiff; use std::fmt::{Formatter, Write}; use std::io::BufReader; @@ -20,7 +20,7 @@ fn black_compatibility() { PyFormatOptions::from_extension(input_path) }; - let printed = format_module(&content, options.clone()).unwrap_or_else(|err| { + let printed = format_module_source(&content, options.clone()).unwrap_or_else(|err| { panic!( "Formatting of {} to succeed but encountered error {err}", input_path.display() @@ -107,7 +107,8 @@ fn format() { let content = fs::read_to_string(input_path).unwrap(); let options = PyFormatOptions::from_extension(input_path); - let printed = format_module(&content, options.clone()).expect("Formatting to succeed"); + let printed = + format_module_source(&content, options.clone()).expect("Formatting to succeed"); let formatted_code = printed.as_code(); ensure_stability_when_formatting_twice(formatted_code, options.clone(), input_path); @@ -124,7 +125,7 @@ fn format() { for (i, options) in options.into_iter().enumerate() { let printed = - format_module(&content, options.clone()).expect("Formatting to succeed"); + format_module_source(&content, options.clone()).expect("Formatting to succeed"); let formatted_code = printed.as_code(); ensure_stability_when_formatting_twice(formatted_code, options.clone(), input_path); @@ -139,17 +140,42 @@ fn format() { .unwrap(); } } else { - let printed = format_module(&content, options.clone()).expect("Formatting to succeed"); - let formatted_code = printed.as_code(); - - ensure_stability_when_formatting_twice(formatted_code, options, input_path); + let printed = + format_module_source(&content, options.clone()).expect("Formatting to succeed"); + let formatted = printed.as_code(); + + ensure_stability_when_formatting_twice(formatted, options.clone(), input_path); + + // We want to capture the differences in the preview style in our fixtures + let options_preview = options.with_preview(PreviewMode::Enabled); + let printed_preview = format_module_source(&content, options_preview.clone()) + .expect("Formatting to succeed"); + let formatted_preview = printed_preview.as_code(); + + ensure_stability_when_formatting_twice( + formatted_preview, + options_preview.clone(), + input_path, + ); - writeln!( - snapshot, - "## Output\n{}", - CodeFrame::new("py", &formatted_code) - ) - .unwrap(); + if formatted == formatted_preview { + writeln!(snapshot, "## Output\n{}", CodeFrame::new("py", &formatted)).unwrap(); + } else { + // Having both snapshots makes it hard to see the difference, so we're keeping only + // diff. + writeln!( + snapshot, + "## Output\n{}\n## Preview changes\n{}", + CodeFrame::new("py", &formatted), + CodeFrame::new( + "diff", + TextDiff::from_lines(formatted, formatted_preview) + .unified_diff() + .header("Stable", "Preview") + ) + ) + .unwrap(); + } } insta::with_settings!({ @@ -174,7 +200,7 @@ fn ensure_stability_when_formatting_twice( options: PyFormatOptions, input_path: &Path, ) { - let reformatted = match format_module(formatted_code, options) { + let reformatted = match format_module_source(formatted_code, options) { Ok(reformatted) => reformatted, Err(err) => { panic!( diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__decorators.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__decorators.py.snap index e864b93275afd..43d3d15edad27 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__decorators.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__decorators.py.snap @@ -162,7 +162,7 @@ def f(): ```diff --- Black +++ Ruff -@@ -1,29 +1,205 @@ +@@ -1,29 +1,206 @@ +# This file doesn't use the standard decomposition. +# Decorator syntax test cases are separated by double # comments. +# Those before the 'output' comment are valid under the old syntax. @@ -172,6 +172,7 @@ def f(): + +## + ++ +@decorator +def f(): + ... @@ -209,29 +210,50 @@ def f(): + ... + + -+## -+ + ## + +-@decorator()() + +@decorator(**kwargs) -+def f(): -+ ... -+ -+ -+## + def f(): + ... + + + ## + +-@(decorator) + +@decorator(*args, **kwargs) -+def f(): -+ ... -+ -+ -+## + def f(): + ... + + + ## + +-@sequence["decorator"] + +@decorator( + *args, + **kwargs, +) + def f(): + ... + ++ + ## + +-@decorator[List[str]] ++ ++@dotted.decorator + def f(): + ... + ++ + ## + +-@var := decorator ++ ++@dotted.decorator(arg) +def f(): + ... + @@ -239,7 +261,7 @@ def f(): +## + + -+@dotted.decorator ++@dotted.decorator(kwarg=0) +def f(): + ... + @@ -247,7 +269,7 @@ def f(): +## + + -+@dotted.decorator(arg) ++@dotted.decorator(*args) +def f(): + ... + @@ -255,53 +277,32 @@ def f(): +## + + -+@dotted.decorator(kwarg=0) ++@dotted.decorator(**kwargs) +def f(): + ... + + - ## - --@decorator()() ++## + -+@dotted.decorator(*args) - def f(): - ... - + - ## - --@(decorator) ++@dotted.decorator(*args, **kwargs) ++def f(): ++ ... + -+@dotted.decorator(**kwargs) - def f(): - ... - + - ## - --@sequence["decorator"] -+ -+@dotted.decorator(*args, **kwargs) - def f(): - ... - ++## + - ## - --@decorator[List[str]] + +@dotted.decorator( + *args, + **kwargs, +) - def f(): - ... - ++def f(): ++ ... ++ ++ ++## + - ## - --@var := decorator + +@double.dotted.decorator +def f(): @@ -387,6 +388,7 @@ def f(): ## + @decorator def f(): ... diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__force_pyi.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__force_pyi.py.snap index b2ea1422961ce..678606a9ed1b3 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__force_pyi.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__force_pyi.py.snap @@ -5,6 +5,7 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/black/miscellan ## Input ```py +# flags: --pyi from typing import Union @bird @@ -42,7 +43,8 @@ def eggs() -> Union[str, int]: ... ```diff --- Black +++ Ruff -@@ -1,32 +1,58 @@ +@@ -1,32 +1,59 @@ ++# flags: --pyi from typing import Union + @@ -67,13 +69,13 @@ def eggs() -> Union[str, int]: ... - def BMethod(self, arg: List[str]) -> None: ... + def BMethod(self, arg: List[str]) -> None: + ... -+ -+ -+class C: -+ ... -class C: ... ++class C: ++ ... ++ ++ @hmm -class D: ... +class D: @@ -118,6 +120,7 @@ def eggs() -> Union[str, int]: ... ## Ruff Output ```py +# flags: --pyi from typing import Union diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__long_strings_flag_disabled.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__long_strings_flag_disabled.py.snap index 8be3c1f3eab42..991b20198c79e 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__long_strings_flag_disabled.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__long_strings_flag_disabled.py.snap @@ -320,17 +320,6 @@ long_unmergable_string_with_pragma = ( "formatting" ) -@@ -221,8 +217,8 @@ - func_with_bad_comma( - ( - "This is a really long string argument to a function that has a trailing comma" -- " which should NOT be there." -- ), # comment after comma -+ " which should NOT be there." # comment after comma -+ ), - ) - - func_with_bad_parens_that_wont_fit_in_one_line( ``` ## Ruff Output @@ -555,8 +544,8 @@ func_with_bad_comma( func_with_bad_comma( ( "This is a really long string argument to a function that has a trailing comma" - " which should NOT be there." # comment after comma - ), + " which should NOT be there." + ), # comment after comma ) func_with_bad_parens_that_wont_fit_in_one_line( diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__string_quotes.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__string_quotes.py.snap index 022b30a5a30a9..4600e1fd20261 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__string_quotes.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@miscellaneous__string_quotes.py.snap @@ -6,6 +6,7 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/black/miscellan ```py '''''' + '\'' '"' "'" @@ -69,7 +70,7 @@ f"\"{a}\"{'hello' * b}\"{c}\"" ```diff --- Black +++ Ruff -@@ -24,7 +24,12 @@ +@@ -25,7 +25,12 @@ r'Tricky "quote' r"Not-so-tricky \"quote" rf"{yay}" @@ -89,6 +90,7 @@ f"\"{a}\"{'hello' * b}\"{c}\"" ```py """""" + "'" '"' "'" @@ -151,6 +153,7 @@ f"\"{a}\"{'hello' * b}\"{c}\"" ```py """""" + "'" '"' "'" diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_39__python39.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_39__python39.py.snap deleted file mode 100644 index 0bfa03ff16902..0000000000000 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_39__python39.py.snap +++ /dev/null @@ -1,86 +0,0 @@ ---- -source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_39/python39.py ---- -## Input - -```py -#!/usr/bin/env python3.9 - -@relaxed_decorator[0] -def f(): - ... - -@relaxed_decorator[extremely_long_name_that_definitely_will_not_fit_on_one_line_of_standard_length] -def f(): - ... - -@extremely_long_variable_name_that_doesnt_fit := complex.expression(with_long="arguments_value_that_wont_fit_at_the_end_of_the_line") -def f(): - ... -``` - -## Black Differences - -```diff ---- Black -+++ Ruff -@@ -1,6 +1,5 @@ - #!/usr/bin/env python3.9 - -- - @relaxed_decorator[0] - def f(): - ... -``` - -## Ruff Output - -```py -#!/usr/bin/env python3.9 - -@relaxed_decorator[0] -def f(): - ... - - -@relaxed_decorator[ - extremely_long_name_that_definitely_will_not_fit_on_one_line_of_standard_length -] -def f(): - ... - - -@extremely_long_variable_name_that_doesnt_fit := complex.expression( - with_long="arguments_value_that_wont_fit_at_the_end_of_the_line" -) -def f(): - ... -``` - -## Black Output - -```py -#!/usr/bin/env python3.9 - - -@relaxed_decorator[0] -def f(): - ... - - -@relaxed_decorator[ - extremely_long_name_that_definitely_will_not_fit_on_one_line_of_standard_length -] -def f(): - ... - - -@extremely_long_variable_name_that_doesnt_fit := complex.expression( - with_long="arguments_value_that_wont_fit_at_the_end_of_the_line" -) -def f(): - ... -``` - - diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@raw_docstring.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@raw_docstring.py.snap new file mode 100644 index 0000000000000..8177e7d37f13b --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@raw_docstring.py.snap @@ -0,0 +1,92 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/black/raw_docstring.py +--- +## Input + +```py +# flags: --preview --skip-string-normalization +class C: + + r"""Raw""" + +def f(): + + r"""Raw""" + +class SingleQuotes: + + + r'''Raw''' + +class UpperCaseR: + R"""Raw""" +``` + +## Black Differences + +```diff +--- Black ++++ Ruff +@@ -1,4 +1,6 @@ ++# flags: --preview --skip-string-normalization + class C: ++ + r"""Raw""" + + +@@ -7,8 +9,9 @@ + + + class SingleQuotes: +- r'''Raw''' + ++ r"""Raw""" ++ + + class UpperCaseR: + R"""Raw""" +``` + +## Ruff Output + +```py +# flags: --preview --skip-string-normalization +class C: + + r"""Raw""" + + +def f(): + r"""Raw""" + + +class SingleQuotes: + + r"""Raw""" + + +class UpperCaseR: + R"""Raw""" +``` + +## Black Output + +```py +class C: + r"""Raw""" + + +def f(): + r"""Raw""" + + +class SingleQuotes: + r'''Raw''' + + +class UpperCaseR: + R"""Raw""" +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__attribute_access_on_number_literals.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__attribute_access_on_number_literals.py.snap deleted file mode 100644 index f1c8df13c2fcc..0000000000000 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__attribute_access_on_number_literals.py.snap +++ /dev/null @@ -1,108 +0,0 @@ ---- -source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/attribute_access_on_number_literals.py ---- -## Input - -```py -x = 123456789 .bit_count() -x = (123456).__abs__() -x = .1.is_integer() -x = 1. .imag -x = 1E+1.imag -x = 1E-1.real -x = 123456789.123456789.hex() -x = 123456789.123456789E123456789 .real -x = 123456789E123456789 .conjugate() -x = 123456789J.real -x = 123456789.123456789J.__add__(0b1011.bit_length()) -x = 0XB1ACC.conjugate() -x = 0B1011 .conjugate() -x = 0O777 .real -x = 0.000000006 .hex() -x = -100.0000J - -if 10 .real: - ... - -y = 100[no] -y = 100(no) -``` - -## Black Differences - -```diff ---- Black -+++ Ruff -@@ -8,10 +8,10 @@ - x = (123456789.123456789e123456789).real - x = (123456789e123456789).conjugate() - x = 123456789j.real --x = 123456789.123456789j.__add__(0b1011.bit_length()) --x = 0xB1ACC.conjugate() --x = 0b1011.conjugate() --x = 0o777.real -+x = 123456789.123456789j.__add__((0b1011).bit_length()) -+x = (0xB1ACC).conjugate() -+x = (0b1011).conjugate() -+x = (0o777).real - x = (0.000000006).hex() - x = -100.0000j - -``` - -## Ruff Output - -```py -x = (123456789).bit_count() -x = (123456).__abs__() -x = (0.1).is_integer() -x = (1.0).imag -x = (1e1).imag -x = (1e-1).real -x = (123456789.123456789).hex() -x = (123456789.123456789e123456789).real -x = (123456789e123456789).conjugate() -x = 123456789j.real -x = 123456789.123456789j.__add__((0b1011).bit_length()) -x = (0xB1ACC).conjugate() -x = (0b1011).conjugate() -x = (0o777).real -x = (0.000000006).hex() -x = -100.0000j - -if (10).real: - ... - -y = 100[no] -y = 100(no) -``` - -## Black Output - -```py -x = (123456789).bit_count() -x = (123456).__abs__() -x = (0.1).is_integer() -x = (1.0).imag -x = (1e1).imag -x = (1e-1).real -x = (123456789.123456789).hex() -x = (123456789.123456789e123456789).real -x = (123456789e123456789).conjugate() -x = 123456789j.real -x = 123456789.123456789j.__add__(0b1011.bit_length()) -x = 0xB1ACC.conjugate() -x = 0b1011.conjugate() -x = 0o777.real -x = (0.000000006).hex() -x = -100.0000j - -if (10).real: - ... - -y = 100[no] -y = 100(no) -``` - - diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap index 43e5c13e54101..02a6a4a76c98a 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap @@ -266,15 +266,6 @@ last_call() ```diff --- Black +++ Ruff -@@ -31,7 +31,7 @@ - -1 - ~int and not v1 ^ 123 + v2 | True - (~int) and (not ((v1 ^ (123 + v2)) | True)) --+(really ** -(confusing ** ~(operator**-precedence))) -++really ** -confusing ** ~operator**-precedence - flags & ~select.EPOLLIN and waiters.write_task is not None - lambda arg: None - lambda a=True: a @@ -115,7 +115,7 @@ arg, another, @@ -322,7 +313,7 @@ not great -1 ~int and not v1 ^ 123 + v2 | True (~int) and (not ((v1 ^ (123 + v2)) | True)) -+really ** -confusing ** ~operator**-precedence ++(really ** -(confusing ** ~(operator**-precedence))) flags & ~select.EPOLLIN and waiters.write_task is not None lambda arg: None lambda a=True: a diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function2.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function2.py.snap index 2570ff4de030a..2d1ed7c6ad0d6 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function2.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function2.py.snap @@ -73,7 +73,7 @@ with hmm_but_this_should_get_two_preceding_newlines(): elif os.name == "nt": try: import msvcrt -@@ -54,12 +53,10 @@ +@@ -54,7 +53,6 @@ class IHopeYouAreHavingALovelyDay: def __call__(self): print("i_should_be_followed_by_only_one_newline") @@ -81,11 +81,6 @@ with hmm_but_this_should_get_two_preceding_newlines(): else: def foo(): - pass -- - - with hmm_but_this_should_get_two_preceding_newlines(): - pass ``` ## Ruff Output @@ -151,6 +146,7 @@ else: def foo(): pass + with hmm_but_this_should_get_two_preceding_newlines(): pass ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__binary.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__binary.py.snap index b0b0c28cbad22..eb9f911a4ed93 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__binary.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__binary.py.snap @@ -81,7 +81,7 @@ if [ dddddddddddddddddddd, eeeeeeeeee, ] & aaaaaaaaaaaaaaaaaaaaaaaaaa: - ... + pass if [ aaaaaaaaaaaaa, @@ -90,7 +90,7 @@ if [ dddddddddddddddddddd, eeeeeeeeee, ] & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: - ... + pass # Right only can break if aaaaaaaaaaaaaaaaaaaaaaaaaa & [ @@ -100,7 +100,7 @@ if aaaaaaaaaaaaaaaaaaaaaaaaaa & [ dddddddddddddddddddd, eeeeeeeeee, ]: - ... + pass if aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa & [ aaaaaaaaaaaaa, @@ -109,7 +109,7 @@ if aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa dddddddddddddddddddd, eeeeeeeeee, ]: - ... + pass # Left or right can break @@ -120,7 +120,7 @@ if [2222, 333] & [ dddddddddddddddddddd, eeeeeeeeee, ]: - ... + pass if [ aaaaaaaaaaaaa, @@ -129,7 +129,7 @@ if [ dddddddddddddddddddd, eeeeeeeeee, ] & [2222, 333]: - ... + pass if [ aaaaaaaaaaaaa, @@ -138,7 +138,7 @@ if [ dddddddddddddddddddd, eeeeeeeeee, ] & [fffffffffffffffff, gggggggggggggggggggg, hhhhhhhhhhhhhhhhhhhhh, iiiiiiiiiiiiiiii, jjjjjjjjjjjjj]: - ... + pass if ( # comment @@ -158,7 +158,7 @@ if ( ]: pass - ... + pass # Nesting if (aaaa + b) & [ @@ -168,7 +168,7 @@ if (aaaa + b) & [ iiiiiiiiiiiiiiii, jjjjjjjjjjjjj, ]: - ... + pass if [ fffffffffffffffff, @@ -177,7 +177,7 @@ if [ iiiiiiiiiiiiiiii, jjjjjjjjjjjjj, ] & (a + b): - ... + pass if [ @@ -191,7 +191,7 @@ if [ a + b ): - ... + pass if ( [ @@ -205,7 +205,7 @@ if ( # comment a + b ): - ... + pass # Unstable formatting in https://github.com/realtyem/synapse-unraid/blob/unraid_develop/synapse/handlers/presence.py @@ -475,9 +475,8 @@ aaaaaaaaaaaaaa + { aaaaaaaaaaaaaa + [ a for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ] -( - aaaaaaaaaaaaaa - + (a for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) +aaaaaaaaaaaaaa + ( + a for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ) aaaaaaaaaaaaaa + { a for x in bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb @@ -532,7 +531,7 @@ if [ dddddddddddddddddddd, eeeeeeeeee, ] & aaaaaaaaaaaaaaaaaaaaaaaaaa: - ... + pass if ( [ @@ -544,7 +543,7 @@ if ( ] & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ): - ... + pass # Right only can break if aaaaaaaaaaaaaaaaaaaaaaaaaa & [ @@ -554,7 +553,7 @@ if aaaaaaaaaaaaaaaaaaaaaaaaaa & [ dddddddddddddddddddd, eeeeeeeeee, ]: - ... + pass if ( aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -566,7 +565,7 @@ if ( eeeeeeeeee, ] ): - ... + pass # Left or right can break @@ -577,7 +576,7 @@ if [2222, 333] & [ dddddddddddddddddddd, eeeeeeeeee, ]: - ... + pass if [ aaaaaaaaaaaaa, @@ -586,7 +585,7 @@ if [ dddddddddddddddddddd, eeeeeeeeee, ] & [2222, 333]: - ... + pass if [ aaaaaaaaaaaaa, @@ -601,7 +600,7 @@ if [ iiiiiiiiiiiiiiii, jjjjjjjjjjjjj, ]: - ... + pass if ( # comment @@ -621,7 +620,7 @@ if ( ]: pass - ... + pass # Nesting if (aaaa + b) & [ @@ -631,7 +630,7 @@ if (aaaa + b) & [ iiiiiiiiiiiiiiii, jjjjjjjjjjjjj, ]: - ... + pass if [ fffffffffffffffff, @@ -640,7 +639,7 @@ if [ iiiiiiiiiiiiiiii, jjjjjjjjjjjjj, ] & (a + b): - ... + pass if [ @@ -653,7 +652,7 @@ if [ # comment a + b ): - ... + pass if ( [ @@ -667,7 +666,7 @@ if ( # comment a + b ): - ... + pass # Unstable formatting in https://github.com/realtyem/synapse-unraid/blob/unraid_develop/synapse/handlers/presence.py diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__binary_pow_spacing.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__binary_pow_spacing.py.snap new file mode 100644 index 0000000000000..c22840f9f2ec4 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__binary_pow_spacing.py.snap @@ -0,0 +1,34 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/binary_pow_spacing.py +--- +## Input +```py +# No spacing +5 ** 5 +5.0 ** 5.0 +1e5 ** 2e5 +True ** True +False ** False +None ** None + +# Space +"a" ** "b" +``` + +## Output +```py +# No spacing +5**5 +5.0**5.0 +1e5**2e5 +True**True +False**False +None**None + +# Space +"a" ** "b" +``` + + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__boolean_operation.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__boolean_operation.py.snap index e62f59f804623..819040b366b7a 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__boolean_operation.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__boolean_operation.py.snap @@ -22,7 +22,7 @@ if ( and self._returncode and self._proc.poll() ): - ... + pass if ( aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -32,14 +32,14 @@ if ( and aaaaaaaaaaaaaaaaaaaaaaaaaa and aaaaaaaaaaaaaaaaaaaaaaaaaaaa ): - ... + pass if ( aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaas and aaaaaaaaaaaaaaaaa ): - ... + pass if [2222, 333] and [ @@ -49,7 +49,7 @@ if [2222, 333] and [ dddddddddddddddddddd, eeeeeeeeee, ]: - ... + pass if [ aaaaaaaaaaaaa, @@ -213,7 +213,7 @@ if ( and self._returncode and self._proc.poll() ): - ... + pass if ( aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -223,14 +223,14 @@ if ( and aaaaaaaaaaaaaaaaaaaaaaaaaa and aaaaaaaaaaaaaaaaaaaaaaaaaaaa ): - ... + pass if ( aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaas and aaaaaaaaaaaaaaaaa ): - ... + pass if [2222, 333] and [ @@ -240,7 +240,7 @@ if [2222, 333] and [ dddddddddddddddddddd, eeeeeeeeee, ]: - ... + pass if [ aaaaaaaaaaaaa, diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__bytes.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__bytes.py.snap index 3b07b0c15d0df..158e4f65c6d13 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__bytes.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__bytes.py.snap @@ -320,17 +320,17 @@ if True: b'This string will not include \ backslashes or newline characters.' -b'''Multiline +b"""Multiline String \" -''' +""" -b'''Multiline +b"""Multiline String \' -''' +""" -b'''Multiline +b"""Multiline String "" -''' +""" b'''Multiline String """ @@ -346,9 +346,9 @@ String ''' b"""Multiline String '""" -b'''Multiline +b"""Multiline String \"\"\" -''' +""" # String continuation diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__call.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__call.py.snap index 136b44be6d934..861c4f0553512 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__call.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__call.py.snap @@ -458,8 +458,9 @@ func( ) func( - # outer comment - ( # inner comment + ( + # outer comment + # inner comment [] ) ) diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__fstring.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__fstring.py.snap index 37fa5a5e40d98..5d39862c2d571 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__fstring.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__fstring.py.snap @@ -63,6 +63,11 @@ result_f = ( ), 2 ) + +# https://github.com/astral-sh/ruff/issues/6841 +x = f'''a{""}b''' +y = f'''c{1}d"""e''' +z = f'''a{""}b''' f'''c{1}d"""e''' ``` ## Output @@ -124,6 +129,11 @@ result_f = ( ), 2, ) + +# https://github.com/astral-sh/ruff/issues/6841 +x = f"""a{""}b""" +y = f'''c{1}d"""e''' +z = f"""a{""}b""" f'''c{1}d"""e''' ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__list_comp.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__list_comp.py.snap index b3a09e301c40b..a7007f72e44b1 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__list_comp.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__list_comp.py.snap @@ -101,6 +101,16 @@ aaaaaaaaaaaaaaaaaaaaa = [ x for (x, y,) in z if head_name ] + +[ + 1 for components in # pylint: disable=undefined-loop-variable + b + # integer 1 may only have decimal 01-09 + c # negative decimal +] + +# Parenthesized targets and iterators. +[x for (x) in y] +[x for x in (y)] ``` ## Output @@ -234,6 +244,16 @@ aaaaaaaaaaaaaaaaaaaaa = [ ) in z if head_name ] + +[ + 1 + for components in b # pylint: disable=undefined-loop-variable # integer 1 may only have decimal 01-09 + + c # negative decimal +] + +# Parenthesized targets and iterators. +[x for (x) in y] +[x for x in (y)] ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__number.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__number.py.snap new file mode 100644 index 0000000000000..feea8103e080f --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__number.py.snap @@ -0,0 +1,28 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/number.py +--- +## Input +```py +.1 +1. +1E+1 +1E-1 +1.E+1 +1.0E+1 +1.1E+1 +``` + +## Output +```py +0.1 +1.0 +1e1 +1e-1 +1.0e1 +1.0e1 +1.1e1 +``` + + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__slice.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__slice.py.snap index ec274d1f86eb7..9ba98aaef7f79 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__slice.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__slice.py.snap @@ -71,7 +71,7 @@ d3 = "d"[ # Spacing around the colon(s) def a(): - ... + pass e00 = "e"[:] e01 = "e"[:1] @@ -184,7 +184,7 @@ d3 = "d"[ # Spacing around the colon(s) def a(): - ... + pass e00 = "e"[:] diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__string.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__string.py.snap index 9c7a8ba79dab6..28ebcfd8502dc 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__string.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__string.py.snap @@ -365,17 +365,17 @@ if True: 'This string will not include \ backslashes or newline characters.' -'''Multiline +"""Multiline String \" -''' +""" -'''Multiline +"""Multiline String \' -''' +""" -'''Multiline +"""Multiline String "" -''' +""" '''Multiline String """ @@ -391,9 +391,9 @@ String ''' """Multiline String '""" -'''Multiline +"""Multiline String \"\"\" -''' +""" # String continuation @@ -471,16 +471,16 @@ test_particular = [ # Regression test for https://github.com/astral-sh/ruff/issues/5893 x = ( - '''aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa''' - '''bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb''' + """aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa""" + """bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb""" ) x = ( - f'''aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa''' - f'''bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb''' + f"""aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa""" + f"""bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb""" ) x = ( - b'''aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa''' - b'''bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb''' + b"""aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa""" + b"""bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb""" ) # https://github.com/astral-sh/ruff/issues/7460 diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__unary.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__unary.py.snap index 93114ae7694ab..6146fd82d5424 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__unary.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__unary.py.snap @@ -143,20 +143,20 @@ if not \ a: pass -# Regression: https://github.com/astral-sh/ruff/issues/5338 +# Regression test for: https://github.com/astral-sh/ruff/issues/5338 if a and not aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: - ... + pass if ( not # comment a): - ... + pass if ( not # comment a): - ... + pass # Regression test for: https://github.com/astral-sh/ruff/issues/7423 if True: @@ -167,6 +167,38 @@ if True: + "WARNING: Removing listed files. Do you really want to continue. yes/n)? " ): pass + +# Regression test for: https://github.com/astral-sh/ruff/issues/7448 +x = ( + # a + not # b + # c + ( # d + # e + True + ) +) + +# Regression test for: https://github.com/astral-sh/ruff/issues/8090 +if "root" not in ( + long_tree_name_tree.split("/")[0] + for long_tree_name_tree in really_really_long_variable_name +): + msg = "Could not find root. Please try a different forest." + raise ValueError(msg) + +# Regression for https://github.com/astral-sh/ruff/issues/8183 +def foo(): + while ( + not (aaaaaaaaaaaaaaaaaaaaa(bbbbbbbb, ccccccc)) and dddddddddd < eeeeeeeeeeeeeee + ): + pass + +def foo(): + while ( + not (aaaaaaaaaaaaaaaaaaaaa[bbbbbbbb, ccccccc]) and dddddddddd < eeeeeeeeeeeeeee + ): + pass ``` ## Output @@ -217,35 +249,31 @@ if +( pass if ( - not # comment - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + not aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ): pass if ( - ~ # comment - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ): pass if ( - - # comment - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ): pass if ( - + # comment - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ): pass @@ -254,8 +282,8 @@ if ( if ( # unary comment + # operand comment not ( - # operand comment # comment aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb @@ -277,37 +305,43 @@ if aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa & ( ): pass -if not ( - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb -) & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: +if ( + not ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + ) + & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +): pass ## Trailing operator comments -if ( - not aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # comment +if ( # comment + not aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ): pass if ( - ~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # comment + # comment + ~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ): pass if ( - -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # comment + # comment + -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ): pass if ( - +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # comment + # comment + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ): pass @@ -318,23 +352,24 @@ if ( if not a: pass -# Regression: https://github.com/astral-sh/ruff/issues/5338 +# Regression test for: https://github.com/astral-sh/ruff/issues/5338 if ( a and not aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ): - ... + pass if ( - not # comment - a + not a ): - ... + pass -if not a: # comment - ... +if ( # comment + not a +): + pass # Regression test for: https://github.com/astral-sh/ruff/issues/7423 if True: @@ -345,6 +380,40 @@ if True: + "WARNING: Removing listed files. Do you really want to continue. yes/n)? " ): pass + +# Regression test for: https://github.com/astral-sh/ruff/issues/7448 +x = ( + # a + # b + # c + not ( # d + # e + True + ) +) + +# Regression test for: https://github.com/astral-sh/ruff/issues/8090 +if "root" not in ( + long_tree_name_tree.split("/")[0] + for long_tree_name_tree in really_really_long_variable_name +): + msg = "Could not find root. Please try a different forest." + raise ValueError(msg) + + +# Regression for https://github.com/astral-sh/ruff/issues/8183 +def foo(): + while ( + not (aaaaaaaaaaaaaaaaaaaaa(bbbbbbbb, ccccccc)) and dddddddddd < eeeeeeeeeeeeeee + ): + pass + + +def foo(): + while ( + not (aaaaaaaaaaaaaaaaaaaaa[bbbbbbbb, ccccccc]) and dddddddddd < eeeeeeeeeeeeeee + ): + pass ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__unsplittable.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__unsplittable.py.snap index 1189d13a37f7b..b3b609ce6eb3b 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__unsplittable.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__unsplittable.py.snap @@ -57,7 +57,7 @@ aaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbb for converter in connection.ops.get_db_converters( expression ) + expression.get_db_converters(connection): - ... + pass aaa = ( @@ -161,7 +161,7 @@ aaaaaaaa = ( for converter in connection.ops.get_db_converters( expression ) + expression.get_db_converters(connection): - ... + pass aaa = ( diff --git a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_unclosed_deep_nested_trailing_comment.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_unclosed_deep_nested_trailing_comment.py.snap new file mode 100644 index 0000000000000..081eb523828fd --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_unclosed_deep_nested_trailing_comment.py.snap @@ -0,0 +1,30 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/fmt_on_off/fmt_off_unclosed_deep_nested_trailing_comment.py +--- +## Input +```py +# Regression test for https://github.com/astral-sh/ruff/issues/8211 + +# fmt: off +from dataclasses import dataclass + +if True: + if False: + x: int # Optional[int] +``` + +## Output +```py +# Regression test for https://github.com/astral-sh/ruff/issues/8211 + +# fmt: off +from dataclasses import dataclass + +if True: + if False: + x: int # Optional[int] +``` + + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_unclosed_trailing_comment.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_unclosed_trailing_comment.py.snap new file mode 100644 index 0000000000000..14cf588e95ccb --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_unclosed_trailing_comment.py.snap @@ -0,0 +1,30 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/fmt_on_off/fmt_off_unclosed_trailing_comment.py +--- +## Input +```py +# Regression test for https://github.com/astral-sh/ruff/issues/8211 + +# fmt: off +from dataclasses import dataclass + +@dataclass +class A: + x: int # Optional[int] +``` + +## Output +```py +# Regression test for https://github.com/astral-sh/ruff/issues/8211 + +# fmt: off +from dataclasses import dataclass + +@dataclass +class A: + x: int # Optional[int] +``` + + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__form_feed.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__form_feed.py.snap index 0c009fa42416d..ba62839bd8149 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__form_feed.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__form_feed.py.snap @@ -20,6 +20,7 @@ def test(): # fmt: on + def test(): pass ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__trailing_comments.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__trailing_comments.py.snap index e80951bd3ac25..89308b0d8a99d 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__trailing_comments.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__trailing_comments.py.snap @@ -93,4 +93,21 @@ def test3 (): ``` +## Preview changes +```diff +--- Stable ++++ Preview +@@ -21,8 +21,7 @@ + + + # formatted +-def test2(): +- ... ++def test2(): ... + + + a = 10 +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@fmt_skip__decorators.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@fmt_skip__decorators.py.snap index 330e73752d3f2..720890d63353e 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@fmt_skip__decorators.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@fmt_skip__decorators.py.snap @@ -23,6 +23,19 @@ class Test: def test(): pass + +# Regression test for https://github.com/astral-sh/ruff/issues/7735 +@decorator1 +@decorator2 +class Foo: # fmt: skip + pass + + +# Regression test for https://github.com/astral-sh/ruff/issues/7735 +@decorator1 +@decorator2 +def foo(): # fmt: skip + pass ``` ## Output @@ -43,6 +56,20 @@ class Test: # leading class comment def test(): pass + + +# Regression test for https://github.com/astral-sh/ruff/issues/7735 +@decorator1 +@decorator2 +class Foo: # fmt: skip + pass + + +# Regression test for https://github.com/astral-sh/ruff/issues/7735 +@decorator1 +@decorator2 +def foo(): # fmt: skip + pass ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@form_feed.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@form_feed.py.snap new file mode 100644 index 0000000000000..f57c3801190c1 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@form_feed.py.snap @@ -0,0 +1,26 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/form_feed.py +--- +## Input +```py +# Regression test for: https://github.com/astral-sh/ruff/issues/7624 +if symbol is not None: + request["market"] = market["id"] + # "remaining_volume": "0.0", +else: + pass +``` + +## Output +```py +# Regression test for: https://github.com/astral-sh/ruff/issues/7624 +if symbol is not None: + request["market"] = market["id"] +# "remaining_volume": "0.0", +else: + pass +``` + + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@newlines.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@newlines.py.snap index 654d55dbb9789..eacf5fe7938d4 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@newlines.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@newlines.py.snap @@ -7,6 +7,7 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/newlines.p ### # Blank lines around functions ### +import sys x = 1 @@ -165,13 +166,107 @@ def f(): # comment x = 1 -``` + + +def f(): + if True: + + def double(s): + return s + s + print("below function") + if True: + + class A: + x = 1 + print("below class") + if True: + + def double(s): + return s + s + # + print("below comment function") + if True: + + class A: + x = 1 + # + print("below comment class") + if True: + + def double(s): + return s + s + # + print("below comment function 2") + if True: + + def double(s): + return s + s + # + def outer(): + def inner(): + pass + print("below nested functions") + +if True: + + def double(s): + return s + s +print("below function") +if True: + + class A: + x = 1 +print("below class") +def outer(): + def inner(): + pass +print("below nested functions") + + +class Path: + if sys.version_info >= (3, 11): + def joinpath(self): ... + + # The .open method comes from pathlib.pyi and should be kept in sync. + @overload + def open(self): ... + + + + +def fakehttp(): + + class FakeHTTPConnection: + if mock_close: + def close(self): + pass + FakeHTTPConnection.fakedata = fakedata + + + + + +if True: + if False: + def x(): + def y(): + pass + #comment + print() + + +# NOTE: Please keep this the last block in this file. This tests that we don't insert +# empty line(s) at the end of the file due to nested function +if True: + def nested_trailing_function(): + pass``` ## Output ```py ### # Blank lines around functions ### +import sys x = 1 @@ -339,6 +434,141 @@ def f(): # comment x = 1 + + +def f(): + if True: + + def double(s): + return s + s + + print("below function") + if True: + + class A: + x = 1 + + print("below class") + if True: + + def double(s): + return s + s + + # + print("below comment function") + if True: + + class A: + x = 1 + + # + print("below comment class") + if True: + + def double(s): + return s + s + + # + print("below comment function 2") + if True: + + def double(s): + return s + s + # + + def outer(): + def inner(): + pass + + print("below nested functions") + + +if True: + + def double(s): + return s + s + + +print("below function") +if True: + + class A: + x = 1 + + +print("below class") + + +def outer(): + def inner(): + pass + + +print("below nested functions") + + +class Path: + if sys.version_info >= (3, 11): + + def joinpath(self): + ... + + # The .open method comes from pathlib.pyi and should be kept in sync. + @overload + def open(self): + ... + + +def fakehttp(): + class FakeHTTPConnection: + if mock_close: + + def close(self): + pass + + FakeHTTPConnection.fakedata = fakedata + + +if True: + if False: + + def x(): + def y(): + pass + + # comment + print() + + +# NOTE: Please keep this the last block in this file. This tests that we don't insert +# empty line(s) at the end of the file due to nested function +if True: + + def nested_trailing_function(): + pass +``` + + +## Preview changes +```diff +--- Stable ++++ Preview +@@ -245,13 +245,11 @@ + class Path: + if sys.version_info >= (3, 11): + +- def joinpath(self): +- ... ++ def joinpath(self): ... + + # The .open method comes from pathlib.pyi and should be kept in sync. + @overload +- def open(self): +- ... ++ def open(self): ... + + + def fakehttp(): ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@parentheses__expression_parentheses_comments.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@parentheses__expression_parentheses_comments.py.snap new file mode 100644 index 0000000000000..f90a84c74c0f4 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@parentheses__expression_parentheses_comments.py.snap @@ -0,0 +1,225 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/parentheses/expression_parentheses_comments.py +--- +## Input +```py +list_with_parenthesized_elements1 = [ + # comment leading outer + ( + # comment leading inner + 1 + 2 # comment trailing inner + ) # comment trailing outer +] + +list_with_parenthesized_elements2 = [ + # leading outer + (1 + 2) +] +list_with_parenthesized_elements3 = [ + # leading outer + (1 + 2) # trailing outer +] +list_with_parenthesized_elements4 = [ + # leading outer + (1 + 2), # trailing outer +] +list_with_parenthesized_elements5 = [ + (1), # trailing outer + (2), # trailing outer +] + +nested_parentheses1 = ( + ( + ( + 1 + ) # i + ) # j +) # k +nested_parentheses2 = [ + ( + ( + ( + 1 + ) # i + # i2 + ) # j + # j2 + ) # k + # k2 +] +nested_parentheses3 = ( + ( # a + ( # b + 1 + ) # i + ) # j +) # k +nested_parentheses4 = [ + # a + ( # b + # c + ( # d + # e + ( #f + 1 + ) # i + # i2 + ) # j + # j2 + ) # k + # k2 +] + + +x = ( + # unary comment + not + # in-between comment + ( + # leading inner + "a" + ), + not # in-between comment + ( + # leading inner + "b" + ), + not + ( # in-between comment + # leading inner + "c" + ), + # 1 + not # 2 + ( # 3 + # 4 + "d" + ) +) + +if ( + # unary comment + not + # in-between comment + ( + # leading inner + 1 + ) +): + pass + +# Make sure we keep a inside the parentheses +# https://github.com/astral-sh/ruff/issues/7892 +x = ( + # a + ( # b + 1 + ) +) +``` + +## Output +```py +list_with_parenthesized_elements1 = [ + # comment leading outer + ( + # comment leading inner + 1 + 2 # comment trailing inner + ) # comment trailing outer +] + +list_with_parenthesized_elements2 = [ + # leading outer + (1 + 2) +] +list_with_parenthesized_elements3 = [ + # leading outer + (1 + 2) # trailing outer +] +list_with_parenthesized_elements4 = [ + # leading outer + (1 + 2), # trailing outer +] +list_with_parenthesized_elements5 = [ + (1), # trailing outer + (2), # trailing outer +] + +nested_parentheses1 = ( + 1 # i # j +) # k +nested_parentheses2 = [ + ( + 1 # i + # i2 + # j + # j2 + ) # k + # k2 +] +nested_parentheses3 = ( # a + # b + 1 # i # j +) # k +nested_parentheses4 = [ + # a + ( # b + # c + # d + # e + # f + 1 # i + # i2 + # j + # j2 + ) # k + # k2 +] + + +x = ( + # unary comment + # in-between comment + not ( + # leading inner + "a" + ), + # in-between comment + not ( + # leading inner + "b" + ), + not ( # in-between comment + # leading inner + "c" + ), + # 1 + # 2 + not ( # 3 + # 4 + "d" + ), +) + +if ( + # unary comment + # in-between comment + not ( + # leading inner + 1 + ) +): + pass + +# Make sure we keep a inside the parentheses +# https://github.com/astral-sh/ruff/issues/7892 +x = ( + # a + # b + 1 +) +``` + + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@parentheses__opening_parentheses_comment_value.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@parentheses__opening_parentheses_comment_value.py.snap index 0c287d1b0ba89..5e387b26fa3fc 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@parentheses__opening_parentheses_comment_value.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@parentheses__opening_parentheses_comment_value.py.snap @@ -327,7 +327,9 @@ f3 = { # f3 # Non-empty parentheses: These are not allowed without a value -def f1[T](): # f1 +def f1[ # f1 + T +](): pass diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__assign_breaking.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@preview.py.snap similarity index 66% rename from crates/ruff_python_formatter/tests/snapshots/format@statement__assign_breaking.py.snap rename to crates/ruff_python_formatter/tests/snapshots/format@preview.py.snap index affcbc0c35642..f37b61a77bf1c 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__assign_breaking.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@preview.py.snap @@ -1,13 +1,45 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/assign_breaking.py +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/preview.py --- ## Input ```py -# Below is black stable style -# In preview style, black always breaks the right side first +""" +Black's `Preview.module_docstring_newlines` +""" +first_stmt_after_module_level_docstring = 1 -if True: + +class CachedRepository: + # Black's `Preview.dummy_implementations` + def get_release_info(self): ... + + +def raw_docstring(): + + r"""Black's `Preview.accept_raw_docstrings` + a + b + """ + pass + + +def reference_docstring_newlines(): + + """A regular docstring for comparison + a + b + """ + pass + + +class RemoveNewlineBeforeClassDocstring: + + """Black's `Preview.no_blank_line_before_class_docstring`""" + + +def f(): + """Black's `Preview.prefer_splitting_right_hand_side_of_assignments`""" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ] = cccccccc.ccccccccccccc.cccccccc @@ -52,10 +84,41 @@ preview = Disabled ``` ```py -# Below is black stable style -# In preview style, black always breaks the right side first +""" +Black's `Preview.module_docstring_newlines` +""" +first_stmt_after_module_level_docstring = 1 + + +class CachedRepository: + # Black's `Preview.dummy_implementations` + def get_release_info(self): + ... + + +def raw_docstring(): + r"""Black's `Preview.accept_raw_docstrings` + a + b + """ + pass + -if True: +def reference_docstring_newlines(): + """A regular docstring for comparison + a + b + """ + pass + + +class RemoveNewlineBeforeClassDocstring: + + """Black's `Preview.no_blank_line_before_class_docstring`""" + + +def f(): + """Black's `Preview.prefer_splitting_right_hand_side_of_assignments`""" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ] = cccccccc.ccccccccccccc.cccccccc @@ -100,10 +163,41 @@ preview = Enabled ``` ```py -# Below is black stable style -# In preview style, black always breaks the right side first +""" +Black's `Preview.module_docstring_newlines` +""" + +first_stmt_after_module_level_docstring = 1 + + +class CachedRepository: + # Black's `Preview.dummy_implementations` + def get_release_info(self): ... + + +def raw_docstring(): + r"""Black's `Preview.accept_raw_docstrings` + a + b + """ + pass + + +def reference_docstring_newlines(): + """A regular docstring for comparison + a + b + """ + pass + + +class RemoveNewlineBeforeClassDocstring: + + """Black's `Preview.no_blank_line_before_class_docstring`""" + -if True: +def f(): + """Black's `Preview.prefer_splitting_right_hand_side_of_assignments`""" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ] = cccccccc.ccccccccccccc.cccccccc diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__ann_assign.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__ann_assign.py.snap index 52d136a3bef13..83dcc0fbac867 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__ann_assign.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__ann_assign.py.snap @@ -7,6 +7,21 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ # Regression test: Don't forget the parentheses in the value when breaking aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int = a + 1 * a +bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = ( + Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb() +) + +bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: ( + Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +)= Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb() + +JSONSerializable: TypeAlias = ( + "str | int | float | bool | None | list | tuple | JSONMapping" +) + +JSONSerializable: str | int | float | bool | None | list | tuple | JSONMapping = {1, 2, 3, 4} + +JSONSerializable: str | int | float | bool | None | list | tuple | JSONMapping = aaaaaaaaaaaaaaaa # Regression test: Don't forget the parentheses in the annotation when breaking class DefaultRunner: @@ -20,12 +35,35 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int = a + 1 * a ) +bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = ( + Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb() +) + +bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: ( + Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +) = Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb() + +JSONSerializable: TypeAlias = ( + "str | int | float | bool | None | list | tuple | JSONMapping" +) + +JSONSerializable: str | int | float | bool | None | list | tuple | JSONMapping = { + 1, + 2, + 3, + 4, +} + +JSONSerializable: str | int | float | bool | None | list | tuple | JSONMapping = ( + aaaaaaaaaaaaaaaa +) + # Regression test: Don't forget the parentheses in the annotation when breaking class DefaultRunner: - task_runner_cls: ( - TaskRunnerProtocol | typing.Callable[[], typing.Any] - ) = DefaultTaskRunner + task_runner_cls: TaskRunnerProtocol | typing.Callable[ + [], typing.Any + ] = DefaultTaskRunner ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__class_definition.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__class_definition.py.snap index 9258c1ca71d98..d555951aa2b01 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__class_definition.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__class_definition.py.snap @@ -4,6 +4,8 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ --- ## Input ```py +# comment + class Test( Aaaaaaaaaaaaaaaaa, Bbbbbbbbbbbbbbbb, @@ -232,6 +234,9 @@ class QuerySet(AltersData): ## Output ```py +# comment + + class Test( Aaaaaaaaaaaaaaaaa, Bbbbbbbbbbbbbbbb, @@ -494,4 +499,45 @@ class QuerySet(AltersData): ``` +## Preview changes +```diff +--- Stable ++++ Preview +@@ -28,8 +28,7 @@ + pass + + +-class Test((Aaaa)): +- ... ++class Test((Aaaa)): ... + + + class Test( +@@ -159,20 +158,17 @@ + + @dataclass + # Copied from transformers.models.clip.modeling_clip.CLIPOutput with CLIP->AltCLIP +-class AltCLIPOutput(ModelOutput): +- ... ++class AltCLIPOutput(ModelOutput): ... + + + @dataclass +-class AltCLIPOutput: # Copied from transformers.models.clip.modeling_clip.CLIPOutput with CLIP->AltCLIP +- ... ++class AltCLIPOutput: ... # Copied from transformers.models.clip.modeling_clip.CLIPOutput with CLIP->AltCLIP + + + @dataclass + class AltCLIPOutput( + # Copied from transformers.models.clip.modeling_clip.CLIPOutput with CLIP->AltCLIP +-): +- ... ++): ... + + + class TestTypeParams[ +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__for.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__for.py.snap index f76bbc6405899..1ff6cc43104ab 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__for.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__for.py.snap @@ -21,23 +21,23 @@ for aVeryLongNameThatSpillsOverToTheNextLineBecauseItIsExtremelyLongAndGoesOnAnd pass else: - ... + pass for ( x, y, ) in z: # comment - ... + pass # remove brackets around x,y but keep them around z,w for (x, y) in (z, w): - ... + pass # type comment for x in (): # type: int - ... + pass # Tuple parentheses for iterable. for x in 1, 2, 3: @@ -97,23 +97,23 @@ for aVeryLongNameThatSpillsOverToTheNextLineBecauseItIsExtremelyLongAndGoesOnAnd pass else: - ... + pass for ( x, y, ) in z: # comment - ... + pass # remove brackets around x,y but keep them around z,w for x, y in (z, w): - ... + pass # type comment for x in (): # type: int - ... + pass # Tuple parentheses for iterable. for x in 1, 2, 3: diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__function.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__function.py.snap index 443e451daf5f1..a5ef8fe28fab8 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__function.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__function.py.snap @@ -390,6 +390,32 @@ try: #comment except ImportError: pass + +# https://github.com/astral-sh/ruff/issues/7603 +def default_arg_comments( + a: str = #a + "a", + b: str = + #b + "b", + c: str =( #c + "c" + ), + d: str =( + #d + "d" + ) +): + print(a, b, c, d) + +def default_arg_comments2(# + x: int#= + = # + # + 123# + # +): + print(x) ``` ## Output @@ -940,6 +966,196 @@ try: # comment except ImportError: pass + + +# https://github.com/astral-sh/ruff/issues/7603 +def default_arg_comments( + a: str = # a + "a", + b: str = + # b + "b", + c: str = ( # c + "c" + ), + d: str = ( + # d + "d" + ), +): + print(a, b, c, d) + + +def default_arg_comments2( # + x: int = # = # + # + 123, # + # +): + print(x) +``` + + +## Preview changes +```diff +--- Stable ++++ Preview +@@ -2,8 +2,7 @@ + def test( + # comment + # another +-): +- ... ++): ... + + + # Argument empty line spacing +@@ -12,8 +11,7 @@ + a, + # another + b, +-): +- ... ++): ... + + + ### Different function argument wrappings +@@ -57,8 +55,7 @@ + b, + # comment + *args, +-): +- ... ++): ... + + + def kwarg_with_leading_comments( +@@ -66,8 +63,7 @@ + b, + # comment + **kwargs, +-): +- ... ++): ... + + + def argument_with_long_default( +@@ -75,8 +71,7 @@ + b=ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc + + [dddddddddddddddddddd, eeeeeeeeeeeeeeeeeeee, ffffffffffffffffffffffff], + h=[], +-): +- ... ++): ... + + + def argument_with_long_type_annotation( +@@ -85,12 +80,10 @@ + | yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy + | zzzzzzzzzzzzzzzzzzz = [0, 1, 2, 3], + h=[], +-): +- ... ++): ... + + +-def test(): +- ... ++def test(): ... + + + # Type parameter empty line spacing +@@ -99,8 +92,7 @@ + A, + # another + B, +-](): +- ... ++](): ... + + + # Type parameter comments +@@ -159,8 +151,7 @@ + + + # Comment +-def with_leading_comment(): +- ... ++def with_leading_comment(): ... + + + # Comment that could be mistaken for a trailing comment of the function declaration when +@@ -192,8 +183,7 @@ + # Regression test for https://github.com/astral-sh/ruff/issues/5176#issuecomment-1598171989 + def foo( + b=3 + 2, # comment +-): +- ... ++): ... + + + # Comments on the slash or the star, both of which don't have a node +@@ -454,8 +444,7 @@ + def f( + # first + # second +-): +- ... ++): ... + + + def f( # first +@@ -475,8 +464,7 @@ + # first + b, + # second +-): +- ... ++): ... + + + def f( # first +@@ -484,8 +472,7 @@ + # second + b, + # third +-): +- ... ++): ... + + + def f( # first +@@ -494,8 +481,7 @@ + # third + b, + # fourth +-): +- ... ++): ... + + + def f( # first +@@ -522,17 +508,14 @@ + a, + # third + /, # second +-): +- ... ++): ... + + + # Walrus operator in return type. +-def this_is_unusual() -> (please := no): +- ... ++def this_is_unusual() -> (please := no): ... + + +-def this_is_unusual(x) -> (please := no): +- ... ++def this_is_unusual(x) -> (please := no): ... + + + # Regression test for: https://github.com/astral-sh/ruff/issues/7465 ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__if.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__if.py.snap index 3b4aac308edf4..cc73bca847797 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__if.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__if.py.snap @@ -25,12 +25,12 @@ else: # 12 trailing else condition if x == y: if y == z: - ... + pass if a == b: - ... + pass else: # trailing comment - ... + pass # trailing else comment @@ -40,11 +40,11 @@ elif aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 2222222222222222222222, 3333333333 ]: - ... + pass else: - ... + pass # Regression test: Don't drop the trailing comment by associating it with the elif # instead of the else. @@ -213,6 +213,31 @@ if True: else: pass +if True: + if True: + pass + else: + pass + # a + + # b + # c + +else: + pass + +if True: + if True: + pass + else: + pass + + # b + # c + +else: + pass + # Regression test for: https://github.com/astral-sh/ruff/issues/7602 if True: @@ -300,12 +325,12 @@ else: # 12 trailing else condition if x == y: if y == z: - ... + pass if a == b: - ... + pass else: # trailing comment - ... + pass # trailing else comment @@ -315,11 +340,11 @@ elif aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 2222222222222222222222, 3333333333, ]: - ... + pass else: - ... + pass # Regression test: Don't drop the trailing comment by associating it with the elif # instead of the else. @@ -385,6 +410,7 @@ else: pass # 3 + if True: print("a") # 1 elif True: @@ -493,6 +519,31 @@ if True: else: pass +if True: + if True: + pass + else: + pass + # a + + # b + # c + +else: + pass + +if True: + if True: + pass + else: + pass + + # b + # c + +else: + pass + # Regression test for: https://github.com/astral-sh/ruff/issues/7602 if True: @@ -503,7 +554,6 @@ if True: # a # b # c - else: pass @@ -515,6 +565,7 @@ if True: # a # c + else: pass @@ -528,7 +579,6 @@ if True: # a # b # c - else: pass diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__import.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__import.py.snap index dd348f8a33967..336ee1db4fd2b 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__import.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__import.py.snap @@ -8,6 +8,15 @@ from a import aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjf from a import aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa, aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa from a import aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa as dfgsdfgsd, aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa as sdkjflsdjlahlfd +# Continuations. +import foo\ + .bar + +from foo\ + .bar import baz + +import tqdm . tqdm + # At the top-level, force one empty line after an import, but allow up to two empty # lines. import os @@ -71,6 +80,17 @@ import os logger = logging.getLogger("FastProject") + +# Regression test for: https://github.com/astral-sh/ruff/issues/7604 +import os +# comment + +# comment + + +# comment +x = 1 + ``` ## Output @@ -87,6 +107,13 @@ from a import ( aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa as sdkjflsdjlahlfd, ) +# Continuations. +import foo.bar + +from foo.bar import baz + +import tqdm.tqdm + # At the top-level, force one empty line after an import, but allow up to two empty # lines. import os @@ -149,6 +176,16 @@ import os logger = logging.getLogger("FastProject") + +# Regression test for: https://github.com/astral-sh/ruff/issues/7604 +import os +# comment + +# comment + + +# comment +x = 1 ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__import_from.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__import_from.py.snap index 6b3942ea0c9ea..af7f8e1fa0e0e 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__import_from.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__import_from.py.snap @@ -41,6 +41,8 @@ from a import \ ( # comment bar, ) + +from tqdm . auto import tqdm ``` ## Output @@ -115,6 +117,8 @@ from a import ( from a import ( # comment bar, ) + +from tqdm.auto import tqdm ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__match.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__match.py.snap index 2ca2c18fa87fe..aaad3203bc943 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__match.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__match.py.snap @@ -212,9 +212,9 @@ match pattern_singleton: case ( True # trailing ): - ... + pass case False: - ... + pass match foo: @@ -412,39 +412,39 @@ match pattern_match_class: case Point2D( # own line ): - ... + pass case ( Point2D # own line () ): - ... + pass case Point2D( # end of line line ): - ... + pass case Point2D( # end of line 0, 0 ): - ... + pass case Point2D(0, 0): - ... + pass case Point2D( ( # end of line # own line 0 ), 0): - ... + pass case Point3D(x=0, y=0, z=000000000000000000000000000000000000000000000000000000000000000000000000000000000): - ... + pass case Bar(0, a=None, b="hello"): - ... + pass case FooBar(# leading # leading @@ -455,7 +455,7 @@ match pattern_match_class: # trailing # trailing ): - ... + pass case A( b # b @@ -487,26 +487,103 @@ match pattern_match_or: # own line 4 c # trailing 5 ): - ... + pass case ( (a) | # trailing ( b ) ): - ... + pass case (a|b|c): - ... + pass case foo | bar | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh: - ... + pass case ( # end of line a | b # own line ): - ... + pass + + +# Single-element tuples. +match pattern: + case (a,): + pass + + case (a, b): + pass + + case (a, b,): + pass + + case a,: + pass + + case a, b: + pass + + case a, b,: + pass + + case (a, # comment + ): + pass + + case (a, b # comment + ): + pass + + case (a, b, # comment + ): + pass + + case ( # comment + a, + ): + pass + + case ( # comment + a, b + ): + pass + + case ( # comment + a, b, + ): + pass + + case ( + # comment + a,): + pass + + case ( + # comment + a, b): + pass + + case ( + # comment + a, b,): + pass + +# Tuple subject. +match n % 3, n % 5: + case 0, 0: + # n is divisible by both 3 and 5 + print("FizzBuzz") + case 0, _: + # n is divisible by 3, but not 5 + print("Fizz") + case _, 0: + # n is divisible by 5, but not 3 + print("Buzz") + case _: + print(n) ``` ## Output @@ -707,9 +784,9 @@ match pattern_singleton: ): pass case True: # trailing - ... + pass case False: - ... + pass match foo: @@ -933,26 +1010,26 @@ match pattern_match_class: case Point2D( # own line ): - ... + pass case ( Point2D # own line () ): - ... + pass case Point2D( # end of line line ): - ... + pass case Point2D( # end of line 0, 0 ): - ... + pass case Point2D(0, 0): - ... + pass case Point2D( ( # end of line @@ -961,17 +1038,17 @@ match pattern_match_class: ), 0, ): - ... + pass case Point3D( x=0, y=0, z=000000000000000000000000000000000000000000000000000000000000000000000000000000000, ): - ... + pass case Bar(0, a=None, b="hello"): - ... + pass case FooBar( # leading # leading @@ -982,7 +1059,7 @@ match pattern_match_class: # trailing # trailing ): - ... + pass case A( # b @@ -1012,7 +1089,7 @@ match pattern_match_or: # own line 4 | c # trailing 5 ): - ... + pass case ( ( @@ -1020,24 +1097,119 @@ match pattern_match_or: ) | (b) ): - ... + pass case a | b | c: - ... + pass case ( foo | bar | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh ): - ... + pass case ( # end of line a | b # own line ): - ... + pass + + +# Single-element tuples. +match pattern: + case (a,): + pass + + case (a, b): + pass + + case ( + a, + b, + ): + pass + + case (a,): + pass + + case a, b: + pass + + case ( + a, + b, + ): + pass + + case ( + a, # comment + ): + pass + + case ( + a, + b, # comment + ): + pass + + case ( + a, + b, # comment + ): + pass + + case ( # comment + a, + ): + pass + + case ( # comment + a, + b, + ): + pass + + case ( # comment + a, + b, + ): + pass + + case ( + # comment + a, + ): + pass + + case ( + # comment + a, + b, + ): + pass + + case ( + # comment + a, + b, + ): + pass + +# Tuple subject. +match n % 3, n % 5: + case 0, 0: + # n is divisible by both 3 and 5 + print("FizzBuzz") + case 0, _: + # n is divisible by 3, but not 5 + print("Fizz") + case _, 0: + # n is divisible by 5, but not 3 + print("Buzz") + case _: + print(n) ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__return_annotation.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__return_annotation.py.snap index 2f8f6b710a718..1f331852019ec 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__return_annotation.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__return_annotation.py.snap @@ -544,4 +544,298 @@ def process_board_action( ``` +## Preview changes +```diff +--- Stable ++++ Preview +@@ -7,8 +7,7 @@ + start: int | None = None, + num: int | None = None, + ) -> ( # type: ignore[override] +-): +- ... ++): ... + + + def zrevrangebylex( +@@ -20,8 +19,7 @@ + num: int | None = None, + ) -> ( # type: ignore[override] + # comment +-): +- ... ++): ... + + + def zrevrangebylex( +@@ -33,8 +31,7 @@ + num: int | None = None, + ) -> ( # type: ignore[override] + 1 +-): +- ... ++): ... + + + def zrevrangebylex( +@@ -47,8 +44,7 @@ + ) -> ( # type: ignore[override] + 1, + 2, +-): +- ... ++): ... + + + def zrevrangebylex( +@@ -60,14 +56,12 @@ + num: int | None = None, + ) -> ( # type: ignore[override] + (1, 2) +-): +- ... ++): ... + + + def handleMatch( # type: ignore[override] # https://github.com/python/mypy/issues/10197 + self, m: Match[str], data: str +-) -> Union[Tuple[None, None, None], Tuple[Element, int, int]]: +- ... ++) -> Union[Tuple[None, None, None], Tuple[Element, int, int]]: ... + + + def double( +@@ -95,50 +89,44 @@ + # function arguments break here with a single argument; we do not.) + def f( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +-) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: +- ... ++) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: ... + + + def f( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, a +-) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: +- ... ++) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: ... + + + def f( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +-) -> a: +- ... ++) -> a: ... + + + def f( + a +-) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: +- ... ++) -> ( ++ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ++): ... + + + def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]() -> ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +-): +- ... ++): ... + + + def f[ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +-]() -> a: +- ... ++]() -> a: ... + + + def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +-) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: +- ... ++) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: ... + + + def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +-) -> a: +- ... ++) -> a: ... + + + # Breaking return type annotations. Black adds parentheses if the parameters are +@@ -147,137 +135,126 @@ + Set[ + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] +-): +- ... ++): ... + + + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( + Set[ + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] +-): +- ... ++): ... + + + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( + Set[ + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] +-): +- ... ++): ... + + + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( + Set[ + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] +-): +- ... ++): ... + + + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( + x + ) -> Set[ + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +-]: +- ... ++]: ... + + + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( + x + ) -> Set[ + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +-]: +- ... ++]: ... + + + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( + *args + ) -> Set[ + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +-]: +- ... ++]: ... + + + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( # foo + ) -> Set[ + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +-]: +- ... ++]: ... + + + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( + # bar + ) -> Set[ + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +-]: +- ... ++]: ... + + + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +-): +- ... ++): ... + + + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +-): +- ... ++): ... + + + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( + x +-) -> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: +- ... ++) -> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: ... + + + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( + x +-) -> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: +- ... ++) -> ( ++ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ++): ... + + +-def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> X + Y + foooooooooooooooooooooooooooooooooooo(): +- ... ++def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( ++ X + Y + foooooooooooooooooooooooooooooooooooo() ++): ... + + +-def xxxxxxxxxxxxxxxxxxxxxxxxxxxx(x) -> X + Y + foooooooooooooooooooooooooooooooooooo(): +- ... ++def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( ++ x ++) -> X + Y + foooooooooooooooooooooooooooooooooooo(): ... + + + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( + X and Y and foooooooooooooooooooooooooooooooooooo() +-): +- ... ++): ... + + + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( + x +-) -> X and Y and foooooooooooooooooooooooooooooooooooo(): +- ... ++) -> X and Y and foooooooooooooooooooooooooooooooooooo(): ... + + +-def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> X | Y | foooooooooooooooooooooooooooooooooooo(): +- ... ++def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( ++ X | Y | foooooooooooooooooooooooooooooooooooo() ++): ... + + +-def xxxxxxxxxxxxxxxxxxxxxxxxxxxx(x) -> X | Y | foooooooooooooooooooooooooooooooooooo(): +- ... ++def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( ++ x ++) -> X | Y | foooooooooooooooooooooooooooooooooooo(): ... + + + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( + X | Y | foooooooooooooooooooooooooooooooooooo() # comment +-): +- ... ++): ... + + + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( + x + ) -> ( + X | Y | foooooooooooooooooooooooooooooooooooo() # comment +-): +- ... ++): ... + + + def double() -> ( +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__top_level.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__top_level.py.snap index 735d40d806f28..7549ab861ed48 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__top_level.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__top_level.py.snap @@ -115,4 +115,57 @@ def quuz(): ``` +## Preview changes +```diff +--- Stable ++++ Preview +@@ -12,25 +12,20 @@ + pass + + +-class Del(expr_context): +- ... ++class Del(expr_context): ... + + +-class Load(expr_context): +- ... ++class Load(expr_context): ... + + + # Some comment. +-class Other(expr_context): +- ... ++class Other(expr_context): ... + + +-class Store(expr_context): +- ... ++class Store(expr_context): ... + + +-class Foo(Bar): +- ... ++class Foo(Bar): ... + + + class Baz(Qux): +@@ -49,12 +44,10 @@ + pass + + +-def bar(): +- ... ++def bar(): ... + + +-def baz(): +- ... ++def baz(): ... + + + def quux(): +``` + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__try.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__try.py.snap index e4fe04e4348cb..8750541e567ff 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__try.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__try.py.snap @@ -5,74 +5,74 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ ## Input ```py try: - ... + pass except: - ... + pass try: - ... + pass except (KeyError): # should remove brackets and be a single line - ... + pass try: # try - ... + pass # end of body # before except except (Exception, ValueError) as exc: # except line - ... + pass # before except 2 except KeyError as key: # except line 2 - ... + pass # in body 2 # before else else: - ... + pass # before finally finally: - ... + pass # with line breaks try: # try - ... + pass # end of body # before except except (Exception, ValueError) as exc: # except line - ... + pass # before except 2 except KeyError as key: # except line 2 - ... + pass # in body 2 # before else else: - ... + pass # before finally finally: - ... + pass # with line breaks try: - ... + pass except: - ... + pass try: - ... + pass except (Exception, Exception, Exception, Exception, Exception, Exception, Exception) as exc: # splits exception over multiple lines - ... + pass try: - ... + pass except: a = 10 # trailing comment1 b = 11 # trailing comment2 @@ -80,21 +80,21 @@ except: # try/except*, mostly the same as try try: # try - ... + pass # end of body # before except except* (Exception, ValueError) as exc: # except line - ... + pass # before except 2 except* KeyError as key: # except line 2 - ... + pass # in body 2 # before else else: - ... + pass # before finally finally: - ... + pass # try and try star are statements with body # Minimized from https://github.com/python/cpython/blob/99b00efd5edfd5b26bf9e2a35cbfc96277fdcbb1/Lib/getpass.py#L68-L91 @@ -177,67 +177,67 @@ finally: ## Output ```py try: - ... + pass except: - ... + pass try: - ... + pass except KeyError: # should remove brackets and be a single line - ... + pass try: # try - ... + pass # end of body # before except except (Exception, ValueError) as exc: # except line - ... + pass # before except 2 except KeyError as key: # except line 2 - ... + pass # in body 2 # before else else: - ... + pass # before finally finally: - ... + pass # with line breaks try: # try - ... + pass # end of body # before except except (Exception, ValueError) as exc: # except line - ... + pass # before except 2 except KeyError as key: # except line 2 - ... + pass # in body 2 # before else else: - ... + pass # before finally finally: - ... + pass # with line breaks try: - ... + pass except: - ... + pass try: - ... + pass except ( Exception, Exception, @@ -247,11 +247,11 @@ except ( Exception, Exception, ) as exc: # splits exception over multiple lines - ... + pass try: - ... + pass except: a = 10 # trailing comment1 b = 11 # trailing comment2 @@ -259,21 +259,21 @@ except: # try/except*, mostly the same as try try: # try - ... + pass # end of body # before except except* (Exception, ValueError) as exc: # except line - ... + pass # before except 2 except* KeyError as key: # except line 2 - ... + pass # in body 2 # before else else: - ... + pass # before finally finally: - ... + pass # try and try star are statements with body # Minimized from https://github.com/python/cpython/blob/99b00efd5edfd5b26bf9e2a35cbfc96277fdcbb1/Lib/getpass.py#L68-L91 @@ -311,6 +311,7 @@ finally: pass # d + try: pass # a except ZeroDivisionError: diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__type_alias.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__type_alias.py.snap index 1009367aa6170..24df936b5a09d 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__type_alias.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__type_alias.py.snap @@ -87,6 +87,10 @@ type type_params_comments[ # trailing open bracket comment D, # trailing comment # leading close bracket comment ] = int # trailing value comment +type type_params_single_comment[ # trailing open bracket comment + A, + B +] = int type type_params_all_kinds[type_var, *type_var_tuple, **param_spec] = int # type variable bounds @@ -201,6 +205,10 @@ type type_params_comments[ # trailing open bracket comment D, # trailing comment # leading close bracket comment ] = int # trailing value comment +type type_params_single_comment[ # trailing open bracket comment + A, + B, +] = int type type_params_all_kinds[type_var, *type_var_tuple, **param_spec] = int # type variable bounds diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__while.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__while.py.snap index 9b09af15dbb59..91f44fa7b9922 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__while.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__while.py.snap @@ -21,7 +21,7 @@ while aVeryLongConditionThatSpillsOverToTheNextLineBecauseItIsExtremelyLongAndGo pass else: - ... + pass while ( some_condition(unformatted, args) and anotherCondition or aThirdCondition @@ -55,7 +55,7 @@ while aVeryLongConditionThatSpillsOverToTheNextLineBecauseItIsExtremelyLongAndGo pass else: - ... + pass while ( some_condition(unformatted, args) and anotherCondition or aThirdCondition diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__with.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__with.py.snap index 1c54019b650d1..145e04e5d4ffe 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__with.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__with.py.snap @@ -5,18 +5,18 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ ## Input ```py with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: - ... + pass # trailing with a, a: # after colon - ... + pass # trailing with ( aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, ): - ... + pass # trailing @@ -25,7 +25,7 @@ with ( , # comma b # c ): # colon - ... + pass with ( @@ -36,7 +36,7 @@ with ( , # comma c # c ): # colon - ... # body + pass # body # body trailing own with ( @@ -48,14 +48,14 @@ with ( with (a,): # magic trailing comma - ... + pass with (a): # should remove brackets - ... + pass with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as c: - ... + pass # currently unparsable by black: https://github.com/psf/black/issues/3678 @@ -66,45 +66,41 @@ with (a, *b): with ( # leading comment - a) as b: ... + a) as b: pass with ( # leading comment a as b -): ... +): pass with ( a as b # trailing comment -): ... +): pass with ( a as ( # leading comment b ) -): ... +): pass with ( a as ( b # trailing comment ) -): ... - -with (a # trailing same line comment - # trailing own line comment - ) as b: ... +): pass with ( a # trailing same line comment # trailing own line comment as b -): ... +): pass with (a # trailing same line comment # trailing own line comment -) as b: ... +) as b: pass with ( (a @@ -112,7 +108,41 @@ with ( ) as # trailing as same line comment b # trailing b same line comment -): ... +): pass + +with ( + # comment + a +): + pass + +with ( + a # comment +): + pass + +with ( + a + # comment +): + pass + +with ( + # comment + a as b +): + pass + +with ( + a as b # comment +): + pass + +with ( + a as b + # comment +): + pass with ( [ @@ -129,7 +159,7 @@ with ( CtxManager2() as example2, CtxManager2() as example2, ): - ... + pass with [ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", @@ -137,7 +167,7 @@ with [ "cccccccccccccccccccccccccccccccccccccccccc", dddddddddddddddddddddddddddddddd, ] as example1, aaaaaaaaaaaaaaaaaaaaaaaaaa * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb * cccccccccccccccccccccccccccc + ddddddddddddddddd as example2, CtxManager222222222222222() as example2: - ... + pass # Comments on open parentheses with ( # comment @@ -145,7 +175,7 @@ with ( # comment CtxManager2() as example2, CtxManager3() as example3, ): - ... + pass with ( # outer comment ( # inner comment @@ -154,25 +184,25 @@ with ( # outer comment CtxManager2() as example2, CtxManager3() as example3, ): - ... + pass with ( # outer comment CtxManager() ) as example: - ... + pass with ( # outer comment CtxManager() ) as example, ( # inner comment CtxManager2() ) as example2: - ... + pass with ( # outer comment CtxManager1(), CtxManager2(), ) as example: - ... + pass with ( # outer comment ( # inner comment @@ -180,7 +210,7 @@ with ( # outer comment ), CtxManager2(), ) as example: - ... + pass # Breaking of with items. with (test # bar @@ -260,23 +290,42 @@ with ( with (foo() as bar, baz() as bop): pass + +if True: + with ( + anyio.CancelScope(shield=True) + if get_running_loop() + else contextlib.nullcontext() + ): + pass + +if True: + with ( + anyio.CancelScope(shield=True) + and B and [aaaaaaaa, bbbbbbbbbbbbb, cccccccccc, dddddddddddd, eeeeeeeeeeeee] + ): + pass + +if True: + with anyio.CancelScope(shield=True) if get_running_loop() else contextlib.nullcontext(): + pass ``` ## Output ```py with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: - ... + pass # trailing with a, a: # after colon - ... + pass # trailing with ( aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, ): - ... + pass # trailing @@ -284,7 +333,7 @@ with ( a, # a # comma b, # c ): # colon - ... + pass with ( @@ -294,27 +343,29 @@ with ( ), # b # comma c, # c ): # colon - ... # body + pass # body # body trailing own -with a as ( # a # as - # own line - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb -): # b +with ( + a as ( # a # as + # own line + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + ) # b +): pass with ( a, ): # magic trailing comma - ... + pass with a: # should remove brackets - ... + pass with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as c: - ... + pass # currently unparsable by black: https://github.com/psf/black/issues/3678 @@ -327,57 +378,87 @@ with ( # leading comment a ) as b: - ... + pass with ( # leading comment a as b ): - ... + pass with ( a as b # trailing comment ): - ... + pass with a as ( # leading comment b ): - ... + pass with a as ( b # trailing comment ): - ... + pass with ( a # trailing same line comment # trailing own line comment ) as b: - ... + pass with ( a # trailing same line comment # trailing own line comment ) as b: - ... + pass with ( - a # trailing same line comment - # trailing own line comment -) as b: - ... + ( + a + # trailing own line comment + ) as ( # trailing as same line comment + b + ) # trailing b same line comment +): + pass with ( + # comment a - # trailing own line comment -) as ( # trailing as same line comment - b -): # trailing b same line comment - ... +): + pass + +with ( + a # comment +): + pass + +with ( + a + # comment +): + pass + +with ( + # comment + a as b +): + pass + +with ( + a as b # comment +): + pass + +with ( + a as b + # comment +): + pass with ( [ @@ -394,7 +475,7 @@ with ( CtxManager2() as example2, CtxManager2() as example2, ): - ... + pass with [ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", @@ -402,7 +483,7 @@ with [ "cccccccccccccccccccccccccccccccccccccccccc", dddddddddddddddddddddddddddddddd, ] as example1, aaaaaaaaaaaaaaaaaaaaaaaaaa * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb * cccccccccccccccccccccccccccc + ddddddddddddddddd as example2, CtxManager222222222222222() as example2: - ... + pass # Comments on open parentheses with ( # comment @@ -410,7 +491,7 @@ with ( # comment CtxManager2() as example2, CtxManager3() as example3, ): - ... + pass with ( # outer comment ( # inner comment @@ -419,25 +500,25 @@ with ( # outer comment CtxManager2() as example2, CtxManager3() as example3, ): - ... + pass with ( # outer comment CtxManager() ) as example: - ... + pass with ( # outer comment CtxManager() ) as example, ( # inner comment CtxManager2() ) as example2: - ... + pass with ( # outer comment CtxManager1(), CtxManager2(), ) as example: - ... + pass with ( # outer comment ( # inner comment @@ -445,7 +526,7 @@ with ( # outer comment ), CtxManager2(), ) as example: - ... + pass # Breaking of with items. with test as ( # bar # foo @@ -508,13 +589,17 @@ with f( ) as b, c as d: pass -with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as b: +with ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +) as b: pass with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as b: pass -with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as b, c as d: +with ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +) as b, c as d: pass with ( @@ -533,6 +618,28 @@ with ( with foo() as bar, baz() as bop: pass + +if True: + with ( + anyio.CancelScope(shield=True) + if get_running_loop() + else contextlib.nullcontext() + ): + pass + +if True: + with ( + anyio.CancelScope(shield=True) + and B + and [aaaaaaaa, bbbbbbbbbbbbb, cccccccccc, dddddddddddd, eeeeeeeeeeeee] + ): + pass + +if True: + with anyio.CancelScope( + shield=True + ) if get_running_loop() else contextlib.nullcontext(): + pass ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@trailing_comments.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@trailing_comments.py.snap index 7e6a4bdc161e4..50c7ab6296719 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@trailing_comments.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@trailing_comments.py.snap @@ -6,6 +6,7 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/trailing_c ```py # Pragma reserved width fixtures i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # noqa: This shouldn't break +i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # NoQA: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # type: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # pyright: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # pylint: This shouldn't break @@ -15,6 +16,7 @@ i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # nocover # Pragma fixtures for non-breaking space (lead by NBSP) i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # noqa: This shouldn't break +i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # NoQA: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # type: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # pyright: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # pylint: This shouldn't break @@ -39,6 +41,7 @@ i = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ```py # Pragma reserved width fixtures i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # noqa: This shouldn't break +i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # NoQA: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # type: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # pyright: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # pylint: This shouldn't break @@ -50,6 +53,7 @@ i = ( # Pragma fixtures for non-breaking space (lead by NBSP) i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # noqa: This shouldn't break +i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # NoQA: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) #  type: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # pyright: This shouldn't break i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # pylint: This shouldn't break diff --git a/crates/ruff_python_formatter/tests/snapshots/format@trivia.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@trivia.py.snap index e9c3d37c5b7b1..e2b329f9ea0e2 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@trivia.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@trivia.py.snap @@ -23,7 +23,7 @@ class Test: c = 30 while a == 10: - ... + print(a) # trailing comment with one line before @@ -32,7 +32,7 @@ while a == 10: d = 40 while b == 20: - ... + print(b) # no empty line before e = 50 # one empty line before @@ -61,7 +61,7 @@ class Test: c = 30 while a == 10: - ... + print(a) # trailing comment with one line before @@ -70,7 +70,7 @@ while a == 10: d = 40 while b == 20: - ... + print(b) # no empty line before e = 50 # one empty line before diff --git a/crates/ruff_python_index/src/comment_ranges.rs b/crates/ruff_python_index/src/comment_ranges.rs index 602446a934c47..e554bb8b00e63 100644 --- a/crates/ruff_python_index/src/comment_ranges.rs +++ b/crates/ruff_python_index/src/comment_ranges.rs @@ -1,6 +1,8 @@ use std::fmt::Debug; -use ruff_python_parser::Tok; +use ruff_python_ast::PySourceType; +use ruff_python_parser::lexer::{lex, LexicalError}; +use ruff_python_parser::{AsMode, Tok}; use ruff_python_trivia::CommentRanges; use ruff_text_size::TextRange; @@ -20,3 +22,22 @@ impl CommentRangesBuilder { CommentRanges::new(self.ranges) } } + +/// Helper method to lex and extract comment ranges +pub fn tokens_and_ranges( + source: &str, + source_type: PySourceType, +) -> Result<(Vec<(Tok, TextRange)>, CommentRanges), LexicalError> { + let mut tokens = Vec::new(); + let mut comment_ranges = CommentRangesBuilder::default(); + + for result in lex(source, source_type.as_mode()) { + let (token, range) = result?; + + comment_ranges.visit_token(&token, range); + tokens.push((token, range)); + } + + let comment_ranges = comment_ranges.finish(); + Ok((tokens, comment_ranges)) +} diff --git a/crates/ruff_python_index/src/fstring_ranges.rs b/crates/ruff_python_index/src/fstring_ranges.rs new file mode 100644 index 0000000000000..bdc31258bb234 --- /dev/null +++ b/crates/ruff_python_index/src/fstring_ranges.rs @@ -0,0 +1,97 @@ +use std::collections::BTreeMap; + +use ruff_python_parser::Tok; +use ruff_text_size::{TextRange, TextSize}; + +/// Stores the ranges of all f-strings in a file sorted by [`TextRange::start`]. +/// There can be multiple overlapping ranges for nested f-strings. +/// +/// Note that the ranges for all unterminated f-strings are not stored. +#[derive(Debug)] +pub struct FStringRanges { + // Mapping from the f-string start location to its range. + raw: BTreeMap, +} + +impl FStringRanges { + /// Return the [`TextRange`] of the innermost f-string at the given offset. + pub fn innermost(&self, offset: TextSize) -> Option { + self.raw + .range(..=offset) + .rev() + .find(|(_, range)| range.contains(offset)) + .map(|(_, range)| *range) + } + + /// Return the [`TextRange`] of the outermost f-string at the given offset. + pub fn outermost(&self, offset: TextSize) -> Option { + // Explanation of the algorithm: + // + // ```python + // # v + // f"normal" f"another" f"first {f"second {f"third"} second"} first" + // # ^^(1)^^^ + // # ^^^^^^^^^^^^(2)^^^^^^^^^^^^ + // # ^^^^^^^^^^^^^^^^^^^^^(3)^^^^^^^^^^^^^^^^^^^^ + // # ^^^(4)^^^^ + // # ^^^(5)^^^ + // ``` + // + // The offset is marked with a `v` and the ranges are numbered in the order + // they are yielded by the iterator in the reverse order. The algorithm + // works as follows: + // 1. Skip all ranges that don't contain the offset (1). + // 2. Take all ranges that contain the offset (2, 3). + // 3. Stop taking ranges when the offset is no longer contained. + // 4. Take the last range that contained the offset (3, the outermost). + self.raw + .range(..=offset) + .rev() + .skip_while(|(_, range)| !range.contains(offset)) + .take_while(|(_, range)| range.contains(offset)) + .last() + .map(|(_, range)| *range) + } + + /// Returns an iterator over all f-string [`TextRange`] sorted by their + /// start location. + /// + /// For nested f-strings, the outermost f-string is yielded first, moving + /// inwards with each iteration. + #[inline] + pub fn values(&self) -> impl Iterator + '_ { + self.raw.values() + } + + /// Returns the number of f-string ranges stored. + #[inline] + pub fn len(&self) -> usize { + self.raw.len() + } +} + +#[derive(Default)] +pub(crate) struct FStringRangesBuilder { + start_locations: Vec, + raw: BTreeMap, +} + +impl FStringRangesBuilder { + pub(crate) fn visit_token(&mut self, token: &Tok, range: TextRange) { + match token { + Tok::FStringStart => { + self.start_locations.push(range.start()); + } + Tok::FStringEnd => { + if let Some(start) = self.start_locations.pop() { + self.raw.insert(start, TextRange::new(start, range.end())); + } + } + _ => {} + } + } + + pub(crate) fn finish(self) -> FStringRanges { + FStringRanges { raw: self.raw } + } +} diff --git a/crates/ruff_python_index/src/indexer.rs b/crates/ruff_python_index/src/indexer.rs index 00add310b65b2..78bf2606b2033 100644 --- a/crates/ruff_python_index/src/indexer.rs +++ b/crates/ruff_python_index/src/indexer.rs @@ -1,25 +1,26 @@ //! Struct used to index source code, to enable efficient lookup of tokens that //! are omitted from the AST (e.g., commented lines). -use crate::CommentRangesBuilder; use ruff_python_ast::Stmt; use ruff_python_parser::lexer::LexResult; -use ruff_python_parser::{StringKind, Tok}; +use ruff_python_parser::Tok; use ruff_python_trivia::{ has_leading_content, has_trailing_content, is_python_whitespace, CommentRanges, }; use ruff_source_file::Locator; use ruff_text_size::{Ranged, TextRange, TextSize}; +use crate::fstring_ranges::{FStringRanges, FStringRangesBuilder}; +use crate::CommentRangesBuilder; + pub struct Indexer { comment_ranges: CommentRanges, /// Stores the start offset of continuation lines. continuation_lines: Vec, - /// The range of all f-string in the source document. The ranges are sorted by their - /// [`TextRange::start`] position in increasing order. No two ranges are overlapping. - f_string_ranges: Vec, + /// The range of all f-string in the source document. + fstring_ranges: FStringRanges, } impl Indexer { @@ -27,8 +28,8 @@ impl Indexer { assert!(TextSize::try_from(locator.contents().len()).is_ok()); let mut comment_ranges_builder = CommentRangesBuilder::default(); + let mut fstring_ranges_builder = FStringRangesBuilder::default(); let mut continuation_lines = Vec::new(); - let mut f_string_ranges = Vec::new(); // Token, end let mut prev_end = TextSize::default(); let mut prev_token: Option<&Tok> = None; @@ -59,18 +60,10 @@ impl Indexer { } comment_ranges_builder.visit_token(tok, *range); + fstring_ranges_builder.visit_token(tok, *range); - match tok { - Tok::Newline | Tok::NonLogicalNewline => { - line_start = range.end(); - } - Tok::String { - kind: StringKind::FString | StringKind::RawFString, - .. - } => { - f_string_ranges.push(*range); - } - _ => {} + if matches!(tok, Tok::Newline | Tok::NonLogicalNewline) { + line_start = range.end(); } prev_token = Some(tok); @@ -79,7 +72,7 @@ impl Indexer { Self { comment_ranges: comment_ranges_builder.finish(), continuation_lines, - f_string_ranges, + fstring_ranges: fstring_ranges_builder.finish(), } } @@ -88,6 +81,11 @@ impl Indexer { &self.comment_ranges } + /// Returns the byte offset ranges of f-strings. + pub const fn fstring_ranges(&self) -> &FStringRanges { + &self.fstring_ranges + } + /// Returns the line start positions of continuations (backslash). pub fn continuation_line_starts(&self) -> &[TextSize] { &self.continuation_lines @@ -99,22 +97,6 @@ impl Indexer { self.continuation_lines.binary_search(&line_start).is_ok() } - /// Return the [`TextRange`] of the f-string containing a given offset. - pub fn f_string_range(&self, offset: TextSize) -> Option { - let Ok(string_range_index) = self.f_string_ranges.binary_search_by(|range| { - if offset < range.start() { - std::cmp::Ordering::Greater - } else if range.contains(offset) { - std::cmp::Ordering::Equal - } else { - std::cmp::Ordering::Less - } - }) else { - return None; - }; - Some(self.f_string_ranges[string_range_index]) - } - /// Returns `true` if a statement or expression includes at least one comment. pub fn has_comments(&self, node: &T, locator: &Locator) -> bool where @@ -250,7 +232,7 @@ mod tests { use ruff_python_parser::lexer::LexResult; use ruff_python_parser::{lexer, Mode}; use ruff_source_file::Locator; - use ruff_text_size::TextSize; + use ruff_text_size::{TextRange, TextSize}; use crate::Indexer; @@ -333,5 +315,203 @@ import os TextSize::from(116) ] ); + + let contents = r" +f'foo { 'str1' \ + 'str2' \ + 'str3' + f'nested { 'str4' + 'str5' \ + 'str6' + }' +}' +" + .trim(); + let lxr: Vec = lexer::lex(contents, Mode::Module).collect(); + let indexer = Indexer::from_tokens(lxr.as_slice(), &Locator::new(contents)); + assert_eq!( + indexer.continuation_line_starts(), + [ + // row 1 + TextSize::new(0), + // row 2 + TextSize::new(17), + // row 5 + TextSize::new(63), + ] + ); + } + + #[test] + fn test_f_string_ranges() { + let contents = r#" +f"normal f-string" +f"start {f"inner {f"another"}"} end" +f"implicit " f"concatenation" +"# + .trim(); + let lxr: Vec = lexer::lex(contents, Mode::Module).collect(); + let indexer = Indexer::from_tokens(lxr.as_slice(), &Locator::new(contents)); + assert_eq!( + indexer + .fstring_ranges() + .values() + .copied() + .collect::>(), + &[ + TextRange::new(TextSize::from(0), TextSize::from(18)), + TextRange::new(TextSize::from(19), TextSize::from(55)), + TextRange::new(TextSize::from(28), TextSize::from(49)), + TextRange::new(TextSize::from(37), TextSize::from(47)), + TextRange::new(TextSize::from(56), TextSize::from(68)), + TextRange::new(TextSize::from(69), TextSize::from(85)), + ] + ); + } + + #[test] + fn test_triple_quoted_f_string_ranges() { + let contents = r#" +f""" +this is one +multiline f-string +""" +f''' +and this is +another +''' +f""" +this is a {f"""nested multiline +f-string"""} +""" +"# + .trim(); + let lxr: Vec = lexer::lex(contents, Mode::Module).collect(); + let indexer = Indexer::from_tokens(lxr.as_slice(), &Locator::new(contents)); + assert_eq!( + indexer + .fstring_ranges() + .values() + .copied() + .collect::>(), + &[ + TextRange::new(TextSize::from(0), TextSize::from(39)), + TextRange::new(TextSize::from(40), TextSize::from(68)), + TextRange::new(TextSize::from(69), TextSize::from(122)), + TextRange::new(TextSize::from(85), TextSize::from(117)), + ] + ); + } + + #[test] + fn test_fstring_innermost_outermost() { + let contents = r#" +f"no nested f-string" + +if True: + f"first {f"second {f"third"} second"} first" + foo = "normal string" + +f"implicit " f"concatenation" + +f"first line { + foo + f"second line {bar}" +} third line" + +f"""this is a +multi-line {f"""nested +f-string"""} +the end""" +"# + .trim(); + let lxr: Vec = lexer::lex(contents, Mode::Module).collect(); + let indexer = Indexer::from_tokens(lxr.as_slice(), &Locator::new(contents)); + + // For reference, the ranges of the f-strings in the above code are as + // follows where the ones inside parentheses are nested f-strings: + // + // [0..21, (36..80, 45..72, 55..63), 108..120, 121..137, (139..198, 164..184), (200..260, 226..248)] + + for (offset, innermost_range, outermost_range) in [ + // Inside a normal f-string + ( + TextSize::new(130), + TextRange::new(TextSize::new(121), TextSize::new(137)), + TextRange::new(TextSize::new(121), TextSize::new(137)), + ), + // Left boundary + ( + TextSize::new(121), + TextRange::new(TextSize::new(121), TextSize::new(137)), + TextRange::new(TextSize::new(121), TextSize::new(137)), + ), + // Right boundary + ( + TextSize::new(136), // End offsets are exclusive + TextRange::new(TextSize::new(121), TextSize::new(137)), + TextRange::new(TextSize::new(121), TextSize::new(137)), + ), + // "first" left + ( + TextSize::new(40), + TextRange::new(TextSize::new(36), TextSize::new(80)), + TextRange::new(TextSize::new(36), TextSize::new(80)), + ), + // "second" left + ( + TextSize::new(50), + TextRange::new(TextSize::new(45), TextSize::new(72)), + TextRange::new(TextSize::new(36), TextSize::new(80)), + ), + // "third" + ( + TextSize::new(60), + TextRange::new(TextSize::new(55), TextSize::new(63)), + TextRange::new(TextSize::new(36), TextSize::new(80)), + ), + // "second" right + ( + TextSize::new(70), + TextRange::new(TextSize::new(45), TextSize::new(72)), + TextRange::new(TextSize::new(36), TextSize::new(80)), + ), + // "first" right + ( + TextSize::new(75), + TextRange::new(TextSize::new(36), TextSize::new(80)), + TextRange::new(TextSize::new(36), TextSize::new(80)), + ), + // Single-quoted f-strings spanning across multiple lines + ( + TextSize::new(160), + TextRange::new(TextSize::new(139), TextSize::new(198)), + TextRange::new(TextSize::new(139), TextSize::new(198)), + ), + ( + TextSize::new(170), + TextRange::new(TextSize::new(164), TextSize::new(184)), + TextRange::new(TextSize::new(139), TextSize::new(198)), + ), + // Multi-line f-strings + ( + TextSize::new(220), + TextRange::new(TextSize::new(200), TextSize::new(260)), + TextRange::new(TextSize::new(200), TextSize::new(260)), + ), + ( + TextSize::new(240), + TextRange::new(TextSize::new(226), TextSize::new(248)), + TextRange::new(TextSize::new(200), TextSize::new(260)), + ), + ] { + assert_eq!( + indexer.fstring_ranges().innermost(offset).unwrap(), + innermost_range + ); + assert_eq!( + indexer.fstring_ranges().outermost(offset).unwrap(), + outermost_range + ); + } } } diff --git a/crates/ruff_python_index/src/lib.rs b/crates/ruff_python_index/src/lib.rs index 2e585ca5df0e1..f2c22a77bf119 100644 --- a/crates/ruff_python_index/src/lib.rs +++ b/crates/ruff_python_index/src/lib.rs @@ -1,5 +1,6 @@ mod comment_ranges; +mod fstring_ranges; mod indexer; -pub use comment_ranges::CommentRangesBuilder; +pub use comment_ranges::{tokens_and_ranges, CommentRangesBuilder}; pub use indexer::Indexer; diff --git a/crates/ruff_python_literal/Cargo.toml b/crates/ruff_python_literal/Cargo.toml index fd6a8dc439347..bce3c89a37562 100644 --- a/crates/ruff_python_literal/Cargo.toml +++ b/crates/ruff_python_literal/Cargo.toml @@ -17,7 +17,6 @@ hexf-parse = "0.2.1" is-macro.workspace = true itertools = { workspace = true } lexical-parse-float = { version = "0.8.0", features = ["format"] } -num-traits = { workspace = true } unic-ucd-category = "0.9" [dev-dependencies] diff --git a/crates/ruff_python_literal/src/float.rs b/crates/ruff_python_literal/src/float.rs index 763d652445cc1..7e35363d56b32 100644 --- a/crates/ruff_python_literal/src/float.rs +++ b/crates/ruff_python_literal/src/float.rs @@ -1,7 +1,7 @@ -use crate::Case; -use num_traits::{Float, Zero}; use std::f64; +use crate::Case; + pub fn parse_str(literal: &str) -> Option { parse_inner(literal.trim().as_bytes()) } @@ -244,46 +244,6 @@ pub fn from_hex(s: &str) -> Option { } } -pub fn to_hex(value: f64) -> String { - let (mantissa, exponent, sign) = value.integer_decode(); - let sign_fmt = if sign < 0 { "-" } else { "" }; - match value { - value if value.is_zero() => format!("{sign_fmt}0x0.0p+0"), - value if value.is_infinite() => format!("{sign_fmt}inf"), - value if value.is_nan() => "nan".to_owned(), - _ => { - const BITS: i16 = 52; - const FRACT_MASK: u64 = 0xf_ffff_ffff_ffff; - format!( - "{}{:#x}.{:013x}p{:+}", - sign_fmt, - mantissa >> BITS, - mantissa & FRACT_MASK, - exponent + BITS - ) - } - } -} - -#[test] -#[allow(clippy::float_cmp)] -fn test_to_hex() { - use rand::Rng; - for _ in 0..20000 { - let bytes = rand::thread_rng().gen::<[u64; 1]>(); - let f = f64::from_bits(bytes[0]); - if !f.is_finite() { - continue; - } - let hex = to_hex(f); - // println!("{} -> {}", f, hex); - let roundtrip = hexf_parse::parse_hexf64(&hex, false).unwrap(); - // println!(" -> {}", roundtrip); - - assert_eq!(f, roundtrip, "{f} {hex} {roundtrip}"); - } -} - #[test] fn test_remove_trailing_zeros() { assert!(remove_trailing_zeros(String::from("100")) == *"1"); diff --git a/crates/ruff_python_parser/Cargo.toml b/crates/ruff_python_parser/Cargo.toml index a4bb8f6c500a8..46a97eabd43c5 100644 --- a/crates/ruff_python_parser/Cargo.toml +++ b/crates/ruff_python_parser/Cargo.toml @@ -18,13 +18,13 @@ ruff_python_ast = { path = "../ruff_python_ast" } ruff_text_size = { path = "../ruff_text_size" } anyhow = { workspace = true } +bitflags = { workspace = true } is-macro = { workspace = true } itertools = { workspace = true } lalrpop-util = { version = "0.20.0", default-features = false } -num-bigint = { workspace = true } -num-traits = { workspace = true } +memchr = { workspace = true } unicode-ident = { workspace = true } -unicode_names2 = { version = "0.6.0", git = "https://github.com/youknowone/unicode_names2.git", rev = "4ce16aa85cbcdd9cc830410f1a72ef9a235f2fde" } +unicode_names2 = { workspace = true } rustc-hash = { workspace = true } static_assertions = "1.1.0" diff --git a/crates/ruff_python_parser/src/lexer.rs b/crates/ruff_python_parser/src/lexer.rs index a8e6833b301cc..b4f3436d5aeab 100644 --- a/crates/ruff_python_parser/src/lexer.rs +++ b/crates/ruff_python_parser/src/lexer.rs @@ -31,13 +31,13 @@ use std::iter::FusedIterator; use std::{char, cmp::Ordering, str::FromStr}; -use num_bigint::BigInt; -use num_traits::{Num, Zero}; -use ruff_python_ast::IpyEscapeKind; -use ruff_text_size::{TextLen, TextRange, TextSize}; use unicode_ident::{is_xid_continue, is_xid_start}; +use ruff_python_ast::{Int, IpyEscapeKind}; +use ruff_text_size::{TextLen, TextRange, TextSize}; + use crate::lexer::cursor::{Cursor, EOF_CHAR}; +use crate::lexer::fstring::{FStringContext, FStringContextFlags, FStrings}; use crate::lexer::indentation::{Indentation, Indentations}; use crate::{ soft_keywords::SoftKeywordTransformer, @@ -47,6 +47,7 @@ use crate::{ }; mod cursor; +mod fstring; mod indentation; /// A lexer for Python source code. @@ -63,6 +64,8 @@ pub struct Lexer<'source> { pending_indentation: Option, // Lexer mode. mode: Mode, + // F-string contexts. + fstrings: FStrings, } /// Contains a Token along with its `range`. @@ -155,6 +158,7 @@ impl<'source> Lexer<'source> { source: input, cursor: Cursor::new(input), mode, + fstrings: FStrings::default(), }; // TODO: Handle possible mismatch between BOM and explicit encoding declaration. // spell-checker:ignore feff @@ -166,16 +170,24 @@ impl<'source> Lexer<'source> { /// Lex an identifier. Also used for keywords and string/bytes literals with a prefix. fn lex_identifier(&mut self, first: char) -> Result { // Detect potential string like rb'' b'' f'' u'' r'' - match self.cursor.first() { - quote @ ('\'' | '"') => { + match (first, self.cursor.first()) { + ('f' | 'F', quote @ ('\'' | '"')) => { + self.cursor.bump(); + return Ok(self.lex_fstring_start(quote, false)); + } + ('r' | 'R', 'f' | 'F') | ('f' | 'F', 'r' | 'R') if is_quote(self.cursor.second()) => { + self.cursor.bump(); + let quote = self.cursor.bump().unwrap(); + return Ok(self.lex_fstring_start(quote, true)); + } + (_, quote @ ('\'' | '"')) => { if let Ok(string_kind) = StringKind::try_from(first) { self.cursor.bump(); return self.lex_string(string_kind, quote); } } - second @ ('f' | 'F' | 'r' | 'R' | 'b' | 'B') if is_quote(self.cursor.second()) => { + (_, second @ ('r' | 'R' | 'b' | 'B')) if is_quote(self.cursor.second()) => { self.cursor.bump(); - if let Ok(string_kind) = StringKind::try_from([first, second]) { let quote = self.cursor.bump().unwrap(); return self.lex_string(string_kind, quote); @@ -262,13 +274,22 @@ impl<'source> Lexer<'source> { 'x' | 'o' | 'b' )); + // Lex the portion of the token after the base prefix (e.g., `9D5` in `0x9D5`). let mut number = LexedText::new(self.offset(), self.source); self.radix_run(&mut number, radix); - let value = - BigInt::from_str_radix(number.as_str(), radix.as_u32()).map_err(|e| LexicalError { - error: LexicalErrorType::OtherError(format!("{e:?}")), - location: self.token_range().start(), - })?; + + // Extract the entire number, including the base prefix (e.g., `0x9D5`). + let token = &self.source[self.token_range()]; + + let value = match Int::from_str_radix(number.as_str(), radix.as_u32(), token) { + Ok(int) => int, + Err(err) => { + return Err(LexicalError { + error: LexicalErrorType::OtherError(format!("{err:?}")), + location: self.token_range().start(), + }); + } + }; Ok(Tok::Int { value }) } @@ -339,14 +360,24 @@ impl<'source> Lexer<'source> { let imag = f64::from_str(number.as_str()).unwrap(); Ok(Tok::Complex { real: 0.0, imag }) } else { - let value = number.as_str().parse::().unwrap(); - if start_is_zero && !value.is_zero() { - // leading zeros in decimal integer literals are not permitted - return Err(LexicalError { - error: LexicalErrorType::OtherError("Invalid Token".to_owned()), - location: self.token_range().start(), - }); - } + let value = match Int::from_str(number.as_str()) { + Ok(value) => { + if start_is_zero && value.as_u8() != Some(0) { + // Leading zeros in decimal integer literals are not permitted. + return Err(LexicalError { + error: LexicalErrorType::OtherError("Invalid Token".to_owned()), + location: self.token_range().start(), + }); + } + value + } + Err(err) => { + return Err(LexicalError { + error: LexicalErrorType::OtherError(format!("{err:?}")), + location: self.token_range().start(), + }) + } + }; Ok(Tok::Int { value }) } } @@ -376,7 +407,9 @@ impl<'source> Lexer<'source> { #[cfg(debug_assertions)] debug_assert_eq!(self.cursor.previous(), '#'); - self.cursor.eat_while(|c| !matches!(c, '\n' | '\r')); + let bytes = self.cursor.rest().as_bytes(); + let offset = memchr::memchr2(b'\n', b'\r', bytes).unwrap_or(bytes.len()); + self.cursor.skip_bytes(offset); Tok::Comment(self.token_text().to_string()) } @@ -491,6 +524,160 @@ impl<'source> Lexer<'source> { } } + /// Lex a f-string start token. + fn lex_fstring_start(&mut self, quote: char, is_raw_string: bool) -> Tok { + #[cfg(debug_assertions)] + debug_assert_eq!(self.cursor.previous(), quote); + + let mut flags = FStringContextFlags::empty(); + if quote == '"' { + flags |= FStringContextFlags::DOUBLE; + } + if is_raw_string { + flags |= FStringContextFlags::RAW; + } + if self.cursor.eat_char2(quote, quote) { + flags |= FStringContextFlags::TRIPLE; + } + + self.fstrings.push(FStringContext::new(flags, self.nesting)); + Tok::FStringStart + } + + /// Lex a f-string middle or end token. + fn lex_fstring_middle_or_end(&mut self) -> Result, LexicalError> { + // SAFETY: Safe because the function is only called when `self.fstrings` is not empty. + let fstring = self.fstrings.current().unwrap(); + self.cursor.start_token(); + + // Check if we're at the end of the f-string. + if fstring.is_triple_quoted() { + let quote_char = fstring.quote_char(); + if self.cursor.eat_char3(quote_char, quote_char, quote_char) { + return Ok(Some(Tok::FStringEnd)); + } + } else if self.cursor.eat_char(fstring.quote_char()) { + return Ok(Some(Tok::FStringEnd)); + } + + // We have to decode `{{` and `}}` into `{` and `}` respectively. As an + // optimization, we only allocate a new string we find any escaped curly braces, + // otherwise this string will remain empty and we'll use a source slice instead. + let mut normalized = String::new(); + + // Tracks the last offset of token value that has been written to `normalized`. + let mut last_offset = self.offset(); + + // This isn't going to change for the duration of the loop. + let in_format_spec = fstring.is_in_format_spec(self.nesting); + + let mut in_named_unicode = false; + + loop { + match self.cursor.first() { + // The condition is to differentiate between the `NUL` (`\0`) character + // in the source code and the one returned by `self.cursor.first()` when + // we reach the end of the source code. + EOF_CHAR if self.cursor.is_eof() => { + let error = if fstring.is_triple_quoted() { + FStringErrorType::UnterminatedTripleQuotedString + } else { + FStringErrorType::UnterminatedString + }; + return Err(LexicalError { + error: LexicalErrorType::FStringError(error), + location: self.offset(), + }); + } + '\n' | '\r' if !fstring.is_triple_quoted() => { + // If we encounter a newline while we're in a format spec, then + // we stop here and let the lexer emit the newline token. + // + // Relevant discussion: https://github.com/python/cpython/issues/110259 + if in_format_spec { + break; + } + return Err(LexicalError { + error: LexicalErrorType::FStringError(FStringErrorType::UnterminatedString), + location: self.offset(), + }); + } + '\\' => { + self.cursor.bump(); // '\' + if matches!(self.cursor.first(), '{' | '}') { + // Don't consume `{` or `}` as we want them to be emitted as tokens. + // They will be handled in the next iteration. + continue; + } else if !fstring.is_raw_string() { + if self.cursor.eat_char2('N', '{') { + in_named_unicode = true; + continue; + } + } + // Consume the escaped character. + if self.cursor.eat_char('\r') { + self.cursor.eat_char('\n'); + } else { + self.cursor.bump(); + } + } + quote @ ('\'' | '"') if quote == fstring.quote_char() => { + if let Some(triple_quotes) = fstring.triple_quotes() { + if self.cursor.rest().starts_with(triple_quotes) { + break; + } + self.cursor.bump(); + } else { + break; + } + } + '{' => { + if self.cursor.second() == '{' && !in_format_spec { + self.cursor.bump(); + normalized + .push_str(&self.source[TextRange::new(last_offset, self.offset())]); + self.cursor.bump(); // Skip the second `{` + last_offset = self.offset(); + } else { + break; + } + } + '}' => { + if in_named_unicode { + in_named_unicode = false; + self.cursor.bump(); + } else if self.cursor.second() == '}' && !in_format_spec { + self.cursor.bump(); + normalized + .push_str(&self.source[TextRange::new(last_offset, self.offset())]); + self.cursor.bump(); // Skip the second `}` + last_offset = self.offset(); + } else { + break; + } + } + _ => { + self.cursor.bump(); + } + } + } + let range = self.token_range(); + if range.is_empty() { + return Ok(None); + } + + let value = if normalized.is_empty() { + self.source[range].to_string() + } else { + normalized.push_str(&self.source[TextRange::new(last_offset, self.offset())]); + normalized + }; + Ok(Some(Tok::FStringMiddle { + value, + is_raw: fstring.is_raw_string(), + })) + } + /// Lex a string literal. fn lex_string(&mut self, kind: StringKind, quote: char) -> Result { #[cfg(debug_assertions)] @@ -512,6 +699,19 @@ impl<'source> Lexer<'source> { } } Some('\r' | '\n') if !triple_quoted => { + if let Some(fstring) = self.fstrings.current() { + // When we are in an f-string, check whether does the initial quote + // matches with f-strings quotes and if it is, then this must be a + // missing '}' token so raise the proper error. + if fstring.quote_char() == quote && !fstring.is_triple_quoted() { + return Err(LexicalError { + error: LexicalErrorType::FStringError( + FStringErrorType::UnclosedLbrace, + ), + location: self.offset() - fstring.quote_size(), + }); + } + } return Err(LexicalError { error: LexicalErrorType::OtherError( "EOL while scanning string literal".to_owned(), @@ -531,6 +731,21 @@ impl<'source> Lexer<'source> { Some(_) => {} None => { + if let Some(fstring) = self.fstrings.current() { + // When we are in an f-string, check whether does the initial quote + // matches with f-strings quotes and if it is, then this must be a + // missing '}' token so raise the proper error. + if fstring.quote_char() == quote + && fstring.is_triple_quoted() == triple_quoted + { + return Err(LexicalError { + error: LexicalErrorType::FStringError( + FStringErrorType::UnclosedLbrace, + ), + location: self.offset() - fstring.quote_size(), + }); + } + } return Err(LexicalError { error: if triple_quoted { LexicalErrorType::Eof @@ -554,8 +769,28 @@ impl<'source> Lexer<'source> { // This is the main entry point. Call this function to retrieve the next token. // This function is used by the iterator implementation. pub fn next_token(&mut self) -> LexResult { + if let Some(fstring) = self.fstrings.current() { + if !fstring.is_in_expression(self.nesting) { + match self.lex_fstring_middle_or_end() { + Ok(Some(tok)) => { + if tok == Tok::FStringEnd { + self.fstrings.pop(); + } + return Ok((tok, self.token_range())); + } + Err(e) => { + // This is to prevent an infinite loop in which the lexer + // continuously returns an error token because the f-string + // remains on the stack. + self.fstrings.pop(); + return Err(e); + } + _ => {} + } + } + } // Return dedent tokens until the current indentation level matches the indentation of the next token. - if let Some(indentation) = self.pending_indentation.take() { + else if let Some(indentation) = self.pending_indentation.take() { match self.indentations.current().try_compare(indentation) { Ok(Ordering::Greater) => { self.pending_indentation = Some(indentation); @@ -876,10 +1111,7 @@ impl<'source> Lexer<'source> { if self.cursor.eat_char('=') { Tok::NotEqual } else { - return Err(LexicalError { - error: LexicalErrorType::UnrecognizedToken { tok: '!' }, - location: self.token_start(), - }); + Tok::Exclamation } } '~' => Tok::Tilde, @@ -904,11 +1136,26 @@ impl<'source> Lexer<'source> { Tok::Lbrace } '}' => { + if let Some(fstring) = self.fstrings.current_mut() { + if fstring.nesting() == self.nesting { + return Err(LexicalError { + error: LexicalErrorType::FStringError(FStringErrorType::SingleRbrace), + location: self.token_start(), + }); + } + fstring.try_end_format_spec(self.nesting); + } self.nesting = self.nesting.saturating_sub(1); Tok::Rbrace } ':' => { - if self.cursor.eat_char('=') { + if self + .fstrings + .current_mut() + .is_some_and(|fstring| fstring.try_start_format_spec(self.nesting)) + { + Tok::Colon + } else if self.cursor.eat_char('=') { Tok::ColonEqual } else { Tok::Colon @@ -957,6 +1204,9 @@ impl<'source> Lexer<'source> { self.state = State::AfterNewline; Tok::Newline } else { + if let Some(fstring) = self.fstrings.current_mut() { + fstring.try_end_format_spec(self.nesting); + } Tok::NonLogicalNewline }, self.token_range(), @@ -970,6 +1220,9 @@ impl<'source> Lexer<'source> { self.state = State::AfterNewline; Tok::Newline } else { + if let Some(fstring) = self.fstrings.current_mut() { + fstring.try_end_format_spec(self.nesting); + } Tok::NonLogicalNewline }, self.token_range(), @@ -1448,10 +1701,30 @@ def f(arg=%timeit a = b): #[test] fn test_numbers() { - let source = "0x2f 0o12 0b1101 0 123 123_45_67_890 0.2 1e+2 2.1e3 2j 2.2j"; + let source = + "0x2f 0o12 0b1101 0 123 123_45_67_890 0.2 1e+2 2.1e3 2j 2.2j 000 0x995DC9BBDF1939FA"; assert_debug_snapshot!(lex_source(source)); } + #[test] + fn test_invalid_leading_zero_small() { + let source = "025"; + + let lexer = lex(source, Mode::Module); + let tokens = lexer.collect::, LexicalError>>(); + assert_debug_snapshot!(tokens); + } + + #[test] + fn test_invalid_leading_zero_big() { + let source = + "0252222222222222522222222222225222222222222252222222222222522222222222225222222222222"; + + let lexer = lex(source, Mode::Module); + let tokens = lexer.collect::, LexicalError>>(); + assert_debug_snapshot!(tokens); + } + #[test] fn test_line_comment_long() { let source = "99232 # foo".to_string(); @@ -1705,4 +1978,234 @@ def f(arg=%timeit a = b): .collect(); assert_debug_snapshot!(tokens); } + + #[test] + fn test_empty_fstrings() { + let source = r#"f"" "" F"" f'' '' f"""""" f''''''"#; + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring_prefix() { + let source = r#"f"" F"" rf"" rF"" Rf"" RF"" fr"" Fr"" fR"" FR"""#; + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring() { + let source = r#"f"normal {foo} {{another}} {bar} {{{three}}}""#; + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring_parentheses() { + let source = r#"f"{}" f"{{}}" f" {}" f"{{{}}}" f"{{{{}}}}" f" {} {{}} {{{}}} {{{{}}}} ""#; + assert_debug_snapshot!(lex_source(source)); + } + + fn fstring_single_quote_escape_eol(eol: &str) -> Vec { + let source = format!(r"f'text \{eol} more text'"); + lex_source(&source) + } + + #[test] + fn test_fstring_single_quote_escape_unix_eol() { + assert_debug_snapshot!(fstring_single_quote_escape_eol(UNIX_EOL)); + } + + #[test] + fn test_fstring_single_quote_escape_mac_eol() { + assert_debug_snapshot!(fstring_single_quote_escape_eol(MAC_EOL)); + } + + #[test] + fn test_fstring_single_quote_escape_windows_eol() { + assert_debug_snapshot!(fstring_single_quote_escape_eol(WINDOWS_EOL)); + } + + #[test] + fn test_fstring_escape() { + let source = r#"f"\{x:\"\{x}} \"\"\ + end""#; + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring_escape_braces() { + let source = r"f'\{foo}' f'\\{foo}' f'\{{foo}}' f'\\{{foo}}'"; + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring_escape_raw() { + let source = r#"rf"\{x:\"\{x}} \"\"\ + end""#; + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring_named_unicode() { + let source = r#"f"\N{BULLET} normal \Nope \N""#; + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring_named_unicode_raw() { + let source = r#"rf"\N{BULLET} normal""#; + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring_with_named_expression() { + let source = r#"f"{x:=10} {(x:=10)} {x,{y:=10}} {[x:=10]}""#; + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring_with_format_spec() { + let source = r#"f"{foo:} {x=!s:.3f} {x:.{y}f} {'':*^{1:{1}}} {x:{{1}.pop()}}""#; + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring_with_multiline_format_spec() { + // The last f-string is invalid syntactically but we should still lex it. + // Note that the `b` is a `Name` token and not a `FStringMiddle` token. + let source = r"f'''__{ + x:d +}__''' +f'''__{ + x:a + b + c +}__''' +f'__{ + x:d +}__' +f'__{ + x:a + b +}__' +"; + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring_conversion() { + let source = r#"f"{x!s} {x=!r} {x:.3f!r} {{x!r}}""#; + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring_nested() { + let source = r#"f"foo {f"bar {x + f"{wow}"}"} baz" f'foo {f'bar'} some {f"another"}'"#; + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring_expression_multiline() { + let source = r#"f"first { + x + * + y +} second""#; + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring_multiline() { + let source = r#"f""" +hello + world +""" f''' + world +hello +''' f"some {f"""multiline +allowed {x}"""} string""#; + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring_comments() { + let source = r#"f""" +# not a comment { # comment { + x +} # not a comment +""""#; + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring_with_ipy_escape_command() { + let source = r#"f"foo {!pwd} bar""#; + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring_with_lambda_expression() { + let source = r#" +f"{lambda x:{x}}" +f"{(lambda x:{x})}" +"# + .trim(); + assert_debug_snapshot!(lex_source(source)); + } + + #[test] + fn test_fstring_with_nul_char() { + let source = r"f'\0'"; + assert_debug_snapshot!(lex_source(source)); + } + + fn lex_fstring_error(source: &str) -> FStringErrorType { + match lex(source, Mode::Module).find_map(std::result::Result::err) { + Some(err) => match err.error { + LexicalErrorType::FStringError(error) => error, + _ => panic!("Expected FStringError: {err:?}"), + }, + _ => panic!("Expected atleast one FStringError"), + } + } + + #[test] + fn test_fstring_error() { + use FStringErrorType::{ + SingleRbrace, UnclosedLbrace, UnterminatedString, UnterminatedTripleQuotedString, + }; + + assert_eq!(lex_fstring_error("f'}'"), SingleRbrace); + assert_eq!(lex_fstring_error("f'{{}'"), SingleRbrace); + assert_eq!(lex_fstring_error("f'{{}}}'"), SingleRbrace); + assert_eq!(lex_fstring_error("f'foo}'"), SingleRbrace); + assert_eq!(lex_fstring_error(r"f'\u007b}'"), SingleRbrace); + assert_eq!(lex_fstring_error("f'{a:b}}'"), SingleRbrace); + assert_eq!(lex_fstring_error("f'{3:}}>10}'"), SingleRbrace); + assert_eq!(lex_fstring_error(r"f'\{foo}\}'"), SingleRbrace); + + assert_eq!(lex_fstring_error("f'{'"), UnclosedLbrace); + assert_eq!(lex_fstring_error("f'{foo!r'"), UnclosedLbrace); + assert_eq!(lex_fstring_error("f'{foo='"), UnclosedLbrace); + assert_eq!( + lex_fstring_error( + r#"f"{" +"# + ), + UnclosedLbrace + ); + assert_eq!(lex_fstring_error(r#"f"""{""""#), UnclosedLbrace); + + assert_eq!(lex_fstring_error(r#"f""#), UnterminatedString); + assert_eq!(lex_fstring_error(r#"f'"#), UnterminatedString); + + assert_eq!(lex_fstring_error(r#"f""""#), UnterminatedTripleQuotedString); + assert_eq!(lex_fstring_error(r#"f'''"#), UnterminatedTripleQuotedString); + assert_eq!( + lex_fstring_error(r#"f"""""#), + UnterminatedTripleQuotedString + ); + assert_eq!( + lex_fstring_error(r#"f""""""#), + UnterminatedTripleQuotedString + ); + } } diff --git a/crates/ruff_python_parser/src/lexer/cursor.rs b/crates/ruff_python_parser/src/lexer/cursor.rs index ed5011a1d8507..91c7d30c53b05 100644 --- a/crates/ruff_python_parser/src/lexer/cursor.rs +++ b/crates/ruff_python_parser/src/lexer/cursor.rs @@ -96,6 +96,18 @@ impl<'a> Cursor<'a> { } } + pub(super) fn eat_char3(&mut self, c1: char, c2: char, c3: char) -> bool { + let mut chars = self.chars.clone(); + if chars.next() == Some(c1) && chars.next() == Some(c2) && chars.next() == Some(c3) { + self.bump(); + self.bump(); + self.bump(); + true + } else { + false + } + } + pub(super) fn eat_if(&mut self, mut predicate: F) -> Option where F: FnMut(char) -> bool, @@ -115,4 +127,21 @@ impl<'a> Cursor<'a> { self.bump(); } } + + /// Skips the next `count` bytes. + /// + /// ## Panics + /// - If `count` is larger than the remaining bytes in the input stream. + /// - If `count` indexes into a multi-byte character. + pub(super) fn skip_bytes(&mut self, count: usize) { + #[cfg(debug_assertions)] + { + self.prev_char = self.chars.as_str()[..count] + .chars() + .next_back() + .unwrap_or('\0'); + } + + self.chars = self.chars.as_str()[count..].chars(); + } } diff --git a/crates/ruff_python_parser/src/lexer/fstring.rs b/crates/ruff_python_parser/src/lexer/fstring.rs new file mode 100644 index 0000000000000..8acf00d52c9c1 --- /dev/null +++ b/crates/ruff_python_parser/src/lexer/fstring.rs @@ -0,0 +1,161 @@ +use bitflags::bitflags; + +use ruff_text_size::TextSize; + +bitflags! { + #[derive(Debug)] + pub(crate) struct FStringContextFlags: u8 { + /// The current f-string is a triple-quoted f-string i.e., the number of + /// opening quotes is 3. If this flag is not set, the number of opening + /// quotes is 1. + const TRIPLE = 1 << 0; + + /// The current f-string is a double-quoted f-string. If this flag is not + /// set, the current f-string is a single-quoted f-string. + const DOUBLE = 1 << 1; + + /// The current f-string is a raw f-string i.e., prefixed with `r`/`R`. + /// If this flag is not set, the current f-string is a normal f-string. + const RAW = 1 << 2; + } +} + +/// The context representing the current f-string that the lexer is in. +#[derive(Debug)] +pub(crate) struct FStringContext { + flags: FStringContextFlags, + + /// The level of nesting for the lexer when it entered the current f-string. + /// The nesting level includes all kinds of parentheses i.e., round, square, + /// and curly. + nesting: u32, + + /// The current depth of format spec for the current f-string. This is because + /// there can be multiple format specs nested for the same f-string. + /// For example, `{a:{b:{c}}}` has 3 format specs. + format_spec_depth: u32, +} + +impl FStringContext { + pub(crate) const fn new(flags: FStringContextFlags, nesting: u32) -> Self { + Self { + flags, + nesting, + format_spec_depth: 0, + } + } + + pub(crate) const fn nesting(&self) -> u32 { + self.nesting + } + + /// Returns the quote character for the current f-string. + pub(crate) const fn quote_char(&self) -> char { + if self.flags.contains(FStringContextFlags::DOUBLE) { + '"' + } else { + '\'' + } + } + + /// Returns the number of quotes for the current f-string. + pub(crate) const fn quote_size(&self) -> TextSize { + if self.is_triple_quoted() { + TextSize::new(3) + } else { + TextSize::new(1) + } + } + + /// Returns the triple quotes for the current f-string if it is a triple-quoted + /// f-string, `None` otherwise. + pub(crate) const fn triple_quotes(&self) -> Option<&'static str> { + if self.is_triple_quoted() { + if self.flags.contains(FStringContextFlags::DOUBLE) { + Some(r#"""""#) + } else { + Some("'''") + } + } else { + None + } + } + + /// Returns `true` if the current f-string is a raw f-string. + pub(crate) const fn is_raw_string(&self) -> bool { + self.flags.contains(FStringContextFlags::RAW) + } + + /// Returns `true` if the current f-string is a triple-quoted f-string. + pub(crate) const fn is_triple_quoted(&self) -> bool { + self.flags.contains(FStringContextFlags::TRIPLE) + } + + /// Calculates the number of open parentheses for the current f-string + /// based on the current level of nesting for the lexer. + const fn open_parentheses_count(&self, current_nesting: u32) -> u32 { + current_nesting.saturating_sub(self.nesting) + } + + /// Returns `true` if the lexer is in a f-string expression i.e., between + /// two curly braces. + pub(crate) const fn is_in_expression(&self, current_nesting: u32) -> bool { + self.open_parentheses_count(current_nesting) > self.format_spec_depth + } + + /// Returns `true` if the lexer is in a f-string format spec i.e., after a colon. + pub(crate) const fn is_in_format_spec(&self, current_nesting: u32) -> bool { + self.format_spec_depth > 0 && !self.is_in_expression(current_nesting) + } + + /// Returns `true` if the context is in a valid position to start format spec + /// i.e., at the same level of nesting as the opening parentheses token. + /// Increments the format spec depth if it is. + /// + /// This assumes that the current character for the lexer is a colon (`:`). + pub(crate) fn try_start_format_spec(&mut self, current_nesting: u32) -> bool { + if self + .open_parentheses_count(current_nesting) + .saturating_sub(self.format_spec_depth) + == 1 + { + self.format_spec_depth += 1; + true + } else { + false + } + } + + /// Decrements the format spec depth if the current f-string is in a format + /// spec. + pub(crate) fn try_end_format_spec(&mut self, current_nesting: u32) { + if self.is_in_format_spec(current_nesting) { + self.format_spec_depth = self.format_spec_depth.saturating_sub(1); + } + } +} + +/// The f-strings stack is used to keep track of all the f-strings that the +/// lexer encounters. This is necessary because f-strings can be nested. +#[derive(Debug, Default)] +pub(crate) struct FStrings { + stack: Vec, +} + +impl FStrings { + pub(crate) fn push(&mut self, context: FStringContext) { + self.stack.push(context); + } + + pub(crate) fn pop(&mut self) -> Option { + self.stack.pop() + } + + pub(crate) fn current(&self) -> Option<&FStringContext> { + self.stack.last() + } + + pub(crate) fn current_mut(&mut self) -> Option<&mut FStringContext> { + self.stack.last_mut() + } +} diff --git a/crates/ruff_python_parser/src/lib.rs b/crates/ruff_python_parser/src/lib.rs index a8262848d09dc..28ff5229c1208 100644 --- a/crates/ruff_python_parser/src/lib.rs +++ b/crates/ruff_python_parser/src/lib.rs @@ -85,7 +85,7 @@ //! return bool(i & 1) //! "#; //! let tokens = lex(python_source, Mode::Module); -//! let ast = parse_tokens(tokens, Mode::Module, ""); +//! let ast = parse_tokens(tokens, python_source, Mode::Module, ""); //! //! assert!(ast.is_ok()); //! ``` @@ -110,8 +110,8 @@ //! [lexer]: crate::lexer pub use parser::{ - parse, parse_expression, parse_expression_starts_at, parse_program, parse_starts_at, - parse_suite, parse_tokens, ParseError, ParseErrorType, + parse, parse_expression, parse_expression_starts_at, parse_ok_tokens, parse_program, + parse_starts_at, parse_suite, parse_tokens, ParseError, ParseErrorType, }; use ruff_python_ast::{CmpOp, Expr, Mod, PySourceType, Suite}; use ruff_text_size::{Ranged, TextRange, TextSize}; @@ -146,6 +146,7 @@ pub fn tokenize(contents: &str, mode: Mode) -> Vec { /// Parse a full Python program from its tokens. pub fn parse_program_tokens( lxr: Vec, + source: &str, source_path: &str, is_jupyter_notebook: bool, ) -> anyhow::Result { @@ -154,7 +155,7 @@ pub fn parse_program_tokens( } else { Mode::Module }; - match parse_tokens(lxr, mode, source_path)? { + match parse_tokens(lxr, source, mode, source_path)? { Mod::Module(m) => Ok(m.body), Mod::Expression(_) => unreachable!("Mode::Module doesn't return other variant"), } @@ -179,66 +180,85 @@ pub fn locate_cmp_ops(expr: &Expr, source: &str) -> Vec { .peekable(); let mut ops: Vec = vec![]; - let mut count = 0u32; + + // Track the bracket depth. + let mut par_count = 0u32; + let mut sqb_count = 0u32; + let mut brace_count = 0u32; + loop { let Some((tok, range)) = tok_iter.next() else { break; }; - if matches!(tok, Tok::Lpar) { - count = count.saturating_add(1); - continue; - } else if matches!(tok, Tok::Rpar) { - count = count.saturating_sub(1); + + match tok { + Tok::Lpar => { + par_count = par_count.saturating_add(1); + } + Tok::Rpar => { + par_count = par_count.saturating_sub(1); + } + Tok::Lsqb => { + sqb_count = sqb_count.saturating_add(1); + } + Tok::Rsqb => { + sqb_count = sqb_count.saturating_sub(1); + } + Tok::Lbrace => { + brace_count = brace_count.saturating_add(1); + } + Tok::Rbrace => { + brace_count = brace_count.saturating_sub(1); + } + _ => {} + } + + if par_count > 0 || sqb_count > 0 || brace_count > 0 { continue; } - if count == 0 { - match tok { - Tok::Not => { - if let Some((_, next_range)) = - tok_iter.next_if(|(tok, _)| matches!(tok, Tok::In)) - { - ops.push(LocatedCmpOp::new( - TextRange::new(range.start(), next_range.end()), - CmpOp::NotIn, - )); - } - } - Tok::In => { - ops.push(LocatedCmpOp::new(range, CmpOp::In)); - } - Tok::Is => { - let op = if let Some((_, next_range)) = - tok_iter.next_if(|(tok, _)| matches!(tok, Tok::Not)) - { - LocatedCmpOp::new( - TextRange::new(range.start(), next_range.end()), - CmpOp::IsNot, - ) - } else { - LocatedCmpOp::new(range, CmpOp::Is) - }; - ops.push(op); - } - Tok::NotEqual => { - ops.push(LocatedCmpOp::new(range, CmpOp::NotEq)); - } - Tok::EqEqual => { - ops.push(LocatedCmpOp::new(range, CmpOp::Eq)); - } - Tok::GreaterEqual => { - ops.push(LocatedCmpOp::new(range, CmpOp::GtE)); - } - Tok::Greater => { - ops.push(LocatedCmpOp::new(range, CmpOp::Gt)); - } - Tok::LessEqual => { - ops.push(LocatedCmpOp::new(range, CmpOp::LtE)); - } - Tok::Less => { - ops.push(LocatedCmpOp::new(range, CmpOp::Lt)); + + match tok { + Tok::Not => { + if let Some((_, next_range)) = tok_iter.next_if(|(tok, _)| tok.is_in()) { + ops.push(LocatedCmpOp::new( + TextRange::new(range.start(), next_range.end()), + CmpOp::NotIn, + )); } - _ => {} } + Tok::In => { + ops.push(LocatedCmpOp::new(range, CmpOp::In)); + } + Tok::Is => { + let op = if let Some((_, next_range)) = tok_iter.next_if(|(tok, _)| tok.is_not()) { + LocatedCmpOp::new( + TextRange::new(range.start(), next_range.end()), + CmpOp::IsNot, + ) + } else { + LocatedCmpOp::new(range, CmpOp::Is) + }; + ops.push(op); + } + Tok::NotEqual => { + ops.push(LocatedCmpOp::new(range, CmpOp::NotEq)); + } + Tok::EqEqual => { + ops.push(LocatedCmpOp::new(range, CmpOp::Eq)); + } + Tok::GreaterEqual => { + ops.push(LocatedCmpOp::new(range, CmpOp::GtE)); + } + Tok::Greater => { + ops.push(LocatedCmpOp::new(range, CmpOp::Gt)); + } + Tok::LessEqual => { + ops.push(LocatedCmpOp::new(range, CmpOp::LtE)); + } + Tok::Less => { + ops.push(LocatedCmpOp::new(range, CmpOp::Lt)); + } + _ => {} } } ops diff --git a/crates/ruff_python_parser/src/parser.rs b/crates/ruff_python_parser/src/parser.rs index d6f6fde5d7c0e..a196c68ffc3f7 100644 --- a/crates/ruff_python_parser/src/parser.rs +++ b/crates/ruff_python_parser/src/parser.rs @@ -18,7 +18,7 @@ use itertools::Itertools; pub(super) use lalrpop_util::ParseError as LalrpopError; use ruff_text_size::{TextRange, TextSize}; -use crate::lexer::{lex, lex_starts_at}; +use crate::lexer::{lex, lex_starts_at, Spanned}; use crate::{ lexer::{self, LexResult, LexicalError, LexicalErrorType}, python, @@ -50,7 +50,7 @@ use ruff_python_ast::{Mod, ModModule, Suite}; /// ``` pub fn parse_program(source: &str, source_path: &str) -> Result { let lexer = lex(source, Mode::Module); - match parse_tokens(lexer, Mode::Module, source_path)? { + match parse_tokens(lexer, source, Mode::Module, source_path)? { Mod::Module(m) => Ok(m), Mod::Expression(_) => unreachable!("Mode::Module doesn't return other variant"), } @@ -78,7 +78,7 @@ pub fn parse_suite(source: &str, source_path: &str) -> Result /// ``` pub fn parse_expression(source: &str, source_path: &str) -> Result { let lexer = lex(source, Mode::Expression); - match parse_tokens(lexer, Mode::Expression, source_path)? { + match parse_tokens(lexer, source, Mode::Expression, source_path)? { Mod::Expression(expression) => Ok(*expression.body), Mod::Module(_m) => unreachable!("Mode::Expression doesn't return other variant"), } @@ -107,7 +107,7 @@ pub fn parse_expression_starts_at( offset: TextSize, ) -> Result { let lexer = lex_starts_at(source, Mode::Module, offset); - match parse_tokens(lexer, Mode::Expression, source_path)? { + match parse_tokens(lexer, source, Mode::Expression, source_path)? { Mod::Expression(expression) => Ok(*expression.body), Mod::Module(_m) => unreachable!("Mode::Expression doesn't return other variant"), } @@ -159,7 +159,7 @@ pub fn parse_expression_starts_at( /// let program = parse(source, Mode::Ipython, ""); /// assert!(program.is_ok()); /// ``` -pub fn parse(source: &str, mode: Mode, source_path: &str) -> Result { +pub fn parse(source: &str, mode: Mode, source_path: &str) -> Result { parse_starts_at(source, mode, source_path, TextSize::default()) } @@ -191,9 +191,9 @@ pub fn parse_starts_at( mode: Mode, source_path: &str, offset: TextSize, -) -> Result { +) -> Result { let lxr = lexer::lex_starts_at(source, mode, offset); - parse_tokens(lxr, mode, source_path) + parse_tokens(lxr, source, mode, source_path) } /// Parse an iterator of [`LexResult`]s using the specified [`Mode`]. @@ -208,36 +208,58 @@ pub fn parse_starts_at( /// ``` /// use ruff_python_parser::{lexer::lex, Mode, parse_tokens}; /// -/// let expr = parse_tokens(lex("1 + 2", Mode::Expression), Mode::Expression, ""); +/// let source = "1 + 2"; +/// let expr = parse_tokens(lex(source, Mode::Expression), source, Mode::Expression, ""); /// assert!(expr.is_ok()); /// ``` pub fn parse_tokens( lxr: impl IntoIterator, + source: &str, mode: Mode, source_path: &str, -) -> Result { +) -> Result { let lxr = lxr.into_iter(); parse_filtered_tokens( lxr.filter_ok(|(tok, _)| !matches!(tok, Tok::Comment { .. } | Tok::NonLogicalNewline)), + source, mode, source_path, ) } +/// Parse tokens into an AST like [`parse_tokens`], but we already know all tokens are valid. +pub fn parse_ok_tokens( + lxr: impl IntoIterator, + source: &str, + mode: Mode, + source_path: &str, +) -> Result { + let lxr = lxr + .into_iter() + .filter(|(tok, _)| !matches!(tok, Tok::Comment { .. } | Tok::NonLogicalNewline)); + let marker_token = (Tok::start_marker(mode), TextRange::default()); + let lexer = iter::once(marker_token) + .chain(lxr) + .map(|(t, range)| (range.start(), t, range.end())); + python::TopParser::new() + .parse(source, mode, lexer) + .map_err(|e| parse_error_from_lalrpop(e, source_path)) +} + fn parse_filtered_tokens( lxr: impl IntoIterator, + source: &str, mode: Mode, source_path: &str, -) -> Result { +) -> Result { let marker_token = (Tok::start_marker(mode), TextRange::default()); let lexer = iter::once(Ok(marker_token)).chain(lxr); python::TopParser::new() .parse( + source, mode, - lexer - .into_iter() - .map_ok(|(t, range)| (range.start(), t, range.end())), + lexer.map_ok(|(t, range)| (range.start(), t, range.end())), ) .map_err(|e| parse_error_from_lalrpop(e, source_path)) } @@ -1114,6 +1136,15 @@ match x: match x: case (0,): y = 0 +match x,: + case z: + pass +match x, y: + case z: + pass +match x, y,: + case z: + pass "#, "", ) @@ -1121,6 +1152,24 @@ match x: insta::assert_debug_snapshot!(parse_ast); } + #[test] + fn test_match_pattern_fstring_literal() { + // F-string literal is not allowed in match pattern. + let parse_error = parse_suite( + r#" +match x: + case f"{y}": + pass +"#, + "", + ) + .err(); + assert!( + parse_error.is_some(), + "expected parse error when f-string literal is used in match pattern" + ); + } + #[test] fn test_variadic_generics() { let parse_ast = parse_suite( @@ -1237,11 +1286,72 @@ a = 1 "# .trim(); let lxr = lexer::lex_starts_at(source, Mode::Ipython, TextSize::default()); - let parse_err = parse_tokens(lxr, Mode::Module, "").unwrap_err(); + let parse_err = parse_tokens(lxr, source, Mode::Module, "").unwrap_err(); assert_eq!( parse_err.to_string(), "IPython escape commands are only allowed in `Mode::Ipython` at byte offset 6" .to_string() ); } + + #[test] + fn test_fstrings() { + let parse_ast = parse_suite( + r#" +f"{" f"}" +f"{foo!s}" +f"{3,}" +f"{3!=4:}" +f'{3:{"}"}>10}' +f'{3:{"{"}>10}' +f"{ foo = }" +f"{ foo = :.3f }" +f"{ foo = !s }" +f"{ 1, 2 = }" +f'{f"{3.1415=:.1f}":*^20}' + +{"foo " f"bar {x + y} " "baz": 10} +match foo: + case "one": + pass + case "implicitly " "concatenated": + pass + +f"\{foo}\{bar:\}" +f"\\{{foo\\}}" +f"""{ + foo:x + y + z +}""" +"# + .trim(), + "", + ) + .unwrap(); + insta::assert_debug_snapshot!(parse_ast); + } + + #[test] + fn test_fstrings_with_unicode() { + let parse_ast = parse_suite( + r#" +u"foo" f"{bar}" "baz" " some" +"foo" f"{bar}" u"baz" " some" +"foo" f"{bar}" "baz" u" some" +u"foo" f"bar {baz} really" u"bar" "no" +"# + .trim(), + "", + ) + .unwrap(); + insta::assert_debug_snapshot!(parse_ast); + } + + #[test] + fn test_unicode_aliases() { + // https://github.com/RustPython/RustPython/issues/4566 + let parse_ast = parse_suite(r#"x = "\N{BACKSPACE}another cool trick""#, "").unwrap(); + insta::assert_debug_snapshot!(parse_ast); + } } diff --git a/crates/ruff_python_parser/src/python.lalrpop b/crates/ruff_python_parser/src/python.lalrpop index 488aded68889d..a0a19f9305ea7 100644 --- a/crates/ruff_python_parser/src/python.lalrpop +++ b/crates/ruff_python_parser/src/python.lalrpop @@ -3,20 +3,20 @@ // See also: file:///usr/share/doc/python/html/reference/compound_stmts.html#function-definitions // See also: https://greentreesnakes.readthedocs.io/en/latest/nodes.html#keyword -use num_bigint::BigInt; -use ruff_text_size::{Ranged, TextSize}; -use ruff_python_ast::{self as ast, IpyEscapeKind}; +use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; +use ruff_python_ast::{self as ast, Int, IpyEscapeKind}; use crate::{ + FStringErrorType, Mode, lexer::{LexicalError, LexicalErrorType}, function::{ArgumentList, parse_arguments, validate_pos_params, validate_arguments}, context::set_context, - string::parse_strings, + string::{StringType, concatenate_strings, parse_fstring_middle, parse_string_literal}, token::{self, StringKind}, }; use lalrpop_util::ParseError; -grammar(mode: Mode); +grammar(source_code: &str, mode: Mode); // This is a hack to reduce the amount of lalrpop tables generated: // For each public entry point, a full parse table is generated. @@ -466,7 +466,7 @@ MatchStatement: ast::Stmt = { } ) }, - "match" "," ":" "\n" Indent Dedent => { + "match" "," ":" "\n" Indent Dedent => { let end_location = cases .last() .unwrap() @@ -476,13 +476,19 @@ MatchStatement: ast::Stmt = { .end(); ast::Stmt::Match( ast::StmtMatch { - subject: Box::new(subject.into()), + subject: Box::new(ast::Expr::Tuple( + ast::ExprTuple { + elts: vec![subject.into()], + ctx: ast::ExprContext::Load, + range: (tuple_location..tuple_end_location).into() + }, + )), cases, range: (location..end_location).into() } ) }, - "match" > ","? ":" "\n" Indent Dedent => { + "match" > ","? ":" "\n" Indent Dedent => { let end_location = cases .last() .unwrap() @@ -497,7 +503,7 @@ MatchStatement: ast::Stmt = { ast::ExprTuple { elts, ctx: ast::ExprContext::Load, - range: (location..end_location).into() + range: (tuple_location..tuple_end_location).into() }, )), cases, @@ -668,8 +674,8 @@ LiteralPattern: ast::Pattern = { value: Box::new(value.into()), range: (location..end_location).into() }.into(), - =>? Ok(ast::PatternMatchValue { - value: Box::new(parse_strings(s)?), + =>? Ok(ast::PatternMatchValue { + value: Box::new(concatenate_strings(strings, (location..end_location).into())?), range: (location..end_location).into() }.into()), } @@ -726,7 +732,7 @@ MappingKey: ast::Expr = { value: false.into(), range: (location..end_location).into() }.into(), - =>? Ok(parse_strings(s)?), + =>? Ok(concatenate_strings(strings, (location..end_location).into())?), } MatchMappingEntry: (ast::Expr, ast::Pattern) = { @@ -1350,7 +1356,13 @@ NamedExpression: ast::ParenthesizedExpr = { }; LambdaDef: ast::ParenthesizedExpr = { - "lambda" ?> ":" > =>? { + "lambda" ?> ":" > =>? { + if fstring_middle.is_some() { + return Err(LexicalError { + error: LexicalErrorType::FStringError(FStringErrorType::LambdaWithoutParentheses), + location, + })?; + } parameters.as_ref().map(validate_arguments).transpose()?; Ok(ast::ExprLambda { @@ -1573,8 +1585,105 @@ SliceOp: Option = { ":" ?> => e, } +StringLiteralOrFString: StringType = { + StringLiteral, + FStringExpr, +}; + +StringLiteral: StringType = { + =>? { + let (source, kind, triple_quoted) = string; + Ok(parse_string_literal(&source, kind, triple_quoted, start_location)?) + } +}; + +FStringExpr: StringType = { + FStringStart FStringEnd => { + StringType::FString(ast::ExprFString { + values, + implicit_concatenated: false, + range: (location..end_location).into() + }) + } +}; + +FStringMiddlePattern: ast::Expr = { + FStringReplacementField, + =>? { + let (source, is_raw) = fstring_middle; + Ok(parse_fstring_middle(&source, is_raw, start_location)?) + } +}; + +FStringReplacementField: ast::Expr = { + "{" "}" =>? { + if value.expr.is_lambda_expr() && !value.is_parenthesized() { + return Err(LexicalError { + error: LexicalErrorType::FStringError(FStringErrorType::LambdaWithoutParentheses), + location: value.start(), + })?; + } + let debug_text = debug.map(|_| { + let start_offset = location + "{".text_len(); + let end_offset = if let Some((conversion_start, _)) = conversion { + conversion_start + } else { + format_spec.as_ref().map_or_else( + || end_location - "}".text_len(), + |spec| spec.range().start() - ":".text_len(), + ) + }; + ast::DebugText { + leading: source_code[TextRange::new(start_offset, value.range().start())].to_string(), + trailing: source_code[TextRange::new(value.range().end(), end_offset)].to_string(), + } + }); + Ok( + ast::ExprFormattedValue { + value: Box::new(value.into()), + debug_text, + conversion: conversion.map_or(ast::ConversionFlag::None, |(_, conversion_flag)| { + conversion_flag + }), + format_spec: format_spec.map(Box::new), + range: (location..end_location).into(), + } + .into() + ) + } +}; + +FStringFormatSpecSuffix: ast::Expr = { + ":" => format_spec +}; + +FStringFormatSpec: ast::Expr = { + => { + ast::ExprFString { + values, + implicit_concatenated: false, + range: (location..end_location).into() + }.into() + }, +}; + +FStringConversion: (TextSize, ast::ConversionFlag) = { + "!" =>? { + let conversion = match s.as_str() { + "s" => ast::ConversionFlag::Str, + "r" => ast::ConversionFlag::Repr, + "a" => ast::ConversionFlag::Ascii, + _ => Err(LexicalError { + error: LexicalErrorType::FStringError(FStringErrorType::InvalidConversionFlag), + location: name_location, + })? + }; + Ok((location, conversion)) + } +}; + Atom: ast::ParenthesizedExpr = { - =>? Ok(parse_strings(s)?.into()), + =>? Ok(concatenate_strings(strings, (location..end_location).into())?.into()), => ast::ExprConstant { value, range: (location..end_location).into(), @@ -1843,6 +1952,9 @@ extern { Dedent => token::Tok::Dedent, StartModule => token::Tok::StartModule, StartExpression => token::Tok::StartExpression, + FStringStart => token::Tok::FStringStart, + FStringEnd => token::Tok::FStringEnd, + "!" => token::Tok::Exclamation, "?" => token::Tok::Question, "+" => token::Tok::Plus, "-" => token::Tok::Minus, @@ -1928,7 +2040,7 @@ extern { "True" => token::Tok::True, "False" => token::Tok::False, "None" => token::Tok::None, - int => token::Tok::Int { value: }, + int => token::Tok::Int { value: }, float => token::Tok::Float { value: }, complex => token::Tok::Complex { real: , imag: }, string => token::Tok::String { @@ -1936,6 +2048,10 @@ extern { kind: , triple_quoted: }, + fstring_middle => token::Tok::FStringMiddle { + value: , + is_raw: + }, name => token::Tok::Name { name: }, ipy_escape_command => token::Tok::IpyEscapeCommand { kind: , diff --git a/crates/ruff_python_parser/src/python.rs b/crates/ruff_python_parser/src/python.rs index 09c0b5a6f1941..e53ba26da7a23 100644 --- a/crates/ruff_python_parser/src/python.rs +++ b/crates/ruff_python_parser/src/python.rs @@ -1,14 +1,14 @@ // auto-generated: "lalrpop 0.20.0" -// sha3: eb535c9ae34baad8c940ef61dbbea0a7fec7baf3cd62af40837b2616f656f927 -use num_bigint::BigInt; -use ruff_text_size::{Ranged, TextSize}; -use ruff_python_ast::{self as ast, IpyEscapeKind}; +// sha3: 01c7c57ce067fcf07c9a5450511cc48a2dd08cf821a5ff3b0f649e87d3c67022 +use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; +use ruff_python_ast::{self as ast, Int, IpyEscapeKind}; use crate::{ + FStringErrorType, Mode, lexer::{LexicalError, LexicalErrorType}, function::{ArgumentList, parse_arguments, validate_pos_params, validate_arguments}, context::set_context, - string::parse_strings, + string::{StringType, concatenate_strings, parse_fstring_middle, parse_string_literal}, token::{self, StringKind}, }; use lalrpop_util::ParseError; @@ -23,15 +23,15 @@ extern crate alloc; #[allow(non_snake_case, non_camel_case_types, unused_mut, unused_variables, unused_imports, unused_parens, clippy::all)] mod __parse__Top { - use num_bigint::BigInt; - use ruff_text_size::{Ranged, TextSize}; - use ruff_python_ast::{self as ast, IpyEscapeKind}; + use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; + use ruff_python_ast::{self as ast, Int, IpyEscapeKind}; use crate::{ + FStringErrorType, Mode, lexer::{LexicalError, LexicalErrorType}, function::{ArgumentList, parse_arguments, validate_pos_params, validate_arguments}, context::set_context, - string::parse_strings, + string::{StringType, concatenate_strings, parse_fstring_middle, parse_string_literal}, token::{self, StringKind}, }; use lalrpop_util::ParseError; @@ -48,2401 +48,2484 @@ mod __parse__Top { Variant0(token::Tok), Variant1((f64, f64)), Variant2(f64), - Variant3(BigInt), - Variant4((IpyEscapeKind, String)), - Variant5(String), - Variant6((String, StringKind, bool)), - Variant7(core::option::Option), - Variant8(Option>), - Variant9(core::option::Option>>), - Variant10(ast::ParameterWithDefault), - Variant11(alloc::vec::Vec), - Variant12((Option>, Vec, Option>)), - Variant13(core::option::Option<(Option>, Vec, Option>)>), - Variant14(ast::ParenthesizedExpr), - Variant15(core::option::Option), - Variant16(alloc::vec::Vec), - Variant17(ast::WithItem), - Variant18(alloc::vec::Vec), - Variant19((token::Tok, ast::Identifier)), - Variant20(alloc::vec::Vec<(token::Tok, ast::Identifier)>), - Variant21(alloc::vec::Vec), - Variant22(ast::Identifier), - Variant23(core::option::Option), - Variant24(ast::Suite), - Variant25(core::option::Option), - Variant26((TextSize, ast::ParenthesizedExpr, ast::Suite)), - Variant27(alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)>), - Variant28((TextSize, ast::Suite)), - Variant29(core::option::Option<(TextSize, ast::Suite)>), - Variant30((Option<(TextSize, TextSize, Option)>, ast::Expr)), - Variant31(alloc::vec::Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>), - Variant32(Vec), - Variant33(core::option::Option>), - Variant34(ast::Pattern), - Variant35(alloc::vec::Vec), - Variant36(ast::Stmt), - Variant37(alloc::vec::Vec), - Variant38((ast::ParenthesizedExpr, ast::Identifier)), - Variant39(Vec), - Variant40(core::option::Option>), - Variant41((TextSize, (String, StringKind, bool), TextSize)), - Variant42(alloc::vec::Vec<(TextSize, (String, StringKind, bool), TextSize)>), - Variant43((ast::CmpOp, ast::ParenthesizedExpr)), - Variant44(alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>), - Variant45(ast::Expr), - Variant46(core::option::Option), - Variant47(ast::Parameters), - Variant48(core::option::Option), - Variant49(TextSize), - Variant50(ast::Operator), - Variant51(ast::Arguments), - Variant52(core::option::Option), - Variant53(Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>), - Variant54(Vec), - Variant55(Vec), - Variant56(core::option::Option>), - Variant57(ast::CmpOp), - Variant58(ast::Constant), - Variant59(ast::Decorator), - Variant60(alloc::vec::Vec), - Variant61((Option>, ast::ParenthesizedExpr)), - Variant62((ast::ParenthesizedExpr, ast::ParenthesizedExpr)), - Variant63(Vec<(Option>, ast::ParenthesizedExpr)>), - Variant64(core::option::Option>, ast::ParenthesizedExpr)>>), - Variant65(ast::Parameter), - Variant66(core::option::Option), - Variant67(ast::ExceptHandler), - Variant68(alloc::vec::Vec), - Variant69(core::option::Option<(Option<(TextSize, TextSize, Option)>, ast::Expr)>), - Variant70(ast::Alias), - Variant71(Vec), - Variant72(u32), - Variant73(alloc::vec::Vec), - Variant74((Option, Option)), - Variant75(ast::MatchCase), - Variant76(alloc::vec::Vec), - Variant77(ast::PatternKeyword), - Variant78((ast::Expr, ast::Pattern)), - Variant79(Vec), - Variant80(Vec), - Variant81(Vec<(ast::Expr, ast::Pattern)>), - Variant82(Vec), - Variant83(Vec), - Variant84((Vec, Vec)), - Variant85(core::option::Option), - Variant86(ast::PatternArguments), - Variant87(ast::Comprehension), - Variant88(alloc::vec::Vec), - Variant89(Option), - Variant90(core::option::Option>), - Variant91(Vec), - Variant92(ast::Mod), - Variant93(ast::TypeParam), - Variant94(ast::TypeParams), - Variant95(core::option::Option), - Variant96(ast::UnaryOp), + Variant3((String, bool)), + Variant4(Int), + Variant5((IpyEscapeKind, String)), + Variant6(String), + Variant7((String, StringKind, bool)), + Variant8(core::option::Option), + Variant9(Option>), + Variant10(core::option::Option>>), + Variant11(ast::ParameterWithDefault), + Variant12(alloc::vec::Vec), + Variant13((Option>, Vec, Option>)), + Variant14(core::option::Option<(Option>, Vec, Option>)>), + Variant15(ast::ParenthesizedExpr), + Variant16(core::option::Option), + Variant17(alloc::vec::Vec), + Variant18(ast::WithItem), + Variant19(alloc::vec::Vec), + Variant20((token::Tok, ast::Identifier)), + Variant21(alloc::vec::Vec<(token::Tok, ast::Identifier)>), + Variant22(alloc::vec::Vec), + Variant23(ast::Identifier), + Variant24(core::option::Option), + Variant25(ast::Suite), + Variant26(core::option::Option), + Variant27((TextSize, ast::ParenthesizedExpr, ast::Suite)), + Variant28(alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)>), + Variant29((TextSize, ast::Suite)), + Variant30(core::option::Option<(TextSize, ast::Suite)>), + Variant31((Option<(TextSize, TextSize, Option)>, ast::Expr)), + Variant32(alloc::vec::Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>), + Variant33(Vec), + Variant34(core::option::Option>), + Variant35(ast::Pattern), + Variant36(alloc::vec::Vec), + Variant37(ast::Stmt), + Variant38(alloc::vec::Vec), + Variant39((ast::ParenthesizedExpr, ast::Identifier)), + Variant40(Vec), + Variant41(core::option::Option>), + Variant42((ast::CmpOp, ast::ParenthesizedExpr)), + Variant43(alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>), + Variant44(ast::Expr), + Variant45(core::option::Option), + Variant46(ast::Parameters), + Variant47(core::option::Option), + Variant48(TextSize), + Variant49(ast::Operator), + Variant50(ast::Arguments), + Variant51(core::option::Option), + Variant52(Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>), + Variant53(Vec), + Variant54(Vec), + Variant55(core::option::Option>), + Variant56(ast::CmpOp), + Variant57(ast::Constant), + Variant58(ast::Decorator), + Variant59(alloc::vec::Vec), + Variant60((Option>, ast::ParenthesizedExpr)), + Variant61((ast::ParenthesizedExpr, ast::ParenthesizedExpr)), + Variant62(Vec<(Option>, ast::ParenthesizedExpr)>), + Variant63(core::option::Option>, ast::ParenthesizedExpr)>>), + Variant64(ast::Parameter), + Variant65(core::option::Option), + Variant66(ast::ExceptHandler), + Variant67(alloc::vec::Vec), + Variant68((TextSize, ast::ConversionFlag)), + Variant69(core::option::Option<(TextSize, ast::ConversionFlag)>), + Variant70(StringType), + Variant71(alloc::vec::Vec), + Variant72(core::option::Option<(Option<(TextSize, TextSize, Option)>, ast::Expr)>), + Variant73(ast::Alias), + Variant74(Vec), + Variant75(u32), + Variant76(alloc::vec::Vec), + Variant77((Option, Option)), + Variant78(ast::MatchCase), + Variant79(alloc::vec::Vec), + Variant80(ast::PatternKeyword), + Variant81((ast::Expr, ast::Pattern)), + Variant82(Vec), + Variant83(Vec), + Variant84(Vec<(ast::Expr, ast::Pattern)>), + Variant85(Vec), + Variant86(Vec), + Variant87((Vec, Vec)), + Variant88(core::option::Option), + Variant89(ast::PatternArguments), + Variant90(ast::Comprehension), + Variant91(alloc::vec::Vec), + Variant92(Option), + Variant93(core::option::Option>), + Variant94(Vec), + Variant95(alloc::vec::Vec), + Variant96(ast::Mod), + Variant97(ast::TypeParam), + Variant98(ast::TypeParams), + Variant99(core::option::Option), + Variant100(ast::UnaryOp), + Variant101(core::option::Option<(String, bool)>), } const __ACTION: &[i16] = &[ // State 0 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, // State 1 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 2 - -743, 0, 0, 0, 0, 0, -743, 0, -743, 0, 0, 0, -743, 0, 0, -743, 0, 0, 0, -743, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -743, 0, -743, -743, -743, -743, 0, 0, 0, 0, 0, -743, -743, -743, -743, 0, -743, -743, -743, -743, 0, 0, 0, 0, -743, -743, -743, -743, -743, 0, 0, -743, -743, -743, -743, 0, -743, -743, -743, -743, -743, -743, -743, -743, -743, 0, 0, 0, -743, 0, 0, 0, 0, -743, -743, -743, -743, -743, -743, + -768, 0, 0, 0, 0, 0, 0, -768, 0, -768, 0, 0, 0, -768, 0, 0, -768, 0, 0, 0, -768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -768, 0, -768, -768, -768, -768, 0, 0, 0, 0, 0, -768, -768, -768, -768, 0, -768, -768, -768, -768, 0, 0, 0, 0, -768, -768, -768, -768, -768, 0, 0, -768, -768, -768, -768, 0, -768, -768, -768, -768, -768, -768, -768, -768, -768, 0, 0, 0, -768, 0, 0, -768, 0, 0, 0, -768, -768, 0, -768, -768, -768, -768, // State 3 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 4 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 5 - -765, -765, 0, -765, -765, -765, 0, -765, 0, 0, -765, -765, 424, -765, -765, 425, -765, 0, 0, 0, 0, 0, -765, -765, -765, 0, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, 0, -765, 0, 0, 0, 0, -765, -765, -765, -765, -765, 0, -765, 0, 0, 0, 0, 0, 0, 0, 0, -765, 0, 0, -765, -765, 0, -765, 0, -765, -765, 0, 0, 0, -765, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, -765, -765, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -790, -790, -790, 0, -790, -790, -790, 0, -790, 0, 0, -790, -790, 440, -790, -790, 441, -790, 0, 0, 0, 0, 0, -790, -790, -790, 0, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, -790, 0, -790, 0, 0, 0, 0, -790, -790, -790, -790, -790, 0, -790, 0, 0, 0, 0, 0, 0, 0, 0, -790, 0, 0, -790, -790, 0, -790, 0, -790, -790, 0, 0, 0, -790, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, -790, -790, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 6 - -249, -249, -249, -249, -249, -249, 23, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, 0, 24, 0, -249, -249, -249, -249, -249, 0, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, 0, 0, 0, 25, -249, -249, -249, -249, -249, 0, -249, 0, 0, 0, 0, 0, 0, 0, 0, -249, 0, 0, -249, -249, 0, -249, 0, -249, -249, 0, 0, 0, -249, -249, 0, 0, 0, 0, 0, 0, 0, 0, 0, -249, -249, -249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -248, -248, -248, -248, -248, -248, -248, 25, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, 0, 26, 0, -248, -248, -248, -248, -248, 0, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, 0, 0, 0, 27, -248, -248, -248, -248, -248, 0, -248, 0, 0, 0, 0, 0, 0, 0, 0, -248, 0, 0, -248, -248, 0, -248, 0, -248, -248, 0, 0, 0, -248, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, -248, -248, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 7 - -305, 427, 0, -305, 0, -305, 0, -305, 0, 0, -305, -305, 0, -305, -305, 0, -305, 0, 0, 0, 0, 0, -305, -305, -305, 0, -305, 428, 0, -305, 429, -305, 430, 431, 432, 0, -305, 0, 0, -305, 0, 0, 0, 0, -305, 0, -305, -305, -305, 0, -305, 0, 0, 0, 0, 0, 0, 0, 0, -305, 0, 0, -305, -305, 0, -305, 0, 433, 434, 0, 0, 0, 435, -305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, -305, -305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -304, -304, 443, 0, -304, 0, -304, 0, -304, 0, 0, -304, -304, 0, -304, -304, 0, -304, 0, 0, 0, 0, 0, -304, -304, -304, 0, -304, 444, 0, -304, 445, -304, 446, 447, 448, 0, -304, 0, 0, -304, 0, 0, 0, 0, -304, 0, -304, -304, -304, 0, -304, 0, 0, 0, 0, 0, 0, 0, 0, -304, 0, 0, -304, -304, 0, -304, 0, 449, 450, 0, 0, 0, 451, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, -304, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 8 - 437, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 9 - -156, -156, 0, -156, -156, -156, 0, -156, 0, 0, -156, -156, 0, -156, -156, 0, -156, 0, 0, 0, 0, 0, -156, -156, -156, 0, -156, -156, 439, -156, -156, -156, -156, -156, -156, 440, -156, -156, 0, -156, 0, 0, 0, 0, -156, -156, -156, -156, -156, 0, -156, 0, 0, 0, 0, 0, 0, 0, 0, -156, 0, 0, -156, -156, 0, -156, 0, -156, -156, 0, 0, 0, -156, -156, 0, 0, 0, 0, 0, 0, 0, 0, 0, -156, -156, -156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -155, -155, -155, 0, -155, -155, -155, 0, -155, 0, 0, -155, -155, 0, -155, -155, 0, -155, 0, 0, 0, 0, 0, -155, -155, -155, 0, -155, -155, 455, -155, -155, -155, -155, -155, -155, 456, -155, -155, 0, -155, 0, 0, 0, 0, -155, -155, -155, -155, -155, 0, -155, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, 0, -155, -155, 0, -155, 0, -155, -155, 0, 0, 0, -155, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, -155, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 10 - -170, -170, 441, -170, -170, -170, 0, -170, 442, 0, -170, -170, -170, -170, -170, -170, -170, 0, 0, 0, 443, 444, -170, -170, -170, 0, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, 445, -170, 0, 0, 0, 0, -170, -170, -170, -170, -170, 0, -170, 0, 0, 0, 0, 0, 0, 0, 0, -170, 0, 0, -170, -170, 0, -170, 0, -170, -170, 0, 0, 0, -170, -170, 0, 0, 0, 0, 0, 0, 0, 0, 0, -170, -170, -170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, 0, -183, 0, -183, -183, -183, -183, -183, 0, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, -183, 0, 0, 0, -183, -183, -183, -183, -183, -183, 0, -183, 0, 0, 0, 0, 0, 0, 0, 0, -183, 0, 0, -183, -183, 0, -183, 0, -183, -183, 0, 0, 0, -183, -183, 0, 0, 0, 0, 0, 0, 0, 0, 0, -183, -183, -183, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 436, // State 11 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + -169, -169, -169, 458, -169, -169, -169, 0, -169, 459, 0, -169, -169, -169, -169, -169, -169, -169, 0, 0, 0, 460, 461, -169, -169, -169, 0, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, 462, -169, 0, 0, 0, 0, -169, -169, -169, -169, -169, 0, -169, 0, 0, 0, 0, 0, 0, 0, 0, -169, 0, 0, -169, -169, 0, -169, 0, -169, -169, 0, 0, 0, -169, -169, 0, 0, 0, 0, 0, 0, 0, 0, 0, -169, -169, -169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 12 - 0, 0, 0, 0, 0, 0, 13, 454, 14, 37, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 13 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 471, 15, 39, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 14 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 462, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 15 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 479, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 16 - 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 17 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 18 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 46, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 477, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 19 - 503, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 504, 16, 505, 0, 53, 506, 54, 55, 0, 0, 0, 0, 56, 57, 58, 59, 60, 0, 0, 17, 61, 62, 18, 0, 507, 63, 64, 508, 65, 66, 67, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 48, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 494, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 20 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 497, 0, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, // State 21 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 524, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 525, 17, 526, 0, 57, 527, 58, 59, 0, 0, 0, 0, 60, 61, 62, 63, 64, 0, 0, 18, 65, 66, 19, 0, 528, 67, 68, 529, 69, 70, 71, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 22 - 0, 0, 0, 0, 0, 0, 13, 514, 72, 73, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 23 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 24 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 535, 76, 77, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 25 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 26 - -304, 427, 0, -304, 0, -304, 0, -304, 0, 0, -304, -304, 0, -304, -304, 0, -304, 0, 0, 0, 0, 0, -304, -304, -304, 0, -304, 428, 0, -304, 429, -304, 430, 431, 432, 0, -304, 0, 0, -304, 0, 0, 0, 0, -304, 0, -304, -304, -304, 0, -304, 0, 0, 0, 0, 0, 0, 0, 0, -304, 0, 0, -304, -304, 0, -304, 0, 433, 434, 0, 0, 0, 435, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -304, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 27 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 28 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + -303, -303, 443, 0, -303, 0, -303, 0, -303, 0, 0, -303, -303, 0, -303, -303, 0, -303, 0, 0, 0, 0, 0, -303, -303, -303, 0, -303, 444, 0, -303, 445, -303, 446, 447, 448, 0, -303, 0, 0, -303, 0, 0, 0, 0, -303, 0, -303, -303, -303, 0, -303, 0, 0, 0, 0, 0, 0, 0, 0, -303, 0, 0, -303, -303, 0, -303, 0, 449, 450, 0, 0, 0, 451, -303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -303, -303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 29 - -409, 0, 0, -409, 0, -409, 13, -409, 14, 0, -409, -409, 408, -409, 0, 409, -409, 0, 0, 410, 0, 0, -409, -409, -409, 0, -409, 0, 0, -409, 0, -409, 0, 0, 0, 0, -409, 0, 0, -409, 411, 412, 413, 15, 0, 0, -409, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, -409, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 30 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 31 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + -432, -432, 0, 0, -432, 0, -432, 14, -432, 15, 0, -432, -432, 425, -432, 0, 426, -432, 0, 0, 427, 0, 0, -432, -432, -432, 0, -432, 0, 0, -432, 0, -432, 0, 0, 0, 0, -432, 0, 0, -432, 428, 429, 430, 16, 0, 0, -432, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, -432, -432, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 32 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 33 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 34 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 35 - 0, 0, 0, 0, 0, 0, 0, 535, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 36 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 37 - -915, 0, 0, 0, 0, 0, 13, -915, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, -915, 0, 0, 0, 0, -915, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 556, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 38 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -527, 0, 0, 0, 0, 0, 533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 39 - -248, -248, -248, -248, -248, -248, 23, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, 0, 24, 0, -248, -248, -248, -248, -248, 0, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, 0, 0, 0, 25, -248, -248, -248, -248, -248, 0, -248, 0, 0, 0, 0, 0, 0, 0, 0, -248, 0, 0, -248, -248, 0, -248, 0, -248, -248, 0, 0, 0, -248, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, -248, -248, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -947, -947, 0, 0, 0, 0, 0, 14, -947, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, -947, 0, -947, 0, 0, 0, 0, -947, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, -947, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 40 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, -698, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -552, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 41 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -443, 0, 0, 0, 0, 0, 0, 0, 0, 0, -443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + -247, -247, -247, -247, -247, -247, -247, 25, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, 0, 26, 0, -247, -247, -247, -247, -247, 0, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, -247, 0, 0, 0, 27, -247, -247, -247, -247, -247, 0, -247, 0, 0, 0, 0, 0, 0, 0, 0, -247, 0, 0, -247, -247, 0, -247, 0, -247, -247, 0, 0, 0, -247, -247, 0, 0, 0, 0, 0, 0, 0, 0, 0, -247, -247, -247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 42 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, -723, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 43 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -466, 0, 0, 0, 0, 0, 0, 0, 0, 0, -466, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 44 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -848, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -848, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 93, 434, 0, 435, 436, // State 45 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 46 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 47 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 92, 0, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 48 - -305, 427, 0, -305, 0, -305, 0, 0, 0, 0, -305, -305, 0, -305, -305, 0, -305, 0, 0, 0, 0, 0, -305, -305, -305, 0, -305, 428, 0, -305, 429, -305, 430, 431, 432, 0, -305, 556, 0, -305, 0, 0, 0, 0, 0, 0, -305, -305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -305, 0, 433, 434, 0, 0, 0, 435, -305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, -305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 574, 0, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, // State 49 - -365, 0, 0, 558, 0, 559, 0, 0, 0, 0, 560, 561, 0, 562, 0, 0, 563, 0, 0, 0, 0, 0, 564, 565, 0, 0, -365, 0, 0, 566, 0, 96, 0, 0, 0, 0, 567, 0, 0, 568, 0, 0, 0, 0, 0, 0, 569, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 570, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 50 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 51 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 579, 0, 0, 0, 98, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 52 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + -304, 0, 443, 0, -304, 0, -304, 0, 0, 0, 0, -304, -304, 0, -304, -304, 0, -304, 0, 0, 0, 0, 0, -304, -304, -304, 0, -304, 444, 0, -304, 445, -304, 446, 447, 448, 0, -304, 581, 0, -304, 0, 0, 0, 0, 0, 0, -304, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -304, 0, 449, 450, 0, 0, 0, 451, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 53 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + -364, 0, 0, 0, 583, 0, 584, 0, 0, 0, 0, 585, 586, 0, 587, 0, 0, 588, 0, 0, 0, 0, 0, 589, 590, 0, 0, -364, 0, 0, 591, 0, 102, 0, 0, 0, 0, 592, 0, 0, 593, 0, 0, 0, 0, 0, 0, 594, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 595, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 54 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 55 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 56 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 586, 587, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 57 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 58 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 59 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 60 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 611, 612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 0, // State 61 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 62 - -750, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 63 - -377, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, -377, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 0, // State 64 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 65 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 66 - 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 629, 630, 631, 117, 0, 0, 0, 0, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + -775, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, -775, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 67 - -155, -155, 0, -155, -155, -155, 0, -155, 0, 0, -155, -155, 0, -155, -155, 0, -155, 0, 0, 0, 0, 0, -155, -155, -155, 0, -155, -155, 439, -155, -155, -155, -155, -155, -155, 440, -155, -155, 0, -155, 0, 0, 0, 0, -155, -155, -155, -155, -155, 0, -155, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, 0, -155, -155, 0, -155, 0, -155, -155, 0, 0, 0, -155, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, -155, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -400, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, -400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 68 - -169, -169, 441, -169, -169, -169, 0, -169, 442, 0, -169, -169, -169, -169, -169, -169, -169, 0, 0, 0, 443, 444, -169, -169, -169, 0, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, -169, 445, -169, 0, 0, 0, 0, -169, -169, -169, -169, -169, 0, -169, 0, 0, 0, 0, 0, 0, 0, 0, -169, 0, 0, -169, -169, 0, -169, 0, -169, -169, 0, 0, 0, -169, -169, 0, 0, 0, 0, 0, 0, 0, 0, 0, -169, -169, -169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 69 - 0, 0, 0, 0, 0, 0, 13, 633, 72, 73, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 70 - 0, 0, 0, 0, 0, 0, 0, -401, 0, 0, 0, 0, 0, 0, -401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 653, 654, 655, 124, 0, 0, 0, 0, 0, 0, 0, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 71 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + -154, -154, -154, 0, -154, -154, -154, 0, -154, 0, 0, -154, -154, 0, -154, -154, 0, -154, 0, 0, 0, 0, 0, -154, -154, -154, 0, -154, -154, 455, -154, -154, -154, -154, -154, -154, 456, -154, -154, 0, -154, 0, 0, 0, 0, -154, -154, -154, -154, -154, 0, -154, 0, 0, 0, 0, 0, 0, 0, 0, -154, 0, 0, -154, -154, 0, -154, 0, -154, -154, 0, 0, 0, -154, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, -154, -154, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 72 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + -168, -168, -168, 458, -168, -168, -168, 0, -168, 459, 0, -168, -168, -168, -168, -168, -168, -168, 0, 0, 0, 460, 461, -168, -168, -168, 0, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, -168, 462, -168, 0, 0, 0, 0, -168, -168, -168, -168, -168, 0, -168, 0, 0, 0, 0, 0, 0, 0, 0, -168, 0, 0, -168, -168, 0, -168, 0, -168, -168, 0, 0, 0, -168, -168, 0, 0, 0, 0, 0, 0, 0, 0, 0, -168, -168, -168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 73 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, -818, 409, 0, 0, 0, 410, 0, 0, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, -818, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 657, 76, 77, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 74 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -424, 0, 0, 0, 0, 0, 0, -424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 75 - -764, -764, 0, -764, -764, -764, 0, -764, 0, 0, -764, -764, 424, -764, -764, 425, -764, 0, 0, 0, 0, 0, -764, -764, -764, 0, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, 0, -764, 0, 0, 0, 0, -764, -764, -764, -764, -764, 0, -764, 0, 0, 0, 0, 0, 0, 0, 0, -764, 0, 0, -764, -764, 0, -764, 0, -764, -764, 0, 0, 0, -764, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, -764, -764, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 76 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 77 - 0, 0, 0, 0, 0, 0, 0, -291, 0, 0, 0, 0, 0, 0, -291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -291, 0, 0, 0, 0, 0, 533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, -850, 426, 0, 0, 0, 427, 0, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, -850, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 78 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 79 - 0, 0, 0, 0, 0, 0, 13, 648, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + -789, -789, -789, 0, -789, -789, -789, 0, -789, 0, 0, -789, -789, 440, -789, -789, 441, -789, 0, 0, 0, 0, 0, -789, -789, -789, 0, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, -789, 0, -789, 0, 0, 0, 0, -789, -789, -789, -789, -789, 0, -789, 0, 0, 0, 0, 0, 0, 0, 0, -789, 0, 0, -789, -789, 0, -789, 0, -789, -789, 0, 0, 0, -789, -789, 0, 0, 0, 0, 0, 0, 0, 0, 0, -789, -789, -789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 80 - 0, 0, 0, 0, 0, 0, 13, 651, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 81 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -290, 0, 0, 0, 0, 0, 0, -290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -290, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 82 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, -446, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 83 - 0, 0, 0, 0, 0, 0, 0, 0, 131, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, -649, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 672, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 84 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 675, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 85 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 86 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, -697, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, -471, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 87 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -690, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, 0, 0, -674, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 88 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 46, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, -336, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 140, 434, 0, 435, 436, // State 89 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, -762, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 90 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, -722, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 91 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -715, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 92 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 93 - -366, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -366, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 48, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, -335, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 94 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, -787, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 95 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 678, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 96 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 695, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 696, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 97 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 98 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 99 - 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 629, 630, 631, 117, 0, 0, 0, 0, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + -365, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -365, 0, 0, 0, 0, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 100 - 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 101 - 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 704, 435, 436, // State 102 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 586, 587, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -434, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 103 - -340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -340, 0, 0, 0, 150, 0, 0, 0, 0, 0, 0, 0, -340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 104 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 105 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 653, 654, 655, 124, 0, 0, 0, 0, 0, 0, 0, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 106 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 107 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 108 - 0, -765, 0, 0, -765, 0, 0, 0, 0, 0, 0, 0, 424, 0, -765, 425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -765, -765, 0, -765, 0, -765, -765, -765, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, -765, 0, -765, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -765, 0, -765, -765, 0, 0, 0, -765, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 611, 612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 0, // State 109 - 0, -249, -249, 0, -249, 0, 23, 0, -249, -249, 0, 0, -249, 0, -249, -249, 0, 0, 164, 0, -249, -249, 0, 0, 0, 0, 0, -249, -249, 0, -249, 0, -249, -249, -249, -249, 0, 0, -249, 0, 0, 0, 0, 165, 0, -249, 0, -249, -249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -249, 0, -249, -249, 0, 0, 0, -249, -249, 0, 0, 0, 0, 0, 0, 0, 0, 0, -249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -339, 0, 0, 0, 161, 0, 0, 0, 0, 0, 0, 0, -339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 110 - 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 0, 0, 429, 0, 430, 431, 432, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -305, -305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -305, 0, 433, 434, 0, 0, 0, 435, -305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 111 - 0, -156, 0, 0, -156, 0, 0, 0, 0, 0, 0, 0, 0, 0, -156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -156, 439, 0, -156, 0, -156, -156, -156, 440, 0, 0, 0, 0, 0, 0, 0, 0, 0, -156, 0, -156, -156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -156, 0, -156, -156, 0, 0, 0, -156, -156, 0, 0, 0, 0, 0, 0, 0, 0, 0, -156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 112 - 0, -170, 441, 0, -170, 0, 0, 0, 442, 0, 0, 0, -170, 0, -170, -170, 0, 0, 0, 0, 443, 444, 0, 0, 0, 0, 0, -170, -170, 0, -170, 0, -170, -170, -170, -170, 0, 0, 445, 0, 0, 0, 0, 0, 0, -170, 0, -170, -170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -170, 0, -170, -170, 0, 0, 0, -170, -170, 0, 0, 0, 0, 0, 0, 0, 0, 0, -170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 113 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 114 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -790, 0, 0, -790, 0, 0, 0, 0, 0, 0, 0, 440, 0, -790, 441, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -790, -790, 0, -790, 0, -790, -790, -790, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, -790, 0, -790, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -790, 0, -790, -790, 0, 0, 0, -790, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 115 - 0, 0, 0, 0, 0, 0, 13, 701, 14, 179, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, -248, -248, 0, -248, 0, 25, 0, -248, -248, 0, 0, -248, 0, -248, -248, 0, 0, 175, 0, -248, -248, 0, 0, 0, 0, 0, -248, -248, 0, -248, 0, -248, -248, -248, -248, 0, 0, -248, 0, 0, 0, 0, 176, 0, -248, 0, -248, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -248, 0, -248, -248, 0, 0, 0, -248, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 116 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 703, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 0, 0, 445, 0, 446, 447, 448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -304, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -304, 0, 449, 450, 0, 0, 0, 451, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 117 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, -155, 0, 0, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 455, 0, -155, 0, -155, -155, -155, 456, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, -155, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, -155, -155, 0, 0, 0, -155, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 118 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, -183, -183, 0, -183, 0, -183, 0, -183, -183, 0, 0, -183, 0, -183, -183, 0, 0, -183, 0, -183, -183, 0, 0, -212, 0, 0, -183, -183, 0, -183, 0, -183, -183, -183, -183, 0, 0, -183, 0, 0, 0, 0, -183, 0, -183, 0, -183, -183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -183, 0, -183, -183, 0, 0, 0, -183, -183, 0, 0, 0, 0, 0, 0, 0, 0, 0, -183, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 436, // State 119 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 46, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 707, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, -169, 458, 0, -169, 0, 0, 0, 459, 0, 0, 0, -169, 0, -169, -169, 0, 0, 0, 0, 460, 461, 0, 0, 0, 0, 0, -169, -169, 0, -169, 0, -169, -169, -169, -169, 0, 0, 462, 0, 0, 0, 0, 0, 0, -169, 0, -169, -169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -169, 0, -169, -169, 0, 0, 0, -169, -169, 0, 0, 0, 0, 0, 0, 0, 0, 0, -169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 120 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 121 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, -820, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 122 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, -816, 409, 0, 0, 0, 410, 0, 0, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, -816, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 727, 15, 190, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 123 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, -821, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 729, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 124 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -817, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -817, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 125 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, -777, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, -777, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 126 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 48, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 733, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 127 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 128 - 0, 0, 0, 0, 0, 0, 13, 719, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, -852, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 129 - 0, 0, 0, 0, 0, 0, 0, 721, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, -848, 426, 0, 0, 0, 427, 0, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, -848, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 130 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, -667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, -853, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 131 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, -677, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -849, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -849, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 132 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -692, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, -802, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, -802, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 133 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -689, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 134 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 135 - 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 745, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 136 - 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 747, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 137 - -369, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -369, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 199, 0, 0, 0, 0, 0, 0, 0, 0, 0, -692, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 138 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, -702, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 139 - 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 140 - 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -717, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 141 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -714, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 142 - 0, 0, 0, 0, 0, 0, 0, 0, 200, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 143 - 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, -374, 0, 0, 0, 0, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, // State 144 - 0, 0, 0, 0, 0, 0, 0, 747, 204, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 695, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 145 - -360, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, -360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 146 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 147 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 148 - 0, 0, 0, 0, 0, 0, 206, 0, 753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + -368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -368, 0, 0, 0, 0, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 149 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 150 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 151 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 152 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 153 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 154 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 155 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 781, 217, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 156 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + -359, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, -359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 157 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 158 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 211, 770, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -430, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 159 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 219, 0, 787, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 160 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 161 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 162 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 163 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 164 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 0, // State 165 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 793, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 166 - 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, -306, 0, 0, 428, 0, 0, 429, 0, 430, 431, 432, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -304, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -304, 0, 433, 434, 0, 0, 0, 435, -304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 167 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 168 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 169 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 804, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 170 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 171 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 172 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 173 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 174 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 175 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 176 - 0, 0, 0, 0, 0, 0, 0, 786, 0, 0, 0, 0, 0, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 177 - 0, 0, 0, 0, 0, 0, 0, 789, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -303, 0, 0, 0, 0, 0, 0, 0, 0, 0, -305, 0, 0, 444, 0, 0, 445, 0, 446, 447, 448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -303, -303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -303, 0, 449, 450, 0, 0, 0, 451, -303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 178 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 179 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -527, 0, 0, 0, 0, 0, 533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 180 - 0, -248, -248, 0, -248, 0, 23, 0, -248, -248, 0, 0, -248, 0, -248, -248, 0, 0, 24, 0, -248, -248, 0, 0, -250, 0, 0, -248, -248, 0, -248, 0, -248, -248, -248, -248, 0, 0, -248, 0, 0, 0, 0, 25, 0, -248, 0, -248, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -248, 0, -248, -248, 0, 0, 0, -248, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, -248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 181 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 182 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -848, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -848, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 183 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -815, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -815, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 184 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 185 - 0, 0, 0, 0, 0, 0, 13, 800, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 186 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, -664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 187 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 820, 0, 0, 0, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 188 - 0, 0, 0, 0, 0, 0, 0, 0, 227, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 823, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 189 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -691, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 190 - 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -552, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 191 - 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -247, -247, 0, -247, 0, 25, 0, -247, -247, 0, 0, -247, 0, -247, -247, 0, 0, 26, 0, -247, -247, 0, 0, -249, 0, 0, -247, -247, 0, -247, 0, -247, -247, -247, -247, 0, 0, -247, 0, 0, 0, 0, 27, 0, -247, 0, -247, -247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -247, 0, -247, -247, 0, 0, 0, -247, -247, 0, 0, 0, 0, 0, 0, 0, 0, 0, -247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 192 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 193 - 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 194 - 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -847, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -847, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 195 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 196 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 834, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 197 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, -689, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 198 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -665, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 199 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -675, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 200 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -716, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 201 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, -375, 0, 0, 0, 0, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, // State 202 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 843, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 203 - 0, 0, 0, 0, 0, 0, 0, -620, 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 204 - 0, 0, 0, 0, 0, 0, 0, -441, 0, 0, 0, 0, 0, 0, -441, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 205 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 206 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 207 - -415, 0, 0, 0, 0, 0, -415, 0, -415, 0, 0, 0, -415, 0, 0, -415, 0, 0, 0, -415, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -415, 0, -415, -415, -415, -415, 0, 0, 0, 0, 0, -415, -415, -415, -415, 0, -415, -415, -415, -415, 248, 830, 0, 0, -415, -415, -415, -415, -415, 0, 0, -415, -415, -415, -415, 0, -415, -415, -415, -415, -415, -415, -415, -415, -415, 0, 0, 0, -415, -415, 0, 0, 0, -415, -415, -415, -415, -415, -415, + 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 208 - -856, 0, 0, 0, 0, 0, -856, 0, -856, 0, 0, 0, -856, 0, 0, -856, 0, 0, 0, -856, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -856, 0, -856, -856, -856, -856, 0, 0, 0, 0, 0, -856, -856, -856, -856, 0, -856, -856, -856, -856, 0, 837, 252, 838, -856, -856, -856, -856, -856, 0, 0, -856, -856, -856, -856, 0, -856, -856, -856, -856, -856, -856, -856, -856, -856, 0, 0, 0, -856, -856, 0, 0, 0, -856, -856, -856, -856, -856, -856, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 209 - -860, 0, 0, 0, 0, 0, -860, 0, -860, 0, 0, 0, -860, 0, 0, -860, 0, 0, 0, -860, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -860, 0, -860, -860, -860, -860, 0, 0, 0, 0, 0, -860, -860, -860, -860, 0, -860, -860, -860, -860, 0, 840, 841, 842, -860, -860, -860, -860, -860, 0, 0, -860, -860, -860, -860, 0, -860, -860, -860, -860, -860, -860, -860, -860, -860, 0, 0, 0, -860, -860, 0, 0, 0, -860, -860, -860, -860, -860, -860, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 210 - 0, 0, 0, 0, 0, 0, 13, 0, 253, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 211 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 504, 16, 505, 0, 53, 506, 54, 55, 0, 0, 0, 0, 56, 57, 58, 59, 60, 0, 0, 17, 61, 62, 18, 0, 507, 63, 64, 508, 65, 66, 67, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 212 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 213 - 0, -155, 0, 0, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, -157, 0, 0, -155, 439, 0, -155, 0, -155, -155, -155, 440, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, -155, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, -155, -155, 0, 0, 0, -155, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, -155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 214 - 0, -169, 441, 0, -169, 0, 0, 0, 442, 0, 0, 0, -169, 0, -169, -169, 0, 0, 0, 0, 443, 444, 0, 0, -171, 0, 0, -169, -169, 0, -169, 0, -169, -169, -169, -169, 0, 0, 445, 0, 0, 0, 0, 0, 0, -169, 0, -169, -169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -169, 0, -169, -169, 0, 0, 0, -169, -169, 0, 0, 0, 0, 0, 0, 0, 0, 0, -169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 215 - 0, -764, 0, 0, -764, 0, 0, 0, 0, 0, 0, 0, 424, 0, -764, 425, 0, 0, 0, 0, 0, 0, 0, 0, -766, 0, 0, -764, -764, 0, -764, 0, -764, -764, -764, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, -764, 0, -764, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -764, 0, -764, -764, 0, 0, 0, -764, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 216 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -645, 0, 0, 0, 0, 0, 0, 257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 217 - 0, 0, 0, 0, 0, 0, 13, 852, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -464, 0, 0, 0, 0, 0, 0, -464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 218 - 0, 0, 0, 0, 0, 0, 13, 854, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 219 - 0, 0, 0, 0, 0, 0, 13, 856, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 220 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + -438, 0, 0, 0, 0, 0, 0, -438, 0, -438, 0, 0, 0, -438, 0, 0, -438, 0, 0, 0, -438, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -438, 0, -438, -438, -438, -438, 0, 0, 0, 0, 0, -438, -438, -438, -438, 0, -438, -438, -438, -438, 261, 868, 0, 0, -438, -438, -438, -438, -438, 0, 0, -438, -438, -438, -438, 0, -438, -438, -438, -438, -438, -438, -438, -438, -438, 0, 0, 0, -438, -438, 0, -438, 0, 0, 0, -438, -438, 0, -438, -438, -438, -438, // State 221 - 0, 0, 0, 0, 0, 0, 0, -772, 0, 0, 0, 0, 0, 0, -772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -772, 0, 0, 0, 0, 0, -772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -772, 0, 0, 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -888, 0, 0, 0, 0, 0, 0, -888, 0, -888, 0, 0, 0, -888, 0, 0, -888, 0, 0, 0, -888, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -888, 0, -888, -888, -888, -888, 0, 0, 0, 0, 0, -888, -888, -888, -888, 0, -888, -888, -888, -888, 0, 875, 265, 876, -888, -888, -888, -888, -888, 0, 0, -888, -888, -888, -888, 0, -888, -888, -888, -888, -888, -888, -888, -888, -888, 0, 0, 0, -888, -888, 0, -888, 0, 0, 0, -888, -888, 0, -888, -888, -888, -888, // State 222 - 0, 0, 0, 0, 0, 0, 13, 862, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + -892, 0, 0, 0, 0, 0, 0, -892, 0, -892, 0, 0, 0, -892, 0, 0, -892, 0, 0, 0, -892, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -892, 0, -892, -892, -892, -892, 0, 0, 0, 0, 0, -892, -892, -892, -892, 0, -892, -892, -892, -892, 0, 878, 879, 880, -892, -892, -892, -892, -892, 0, 0, -892, -892, -892, -892, 0, -892, -892, -892, -892, -892, -892, -892, -892, -892, 0, 0, 0, -892, -892, 0, -892, 0, 0, 0, -892, -892, 0, -892, -892, -892, -892, // State 223 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -646, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 266, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 224 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -637, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 525, 17, 526, 0, 57, 527, 58, 59, 0, 0, 0, 0, 60, 61, 62, 63, 64, 0, 0, 18, 65, 66, 19, 0, 528, 67, 68, 529, 69, 70, 71, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 225 - 0, 0, 0, 0, 0, 0, 0, 0, 267, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -651, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 226 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, 0, 0, 0, 0, 0, -668, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, -154, 0, 0, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, -156, 0, 0, -154, 455, 0, -154, 0, -154, -154, -154, 456, 0, 0, 0, 0, 0, 0, 0, 0, 0, -154, 0, -154, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -154, 0, -154, -154, 0, 0, 0, -154, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 227 - 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -168, 458, 0, -168, 0, 0, 0, 459, 0, 0, 0, -168, 0, -168, -168, 0, 0, 0, 0, 460, 461, 0, 0, -170, 0, 0, -168, -168, 0, -168, 0, -168, -168, -168, -168, 0, 0, 462, 0, 0, 0, 0, 0, 0, -168, 0, -168, -168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -168, 0, -168, -168, 0, 0, 0, -168, -168, 0, 0, 0, 0, 0, 0, 0, 0, 0, -168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 228 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, -789, 0, 0, -789, 0, 0, 0, 0, 0, 0, 0, 440, 0, -789, 441, 0, 0, 0, 0, 0, 0, 0, 0, -791, 0, 0, -789, -789, 0, -789, 0, -789, -789, -789, -789, 0, 0, 0, 0, 0, 0, 0, 0, 0, -789, 0, -789, -789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -789, 0, -789, -789, 0, 0, 0, -789, -789, 0, 0, 0, 0, 0, 0, 0, 0, 0, -789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 229 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 230 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 890, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 231 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 892, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 232 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 894, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 233 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 234 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -797, 0, 0, 0, 0, 0, 0, -797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -797, 0, 0, 0, 0, 0, -797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -797, 0, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 235 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 900, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 236 - 0, 0, 0, 0, 0, 0, 0, 0, 200, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 237 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -662, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 238 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 280, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -676, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 239 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, -693, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 240 - 0, 0, 0, 0, 0, 0, 0, -571, 279, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 241 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 242 - 0, 0, 0, 0, 0, 0, 0, -619, 0, 0, 0, 0, 0, 0, 283, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 243 - 0, 0, 0, 0, 0, 0, 0, -612, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 244 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 245 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 246 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 247 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 248 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 249 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 919, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 250 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 251 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 252 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 253 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -596, 292, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 254 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 255 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -644, 0, 0, 0, 0, 0, 0, 296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 256 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 504, 16, 505, 0, 53, 506, 54, 55, 0, 0, 0, 0, 56, 57, 58, 59, 60, 0, 0, 17, 61, 62, 18, 0, 507, 63, 64, 508, 65, 66, 67, 38, 19, 0, 0, 0, 414, 907, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -637, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 257 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 258 - 0, 0, 0, 0, 0, 0, 13, 909, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 259 - 0, 0, 0, 0, 0, 0, 0, 911, 0, 0, 0, 0, 0, 0, 301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 260 - 0, 0, 0, 0, 0, 0, 0, 913, 0, 0, 0, 0, 0, 0, 302, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 261 - 0, 0, 0, 0, 0, 0, 13, 914, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 262 - 0, 0, 0, 0, 0, 0, 0, -770, 0, 0, 0, 0, 0, 0, -770, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -770, 0, 0, 0, 0, 0, -770, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -770, 0, 0, 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -770, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 263 - 0, 0, 0, 0, 0, 0, 0, -773, 0, 0, 0, 0, 0, 0, -773, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -773, 0, 0, 0, 0, 0, -773, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -773, 0, 0, 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -773, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 264 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 265 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 266 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 305, 0, 0, 0, 0, 0, 0, 0, 0, 0, -669, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 267 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 307, 0, 0, 0, 0, 0, 0, 0, 0, 0, -665, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 268 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 269 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 525, 17, 526, 0, 57, 527, 58, 59, 0, 0, 0, 0, 60, 61, 62, 63, 64, 0, 0, 18, 65, 66, 19, 0, 528, 67, 68, 529, 69, 70, 71, 40, 20, 0, 0, 0, 431, 946, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 270 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 271 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 948, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 272 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 950, 0, 0, 0, 0, 0, 0, 314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 273 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 952, 0, 0, 0, 0, 0, 0, 315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 274 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 953, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 275 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -795, 0, 0, 0, 0, 0, 0, -795, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -795, 0, 0, 0, 0, 0, -795, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -795, 0, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -795, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 276 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -798, 0, 0, 0, 0, 0, 0, -798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -798, 0, 0, 0, 0, 0, -798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -798, 0, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 277 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 278 - 0, 0, 0, 0, 0, 0, 0, -589, 0, 0, 0, 0, 0, 0, 314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -668, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 279 - 0, 0, 0, 0, 0, 0, 0, -599, 0, 0, 0, 0, 0, 0, 315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 318, 0, 0, 0, 0, 0, 0, 0, 0, 0, -694, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 280 - 0, 0, 0, 0, 0, 0, 0, -614, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 320, 0, 0, 0, 0, 0, 0, 0, 0, 0, -690, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 281 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 282 - 0, 0, 0, 0, 0, 0, 0, -611, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 283 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 284 - 0, 0, 0, 0, 0, 0, 0, 944, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 285 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 286 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 287 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 288 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 948, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 289 - 0, 0, 0, 0, 0, 0, 325, 0, 326, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 967, 968, 969, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 290 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 291 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 970, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -614, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 292 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -624, 0, 0, 0, 0, 0, 0, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 293 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -639, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 294 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 295 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -636, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 296 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 297 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 983, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 298 - 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 299 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 300 - 0, 0, 0, 0, 0, 0, 13, 985, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 301 - 0, 0, 0, 0, 0, 0, 13, 987, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 987, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 302 - 0, 0, 0, 0, 0, 0, 0, -771, 0, 0, 0, 0, 0, 0, -771, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -771, 0, 0, 0, 0, 0, -771, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -771, 0, 0, 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -771, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 303 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, -666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 304 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -642, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1009, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 305 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -647, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 306 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -638, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 307 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 308 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 309 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 310 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 311 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 312 - 0, 0, 0, 0, 0, 0, 0, -586, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 313 - 0, 0, 0, 0, 0, 0, 0, -562, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 1024, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 314 - 0, 0, 0, 0, 0, 0, 0, -572, 344, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 1026, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 315 - 0, 0, 0, 0, 0, 0, 0, -613, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -796, 0, 0, 0, 0, 0, 0, -796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -796, 0, 0, 0, 0, 0, -796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -796, 0, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 316 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 350, 0, 0, 0, 0, 0, 0, 0, 0, 0, -691, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 317 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 318 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 319 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1009, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 320 - 0, 0, 0, 0, 0, 0, 0, -453, 0, 0, 0, 0, 424, 0, -453, 425, 0, 0, 0, 0, 0, 0, 0, 0, -453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -453, 0, 0, 0, -453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -453, 0, -453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 321 - 0, 0, 0, 0, 0, 0, 349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 350, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 322 - 0, 0, 0, 0, 0, 0, 349, -887, 0, 0, 0, 0, 0, 0, -887, 0, 0, 0, 351, 0, 0, 0, 0, 0, -887, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -887, 0, 0, 0, -887, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -887, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -887, 0, -887, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 323 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 324 - 0, 0, 0, 0, 0, 0, 325, 1014, 326, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 967, 968, 969, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 325 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -611, 0, 0, 0, 0, 0, 0, 356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 326 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 415, 416, 417, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -587, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 327 - 0, 0, 0, 0, 0, 0, 325, 0, 326, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 967, 968, 969, 328, 1018, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -597, 358, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 328 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 361, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1027, 1028, 1029, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1030, 0, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -638, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 329 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1031, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 330 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 331 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 332 - 0, 0, 0, 0, 0, 0, 13, 1040, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1048, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 333 - 0, 0, 0, 0, 0, 0, 13, 1041, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -478, 0, 0, 0, 0, 440, 0, -478, 441, 0, 0, 0, 0, 0, 0, 0, 0, -478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -478, 0, 0, 0, -478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -478, 0, -478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 334 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -648, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 364, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 335 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -639, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 363, -919, 0, 0, 0, 0, 0, 0, -919, 0, 0, 0, 365, 0, 0, 0, 0, 0, -919, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -919, 0, 0, 0, -919, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -919, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -919, 0, -919, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 336 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -644, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 369, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 337 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -480, 0, 0, 0, 0, 0, 0, -480, 0, 0, 0, 0, 0, 0, 0, 0, 0, -480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -480, 0, 0, 0, -480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -480, 0, -480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 436, // State 338 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 339, 1054, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 339 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 340 - 0, 0, 0, 0, 0, 0, 0, -568, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 0, 0, // State 341 - 0, 0, 0, 0, 0, 0, 0, -559, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 1058, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 342 - 0, 0, 0, 0, 0, 0, 0, -573, 367, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 376, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1066, 1067, 1068, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1069, 0, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 343 - 0, 0, 0, 0, 0, 0, 0, -590, 0, 0, 0, 0, 0, 0, 369, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1070, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 344 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 345 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 346 - 0, 0, 0, 0, 0, 0, 325, 0, 326, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 967, 968, 969, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 14, 1079, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 347 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 415, 416, 417, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 1080, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 348 - 0, 0, 0, 0, 0, 0, 325, 1067, 326, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 967, 968, 969, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -673, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 349 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 350 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -669, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 351 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 352 - 0, 0, 0, 0, 0, 0, 325, 0, 326, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, -735, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 967, 968, 969, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -735, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 353 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 354 - 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -593, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 355 - 0, 0, 0, 0, 0, 0, 325, 0, 326, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 967, 968, 969, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -584, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 356 - 0, 0, 0, 0, 0, 0, 325, 0, 326, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, -736, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 967, 968, 969, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -736, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -598, 382, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 357 - 0, 0, 0, 0, 0, 0, 325, 0, 326, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 967, 968, 969, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -615, 0, 0, 0, 0, 0, 0, 384, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 358 - 0, 0, 0, 0, 0, 0, 325, 0, 326, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 967, 968, 969, 328, 1080, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 359 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 424, 0, 0, 425, 0, 0, 0, 0, 0, 0, 0, 0, -457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 360 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 361 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 0, 0, // State 362 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 339, 1106, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 363 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 364 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 365 - 0, 0, 0, 0, 0, 0, 0, -565, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 366 - 0, 0, 0, 0, 0, 0, 0, -591, 0, 0, 0, 0, 0, 0, 377, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, -760, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -760, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 367 - 0, 0, 0, 0, 0, 0, 0, -587, 0, 0, 0, 0, 0, 0, 379, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 368 - 0, 0, 0, 0, 0, 0, 0, -563, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 369 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 370 - 0, 0, 0, 0, 0, 0, 325, 0, 326, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 967, 968, 969, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, -761, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -761, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 371 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 383, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1027, 1028, 1029, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1110, 0, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 372 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 1119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 373 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 440, 0, 0, 441, 0, 0, 0, 0, 0, 0, 0, 0, -482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 374 - 691, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 0, 408, 0, 0, 409, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 412, 413, 15, 0, 0, 0, 0, 0, 52, 0, 16, 505, 0, 0, 506, 0, 55, 0, 0, 0, 0, 0, 57, 58, 0, 60, 0, 0, 17, 0, 62, 18, 0, 507, 63, 64, 0, 65, 0, 0, 38, 19, 0, 0, 0, 414, 0, 0, 0, 0, 415, 416, 417, 509, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 436, // State 375 - 0, 0, 0, 0, 0, 0, 0, -588, 0, 0, 0, 0, 0, 0, 385, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 376 - 0, 0, 0, 0, 0, 0, 0, -564, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 377 - 0, 0, 0, 0, 0, 0, 0, -569, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 378 - 0, 0, 0, 0, 0, 0, 0, -560, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 379 - 0, 0, 0, 0, 0, 0, 325, 0, 326, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 967, 968, 969, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 380 - 0, 0, 0, 0, 0, 0, 0, 1126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -590, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 381 - 0, 0, 0, 0, 0, 0, 325, 1129, 326, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 967, 968, 969, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 415, 416, 417, 0, 418, 419, + 0, 0, 0, 0, 0, 0, 0, 0, -616, 0, 0, 0, 0, 0, 0, 392, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 382 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -612, 0, 0, 0, 0, 0, 0, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 383 - 0, 0, 0, 0, 0, 0, 0, -570, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -588, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 384 - 0, 0, 0, 0, 0, 0, 0, -561, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 385 - 0, 0, 0, 0, 0, 0, 0, -566, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 386 - 0, 0, 0, 0, 0, 0, 0, -567, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 398, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1066, 1067, 1068, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1149, 0, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 387 - 0, 0, 0, 0, 0, 0, 0, 1146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 388 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 389 - -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, 0, -184, 0, -184, -184, -184, -184, -184, 0, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, 0, 0, 0, -184, -184, -184, -184, -184, -184, 0, -184, 0, 0, 0, 0, 0, 0, 0, 0, -184, 0, 0, -184, -184, 0, -184, 0, -184, -184, 0, 0, 0, -184, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, -184, -184, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 422, + 717, 0, 0, 0, 0, 0, 0, 14, 0, 15, 0, 0, 0, 425, 0, 0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, 430, 16, 0, 0, 0, 0, 0, 56, 0, 17, 526, 0, 0, 527, 0, 59, 0, 0, 0, 0, 0, 61, 62, 0, 64, 0, 0, 18, 0, 66, 19, 0, 528, 67, 68, 0, 69, 0, 0, 40, 20, 0, 0, 0, 431, 0, 0, 21, 0, 0, 0, 432, 433, 0, 434, 530, 435, 436, // State 390 - -911, -911, 0, -911, 21, -911, 0, -911, 0, 0, -911, -911, 0, -911, -911, 0, -911, 0, 0, 0, 0, 0, -911, -911, -911, 0, -911, -911, 0, -911, -911, -911, -911, -911, -911, 0, -911, -911, 0, -911, 0, 0, 0, 0, -911, -911, -911, -911, -911, 0, -911, 0, 0, 0, 0, 0, 0, 0, 0, -911, 0, 0, -911, -911, 0, -911, 0, -911, -911, 0, 0, 0, -911, -911, 0, 0, 0, 0, 0, 0, 0, 0, 0, -911, -911, -911, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -613, 0, 0, 0, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 391 - -534, 0, 0, -534, 0, -534, 0, -534, 0, 0, -534, -534, 0, -534, -534, 0, -534, 0, 0, 0, 0, 0, -534, -534, -534, 0, -534, 0, 0, -534, 0, -534, 0, 0, 0, 0, -534, 0, 0, -534, 0, 0, 0, 0, -534, 0, -534, 0, -534, 0, -534, 0, 0, 0, 0, 0, 0, 0, 0, -534, 0, 0, -534, -534, 0, -534, 0, 0, 0, 0, 0, 0, 0, 423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -534, -534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -589, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 392 - -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, 0, -240, 0, -240, -240, -240, -240, -240, 0, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, 0, 0, 0, -240, -240, -240, -240, -240, -240, 0, -240, 0, 0, 0, 0, 0, 0, 0, 0, -240, 0, 0, -240, -240, 0, -240, 0, -240, -240, 0, 0, 0, -240, -240, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, -240, -240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -594, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 393 - -740, -740, -740, -740, -740, -740, 0, -740, -740, 26, -740, -740, -740, -740, -740, -740, -740, 0, 0, 0, -740, -740, -740, -740, -740, 0, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, -740, 0, 0, 0, 0, -740, -740, -740, -740, -740, 0, -740, 0, 0, 0, 0, 0, 0, 0, 0, -740, 0, 0, -740, -740, 0, -740, 0, -740, -740, 0, 0, 0, -740, -740, 0, 0, 0, 0, 0, 0, 0, 0, 0, -740, -740, -740, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -585, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 394 - -496, 0, 0, -496, 0, -496, 0, -496, 0, 0, -496, -496, 0, -496, -496, 0, -496, 0, 0, 0, 0, 0, -496, -496, -496, 0, -496, 0, 0, -496, 0, -496, 0, 0, 0, 0, -496, 0, 0, -496, 0, 0, 0, 0, -496, 0, -496, -496, -496, 0, -496, 0, 0, 0, 0, 0, 0, 0, 0, -496, 0, 0, -496, -496, 0, -496, 0, 0, 0, 0, 0, 0, 0, -496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -496, -496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 339, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 395 - -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, 0, -185, 0, -185, -185, -185, -185, -185, 0, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, 0, 0, 0, -185, -185, -185, -185, -185, -185, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, 0, -185, -185, 0, -185, 0, -185, -185, 0, 0, 0, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 396 - -829, -829, -829, -829, -829, -829, 0, -829, -829, 0, -829, -829, -829, -829, -829, -829, -829, 0, 0, 0, -829, -829, -829, -829, -829, 0, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, -829, 0, 0, 0, 0, -829, -829, -829, -829, -829, 0, -829, 0, 0, 0, 0, 0, 0, 0, 0, -829, 0, 0, -829, -829, 0, -829, 0, -829, -829, 0, 0, 0, -829, -829, 0, 0, 0, 0, 0, 0, 0, 0, 0, -829, -829, -829, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 339, 1168, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1006, 1007, 1008, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 433, 0, 434, 0, 435, 436, // State 397 - -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, 0, -186, 0, -186, -186, -186, -186, -186, 0, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, 0, 0, 0, -186, -186, -186, -186, -186, -186, 0, -186, 0, 0, 0, 0, 0, 0, 0, 0, -186, 0, 0, -186, -186, 0, -186, 0, -186, -186, 0, 0, 0, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, -186, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 398 - -834, 0, 0, -834, 0, -834, 0, -834, 0, 0, -834, -834, 0, -834, -834, 0, -834, 0, 0, 0, 0, 0, -834, -834, -834, 0, -834, 0, 0, -834, 0, -834, 0, 0, 0, 0, -834, 0, 0, -834, 0, 0, 0, 0, -834, 0, -834, 0, -834, 0, -834, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -834, -834, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -834, -834, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -595, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 399 - -160, 0, 0, -160, 0, -160, 0, -160, 0, 0, -160, -160, 0, -160, -160, 0, -160, 0, 0, 0, 0, 0, -160, -160, -160, 0, -160, 0, 0, -160, 0, -160, 0, 0, 0, 0, -160, 0, 0, -160, 0, 0, 0, 0, -160, 0, -160, 438, -160, 0, -160, 0, 0, 0, 0, 0, 0, 0, 0, -160, 0, 0, -160, -160, 0, -160, 0, 0, 0, 0, 0, 0, 0, -160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -160, -160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -586, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 400 - -410, 0, 0, -410, 0, -410, 0, -410, 0, 0, -410, -410, 0, -410, 30, 0, -410, 0, 0, 0, 0, 0, -410, -410, -410, 0, -410, 0, 0, -410, 0, -410, 0, 0, 0, 0, -410, 0, 0, -410, 0, 0, 0, 0, 0, 0, -410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -591, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 401 - -833, 0, 0, -833, 0, -833, 0, -833, 0, 0, -833, -833, 0, -833, -833, 0, -833, 0, 0, 0, 0, 0, -833, -833, -833, 0, -833, 0, 0, -833, 0, -833, 0, 0, 0, 0, -833, 0, 0, -833, 0, 0, 0, 0, -833, 0, -833, 0, -833, 0, -833, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -833, -833, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -833, -833, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -592, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 402 - -371, -371, -371, -371, -371, -371, 0, -371, -371, 0, -371, -371, -371, -371, -371, -371, -371, 0, 0, 0, -371, -371, -371, -371, -371, 0, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, -371, 0, 0, 0, 0, -371, -371, -371, -371, -371, 0, -371, 0, 0, 0, 0, 0, 0, 0, 0, -371, 0, 0, -371, -371, 0, -371, 0, -371, -371, 0, 0, 0, -371, -371, 0, 0, 0, 0, 0, 0, 0, 0, 0, -371, -371, -371, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, // State 403 - -846, 0, 0, -846, 0, -846, 0, -846, 0, 0, -846, -846, 0, -846, -846, 0, -846, 0, 0, 0, 0, 0, -846, -846, -846, 0, -846, 0, 0, -846, 0, -846, 0, 0, 0, 0, -846, 0, 0, -846, 0, 0, 0, 0, 0, 0, -846, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -846, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 404 - -845, 0, 0, -845, 0, -845, 0, -845, 0, 0, -845, -845, 0, -845, -845, 0, -845, 0, 0, 0, 0, 0, -845, -845, -845, 0, -845, 0, 0, -845, 0, -845, 0, 0, 0, 0, -845, 0, 0, -845, 0, 0, 0, 0, 0, 0, -845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -943, -943, -943, 0, -943, 23, -943, 0, -943, 0, 0, -943, -943, 0, -943, -943, 0, -943, 0, 0, 0, 0, 0, -943, -943, -943, 0, -943, -943, 0, -943, -943, -943, -943, -943, -943, 0, -943, -943, 0, -943, 0, 0, 0, 0, -943, -943, -943, -943, -943, 0, -943, 0, 0, 0, 0, 0, 0, 0, 0, -943, 0, 0, -943, -943, 0, -943, 0, -943, -943, 0, 0, 0, -943, -943, 0, 0, 0, 0, 0, 0, 0, 0, 0, -943, -943, -943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 405 - -525, 0, 0, -525, 0, -525, 0, -525, 0, 0, -525, -525, 0, -525, -525, 0, -525, 0, 0, 0, 0, 0, -525, -525, -525, 0, -525, 0, 0, -525, 0, -525, 0, 0, 0, 0, -525, 0, 0, -525, 0, 0, 0, 0, 0, 0, -525, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -525, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -559, -559, 0, 0, -559, 0, -559, 0, -559, 0, 0, -559, -559, 0, -559, -559, 0, -559, 0, 0, 0, 0, 0, -559, -559, -559, 0, -559, 0, 0, -559, 0, -559, 0, 0, 0, 0, -559, 0, 0, -559, 0, 0, 0, 0, -559, 0, -559, 0, -559, 0, -559, 0, 0, 0, 0, 0, 0, 0, 0, -559, 0, 0, -559, -559, 0, -559, 0, 0, 0, 0, 0, 0, 0, 439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -559, -559, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 406 - -356, -356, 0, -356, 0, -356, 0, -356, 0, 0, -356, -356, 0, -356, -356, 0, -356, 0, 0, 0, 0, 0, -356, -356, -356, 0, -356, -356, 0, -356, -356, -356, -356, -356, -356, 0, -356, -356, 0, -356, 0, 0, 0, 0, -356, 34, -356, -356, -356, 0, -356, 0, 0, 0, 0, 0, 0, 0, 0, -356, 0, 0, -356, -356, 0, -356, 0, -356, -356, 0, 0, 0, -356, -356, 0, 0, 0, 0, 0, 0, 0, 0, 0, -356, -356, -356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, 0, -239, 0, -239, -239, -239, -239, -239, 0, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, 0, 0, 0, -239, -239, -239, -239, -239, -239, 0, -239, 0, 0, 0, 0, 0, 0, 0, 0, -239, 0, 0, -239, -239, 0, -239, 0, -239, -239, 0, 0, 0, -239, -239, 0, 0, 0, 0, 0, 0, 0, 0, 0, -239, -239, -239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 407 - 0, 0, 0, 0, 0, 0, -883, 0, 0, 0, 0, 0, -883, 0, 0, -883, 0, 0, 0, -883, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -883, -883, -883, -883, 0, 0, 0, 0, 0, 0, 0, -883, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -883, 0, 0, 0, -883, 0, 0, 0, 0, -883, -883, -883, 0, -883, -883, + -765, -765, -765, -765, -765, -765, -765, 0, -765, -765, 28, -765, -765, -765, -765, -765, -765, -765, 0, 0, 0, -765, -765, -765, -765, -765, 0, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, 0, 0, 0, 0, -765, -765, -765, -765, -765, 0, -765, 0, 0, 0, 0, 0, 0, 0, 0, -765, 0, 0, -765, -765, 0, -765, 0, -765, -765, 0, 0, 0, -765, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, -765, -765, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 408 - 0, 0, 0, 0, 0, 0, -884, 0, 0, 0, 0, 0, -884, 0, 0, -884, 0, 0, 0, -884, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -884, -884, -884, -884, 0, 0, 0, 0, 0, 0, 0, -884, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -884, 0, 0, 0, -884, 0, 0, 0, 0, -884, -884, -884, 0, -884, -884, + -521, -521, 0, 0, -521, 0, -521, 0, -521, 0, 0, -521, -521, 0, -521, -521, 0, -521, 0, 0, 0, 0, 0, -521, -521, -521, 0, -521, 0, 0, -521, 0, -521, 0, 0, 0, 0, -521, 0, 0, -521, 0, 0, 0, 0, -521, 0, -521, -521, -521, 0, -521, 0, 0, 0, 0, 0, 0, 0, 0, -521, 0, 0, -521, -521, 0, -521, 0, 0, 0, 0, 0, 0, 0, -521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -521, -521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 409 - -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, 0, -212, 0, -212, -212, -212, -212, -212, 0, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, 0, 0, 0, -212, -212, -212, -212, -212, -212, 0, -212, 0, 0, 0, 0, 0, 0, 0, 0, -212, 0, 0, -212, -212, 0, -212, 0, -212, -212, 0, 0, 0, -212, -212, 0, 0, 0, 0, 0, 0, 0, 0, 0, -212, -212, -212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, 0, -184, 0, -184, -184, -184, -184, -184, 0, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, -184, 0, 0, 0, -184, -184, -184, -184, -184, -184, 0, -184, 0, 0, 0, 0, 0, 0, 0, 0, -184, 0, 0, -184, -184, 0, -184, 0, -184, -184, 0, 0, 0, -184, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, -184, -184, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 410 - -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, 0, -210, 0, -210, -210, -210, -210, -210, 0, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, 0, 0, 0, -210, -210, -210, -210, -210, -210, 0, -210, 0, 0, 0, 0, 0, 0, 0, 0, -210, 0, 0, -210, -210, 0, -210, 0, -210, -210, 0, 0, 0, -210, -210, 0, 0, 0, 0, 0, 0, 0, 0, 0, -210, -210, -210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, 0, -839, 0, -839, -839, -839, -839, -839, 0, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, -839, 0, 0, 0, -839, -839, -839, -839, -839, -839, 0, -839, 0, 0, 0, 0, 0, 0, 0, 0, -839, 0, 0, -839, -839, 0, -839, 0, -839, -839, 0, 0, 0, -839, -839, 0, 0, 0, 0, 0, 0, 0, 0, 0, -839, -839, -839, 0, 0, 0, -839, 0, 0, 0, 0, 0, 0, 0, 0, 0, -839, // State 411 - -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, 0, -211, 0, -211, -211, -211, -211, -211, 0, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, 0, 0, 0, -211, -211, -211, -211, -211, -211, 0, -211, 0, 0, 0, 0, 0, 0, 0, 0, -211, 0, 0, -211, -211, 0, -211, 0, -211, -211, 0, 0, 0, -211, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, -211, -211, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -861, -861, -861, -861, -861, -861, -861, 0, -861, -861, 0, -861, -861, -861, -861, -861, -861, -861, 0, 0, 0, -861, -861, -861, -861, -861, 0, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, -861, 0, 0, 0, 0, -861, -861, -861, -861, -861, 0, -861, 0, 0, 0, 0, 0, 0, 0, 0, -861, 0, 0, -861, -861, 0, -861, 0, -861, -861, 0, 0, 0, -861, -861, 0, 0, 0, 0, 0, 0, 0, 0, 0, -861, -861, -861, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 412 - -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, 0, -209, 0, -209, -209, -209, -209, -209, 0, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, 0, 0, 0, -209, -209, -209, -209, -209, -209, 0, -209, 0, 0, 0, 0, 0, 0, 0, 0, -209, 0, 0, -209, -209, 0, -209, 0, -209, -209, 0, 0, 0, -209, -209, 0, 0, 0, 0, 0, 0, 0, 0, 0, -209, -209, -209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, 0, -185, 0, -185, -185, -185, -185, -185, 0, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, -185, 0, 0, 0, -185, -185, -185, -185, -185, -185, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, 0, -185, -185, 0, -185, 0, -185, -185, 0, 0, 0, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 413 - 0, 0, 0, 0, 0, 0, -885, 0, 0, 0, 0, 0, -885, 0, 0, -885, 0, 0, 0, -885, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -885, -885, -885, -885, 0, 0, 0, 0, 0, 0, 0, -885, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -885, 0, 0, 0, -885, 0, 0, 0, 0, -885, -885, -885, 0, -885, -885, + -866, -866, 0, 0, -866, 0, -866, 0, -866, 0, 0, -866, -866, 0, -866, -866, 0, -866, 0, 0, 0, 0, 0, -866, -866, -866, 0, -866, 0, 0, -866, 0, -866, 0, 0, 0, 0, -866, 0, 0, -866, 0, 0, 0, 0, -866, 0, -866, 0, -866, 0, -866, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -866, -866, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -866, -866, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 414 - -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, 0, -323, 0, -323, -323, -323, -323, -323, 0, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, -323, 0, 0, 0, -323, -323, -323, -323, -323, -323, 0, -323, 0, 0, 0, 0, 0, 0, 0, 0, -323, 0, 0, -323, -323, 0, -323, 0, -323, -323, 0, 0, 0, -323, -323, 0, 0, 0, 0, 0, 0, 0, 0, 0, -323, -323, -323, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -159, -159, 0, 0, -159, 0, -159, 0, -159, 0, 0, -159, -159, 0, -159, -159, 0, -159, 0, 0, 0, 0, 0, -159, -159, -159, 0, -159, 0, 0, -159, 0, -159, 0, 0, 0, 0, -159, 0, 0, -159, 0, 0, 0, 0, -159, 0, -159, 454, -159, 0, -159, 0, 0, 0, 0, 0, 0, 0, 0, -159, 0, 0, -159, -159, 0, -159, 0, 0, 0, 0, 0, 0, 0, -159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -159, -159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 415 - -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, 0, -322, 0, -322, -322, -322, -322, -322, 0, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, 0, 0, 0, -322, -322, -322, -322, -322, -322, 0, -322, 0, 0, 0, 0, 0, 0, 0, 0, -322, 0, 0, -322, -322, 0, -322, 0, -322, -322, 0, 0, 0, -322, -322, 0, 0, 0, 0, 0, 0, 0, 0, 0, -322, -322, -322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -433, -433, 0, 0, -433, 0, -433, 0, -433, 0, 0, -433, -433, 0, -433, 32, 0, -433, 0, 0, 0, 0, 0, -433, -433, -433, 0, -433, 0, 0, -433, 0, -433, 0, 0, 0, 0, -433, 0, 0, -433, 0, 0, 0, 0, 0, 0, -433, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -433, -433, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 416 - -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, 0, -321, 0, -321, -321, -321, -321, -321, 0, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, 0, 0, 0, -321, -321, -321, -321, -321, -321, 0, -321, 0, 0, 0, 0, 0, 0, 0, 0, -321, 0, 0, -321, -321, 0, -321, 0, -321, -321, 0, 0, 0, -321, -321, 0, 0, 0, 0, 0, 0, 0, 0, 0, -321, -321, -321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -865, -865, 0, 0, -865, 0, -865, 0, -865, 0, 0, -865, -865, 0, -865, -865, 0, -865, 0, 0, 0, 0, 0, -865, -865, -865, 0, -865, 0, 0, -865, 0, -865, 0, 0, 0, 0, -865, 0, 0, -865, 0, 0, 0, 0, -865, 0, -865, 0, -865, 0, -865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -865, -865, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -865, -865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 417 - -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, 0, -413, 0, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, 0, 0, 0, -413, -413, -413, -413, -413, -413, 0, -413, 0, 0, 0, 0, 0, 0, 0, 0, -413, 0, 0, -413, -413, 0, -413, -413, -413, -413, 0, 0, 0, -413, -413, 0, 0, 0, 0, 0, 0, 0, 0, 0, -413, -413, -413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -394, -394, -394, -394, -394, -394, -394, 0, -394, -394, 0, -394, -394, -394, -394, -394, -394, -394, 0, 0, 0, -394, -394, -394, -394, -394, 0, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, -394, 0, 0, 0, 0, -394, -394, -394, -394, -394, 0, -394, 0, 0, 0, 0, 0, 0, 0, 0, -394, 0, 0, -394, -394, 0, -394, 0, -394, -394, 0, 0, 0, -394, -394, 0, 0, 0, 0, 0, 0, 0, 0, 0, -394, -394, -394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 418 - -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, 0, -139, 0, -139, -139, -139, -139, -139, 0, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, -139, 0, 0, 0, -139, -139, -139, -139, -139, -139, 0, -139, 0, 0, 0, 0, 0, 0, 0, 0, -139, 0, 0, -139, -139, 0, -139, 0, -139, -139, 0, 0, 0, -139, -139, 0, 0, 0, 0, 0, 0, 0, 0, 0, -139, -139, -139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -139, + -878, -878, 0, 0, -878, 0, -878, 0, -878, 0, 0, -878, -878, 0, -878, -878, 0, -878, 0, 0, 0, 0, 0, -878, -878, -878, 0, -878, 0, 0, -878, 0, -878, 0, 0, 0, 0, -878, 0, 0, -878, 0, 0, 0, 0, 0, 0, -878, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -878, -878, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 419 - -533, 0, 0, -533, 0, -533, 0, -533, 0, 0, -533, -533, 0, -533, -533, 0, -533, 0, 0, 0, 0, 0, -533, -533, -533, 0, -533, 0, 0, -533, 0, -533, 0, 0, 0, 0, -533, 0, 0, -533, 0, 0, 0, 0, -533, 0, -533, 0, -533, 0, -533, 0, 0, 0, 0, 0, 0, 0, 0, -533, 0, 0, -533, -533, 0, -533, 0, 0, 0, 0, 0, 0, 0, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -533, -533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, 0, -838, 0, -838, -838, -838, -838, -838, 0, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, -838, 0, 0, 0, -838, -838, -838, -838, -838, -838, 0, -838, 0, 0, 0, 0, 0, 0, 0, 0, -838, 0, 0, -838, -838, 0, -838, 0, -838, -838, 0, 0, 0, -838, -838, 0, 0, 0, 0, 0, 0, 0, 0, 0, -838, -838, -838, 0, 0, 0, -838, 0, 0, 0, 0, 0, 0, 0, 0, 0, -838, // State 420 - -159, 0, 0, -159, 0, -159, 0, -159, 0, 0, -159, -159, 0, -159, -159, 0, -159, 0, 0, 0, 0, 0, -159, -159, -159, 0, -159, 0, 0, -159, 0, -159, 0, 0, 0, 0, -159, 0, 0, -159, 0, 0, 0, 0, -159, 0, -159, 511, -159, 0, -159, 0, 0, 0, 0, 0, 0, 0, 0, -159, 0, 0, -159, -159, 0, -159, 0, 0, 0, 0, 0, 0, 0, -159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -159, -159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, 0, -840, 0, -840, -840, -840, -840, -840, 0, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, -840, 0, 0, 0, -840, -840, -840, -840, -840, -840, 0, -840, 0, 0, 0, 0, 0, 0, 0, 0, -840, 0, 0, -840, -840, 0, -840, 0, -840, -840, 0, 0, 0, -840, -840, 0, 0, 0, 0, 0, 0, 0, 0, 0, -840, -840, -840, 0, 0, 0, -840, 0, 0, 0, 0, 0, 0, 0, 0, 0, -840, // State 421 - -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, 0, -140, 0, -140, -140, -140, -140, -140, 0, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, 0, 0, 0, -140, -140, -140, -140, -140, -140, 0, -140, 0, 0, 0, 0, 0, 0, 0, 0, -140, 0, 0, -140, -140, 0, -140, 0, -140, -140, 0, 0, 0, -140, -140, 0, 0, 0, 0, 0, 0, 0, 0, 0, -140, -140, -140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -140, + -877, -877, 0, 0, -877, 0, -877, 0, -877, 0, 0, -877, -877, 0, -877, -877, 0, -877, 0, 0, 0, 0, 0, -877, -877, -877, 0, -877, 0, 0, -877, 0, -877, 0, 0, 0, 0, -877, 0, 0, -877, 0, 0, 0, 0, 0, 0, -877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -877, -877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 422 - 0, 0, 0, 0, 0, 0, -111, 0, 0, 0, 0, 0, -111, 0, 0, -111, 0, 0, 0, -111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -111, -111, -111, -111, 0, 0, 0, 0, 0, 0, 0, -111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -111, 0, 0, 0, 0, 0, 0, 0, 0, 0, -111, 0, 0, 0, -111, 0, 0, 0, 0, -111, -111, -111, 0, -111, -111, + -550, -550, 0, 0, -550, 0, -550, 0, -550, 0, 0, -550, -550, 0, -550, -550, 0, -550, 0, 0, 0, 0, 0, -550, -550, -550, 0, -550, 0, 0, -550, 0, -550, 0, 0, 0, 0, -550, 0, 0, -550, 0, 0, 0, 0, 0, 0, -550, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -550, -550, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 423 - 0, 0, 0, 0, 0, 0, -152, 0, 0, 0, 0, 0, -152, 0, 0, -152, 0, 0, 0, -152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -152, -152, -152, -152, 0, 0, 0, 0, 0, 0, 0, -152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -152, 0, 0, 0, -152, 0, 0, 0, 0, -152, -152, -152, 0, -152, -152, + -355, -355, -355, 0, -355, 0, -355, 0, -355, 0, 0, -355, -355, 0, -355, -355, 0, -355, 0, 0, 0, 0, 0, -355, -355, -355, 0, -355, -355, 0, -355, -355, -355, -355, -355, -355, 0, -355, -355, 0, -355, 0, 0, 0, 0, -355, 36, -355, -355, -355, 0, -355, 0, 0, 0, 0, 0, 0, 0, 0, -355, 0, 0, -355, -355, 0, -355, 0, -355, -355, 0, 0, 0, -355, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, -355, -355, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 424 - 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, 0, 0, -153, 0, 0, -153, 0, 0, 0, -153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -153, -153, -153, -153, 0, 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, -153, 0, 0, 0, 0, -153, -153, -153, 0, -153, -153, + 0, 0, 0, 0, 0, 0, 0, -915, 0, 0, 0, 0, 0, -915, 0, 0, -915, 0, 0, 0, -915, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -915, -915, -915, -915, 0, 0, 0, 0, 0, 0, 0, -915, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -915, 0, 0, 0, -915, 0, 0, -915, 0, 0, 0, -915, -915, 0, -915, 0, -915, -915, // State 425 - -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, 0, -241, 0, -241, -241, -241, -241, -241, 0, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, 0, 0, 0, -241, -241, -241, -241, -241, -241, 0, -241, 0, 0, 0, 0, 0, 0, 0, 0, -241, 0, 0, -241, -241, 0, -241, 0, -241, -241, 0, 0, 0, -241, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, -241, -241, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -916, 0, 0, 0, 0, 0, -916, 0, 0, -916, 0, 0, 0, -916, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -916, -916, -916, -916, 0, 0, 0, 0, 0, 0, 0, -916, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -916, 0, 0, 0, -916, 0, 0, -916, 0, 0, 0, -916, -916, 0, -916, 0, -916, -916, // State 426 - 0, 0, 0, 0, 0, 0, -295, 0, 0, 0, 0, 0, -295, 0, 0, -295, 0, 0, 0, -295, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -295, -295, -295, -295, 0, 0, 0, 0, 0, 0, 0, -295, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -295, 0, 0, 0, -295, 0, 0, 0, 0, -295, -295, -295, 0, -295, -295, + -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, 0, -211, 0, -211, -211, -211, -211, -211, 0, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, -211, 0, 0, 0, -211, -211, -211, -211, -211, -211, 0, -211, 0, 0, 0, 0, 0, 0, 0, 0, -211, 0, 0, -211, -211, 0, -211, 0, -211, -211, 0, 0, 0, -211, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, -211, -211, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 427 - 0, 0, 0, 0, 0, 0, -296, 0, 0, 0, 0, 0, -296, 0, 0, -296, 0, 0, 0, -296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -296, -296, -296, -296, 0, 0, 0, 0, 0, 0, 0, -296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -296, 0, 0, 0, -296, 0, 0, 0, 0, -296, -296, -296, 0, -296, -296, + -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, 0, -209, 0, -209, -209, -209, -209, -209, 0, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, -209, 0, 0, 0, -209, -209, -209, -209, -209, -209, 0, -209, 0, 0, 0, 0, 0, 0, 0, 0, -209, 0, 0, -209, -209, 0, -209, 0, -209, -209, 0, 0, 0, -209, -209, 0, 0, 0, 0, 0, 0, 0, 0, 0, -209, -209, -209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 428 - 0, 0, 0, 0, 0, 0, -297, 0, 0, 0, 0, 0, -297, 0, 0, -297, 0, 0, 0, -297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -297, -297, -297, -297, 0, 0, 0, 0, 0, 0, 0, -297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -297, 0, 0, 0, -297, 0, 0, 0, 0, -297, -297, -297, 0, -297, -297, + -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, 0, -210, 0, -210, -210, -210, -210, -210, 0, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, -210, 0, 0, 0, -210, -210, -210, -210, -210, -210, 0, -210, 0, 0, 0, 0, 0, 0, 0, 0, -210, 0, 0, -210, -210, 0, -210, 0, -210, -210, 0, 0, 0, -210, -210, 0, 0, 0, 0, 0, 0, 0, 0, 0, -210, -210, -210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 429 - 0, 0, 0, 0, 0, 0, -294, 0, 0, 0, 0, 0, -294, 0, 0, -294, 0, 0, 0, -294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -294, -294, -294, -294, 0, 0, 0, 0, 0, 0, 0, -294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -294, 0, 0, 0, -294, 0, 0, 0, 0, -294, -294, -294, 0, -294, -294, + -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, 0, -208, 0, -208, -208, -208, -208, -208, 0, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, 0, 0, 0, -208, -208, -208, -208, -208, -208, 0, -208, 0, 0, 0, 0, 0, 0, 0, 0, -208, 0, 0, -208, -208, 0, -208, 0, -208, -208, 0, 0, 0, -208, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, -208, -208, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 430 - 0, 0, 0, 0, 0, 0, -298, 0, 0, 0, 0, 0, -298, 0, 0, -298, 0, 0, 0, -298, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -298, -298, -298, -298, 0, 0, 0, 0, 0, 0, 0, -298, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -298, 0, 0, 0, -298, 0, 0, 0, 0, -298, -298, -298, 0, -298, -298, + 0, 0, 0, 0, 0, 0, 0, -917, 0, 0, 0, 0, 0, -917, 0, 0, -917, 0, 0, 0, -917, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -917, -917, -917, -917, 0, 0, 0, 0, 0, 0, 0, -917, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -917, 0, 0, 0, -917, 0, 0, -917, 0, 0, 0, -917, -917, 0, -917, 0, -917, -917, // State 431 - 0, 0, 0, 0, 0, 0, -299, 0, 0, 0, 0, 0, -299, 0, 0, -299, 0, 0, 0, -299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -299, -299, -299, -299, 0, 0, 0, 0, 0, 0, 0, -299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -299, 0, 0, 0, -299, 0, 0, 0, 0, -299, -299, -299, 0, -299, -299, + -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, 0, -322, 0, -322, -322, -322, -322, -322, 0, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, 0, 0, 0, -322, -322, -322, -322, -322, -322, 0, -322, 0, 0, 0, 0, 0, 0, 0, 0, -322, 0, 0, -322, -322, 0, -322, 0, -322, -322, 0, 0, 0, -322, -322, 0, 0, 0, 0, 0, 0, 0, 0, 0, -322, -322, -322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 432 - 0, 0, 0, 0, 0, 0, -300, 0, 0, 0, 0, 0, -300, 0, 0, -300, 0, 0, 0, -300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -300, -300, -300, -300, 0, 0, 0, 0, 0, 0, 0, -300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -300, 0, 0, 0, -300, 0, 0, 0, 0, -300, -300, -300, 0, -300, -300, + -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, 0, -321, 0, -321, -321, -321, -321, -321, 0, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, 0, 0, 0, -321, -321, -321, -321, -321, -321, 0, -321, 0, 0, 0, 0, 0, 0, 0, 0, -321, 0, 0, -321, -321, 0, -321, 0, -321, -321, 0, 0, 0, -321, -321, 0, 0, 0, 0, 0, 0, 0, 0, 0, -321, -321, -321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 433 - 0, 0, 0, 0, 0, 0, -302, 0, 0, 0, 0, 0, -302, 0, 0, -302, 0, 0, 0, -302, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -302, -302, -302, -302, 0, 0, 0, 0, 0, 0, 0, -302, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 523, 0, 0, 0, 0, 0, 0, 0, 0, 0, -302, 0, 0, 0, -302, 0, 0, 0, 0, -302, -302, -302, 0, -302, -302, + -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, 0, -320, 0, -320, -320, -320, -320, -320, 0, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, 0, 0, 0, -320, -320, -320, -320, -320, -320, 0, -320, 0, 0, 0, 0, 0, 0, 0, 0, -320, 0, 0, -320, -320, 0, -320, 0, -320, -320, 0, 0, 0, -320, -320, 0, 0, 0, 0, 0, 0, 0, 0, 0, -320, -320, -320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 434 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, 0, -436, 0, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, -436, 0, 0, 0, -436, -436, -436, -436, -436, -436, 0, -436, 0, 0, 0, 0, 0, 0, 0, 0, -436, 0, 0, -436, -436, 0, -436, -436, -436, -436, 0, 0, 0, -436, -436, 0, 0, 0, 0, 0, 0, 0, 0, 0, -436, -436, -436, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 435 - 526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, 0, -835, 0, -835, -835, -835, -835, -835, 0, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, -835, 0, 0, 0, -835, -835, -835, -835, -835, -835, 0, -835, 0, 0, 0, 0, 0, 0, 0, 0, -835, 0, 0, -835, -835, 0, -835, 0, -835, -835, 0, 0, 0, -835, -835, 0, 0, 0, 0, 0, 0, 0, 0, 0, -835, -835, -835, 0, 0, 0, -835, 0, 0, 0, 0, 0, 0, 0, 0, 0, -835, // State 436 - -88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -558, -558, 0, 0, -558, 0, -558, 0, -558, 0, 0, -558, -558, 0, -558, -558, 0, -558, 0, 0, 0, 0, 0, -558, -558, -558, 0, -558, 0, 0, -558, 0, -558, 0, 0, 0, 0, -558, 0, 0, -558, 0, 0, 0, 0, -558, 0, -558, 0, -558, 0, -558, 0, 0, 0, 0, 0, 0, 0, 0, -558, 0, 0, -558, -558, 0, -558, 0, 0, 0, 0, 0, 0, 0, 531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -558, -558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 437 - 0, 0, 0, 0, 0, 0, -119, 0, 0, 0, 0, 0, -119, 0, 0, -119, 0, 0, 0, -119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -119, -119, -119, -119, 0, 0, 0, 0, 0, 0, 0, -119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -119, 0, 0, 0, 0, 0, 0, 0, 0, 0, -119, 0, 0, 0, -119, 0, 0, 0, 0, -119, -119, -119, 0, -119, -119, + -158, -158, 0, 0, -158, 0, -158, 0, -158, 0, 0, -158, -158, 0, -158, -158, 0, -158, 0, 0, 0, 0, 0, -158, -158, -158, 0, -158, 0, 0, -158, 0, -158, 0, 0, 0, 0, -158, 0, 0, -158, 0, 0, 0, 0, -158, 0, -158, 532, -158, 0, -158, 0, 0, 0, 0, 0, 0, 0, 0, -158, 0, 0, -158, -158, 0, -158, 0, 0, 0, 0, 0, 0, 0, -158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -158, -158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 438 - 0, 0, 0, 0, 0, 0, -768, 0, 0, 0, 0, 0, -768, 0, 0, -768, 0, 0, 0, -768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -768, -768, -768, -768, 0, 0, 0, 0, 0, 0, 0, -768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -768, 0, 0, 0, -768, 0, 0, 0, 0, -768, -768, -768, 0, -768, -768, + 0, 0, 0, 0, 0, 0, 0, -113, 0, 0, 0, 0, 0, -113, 0, 0, -113, 0, 0, 0, -113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -113, -113, -113, -113, 0, 0, 0, 0, 0, 0, 0, -113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -113, 0, 0, 0, 0, 0, 0, 0, 0, 0, -113, 0, 0, 0, -113, 0, 0, -113, 0, 0, 0, -113, -113, 0, -113, 0, -113, -113, // State 439 - 0, 0, 0, 0, 0, 0, -769, 0, 0, 0, 0, 0, -769, 0, 0, -769, 0, 0, 0, -769, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -769, -769, -769, -769, 0, 0, 0, 0, 0, 0, 0, -769, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -769, 0, 0, 0, -769, 0, 0, 0, 0, -769, -769, -769, 0, -769, -769, + 0, 0, 0, 0, 0, 0, 0, -151, 0, 0, 0, 0, 0, -151, 0, 0, -151, 0, 0, 0, -151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -151, -151, -151, -151, 0, 0, 0, 0, 0, 0, 0, -151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -151, 0, 0, 0, -151, 0, 0, -151, 0, 0, 0, -151, -151, 0, -151, 0, -151, -151, // State 440 - 0, 0, 0, 0, 0, 0, -486, 0, 0, 0, 0, 0, -486, 0, 0, -486, 0, 0, 0, -486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -486, -486, -486, -486, 0, 0, 0, 0, 0, 0, 0, -486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -486, 0, 0, 0, -486, 0, 0, 0, 0, -486, -486, -486, 0, -486, -486, + 0, 0, 0, 0, 0, 0, 0, -152, 0, 0, 0, 0, 0, -152, 0, 0, -152, 0, 0, 0, -152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -152, -152, -152, -152, 0, 0, 0, 0, 0, 0, 0, -152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -152, 0, 0, 0, -152, 0, 0, -152, 0, 0, 0, -152, -152, 0, -152, 0, -152, -152, // State 441 - 0, 0, 0, 0, 0, 0, -483, 0, 0, 0, 0, 0, -483, 0, 0, -483, 0, 0, 0, -483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -483, -483, -483, -483, 0, 0, 0, 0, 0, 0, 0, -483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -483, 0, 0, 0, -483, 0, 0, 0, 0, -483, -483, -483, 0, -483, -483, + -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, 0, -240, 0, -240, -240, -240, -240, -240, 0, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, 0, 0, 0, -240, -240, -240, -240, -240, -240, 0, -240, 0, 0, 0, 0, 0, 0, 0, 0, -240, 0, 0, -240, -240, 0, -240, 0, -240, -240, 0, 0, 0, -240, -240, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, -240, -240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 442 - 0, 0, 0, 0, 0, 0, -484, 0, 0, 0, 0, 0, -484, 0, 0, -484, 0, 0, 0, -484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -484, -484, -484, -484, 0, 0, 0, 0, 0, 0, 0, -484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -484, 0, 0, 0, -484, 0, 0, 0, 0, -484, -484, -484, 0, -484, -484, + 0, 0, 0, 0, 0, 0, 0, -294, 0, 0, 0, 0, 0, -294, 0, 0, -294, 0, 0, 0, -294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -294, -294, -294, -294, 0, 0, 0, 0, 0, 0, 0, -294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -294, 0, 0, 0, -294, 0, 0, -294, 0, 0, 0, -294, -294, 0, -294, 0, -294, -294, // State 443 - 0, 0, 0, 0, 0, 0, -485, 0, 0, 0, 0, 0, -485, 0, 0, -485, 0, 0, 0, -485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -485, -485, -485, -485, 0, 0, 0, 0, 0, 0, 0, -485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -485, 0, 0, 0, -485, 0, 0, 0, 0, -485, -485, -485, 0, -485, -485, + 0, 0, 0, 0, 0, 0, 0, -295, 0, 0, 0, 0, 0, -295, 0, 0, -295, 0, 0, 0, -295, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -295, -295, -295, -295, 0, 0, 0, 0, 0, 0, 0, -295, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -295, 0, 0, 0, -295, 0, 0, -295, 0, 0, 0, -295, -295, 0, -295, 0, -295, -295, // State 444 - 0, 0, 0, 0, 0, 0, -487, 0, 0, 0, 0, 0, -487, 0, 0, -487, 0, 0, 0, -487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -487, -487, -487, -487, 0, 0, 0, 0, 0, 0, 0, -487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -487, 0, 0, 0, -487, 0, 0, 0, 0, -487, -487, -487, 0, -487, -487, + 0, 0, 0, 0, 0, 0, 0, -296, 0, 0, 0, 0, 0, -296, 0, 0, -296, 0, 0, 0, -296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -296, -296, -296, -296, 0, 0, 0, 0, 0, 0, 0, -296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -296, 0, 0, 0, -296, 0, 0, -296, 0, 0, 0, -296, -296, 0, -296, 0, -296, -296, // State 445 - -370, -370, -370, -370, -370, -370, 0, -370, -370, 0, -370, -370, -370, -370, -370, -370, -370, 0, 0, 0, -370, -370, -370, -370, -370, 0, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, -370, 0, 0, 0, 0, -370, -370, -370, -370, -370, 0, -370, 0, 0, 0, 0, 0, 0, 0, 0, -370, 0, 0, -370, -370, 0, -370, 0, -370, -370, 0, 0, 0, -370, -370, 0, 0, 0, 0, 0, 0, 0, 0, 0, -370, -370, -370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -293, 0, 0, 0, 0, 0, -293, 0, 0, -293, 0, 0, 0, -293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -293, -293, -293, -293, 0, 0, 0, 0, 0, 0, 0, -293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -293, 0, 0, 0, -293, 0, 0, -293, 0, 0, 0, -293, -293, 0, -293, 0, -293, -293, // State 446 - -186, -186, -186, 0, -186, 0, -186, -186, -186, -186, 0, 0, -186, 0, -186, -186, 0, 0, -186, 0, -186, -186, 0, 0, -186, -489, 0, -186, -186, 0, -186, 0, -186, -186, -186, -186, 0, 0, -186, 0, 0, 0, 0, -186, -186, -186, 0, -186, -186, 0, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -186, 0, 0, -186, 0, -186, -186, 0, 0, 0, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, -186, 0, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -297, 0, 0, 0, 0, 0, -297, 0, 0, -297, 0, 0, 0, -297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -297, -297, -297, -297, 0, 0, 0, 0, 0, 0, 0, -297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -297, 0, 0, 0, -297, 0, 0, -297, 0, 0, 0, -297, -297, 0, -297, 0, -297, -297, // State 447 - 0, 0, 0, 0, 0, 0, 0, -492, 0, 0, 0, 0, 0, 0, -492, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -298, 0, 0, 0, 0, 0, -298, 0, 0, -298, 0, 0, 0, -298, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -298, -298, -298, -298, 0, 0, 0, 0, 0, 0, 0, -298, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -298, 0, 0, 0, -298, 0, 0, -298, 0, 0, 0, -298, -298, 0, -298, 0, -298, -298, // State 448 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -299, 0, 0, 0, 0, 0, -299, 0, 0, -299, 0, 0, 0, -299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -299, -299, -299, -299, 0, 0, 0, 0, 0, 0, 0, -299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -299, 0, 0, 0, -299, 0, 0, -299, 0, 0, 0, -299, -299, 0, -299, 0, -299, -299, // State 449 - 0, 0, 0, 0, 0, 0, 0, 536, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -301, 0, 0, 0, 0, 0, -301, 0, 0, -301, 0, 0, 0, -301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -301, -301, -301, -301, 0, 0, 0, 0, 0, 0, 0, -301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 544, 0, 0, 0, 0, 0, 0, 0, 0, 0, -301, 0, 0, 0, -301, 0, 0, -301, 0, 0, 0, -301, -301, 0, -301, 0, -301, -301, // State 450 - 0, 0, 0, 0, 0, 0, 0, -493, 0, 0, 0, 0, 0, 0, -493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 545, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 451 - 0, 0, 0, 0, 0, 0, 0, -523, 0, 0, 0, 0, 0, 0, -523, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 452 - 0, 0, 0, 0, 0, 0, 0, 537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 453 - -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, 0, -200, 0, -200, -200, -200, -200, -200, 0, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, 0, 0, 0, -200, -200, -200, -200, -200, -200, 0, -200, 0, 0, 0, 0, 0, 0, 0, 0, -200, 0, 0, -200, -200, 0, -200, 0, -200, -200, 0, 0, 0, -200, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, -200, -200, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -121, 0, 0, 0, 0, 0, -121, 0, 0, -121, 0, 0, 0, -121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -121, -121, -121, -121, 0, 0, 0, 0, 0, 0, 0, -121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -121, 0, 0, 0, 0, 0, 0, 0, 0, 0, -121, 0, 0, 0, -121, 0, 0, -121, 0, 0, 0, -121, -121, 0, -121, 0, -121, -121, // State 454 - -791, 0, 0, -791, 0, -791, 0, -791, 0, 0, -791, -791, 0, -791, -791, 0, -791, 0, 0, 0, 0, 0, -791, -791, -791, 0, -791, 0, 0, -791, 0, -791, 0, 0, 0, 0, -791, 0, 0, -791, 0, 0, 0, 0, -791, 0, -791, 0, 0, 0, -791, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -791, 0, 0, 0, 0, -791, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, -791, -791, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -793, 0, 0, 0, 0, 0, -793, 0, 0, -793, 0, 0, 0, -793, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -793, -793, -793, -793, 0, 0, 0, 0, 0, 0, 0, -793, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -793, 0, 0, 0, -793, 0, 0, -793, 0, 0, 0, -793, -793, 0, -793, 0, -793, -793, // State 455 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -794, 0, 0, 0, 0, 0, -794, 0, 0, -794, 0, 0, 0, -794, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -794, -794, -794, -794, 0, 0, 0, 0, 0, 0, 0, -794, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -794, 0, 0, 0, -794, 0, 0, -794, 0, 0, 0, -794, -794, 0, -794, 0, -794, -794, // State 456 - -490, 0, 0, 0, 0, 0, 0, -490, 0, 0, 0, 0, 0, 0, -490, 0, 0, 0, 0, 0, 0, 0, 0, 0, -490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -490, 0, 0, 0, 0, 0, -490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, 0, -841, 0, -841, -841, -841, -841, -841, 0, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, -841, 0, 0, 0, -841, -841, -841, -841, -841, -841, 0, -841, 0, 0, 0, 0, 0, 0, 0, 0, -841, 0, 0, -841, -841, 0, -841, 0, -841, -841, 0, 0, 0, -841, -841, 0, 0, 0, 0, 0, 0, 0, 0, 0, -841, -841, -841, 0, 0, 0, -841, 0, 0, 0, 0, 0, 0, 0, 0, 0, -841, // State 457 - 0, 0, 0, 0, 0, 0, 0, -848, 0, 0, 0, 0, 0, 0, -848, 0, 0, 0, 0, 0, 0, 0, 0, 0, -848, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -848, 0, 0, 0, 0, 0, -848, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -848, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -848, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, -511, 0, 0, -511, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -511, -511, -511, -511, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, -511, 0, 0, -511, 0, 0, 0, -511, -511, 0, -511, 0, -511, -511, // State 458 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -508, 0, 0, 0, 0, 0, -508, 0, 0, -508, 0, 0, 0, -508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -508, -508, -508, -508, 0, 0, 0, 0, 0, 0, 0, -508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -508, 0, 0, 0, -508, 0, 0, -508, 0, 0, 0, -508, -508, 0, -508, 0, -508, -508, // State 459 - 0, 0, 0, 0, 0, 0, 0, -849, 0, 0, 0, 0, 0, 0, -849, 0, 0, 0, 0, 0, 0, 0, 0, 0, -849, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -849, 0, 0, 0, 0, 0, -849, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -849, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -849, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -509, 0, 0, 0, 0, 0, -509, 0, 0, -509, 0, 0, 0, -509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -509, -509, -509, -509, 0, 0, 0, 0, 0, 0, 0, -509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -509, 0, 0, 0, -509, 0, 0, -509, 0, 0, 0, -509, -509, 0, -509, 0, -509, -509, // State 460 - -491, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, -510, 0, 0, -510, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, -510, -510, -510, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, -510, 0, 0, -510, 0, 0, 0, -510, -510, 0, -510, 0, -510, -510, // State 461 - -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, 0, -188, 0, -188, -188, -188, -188, -188, 0, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, 0, 0, 0, -188, -188, -188, -188, -188, -188, 0, -188, 0, 0, 0, 0, 0, 0, 0, 0, -188, 0, 0, -188, -188, 0, -188, 0, -188, -188, 0, 0, 0, -188, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, -188, -188, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -512, 0, 0, 0, 0, 0, -512, 0, 0, -512, 0, 0, 0, -512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -512, -512, -512, -512, 0, 0, 0, 0, 0, 0, 0, -512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -512, 0, 0, 0, -512, 0, 0, -512, 0, 0, 0, -512, -512, 0, -512, 0, -512, -512, // State 462 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -886, 0, 0, 0, 0, 0, 0, 0, 0, 0, -886, 0, 0, 0, 0, 0, 0, -886, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -393, -393, -393, -393, -393, -393, -393, 0, -393, -393, 0, -393, -393, -393, -393, -393, -393, -393, 0, 0, 0, -393, -393, -393, -393, -393, 0, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, -393, 0, 0, 0, 0, -393, -393, -393, -393, -393, 0, -393, 0, 0, 0, 0, 0, 0, 0, 0, -393, 0, 0, -393, -393, 0, -393, 0, -393, -393, 0, 0, 0, -393, -393, 0, 0, 0, 0, 0, 0, 0, 0, 0, -393, -393, -393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 463 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 542, 0, 0, 0, 0, 0, 0, 0, 0, 0, -702, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -185, 0, -185, -185, 0, -185, 0, -185, -185, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, -185, -514, 0, -185, -185, 0, -185, 0, -185, -185, -185, -185, 0, 0, -185, 0, 0, 0, 0, -185, -185, -185, 0, -185, -185, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, 0, -185, 0, -185, -185, 0, 0, 0, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 464 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, -676, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -517, 0, 0, 0, 0, 0, 0, -517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 465 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -519, 0, 0, 0, 0, 0, 0, 0, 0, 0, -519, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 466 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 557, 0, 0, 0, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 467 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -539, 0, 0, 0, 0, 0, 0, 0, 0, 0, -539, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -518, 0, 0, 0, 0, 0, 0, -518, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 468 - -495, 0, 0, -495, 0, -495, 0, -495, 0, 0, -495, -495, 0, -495, -495, 0, -495, 0, 0, 0, 0, 0, -495, -495, -495, 0, -495, 0, 0, -495, 0, -495, 0, 0, 0, 0, -495, 0, 0, -495, 0, 0, 0, 0, -495, 0, -495, -495, -495, 0, -495, 0, 0, 0, 0, 0, 0, 0, 0, -495, 0, 0, -495, -495, 0, -495, 0, 0, 0, 0, 0, 0, 0, -495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -495, -495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -548, 0, 0, 0, 0, 0, 0, -548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 469 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -499, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -499, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 470 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, 0, -199, 0, -199, -199, -199, -199, -199, 0, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, 0, 0, 0, -199, -199, -199, -199, -199, -199, 0, -199, 0, 0, 0, 0, 0, 0, 0, 0, -199, 0, 0, -199, -199, 0, -199, 0, -199, -199, 0, 0, 0, -199, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, -199, -199, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 471 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -816, -816, 0, 0, -816, 0, -816, 0, -816, 0, 0, -816, -816, 0, -816, -816, 0, -816, 0, 0, 0, 0, 0, -816, -816, -816, 0, -816, 0, 0, -816, 0, -816, 0, 0, 0, 0, -816, 0, 0, -816, 0, 0, 0, 0, -816, 0, -816, 0, 0, 0, -816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -816, 0, 0, 0, 0, -816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, -816, -816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 472 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -763, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 473 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 550, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -515, 0, 0, 0, 0, 0, 0, 0, -515, 0, 0, 0, 0, 0, 0, -515, 0, 0, 0, 0, 0, 0, 0, 0, 0, -515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -515, 0, 0, 0, 0, 0, -515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 474 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 475 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -472, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 476 - -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, 0, -205, 0, -205, -205, -205, -205, -205, 0, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, 0, 0, 0, -205, -205, -205, -205, -205, -205, 0, -205, 0, 0, 0, 0, 0, 0, 0, 0, -205, 0, 0, -205, -205, 0, -205, 0, -205, -205, 0, 0, 0, -205, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, -205, -205, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -881, 0, 0, 0, 0, 0, 0, -881, 0, 0, 0, 0, 0, 0, 0, 0, 0, -881, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -881, 0, 0, 0, 0, 0, -881, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -881, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -881, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 477 - -787, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -787, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -516, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 478 - -315, 0, 0, 0, 0, 0, -315, 0, -315, 0, 0, 0, -315, 0, 0, -315, 0, 0, 0, -315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -315, 0, -315, -315, -315, -315, 0, 0, 0, 0, 0, -315, -315, -315, -315, 0, -315, -315, -315, -315, 0, 0, 0, 0, -315, -315, -315, -315, -315, 0, 0, -315, -315, -315, -315, 0, -315, -315, -315, -315, -315, -315, -315, -315, -315, 0, 0, 0, -315, -315, 0, 0, 0, -315, -315, -315, -315, -315, -315, + -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, 0, -187, 0, -187, -187, -187, -187, -187, 0, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, 0, 0, 0, -187, -187, -187, -187, -187, -187, 0, -187, 0, 0, 0, 0, 0, 0, 0, 0, -187, 0, 0, -187, -187, 0, -187, 0, -187, -187, 0, 0, 0, -187, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, -187, -187, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 479 - -744, 0, 0, 0, 0, 0, -744, 0, -744, 0, 0, 0, -744, 0, 0, -744, 0, 0, 0, -744, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -744, 0, -744, -744, -744, -744, 0, 0, 0, 0, 0, -744, -744, -744, -744, 0, -744, -744, -744, -744, 0, 0, 0, 0, -744, -744, -744, -744, -744, 0, 0, -744, -744, -744, -744, 0, -744, -744, -744, -744, -744, -744, -744, -744, -744, 0, 0, 0, -744, 0, 0, 0, 0, -744, -744, -744, -744, -744, -744, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -918, 0, 0, 0, 0, 0, 0, 0, 0, 0, -918, 0, 0, 0, 0, 0, 0, -918, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 480 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -330, 0, 0, 0, -330, 0, -330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 563, 0, 0, 0, 0, 0, 0, 0, 0, 0, -727, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 481 - -782, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -782, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, -701, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 482 - -780, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -780, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -544, 0, 0, 0, 0, 0, 0, 0, 0, 0, -544, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 483 - -783, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -783, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 484 - -311, 0, 0, 0, 0, 0, -311, 0, -311, 0, 0, 0, -311, 0, 0, -311, 0, 0, 0, -311, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -311, 0, -311, -311, -311, -311, 0, 0, 0, 0, 0, -311, -311, -311, -311, 0, -311, -311, -311, -311, 0, 0, 0, 0, -311, -311, -311, -311, -311, 0, 0, -311, -311, -311, -311, 0, -311, -311, -311, -311, -311, -311, -311, -311, -311, 0, 0, 0, -311, -311, 0, 0, 0, -311, -311, -311, -311, -311, -311, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -564, 0, 0, 0, 0, 0, 0, 0, 0, 0, -564, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 485 - -314, 0, 0, 0, 0, 0, -314, 0, -314, 0, 0, 0, -314, 0, 0, -314, 0, 0, 0, -314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -314, 0, -314, -314, -314, -314, 0, 0, 0, 0, 0, -314, -314, -314, -314, 0, -314, -314, -314, -314, 0, 0, 0, 0, -314, -314, -314, -314, -314, 0, 0, -314, -314, -314, -314, 0, -314, -314, -314, -314, -314, -314, -314, -314, -314, 0, 0, 0, -314, -314, 0, 0, 0, -314, -314, -314, -314, -314, -314, + -520, -520, 0, 0, -520, 0, -520, 0, -520, 0, 0, -520, -520, 0, -520, -520, 0, -520, 0, 0, 0, 0, 0, -520, -520, -520, 0, -520, 0, 0, -520, 0, -520, 0, 0, 0, 0, -520, 0, 0, -520, 0, 0, 0, 0, -520, 0, -520, -520, -520, 0, -520, 0, 0, 0, 0, 0, 0, 0, 0, -520, 0, 0, -520, -520, 0, -520, 0, 0, 0, 0, 0, 0, 0, -520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -520, -520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 486 - -785, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -785, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 487 - -309, 0, 0, 0, 0, 0, -309, 0, -309, 0, 0, 0, -309, 0, 0, -309, 0, 0, 0, -309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -309, 0, -309, -309, -309, -309, 0, 0, 0, 0, 0, -309, -309, -309, -309, 0, -309, -309, -309, -309, 0, 0, 0, 0, -309, -309, -309, -309, -309, 0, 0, -309, -309, -309, -309, 0, -309, -309, -309, -309, -309, -309, -309, -309, -309, 0, 0, 0, -309, -309, 0, 0, 0, -309, -309, -309, -309, -309, -309, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 569, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 488 - -784, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -784, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 489 - -789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -788, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 490 - -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 571, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 491 - -308, 0, 0, 0, 0, 0, -308, 0, -308, 0, 0, 0, -308, 0, 0, -308, 0, 0, 0, -308, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -308, 0, -308, -308, -308, -308, 0, 0, 0, 0, 0, -308, -308, -308, -308, 0, -308, -308, -308, -308, 0, 0, 0, 0, -308, -308, -308, -308, -308, 0, 0, -308, -308, -308, -308, 0, -308, -308, -308, -308, -308, -308, -308, -308, -308, 0, 0, 0, -308, -308, 0, 0, 0, -308, -308, -308, -308, -308, -308, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 492 - -786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 493 - -781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, 0, -204, 0, -204, -204, -204, -204, -204, 0, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, 0, 0, 0, -204, -204, -204, -204, -204, -204, 0, -204, 0, 0, 0, 0, 0, 0, 0, 0, -204, 0, 0, -204, -204, 0, -204, 0, -204, -204, 0, 0, 0, -204, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, -204, -204, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 494 - -379, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -379, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -383, 0, 0, -383, 0, 0, -383, 0, 0, 0, 0, 0, 0, -383, 0, 0, 0, 0, // State 495 - 571, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -379, 0, 0, -379, 0, 0, -379, 0, 0, 0, 0, 0, 0, -379, 0, 0, 0, 0, // State 496 - -845, 0, 0, -845, 0, -845, 0, 0, 0, 0, -845, -845, 0, -845, -845, 0, -845, 0, 0, 0, 0, 0, -845, -845, 97, 0, -845, 0, 0, -845, 0, -845, 0, 0, 0, 0, -845, 0, 0, -845, 0, 0, 0, 0, 0, 0, -845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, 0, -372, 0, -372, -372, -372, -372, -372, 0, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, 0, 0, 0, -372, -372, -372, -372, -372, -372, 0, -372, 0, 0, 0, 0, 0, 0, 0, 0, -372, 0, 0, -372, -372, 0, -372, 0, -372, -372, 0, 0, 0, -372, -372, 0, 0, 0, 0, 0, 0, 0, 0, 0, -372, -372, -372, 0, 0, 0, -372, 0, 0, 0, 0, 0, 0, 0, 0, 0, -372, // State 497 - -312, 0, 0, 0, 0, 0, -312, 0, -312, 0, 0, 0, -312, 0, 0, -312, 0, 0, 0, -312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -312, 0, -312, -312, -312, -312, 0, 0, 0, 0, 0, -312, -312, -312, -312, 0, -312, -312, -312, -312, 0, 0, 0, 0, -312, -312, -312, -312, -312, 0, 0, -312, -312, -312, -312, 0, -312, -312, -312, -312, -312, -312, -312, -312, -312, 0, 0, 0, -312, -312, 0, 0, 0, -312, -312, -312, -312, -312, -312, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -380, 0, 0, -380, 0, 0, -380, 0, 0, 0, 0, 0, 0, -380, 0, 0, 0, 0, // State 498 - -788, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -788, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -812, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -812, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 499 - -310, 0, 0, 0, 0, 0, -310, 0, -310, 0, 0, 0, -310, 0, 0, -310, 0, 0, 0, -310, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -310, 0, -310, -310, -310, -310, 0, 0, 0, 0, 0, -310, -310, -310, -310, 0, -310, -310, -310, -310, 0, 0, 0, 0, -310, -310, -310, -310, -310, 0, 0, -310, -310, -310, -310, 0, -310, -310, -310, -310, -310, -310, -310, -310, -310, 0, 0, 0, -310, -310, 0, 0, 0, -310, -310, -310, -310, -310, -310, + -314, 0, 0, 0, 0, 0, 0, -314, 0, -314, 0, 0, 0, -314, 0, 0, -314, 0, 0, 0, -314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -314, 0, -314, -314, -314, -314, 0, 0, 0, 0, 0, -314, -314, -314, -314, 0, -314, -314, -314, -314, 0, 0, 0, 0, -314, -314, -314, -314, -314, 0, 0, -314, -314, -314, -314, 0, -314, -314, -314, -314, -314, -314, -314, -314, -314, 0, 0, 0, -314, -314, 0, -314, 0, 0, 0, -314, -314, 0, -314, -314, -314, -314, // State 500 - -313, 0, 0, 0, 0, 0, -313, 0, -313, 0, 0, 0, -313, 0, 0, -313, 0, 0, 0, -313, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -313, 0, -313, -313, -313, -313, 0, 0, 0, 0, 0, -313, -313, -313, -313, 0, -313, -313, -313, -313, 0, 0, 0, 0, -313, -313, -313, -313, -313, 0, 0, -313, -313, -313, -313, 0, -313, -313, -313, -313, -313, -313, -313, -313, -313, 0, 0, 0, -313, -313, 0, 0, 0, -313, -313, -313, -313, -313, -313, + -769, 0, 0, 0, 0, 0, 0, -769, 0, -769, 0, 0, 0, -769, 0, 0, -769, 0, 0, 0, -769, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -769, 0, -769, -769, -769, -769, 0, 0, 0, 0, 0, -769, -769, -769, -769, 0, -769, -769, -769, -769, 0, 0, 0, 0, -769, -769, -769, -769, -769, 0, 0, -769, -769, -769, -769, 0, -769, -769, -769, -769, -769, -769, -769, -769, -769, 0, 0, 0, -769, 0, 0, -769, 0, 0, 0, -769, -769, 0, -769, -769, -769, -769, // State 501 - -378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -329, 0, 0, 0, -329, 0, -329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 502 - -749, 0, 0, 0, 0, 0, -749, 0, -749, 0, 0, 0, -749, 0, 0, -749, 0, 0, 0, -749, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -749, 0, -749, -749, -749, -749, 0, 0, 0, 0, 0, -749, -749, -749, -749, 0, -749, -749, -749, -749, 0, 0, 0, 0, -749, -749, -749, -749, -749, 0, 0, -749, -749, -749, -749, 0, -749, -749, -749, -749, -749, -749, -749, -749, -749, 0, 0, 0, -749, 0, 0, 0, 0, -749, -749, -749, -749, -749, -749, + -807, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -807, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 503 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 0, 0, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -805, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -805, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 504 - -374, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -374, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -808, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -808, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 505 - -375, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -375, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -310, 0, 0, 0, 0, 0, 0, -310, 0, -310, 0, 0, 0, -310, 0, 0, -310, 0, 0, 0, -310, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -310, 0, -310, -310, -310, -310, 0, 0, 0, 0, 0, -310, -310, -310, -310, 0, -310, -310, -310, -310, 0, 0, 0, 0, -310, -310, -310, -310, -310, 0, 0, -310, -310, -310, -310, 0, -310, -310, -310, -310, -310, -310, -310, -310, -310, 0, 0, 0, -310, -310, 0, -310, 0, 0, 0, -310, -310, 0, -310, -310, -310, -310, // State 506 - -723, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -723, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -313, 0, 0, 0, 0, 0, 0, -313, 0, -313, 0, 0, 0, -313, 0, 0, -313, 0, 0, 0, -313, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -313, 0, -313, -313, -313, -313, 0, 0, 0, 0, 0, -313, -313, -313, -313, 0, -313, -313, -313, -313, 0, 0, 0, 0, -313, -313, -313, -313, -313, 0, 0, -313, -313, -313, -313, 0, -313, -313, -313, -313, -313, -313, -313, -313, -313, 0, 0, 0, -313, -313, 0, -313, 0, 0, 0, -313, -313, 0, -313, -313, -313, -313, // State 507 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -810, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -810, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 508 - -438, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -438, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -308, 0, 0, 0, 0, 0, 0, -308, 0, -308, 0, 0, 0, -308, 0, 0, -308, 0, 0, 0, -308, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -308, 0, -308, -308, -308, -308, 0, 0, 0, 0, 0, -308, -308, -308, -308, 0, -308, -308, -308, -308, 0, 0, 0, 0, -308, -308, -308, -308, -308, 0, 0, -308, -308, -308, -308, 0, -308, -308, -308, -308, -308, -308, -308, -308, -308, 0, 0, 0, -308, -308, 0, -308, 0, 0, 0, -308, -308, 0, -308, -308, -308, -308, // State 509 - 0, 0, 0, 0, 0, 0, -112, 0, 0, 0, 0, 0, -112, 0, 0, -112, 0, 0, 0, -112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -112, -112, -112, -112, 0, 0, 0, 0, 0, 0, 0, -112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -112, 0, 0, 0, 0, 0, 0, 0, 0, 0, -112, 0, 0, 0, -112, 0, 0, 0, 0, -112, -112, -112, 0, -112, -112, + -809, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -809, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 510 - 0, 0, 0, 0, 0, 0, -120, 0, 0, 0, 0, 0, -120, 0, 0, -120, 0, 0, 0, -120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -120, -120, -120, -120, 0, 0, 0, 0, 0, 0, 0, -120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -120, 0, 0, 0, 0, 0, 0, 0, 0, 0, -120, 0, 0, 0, -120, 0, 0, 0, 0, -120, -120, -120, 0, -120, -120, + -814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 511 - 0, 0, 0, 0, 0, 0, 0, 634, 0, 0, 0, 0, 0, 0, 635, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -815, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -815, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 512 - 0, -186, -186, 0, -186, 0, -186, -186, -186, -186, 0, 0, -186, 0, -186, -186, 0, 0, -186, 0, -186, -186, 0, 0, 0, -489, 0, -186, -186, 0, -186, 121, -186, -186, -186, -186, 0, 0, -186, 0, 0, 0, 0, -186, 0, -186, 0, -186, 0, 0, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -186, 0, 0, -186, 0, -186, -186, 0, 0, 0, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -307, 0, 0, 0, 0, 0, 0, -307, 0, -307, 0, 0, 0, -307, 0, 0, -307, 0, 0, 0, -307, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -307, 0, -307, -307, -307, -307, 0, 0, 0, 0, 0, -307, -307, -307, -307, 0, -307, -307, -307, -307, 0, 0, 0, 0, -307, -307, -307, -307, -307, 0, 0, -307, -307, -307, -307, 0, -307, -307, -307, -307, -307, -307, -307, -307, -307, 0, 0, 0, -307, -307, 0, -307, 0, 0, 0, -307, -307, 0, -307, -307, -307, -307, // State 513 - -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, 0, -164, 0, -164, -164, -164, -164, -164, 0, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, 0, 0, 0, -164, -164, -164, -164, -164, -164, 0, -164, 0, 0, 0, 0, 0, 0, 0, 0, -164, 0, 0, -164, -164, 0, -164, 0, -164, -164, 0, 0, 0, -164, -164, 0, 0, 0, 0, 0, 0, 0, 0, 0, -164, -164, -164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -811, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -811, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 514 - -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, 0, -243, 0, -243, -243, -243, -243, -243, 0, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, 0, 0, 0, -243, -243, -243, -243, -243, -243, 0, -243, 0, 0, 0, 0, 0, 0, 0, 0, -243, 0, 0, -243, -243, 0, -243, 0, -243, -243, 0, 0, 0, -243, -243, 0, 0, 0, 0, 0, 0, 0, 0, 0, -243, -243, -243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -806, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -806, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 515 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -819, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 516 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 639, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 596, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 517 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -877, 0, 0, 0, -877, 0, -877, 0, 0, 0, 0, -877, -877, 0, -877, -877, 0, -877, 0, 0, 0, 0, 0, -877, -877, 103, 0, -877, 0, 0, -877, 0, -877, 0, 0, 0, 0, -877, 0, 0, -877, 0, 0, 0, 0, 0, 0, -877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 518 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -810, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -810, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -311, 0, 0, 0, 0, 0, 0, -311, 0, -311, 0, 0, 0, -311, 0, 0, -311, 0, 0, 0, -311, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -311, 0, -311, -311, -311, -311, 0, 0, 0, 0, 0, -311, -311, -311, -311, 0, -311, -311, -311, -311, 0, 0, 0, 0, -311, -311, -311, -311, -311, 0, 0, -311, -311, -311, -311, 0, -311, -311, -311, -311, -311, -311, -311, -311, -311, 0, 0, 0, -311, -311, 0, -311, 0, 0, 0, -311, -311, 0, -311, -311, -311, -311, // State 519 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -822, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -813, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -813, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 520 - -739, -739, -739, -739, -739, -739, 0, -739, -739, 0, -739, -739, -739, -739, -739, -739, -739, 0, 0, 0, -739, -739, -739, -739, -739, 0, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, -739, 0, 0, 0, 0, -739, -739, -739, -739, -739, 0, -739, 0, 0, 0, 0, 0, 0, 0, 0, -739, 0, 0, -739, -739, 0, -739, 0, -739, -739, 0, 0, 0, -739, -739, 0, 0, 0, 0, 0, 0, 0, 0, 0, -739, -739, -739, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -309, 0, 0, 0, 0, 0, 0, -309, 0, -309, 0, 0, 0, -309, 0, 0, -309, 0, 0, 0, -309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -309, 0, -309, -309, -309, -309, 0, 0, 0, 0, 0, -309, -309, -309, -309, 0, -309, -309, -309, -309, 0, 0, 0, 0, -309, -309, -309, -309, -309, 0, 0, -309, -309, -309, -309, 0, -309, -309, -309, -309, -309, -309, -309, -309, -309, 0, 0, 0, -309, -309, 0, -309, 0, 0, 0, -309, -309, 0, -309, -309, -309, -309, // State 521 - -142, -142, 0, -142, 0, -142, 0, -142, 0, 0, -142, -142, 0, -142, -142, 0, -142, 0, 0, 0, 0, 0, -142, -142, -142, 0, -142, -142, 0, -142, -142, -142, -142, -142, -142, 0, -142, 0, 0, -142, 0, 0, 0, 0, -142, 0, -142, -142, -142, 0, -142, 0, 0, 0, 0, 0, 0, 0, 0, -142, 0, 0, -142, -142, 0, -142, 0, -142, -142, 0, 0, 0, -142, -142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, -142, -142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -312, 0, 0, 0, 0, 0, 0, -312, 0, -312, 0, 0, 0, -312, 0, 0, -312, 0, 0, 0, -312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -312, 0, -312, -312, -312, -312, 0, 0, 0, 0, 0, -312, -312, -312, -312, 0, -312, -312, -312, -312, 0, 0, 0, 0, -312, -312, -312, -312, -312, 0, 0, -312, -312, -312, -312, 0, -312, -312, -312, -312, -312, -312, -312, -312, -312, 0, 0, 0, -312, -312, 0, -312, 0, 0, 0, -312, -312, 0, -312, -312, -312, -312, // State 522 - 0, 0, 0, 0, 0, 0, -303, 0, 0, 0, 0, 0, -303, 0, 0, -303, 0, 0, 0, -303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -303, -303, -303, -303, 0, 0, 0, 0, 0, 0, 0, -303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -303, 0, 0, 0, -303, 0, 0, 0, 0, -303, -303, -303, 0, -303, -303, + -401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 523 - 0, 0, 0, 0, 0, 0, -301, 0, 0, 0, 0, 0, -301, 0, 0, -301, 0, 0, 0, -301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -301, -301, -301, -301, 0, 0, 0, 0, 0, 0, 0, -301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -301, 0, 0, 0, -301, 0, 0, 0, 0, -301, -301, -301, 0, -301, -301, + -774, 0, 0, 0, 0, 0, 0, -774, 0, -774, 0, 0, 0, -774, 0, 0, -774, 0, 0, 0, -774, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -774, 0, -774, -774, -774, -774, 0, 0, 0, 0, 0, -774, -774, -774, -774, 0, -774, -774, -774, -774, 0, 0, 0, 0, -774, -774, -774, -774, -774, 0, 0, -774, -774, -774, -774, 0, -774, -774, -774, -774, -774, -774, -774, -774, -774, 0, 0, 0, -774, 0, 0, -774, 0, 0, 0, -774, -774, 0, -774, -774, -774, -774, // State 524 - -355, -355, 0, -355, 0, -355, 0, -355, 0, 0, -355, -355, 0, -355, -355, 0, -355, 0, 0, 0, 0, 0, -355, -355, -355, 0, -355, -355, 0, -355, -355, -355, -355, -355, -355, 0, -355, -355, 0, -355, 0, 0, 0, 0, -355, 34, -355, -355, -355, 0, -355, 0, 0, 0, 0, 0, 0, 0, 0, -355, 0, 0, -355, -355, 0, -355, 0, -355, -355, 0, 0, 0, -355, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, -355, -355, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 525 - -89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -397, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -397, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 526 - -526, 0, 0, -526, 0, -526, 0, -526, 0, 0, -526, -526, 0, -526, -526, 0, -526, 0, 0, 0, 0, 0, -526, -526, -526, 0, -526, 0, 0, -526, 0, -526, 0, 0, 0, 0, -526, 0, 0, -526, 0, 0, 0, 0, 0, 0, -526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 527 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -748, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -748, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 528 - -828, -828, -828, -828, -828, -828, 0, -828, -828, 0, -828, -828, -828, -828, -828, -828, -828, 0, 0, 0, -828, -828, -828, -828, -828, 0, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, -828, 0, 0, 0, 0, -828, -828, -828, -828, -828, 0, -828, 0, 0, 0, 0, 0, 0, 0, 0, -828, 0, 0, -828, -828, 0, -828, 0, -828, -828, 0, 0, 0, -828, -828, 0, 0, 0, 0, 0, 0, 0, 0, 0, -828, -828, -828, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 529 - -910, -910, 0, -910, 21, -910, 0, -910, 0, 0, -910, -910, 0, -910, -910, 0, -910, 0, 0, 0, 0, 0, -910, -910, -910, 0, -910, -910, 0, -910, -910, -910, -910, -910, -910, 0, -910, -910, 0, -910, 0, 0, 0, 0, -910, -910, -910, -910, -910, 0, -910, 0, 0, 0, 0, 0, 0, 0, 0, -910, 0, 0, -910, -910, 0, -910, 0, -910, -910, 0, 0, 0, -910, -910, 0, 0, 0, 0, 0, 0, 0, 0, 0, -910, -910, -910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 530 - 0, 0, 0, 0, 0, 0, 0, 643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -114, 0, 0, 0, 0, 0, -114, 0, 0, -114, 0, 0, 0, -114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -114, -114, -114, -114, 0, 0, 0, 0, 0, 0, 0, -114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -114, 0, 0, 0, 0, 0, 0, 0, 0, 0, -114, 0, 0, 0, -114, 0, 0, -114, 0, 0, 0, -114, -114, 0, -114, 0, -114, -114, // State 531 - 0, 0, 0, 0, 0, 0, 0, -774, 0, 0, 0, 0, 0, 0, -774, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -774, 0, 0, 0, 0, 0, -774, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -774, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -774, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -122, 0, 0, 0, 0, 0, -122, 0, 0, -122, 0, 0, 0, -122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -122, -122, -122, -122, 0, 0, 0, 0, 0, 0, 0, -122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -122, 0, 0, 0, 0, 0, 0, 0, 0, 0, -122, 0, 0, 0, -122, 0, 0, -122, 0, 0, 0, -122, -122, 0, -122, 0, -122, -122, // State 532 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 658, 0, 0, 0, 0, 0, 0, 659, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 533 - 0, 0, 0, 0, 0, 0, 0, 646, 0, 0, 0, 0, 0, 0, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -185, -185, 0, -185, 0, -185, -185, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, 0, -514, 0, -185, -185, 0, -185, 128, -185, -185, -185, -185, 0, 0, -185, 0, 0, 0, 0, -185, 0, -185, 0, -185, 0, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, 0, -185, 0, -185, -185, 0, 0, 0, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 534 - -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, 0, -197, 0, -197, -197, -197, -197, -197, 0, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, 0, 0, 0, -197, -197, -197, -197, -197, -197, 0, -197, 0, 0, 0, 0, 0, 0, 0, 0, -197, 0, 0, -197, -197, 0, -197, 0, -197, -197, 0, 0, 0, -197, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, -197, -197, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, 0, -163, 0, -163, -163, -163, -163, -163, 0, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, 0, 0, 0, -163, -163, -163, -163, -163, -163, 0, -163, 0, 0, 0, 0, 0, 0, 0, 0, -163, 0, 0, -163, -163, 0, -163, 0, -163, -163, 0, 0, 0, -163, -163, 0, 0, 0, 0, 0, 0, 0, 0, 0, -163, -163, -163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 535 - -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, 0, -191, 0, -191, -191, -191, -191, -191, 0, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, 0, 0, 0, -191, -191, -191, -191, -191, -191, 0, -191, 0, 0, 0, 0, 0, 0, 0, 0, -191, 0, 0, -191, -191, 0, -191, 0, -191, -191, 0, 0, 0, -191, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, -191, -191, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, 0, -242, 0, -242, -242, -242, -242, -242, 0, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, 0, 0, 0, -242, -242, -242, -242, -242, -242, 0, -242, 0, 0, 0, 0, 0, 0, 0, 0, -242, 0, 0, -242, -242, 0, -242, 0, -242, -242, 0, 0, 0, -242, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, -242, -242, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 536 - -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, 0, -201, 0, -201, -201, -201, -201, -201, 0, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, 0, 0, 0, -201, -201, -201, -201, -201, -201, 0, -201, 0, 0, 0, 0, 0, 0, 0, 0, -201, 0, 0, -201, -201, 0, -201, 0, -201, -201, 0, 0, 0, -201, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, -201, -201, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -851, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 537 - 0, 0, 0, 0, 0, 0, 0, 652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 538 - -914, 0, 0, 0, 0, 0, 0, -914, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -914, 0, 0, 0, 0, -914, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 539 - -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, 0, -187, 0, -187, -187, -187, -187, -187, 0, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, -187, 0, 0, 0, -187, -187, -187, -187, -187, -187, 0, -187, 0, 0, 0, 0, 0, 0, 0, 0, -187, 0, 0, -187, -187, 0, -187, 0, -187, -187, 0, 0, 0, -187, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, -187, -187, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -842, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -842, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 540 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 655, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -854, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 541 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -701, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -764, -764, -764, -764, -764, -764, -764, 0, -764, -764, 0, -764, -764, -764, -764, -764, -764, -764, 0, 0, 0, -764, -764, -764, -764, -764, 0, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, -764, 0, 0, 0, 0, -764, -764, -764, -764, -764, 0, -764, 0, 0, 0, 0, 0, 0, 0, 0, -764, 0, 0, -764, -764, 0, -764, 0, -764, -764, 0, 0, 0, -764, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, -764, -764, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 542 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, -700, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -141, -141, -141, 0, -141, 0, -141, 0, -141, 0, 0, -141, -141, 0, -141, -141, 0, -141, 0, 0, 0, 0, 0, -141, -141, -141, 0, -141, -141, 0, -141, -141, -141, -141, -141, -141, 0, -141, 0, 0, -141, 0, 0, 0, 0, -141, 0, -141, -141, -141, 0, -141, 0, 0, 0, 0, 0, 0, 0, 0, -141, 0, 0, -141, -141, 0, -141, 0, -141, -141, 0, 0, 0, -141, -141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, -141, -141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 543 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -797, 0, 0, 0, 0, 0, 0, 0, 0, 0, -797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -302, 0, 0, 0, 0, 0, -302, 0, 0, -302, 0, 0, 0, -302, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -302, -302, -302, -302, 0, 0, 0, 0, 0, 0, 0, -302, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -302, 0, 0, 0, -302, 0, 0, -302, 0, 0, 0, -302, -302, 0, -302, 0, -302, -302, // State 544 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -442, 0, 0, 0, 0, 0, 0, 0, 0, 0, -442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -300, 0, 0, 0, 0, 0, -300, 0, 0, -300, 0, 0, 0, -300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -300, -300, -300, -300, 0, 0, 0, 0, 0, 0, 0, -300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -300, 0, 0, 0, -300, 0, 0, -300, 0, 0, 0, -300, -300, 0, -300, 0, -300, -300, // State 545 - -445, 0, 0, -445, 0, -445, 0, -445, 0, 0, -445, -445, 0, -445, -445, 0, -445, 0, 0, 0, 0, 0, -445, -445, -445, 0, -445, 0, 0, -445, 0, -445, 0, 0, 0, 0, -445, 0, 0, -445, 0, 0, 0, 0, -445, 0, -445, 0, -445, 0, -445, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -445, -445, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -445, -445, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -354, -354, -354, 0, -354, 0, -354, 0, -354, 0, 0, -354, -354, 0, -354, -354, 0, -354, 0, 0, 0, 0, 0, -354, -354, -354, 0, -354, -354, 0, -354, -354, -354, -354, -354, -354, 0, -354, -354, 0, -354, 0, 0, 0, 0, -354, 36, -354, -354, -354, 0, -354, 0, 0, 0, 0, 0, 0, 0, 0, -354, 0, 0, -354, -354, 0, -354, 0, -354, -354, 0, 0, 0, -354, -354, 0, 0, 0, 0, 0, 0, 0, 0, 0, -354, -354, -354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 546 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 547 - -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, 0, -204, 0, -204, -204, -204, -204, -204, 0, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, -204, 0, 0, 0, -204, -204, -204, -204, -204, -204, 0, -204, 0, 0, 0, 0, 0, 0, 0, 0, -204, 0, 0, -204, -204, 0, -204, 0, -204, -204, 0, 0, 0, -204, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, -204, -204, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -551, -551, 0, 0, -551, 0, -551, 0, -551, 0, 0, -551, -551, 0, -551, -551, 0, -551, 0, 0, 0, 0, 0, -551, -551, -551, 0, -551, 0, 0, -551, 0, -551, 0, 0, 0, 0, -551, 0, 0, -551, 0, 0, 0, 0, 0, 0, -551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -551, -551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 548 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 549 - -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, 0, -207, 0, -207, -207, -207, -207, -207, 0, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, 0, 0, 0, -207, -207, -207, -207, -207, -207, 0, -207, 0, 0, 0, 0, 0, 0, 0, 0, -207, 0, 0, -207, -207, 0, -207, 0, -207, -207, 0, 0, 0, -207, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, -207, -207, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -860, -860, -860, -860, -860, -860, -860, 0, -860, -860, 0, -860, -860, -860, -860, -860, -860, -860, 0, 0, 0, -860, -860, -860, -860, -860, 0, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, -860, 0, 0, 0, 0, -860, -860, -860, -860, -860, 0, -860, 0, 0, 0, 0, 0, 0, 0, 0, -860, 0, 0, -860, -860, 0, -860, 0, -860, -860, 0, 0, 0, -860, -860, 0, 0, 0, 0, 0, 0, 0, 0, 0, -860, -860, -860, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 550 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, -334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -942, -942, -942, 0, -942, 23, -942, 0, -942, 0, 0, -942, -942, 0, -942, -942, 0, -942, 0, 0, 0, 0, 0, -942, -942, -942, 0, -942, -942, 0, -942, -942, -942, -942, -942, -942, 0, -942, -942, 0, -942, 0, 0, 0, 0, -942, -942, -942, -942, -942, 0, -942, 0, 0, 0, 0, 0, 0, 0, 0, -942, 0, 0, -942, -942, 0, -942, 0, -942, -942, 0, 0, 0, -942, -942, 0, 0, 0, 0, 0, 0, 0, 0, 0, -942, -942, -942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 551 - 669, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 552 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -331, 0, 0, 0, -331, 0, -331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -799, 0, 0, 0, 0, 0, 0, -799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -799, 0, 0, 0, 0, 0, -799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 553 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 554 - -439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 670, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 555 - -83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, 0, -196, 0, -196, -196, -196, -196, -196, 0, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, 0, 0, 0, -196, -196, -196, -196, -196, -196, 0, -196, 0, 0, 0, 0, 0, 0, 0, 0, -196, 0, 0, -196, -196, 0, -196, 0, -196, -196, 0, 0, 0, -196, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, -196, -196, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 556 - -180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -180, 0, 0, 0, 0, -180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, 0, -190, 0, -190, -190, -190, -190, -190, 0, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, 0, 0, 0, -190, -190, -190, -190, -190, -190, 0, -190, 0, 0, 0, 0, 0, 0, 0, 0, -190, 0, 0, -190, -190, 0, -190, 0, -190, -190, 0, 0, 0, -190, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, -190, -190, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 557 - 0, 0, 0, 0, 0, 0, -257, 0, -257, 0, 0, 0, -257, 0, 0, -257, 0, 0, 0, -257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -257, -257, -257, -257, 0, 0, 0, 0, 0, 0, 0, -257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -257, 0, 0, -257, 0, 0, 0, 0, 0, 0, 0, 0, -257, -257, 0, 0, 0, -257, 0, 0, 0, 0, -257, -257, -257, 0, -257, -257, + -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, 0, -200, 0, -200, -200, -200, -200, -200, 0, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, -200, 0, 0, 0, -200, -200, -200, -200, -200, -200, 0, -200, 0, 0, 0, 0, 0, 0, 0, 0, -200, 0, 0, -200, -200, 0, -200, 0, -200, -200, 0, 0, 0, -200, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, -200, -200, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 558 - 0, 0, 0, 0, 0, 0, -258, 0, -258, 0, 0, 0, -258, 0, 0, -258, 0, 0, 0, -258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -258, -258, -258, -258, 0, 0, 0, 0, 0, 0, 0, -258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -258, 0, 0, -258, 0, 0, 0, 0, 0, 0, 0, 0, -258, -258, 0, 0, 0, -258, 0, 0, 0, 0, -258, -258, -258, 0, -258, -258, + 0, 0, 0, 0, 0, 0, 0, 0, 676, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 559 - 0, 0, 0, 0, 0, 0, -263, 0, -263, 0, 0, 0, -263, 0, 0, -263, 0, 0, 0, -263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -263, -263, -263, -263, 0, 0, 0, 0, 0, 0, 0, -263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -263, 0, 0, -263, 0, 0, 0, 0, 0, 0, 0, 0, -263, -263, 0, 0, 0, -263, 0, 0, 0, 0, -263, -263, -263, 0, -263, -263, + -946, -946, 0, 0, 0, 0, 0, 0, -946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -946, 0, -946, 0, 0, 0, 0, -946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 560 - 0, 0, 0, 0, 0, 0, -254, 0, -254, 0, 0, 0, -254, 0, 0, -254, 0, 0, 0, -254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -254, -254, -254, -254, 0, 0, 0, 0, 0, 0, 0, -254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -254, 0, 0, -254, 0, 0, 0, 0, 0, 0, 0, 0, -254, -254, 0, 0, 0, -254, 0, 0, 0, 0, -254, -254, -254, 0, -254, -254, + -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, 0, -186, 0, -186, -186, -186, -186, -186, 0, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, -186, 0, 0, 0, -186, -186, -186, -186, -186, -186, 0, -186, 0, 0, 0, 0, 0, 0, 0, 0, -186, 0, 0, -186, -186, 0, -186, 0, -186, -186, 0, 0, 0, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, -186, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 561 - 0, 0, 0, 0, 0, 0, -252, 0, -252, 0, 0, 0, -252, 0, 0, -252, 0, 0, 0, -252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -252, -252, -252, -252, 0, 0, 0, 0, 0, 0, 0, -252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -252, 0, 0, -252, 0, 0, 0, 0, 0, 0, 0, 0, -252, -252, 0, 0, 0, -252, 0, 0, 0, 0, -252, -252, -252, 0, -252, -252, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 679, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 562 - 0, 0, 0, 0, 0, 0, -253, 0, -253, 0, 0, 0, -253, 0, 0, -253, 0, 0, 0, -253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -253, -253, -253, -253, 0, 0, 0, 0, 0, 0, 0, -253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -253, 0, 0, -253, 0, 0, 0, 0, 0, 0, 0, 0, -253, -253, 0, 0, 0, -253, 0, 0, 0, 0, -253, -253, -253, 0, -253, -253, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -726, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 563 - 0, 0, 0, 0, 0, 0, -264, 0, -264, 0, 0, 0, -264, 0, 0, -264, 0, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -264, -264, -264, -264, 0, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -264, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, -264, -264, 0, 0, 0, -264, 0, 0, 0, 0, -264, -264, -264, 0, -264, -264, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, -725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 564 - 0, 0, 0, 0, 0, 0, -256, 0, -256, 0, 0, 0, -256, 0, 0, -256, 0, 0, 0, -256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -256, -256, -256, -256, 0, 0, 0, 0, 0, 0, 0, -256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -256, 0, 0, -256, 0, 0, 0, 0, 0, 0, 0, 0, -256, -256, 0, 0, 0, -256, 0, 0, 0, 0, -256, -256, -256, 0, -256, -256, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -822, 0, 0, 0, 0, 0, 0, 0, 0, 0, -822, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 565 - 0, 0, 0, 0, 0, 0, -261, 0, -261, 0, 0, 0, -261, 0, 0, -261, 0, 0, 0, -261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -261, -261, -261, -261, 0, 0, 0, 0, 0, 0, 0, -261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -261, 0, 0, -261, 0, 0, 0, 0, 0, 0, 0, 0, -261, -261, 0, 0, 0, -261, 0, 0, 0, 0, -261, -261, -261, 0, -261, -261, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -465, 0, 0, 0, 0, 0, 0, 0, 0, 0, -465, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 566 - 0, 0, 0, 0, 0, 0, -262, 0, -262, 0, 0, 0, -262, 0, 0, -262, 0, 0, 0, -262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -262, -262, -262, -262, 0, 0, 0, 0, 0, 0, 0, -262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -262, 0, 0, -262, 0, 0, 0, 0, 0, 0, 0, 0, -262, -262, 0, 0, 0, -262, 0, 0, 0, 0, -262, -262, -262, 0, -262, -262, + -470, -470, 0, 0, -470, 0, -470, 0, -470, 0, 0, -470, -470, 0, -470, -470, 0, -470, 0, 0, 0, 0, 0, -470, -470, -470, 0, -470, 0, 0, -470, 0, -470, 0, 0, 0, 0, -470, 0, 0, -470, 0, 0, 0, 0, -470, 0, -470, 0, -470, 0, -470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -470, -470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -470, -470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 567 - 0, 0, 0, 0, 0, 0, -255, 0, -255, 0, 0, 0, -255, 0, 0, -255, 0, 0, 0, -255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, -255, -255, -255, 0, 0, 0, 0, 0, 0, 0, -255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 0, 0, -255, 0, 0, 0, 0, 0, 0, 0, 0, -255, -255, 0, 0, 0, -255, 0, 0, 0, 0, -255, -255, -255, 0, -255, -255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 688, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 568 - 0, 0, 0, 0, 0, 0, -260, 0, -260, 0, 0, 0, -260, 0, 0, -260, 0, 0, 0, -260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -260, -260, -260, -260, 0, 0, 0, 0, 0, 0, 0, -260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -260, 0, 0, -260, 0, 0, 0, 0, 0, 0, 0, 0, -260, -260, 0, 0, 0, -260, 0, 0, 0, 0, -260, -260, -260, 0, -260, -260, + -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, 0, -203, 0, -203, -203, -203, -203, -203, 0, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, 0, 0, 0, -203, -203, -203, -203, -203, -203, 0, -203, 0, 0, 0, 0, 0, 0, 0, 0, -203, 0, 0, -203, -203, 0, -203, 0, -203, -203, 0, 0, 0, -203, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, -203, -203, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 569 - 0, 0, 0, 0, 0, 0, -259, 0, -259, 0, 0, 0, -259, 0, 0, -259, 0, 0, 0, -259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -259, -259, -259, -259, 0, 0, 0, 0, 0, 0, 0, -259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -259, 0, 0, -259, 0, 0, 0, 0, 0, 0, 0, 0, -259, -259, 0, 0, 0, -259, 0, 0, 0, 0, -259, -259, -259, 0, -259, -259, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 689, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 570 - -747, 0, 0, 0, 0, 0, -747, 0, -747, 0, 0, 0, -747, 0, 0, -747, 0, 0, 0, -747, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -747, 0, -747, -747, -747, -747, 0, 0, 0, 0, 0, -747, -747, -747, -747, 0, -747, -747, -747, -747, 0, 0, 0, 0, -747, -747, -747, -747, -747, 0, 0, -747, -747, -747, -747, 0, -747, -747, -747, -747, -747, -747, -747, -747, -747, 0, 0, 0, -747, 0, 0, 0, 0, -747, -747, -747, -747, -747, -747, + -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, 0, -206, 0, -206, -206, -206, -206, -206, 0, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, 0, 0, 0, -206, -206, -206, -206, -206, -206, 0, -206, 0, 0, 0, 0, 0, 0, 0, 0, -206, 0, 0, -206, -206, 0, -206, 0, -206, -206, 0, 0, 0, -206, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, -206, -206, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 571 - 679, 0, 0, 0, 0, 0, -132, 0, -132, 0, 0, 0, -132, 0, 0, -132, 0, 0, 0, -132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -132, -132, -132, -132, 0, 0, 0, 0, 0, -132, 0, -132, -132, 0, 0, -132, 0, -132, 0, 0, 0, 0, 0, -132, -132, 0, -132, 0, 0, -132, 0, -132, -132, 0, -132, -132, -132, 0, -132, 0, 0, -132, -132, 0, 0, 0, -132, 0, 0, 0, 0, -132, -132, -132, -132, -132, -132, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, -333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 572 - 680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -384, 0, 0, -384, 0, 0, -384, 0, 0, 0, 0, 0, 0, -384, 0, 0, 0, 0, // State 573 - -175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, 0, -373, 0, -373, -373, -373, -373, -373, 0, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, -373, 0, 0, 0, -373, -373, -373, -373, -373, -373, 0, -373, 0, 0, 0, 0, 0, 0, 0, 0, -373, 0, 0, -373, -373, 0, -373, 0, -373, -373, 0, 0, 0, -373, -373, 0, 0, 0, 0, 0, 0, 0, 0, 0, -373, -373, -373, 0, 0, 0, -373, 0, 0, 0, 0, 0, 0, 0, 0, 0, -373, // State 574 - -363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -875, -875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -875, 0, -875, 0, 0, 0, 0, -875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 575 - -332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -876, -876, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -876, 0, -876, 0, 0, 0, 0, -876, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -876, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 576 - -501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 697, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 698, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 577 - -361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -330, 0, 0, 0, -330, 0, -330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 578 - -364, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -364, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -364, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -364, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 579 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -462, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -462, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 699, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 580 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 581 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -179, 0, 0, 0, 0, -179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 582 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -432, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -256, 0, -256, 0, 0, 0, -256, 0, 0, -256, 0, 0, 0, -256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -256, -256, -256, -256, 0, 0, 0, 0, 0, 0, 0, -256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -256, 0, 0, -256, 0, 0, 0, 0, 0, 0, 0, 0, -256, -256, 0, 0, 0, -256, 0, 0, -256, 0, 0, 0, -256, -256, 0, -256, 0, -256, -256, // State 583 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -430, -430, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -430, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -430, 0, + 0, 0, 0, 0, 0, 0, 0, -257, 0, -257, 0, 0, 0, -257, 0, 0, -257, 0, 0, 0, -257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -257, -257, -257, -257, 0, 0, 0, 0, 0, 0, 0, -257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -257, 0, 0, -257, 0, 0, 0, 0, 0, 0, 0, 0, -257, -257, 0, 0, 0, -257, 0, 0, -257, 0, 0, 0, -257, -257, 0, -257, 0, -257, -257, // State 584 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -262, 0, -262, 0, 0, 0, -262, 0, 0, -262, 0, 0, 0, -262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -262, -262, -262, -262, 0, 0, 0, 0, 0, 0, 0, -262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -262, 0, 0, -262, 0, 0, 0, 0, 0, 0, 0, 0, -262, -262, 0, 0, 0, -262, 0, 0, -262, 0, 0, 0, -262, -262, 0, -262, 0, -262, -262, // State 585 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -427, -427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -427, 0, + 0, 0, 0, 0, 0, 0, 0, -253, 0, -253, 0, 0, 0, -253, 0, 0, -253, 0, 0, 0, -253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -253, -253, -253, -253, 0, 0, 0, 0, 0, 0, 0, -253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -253, 0, 0, -253, 0, 0, 0, 0, 0, 0, 0, 0, -253, -253, 0, 0, 0, -253, 0, 0, -253, 0, 0, 0, -253, -253, 0, -253, 0, -253, -253, // State 586 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -426, -426, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -426, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -426, 0, + 0, 0, 0, 0, 0, 0, 0, -251, 0, -251, 0, 0, 0, -251, 0, 0, -251, 0, 0, 0, -251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -251, -251, -251, -251, 0, 0, 0, 0, 0, 0, 0, -251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -251, 0, 0, -251, 0, 0, 0, 0, 0, 0, 0, 0, -251, -251, 0, 0, 0, -251, 0, 0, -251, 0, 0, 0, -251, -251, 0, -251, 0, -251, -251, // State 587 - -503, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -503, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -503, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -252, 0, -252, 0, 0, 0, -252, 0, 0, -252, 0, 0, 0, -252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -252, -252, -252, -252, 0, 0, 0, 0, 0, 0, 0, -252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -252, 0, 0, -252, 0, 0, 0, 0, 0, 0, 0, 0, -252, -252, 0, 0, 0, -252, 0, 0, -252, 0, 0, 0, -252, -252, 0, -252, 0, -252, -252, // State 588 - -411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -263, 0, -263, 0, 0, 0, -263, 0, 0, -263, 0, 0, 0, -263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -263, -263, -263, -263, 0, 0, 0, 0, 0, 0, 0, -263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -263, 0, 0, -263, 0, 0, 0, 0, 0, 0, 0, 0, -263, -263, 0, 0, 0, -263, 0, 0, -263, 0, 0, 0, -263, -263, 0, -263, 0, -263, -263, // State 589 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -255, 0, -255, 0, 0, 0, -255, 0, 0, -255, 0, 0, 0, -255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, -255, -255, -255, 0, 0, 0, 0, 0, 0, 0, -255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 0, 0, -255, 0, 0, 0, 0, 0, 0, 0, 0, -255, -255, 0, 0, 0, -255, 0, 0, -255, 0, 0, 0, -255, -255, 0, -255, 0, -255, -255, // State 590 - -506, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -506, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -506, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -260, 0, -260, 0, 0, 0, -260, 0, 0, -260, 0, 0, 0, -260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -260, -260, -260, -260, 0, 0, 0, 0, 0, 0, 0, -260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -260, 0, 0, -260, 0, 0, 0, 0, 0, 0, 0, 0, -260, -260, 0, 0, 0, -260, 0, 0, -260, 0, 0, 0, -260, -260, 0, -260, 0, -260, -260, // State 591 - -435, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -435, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -261, 0, -261, 0, 0, 0, -261, 0, 0, -261, 0, 0, 0, -261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -261, -261, -261, -261, 0, 0, 0, 0, 0, 0, 0, -261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -261, 0, 0, -261, 0, 0, 0, 0, 0, 0, 0, 0, -261, -261, 0, 0, 0, -261, 0, 0, -261, 0, 0, 0, -261, -261, 0, -261, 0, -261, -261, // State 592 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 688, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -254, 0, -254, 0, 0, 0, -254, 0, 0, -254, 0, 0, 0, -254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -254, -254, -254, -254, 0, 0, 0, 0, 0, 0, 0, -254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -254, 0, 0, -254, 0, 0, 0, 0, 0, 0, 0, 0, -254, -254, 0, 0, 0, -254, 0, 0, -254, 0, 0, 0, -254, -254, 0, -254, 0, -254, -254, // State 593 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 689, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -259, 0, -259, 0, 0, 0, -259, 0, 0, -259, 0, 0, 0, -259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -259, -259, -259, -259, 0, 0, 0, 0, 0, 0, 0, -259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -259, 0, 0, -259, 0, 0, 0, 0, 0, 0, 0, 0, -259, -259, 0, 0, 0, -259, 0, 0, -259, 0, 0, 0, -259, -259, 0, -259, 0, -259, -259, // State 594 - -494, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -494, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -258, 0, -258, 0, 0, 0, -258, 0, 0, -258, 0, 0, 0, -258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -258, -258, -258, -258, 0, 0, 0, 0, 0, 0, 0, -258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -258, 0, 0, -258, 0, 0, 0, 0, 0, 0, 0, 0, -258, -258, 0, 0, 0, -258, 0, 0, -258, 0, 0, 0, -258, -258, 0, -258, 0, -258, -258, // State 595 - -752, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -752, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -772, 0, 0, 0, 0, 0, 0, -772, 0, -772, 0, 0, 0, -772, 0, 0, -772, 0, 0, 0, -772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -772, 0, -772, -772, -772, -772, 0, 0, 0, 0, 0, -772, -772, -772, -772, 0, -772, -772, -772, -772, 0, 0, 0, 0, -772, -772, -772, -772, -772, 0, 0, -772, -772, -772, -772, 0, -772, -772, -772, -772, -772, -772, -772, -772, -772, 0, 0, 0, -772, 0, 0, -772, 0, 0, 0, -772, -772, 0, -772, -772, -772, -772, // State 596 - -376, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -376, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 705, 0, 0, 0, 0, 0, 0, -134, 0, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -134, -134, -134, -134, 0, 0, 0, 0, 0, -134, 0, -134, -134, 0, 0, -134, 0, -134, 0, 0, 0, 0, 0, -134, -134, 0, -134, 0, 0, -134, 0, -134, -134, 0, -134, -134, -134, 0, -134, 0, 0, -134, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, -134, 0, -134, -134, -134, -134, // State 597 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -870, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -870, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 706, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 598 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 599 - 0, -184, -184, 0, -184, 0, -184, 0, -184, -184, 0, 0, -184, 0, -184, -184, 0, 0, -184, 0, -184, -184, 0, 0, -213, 0, 0, -184, -184, 0, -184, 0, -184, -184, -184, -184, 0, 0, -184, 0, 0, 0, 0, -184, 0, -184, 0, -184, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -184, 0, -184, -184, 0, 0, 0, -184, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 422, + -362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 600 - 0, -911, 0, 0, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, -911, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -911, 0, 0, -911, 0, -911, -911, -911, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -911, 0, -911, -911, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -911, 0, -911, -911, 0, 0, 0, -911, -911, 0, 0, 0, 0, 0, 0, 0, 0, 0, -911, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 601 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -913, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 602 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 603 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 604 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 605 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -358, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 606 - 0, -740, -740, 0, -740, 0, 0, 0, -740, 166, 0, 0, -740, 0, -740, -740, 0, 0, 0, 0, -740, -740, 0, 0, 0, 0, 0, -740, -740, 0, -740, 0, -740, -740, -740, -740, 0, 0, -740, 0, 0, 0, 0, 0, 0, -740, 0, -740, -740, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -740, 0, -740, -740, 0, 0, 0, -740, -740, 0, 0, 0, 0, 0, 0, 0, 0, 0, -740, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -431, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 607 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -742, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 608 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -453, -453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -453, 0, // State 609 - 0, -185, -185, 0, -185, 0, -185, 0, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, -214, 0, 0, -185, -185, 0, -185, 0, -185, -185, -185, -185, 0, 0, -185, 0, 0, 0, 0, -185, 0, -185, 0, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, -185, -185, 0, 0, 0, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 610 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -307, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -450, -450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -450, 0, // State 611 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -831, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -449, -449, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -449, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -449, 0, // State 612 - 0, -186, -186, 0, -186, 0, -186, 0, -186, -186, 0, 0, -186, 0, -186, -186, 0, 0, -186, 0, -186, -186, 0, 0, -215, 0, 0, -186, -186, 0, -186, 0, -186, -186, -186, -186, 0, 0, -186, 0, 0, 0, 0, -186, 0, -186, 0, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -186, 0, -186, -186, 0, 0, 0, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 613 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -834, 0, 0, 0, 0, 0, 0, 0, 0, 0, -839, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -834, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -434, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -434, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 614 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 615 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -833, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -833, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 616 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -838, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -458, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -458, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 617 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -373, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 714, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 618 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 619 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -519, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -519, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 620 - 0, 0, 0, 0, 0, 0, 0, -890, 0, 0, 0, 0, 0, 0, -890, 0, 0, 0, 0, 0, 0, 0, 0, 0, -890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -777, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -777, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 621 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -892, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -399, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -399, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 622 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -905, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -902, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -902, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 623 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -891, 0, 0, 0, 0, 0, 0, 0, 0, 0, -893, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 624 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -943, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, -943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -943, 0, 0, -943, 0, -943, -943, -943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -943, 0, -943, -943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -943, 0, -943, -943, 0, 0, 0, -943, -943, 0, 0, 0, 0, 0, 0, 0, 0, 0, -943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 625 - 0, -356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -356, 0, 0, -356, 0, -356, -356, -356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, 0, -356, -356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -356, 0, -356, -356, 0, 0, 0, -356, -356, 0, 0, 0, 0, 0, 0, 0, 0, 0, -356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -945, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 626 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -358, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 627 - 0, -212, -212, 0, -212, 0, -212, 0, -212, -212, 0, 0, -212, 0, -212, -212, 0, 0, -212, 0, -212, -212, 0, 0, -239, 0, 0, -212, -212, 0, -212, 0, -212, -212, -212, -212, 0, 0, -212, 0, 0, 0, 0, -212, 0, -212, 0, -212, -212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -212, 0, -212, -212, 0, 0, 0, -212, -212, 0, 0, 0, 0, 0, 0, 0, 0, 0, -212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -792, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 628 - 0, -210, -210, 0, -210, 0, -210, 0, -210, -210, 0, 0, -210, 0, -210, -210, 0, 0, -210, 0, -210, -210, 0, 0, -237, 0, 0, -210, -210, 0, -210, 0, -210, -210, -210, -210, 0, 0, -210, 0, 0, 0, 0, -210, 0, -210, 0, -210, -210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -210, 0, -210, -210, 0, 0, 0, -210, -210, 0, 0, 0, 0, 0, 0, 0, 0, 0, -210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 629 - 0, -211, -211, 0, -211, 0, -211, 0, -211, -211, 0, 0, -211, 0, -211, -211, 0, 0, -211, 0, -211, -211, 0, 0, -238, 0, 0, -211, -211, 0, -211, 0, -211, -211, -211, -211, 0, 0, -211, 0, 0, 0, 0, -211, 0, -211, 0, -211, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -211, 0, -211, -211, 0, 0, 0, -211, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 630 - 0, -209, -209, 0, -209, 0, -209, 0, -209, -209, 0, 0, -209, 0, -209, -209, 0, 0, -209, 0, -209, -209, 0, 0, -236, 0, 0, -209, -209, 0, -209, 0, -209, -209, -209, -209, 0, 0, -209, 0, 0, 0, 0, -209, 0, -209, 0, -209, -209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -209, 0, -209, -209, 0, 0, 0, -209, -209, 0, 0, 0, 0, 0, 0, 0, 0, 0, -209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -765, -765, 0, -765, 0, 0, 0, -765, 177, 0, 0, -765, 0, -765, -765, 0, 0, 0, 0, -765, -765, 0, 0, 0, 0, 0, -765, -765, 0, -765, 0, -765, -765, -765, -765, 0, 0, -765, 0, 0, 0, 0, 0, 0, -765, 0, -765, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -765, 0, -765, -765, 0, 0, 0, -765, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, -765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 631 - 0, 0, 0, 0, 0, 0, 0, 708, 0, 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 632 - -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, 0, -166, 0, -166, -166, -166, -166, -166, 0, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, -166, 0, 0, 0, -166, -166, -166, -166, -166, -166, 0, -166, 0, 0, 0, 0, 0, 0, 0, 0, -166, 0, 0, -166, -166, 0, -166, 0, -166, -166, 0, 0, 0, -166, -166, 0, 0, 0, 0, 0, 0, 0, 0, 0, -166, -166, -166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -523, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 633 - -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, 0, -163, 0, -163, -163, -163, -163, -163, 0, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, -163, 0, 0, 0, -163, -163, -163, -163, -163, -163, 0, -163, 0, 0, 0, 0, 0, 0, 0, 0, -163, 0, 0, -163, -163, 0, -163, 0, -163, -163, 0, 0, 0, -163, -163, 0, 0, 0, 0, 0, 0, 0, 0, 0, -163, -163, -163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -184, -184, 0, -184, 0, -184, 0, -184, -184, 0, 0, -184, 0, -184, -184, 0, 0, -184, 0, -184, -184, 0, 0, -213, 0, 0, -184, -184, 0, -184, 0, -184, -184, -184, -184, 0, 0, -184, 0, 0, 0, 0, -184, 0, -184, 0, -184, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -184, 0, -184, -184, 0, 0, 0, -184, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, -184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 634 - 0, 0, 0, 0, 0, 0, -116, -116, -116, -116, 0, 0, -116, 0, 0, -116, 0, 0, 0, -116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -116, -116, -116, -116, 0, 0, 0, 0, 0, 0, 0, -116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -116, 0, 0, -116, 0, 0, 0, 0, 0, 0, 0, 0, 0, -116, 0, 0, 0, -116, 0, 0, 0, 0, -116, -116, -116, 0, -116, -116, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 635 - 0, 0, 0, 0, 0, 0, 0, -400, 0, 0, 0, 0, 0, 0, -400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -863, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 636 - 0, 0, 0, 0, 0, 0, 0, -403, 0, 0, 0, 0, 0, 0, -403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -185, -185, 0, -185, 0, -185, 0, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, -185, 0, -185, -185, 0, 0, -214, 0, 0, -185, -185, 0, -185, 0, -185, -185, -185, -185, 0, 0, -185, 0, 0, 0, 0, -185, 0, -185, 0, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, -185, -185, 0, 0, 0, -185, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, -185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 637 - 0, 0, 0, 0, 0, 0, 0, -404, 0, 0, 0, 0, 0, 0, -404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -866, 0, 0, 0, 0, 0, 0, 0, 0, 0, -871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -866, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 638 - -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, 0, -242, 0, -242, -242, -242, -242, -242, 0, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, -242, 0, 0, 0, -242, -242, -242, -242, -242, -242, 0, -242, 0, 0, 0, 0, 0, 0, 0, 0, -242, 0, 0, -242, -242, 0, -242, 0, -242, -242, 0, 0, 0, -242, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, -242, -242, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 639 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 640 - -143, -143, 0, -143, 0, -143, 0, -143, 0, 0, -143, -143, 0, -143, -143, 0, -143, 0, 0, 0, 0, 0, -143, -143, -143, 0, -143, -143, 0, -143, -143, -143, -143, -143, -143, 0, -143, 0, 0, -143, 0, 0, 0, 0, -143, 0, -143, -143, -143, 0, -143, 0, 0, 0, 0, 0, 0, 0, 0, -143, 0, 0, -143, -143, 0, -143, 0, -143, -143, 0, 0, 0, -143, -143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, -143, -143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -870, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 641 - -488, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 642 - -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, 0, -202, 0, -202, -202, -202, -202, -202, 0, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, 0, 0, 0, -202, -202, -202, -202, -202, -202, 0, -202, 0, 0, 0, 0, 0, 0, 0, 0, -202, 0, 0, -202, -202, 0, -202, 0, -202, -202, 0, 0, 0, -202, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, -202, -202, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 643 - 0, 0, 0, 0, 0, 0, 0, -775, 0, 0, 0, 0, 0, 0, -775, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -775, 0, 0, 0, 0, 0, -775, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -775, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -775, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 644 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -922, 0, 0, 0, 0, 0, 0, -922, 0, 0, 0, 0, 0, 0, 0, 0, 0, -922, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 645 - -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, 0, -199, 0, -199, -199, -199, -199, -199, 0, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, -199, 0, 0, 0, -199, -199, -199, -199, -199, -199, 0, -199, 0, 0, 0, 0, 0, 0, 0, 0, -199, 0, 0, -199, -199, 0, -199, 0, -199, -199, 0, 0, 0, -199, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, -199, -199, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 646 - 0, 0, 0, 0, 0, 0, 0, -63, 0, 0, 0, 0, 0, 0, -63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 647 - -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, 0, -193, 0, -193, -193, -193, -193, -193, 0, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, 0, 0, 0, -193, -193, -193, -193, -193, -193, 0, -193, 0, 0, 0, 0, 0, 0, 0, 0, -193, 0, 0, -193, -193, 0, -193, 0, -193, -193, 0, 0, 0, -193, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, -193, -193, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -923, 0, 0, 0, 0, 0, 0, 0, 0, 0, -925, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 648 - 0, 0, 0, 0, 0, 0, 0, -492, 0, 0, 0, 0, 0, 0, -492, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 649 - 0, 0, 0, 0, 0, 0, 0, -524, 0, 0, 0, 0, 0, 0, -524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -355, 0, 0, -355, 0, -355, -355, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, -355, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -355, 0, -355, -355, 0, 0, 0, -355, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 650 - -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, 0, -190, 0, -190, -190, -190, -190, -190, 0, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, -190, 0, 0, 0, -190, -190, -190, -190, -190, -190, 0, -190, 0, 0, 0, 0, 0, 0, 0, 0, -190, 0, 0, -190, -190, 0, -190, 0, -190, -190, 0, 0, 0, -190, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, -190, -190, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 651 - -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, 0, -203, 0, -203, -203, -203, -203, -203, 0, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, -203, 0, 0, 0, -203, -203, -203, -203, -203, -203, 0, -203, 0, 0, 0, 0, 0, 0, 0, 0, -203, 0, 0, -203, -203, 0, -203, 0, -203, -203, 0, 0, 0, -203, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, -203, -203, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -211, -211, 0, -211, 0, -211, 0, -211, -211, 0, 0, -211, 0, -211, -211, 0, 0, -211, 0, -211, -211, 0, 0, -238, 0, 0, -211, -211, 0, -211, 0, -211, -211, -211, -211, 0, 0, -211, 0, 0, 0, 0, -211, 0, -211, 0, -211, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -211, 0, -211, -211, 0, 0, 0, -211, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, -211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 652 - -916, 0, 0, 0, 0, 0, 0, -916, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -916, 0, 0, 0, 0, -916, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -209, -209, 0, -209, 0, -209, 0, -209, -209, 0, 0, -209, 0, -209, -209, 0, 0, -209, 0, -209, -209, 0, 0, -236, 0, 0, -209, -209, 0, -209, 0, -209, -209, -209, -209, 0, 0, -209, 0, 0, 0, 0, -209, 0, -209, 0, -209, -209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -209, 0, -209, -209, 0, 0, 0, -209, -209, 0, 0, 0, 0, 0, 0, 0, 0, 0, -209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 653 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -210, -210, 0, -210, 0, -210, 0, -210, -210, 0, 0, -210, 0, -210, -210, 0, 0, -210, 0, -210, -210, 0, 0, -237, 0, 0, -210, -210, 0, -210, 0, -210, -210, -210, -210, 0, 0, -210, 0, 0, 0, 0, -210, 0, -210, 0, -210, -210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -210, 0, -210, -210, 0, 0, 0, -210, -210, 0, 0, 0, 0, 0, 0, 0, 0, 0, -210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 654 - -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, 0, -189, 0, -189, -189, -189, -189, -189, 0, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, 0, 0, 0, -189, -189, -189, -189, -189, -189, 0, -189, 0, 0, 0, 0, 0, 0, 0, 0, -189, 0, 0, -189, -189, 0, -189, 0, -189, -189, 0, 0, 0, -189, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, -189, -189, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -208, -208, 0, -208, 0, -208, 0, -208, -208, 0, 0, -208, 0, -208, -208, 0, 0, -208, 0, -208, -208, 0, 0, -235, 0, 0, -208, -208, 0, -208, 0, -208, -208, -208, -208, 0, 0, -208, 0, 0, 0, 0, -208, 0, -208, 0, -208, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -208, 0, -208, -208, 0, 0, 0, -208, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 655 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 722, 0, 0, 0, 0, 0, 0, 0, 0, 0, -682, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 734, 0, 0, 0, 0, 0, 0, 735, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 656 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -520, 0, 0, 0, 0, 0, 0, 0, 0, 0, -520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, 0, -165, 0, -165, -165, -165, -165, -165, 0, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, 0, 0, 0, -165, -165, -165, -165, -165, -165, 0, -165, 0, 0, 0, 0, 0, 0, 0, 0, -165, 0, 0, -165, -165, 0, -165, 0, -165, -165, 0, 0, 0, -165, -165, 0, 0, 0, 0, 0, 0, 0, 0, 0, -165, -165, -165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 657 - -444, 0, 0, -444, 0, -444, 0, -444, 0, 0, -444, -444, 0, -444, -444, 0, -444, 0, 0, 0, 0, 0, -444, -444, -444, 0, -444, 0, 0, -444, 0, -444, 0, 0, 0, 0, -444, 0, 0, -444, 0, 0, 0, 0, -444, 0, -444, 0, -444, 0, -444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -444, -444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -444, -444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, 0, -162, 0, -162, -162, -162, -162, -162, 0, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, -162, 0, 0, 0, -162, -162, -162, -162, -162, -162, 0, -162, 0, 0, 0, 0, 0, 0, 0, 0, -162, 0, 0, -162, -162, 0, -162, 0, -162, -162, 0, 0, 0, -162, -162, 0, 0, 0, 0, 0, 0, 0, 0, 0, -162, -162, -162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 658 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -540, 0, 0, 0, 0, 0, 0, 0, 0, 0, -540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -118, -118, -118, -118, 0, 0, -118, 0, 0, -118, 0, 0, 0, -118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -118, -118, -118, -118, 0, 0, 0, 0, 0, 0, 0, -118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -118, 0, 0, -118, 0, 0, 0, 0, 0, 0, 0, 0, 0, -118, 0, 0, 0, -118, 0, 0, -118, 0, 0, 0, -118, -118, 0, -118, 0, -118, -118, // State 659 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, -699, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -423, 0, 0, 0, 0, 0, 0, -423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 660 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 728, 0, 0, 0, 0, 0, 0, 0, 0, 0, -694, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -426, 0, 0, 0, 0, 0, 0, -426, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 661 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -21, 0, 0, 0, 0, 0, 0, 0, 0, 0, -21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -427, 0, 0, 0, 0, 0, 0, -427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 662 - -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, 0, -206, 0, -206, -206, -206, -206, -206, 0, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, 0, 0, 0, -206, -206, -206, -206, -206, -206, 0, -206, 0, 0, 0, 0, 0, 0, 0, 0, -206, 0, 0, -206, -206, 0, -206, 0, -206, -206, 0, 0, 0, -206, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, -206, -206, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, 0, -241, 0, -241, -241, -241, -241, -241, 0, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, -241, 0, 0, 0, -241, -241, -241, -241, -241, -241, 0, -241, 0, 0, 0, 0, 0, 0, 0, 0, -241, 0, 0, -241, -241, 0, -241, 0, -241, -241, 0, 0, 0, -241, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, -241, -241, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 663 - -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, 0, -208, 0, -208, -208, -208, -208, -208, 0, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, -208, 0, 0, 0, -208, -208, -208, -208, -208, -208, 0, -208, 0, 0, 0, 0, 0, 0, 0, 0, -208, 0, 0, -208, -208, 0, -208, 0, -208, -208, 0, 0, 0, -208, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, -208, -208, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -846, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -846, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 664 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -142, -142, -142, 0, -142, 0, -142, 0, -142, 0, 0, -142, -142, 0, -142, -142, 0, -142, 0, 0, 0, 0, 0, -142, -142, -142, 0, -142, -142, 0, -142, -142, -142, -142, -142, -142, 0, -142, 0, 0, -142, 0, 0, 0, 0, -142, 0, -142, -142, -142, 0, -142, 0, 0, 0, 0, 0, 0, 0, 0, -142, 0, 0, -142, -142, 0, -142, 0, -142, -142, 0, 0, 0, -142, -142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, -142, -142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 665 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -513, 0, 0, 0, 0, 0, 0, 0, -513, 0, 0, 0, 0, 0, 0, -513, 0, 0, 0, 0, 0, 0, 0, 0, 0, -513, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -513, 0, 0, 0, 0, 0, -513, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -513, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -513, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 666 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, 0, -201, 0, -201, -201, -201, -201, -201, 0, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, -201, 0, 0, 0, -201, -201, -201, -201, -201, -201, 0, -201, 0, 0, 0, 0, 0, 0, 0, 0, -201, 0, 0, -201, -201, 0, -201, 0, -201, -201, 0, 0, 0, -201, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, -201, -201, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 667 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 668 - -748, 0, 0, 0, 0, 0, -748, 0, -748, 0, 0, 0, -748, 0, 0, -748, 0, 0, 0, -748, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -748, 0, -748, -748, -748, -748, 0, 0, 0, 0, 0, -748, -748, -748, -748, 0, -748, -748, -748, -748, 0, 0, 0, 0, -748, -748, -748, -748, -748, 0, 0, -748, -748, -748, -748, 0, -748, -748, -748, -748, -748, -748, -748, -748, -748, 0, 0, 0, -748, 0, 0, 0, 0, -748, -748, -748, -748, -748, -748, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 669 - 729, 0, 0, 0, 0, 0, -133, 0, -133, 0, 0, 0, -133, 0, 0, -133, 0, 0, 0, -133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -133, -133, -133, -133, 0, 0, 0, 0, 0, -133, 0, -133, -133, 0, 0, -133, 0, -133, 0, 0, 0, 0, 0, -133, -133, 0, -133, 0, 0, -133, 0, -133, -133, 0, -133, -133, -133, 0, -133, 0, 0, -133, -133, 0, 0, 0, -133, 0, 0, 0, 0, -133, -133, -133, -133, -133, -133, + -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, 0, -198, 0, -198, -198, -198, -198, -198, 0, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, 0, 0, 0, -198, -198, -198, -198, -198, -198, 0, -198, 0, 0, 0, 0, 0, 0, 0, 0, -198, 0, 0, -198, -198, 0, -198, 0, -198, -198, 0, 0, 0, -198, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, -198, -198, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 670 - -84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -65, 0, 0, 0, 0, 0, 0, -65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 671 - -181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -181, 0, 0, 0, 0, -181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, 0, -192, 0, -192, -192, -192, -192, -192, 0, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, 0, 0, 0, -192, -192, -192, -192, -192, -192, 0, -192, 0, 0, 0, 0, 0, 0, 0, 0, -192, 0, 0, -192, -192, 0, -192, 0, -192, -192, 0, 0, 0, -192, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, -192, -192, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 672 - -843, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -843, 0, 0, 0, 0, -843, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -517, 0, 0, 0, 0, 0, 0, -517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 673 - -367, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -367, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -549, 0, 0, 0, 0, 0, 0, -549, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 674 - -844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -844, 0, 0, 0, 0, -844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, 0, -189, 0, -189, -189, -189, -189, -189, 0, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, -189, 0, 0, 0, -189, -189, -189, -189, -189, -189, 0, -189, 0, 0, 0, 0, 0, 0, 0, 0, -189, 0, 0, -189, -189, 0, -189, 0, -189, -189, 0, 0, 0, -189, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, -189, -189, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 675 - -177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -177, 0, 0, 0, 0, -177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, 0, -202, 0, -202, -202, -202, -202, -202, 0, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, -202, 0, 0, 0, -202, -202, -202, -202, -202, -202, 0, -202, 0, 0, 0, 0, 0, 0, 0, 0, -202, 0, 0, -202, -202, 0, -202, 0, -202, -202, 0, 0, 0, -202, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, -202, -202, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 676 - -176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -176, 0, 0, 0, 0, -176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -948, -948, 0, 0, 0, 0, 0, 0, -948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -948, 0, -948, 0, 0, 0, 0, -948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 677 - -437, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -437, 0, 0, 0, 0, -437, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 678 - -745, 0, 0, 0, 0, 0, -745, 0, -745, 0, 0, 0, -745, 0, 0, -745, 0, 0, 0, -745, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -745, 0, -745, -745, -745, -745, 0, 0, 0, 0, 0, -745, -745, -745, -745, 0, -745, -745, -745, -745, 0, 0, 0, 0, -745, -745, -745, -745, -745, 0, 0, -745, -745, -745, -745, 0, -745, -745, -745, -745, -745, -745, -745, -745, -745, 0, 0, 0, -745, 0, 0, 0, 0, -745, -745, -745, -745, -745, -745, + -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, 0, -188, 0, -188, -188, -188, -188, -188, 0, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, -188, 0, 0, 0, -188, -188, -188, -188, -188, -188, 0, -188, 0, 0, 0, 0, 0, 0, 0, 0, -188, 0, 0, -188, -188, 0, -188, 0, -188, -188, 0, 0, 0, -188, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, -188, -188, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 679 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -327, 0, 0, 0, -327, 0, -327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 748, 0, 0, 0, 0, 0, 0, 0, 0, 0, -707, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 680 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -545, 0, 0, 0, 0, 0, 0, 0, 0, 0, -545, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 681 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -468, -468, 0, 0, -468, 0, -468, 0, -468, 0, 0, -468, -468, 0, -468, -468, 0, -468, 0, 0, 0, 0, 0, -468, -468, -468, 0, -468, 0, 0, -468, 0, -468, 0, 0, 0, 0, -468, 0, 0, -468, 0, 0, 0, 0, -468, 0, -468, 0, -468, 0, -468, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -468, -468, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -468, -468, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 682 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -565, 0, 0, 0, 0, 0, 0, 0, 0, 0, -565, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 683 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, -724, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 684 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -433, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 755, 0, 0, 0, 0, 0, 0, 0, 0, 0, -719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 685 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -431, -431, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -431, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -431, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -23, 0, 0, 0, 0, 0, 0, 0, 0, 0, -23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 686 - -341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -341, 0, 0, 0, 207, 0, 0, 0, 0, 0, 0, 0, -341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -469, -469, 0, 0, -469, 0, -469, 0, -469, 0, 0, -469, -469, 0, -469, -469, 0, -469, 0, 0, 0, 0, 0, -469, -469, -469, 0, -469, 0, 0, -469, 0, -469, 0, 0, 0, 0, -469, 0, 0, -469, 0, 0, 0, 0, -469, 0, -469, 0, -469, 0, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -469, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -469, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 687 - 760, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, 0, -205, 0, -205, -205, -205, -205, -205, 0, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, 0, 0, 0, -205, -205, -205, -205, -205, -205, 0, -205, 0, 0, 0, 0, 0, 0, 0, 0, -205, 0, 0, -205, -205, 0, -205, 0, -205, -205, 0, 0, 0, -205, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, -205, -205, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 688 - 763, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, 0, -207, 0, -207, -207, -207, -207, -207, 0, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, -207, 0, 0, 0, -207, -207, -207, -207, -207, -207, 0, -207, 0, 0, 0, 0, 0, 0, 0, 0, -207, 0, 0, -207, -207, 0, -207, 0, -207, -207, 0, 0, 0, -207, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, -207, -207, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 689 - 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -525, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -525, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 690 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 691 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 692 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -533, 0, 0, 0, 0, 0, 0, 0, 0, 0, -535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -533, 0, 0, 0, 0, 0, 0, 0, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 693 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -159, 0, 0, 0, 0, 0, 0, 0, 0, 0, -161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 511, -159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -159, 0, 0, 0, 0, 0, 0, 0, -159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 694 - 0, -241, -241, 0, -241, 0, -241, 0, -241, -241, 0, 0, -241, 0, -241, -241, 0, 0, -241, 0, -241, -241, 0, 0, -245, 0, 0, -241, -241, 0, -241, 0, -241, -241, -241, -241, 0, 0, -241, 0, 0, 0, 0, -241, 0, -241, 0, -241, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -241, 0, -241, -241, 0, 0, 0, -241, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 759, 0, // State 695 - 0, -370, -370, 0, -370, 0, 0, 0, -370, 0, 0, 0, -370, 0, -370, -370, 0, 0, 0, 0, -370, -370, 0, 0, -372, 0, 0, -370, -370, 0, -370, 0, -370, -370, -370, -370, 0, 0, -370, 0, 0, 0, 0, 0, 0, -370, 0, -370, -370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -370, 0, -370, -370, 0, 0, 0, -370, -370, 0, 0, 0, 0, 0, 0, 0, 0, 0, -370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -392, 0, 0, -392, 0, 0, -392, 0, 0, 0, 0, 0, 0, -392, 0, 0, 0, 0, // State 696 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, 0, 0, 0, 0, 0, 0, 0, 0, 0, -906, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -773, 0, 0, 0, 0, 0, 0, -773, 0, -773, 0, 0, 0, -773, 0, 0, -773, 0, 0, 0, -773, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -773, 0, -773, -773, -773, -773, 0, 0, 0, 0, 0, -773, -773, -773, -773, 0, -773, -773, -773, -773, 0, 0, 0, 0, -773, -773, -773, -773, -773, 0, 0, -773, -773, -773, -773, 0, -773, -773, -773, -773, -773, -773, -773, -773, -773, 0, 0, 0, -773, 0, 0, -773, 0, 0, 0, -773, -773, 0, -773, -773, -773, -773, // State 697 - 0, 0, 0, 0, 0, 0, 0, 787, 0, 0, 0, 0, 0, 0, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 763, 0, 0, 0, 0, 0, 0, -135, 0, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -135, -135, -135, -135, 0, 0, 0, 0, 0, -135, 0, -135, -135, 0, 0, -135, 0, -135, 0, 0, 0, 0, 0, -135, -135, 0, -135, 0, 0, -135, 0, -135, -135, 0, -135, -135, -135, 0, -135, 0, 0, -135, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, -135, 0, -135, -135, -135, -135, // State 698 - 0, 0, 0, 0, 0, 0, 0, -523, 0, 0, 0, 0, 0, 0, -523, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 699 - 0, 0, 0, 0, 0, 0, 0, 790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -180, 0, 0, 0, 0, -180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 700 - 0, -200, -200, 0, -200, 0, -200, 0, -200, -200, 0, 0, -200, 0, -200, -200, 0, 0, -200, 0, -200, -200, 0, 0, -227, 0, 0, -200, -200, 0, -200, 0, -200, -200, -200, -200, 0, 0, -200, 0, 0, 0, 0, -200, 0, -200, 0, -200, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -200, 0, -200, -200, 0, 0, 0, -200, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -366, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -366, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 701 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 792, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -176, 0, 0, 0, 0, -176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 702 - 0, -188, -188, 0, -188, 0, -188, 0, -188, -188, 0, 0, -188, 0, -188, -188, 0, 0, -188, 0, -188, -188, 0, 0, -217, 0, 0, -188, -188, 0, -188, 0, -188, -188, -188, -188, 0, 0, -188, 0, 0, 0, 0, -188, 0, -188, 0, -188, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -188, 0, -188, -188, 0, 0, 0, -188, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -175, 0, 0, 0, 0, -175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 703 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -495, 0, 0, 0, 0, 0, 0, 0, 0, 0, -497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -495, -495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -495, 0, 0, 0, 0, 0, 0, 0, -495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -460, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -460, 0, 0, 0, 0, -460, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 704 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 795, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -770, 0, 0, 0, 0, 0, 0, -770, 0, -770, 0, 0, 0, -770, 0, 0, -770, 0, 0, 0, -770, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -770, 0, -770, -770, -770, -770, 0, 0, 0, 0, 0, -770, -770, -770, -770, 0, -770, -770, -770, -770, 0, 0, 0, 0, -770, -770, -770, -770, -770, 0, 0, -770, -770, -770, -770, 0, -770, -770, -770, -770, -770, -770, -770, -770, -770, 0, 0, 0, -770, 0, 0, -770, 0, 0, 0, -770, -770, 0, -770, -770, -770, -770, // State 705 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, -326, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 706 - 0, -205, -205, 0, -205, 0, -205, 0, -205, -205, 0, 0, -205, 0, -205, -205, 0, 0, -205, 0, -205, -205, 0, 0, -232, 0, 0, -205, -205, 0, -205, 0, -205, -205, -205, -205, 0, 0, -205, 0, 0, 0, 0, -205, 0, -205, 0, -205, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -205, 0, -205, -205, 0, 0, 0, -205, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 707 - -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, 0, -165, 0, -165, -165, -165, -165, -165, 0, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, 0, 0, 0, -165, -165, -165, -165, -165, -165, 0, -165, 0, 0, 0, 0, 0, 0, 0, 0, -165, 0, 0, -165, -165, 0, -165, 0, -165, -165, 0, 0, 0, -165, -165, 0, 0, 0, 0, 0, 0, 0, 0, 0, -165, -165, -165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 708 - 0, 0, 0, 0, 0, 0, -117, -117, -117, -117, 0, 0, -117, 0, 0, -117, 0, 0, 0, -117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -117, -117, -117, -117, 0, 0, 0, 0, 0, 0, 0, -117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -117, 0, 0, -117, 0, 0, 0, 0, 0, 0, 0, 0, 0, -117, 0, 0, 0, -117, 0, 0, 0, 0, -117, -117, -117, 0, -117, -117, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 709 - 0, 0, 0, 0, 0, 0, 0, -402, 0, 0, 0, 0, 0, 0, -402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 710 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -866, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -866, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -456, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 711 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -812, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -812, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -454, -454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -454, 0, // State 712 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -867, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -867, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -340, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, -340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 713 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -813, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -813, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 794, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 714 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -776, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -776, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 715 - -832, 0, 0, -832, 0, -832, 0, -832, 0, 0, -832, -832, 0, -832, -832, 0, -832, 0, 0, 0, 0, 0, -832, -832, -832, 0, -832, 0, 0, -832, 0, -832, 0, 0, 0, 0, -832, 0, 0, -832, 0, 0, 0, 0, -832, 0, -832, 0, -832, 0, -832, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -832, -832, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -832, -832, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 801, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 716 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 717 - 0, 0, 0, 0, 0, 0, 0, -64, 0, 0, 0, 0, 0, 0, -64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 718 - -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, 0, -195, 0, -195, -195, -195, -195, -195, 0, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, 0, 0, 0, -195, -195, -195, -195, -195, -195, 0, -195, 0, 0, 0, 0, 0, 0, 0, 0, -195, 0, 0, -195, -195, 0, -195, 0, -195, -195, 0, 0, 0, -195, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, -195, -195, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -558, 0, 0, 0, 0, 0, 0, 0, 0, 0, -560, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -558, 0, 0, 0, 0, 0, 0, 0, 531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 719 - 0, 0, 0, 0, 0, 0, 0, 799, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -158, 0, 0, 0, 0, 0, 0, 0, 0, 0, -160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 532, -158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -158, 0, 0, 0, 0, 0, 0, 0, -158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 720 - -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, 0, -196, 0, -196, -196, -196, -196, -196, 0, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, -196, 0, 0, 0, -196, -196, -196, -196, -196, -196, 0, -196, 0, 0, 0, 0, 0, 0, 0, 0, -196, 0, 0, -196, -196, 0, -196, 0, -196, -196, 0, 0, 0, -196, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, -196, -196, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -240, -240, 0, -240, 0, -240, 0, -240, -240, 0, 0, -240, 0, -240, -240, 0, 0, -240, 0, -240, -240, 0, 0, -244, 0, 0, -240, -240, 0, -240, 0, -240, -240, -240, -240, 0, 0, -240, 0, 0, 0, 0, -240, 0, -240, 0, -240, -240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 0, -240, -240, 0, 0, 0, -240, -240, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 721 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -679, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -393, -393, 0, -393, 0, 0, 0, -393, 0, 0, 0, -393, 0, -393, -393, 0, 0, 0, 0, -393, -393, 0, 0, -395, 0, 0, -393, -393, 0, -393, 0, -393, -393, -393, -393, 0, 0, -393, 0, 0, 0, 0, 0, 0, -393, 0, -393, -393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -393, 0, -393, -393, 0, 0, 0, -393, -393, 0, 0, 0, 0, 0, 0, 0, 0, 0, -393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 722 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, -673, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, -938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 723 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 0, 0, 0, -678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 821, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 724 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 804, 0, 0, 0, 0, 0, 0, 0, 0, 0, -696, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -548, 0, 0, 0, 0, 0, 0, -548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 725 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -22, 0, 0, 0, 0, 0, 0, 0, 0, 0, -22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 726 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 806, 0, 0, 0, 0, 0, 0, 0, 0, 0, -693, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -199, -199, 0, -199, 0, -199, 0, -199, -199, 0, 0, -199, 0, -199, -199, 0, 0, -199, 0, -199, -199, 0, 0, -226, 0, 0, -199, -199, 0, -199, 0, -199, -199, -199, -199, 0, 0, -199, 0, 0, 0, 0, -199, 0, -199, 0, -199, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -199, 0, -199, -199, 0, 0, 0, -199, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 727 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -686, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 826, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 728 - -746, 0, 0, 0, 0, 0, -746, 0, -746, 0, 0, 0, -746, 0, 0, -746, 0, 0, 0, -746, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -746, 0, -746, -746, -746, -746, 0, 0, 0, 0, 0, -746, -746, -746, -746, 0, -746, -746, -746, -746, 0, 0, 0, 0, -746, -746, -746, -746, -746, 0, 0, -746, -746, -746, -746, 0, -746, -746, -746, -746, -746, -746, -746, -746, -746, 0, 0, 0, -746, 0, 0, 0, 0, -746, -746, -746, -746, -746, -746, + 0, 0, -187, -187, 0, -187, 0, -187, 0, -187, -187, 0, 0, -187, 0, -187, -187, 0, 0, -187, 0, -187, -187, 0, 0, -216, 0, 0, -187, -187, 0, -187, 0, -187, -187, -187, -187, 0, 0, -187, 0, 0, 0, 0, -187, 0, -187, 0, -187, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -187, 0, -187, -187, 0, 0, 0, -187, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 729 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -520, 0, 0, 0, 0, 0, 0, 0, 0, 0, -522, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -520, -520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -520, 0, 0, 0, 0, 0, 0, 0, -520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 730 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 829, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 731 - -368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 831, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 732 - -174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -204, -204, 0, -204, 0, -204, 0, -204, -204, 0, 0, -204, 0, -204, -204, 0, 0, -204, 0, -204, -204, 0, 0, -231, 0, 0, -204, -204, 0, -204, 0, -204, -204, -204, -204, 0, 0, -204, 0, 0, 0, 0, -204, 0, -204, 0, -204, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -204, 0, -204, -204, 0, 0, 0, -204, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 733 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, 0, -164, 0, -164, -164, -164, -164, -164, 0, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, -164, 0, 0, 0, -164, -164, -164, -164, -164, -164, 0, -164, 0, 0, 0, 0, 0, 0, 0, 0, -164, 0, 0, -164, -164, 0, -164, 0, -164, -164, 0, 0, 0, -164, -164, 0, 0, 0, 0, 0, 0, 0, 0, 0, -164, -164, -164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 734 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 235, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -119, -119, -119, -119, 0, 0, -119, 0, 0, -119, 0, 0, 0, -119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -119, -119, -119, -119, 0, 0, 0, 0, 0, 0, 0, -119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -119, 0, 0, -119, 0, 0, 0, 0, 0, 0, 0, 0, 0, -119, 0, 0, 0, -119, 0, 0, -119, 0, 0, 0, -119, -119, 0, -119, 0, -119, -119, // State 735 - -271, 0, 0, 0, 0, 0, -271, 0, -271, 0, 0, 0, -271, 0, 0, -271, 0, 0, 0, -271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -271, 0, -271, -271, -271, -271, 0, 0, 0, 0, 0, -271, -271, -271, -271, 0, -271, -271, -271, -271, 0, 0, 0, 0, -271, -271, -271, -271, -271, 0, 0, -271, -271, -271, -271, 0, -271, -271, -271, -271, -271, -271, -271, -271, -271, 0, 0, 0, -271, -271, 0, 0, 0, -271, -271, -271, -271, -271, -271, + 0, 0, 0, 0, 0, 0, 0, 0, -425, 0, 0, 0, 0, 0, 0, -425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 736 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -898, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -898, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 737 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 738 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 739 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, 0, 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 740 - 0, 0, 0, 0, 0, 0, 0, -882, 0, 0, 0, 0, 0, 0, -882, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, -882, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -801, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -801, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 741 - 0, 0, 0, 0, 0, 0, 0, -624, 0, 0, 0, 0, 0, 0, 821, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -864, -864, 0, 0, -864, 0, -864, 0, -864, 0, 0, -864, -864, 0, -864, -864, 0, -864, 0, 0, 0, 0, 0, -864, -864, -864, 0, -864, 0, 0, -864, 0, -864, 0, 0, 0, 0, -864, 0, 0, -864, 0, 0, 0, 0, -864, 0, -864, 0, -864, 0, -864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -864, -864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -864, -864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 742 - 0, 0, 0, 0, 0, 0, 0, -598, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 743 - 0, 0, 0, 0, 0, 0, 0, -517, 0, 0, 0, 0, 0, 0, -517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -66, 0, 0, 0, 0, 0, 0, -66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 744 - 0, 0, 0, 0, 0, 0, 0, 822, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, 0, -194, 0, -194, -194, -194, -194, -194, 0, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, 0, 0, 0, -194, -194, -194, -194, -194, -194, 0, -194, 0, 0, 0, 0, 0, 0, 0, 0, -194, 0, 0, -194, -194, 0, -194, 0, -194, -194, 0, 0, 0, -194, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, -194, -194, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 745 - 0, 0, 0, 0, 0, 0, 0, -537, 0, 0, 0, 0, 0, 0, -537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 833, 0, 0, 0, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 746 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -722, 0, 0, 0, 0, 0, 0, -722, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, 0, -195, 0, -195, -195, -195, -195, -195, 0, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, 0, 0, 0, -195, -195, -195, -195, -195, -195, 0, -195, 0, 0, 0, 0, 0, 0, 0, 0, -195, 0, 0, -195, -195, 0, -195, 0, -195, -195, 0, 0, 0, -195, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, -195, -195, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 747 - -502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -704, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 748 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, -698, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 749 - -510, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, -703, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 750 - -436, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -436, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -467, -467, 0, 0, -467, 0, -467, 0, -467, 0, 0, -467, -467, 0, -467, -467, 0, -467, 0, 0, 0, 0, 0, -467, -467, -467, 0, -467, 0, 0, -467, 0, -467, 0, 0, 0, 0, -467, 0, 0, -467, 0, 0, 0, 0, -467, 0, -467, 0, -467, 0, -467, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -467, -467, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -467, -467, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 751 - -422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 838, 0, 0, 0, 0, 0, 0, 0, 0, 0, -721, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 752 - -425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -24, 0, 0, 0, 0, 0, 0, 0, 0, 0, -24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 753 - -74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -74, 0, 0, 0, -74, 0, 0, 0, 0, 0, 0, 0, -74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 840, 0, 0, 0, 0, 0, 0, 0, 0, 0, -718, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 754 - -504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -711, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 755 - -505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 841, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 756 - -508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -390, 0, 0, -390, 0, 0, -390, 0, 0, 0, 0, 0, 0, -390, 0, 0, 0, 0, // State 757 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -868, 0, 0, 0, 0, 0, 0, 0, 0, 0, -868, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -391, 0, 0, -391, 0, 0, -391, 0, 0, 0, 0, 0, 0, -391, 0, 0, 0, 0, // State 758 - 831, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -369, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -369, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 759 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -376, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 760 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -869, 0, 0, 0, 0, 0, 0, 0, 0, 0, -869, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 761 - 832, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -388, 0, 0, -388, 0, 0, -388, 0, 0, 0, 0, 0, 0, -388, 0, 0, 0, 0, // State 762 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 251, 0, 0, 0, 0, 0, 0, 0, 0, + -771, 0, 0, 0, 0, 0, 0, -771, 0, -771, 0, 0, 0, -771, 0, 0, -771, 0, 0, 0, -771, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -771, 0, -771, -771, -771, -771, 0, 0, 0, 0, 0, -771, -771, -771, -771, 0, -771, -771, -771, -771, 0, 0, 0, 0, -771, -771, -771, -771, -771, 0, 0, -771, -771, -771, -771, 0, -771, -771, -771, -771, -771, -771, -771, -771, -771, 0, 0, 0, -771, 0, 0, -771, 0, 0, 0, -771, -771, 0, -771, -771, -771, -771, // State 763 - -751, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -751, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 764 - 833, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 834, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 765 - -825, 0, 0, 0, 0, 0, -825, 0, -825, 0, 0, 0, -825, 0, 0, -825, 0, 0, 0, -825, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -825, 0, -825, -825, -825, -825, 0, 0, 0, 0, 0, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, -825, 0, 0, -825, -825, -825, -825, 0, -825, -825, -825, -825, -825, -825, -825, -825, -825, 0, 0, 0, -825, -825, 0, 0, 0, -825, -825, -825, -825, -825, -825, + -367, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -367, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 766 - 835, 0, 0, 0, 0, 0, -132, 0, -132, 0, 0, 0, -132, 0, 0, -132, 0, 0, 0, -132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -132, -132, -132, -132, 0, 0, 0, 0, 0, -132, 0, -132, -132, 0, 0, -132, 0, -132, 0, 0, 0, 0, 0, -132, -132, 0, -132, 0, 0, -132, 0, -132, -132, 0, -132, -132, -132, 0, -132, 0, 0, -132, -132, 0, 0, 0, -132, 0, 0, 0, 0, -132, -132, -132, -132, -132, -132, + -173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 767 - -349, 0, 0, 0, 0, 0, -349, 0, -349, 0, 0, 0, -349, 0, 0, -349, 0, 0, 0, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -349, 0, -349, -349, -349, -349, 0, 0, 0, 0, 0, -349, -349, -349, -349, 0, -349, -349, -349, -349, 0, -349, -349, -349, -349, -349, -349, -349, -349, 0, 0, -349, -349, -349, -349, 0, -349, -349, -349, -349, -349, -349, -349, -349, -349, 0, 0, 0, -349, -349, 0, 0, 0, -349, -349, -349, -349, -349, -349, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 0, 0, 0, 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 768 - -353, 0, 0, 0, 0, 0, -353, 0, -353, 0, 0, 0, -353, 0, 0, -353, 0, 0, 0, -353, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -353, 0, -353, -353, -353, -353, 0, 0, 0, 0, 0, -353, -353, -353, -353, 0, -353, -353, -353, -353, 0, -353, -353, -353, -353, -353, -353, -353, -353, 0, 0, -353, -353, -353, -353, 0, -353, -353, -353, -353, -353, -353, -353, -353, -353, 0, 0, 0, -353, -353, 0, 0, 0, -353, -353, -353, -353, -353, -353, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 769 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -270, 0, 0, 0, 0, 0, 0, -270, 0, -270, 0, 0, 0, -270, 0, 0, -270, 0, 0, 0, -270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -270, 0, -270, -270, -270, -270, 0, 0, 0, 0, 0, -270, -270, -270, -270, 0, -270, -270, -270, -270, 0, 0, 0, 0, -270, -270, -270, -270, -270, 0, 0, -270, -270, -270, -270, 0, -270, -270, -270, -270, -270, -270, -270, -270, -270, 0, 0, 0, -270, -270, 0, -270, 0, 0, 0, -270, -270, 0, -270, -270, -270, -270, // State 770 - -872, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -872, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -906, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -906, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 771 - -889, 0, 0, 0, 0, 0, -889, 0, -889, 0, 0, 0, -889, 0, 0, -889, 0, 0, 0, -889, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -889, 0, -889, -889, -889, -889, 0, 0, 0, 0, 0, -889, -889, -889, -889, 0, -889, -889, -889, -889, 0, 847, 0, 0, -889, -889, -889, -889, -889, 0, 0, -889, -889, -889, -889, 0, -889, -889, -889, -889, -889, -889, -889, -889, -889, 0, 0, 0, -889, -889, 0, 0, 0, -889, -889, -889, -889, -889, -889, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 854, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 772 - 0, -243, -243, 0, -243, 0, -243, 0, -243, -243, 0, 0, -243, 0, -243, -243, 0, 0, -243, 0, -243, -243, 0, 0, -247, 0, 0, -243, -243, 0, -243, 0, -243, -243, -243, -243, 0, 0, -243, 0, 0, 0, 0, -243, 0, -243, 0, -243, -243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -243, 0, -243, -243, 0, 0, 0, -243, -243, 0, 0, 0, 0, 0, 0, 0, 0, 0, -243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 773 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 848, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 251, 0, 0, 0, 0, 0, 0, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 774 - 0, -739, -739, 0, -739, 0, 0, 0, -739, 0, 0, 0, -739, 0, -739, -739, 0, 0, 0, 0, -739, -739, 0, 0, -741, 0, 0, -739, -739, 0, -739, 0, -739, -739, -739, -739, 0, 0, -739, 0, 0, 0, 0, 0, 0, -739, 0, -739, -739, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -739, 0, -739, -739, 0, 0, 0, -739, -739, 0, 0, 0, 0, 0, 0, 0, 0, 0, -739, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -914, 0, 0, 0, 0, 0, 0, -914, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 0, 0, 0, 0, 0, 0, -914, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 775 - 0, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, -357, 0, 0, -355, 0, 0, -355, 0, -355, -355, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, -355, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -355, 0, -355, -355, 0, 0, 0, -355, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, -355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -649, 0, 0, 0, 0, 0, 0, 859, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 776 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -623, 0, 0, 0, 0, 0, 0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 777 - 0, -828, -828, 0, -828, 0, 0, 0, -828, 0, 0, 0, -828, 0, -828, -828, 0, 0, 0, 0, -828, -828, 0, 0, -830, 0, 0, -828, -828, 0, -828, 0, -828, -828, -828, -828, 0, 0, -828, 0, 0, 0, 0, 0, 0, -828, 0, -828, -828, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -828, 0, -828, -828, 0, 0, 0, -828, -828, 0, 0, 0, 0, 0, 0, 0, 0, 0, -828, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -542, 0, 0, 0, 0, 0, 0, -542, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 778 - 0, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 860, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 779 - 0, 0, 0, 0, 0, 0, 0, -68, 0, 0, 0, 0, 0, 0, -68, 0, 0, 0, 0, 0, 0, 0, 0, 0, -68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -562, 0, 0, 0, 0, 0, 0, -562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 780 - 0, 0, 0, 0, 0, 0, 0, -891, 0, 0, 0, 0, 0, 0, -891, 0, 0, 0, 0, 0, 0, 0, 0, 0, -891, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -747, 0, 0, 0, 0, 0, 0, -747, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 781 - -909, 0, 0, 0, 0, 0, -909, 0, -909, 0, 0, 0, -909, 0, 0, -909, 0, 0, 0, -909, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -909, 0, -909, -909, -909, -909, 0, 0, 0, 0, 0, -909, -909, -909, -909, 0, -909, -909, -909, -909, 0, 0, 0, 0, -909, -909, -909, -909, -909, 0, 0, -909, -909, -909, -909, 0, -909, -909, -909, -909, -909, -909, -909, -909, -909, 0, 0, 0, -909, -909, 0, 0, 0, -909, -909, -909, -909, -909, -909, + -527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 782 - 0, -910, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, -910, 0, 0, 0, 0, 0, 0, 0, 0, 0, -912, 0, 0, -910, 0, 0, -910, 0, -910, -910, -910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -910, 0, -910, -910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -910, 0, -910, -910, 0, 0, 0, -910, -910, 0, 0, 0, 0, 0, 0, 0, 0, 0, -910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 783 - 0, 0, 0, 0, 0, 0, 0, 850, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -535, 0, 0, 0, 0, 0, 0, 0, -535, 0, 0, 0, 0, 0, 0, -535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 784 - 0, 0, 0, 0, 0, 0, 0, 851, 0, 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -459, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -459, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 785 - 0, -197, -197, 0, -197, 0, -197, 0, -197, -197, 0, 0, -197, 0, -197, -197, 0, 0, -197, 0, -197, -197, 0, 0, -224, 0, 0, -197, -197, 0, -197, 0, -197, -197, -197, -197, 0, 0, -197, 0, 0, 0, 0, -197, 0, -197, 0, -197, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -197, 0, -197, -197, 0, 0, 0, -197, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -445, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -445, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 786 - 0, -191, -191, 0, -191, 0, -191, 0, -191, -191, 0, 0, -191, 0, -191, -191, 0, 0, -191, 0, -191, -191, 0, 0, -896, 0, 0, -191, -191, 0, -191, 0, -191, -191, -191, -191, 0, 0, -191, 0, 0, 0, 0, -191, 0, -191, 0, -191, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -191, 0, -191, -191, 0, 0, 0, -191, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 787 - 0, 0, 0, 0, 0, 0, 0, 855, 0, 0, 0, 0, 0, 0, 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -76, 0, 0, 0, -76, 0, 0, 0, 0, 0, 0, 0, -76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 788 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -902, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 789 - 0, -201, -201, 0, -201, 0, -201, 0, -201, -201, 0, 0, -201, 0, -201, -201, 0, 0, -201, 0, -201, -201, 0, 0, -228, 0, 0, -201, -201, 0, -201, 0, -201, -201, -201, -201, 0, 0, -201, 0, 0, 0, 0, -201, 0, -201, 0, -201, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -201, 0, -201, -201, 0, 0, 0, -201, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 790 - 0, 0, 0, 0, 0, 0, 0, 857, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 791 - 0, -187, -187, 0, -187, 0, -187, 0, -187, -187, 0, 0, -187, 0, -187, -187, 0, 0, -187, 0, -187, -187, 0, 0, -216, 0, 0, -187, -187, 0, -187, 0, -187, -187, -187, -187, 0, 0, -187, 0, 0, 0, 0, -187, 0, -187, 0, -187, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -187, 0, -187, -187, 0, 0, 0, -187, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, -187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -900, 0, 0, 0, 0, 0, 0, 0, 0, 0, -900, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 792 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 858, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 869, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 793 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 859, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 794 - 0, -204, -204, 0, -204, 0, -204, 0, -204, -204, 0, 0, -204, 0, -204, -204, 0, 0, -204, 0, -204, -204, 0, 0, -231, 0, 0, -204, -204, 0, -204, 0, -204, -204, -204, -204, 0, 0, -204, 0, 0, 0, 0, -204, 0, -204, 0, -204, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -204, 0, -204, -204, 0, 0, 0, -204, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, -204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -901, 0, 0, 0, 0, 0, 0, 0, 0, 0, -901, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 795 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 860, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 870, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 796 - 0, -207, -207, 0, -207, 0, -207, 0, -207, -207, 0, 0, -207, 0, -207, -207, 0, 0, -207, 0, -207, -207, 0, 0, -234, 0, 0, -207, -207, 0, -207, 0, -207, -207, -207, -207, 0, 0, -207, 0, 0, 0, 0, -207, 0, -207, 0, -207, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -207, 0, -207, -207, 0, 0, 0, -207, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 264, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 797 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -811, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -811, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -776, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -776, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 798 - -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, 0, -198, 0, -198, -198, -198, -198, -198, 0, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, -198, 0, 0, 0, -198, -198, -198, -198, -198, -198, 0, -198, 0, 0, 0, 0, 0, 0, 0, 0, -198, 0, 0, -198, -198, 0, -198, 0, -198, -198, 0, 0, 0, -198, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, -198, -198, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 872, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 799 - -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, 0, -192, 0, -192, -192, -192, -192, -192, 0, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, -192, 0, 0, 0, -192, -192, -192, -192, -192, -192, 0, -192, 0, 0, 0, 0, 0, 0, 0, 0, -192, 0, 0, -192, -192, 0, -192, 0, -192, -192, 0, 0, 0, -192, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, -192, -192, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -857, 0, 0, 0, 0, 0, 0, -857, 0, -857, 0, 0, 0, -857, 0, 0, -857, 0, 0, 0, -857, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -857, 0, -857, -857, -857, -857, 0, 0, 0, 0, 0, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, -857, 0, 0, -857, -857, -857, -857, 0, -857, -857, -857, -857, -857, -857, -857, -857, -857, 0, 0, 0, -857, -857, 0, -857, 0, 0, 0, -857, -857, 0, -857, -857, -857, -857, // State 800 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 266, 0, 0, 0, 0, 0, 0, 0, 0, 0, -670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 873, 0, 0, 0, 0, 0, 0, -134, 0, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -134, -134, -134, -134, 0, 0, 0, 0, 0, -134, 0, -134, -134, 0, 0, -134, 0, -134, 0, 0, 0, 0, 0, -134, -134, 0, -134, 0, 0, -134, 0, -134, -134, 0, -134, -134, -134, 0, -134, 0, 0, -134, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, -134, 0, -134, -134, -134, -134, // State 801 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 865, 0, 0, 0, 0, 0, 0, 0, 0, 0, -655, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -348, 0, 0, 0, 0, 0, 0, -348, 0, -348, 0, 0, 0, -348, 0, 0, -348, 0, 0, 0, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -348, 0, -348, -348, -348, -348, 0, 0, 0, 0, 0, -348, -348, -348, -348, 0, -348, -348, -348, -348, 0, -348, -348, -348, -348, -348, -348, -348, -348, 0, 0, -348, -348, -348, -348, 0, -348, -348, -348, -348, -348, -348, -348, -348, -348, 0, 0, 0, -348, -348, 0, -348, 0, 0, 0, -348, -348, 0, -348, -348, -348, -348, // State 802 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 867, 0, 0, 0, 0, 0, 0, 0, 0, 0, -683, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -352, 0, 0, 0, 0, 0, 0, -352, 0, -352, 0, 0, 0, -352, 0, 0, -352, 0, 0, 0, -352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -352, 0, -352, -352, -352, -352, 0, 0, 0, 0, 0, -352, -352, -352, -352, 0, -352, -352, -352, -352, 0, -352, -352, -352, -352, -352, -352, -352, -352, 0, 0, -352, -352, -352, -352, 0, -352, -352, -352, -352, -352, -352, -352, -352, -352, 0, 0, 0, -352, -352, 0, -352, 0, 0, 0, -352, -352, 0, -352, -352, -352, -352, // State 803 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -688, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 804 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 869, 0, 0, 0, 0, 0, 0, 0, 0, 0, -695, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -904, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -904, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 805 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -685, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -921, 0, 0, 0, 0, 0, 0, -921, 0, -921, 0, 0, 0, -921, 0, 0, -921, 0, 0, 0, -921, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -921, 0, -921, -921, -921, -921, 0, 0, 0, 0, 0, -921, -921, -921, -921, 0, -921, -921, -921, -921, 0, 885, 0, 0, -921, -921, -921, -921, -921, 0, 0, -921, -921, -921, -921, 0, -921, -921, -921, -921, -921, -921, -921, -921, -921, 0, 0, 0, -921, -921, 0, -921, 0, 0, 0, -921, -921, 0, -921, -921, -921, -921, // State 806 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, 0, 0, 0, 0, 271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -242, -242, 0, -242, 0, -242, 0, -242, -242, 0, 0, -242, 0, -242, -242, 0, 0, -242, 0, -242, -242, 0, 0, -246, 0, 0, -242, -242, 0, -242, 0, -242, -242, -242, -242, 0, 0, -242, 0, 0, 0, 0, -242, 0, -242, 0, -242, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -242, 0, -242, -242, 0, 0, 0, -242, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 807 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 886, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 808 - -273, 0, 0, 0, 0, 0, -273, 0, -273, 0, 0, 0, -273, 0, 0, -273, 0, 0, 0, -273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -273, 0, -273, -273, -273, -273, 0, 0, 0, 0, 0, -273, -273, -273, -273, 0, -273, -273, -273, -273, 0, 0, 0, 0, -273, -273, -273, -273, -273, 0, 0, -273, -273, -273, -273, 0, -273, -273, -273, -273, -273, -273, -273, -273, -273, 0, 0, 0, -273, -273, 0, 0, 0, -273, -273, -273, -273, -273, -273, + 0, 0, -764, -764, 0, -764, 0, 0, 0, -764, 0, 0, 0, -764, 0, -764, -764, 0, 0, 0, 0, -764, -764, 0, 0, -766, 0, 0, -764, -764, 0, -764, 0, -764, -764, -764, -764, 0, 0, -764, 0, 0, 0, 0, 0, 0, -764, 0, -764, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -764, 0, -764, -764, 0, 0, 0, -764, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, -764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 809 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 273, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -354, 0, 0, 0, 0, 0, 0, 0, 0, 0, -356, 0, 0, -354, 0, 0, -354, 0, -354, -354, -354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, -354, -354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -354, 0, -354, -354, 0, 0, 0, -354, -354, 0, 0, 0, 0, 0, 0, 0, 0, 0, -354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 810 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 0, 0, 0, 0, 0, 0, 276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 811 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -860, -860, 0, -860, 0, 0, 0, -860, 0, 0, 0, -860, 0, -860, -860, 0, 0, 0, 0, -860, -860, 0, 0, -862, 0, 0, -860, -860, 0, -860, 0, -860, -860, -860, -860, 0, 0, -860, 0, 0, 0, 0, 0, 0, -860, 0, -860, -860, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -860, 0, -860, -860, 0, 0, 0, -860, -860, 0, 0, 0, 0, 0, 0, 0, 0, 0, -860, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 812 - -908, 0, 0, 0, 0, 0, -908, 0, -908, 0, 0, 0, -908, 0, 0, -908, 0, 0, 0, -908, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -908, 0, -908, -908, -908, -908, 0, 0, 0, 0, 0, -908, -908, -908, -908, 0, -908, -908, -908, -908, 0, 0, 0, 0, -908, -908, -908, -908, -908, 0, 0, -908, -908, -908, -908, 0, -908, -908, -908, -908, -908, -908, -908, -908, -908, 0, 0, 0, -908, -908, 0, 0, 0, -908, -908, -908, -908, -908, -908, + 0, 0, 0, 0, 0, 0, 0, 0, -926, 0, 0, 0, 0, 0, 0, -926, 0, 0, 0, 0, 0, 0, 0, 0, 0, -926, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 813 - -267, 0, 0, 0, 0, 0, -267, 0, -267, 0, 0, 0, -267, 0, 0, -267, 0, 0, 0, -267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -267, 0, -267, -267, -267, -267, 0, 0, 0, 0, 0, -267, -267, -267, -267, 0, -267, -267, -267, -267, 0, 0, 0, 0, -267, -267, -267, -267, -267, 0, 0, -267, -267, -267, -267, 0, -267, -267, -267, -267, -267, -267, -267, -267, -267, 0, 0, 0, -267, -267, 0, 0, 0, -267, -267, -267, -267, -267, -267, + 0, 0, 0, 0, 0, 0, 0, 0, -70, 0, 0, 0, 0, 0, 0, -70, 0, 0, 0, 0, 0, 0, 0, 0, 0, -70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 814 - -270, 0, 0, 0, 0, 0, -270, 0, -270, 0, 0, 0, -270, 0, 0, -270, 0, 0, 0, -270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -270, 0, -270, -270, -270, -270, 0, 0, 0, 0, 0, -270, -270, -270, -270, 0, -270, -270, -270, -270, 0, 0, 0, 0, -270, -270, -270, -270, -270, 0, 0, -270, -270, -270, -270, 0, -270, -270, -270, -270, -270, -270, -270, -270, -270, 0, 0, 0, -270, -270, 0, 0, 0, -270, -270, -270, -270, -270, -270, + 0, 0, 0, 0, 0, 0, 0, 0, -923, 0, 0, 0, 0, 0, 0, -923, 0, 0, 0, 0, 0, 0, 0, 0, 0, -923, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 815 - 0, 0, 0, 0, 0, 0, -878, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -878, 0, 0, 0, 0, 0, 0, -878, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -941, 0, 0, 0, 0, 0, 0, -941, 0, -941, 0, 0, 0, -941, 0, 0, -941, 0, 0, 0, -941, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -941, 0, -941, -941, -941, -941, 0, 0, 0, 0, 0, -941, -941, -941, -941, 0, -941, -941, -941, -941, 0, 0, 0, 0, -941, -941, -941, -941, -941, 0, 0, -941, -941, -941, -941, 0, -941, -941, -941, -941, -941, -941, -941, -941, -941, 0, 0, 0, -941, -941, 0, -941, 0, 0, 0, -941, -941, 0, -941, -941, -941, -941, // State 816 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -942, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, -942, 0, 0, 0, 0, 0, 0, 0, 0, 0, -944, 0, 0, -942, 0, 0, -942, 0, -942, -942, -942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -942, 0, -942, -942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -942, 0, -942, -942, 0, 0, 0, -942, -942, 0, 0, 0, 0, 0, 0, 0, 0, 0, -942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 817 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -876, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -876, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 888, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 818 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 889, 0, 0, 0, 0, 0, 0, 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 819 - -397, 0, 0, 0, 0, 0, -397, 0, -397, 0, 0, 0, -397, 0, 0, -397, 0, 0, 0, -397, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -397, 0, -397, -397, -397, -397, 0, 0, 0, 0, 0, -397, -397, -397, -397, 0, -397, -397, -397, -397, 0, 0, 0, 0, -397, -397, -397, -397, -397, 0, 0, -397, -397, -397, -397, 0, -397, -397, -397, -397, -397, -397, -397, -397, -397, 0, 0, 0, -397, -397, 0, 0, 0, -397, -397, -397, -397, -397, -397, + 0, 0, -196, -196, 0, -196, 0, -196, 0, -196, -196, 0, 0, -196, 0, -196, -196, 0, 0, -196, 0, -196, -196, 0, 0, -223, 0, 0, -196, -196, 0, -196, 0, -196, -196, -196, -196, 0, 0, -196, 0, 0, 0, 0, -196, 0, -196, 0, -196, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -196, 0, -196, -196, 0, 0, 0, -196, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 820 - 0, 0, 0, 0, 0, 0, 0, -623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -190, -190, 0, -190, 0, -190, 0, -190, -190, 0, 0, -190, 0, -190, -190, 0, 0, -190, 0, -190, -190, 0, 0, -928, 0, 0, -190, -190, 0, -190, 0, -190, -190, -190, -190, 0, 0, -190, 0, 0, 0, 0, -190, 0, -190, 0, -190, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -190, 0, -190, -190, 0, 0, 0, -190, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 821 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -721, 0, 0, 0, 0, 0, 0, -721, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 893, 0, 0, 0, 0, 0, 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 822 - 0, 0, 0, 0, 0, 0, 0, -622, 0, 0, 0, 0, 0, 0, 281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -934, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 823 - 0, 0, 0, 0, 0, 0, 0, -794, 0, 0, 0, 0, 0, 0, -794, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -200, -200, 0, -200, 0, -200, 0, -200, -200, 0, 0, -200, 0, -200, -200, 0, 0, -200, 0, -200, -200, 0, 0, -227, 0, 0, -200, -200, 0, -200, 0, -200, -200, -200, -200, 0, 0, -200, 0, 0, 0, 0, -200, 0, -200, 0, -200, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -200, 0, -200, -200, 0, 0, 0, -200, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, -200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 824 - 0, 0, 0, 0, 0, 0, 0, -440, 0, 0, 0, 0, 0, 0, -440, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 895, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 825 - 0, 0, 0, 0, 0, 0, 0, -343, 0, 0, 0, 0, 0, 0, -343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 284, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -186, -186, 0, -186, 0, -186, 0, -186, -186, 0, 0, -186, 0, -186, -186, 0, 0, -186, 0, -186, -186, 0, 0, -215, 0, 0, -186, -186, 0, -186, 0, -186, -186, -186, -186, 0, 0, -186, 0, 0, 0, 0, -186, 0, -186, 0, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -186, 0, -186, -186, 0, 0, 0, -186, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, -186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 826 - 0, 0, 0, 0, 0, 0, 0, 893, 0, 0, 0, 0, 0, 0, 285, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 896, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 827 - -75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -75, 0, 0, 0, -75, 0, 0, 0, 0, 0, 0, 0, -75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 897, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 828 - -417, 0, 0, 0, 0, 0, -417, 0, -417, 0, 0, 0, -417, 0, 0, -417, 0, 0, 0, -417, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -417, 0, -417, -417, -417, -417, 0, 0, 0, 0, 0, -417, -417, -417, -417, 0, -417, -417, -417, -417, 286, 894, 0, 0, -417, -417, -417, -417, -417, 0, 0, -417, -417, -417, -417, 0, -417, -417, -417, -417, -417, -417, -417, -417, -417, 0, 0, 0, -417, -417, 0, 0, 0, -417, -417, -417, -417, -417, -417, + 0, 0, -203, -203, 0, -203, 0, -203, 0, -203, -203, 0, 0, -203, 0, -203, -203, 0, 0, -203, 0, -203, -203, 0, 0, -230, 0, 0, -203, -203, 0, -203, 0, -203, -203, -203, -203, 0, 0, -203, 0, 0, 0, 0, -203, 0, -203, 0, -203, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -203, 0, -203, -203, 0, 0, 0, -203, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 829 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 287, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 898, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 830 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 288, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -206, -206, 0, -206, 0, -206, 0, -206, -206, 0, 0, -206, 0, -206, -206, 0, 0, -206, 0, -206, -206, 0, 0, -233, 0, 0, -206, -206, 0, -206, 0, -206, -206, -206, -206, 0, 0, -206, 0, 0, 0, 0, -206, 0, -206, 0, -206, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -206, 0, -206, -206, 0, 0, 0, -206, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 831 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -843, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -843, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 832 - -826, 0, 0, 0, 0, 0, -826, 0, -826, 0, 0, 0, -826, 0, 0, -826, 0, 0, 0, -826, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -826, 0, -826, -826, -826, -826, 0, 0, 0, 0, 0, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, -826, 0, 0, -826, -826, -826, -826, 0, -826, -826, -826, -826, -826, -826, -826, -826, -826, 0, 0, 0, -826, -826, 0, 0, 0, -826, -826, -826, -826, -826, -826, + -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, 0, -197, 0, -197, -197, -197, -197, -197, 0, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, -197, 0, 0, 0, -197, -197, -197, -197, -197, -197, 0, -197, 0, 0, 0, 0, 0, 0, 0, 0, -197, 0, 0, -197, -197, 0, -197, 0, -197, -197, 0, 0, 0, -197, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, -197, -197, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 833 - 898, 0, 0, 0, 0, 0, -133, 0, -133, 0, 0, 0, -133, 0, 0, -133, 0, 0, 0, -133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -133, -133, -133, -133, 0, 0, 0, 0, 0, -133, 0, -133, -133, 0, 0, -133, 0, -133, 0, 0, 0, 0, 0, -133, -133, 0, -133, 0, 0, -133, 0, -133, -133, 0, -133, -133, -133, 0, -133, 0, 0, -133, -133, 0, 0, 0, -133, 0, 0, 0, 0, -133, -133, -133, -133, -133, -133, + -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, 0, -191, 0, -191, -191, -191, -191, -191, 0, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, -191, 0, 0, 0, -191, -191, -191, -191, -191, -191, 0, -191, 0, 0, 0, 0, 0, 0, 0, 0, -191, 0, 0, -191, -191, 0, -191, 0, -191, -191, 0, 0, 0, -191, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, -191, -191, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 834 - -823, 0, 0, 0, 0, 0, -823, 0, -823, 0, 0, 0, -823, 0, 0, -823, 0, 0, 0, -823, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -823, 0, -823, -823, -823, -823, 0, 0, 0, 0, 0, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, -823, 0, 0, -823, -823, -823, -823, 0, -823, -823, -823, -823, -823, -823, -823, -823, -823, 0, 0, 0, -823, -823, 0, 0, 0, -823, -823, -823, -823, -823, -823, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, 0, 0, 0, 0, 0, 0, 0, 0, 0, -695, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 835 - -350, 0, 0, 0, 0, 0, -350, 0, -350, 0, 0, 0, -350, 0, 0, -350, 0, 0, 0, -350, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -350, 0, -350, -350, -350, -350, 0, 0, 0, 0, 0, -350, -350, -350, -350, 0, -350, -350, -350, -350, 0, -350, -350, -350, -350, -350, -350, -350, -350, 0, 0, -350, -350, -350, -350, 0, -350, -350, -350, -350, -350, -350, -350, -350, -350, 0, 0, 0, -350, -350, 0, 0, 0, -350, -350, -350, -350, -350, -350, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 903, 0, 0, 0, 0, 0, 0, 0, 0, 0, -680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 836 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 905, 0, 0, 0, 0, 0, 0, 0, 0, 0, -708, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 837 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -713, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 838 - -354, 0, 0, 0, 0, 0, -354, 0, -354, 0, 0, 0, -354, 0, 0, -354, 0, 0, 0, -354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -354, 0, -354, -354, -354, -354, 0, 0, 0, 0, 0, -354, -354, -354, -354, 0, -354, -354, -354, -354, 0, -354, -354, -354, -354, -354, -354, -354, -354, 0, 0, -354, -354, -354, -354, 0, -354, -354, -354, -354, -354, -354, -354, -354, -354, 0, 0, 0, -354, -354, 0, 0, 0, -354, -354, -354, -354, -354, -354, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 907, 0, 0, 0, 0, 0, 0, 0, 0, 0, -720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 839 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 295, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -710, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 840 - 0, 0, 0, 0, 0, 0, 0, 0, 253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -389, 0, 0, -389, 0, 0, -389, 0, 0, 0, 0, 0, 0, -389, 0, 0, 0, 0, // State 841 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 908, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 842 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 298, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -386, 0, 0, -386, 0, 0, -386, 0, 0, 0, 0, 0, 0, -386, 0, 0, 0, 0, // State 843 - 0, 0, 0, 0, 0, 0, -804, 0, -804, 0, 0, 0, -804, 0, 0, -804, 0, 0, 0, -804, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -804, 0, -804, -804, -804, -804, 0, 0, 0, 0, 0, -804, -804, -804, -804, 0, -804, -804, -804, -804, 0, 0, 0, 0, -804, -804, -804, -804, -804, 0, 0, -804, -804, -804, -804, 0, -804, -804, -804, -804, -804, -804, -804, -804, -804, 0, 0, 0, -804, -804, 0, 0, 0, -804, -804, -804, -804, -804, -804, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -387, 0, 0, -387, 0, 0, -387, 0, 0, 0, 0, 0, 0, -387, 0, 0, 0, 0, // State 844 - 903, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 904, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 283, 0, 0, 0, 0, 0, 0, 284, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 845 - -871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 285, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 846 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -272, 0, 0, 0, 0, 0, 0, -272, 0, -272, 0, 0, 0, -272, 0, 0, -272, 0, 0, 0, -272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -272, 0, -272, -272, -272, -272, 0, 0, 0, 0, 0, -272, -272, -272, -272, 0, -272, -272, -272, -272, 0, 0, 0, 0, -272, -272, -272, -272, -272, 0, 0, -272, -272, -272, -272, 0, -272, -272, -272, -272, -272, -272, -272, -272, -272, 0, 0, 0, -272, -272, 0, -272, 0, 0, 0, -272, -272, 0, -272, -272, -272, -272, // State 847 - 0, -242, -242, 0, -242, 0, -242, 0, -242, -242, 0, 0, -242, 0, -242, -242, 0, 0, -242, 0, -242, -242, 0, 0, -246, 0, 0, -242, -242, 0, -242, 0, -242, -242, -242, -242, 0, 0, -242, 0, 0, 0, 0, -242, 0, -242, 0, -242, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -242, 0, -242, -242, 0, 0, 0, -242, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, -242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, 0, 0, 287, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 848 - 0, 0, 0, 0, 0, 0, 0, -69, 0, 0, 0, 0, 0, 0, -69, 0, 0, 0, 0, 0, 0, 0, 0, 0, -69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 288, 0, 0, 0, 0, 0, 0, 289, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 849 - 0, -202, -202, 0, -202, 0, -202, 0, -202, -202, 0, 0, -202, 0, -202, -202, 0, 0, -202, 0, -202, -202, 0, 0, -229, 0, 0, -202, -202, 0, -202, 0, -202, -202, -202, -202, 0, 0, -202, 0, 0, 0, 0, -202, 0, -202, 0, -202, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -202, 0, -202, -202, 0, 0, 0, -202, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 850 - 0, -199, -199, 0, -199, 0, -199, 0, -199, -199, 0, 0, -199, 0, -199, -199, 0, 0, -199, 0, -199, -199, 0, 0, -226, 0, 0, -199, -199, 0, -199, 0, -199, -199, -199, -199, 0, 0, -199, 0, 0, 0, 0, -199, 0, -199, 0, -199, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -199, 0, -199, -199, 0, 0, 0, -199, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, -199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -940, 0, 0, 0, 0, 0, 0, -940, 0, -940, 0, 0, 0, -940, 0, 0, -940, 0, 0, 0, -940, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -940, 0, -940, -940, -940, -940, 0, 0, 0, 0, 0, -940, -940, -940, -940, 0, -940, -940, -940, -940, 0, 0, 0, 0, -940, -940, -940, -940, -940, 0, 0, -940, -940, -940, -940, 0, -940, -940, -940, -940, -940, -940, -940, -940, -940, 0, 0, 0, -940, -940, 0, -940, 0, 0, 0, -940, -940, 0, -940, -940, -940, -940, // State 851 - 0, -193, -193, 0, -193, 0, -193, 0, -193, -193, 0, 0, -193, 0, -193, -193, 0, 0, -193, 0, -193, -193, 0, 0, -220, 0, 0, -193, -193, 0, -193, 0, -193, -193, -193, -193, 0, 0, -193, 0, 0, 0, 0, -193, 0, -193, 0, -193, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -193, 0, -193, -193, 0, 0, 0, -193, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -266, 0, 0, 0, 0, 0, 0, -266, 0, -266, 0, 0, 0, -266, 0, 0, -266, 0, 0, 0, -266, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -266, 0, -266, -266, -266, -266, 0, 0, 0, 0, 0, -266, -266, -266, -266, 0, -266, -266, -266, -266, 0, 0, 0, 0, -266, -266, -266, -266, -266, 0, 0, -266, -266, -266, -266, 0, -266, -266, -266, -266, -266, -266, -266, -266, -266, 0, 0, 0, -266, -266, 0, -266, 0, 0, 0, -266, -266, 0, -266, -266, -266, -266, // State 852 - 0, 0, 0, 0, 0, 0, 0, -524, 0, 0, 0, 0, 0, 0, -524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -269, 0, 0, 0, 0, 0, 0, -269, 0, -269, 0, 0, 0, -269, 0, 0, -269, 0, 0, 0, -269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -269, 0, -269, -269, -269, -269, 0, 0, 0, 0, 0, -269, -269, -269, -269, 0, -269, -269, -269, -269, 0, 0, 0, 0, -269, -269, -269, -269, -269, 0, 0, -269, -269, -269, -269, 0, -269, -269, -269, -269, -269, -269, -269, -269, -269, 0, 0, 0, -269, -269, 0, -269, 0, 0, 0, -269, -269, 0, -269, -269, -269, -269, // State 853 - 0, -190, -190, 0, -190, 0, -190, 0, -190, -190, 0, 0, -190, 0, -190, -190, 0, 0, -190, 0, -190, -190, 0, 0, -895, 0, 0, -190, -190, 0, -190, 0, -190, -190, -190, -190, 0, 0, -190, 0, 0, 0, 0, -190, 0, -190, 0, -190, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -190, 0, -190, -190, 0, 0, 0, -190, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, -190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -910, 0, 0, 0, 0, 0, 0, -910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 854 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -904, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -907, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -907, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 855 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -898, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -908, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -908, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 856 - 0, -203, -203, 0, -203, 0, -203, 0, -203, -203, 0, 0, -203, 0, -203, -203, 0, 0, -203, 0, -203, -203, 0, 0, -230, 0, 0, -203, -203, 0, -203, 0, -203, -203, -203, -203, 0, 0, -203, 0, 0, 0, 0, -203, 0, -203, 0, -203, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -203, 0, -203, -203, 0, 0, 0, -203, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, -203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 857 - 0, -189, -189, 0, -189, 0, -189, 0, -189, -189, 0, 0, -189, 0, -189, -189, 0, 0, -189, 0, -189, -189, 0, 0, -218, 0, 0, -189, -189, 0, -189, 0, -189, -189, -189, -189, 0, 0, -189, 0, 0, 0, 0, -189, 0, -189, 0, -189, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -189, 0, -189, -189, 0, 0, 0, -189, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -420, 0, 0, 0, 0, 0, 0, -420, 0, -420, 0, 0, 0, -420, 0, 0, -420, 0, 0, 0, -420, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -420, 0, -420, -420, -420, -420, 0, 0, 0, 0, 0, -420, -420, -420, -420, 0, -420, -420, -420, -420, 0, 0, 0, 0, -420, -420, -420, -420, -420, 0, 0, -420, -420, -420, -420, 0, -420, -420, -420, -420, -420, -420, -420, -420, -420, 0, 0, 0, -420, -420, 0, -420, 0, 0, 0, -420, -420, 0, -420, -420, -420, -420, // State 858 - 0, -206, -206, 0, -206, 0, -206, 0, -206, -206, 0, 0, -206, 0, -206, -206, 0, 0, -206, 0, -206, -206, 0, 0, -233, 0, 0, -206, -206, 0, -206, 0, -206, -206, -206, -206, 0, 0, -206, 0, 0, 0, 0, -206, 0, -206, 0, -206, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -206, 0, -206, -206, 0, 0, 0, -206, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, -206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -648, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 859 - 0, -208, -208, 0, -208, 0, -208, 0, -208, -208, 0, 0, -208, 0, -208, -208, 0, 0, -208, 0, -208, -208, 0, 0, -235, 0, 0, -208, -208, 0, -208, 0, -208, -208, -208, -208, 0, 0, -208, 0, 0, 0, 0, -208, 0, -208, 0, -208, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -208, 0, -208, -208, 0, 0, 0, -208, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, -208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -746, 0, 0, 0, 0, 0, 0, -746, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 860 - 0, 0, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -319, 0, 0, -319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -647, 0, 0, 0, 0, 0, 0, 294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 861 - -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, 0, -194, 0, -194, -194, -194, -194, -194, 0, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, -194, 0, 0, 0, -194, -194, -194, -194, -194, -194, 0, -194, 0, 0, 0, 0, 0, 0, 0, 0, -194, 0, 0, -194, -194, 0, -194, 0, -194, -194, 0, 0, 0, -194, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, -194, -194, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -819, 0, 0, 0, 0, 0, 0, -819, 0, 0, 0, 0, 0, 0, 0, 0, 0, 295, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 862 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 918, 0, 0, 0, 0, 0, 0, 0, 0, 0, -661, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -463, 0, 0, 0, 0, 0, 0, -463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 863 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 920, 0, 0, 0, 0, 0, 0, 0, 0, 0, -652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -342, 0, 0, 0, 0, 0, 0, -342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 864 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 932, 0, 0, 0, 0, 0, 0, 298, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 865 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 921, 0, 0, 0, 0, 0, 0, 0, 0, 0, -684, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -77, 0, 0, 0, -77, 0, 0, 0, 0, 0, 0, 0, -77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 866 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -440, 0, 0, 0, 0, 0, 0, -440, 0, -440, 0, 0, 0, -440, 0, 0, -440, 0, 0, 0, -440, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -440, 0, -440, -440, -440, -440, 0, 0, 0, 0, 0, -440, -440, -440, -440, 0, -440, -440, -440, -440, 299, 933, 0, 0, -440, -440, -440, -440, -440, 0, 0, -440, -440, -440, -440, 0, -440, -440, -440, -440, -440, -440, -440, -440, -440, 0, 0, 0, -440, -440, 0, -440, 0, 0, 0, -440, -440, 0, -440, -440, -440, -440, // State 867 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, -674, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 868 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -687, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 301, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 869 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 308, 0, 0, 0, 0, 0, 0, 309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 870 - -269, 0, 0, 0, 0, 0, -269, 0, -269, 0, 0, 0, -269, 0, 0, -269, 0, 0, 0, -269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -269, 0, -269, -269, -269, -269, 0, 0, 0, 0, 0, -269, -269, -269, -269, 0, -269, -269, -269, -269, 0, 0, 0, 0, -269, -269, -269, -269, -269, 0, 0, -269, -269, -269, -269, 0, -269, -269, -269, -269, -269, -269, -269, -269, -269, 0, 0, 0, -269, -269, 0, 0, 0, -269, -269, -269, -269, -269, -269, + -858, 0, 0, 0, 0, 0, 0, -858, 0, -858, 0, 0, 0, -858, 0, 0, -858, 0, 0, 0, -858, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -858, 0, -858, -858, -858, -858, 0, 0, 0, 0, 0, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, -858, 0, 0, -858, -858, -858, -858, 0, -858, -858, -858, -858, -858, -858, -858, -858, -858, 0, 0, 0, -858, -858, 0, -858, 0, 0, 0, -858, -858, 0, -858, -858, -858, -858, // State 871 - -272, 0, 0, 0, 0, 0, -272, 0, -272, 0, 0, 0, -272, 0, 0, -272, 0, 0, 0, -272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -272, 0, -272, -272, -272, -272, 0, 0, 0, 0, 0, -272, -272, -272, -272, 0, -272, -272, -272, -272, 0, 0, 0, 0, -272, -272, -272, -272, -272, 0, 0, -272, -272, -272, -272, 0, -272, -272, -272, -272, -272, -272, -272, -272, -272, 0, 0, 0, -272, -272, 0, 0, 0, -272, -272, -272, -272, -272, -272, + 937, 0, 0, 0, 0, 0, 0, -135, 0, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -135, -135, -135, -135, 0, 0, 0, 0, 0, -135, 0, -135, -135, 0, 0, -135, 0, -135, 0, 0, 0, 0, 0, -135, -135, 0, -135, 0, 0, -135, 0, -135, -135, 0, -135, -135, -135, 0, -135, 0, 0, -135, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, -135, 0, -135, -135, -135, -135, // State 872 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 310, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -855, 0, 0, 0, 0, 0, 0, -855, 0, -855, 0, 0, 0, -855, 0, 0, -855, 0, 0, 0, -855, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -855, 0, -855, -855, -855, -855, 0, 0, 0, 0, 0, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, 0, 0, -855, -855, -855, -855, 0, -855, -855, -855, -855, -855, -855, -855, -855, -855, 0, 0, 0, -855, -855, 0, -855, 0, 0, 0, -855, -855, 0, -855, -855, -855, -855, // State 873 - -399, 0, 0, 0, 0, 0, -399, 0, -399, 0, 0, 0, -399, 0, 0, -399, 0, 0, 0, -399, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -399, 0, -399, -399, -399, -399, 0, 0, 0, 0, 0, -399, -399, -399, -399, 0, -399, -399, -399, -399, 0, 0, 0, 0, -399, -399, -399, -399, -399, 0, 0, -399, -399, -399, -399, 0, -399, -399, -399, -399, -399, -399, -399, -399, -399, 0, 0, 0, -399, -399, 0, 0, 0, -399, -399, -399, -399, -399, -399, + -349, 0, 0, 0, 0, 0, 0, -349, 0, -349, 0, 0, 0, -349, 0, 0, -349, 0, 0, 0, -349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -349, 0, -349, -349, -349, -349, 0, 0, 0, 0, 0, -349, -349, -349, -349, 0, -349, -349, -349, -349, 0, -349, -349, -349, -349, -349, -349, -349, -349, 0, 0, -349, -349, -349, -349, 0, -349, -349, -349, -349, -349, -349, -349, -349, -349, 0, 0, 0, -349, -349, 0, -349, 0, 0, 0, -349, -349, 0, -349, -349, -349, -349, // State 874 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 311, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 875 - -389, 0, 0, 0, 0, 0, -389, 0, -389, 0, 0, 0, -389, 0, 0, -389, 0, 0, 0, -389, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -389, 0, -389, -389, -389, -389, 0, 0, 0, 0, 0, -389, -389, -389, -389, 0, -389, -389, -389, -389, 0, 0, 0, 0, -389, -389, -389, -389, -389, 0, 0, -389, -389, -389, -389, 0, -389, -389, -389, -389, -389, -389, -389, -389, -389, 0, 0, 0, -389, -389, 0, 0, 0, -389, -389, -389, -389, -389, -389, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 307, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 876 - -266, 0, 0, 0, 0, 0, -266, 0, -266, 0, 0, 0, -266, 0, 0, -266, 0, 0, 0, -266, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -266, 0, -266, -266, -266, -266, 0, 0, 0, 0, 0, -266, -266, -266, -266, 0, -266, -266, -266, -266, 0, 0, 0, 0, -266, -266, -266, -266, -266, 0, 0, -266, -266, -266, -266, 0, -266, -266, -266, -266, -266, -266, -266, -266, -266, 0, 0, 0, -266, -266, 0, 0, 0, -266, -266, -266, -266, -266, -266, + -353, 0, 0, 0, 0, 0, 0, -353, 0, -353, 0, 0, 0, -353, 0, 0, -353, 0, 0, 0, -353, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -353, 0, -353, -353, -353, -353, 0, 0, 0, 0, 0, -353, -353, -353, -353, 0, -353, -353, -353, -353, 0, -353, -353, -353, -353, -353, -353, -353, -353, 0, 0, -353, -353, -353, -353, 0, -353, -353, -353, -353, -353, -353, -353, -353, -353, 0, 0, 0, -353, -353, 0, -353, 0, 0, 0, -353, -353, 0, -353, -353, -353, -353, // State 877 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -873, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -873, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 308, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 878 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 266, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 879 - 0, 0, 0, 0, 0, 0, -877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -877, 0, 0, 0, 0, 0, 0, -877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 880 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 310, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 311, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 881 - -396, 0, 0, 0, 0, 0, -396, 0, -396, 0, 0, 0, -396, 0, 0, -396, 0, 0, 0, -396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -396, 0, -396, -396, -396, -396, 0, 0, 0, 0, 0, -396, -396, -396, -396, 0, -396, -396, -396, -396, 0, 0, 0, 0, -396, -396, -396, -396, -396, 0, 0, -396, -396, -396, -396, 0, -396, -396, -396, -396, -396, -396, -396, -396, -396, 0, 0, 0, -396, -396, 0, 0, 0, -396, -396, -396, -396, -396, -396, + 0, 0, 0, 0, 0, 0, 0, -829, 0, -829, 0, 0, 0, -829, 0, 0, -829, 0, 0, 0, -829, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -829, 0, -829, -829, -829, -829, 0, 0, 0, 0, 0, -829, -829, -829, -829, 0, -829, -829, -829, -829, 0, 0, 0, 0, -829, -829, -829, -829, -829, 0, 0, -829, -829, -829, -829, 0, -829, -829, -829, -829, -829, -829, -829, -829, -829, 0, 0, 0, -829, -829, 0, -829, 0, 0, 0, -829, -829, 0, -829, -829, -829, -829, // State 882 - 0, 0, 0, 0, 0, 0, 0, -881, 0, 0, 0, 0, 0, 0, -881, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -881, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 883 - 0, 0, 0, 0, 0, 0, 0, -604, 0, 0, 0, 0, 0, 0, 934, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -903, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -903, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 884 - 0, 0, 0, 0, 0, 0, 0, -518, 0, 0, 0, 0, 0, 0, -518, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 885 - 0, 0, 0, 0, 0, 0, 0, -538, 0, 0, 0, 0, 0, 0, -538, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -241, -241, 0, -241, 0, -241, 0, -241, -241, 0, 0, -241, 0, -241, -241, 0, 0, -241, 0, -241, -241, 0, 0, -245, 0, 0, -241, -241, 0, -241, 0, -241, -241, -241, -241, 0, 0, -241, 0, 0, 0, 0, -241, 0, -241, 0, -241, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -241, 0, -241, -241, 0, 0, 0, -241, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, -241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 886 - 0, 0, 0, 0, 0, 0, 0, -621, 0, 0, 0, 0, 0, 0, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -71, 0, 0, 0, 0, 0, 0, -71, 0, 0, 0, 0, 0, 0, 0, 0, 0, -71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 887 - 0, 0, 0, 0, 0, 0, 0, -616, 0, 0, 0, 0, 0, 0, 941, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -201, -201, 0, -201, 0, -201, 0, -201, -201, 0, 0, -201, 0, -201, -201, 0, 0, -201, 0, -201, -201, 0, 0, -228, 0, 0, -201, -201, 0, -201, 0, -201, -201, -201, -201, 0, 0, -201, 0, 0, 0, 0, -201, 0, -201, 0, -201, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -201, 0, -201, -201, 0, 0, 0, -201, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, -201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 888 - 0, 0, 0, 0, 0, 0, 0, -16, 0, 0, 0, 0, 0, 0, -16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -198, -198, 0, -198, 0, -198, 0, -198, -198, 0, 0, -198, 0, -198, -198, 0, 0, -198, 0, -198, -198, 0, 0, -225, 0, 0, -198, -198, 0, -198, 0, -198, -198, -198, -198, 0, 0, -198, 0, 0, 0, 0, -198, 0, -198, 0, -198, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -198, 0, -198, -198, 0, 0, 0, -198, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 889 - -383, 0, 0, 0, 0, 0, -383, 0, -383, 0, 0, 0, -383, 0, 0, -383, 0, 0, 0, -383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -383, 0, -383, -383, -383, -383, 0, 0, 0, 0, 0, -383, -383, -383, -383, 0, -383, -383, -383, -383, 0, 943, 0, 0, -383, -383, -383, -383, -383, 0, 0, -383, -383, -383, -383, 0, -383, -383, -383, -383, -383, -383, -383, -383, -383, 0, 0, 0, -383, -383, 0, 0, 0, -383, -383, -383, -383, -383, -383, + 0, 0, -192, -192, 0, -192, 0, -192, 0, -192, -192, 0, 0, -192, 0, -192, -192, 0, 0, -192, 0, -192, -192, 0, 0, -219, 0, 0, -192, -192, 0, -192, 0, -192, -192, -192, -192, 0, 0, -192, 0, 0, 0, 0, -192, 0, -192, 0, -192, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -192, 0, -192, -192, 0, 0, 0, -192, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 890 - -509, 0, 0, 0, 0, 0, 0, -509, 0, 0, 0, 0, 0, 0, -509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -549, 0, 0, 0, 0, 0, 0, -549, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 891 - -512, 0, 0, 0, 0, 0, 0, -512, 0, 0, 0, 0, 0, 0, -512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 317, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -189, -189, 0, -189, 0, -189, 0, -189, -189, 0, 0, -189, 0, -189, -189, 0, 0, -189, 0, -189, -189, 0, 0, -927, 0, 0, -189, -189, 0, -189, 0, -189, -189, -189, -189, 0, 0, -189, 0, 0, 0, 0, -189, 0, -189, 0, -189, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -189, 0, -189, -189, 0, 0, 0, -189, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, -189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 892 - -424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 893 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -930, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 894 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -202, -202, 0, -202, 0, -202, 0, -202, -202, 0, 0, -202, 0, -202, -202, 0, 0, -202, 0, -202, -202, 0, 0, -229, 0, 0, -202, -202, 0, -202, 0, -202, -202, -202, -202, 0, 0, -202, 0, 0, 0, 0, -202, 0, -202, 0, -202, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -202, 0, -202, -202, 0, 0, 0, -202, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, -202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 895 - -507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -188, -188, 0, -188, 0, -188, 0, -188, -188, 0, 0, -188, 0, -188, -188, 0, 0, -188, 0, -188, -188, 0, 0, -217, 0, 0, -188, -188, 0, -188, 0, -188, -188, -188, -188, 0, 0, -188, 0, 0, 0, 0, -188, 0, -188, 0, -188, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -188, 0, -188, -188, 0, 0, 0, -188, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, -188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 896 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -472, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -472, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -205, -205, 0, -205, 0, -205, 0, -205, -205, 0, 0, -205, 0, -205, -205, 0, 0, -205, 0, -205, -205, 0, 0, -232, 0, 0, -205, -205, 0, -205, 0, -205, -205, -205, -205, 0, 0, -205, 0, 0, 0, 0, -205, 0, -205, 0, -205, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -205, 0, -205, -205, 0, 0, 0, -205, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, -205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 897 - -824, 0, 0, 0, 0, 0, -824, 0, -824, 0, 0, 0, -824, 0, 0, -824, 0, 0, 0, -824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -824, 0, -824, -824, -824, -824, 0, 0, 0, 0, 0, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, -824, 0, 0, -824, -824, -824, -824, 0, -824, -824, -824, -824, -824, -824, -824, -824, -824, 0, 0, 0, -824, -824, 0, 0, 0, -824, -824, -824, -824, -824, -824, + 0, 0, -207, -207, 0, -207, 0, -207, 0, -207, -207, 0, 0, -207, 0, -207, -207, 0, 0, -207, 0, -207, -207, 0, 0, -234, 0, 0, -207, -207, 0, -207, 0, -207, -207, -207, -207, 0, 0, -207, 0, 0, 0, 0, -207, 0, -207, 0, -207, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -207, 0, -207, -207, 0, 0, 0, -207, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, -207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 898 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -318, 0, 0, 0, 0, 0, 0, -318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -318, 0, 0, 0, 0, 0, -318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -318, 0, 0, -318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 899 - -347, 0, 0, 0, 0, 0, -347, 0, -347, 0, 0, 0, -347, 0, 0, -347, 0, 0, 0, -347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -347, 0, -347, -347, -347, -347, 0, 0, 0, 0, 0, -347, -347, -347, -347, 0, -347, -347, -347, -347, 0, -347, -347, -347, -347, -347, -347, -347, -347, 0, 0, -347, -347, -347, -347, 0, -347, -347, -347, -347, -347, -347, -347, -347, -347, 0, 0, 0, -347, -347, 0, 0, 0, -347, -347, -347, -347, -347, -347, + -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, 0, -193, 0, -193, -193, -193, -193, -193, 0, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, -193, 0, 0, 0, -193, -193, -193, -193, -193, -193, 0, -193, 0, 0, 0, 0, 0, 0, 0, 0, -193, 0, 0, -193, -193, 0, -193, 0, -193, -193, 0, 0, 0, -193, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, -193, -193, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 900 - -861, 0, 0, 0, 0, 0, -861, 0, -861, 0, 0, 0, -861, 0, 0, -861, 0, 0, 0, -861, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -861, 0, -861, -861, -861, -861, 0, 0, 0, 0, 0, -861, -861, -861, -861, 0, -861, -861, -861, -861, 0, 0, 0, 0, -861, -861, -861, -861, -861, 0, 0, -861, -861, -861, -861, 0, -861, -861, -861, -861, -861, -861, -861, -861, -861, 0, 0, 0, -861, -861, 0, 0, 0, -861, -861, -861, -861, -861, -861, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 957, 0, 0, 0, 0, 0, 0, 0, 0, 0, -686, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 901 - 977, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 978, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 959, 0, 0, 0, 0, 0, 0, 0, 0, 0, -677, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 902 - 0, 0, 0, 0, 0, 0, -802, 0, -802, 0, 0, 0, -802, 0, 0, -802, 0, 0, 0, -802, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -802, 0, -802, -802, -802, -802, 0, 0, 0, 0, 0, -802, -802, -802, -802, 0, -802, -802, -802, -802, 0, 0, 0, 0, -802, -802, -802, -802, -802, 0, 0, -802, -802, -802, -802, 0, -802, -802, -802, -802, -802, -802, -802, -802, -802, 0, 0, 0, -802, -802, 0, 0, 0, -802, -802, -802, -802, -802, -802, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -653, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 903 - 979, 0, 0, 0, 0, 0, -132, 0, -132, 0, 0, 0, -132, 0, 0, -132, 0, 0, 0, -132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -132, -132, -132, -132, 0, 0, 0, 0, 0, -132, 0, -132, -132, 0, 0, -132, 0, -132, 0, 0, 0, 0, 0, -132, -132, 0, -132, 0, 0, -132, 0, -132, -132, 0, -132, -132, -132, 0, -132, 0, 0, -132, -132, 0, 0, 0, -132, 0, 0, 0, 0, -132, -132, -132, -132, -132, -132, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 960, 0, 0, 0, 0, 0, 0, 0, 0, 0, -709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 904 - 0, 0, 0, 0, 0, 0, -805, 0, -805, 0, 0, 0, -805, 0, 0, -805, 0, 0, 0, -805, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -805, 0, -805, -805, -805, -805, 0, 0, 0, 0, 0, -805, -805, -805, -805, 0, -805, -805, -805, -805, 0, 0, 0, 0, -805, -805, -805, -805, -805, 0, 0, -805, -805, -805, -805, 0, -805, -805, -805, -805, -805, -805, -805, -805, -805, 0, 0, 0, -805, -805, 0, 0, 0, -805, -805, -805, -805, -805, -805, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -705, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 905 - 981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 982, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, -699, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 906 - -827, 0, 0, 0, 0, 0, -827, 0, -827, 0, 0, 0, -827, 0, 0, -827, 0, 0, 0, -827, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -827, 0, -827, -827, -827, -827, 0, 0, 0, 0, 0, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, -827, 0, 0, -827, -827, -827, -827, 0, -827, -827, -827, -827, -827, -827, -827, -827, -827, 0, 0, 0, -827, -827, 0, 0, 0, -827, -827, -827, -827, -827, -827, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -712, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 907 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -832, 0, 0, 0, 0, 0, 0, 0, 0, 0, -837, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -832, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -385, 0, 0, -385, 0, 0, -385, 0, 0, 0, 0, 0, 0, -385, 0, 0, 0, 0, // State 908 - 0, -195, -195, 0, -195, 0, -195, 0, -195, -195, 0, 0, -195, 0, -195, -195, 0, 0, -195, 0, -195, -195, 0, 0, -222, 0, 0, -195, -195, 0, -195, 0, -195, -195, -195, -195, 0, 0, -195, 0, 0, 0, 0, -195, 0, -195, 0, -195, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -195, 0, -195, -195, 0, 0, 0, -195, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 0, 0, 0, 0, 0, 0, 322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 909 - 0, 0, 0, 0, 0, 0, 0, 984, 0, 0, 0, 0, 0, 0, 333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -268, 0, 0, 0, 0, 0, 0, -268, 0, -268, 0, 0, 0, -268, 0, 0, -268, 0, 0, 0, -268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -268, 0, -268, -268, -268, -268, 0, 0, 0, 0, 0, -268, -268, -268, -268, 0, -268, -268, -268, -268, 0, 0, 0, 0, -268, -268, -268, -268, -268, 0, 0, -268, -268, -268, -268, 0, -268, -268, -268, -268, -268, -268, -268, -268, -268, 0, 0, 0, -268, -268, 0, -268, 0, 0, 0, -268, -268, 0, -268, -268, -268, -268, // State 910 - 0, -196, -196, 0, -196, 0, -196, 0, -196, -196, 0, 0, -196, 0, -196, -196, 0, 0, -196, 0, -196, -196, 0, 0, -223, 0, 0, -196, -196, 0, -196, 0, -196, -196, -196, -196, 0, 0, -196, 0, 0, 0, 0, -196, 0, -196, 0, -196, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -196, 0, -196, -196, 0, 0, 0, -196, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, -196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -271, 0, 0, 0, 0, 0, 0, -271, 0, -271, 0, 0, 0, -271, 0, 0, -271, 0, 0, 0, -271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -271, 0, -271, -271, -271, -271, 0, 0, 0, 0, 0, -271, -271, -271, -271, 0, -271, -271, -271, -271, 0, 0, 0, 0, -271, -271, -271, -271, -271, 0, 0, -271, -271, -271, -271, 0, -271, -271, -271, -271, -271, -271, -271, -271, -271, 0, 0, 0, -271, -271, 0, -271, 0, 0, 0, -271, -271, 0, -271, -271, -271, -271, // State 911 - 0, 0, 0, 0, 0, 0, 0, 986, 0, 0, 0, 0, 0, 0, 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 323, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 912 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -901, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -422, 0, 0, 0, 0, 0, 0, -422, 0, -422, 0, 0, 0, -422, 0, 0, -422, 0, 0, 0, -422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -422, 0, -422, -422, -422, -422, 0, 0, 0, 0, 0, -422, -422, -422, -422, 0, -422, -422, -422, -422, 0, 0, 0, 0, -422, -422, -422, -422, -422, 0, 0, -422, -422, -422, -422, 0, -422, -422, -422, -422, -422, -422, -422, -422, -422, 0, 0, 0, -422, -422, 0, -422, 0, 0, 0, -422, -422, 0, -422, -422, -422, -422, // State 913 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -900, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 914 - 0, 0, 0, 0, 0, 0, 0, -320, 0, 0, 0, 0, 0, 0, -320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -320, 0, 0, 0, 0, 0, -320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -320, 0, 0, -320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -412, 0, 0, 0, 0, 0, 0, -412, 0, -412, 0, 0, 0, -412, 0, 0, -412, 0, 0, 0, -412, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -412, 0, -412, -412, -412, -412, 0, 0, 0, 0, 0, -412, -412, -412, -412, 0, -412, -412, -412, -412, 0, 0, 0, 0, -412, -412, -412, -412, -412, 0, 0, -412, -412, -412, -412, 0, -412, -412, -412, -412, -412, -412, -412, -412, -412, 0, 0, 0, -412, -412, 0, -412, 0, 0, 0, -412, -412, 0, -412, -412, -412, -412, // State 915 - 0, 0, 0, 0, 0, 0, 0, -316, 0, 0, 0, 0, 0, 0, -316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -316, 0, 0, 0, 0, 0, -316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -316, 0, 0, -316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -265, 0, 0, 0, 0, 0, 0, -265, 0, -265, 0, 0, 0, -265, 0, 0, -265, 0, 0, 0, -265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -265, 0, -265, -265, -265, -265, 0, 0, 0, 0, 0, -265, -265, -265, -265, 0, -265, -265, -265, -265, 0, 0, 0, 0, -265, -265, -265, -265, -265, 0, 0, -265, -265, -265, -265, 0, -265, -265, -265, -265, -265, -265, -265, -265, -265, 0, 0, 0, -265, -265, 0, -265, 0, 0, 0, -265, -265, 0, -265, -265, -265, -265, // State 916 - 0, 0, 0, 0, 0, 0, 0, -362, 0, 0, 0, 0, 0, 0, -362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -362, 0, 0, 0, 0, 0, -362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -362, 0, 0, -362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -905, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -905, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 917 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -634, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 918 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 988, 0, 0, 0, 0, 0, 0, 0, 0, 0, -658, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -909, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -909, 0, 0, 0, 0, 0, 0, -909, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 919 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -625, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 920 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -681, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -419, 0, 0, 0, 0, 0, 0, -419, 0, -419, 0, 0, 0, -419, 0, 0, -419, 0, 0, 0, -419, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -419, 0, -419, -419, -419, -419, 0, 0, 0, 0, 0, -419, -419, -419, -419, 0, -419, -419, -419, -419, 0, 0, 0, 0, -419, -419, -419, -419, -419, 0, 0, -419, -419, -419, -419, 0, -419, -419, -419, -419, -419, -419, -419, -419, -419, 0, 0, 0, -419, -419, 0, -419, 0, 0, 0, -419, -419, 0, -419, -419, -419, -419, // State 921 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 335, 0, 0, 0, 0, 0, 0, 0, 0, 0, -675, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -913, 0, 0, 0, 0, 0, 0, -913, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -913, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 922 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, -671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -629, 0, 0, 0, 0, 0, 0, 973, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 923 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 993, 0, 0, 0, 0, 0, 0, 0, 0, 0, -656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -543, 0, 0, 0, 0, 0, 0, -543, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 924 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -563, 0, 0, 0, 0, 0, 0, -563, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 925 - -391, 0, 0, 0, 0, 0, -391, 0, -391, 0, 0, 0, -391, 0, 0, -391, 0, 0, 0, -391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -391, 0, -391, -391, -391, -391, 0, 0, 0, 0, 0, -391, -391, -391, -391, 0, -391, -391, -391, -391, 0, 0, 0, 0, -391, -391, -391, -391, -391, 0, 0, -391, -391, -391, -391, 0, -391, -391, -391, -391, -391, -391, -391, -391, -391, 0, 0, 0, -391, -391, 0, 0, 0, -391, -391, -391, -391, -391, -391, + 0, 0, 0, 0, 0, 0, 0, 0, -646, 0, 0, 0, 0, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 926 - -268, 0, 0, 0, 0, 0, -268, 0, -268, 0, 0, 0, -268, 0, 0, -268, 0, 0, 0, -268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -268, 0, -268, -268, -268, -268, 0, 0, 0, 0, 0, -268, -268, -268, -268, 0, -268, -268, -268, -268, 0, 0, 0, 0, -268, -268, -268, -268, -268, 0, 0, -268, -268, -268, -268, 0, -268, -268, -268, -268, -268, -268, -268, -268, -268, 0, 0, 0, -268, -268, 0, 0, 0, -268, -268, -268, -268, -268, -268, + 0, 0, 0, 0, 0, 0, 0, 0, -641, 0, 0, 0, 0, 0, 0, 980, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 927 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -18, 0, 0, 0, 0, 0, 0, -18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 928 - -398, 0, 0, 0, 0, 0, -398, 0, -398, 0, 0, 0, -398, 0, 0, -398, 0, 0, 0, -398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -398, 0, -398, -398, -398, -398, 0, 0, 0, 0, 0, -398, -398, -398, -398, 0, -398, -398, -398, -398, 0, 0, 0, 0, -398, -398, -398, -398, -398, 0, 0, -398, -398, -398, -398, 0, -398, -398, -398, -398, -398, -398, -398, -398, -398, 0, 0, 0, -398, -398, 0, 0, 0, -398, -398, -398, -398, -398, -398, + -406, 0, 0, 0, 0, 0, 0, -406, 0, -406, 0, 0, 0, -406, 0, 0, -406, 0, 0, 0, -406, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -406, 0, -406, -406, -406, -406, 0, 0, 0, 0, 0, -406, -406, -406, -406, 0, -406, -406, -406, -406, 0, 982, 0, 0, -406, -406, -406, -406, -406, 0, 0, -406, -406, -406, -406, 0, -406, -406, -406, -406, -406, -406, -406, -406, -406, 0, 0, 0, -406, -406, 0, -406, 0, 0, 0, -406, -406, 0, -406, -406, -406, -406, // State 929 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -534, 0, 0, 0, 0, 0, 0, 0, -534, 0, 0, 0, 0, 0, 0, -534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 930 - -388, 0, 0, 0, 0, 0, -388, 0, -388, 0, 0, 0, -388, 0, 0, -388, 0, 0, 0, -388, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -388, 0, -388, -388, -388, -388, 0, 0, 0, 0, 0, -388, -388, -388, -388, 0, -388, -388, -388, -388, 0, 0, 0, 0, -388, -388, -388, -388, -388, 0, 0, -388, -388, -388, -388, 0, -388, -388, -388, -388, -388, -388, -388, -388, -388, 0, 0, 0, -388, -388, 0, 0, 0, -388, -388, -388, -388, -388, -388, + -537, 0, 0, 0, 0, 0, 0, 0, -537, 0, 0, 0, 0, 0, 0, -537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 931 - -381, 0, 0, 0, 0, 0, -381, 0, -381, 0, 0, 0, -381, 0, 0, -381, 0, 0, 0, -381, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -381, 0, -381, -381, -381, -381, 0, 0, 0, 0, 0, -381, -381, -381, -381, 0, -381, -381, -381, -381, 0, 998, 0, 0, -381, -381, -381, -381, -381, 0, 0, -381, -381, -381, -381, 0, -381, -381, -381, -381, -381, -381, -381, -381, -381, 0, 0, 0, -381, -381, 0, 0, 0, -381, -381, -381, -381, -381, -381, + -447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 932 - -393, 0, 0, 0, 0, 0, -393, 0, -393, 0, 0, 0, -393, 0, 0, -393, 0, 0, 0, -393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -393, 0, -393, -393, -393, -393, 0, 0, 0, 0, 0, -393, -393, -393, -393, 0, -393, -393, -393, -393, 0, 0, 0, 0, -393, -393, -393, -393, -393, 0, 0, -393, -393, -393, -393, 0, -393, -393, -393, -393, -393, -393, -393, -393, -393, 0, 0, 0, -393, -393, 0, 0, 0, -393, -393, -393, -393, -393, -393, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 933 - 0, 0, 0, 0, 0, 0, 0, -601, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 934 - 0, 0, 0, 0, 0, 0, 0, -595, 0, 0, 0, 0, 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 935 - 0, 0, 0, 0, 0, 0, 0, -600, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 936 - 0, 0, 0, 0, 0, 0, 0, -618, 0, 0, 0, 0, 0, 0, 1003, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -856, 0, 0, 0, 0, 0, 0, -856, 0, -856, 0, 0, 0, -856, 0, 0, -856, 0, 0, 0, -856, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -856, 0, -856, -856, -856, -856, 0, 0, 0, 0, 0, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, -856, 0, 0, -856, -856, -856, -856, 0, -856, -856, -856, -856, -856, -856, -856, -856, -856, 0, 0, 0, -856, -856, 0, -856, 0, 0, 0, -856, -856, 0, -856, -856, -856, -856, // State 937 - 0, 0, 0, 0, 0, 0, 0, -17, 0, 0, 0, 0, 0, 0, -17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 938 - 0, 0, 0, 0, 0, 0, 0, -793, 0, 0, 0, 0, 0, 0, -793, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -346, 0, 0, 0, 0, 0, 0, -346, 0, -346, 0, 0, 0, -346, 0, 0, -346, 0, 0, 0, -346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -346, 0, -346, -346, -346, -346, 0, 0, 0, 0, 0, -346, -346, -346, -346, 0, -346, -346, -346, -346, 0, -346, -346, -346, -346, -346, -346, -346, -346, 0, 0, -346, -346, -346, -346, 0, -346, -346, -346, -346, -346, -346, -346, -346, -346, 0, 0, 0, -346, -346, 0, -346, 0, 0, 0, -346, -346, 0, -346, -346, -346, -346, // State 939 - 0, 0, 0, 0, 0, 0, 0, -615, 0, 0, 0, 0, 0, 0, 1005, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -893, 0, 0, 0, 0, 0, 0, -893, 0, -893, 0, 0, 0, -893, 0, 0, -893, 0, 0, 0, -893, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -893, 0, -893, -893, -893, -893, 0, 0, 0, 0, 0, -893, -893, -893, -893, 0, -893, -893, -893, -893, 0, 0, 0, 0, -893, -893, -893, -893, -893, 0, 0, -893, -893, -893, -893, 0, -893, -893, -893, -893, -893, -893, -893, -893, -893, 0, 0, 0, -893, -893, 0, -893, 0, 0, 0, -893, -893, 0, -893, -893, -893, -893, // State 940 - 0, 0, 0, 0, 0, 0, 0, -608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1016, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1017, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 941 - 0, 0, 0, 0, 0, 0, 0, -342, 0, 0, 0, 0, 0, 0, -342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -827, 0, -827, 0, 0, 0, -827, 0, 0, -827, 0, 0, 0, -827, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -827, 0, -827, -827, -827, -827, 0, 0, 0, 0, 0, -827, -827, -827, -827, 0, -827, -827, -827, -827, 0, 0, 0, 0, -827, -827, -827, -827, -827, 0, 0, -827, -827, -827, -827, 0, -827, -827, -827, -827, -827, -827, -827, -827, -827, 0, 0, 0, -827, -827, 0, -827, 0, 0, 0, -827, -827, 0, -827, -827, -827, -827, // State 942 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1018, 0, 0, 0, 0, 0, 0, -134, 0, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -134, -134, -134, -134, 0, 0, 0, 0, 0, -134, 0, -134, -134, 0, 0, -134, 0, -134, 0, 0, 0, 0, 0, -134, -134, 0, -134, 0, 0, -134, 0, -134, -134, 0, -134, -134, -134, 0, -134, 0, 0, -134, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, -134, 0, -134, -134, -134, -134, // State 943 - -423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -830, 0, -830, 0, 0, 0, -830, 0, 0, -830, 0, 0, 0, -830, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -830, 0, -830, -830, -830, -830, 0, 0, 0, 0, 0, -830, -830, -830, -830, 0, -830, -830, -830, -830, 0, 0, 0, 0, -830, -830, -830, -830, -830, 0, 0, -830, -830, -830, -830, 0, -830, -830, -830, -830, -830, -830, -830, -830, -830, 0, 0, 0, -830, -830, 0, -830, 0, 0, 0, -830, -830, 0, -830, -830, -830, -830, // State 944 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1020, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1021, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 945 - -414, 0, 0, 0, 0, 0, -414, 0, -414, 0, 0, 0, -414, 0, 0, -414, 0, 0, 0, -414, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -414, 0, -414, -414, -414, -414, 0, 0, 0, 0, 0, -414, -414, -414, -414, 0, -414, -414, -414, -414, 0, 0, 0, 0, -414, -414, -414, -414, -414, 0, 0, -414, -414, -414, -414, 0, -414, -414, -414, -414, -414, -414, -414, -414, -414, 0, 0, 0, -414, -414, 0, 0, 0, -414, -414, -414, -414, -414, -414, + -859, 0, 0, 0, 0, 0, 0, -859, 0, -859, 0, 0, 0, -859, 0, 0, -859, 0, 0, 0, -859, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -859, 0, -859, -859, -859, -859, 0, 0, 0, 0, 0, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, 0, 0, -859, -859, -859, -859, 0, -859, -859, -859, -859, -859, -859, -859, -859, -859, 0, 0, 0, -859, -859, 0, -859, 0, 0, 0, -859, -859, 0, -859, -859, -859, -859, // State 946 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -473, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -864, 0, 0, 0, 0, 0, 0, 0, 0, 0, -869, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 947 - -479, 0, 0, 0, 0, 0, -479, 0, -479, 0, 0, 0, -479, 0, 0, -479, 0, 0, 0, -479, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -479, 0, -479, -479, -479, -479, 0, 0, 0, 0, 0, -479, -479, -479, -479, 0, -479, -479, -479, -479, 0, 0, 0, 0, -479, -479, -479, -479, -479, 0, 0, -479, -479, -479, -479, 0, -479, -479, -479, -479, -479, -479, -479, -479, -479, 0, 0, 0, -479, -479, 0, 0, 0, -479, -479, -479, -479, -479, -479, + 0, 0, -194, -194, 0, -194, 0, -194, 0, -194, -194, 0, 0, -194, 0, -194, -194, 0, 0, -194, 0, -194, -194, 0, 0, -221, 0, 0, -194, -194, 0, -194, 0, -194, -194, -194, -194, 0, 0, -194, 0, 0, 0, 0, -194, 0, -194, 0, -194, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -194, 0, -194, -194, 0, 0, 0, -194, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 948 - 0, 0, 0, 0, 0, 0, 0, -455, 0, 0, 0, 0, 0, 0, -455, 0, 0, 0, 0, 0, 0, 0, 0, 0, -455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -455, 0, 0, 0, -455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -455, 0, -455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 422, + 0, 0, 0, 0, 0, 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 949 - 0, 0, 0, 0, 0, 0, 0, -454, 0, 0, 0, 0, 0, 0, -454, 0, 0, 0, 0, 0, 0, 0, 0, 0, -454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -454, 0, 0, 0, -454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -454, 0, -454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -195, -195, 0, -195, 0, -195, 0, -195, -195, 0, 0, -195, 0, -195, -195, 0, 0, -195, 0, -195, -195, 0, 0, -222, 0, 0, -195, -195, 0, -195, 0, -195, -195, -195, -195, 0, 0, -195, 0, 0, 0, 0, -195, 0, -195, 0, -195, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -195, 0, -195, -195, 0, 0, 0, -195, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 950 - 0, 0, 0, 0, 0, 0, 0, -724, 0, 0, 0, 0, 0, 0, -724, 0, 0, 0, 0, 0, 0, 0, 0, 0, -724, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -724, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -724, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -724, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1025, 0, 0, 0, 0, 0, 0, 348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 951 - 0, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 952 - 0, 0, 0, 0, 0, 0, 0, -282, 0, 0, 0, 0, 0, 0, -282, 0, 0, 0, 0, 0, 0, 0, 0, 0, -282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -282, 0, 0, 0, -282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -282, 0, -282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -932, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 953 - 0, 0, 0, 0, 0, 0, 0, -531, 0, 0, 0, 0, 0, 0, -531, 0, 0, 0, 0, 0, 0, 0, 0, 0, -531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -531, 0, 0, 0, -531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 347, 0, -531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -319, 0, 0, -319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 954 - 0, 0, 0, 0, 0, 0, 0, -324, 0, 0, 0, 0, -324, 0, -324, -324, 0, 0, 0, 0, 0, 0, 0, 0, -324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -324, 0, 0, 0, -324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -324, 0, -324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -315, 0, 0, 0, 0, 0, 0, -315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -315, 0, 0, 0, 0, 0, -315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -315, 0, 0, -315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 955 - 0, 0, 0, 0, 0, 0, 0, -325, 0, 0, 0, 0, -325, 0, -325, -325, 0, 0, 0, 0, 0, 0, 0, 0, -325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -325, 0, 0, 0, -325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -325, 0, -325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -361, 0, 0, 0, 0, 0, 0, -361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -361, 0, 0, 0, 0, 0, -361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -361, 0, 0, -361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 956 - 0, 0, 0, 0, 0, 0, -476, -265, 0, 0, 0, 0, 0, 0, -265, 0, 0, 0, -476, 0, 0, 0, 0, 0, -265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -265, 0, 0, 0, -265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -265, 0, -265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -659, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 957 - 0, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, -683, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 958 - 0, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 959 - 0, 0, 0, 0, 0, 0, 0, -725, 0, 0, 0, 0, 0, 0, -725, 0, 0, 0, 0, 0, 0, 0, 0, 0, -725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -725, 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -706, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 960 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 353, 0, 0, 0, 0, 0, 0, 0, 0, 0, -738, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -738, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 349, 0, 0, 0, 0, 0, 0, 0, 0, 0, -700, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 961 - 0, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 351, 0, 0, 0, 0, 0, 0, 0, 0, 0, -696, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 962 - 0, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1032, 0, 0, 0, 0, 0, 0, 0, 0, 0, -681, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 963 - 0, 0, 0, 0, 0, 0, 0, -532, 0, 0, 0, 0, 0, 0, -532, 0, 0, 0, 0, 0, 0, 0, 0, 0, -532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -532, 0, 0, 0, -532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 356, 0, -532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 964 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 357, 0, 0, 0, 0, 0, 0, 0, 0, 0, -737, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -737, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -414, 0, 0, 0, 0, 0, 0, -414, 0, -414, 0, 0, 0, -414, 0, 0, -414, 0, 0, 0, -414, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -414, 0, -414, -414, -414, -414, 0, 0, 0, 0, 0, -414, -414, -414, -414, 0, -414, -414, -414, -414, 0, 0, 0, 0, -414, -414, -414, -414, -414, 0, 0, -414, -414, -414, -414, 0, -414, -414, -414, -414, -414, -414, -414, -414, -414, 0, 0, 0, -414, -414, 0, -414, 0, 0, 0, -414, -414, 0, -414, -414, -414, -414, // State 965 - 0, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -267, 0, 0, 0, 0, 0, 0, -267, 0, -267, 0, 0, 0, -267, 0, 0, -267, 0, 0, 0, -267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -267, 0, -267, -267, -267, -267, 0, 0, 0, 0, 0, -267, -267, -267, -267, 0, -267, -267, -267, -267, 0, 0, 0, 0, -267, -267, -267, -267, -267, 0, 0, -267, -267, -267, -267, 0, -267, -267, -267, -267, -267, -267, -267, -267, -267, 0, 0, 0, -267, -267, 0, -267, 0, 0, 0, -267, -267, 0, -267, -267, -267, -267, // State 966 - 0, 0, 0, 0, 0, 0, 0, -452, 0, 0, 0, 0, 0, 0, -452, 0, 0, 0, 0, 0, 0, 0, 0, 0, -452, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -452, 0, 0, 0, -452, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -452, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -452, 0, -452, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 353, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 967 - 0, 0, 0, 0, 0, 0, 0, -450, 0, 0, 0, 0, 0, 0, -450, 0, 0, 0, 0, 0, 0, 0, 0, 0, -450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -450, 0, 0, 0, -450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -450, 0, -450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -421, 0, 0, 0, 0, 0, 0, -421, 0, -421, 0, 0, 0, -421, 0, 0, -421, 0, 0, 0, -421, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -421, 0, -421, -421, -421, -421, 0, 0, 0, 0, 0, -421, -421, -421, -421, 0, -421, -421, -421, -421, 0, 0, 0, 0, -421, -421, -421, -421, -421, 0, 0, -421, -421, -421, -421, 0, -421, -421, -421, -421, -421, -421, -421, -421, -421, 0, 0, 0, -421, -421, 0, -421, 0, 0, 0, -421, -421, 0, -421, -421, -421, -421, // State 968 - 0, 0, 0, 0, 0, 0, 0, -451, 0, 0, 0, 0, 0, 0, -451, 0, 0, 0, 0, 0, 0, 0, 0, 0, -451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -451, 0, 0, 0, -451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -451, 0, -451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 969 - -482, 0, 0, 0, 0, 0, -482, 0, -482, 0, 0, 0, -482, 0, 0, -482, 0, 0, 0, -482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -482, 0, -482, -482, -482, -482, 0, 0, 0, 0, 0, -482, -482, -482, -482, 0, -482, -482, -482, -482, 0, 0, 0, 0, -482, -482, -482, -482, -482, 0, 0, -482, -482, -482, -482, 0, -482, -482, -482, -482, -482, -482, -482, -482, -482, 0, 0, 0, -482, -482, 0, 0, 0, -482, -482, -482, -482, -482, -482, + -411, 0, 0, 0, 0, 0, 0, -411, 0, -411, 0, 0, 0, -411, 0, 0, -411, 0, 0, 0, -411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -411, 0, -411, -411, -411, -411, 0, 0, 0, 0, 0, -411, -411, -411, -411, 0, -411, -411, -411, -411, 0, 0, 0, 0, -411, -411, -411, -411, -411, 0, 0, -411, -411, -411, -411, 0, -411, -411, -411, -411, -411, -411, -411, -411, -411, 0, 0, 0, -411, -411, 0, -411, 0, 0, 0, -411, -411, 0, -411, -411, -411, -411, // State 970 - -854, 0, 0, 0, 0, 0, -854, 0, -854, 0, 0, 0, -854, 0, 0, -854, 0, 0, 0, -854, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -854, 0, -854, -854, -854, -854, 0, 0, 0, 0, 0, -854, -854, -854, -854, 0, -854, -854, -854, -854, 0, 0, 0, 1032, -854, -854, -854, -854, -854, 0, 0, -854, -854, -854, -854, 0, -854, -854, -854, -854, -854, -854, -854, -854, -854, 0, 0, 0, -854, -854, 0, 0, 0, -854, -854, -854, -854, -854, -854, + -404, 0, 0, 0, 0, 0, 0, -404, 0, -404, 0, 0, 0, -404, 0, 0, -404, 0, 0, 0, -404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -404, 0, -404, -404, -404, -404, 0, 0, 0, 0, 0, -404, -404, -404, -404, 0, -404, -404, -404, -404, 0, 1037, 0, 0, -404, -404, -404, -404, -404, 0, 0, -404, -404, -404, -404, 0, -404, -404, -404, -404, -404, -404, -404, -404, -404, 0, 0, 0, -404, -404, 0, -404, 0, 0, 0, -404, -404, 0, -404, -404, -404, -404, // State 971 - -855, 0, 0, 0, 0, 0, -855, 0, -855, 0, 0, 0, -855, 0, 0, -855, 0, 0, 0, -855, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -855, 0, -855, -855, -855, -855, 0, 0, 0, 0, 0, -855, -855, -855, -855, 0, -855, -855, -855, -855, 0, 0, 0, 0, -855, -855, -855, -855, -855, 0, 0, -855, -855, -855, -855, 0, -855, -855, -855, -855, -855, -855, -855, -855, -855, 0, 0, 0, -855, -855, 0, 0, 0, -855, -855, -855, -855, -855, -855, + -416, 0, 0, 0, 0, 0, 0, -416, 0, -416, 0, 0, 0, -416, 0, 0, -416, 0, 0, 0, -416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -416, 0, -416, -416, -416, -416, 0, 0, 0, 0, 0, -416, -416, -416, -416, 0, -416, -416, -416, -416, 0, 0, 0, 0, -416, -416, -416, -416, -416, 0, 0, -416, -416, -416, -416, 0, -416, -416, -416, -416, -416, -416, -416, -416, -416, 0, 0, 0, -416, -416, 0, -416, 0, 0, 0, -416, -416, 0, -416, -416, -416, -416, // State 972 - -858, 0, 0, 0, 0, 0, -858, 0, -858, 0, 0, 0, -858, 0, 0, -858, 0, 0, 0, -858, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -858, 0, -858, -858, -858, -858, 0, 0, 0, 0, 0, -858, -858, -858, -858, 0, -858, -858, -858, -858, 0, 0, 0, 1033, -858, -858, -858, -858, -858, 0, 0, -858, -858, -858, -858, 0, -858, -858, -858, -858, -858, -858, -858, -858, -858, 0, 0, 0, -858, -858, 0, 0, 0, -858, -858, -858, -858, -858, -858, + 0, 0, 0, 0, 0, 0, 0, 0, -626, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 973 - -859, 0, 0, 0, 0, 0, -859, 0, -859, 0, 0, 0, -859, 0, 0, -859, 0, 0, 0, -859, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -859, 0, -859, -859, -859, -859, 0, 0, 0, 0, 0, -859, -859, -859, -859, 0, -859, -859, -859, -859, 0, 0, 0, 0, -859, -859, -859, -859, -859, 0, 0, -859, -859, -859, -859, 0, -859, -859, -859, -859, -859, -859, -859, -859, -859, 0, 0, 0, -859, -859, 0, 0, 0, -859, -859, -859, -859, -859, -859, + 0, 0, 0, 0, 0, 0, 0, 0, -620, 0, 0, 0, 0, 0, 0, 355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 974 - -346, 0, 0, 0, 0, 0, -346, 0, -346, 0, 0, 0, -346, 0, 0, -346, 0, 0, 0, -346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -346, 0, -346, -346, -346, -346, 0, 0, 0, 0, 0, -346, -346, -346, -346, 0, -346, -346, -346, -346, 0, -346, -346, -346, -346, -346, -346, -346, -346, 0, 0, -346, -346, -346, -346, 0, -346, -346, -346, -346, -346, -346, -346, -346, -346, 0, 0, 0, -346, -346, 0, 0, 0, -346, -346, -346, -346, -346, -346, + 0, 0, 0, 0, 0, 0, 0, 0, -625, 0, 0, 0, 0, 0, 0, 357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 975 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -643, 0, 0, 0, 0, 0, 0, 1042, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 976 - 0, 0, 0, 0, 0, 0, -803, 0, -803, 0, 0, 0, -803, 0, 0, -803, 0, 0, 0, -803, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -803, 0, -803, -803, -803, -803, 0, 0, 0, 0, 0, -803, -803, -803, -803, 0, -803, -803, -803, -803, 0, 0, 0, 0, -803, -803, -803, -803, -803, 0, 0, -803, -803, -803, -803, 0, -803, -803, -803, -803, -803, -803, -803, -803, -803, 0, 0, 0, -803, -803, 0, 0, 0, -803, -803, -803, -803, -803, -803, + 0, 0, 0, 0, 0, 0, 0, 0, -19, 0, 0, 0, 0, 0, 0, -19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 977 - 1036, 0, 0, 0, 0, 0, -133, 0, -133, 0, 0, 0, -133, 0, 0, -133, 0, 0, 0, -133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -133, -133, -133, -133, 0, 0, 0, 0, 0, -133, 0, -133, -133, 0, 0, -133, 0, -133, 0, 0, 0, 0, 0, -133, -133, 0, -133, 0, 0, -133, 0, -133, -133, 0, -133, -133, -133, 0, -133, 0, 0, -133, -133, 0, 0, 0, -133, 0, 0, 0, 0, -133, -133, -133, -133, -133, -133, + 0, 0, 0, 0, 0, 0, 0, 0, -818, 0, 0, 0, 0, 0, 0, -818, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 978 - 0, 0, 0, 0, 0, 0, -800, 0, -800, 0, 0, 0, -800, 0, 0, -800, 0, 0, 0, -800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -800, 0, -800, -800, -800, -800, 0, 0, 0, 0, 0, -800, -800, -800, -800, 0, -800, -800, -800, -800, 0, 0, 0, 0, -800, -800, -800, -800, -800, 0, 0, -800, -800, -800, -800, 0, -800, -800, -800, -800, -800, -800, -800, -800, -800, 0, 0, 0, -800, -800, 0, 0, 0, -800, -800, -800, -800, -800, -800, + 0, 0, 0, 0, 0, 0, 0, 0, -640, 0, 0, 0, 0, 0, 0, 1044, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 979 - 1037, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1038, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -633, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 980 - 0, 0, 0, 0, 0, 0, -808, 0, -808, 0, 0, 0, -808, 0, 0, -808, 0, 0, 0, -808, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -808, 0, -808, -808, -808, -808, 0, 0, 0, 0, 0, -808, -808, -808, -808, 0, -808, -808, -808, -808, 0, 0, 0, 0, -808, -808, -808, -808, -808, 0, 0, -808, -808, -808, -808, 0, -808, -808, -808, -808, -808, -808, -808, -808, -808, 0, 0, 0, -808, -808, 0, 0, 0, -808, -808, -808, -808, -808, -808, + 0, 0, 0, 0, 0, 0, 0, 0, -341, 0, 0, 0, 0, 0, 0, -341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 981 - 1039, 0, 0, 0, 0, 0, -132, 0, -132, 0, 0, 0, -132, 0, 0, -132, 0, 0, 0, -132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -132, -132, -132, -132, 0, 0, 0, 0, 0, -132, 0, -132, -132, 0, 0, -132, 0, -132, 0, 0, 0, 0, 0, -132, -132, 0, -132, 0, 0, -132, 0, -132, -132, 0, -132, -132, -132, 0, -132, 0, 0, -132, -132, 0, 0, 0, -132, 0, 0, 0, 0, -132, -132, -132, -132, -132, -132, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 982 - -888, 0, 0, 0, 0, 0, -888, 0, -888, 0, 0, 0, -888, 0, 0, -888, 0, 0, 0, -888, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -888, 0, -888, -888, -888, -888, 0, 0, 0, 0, 0, -888, -888, -888, -888, 0, -888, -888, -888, -888, 0, 0, 0, 0, -888, -888, -888, -888, -888, 0, 0, -888, -888, -888, -888, 0, -888, -888, -888, -888, -888, -888, -888, -888, -888, 0, 0, 0, -888, -888, 0, 0, 0, -888, -888, -888, -888, -888, -888, + -446, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -446, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 983 - 0, -198, -198, 0, -198, 0, -198, 0, -198, -198, 0, 0, -198, 0, -198, -198, 0, 0, -198, 0, -198, -198, 0, 0, -225, 0, 0, -198, -198, 0, -198, 0, -198, -198, -198, -198, 0, 0, -198, 0, 0, 0, 0, -198, 0, -198, 0, -198, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -198, 0, -198, -198, 0, 0, 0, -198, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 984 - 0, -192, -192, 0, -192, 0, -192, 0, -192, -192, 0, 0, -192, 0, -192, -192, 0, 0, -192, 0, -192, -192, 0, 0, -219, 0, 0, -192, -192, 0, -192, 0, -192, -192, -192, -192, 0, 0, -192, 0, 0, 0, 0, -192, 0, -192, 0, -192, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -192, 0, -192, -192, 0, 0, 0, -192, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, -192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -437, 0, 0, 0, 0, 0, 0, -437, 0, -437, 0, 0, 0, -437, 0, 0, -437, 0, 0, 0, -437, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -437, 0, -437, -437, -437, -437, 0, 0, 0, 0, 0, -437, -437, -437, -437, 0, -437, -437, -437, -437, 0, 0, 0, 0, -437, -437, -437, -437, -437, 0, 0, -437, -437, -437, -437, 0, -437, -437, -437, -437, -437, -437, -437, -437, -437, 0, 0, 0, -437, -437, 0, -437, 0, 0, 0, -437, -437, 0, -437, -437, -437, -437, // State 985 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -903, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 986 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -897, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -504, 0, 0, 0, 0, 0, 0, -504, 0, -504, 0, 0, 0, -504, 0, 0, -504, 0, 0, 0, -504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -504, 0, -504, -504, -504, -504, 0, 0, 0, 0, 0, -504, -504, -504, -504, 0, -504, -504, -504, -504, 0, 0, 0, 0, -504, -504, -504, -504, -504, 0, 0, -504, -504, -504, -504, 0, -504, -504, -504, -504, -504, -504, -504, -504, -504, 0, 0, 0, -504, -504, 0, -504, 0, 0, 0, -504, -504, 0, -504, -504, -504, -504, // State 987 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -479, 0, 0, 0, 0, 0, 0, -479, 0, 0, 0, 0, 0, 0, 0, 0, 0, -479, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -479, 0, 0, 0, -479, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -479, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -479, 0, -479, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 988 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 363, 0, 0, 0, 0, 0, 0, 0, 0, 0, -672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -749, 0, 0, 0, 0, 0, 0, -749, 0, 0, 0, 0, 0, 0, 0, 0, 0, -749, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -749, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -749, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -749, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 989 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1044, 0, 0, 0, 0, 0, 0, 0, 0, 0, -657, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -276, 0, -276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 990 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1045, 0, 0, 0, 0, 0, 0, 0, 0, 0, -662, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -281, 0, -281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 991 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1047, 0, 0, 0, 0, 0, 0, 0, 0, 0, -653, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -556, 0, 0, 0, 0, 0, 0, -556, 0, 0, 0, 0, 0, 0, 0, 0, 0, -556, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -556, 0, 0, 0, -556, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -556, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 361, 0, -556, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 992 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -323, 0, 0, 0, 0, -323, 0, -323, -323, 0, 0, 0, 0, 0, 0, 0, 0, -323, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -323, 0, 0, 0, -323, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -323, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -323, 0, -323, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 993 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 364, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -324, 0, 0, 0, 0, -324, 0, -324, -324, 0, 0, 0, 0, 0, 0, 0, 0, -324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -324, 0, 0, 0, -324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -324, 0, -324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 994 - -390, 0, 0, 0, 0, 0, -390, 0, -390, 0, 0, 0, -390, 0, 0, -390, 0, 0, 0, -390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -390, 0, -390, -390, -390, -390, 0, 0, 0, 0, 0, -390, -390, -390, -390, 0, -390, -390, -390, -390, 0, 0, 0, 0, -390, -390, -390, -390, -390, 0, 0, -390, -390, -390, -390, 0, -390, -390, -390, -390, -390, -390, -390, -390, -390, 0, 0, 0, -390, -390, 0, 0, 0, -390, -390, -390, -390, -390, -390, + 0, 0, 0, 0, 0, 0, 0, -501, -264, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, -501, 0, 0, 0, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -264, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 995 - -395, 0, 0, 0, 0, 0, -395, 0, -395, 0, 0, 0, -395, 0, 0, -395, 0, 0, 0, -395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -395, 0, -395, -395, -395, -395, 0, 0, 0, 0, 0, -395, -395, -395, -395, 0, -395, -395, -395, -395, 0, 0, 0, 0, -395, -395, -395, -395, -395, 0, 0, -395, -395, -395, -395, 0, -395, -395, -395, -395, -395, -395, -395, -395, -395, 0, 0, 0, -395, -395, 0, 0, 0, -395, -395, -395, -395, -395, -395, + 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 996 - -385, 0, 0, 0, 0, 0, -385, 0, -385, 0, 0, 0, -385, 0, 0, -385, 0, 0, 0, -385, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -385, 0, -385, -385, -385, -385, 0, 0, 0, 0, 0, -385, -385, -385, -385, 0, -385, -385, -385, -385, 0, 0, 0, 0, -385, -385, -385, -385, -385, 0, 0, -385, -385, -385, -385, 0, -385, -385, -385, -385, -385, -385, -385, -385, -385, 0, 0, 0, -385, -385, 0, 0, 0, -385, -385, -385, -385, -385, -385, + 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -280, 0, -280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 997 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 365, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 366, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -750, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 998 - -392, 0, 0, 0, 0, 0, -392, 0, -392, 0, 0, 0, -392, 0, 0, -392, 0, 0, 0, -392, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -392, 0, -392, -392, -392, -392, 0, 0, 0, 0, 0, -392, -392, -392, -392, 0, -392, -392, -392, -392, 0, 0, 0, 0, -392, -392, -392, -392, -392, 0, 0, -392, -392, -392, -392, 0, -392, -392, -392, -392, -392, -392, -392, -392, -392, 0, 0, 0, -392, -392, 0, 0, 0, -392, -392, -392, -392, -392, -392, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 367, 0, 0, 0, 0, 0, 0, 0, 0, 0, -763, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -763, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 999 - 0, 0, 0, 0, 0, 0, 0, -592, 0, 0, 0, 0, 0, 0, 366, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -279, 0, -279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1000 - 0, 0, 0, 0, 0, 0, 0, -577, 0, 0, 0, 0, 0, 0, 1053, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -277, 0, -277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1001 - 0, 0, 0, 0, 0, 0, 0, -605, 0, 0, 0, 0, 0, 0, 1055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -836, 0, 0, 0, 0, 0, 0, -836, 0, 0, 0, 0, 0, 0, 0, 0, 0, -836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -836, 0, 0, 0, -836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -836, 0, -836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -836, // State 1002 - 0, 0, 0, 0, 0, 0, 0, -610, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -557, 0, 0, 0, 0, 0, 0, -557, 0, 0, 0, 0, 0, 0, 0, 0, 0, -557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -557, 0, 0, 0, -557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, 0, -557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1003 - 0, 0, 0, 0, 0, 0, 0, -617, 0, 0, 0, 0, 0, 0, 1057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 371, 0, 0, 0, 0, 0, 0, 0, 0, 0, -762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1004 - 0, 0, 0, 0, 0, 0, 0, -607, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -278, 0, -278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1005 - -511, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -477, 0, 0, 0, 0, 0, 0, -477, 0, 0, 0, 0, 0, 0, 0, 0, 0, -477, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -477, 0, 0, 0, -477, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -477, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -477, 0, -477, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1006 - -416, 0, 0, 0, 0, 0, -416, 0, -416, 0, 0, 0, -416, 0, 0, -416, 0, 0, 0, -416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -416, 0, -416, -416, -416, -416, 0, 0, 0, 0, 0, -416, -416, -416, -416, 0, -416, -416, -416, -416, 0, 0, 0, 0, -416, -416, -416, -416, -416, 0, 0, -416, -416, -416, -416, 0, -416, -416, -416, -416, -416, -416, -416, -416, -416, 0, 0, 0, -416, -416, 0, 0, 0, -416, -416, -416, -416, -416, -416, + 0, 0, 0, 0, 0, 0, 0, 0, -475, 0, 0, 0, 0, 0, 0, -475, 0, 0, 0, 0, 0, 0, 0, 0, 0, -475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -475, 0, 0, 0, -475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -475, 0, -475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1007 - -105, 0, 0, 0, 0, 0, -105, 0, -105, 0, 0, 0, -105, 0, 0, -105, 0, 0, 0, -105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -105, 0, -105, -105, -105, -105, 0, 0, 0, 0, 0, -105, -105, -105, -105, 0, -105, -105, -105, -105, -105, -105, 0, 0, -105, -105, -105, -105, -105, 0, 0, -105, -105, -105, -105, 0, -105, -105, -105, -105, -105, -105, -105, -105, -105, 0, 0, 0, -105, -105, 0, 0, 0, -105, -105, -105, -105, -105, -105, + 0, 0, 0, 0, 0, 0, 0, 0, -476, 0, 0, 0, 0, 0, 0, -476, 0, 0, 0, 0, 0, 0, 0, 0, 0, -476, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -476, 0, 0, 0, -476, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -476, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -476, 0, -476, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1008 - -480, 0, 0, 0, 0, 0, -480, 0, -480, 0, 0, 0, -480, 0, 0, -480, 0, 0, 0, -480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -480, 0, -480, -480, -480, -480, 0, 0, 0, 0, 0, -480, -480, -480, -480, 0, -480, -480, -480, -480, 0, 0, 0, 0, -480, -480, -480, -480, -480, 0, 0, -480, -480, -480, -480, 0, -480, -480, -480, -480, -480, -480, -480, -480, -480, 0, 0, 0, -480, -480, 0, 0, 0, -480, -480, -480, -480, -480, -480, + -507, 0, 0, 0, 0, 0, 0, -507, 0, -507, 0, 0, 0, -507, 0, 0, -507, 0, 0, 0, -507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -507, 0, -507, -507, -507, -507, 0, 0, 0, 0, 0, -507, -507, -507, -507, 0, -507, -507, -507, -507, 0, 0, 0, 0, -507, -507, -507, -507, -507, 0, 0, -507, -507, -507, -507, 0, -507, -507, -507, -507, -507, -507, -507, -507, -507, 0, 0, 0, -507, -507, 0, -507, 0, 0, 0, -507, -507, 0, -507, -507, -507, -507, // State 1009 - 0, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -886, 0, 0, 0, 0, 0, 0, -886, 0, -886, 0, 0, 0, -886, 0, 0, -886, 0, 0, 0, -886, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -886, 0, -886, -886, -886, -886, 0, 0, 0, 0, 0, -886, -886, -886, -886, 0, -886, -886, -886, -886, 0, 0, 0, 1071, -886, -886, -886, -886, -886, 0, 0, -886, -886, -886, -886, 0, -886, -886, -886, -886, -886, -886, -886, -886, -886, 0, 0, 0, -886, -886, 0, -886, 0, 0, 0, -886, -886, 0, -886, -886, -886, -886, // State 1010 - 0, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -275, 0, -275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -887, 0, 0, 0, 0, 0, 0, -887, 0, -887, 0, 0, 0, -887, 0, 0, -887, 0, 0, 0, -887, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -887, 0, -887, -887, -887, -887, 0, 0, 0, 0, 0, -887, -887, -887, -887, 0, -887, -887, -887, -887, 0, 0, 0, 0, -887, -887, -887, -887, -887, 0, 0, -887, -887, -887, -887, 0, -887, -887, -887, -887, -887, -887, -887, -887, -887, 0, 0, 0, -887, -887, 0, -887, 0, 0, 0, -887, -887, 0, -887, -887, -887, -887, // State 1011 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -890, 0, 0, 0, 0, 0, 0, -890, 0, -890, 0, 0, 0, -890, 0, 0, -890, 0, 0, 0, -890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -890, 0, -890, -890, -890, -890, 0, 0, 0, 0, 0, -890, -890, -890, -890, 0, -890, -890, -890, -890, 0, 0, 0, 1072, -890, -890, -890, -890, -890, 0, 0, -890, -890, -890, -890, 0, -890, -890, -890, -890, -890, -890, -890, -890, -890, 0, 0, 0, -890, -890, 0, -890, 0, 0, 0, -890, -890, 0, -890, -890, -890, -890, // State 1012 - 0, 0, 0, 0, 0, 0, 0, 1077, 0, 0, 0, 0, 0, 0, 1078, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -891, 0, 0, 0, 0, 0, 0, -891, 0, -891, 0, 0, 0, -891, 0, 0, -891, 0, 0, 0, -891, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -891, 0, -891, -891, -891, -891, 0, 0, 0, 0, 0, -891, -891, -891, -891, 0, -891, -891, -891, -891, 0, 0, 0, 0, -891, -891, -891, -891, -891, 0, 0, -891, -891, -891, -891, 0, -891, -891, -891, -891, -891, -891, -891, -891, -891, 0, 0, 0, -891, -891, 0, -891, 0, 0, 0, -891, -891, 0, -891, -891, -891, -891, // State 1013 - 0, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -345, 0, 0, 0, 0, 0, 0, -345, 0, -345, 0, 0, 0, -345, 0, 0, -345, 0, 0, 0, -345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -345, 0, -345, -345, -345, -345, 0, 0, 0, 0, 0, -345, -345, -345, -345, 0, -345, -345, -345, -345, 0, -345, -345, -345, -345, -345, -345, -345, -345, 0, 0, -345, -345, -345, -345, 0, -345, -345, -345, -345, -345, -345, -345, -345, -345, 0, 0, 0, -345, -345, 0, -345, 0, 0, 0, -345, -345, 0, -345, -345, -345, -345, // State 1014 - 0, 0, 0, 0, 0, 0, 0, -792, 0, 0, 0, 0, 0, 0, -792, 0, 0, 0, 0, 0, 0, 0, 0, 0, -792, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -792, 0, 0, 0, -792, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -792, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -792, 0, -792, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 377, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1015 - 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, 0, -326, 0, -326, -326, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -326, 0, -326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -828, 0, -828, 0, 0, 0, -828, 0, 0, -828, 0, 0, 0, -828, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -828, 0, -828, -828, -828, -828, 0, 0, 0, 0, 0, -828, -828, -828, -828, 0, -828, -828, -828, -828, 0, 0, 0, 0, -828, -828, -828, -828, -828, 0, 0, -828, -828, -828, -828, 0, -828, -828, -828, -828, -828, -828, -828, -828, -828, 0, 0, 0, -828, -828, 0, -828, 0, 0, 0, -828, -828, 0, -828, -828, -828, -828, // State 1016 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1081, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1082, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1075, 0, 0, 0, 0, 0, 0, -135, 0, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -135, -135, -135, -135, 0, 0, 0, 0, 0, -135, 0, -135, -135, 0, 0, -135, 0, -135, 0, 0, 0, 0, 0, -135, -135, 0, -135, 0, 0, -135, 0, -135, -135, 0, -135, -135, -135, 0, -135, 0, 0, -135, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, -135, 0, -135, -135, -135, -135, // State 1017 - 0, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -825, 0, -825, 0, 0, 0, -825, 0, 0, -825, 0, 0, 0, -825, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -825, 0, -825, -825, -825, -825, 0, 0, 0, 0, 0, -825, -825, -825, -825, 0, -825, -825, -825, -825, 0, 0, 0, 0, -825, -825, -825, -825, -825, 0, 0, -825, -825, -825, -825, 0, -825, -825, -825, -825, -825, -825, -825, -825, -825, 0, 0, 0, -825, -825, 0, -825, 0, 0, 0, -825, -825, 0, -825, -825, -825, -825, // State 1018 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -462, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 422, + 1076, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1077, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1019 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -458, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -833, 0, -833, 0, 0, 0, -833, 0, 0, -833, 0, 0, 0, -833, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -833, 0, -833, -833, -833, -833, 0, 0, 0, 0, 0, -833, -833, -833, -833, 0, -833, -833, -833, -833, 0, 0, 0, 0, -833, -833, -833, -833, -833, 0, 0, -833, -833, -833, -833, 0, -833, -833, -833, -833, -833, -833, -833, -833, -833, 0, 0, 0, -833, -833, 0, -833, 0, 0, 0, -833, -833, 0, -833, -833, -833, -833, // State 1020 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -476, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1078, 0, 0, 0, 0, 0, 0, -134, 0, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -134, -134, -134, -134, 0, 0, 0, 0, 0, -134, 0, -134, -134, 0, 0, -134, 0, -134, 0, 0, 0, 0, 0, -134, -134, 0, -134, 0, 0, -134, 0, -134, -134, 0, -134, -134, -134, 0, -134, 0, 0, -134, -134, 0, 0, 0, -134, 0, 0, -134, 0, 0, 0, -134, -134, 0, -134, -134, -134, -134, // State 1021 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 371, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -920, 0, 0, 0, 0, 0, 0, -920, 0, -920, 0, 0, 0, -920, 0, 0, -920, 0, 0, 0, -920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -920, 0, -920, -920, -920, -920, 0, 0, 0, 0, 0, -920, -920, -920, -920, 0, -920, -920, -920, -920, 0, 0, 0, 0, -920, -920, -920, -920, -920, 0, 0, -920, -920, -920, -920, 0, -920, -920, -920, -920, -920, -920, -920, -920, -920, 0, 0, 0, -920, -920, 0, -920, 0, 0, 0, -920, -920, 0, -920, -920, -920, -920, // State 1022 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -197, -197, 0, -197, 0, -197, 0, -197, -197, 0, 0, -197, 0, -197, -197, 0, 0, -197, 0, -197, -197, 0, 0, -224, 0, 0, -197, -197, 0, -197, 0, -197, -197, -197, -197, 0, 0, -197, 0, 0, 0, 0, -197, 0, -197, 0, -197, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -197, 0, -197, -197, 0, 0, 0, -197, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, -197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1023 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 350, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -191, -191, 0, -191, 0, -191, 0, -191, -191, 0, 0, -191, 0, -191, -191, 0, 0, -191, 0, -191, -191, 0, 0, -218, 0, 0, -191, -191, 0, -191, 0, -191, -191, -191, -191, 0, 0, -191, 0, 0, 0, 0, -191, 0, -191, 0, -191, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -191, 0, -191, -191, 0, 0, 0, -191, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, -191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1024 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 351, 0, 0, 0, 0, 0, -456, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -935, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1025 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 372, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1083, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -929, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1026 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1027 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -459, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, -697, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1028 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -460, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1083, 0, 0, 0, 0, 0, 0, 0, 0, 0, -682, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1029 - 0, 0, 0, 0, 0, 0, 0, -463, 0, 0, 0, 0, 0, 0, -463, 0, 0, 0, 0, 0, 0, 0, 0, 0, -463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -463, 0, 0, 0, -463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -463, 0, -463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1084, 0, 0, 0, 0, 0, 0, 0, 0, 0, -687, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1030 - -481, 0, 0, 0, 0, 0, -481, 0, -481, 0, 0, 0, -481, 0, 0, -481, 0, 0, 0, -481, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -481, 0, -481, -481, -481, -481, 0, 0, 0, 0, 0, -481, -481, -481, -481, 0, -481, -481, -481, -481, 0, 0, 0, 0, -481, -481, -481, -481, -481, 0, 0, -481, -481, -481, -481, 0, -481, -481, -481, -481, -481, -481, -481, -481, -481, 0, 0, 0, -481, -481, 0, 0, 0, -481, -481, -481, -481, -481, -481, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1086, 0, 0, 0, 0, 0, 0, 0, 0, 0, -678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1031 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 373, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -654, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1032 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 374, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 379, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1033 - -351, 0, 0, 0, 0, 0, -351, 0, -351, 0, 0, 0, -351, 0, 0, -351, 0, 0, 0, -351, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -351, 0, -351, -351, -351, -351, 0, 0, 0, 0, 0, -351, -351, -351, -351, 0, -351, -351, -351, -351, 0, -351, -351, -351, -351, -351, -351, -351, -351, 0, 0, -351, -351, -351, -351, 0, -351, -351, -351, -351, -351, -351, -351, -351, -351, 0, 0, 0, -351, -351, 0, 0, 0, -351, -351, -351, -351, -351, -351, + -413, 0, 0, 0, 0, 0, 0, -413, 0, -413, 0, 0, 0, -413, 0, 0, -413, 0, 0, 0, -413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -413, 0, -413, -413, -413, -413, 0, 0, 0, 0, 0, -413, -413, -413, -413, 0, -413, -413, -413, -413, 0, 0, 0, 0, -413, -413, -413, -413, -413, 0, 0, -413, -413, -413, -413, 0, -413, -413, -413, -413, -413, -413, -413, -413, -413, 0, 0, 0, -413, -413, 0, -413, 0, 0, 0, -413, -413, 0, -413, -413, -413, -413, // State 1034 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 375, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -418, 0, 0, 0, 0, 0, 0, -418, 0, -418, 0, 0, 0, -418, 0, 0, -418, 0, 0, 0, -418, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -418, 0, -418, -418, -418, -418, 0, 0, 0, 0, 0, -418, -418, -418, -418, 0, -418, -418, -418, -418, 0, 0, 0, 0, -418, -418, -418, -418, -418, 0, 0, -418, -418, -418, -418, 0, -418, -418, -418, -418, -418, -418, -418, -418, -418, 0, 0, 0, -418, -418, 0, -418, 0, 0, 0, -418, -418, 0, -418, -418, -418, -418, // State 1035 - 0, 0, 0, 0, 0, 0, -801, 0, -801, 0, 0, 0, -801, 0, 0, -801, 0, 0, 0, -801, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -801, 0, -801, -801, -801, -801, 0, 0, 0, 0, 0, -801, -801, -801, -801, 0, -801, -801, -801, -801, 0, 0, 0, 0, -801, -801, -801, -801, -801, 0, 0, -801, -801, -801, -801, 0, -801, -801, -801, -801, -801, -801, -801, -801, -801, 0, 0, 0, -801, -801, 0, 0, 0, -801, -801, -801, -801, -801, -801, + -408, 0, 0, 0, 0, 0, 0, -408, 0, -408, 0, 0, 0, -408, 0, 0, -408, 0, 0, 0, -408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -408, 0, -408, -408, -408, -408, 0, 0, 0, 0, 0, -408, -408, -408, -408, 0, -408, -408, -408, -408, 0, 0, 0, 0, -408, -408, -408, -408, -408, 0, 0, -408, -408, -408, -408, 0, -408, -408, -408, -408, -408, -408, -408, -408, -408, 0, 0, 0, -408, -408, 0, -408, 0, 0, 0, -408, -408, 0, -408, -408, -408, -408, // State 1036 - 0, 0, 0, 0, 0, 0, -809, 0, -809, 0, 0, 0, -809, 0, 0, -809, 0, 0, 0, -809, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -809, 0, -809, -809, -809, -809, 0, 0, 0, 0, 0, -809, -809, -809, -809, 0, -809, -809, -809, -809, 0, 0, 0, 0, -809, -809, -809, -809, -809, 0, 0, -809, -809, -809, -809, 0, -809, -809, -809, -809, -809, -809, -809, -809, -809, 0, 0, 0, -809, -809, 0, 0, 0, -809, -809, -809, -809, -809, -809, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1037 - 1086, 0, 0, 0, 0, 0, -133, 0, -133, 0, 0, 0, -133, 0, 0, -133, 0, 0, 0, -133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -133, -133, -133, -133, 0, 0, 0, 0, 0, -133, 0, -133, -133, 0, 0, -133, 0, -133, 0, 0, 0, 0, 0, -133, -133, 0, -133, 0, 0, -133, 0, -133, -133, 0, -133, -133, -133, 0, -133, 0, 0, -133, -133, 0, 0, 0, -133, 0, 0, 0, 0, -133, -133, -133, -133, -133, -133, + -415, 0, 0, 0, 0, 0, 0, -415, 0, -415, 0, 0, 0, -415, 0, 0, -415, 0, 0, 0, -415, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -415, 0, -415, -415, -415, -415, 0, 0, 0, 0, 0, -415, -415, -415, -415, 0, -415, -415, -415, -415, 0, 0, 0, 0, -415, -415, -415, -415, -415, 0, 0, -415, -415, -415, -415, 0, -415, -415, -415, -415, -415, -415, -415, -415, -415, 0, 0, 0, -415, -415, 0, -415, 0, 0, 0, -415, -415, 0, -415, -415, -415, -415, // State 1038 - 0, 0, 0, 0, 0, 0, -806, 0, -806, 0, 0, 0, -806, 0, 0, -806, 0, 0, 0, -806, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -806, 0, -806, -806, -806, -806, 0, 0, 0, 0, 0, -806, -806, -806, -806, 0, -806, -806, -806, -806, 0, 0, 0, 0, -806, -806, -806, -806, -806, 0, 0, -806, -806, -806, -806, 0, -806, -806, -806, -806, -806, -806, -806, -806, -806, 0, 0, 0, -806, -806, 0, 0, 0, -806, -806, -806, -806, -806, -806, + 0, 0, 0, 0, 0, 0, 0, 0, -617, 0, 0, 0, 0, 0, 0, 381, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1039 - 0, -194, -194, 0, -194, 0, -194, 0, -194, -194, 0, 0, -194, 0, -194, -194, 0, 0, -194, 0, -194, -194, 0, 0, -221, 0, 0, -194, -194, 0, -194, 0, -194, -194, -194, -194, 0, 0, -194, 0, 0, 0, 0, -194, 0, -194, 0, -194, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -194, 0, -194, -194, 0, 0, 0, -194, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, -194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -602, 0, 0, 0, 0, 0, 0, 1092, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1040 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -630, 0, 0, 0, 0, 0, 0, 1094, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1041 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1087, 0, 0, 0, 0, 0, 0, 0, 0, 0, -663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -635, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1042 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1089, 0, 0, 0, 0, 0, 0, 0, 0, 0, -654, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -642, 0, 0, 0, 0, 0, 0, 1096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1043 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -630, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1044 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -635, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -536, 0, 0, 0, 0, 0, 0, 0, -536, 0, 0, 0, 0, 0, 0, -536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1045 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1090, 0, 0, 0, 0, 0, 0, 0, 0, 0, -659, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -439, 0, 0, 0, 0, 0, 0, -439, 0, -439, 0, 0, 0, -439, 0, 0, -439, 0, 0, 0, -439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -439, 0, -439, -439, -439, -439, 0, 0, 0, 0, 0, -439, -439, -439, -439, 0, -439, -439, -439, -439, 0, 0, 0, 0, -439, -439, -439, -439, -439, 0, 0, -439, -439, -439, -439, 0, -439, -439, -439, -439, -439, -439, -439, -439, -439, 0, 0, 0, -439, -439, 0, -439, 0, 0, 0, -439, -439, 0, -439, -439, -439, -439, // State 1046 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -626, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -107, 0, 0, 0, 0, 0, 0, -107, 0, -107, 0, 0, 0, -107, 0, 0, -107, 0, 0, 0, -107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -107, 0, -107, -107, -107, -107, 0, 0, 0, 0, 0, -107, -107, -107, -107, 0, -107, -107, -107, -107, -107, -107, 0, 0, -107, -107, -107, -107, -107, 0, 0, -107, -107, -107, -107, 0, -107, -107, -107, -107, -107, -107, -107, -107, -107, 0, 0, 0, -107, -107, 0, -107, 0, 0, 0, -107, -107, 0, -107, -107, -107, -107, // State 1047 - -387, 0, 0, 0, 0, 0, -387, 0, -387, 0, 0, 0, -387, 0, 0, -387, 0, 0, 0, -387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -387, 0, -387, -387, -387, -387, 0, 0, 0, 0, 0, -387, -387, -387, -387, 0, -387, -387, -387, -387, 0, 0, 0, 0, -387, -387, -387, -387, -387, 0, 0, -387, -387, -387, -387, 0, -387, -387, -387, -387, -387, -387, -387, -387, -387, 0, 0, 0, -387, -387, 0, 0, 0, -387, -387, -387, -387, -387, -387, + -505, 0, 0, 0, 0, 0, 0, -505, 0, -505, 0, 0, 0, -505, 0, 0, -505, 0, 0, 0, -505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -505, 0, -505, -505, -505, -505, 0, 0, 0, 0, 0, -505, -505, -505, -505, 0, -505, -505, -505, -505, 0, 0, 0, 0, -505, -505, -505, -505, -505, 0, 0, -505, -505, -505, -505, 0, -505, -505, -505, -505, -505, -505, -505, -505, -505, 0, 0, 0, -505, -505, 0, -505, 0, 0, 0, -505, -505, 0, -505, -505, -505, -505, // State 1048 - -394, 0, 0, 0, 0, 0, -394, 0, -394, 0, 0, 0, -394, 0, 0, -394, 0, 0, 0, -394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -394, 0, -394, -394, -394, -394, 0, 0, 0, 0, 0, -394, -394, -394, -394, 0, -394, -394, -394, -394, 0, 0, 0, 0, -394, -394, -394, -394, -394, 0, 0, -394, -394, -394, -394, 0, -394, -394, -394, -394, -394, -394, -394, -394, -394, 0, 0, 0, -394, -394, 0, 0, 0, -394, -394, -394, -394, -394, -394, + 0, 0, 0, 0, 0, 0, 0, 0, -273, 0, 0, 0, 0, 0, 0, -273, 0, 0, 0, 0, 0, 0, 0, 0, 0, -273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -273, 0, 0, 0, -273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -273, 0, -273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1049 - -384, 0, 0, 0, 0, 0, -384, 0, -384, 0, 0, 0, -384, 0, 0, -384, 0, 0, 0, -384, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -384, 0, -384, -384, -384, -384, 0, 0, 0, 0, 0, -384, -384, -384, -384, 0, -384, -384, -384, -384, 0, 0, 0, 0, -384, -384, -384, -384, -384, 0, 0, -384, -384, -384, -384, 0, -384, -384, -384, -384, -384, -384, -384, -384, -384, 0, 0, 0, -384, -384, 0, 0, 0, -384, -384, -384, -384, -384, -384, + 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -274, 0, -274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1050 - 0, 0, 0, 0, 0, 0, 0, -583, 0, 0, 0, 0, 0, 0, 1093, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 385, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1051 - 0, 0, 0, 0, 0, 0, 0, -574, 0, 0, 0, 0, 0, 0, 1095, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -837, 0, 0, 0, 0, 0, 0, -837, 0, 0, 0, 0, 0, 0, 0, 0, 0, -837, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -837, 0, 0, 0, -837, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -837, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -837, 0, -837, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -837, // State 1052 - 0, 0, 0, 0, 0, 0, 0, -550, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1116, 0, 0, 0, 0, 0, 0, 1117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1053 - 0, 0, 0, 0, 0, 0, 0, -606, 0, 0, 0, 0, 0, 0, 1096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -779, 0, 0, 0, 0, 0, 0, -779, 0, 0, 0, 0, 0, 0, 0, 0, 0, -779, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -779, 0, 0, 0, -779, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -779, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -779, 0, -779, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1054 - 0, 0, 0, 0, 0, 0, 0, -602, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -817, 0, 0, 0, 0, 0, 0, -817, 0, 0, 0, 0, 0, 0, 0, 0, 0, -817, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -817, 0, 0, 0, -817, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -817, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -817, 0, -817, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1055 - 0, 0, 0, 0, 0, 0, 0, -596, 0, 0, 0, 0, 0, 0, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -325, 0, 0, 0, 0, -325, 0, -325, -325, 0, 0, 0, 0, 0, 0, 0, 0, -325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -325, 0, 0, 0, -325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -325, 0, -325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1056 - 0, 0, 0, 0, 0, 0, 0, -609, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1057 - -382, 0, 0, 0, 0, 0, -382, 0, -382, 0, 0, 0, -382, 0, 0, -382, 0, 0, 0, -382, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -382, 0, -382, -382, -382, -382, 0, 0, 0, 0, 0, -382, -382, -382, -382, 0, -382, -382, -382, -382, 0, 0, 0, 0, -382, -382, -382, -382, -382, 0, 0, -382, -382, -382, -382, 0, -382, -382, -382, -382, -382, -382, -382, -382, -382, 0, 0, 0, -382, -382, 0, 0, 0, -382, -382, -382, -382, -382, -382, + 0, 0, 0, 0, 0, 0, 0, 0, -784, 0, 0, 0, 0, 0, 0, -784, 0, 0, 0, 0, 0, 0, 0, 0, 0, -784, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -784, 0, 0, 0, -784, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -784, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -784, 0, -784, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1058 - -106, 0, 0, 0, 0, 0, -106, 0, -106, 0, 0, 0, -106, 0, 0, -106, 0, 0, 0, -106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -106, 0, -106, -106, -106, -106, 0, 0, 0, 0, 0, -106, -106, -106, -106, 0, -106, -106, -106, -106, -106, -106, 0, 0, -106, -106, -106, -106, -106, 0, 0, -106, -106, -106, -106, 0, -106, -106, -106, -106, -106, -106, -106, -106, -106, 0, 0, 0, -106, -106, 0, 0, 0, -106, -106, -106, -106, -106, -106, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1059 - 0, 0, 0, 0, 0, 0, 0, -862, 0, 0, 0, 0, 0, 0, -862, 0, 0, 0, 0, 0, 0, 0, 0, 0, -862, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -862, 0, 0, 0, -862, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -862, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -862, 0, -862, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1060 - 0, 0, 0, 0, 0, 0, 0, -154, 0, 0, 0, 0, 0, 0, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -154, 0, 0, 0, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -154, 0, -154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 386, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1061 - 0, 0, 0, 0, 0, 0, -476, -265, 0, 0, 0, 0, 0, 0, -265, 0, 0, 0, -476, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1062 - 0, 0, 0, 0, 0, 0, 0, -513, 0, 0, 0, 0, 0, 0, -513, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 364, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1063 - 0, 0, 0, 0, 0, 0, 0, 1100, 0, 0, 0, 0, 0, 0, 381, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 365, 0, 0, 0, 0, 0, -481, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1064 - 0, 0, 0, 0, 0, 0, 0, 1101, 0, 0, 0, 0, 0, 0, 382, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1065 - 0, 0, 0, 0, 0, 0, 0, -521, 0, 0, 0, 0, 0, 0, -521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1066 - 0, 0, 0, 0, 0, 0, 0, -734, 0, 0, 0, 0, 0, 0, -734, 0, 0, 0, 0, 0, 0, 0, 0, 0, -734, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -734, 0, 0, 0, -734, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -734, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -734, 0, -734, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1067 - 0, 0, 0, 0, 0, 0, -477, -477, 0, 0, 0, 0, 0, 0, -477, 0, 0, 0, -477, 0, 0, 0, 0, 0, -477, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -477, 0, 0, 0, -477, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -477, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -477, 0, -477, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1068 - 0, 0, 0, 0, 0, 0, -478, -478, 0, 0, 0, 0, 0, 0, -478, 0, 0, 0, -478, 0, 0, 0, 0, 0, -478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -478, 0, 0, 0, -478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -478, 0, -478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -488, 0, -488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1069 - 0, 0, 0, 0, 0, 0, 0, -173, 0, 0, 0, 0, 0, 0, -173, 0, 0, 0, 0, 0, 0, 0, 0, 0, -173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -506, 0, 0, 0, 0, 0, 0, -506, 0, -506, 0, 0, 0, -506, 0, 0, -506, 0, 0, 0, -506, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -506, 0, -506, -506, -506, -506, 0, 0, 0, 0, 0, -506, -506, -506, -506, 0, -506, -506, -506, -506, 0, 0, 0, 0, -506, -506, -506, -506, -506, 0, 0, -506, -506, -506, -506, 0, -506, -506, -506, -506, -506, -506, -506, -506, -506, 0, 0, 0, -506, -506, 0, -506, 0, 0, 0, -506, -506, 0, -506, -506, -506, -506, // State 1070 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -864, 0, 0, 0, 0, 0, 0, 0, 0, 0, -864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 388, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1071 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -471, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 389, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1072 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -412, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -350, 0, 0, 0, 0, 0, 0, -350, 0, -350, 0, 0, 0, -350, 0, 0, -350, 0, 0, 0, -350, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -350, 0, -350, -350, -350, -350, 0, 0, 0, 0, 0, -350, -350, -350, -350, 0, -350, -350, -350, -350, 0, -350, -350, -350, -350, -350, -350, -350, -350, 0, 0, -350, -350, -350, -350, 0, -350, -350, -350, -350, -350, -350, -350, -350, -350, 0, 0, 0, -350, -350, 0, -350, 0, 0, 0, -350, -350, 0, -350, -350, -350, -350, // State 1073 - 0, 0, 0, 0, 0, 0, 0, -863, 0, 0, 0, 0, 0, 0, -863, 0, 0, 0, 0, 0, 0, 0, 0, 0, -863, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -863, 0, 0, 0, -863, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -863, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -863, 0, -863, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1074 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -865, 0, 0, 0, 0, 0, 0, 0, 0, 0, -865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -826, 0, -826, 0, 0, 0, -826, 0, 0, -826, 0, 0, 0, -826, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -826, 0, -826, -826, -826, -826, 0, 0, 0, 0, 0, -826, -826, -826, -826, 0, -826, -826, -826, -826, 0, 0, 0, 0, -826, -826, -826, -826, -826, 0, 0, -826, -826, -826, -826, 0, -826, -826, -826, -826, -826, -826, -826, -826, -826, 0, 0, 0, -826, -826, 0, -826, 0, 0, 0, -826, -826, 0, -826, -826, -826, -826, // State 1075 - 0, 0, 0, 0, 0, 0, 0, 1103, 0, 0, 0, 0, 0, 0, 1104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -834, 0, -834, 0, 0, 0, -834, 0, 0, -834, 0, 0, 0, -834, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -834, 0, -834, -834, -834, -834, 0, 0, 0, 0, 0, -834, -834, -834, -834, 0, -834, -834, -834, -834, 0, 0, 0, 0, -834, -834, -834, -834, -834, 0, 0, -834, -834, -834, -834, 0, -834, -834, -834, -834, -834, -834, -834, -834, -834, 0, 0, 0, -834, -834, 0, -834, 0, 0, 0, -834, -834, 0, -834, -834, -834, -834, // State 1076 - 0, 0, 0, 0, 0, 0, 0, -753, 0, 0, 0, 0, 0, 0, -753, 0, 0, 0, 0, 0, 0, 0, 0, 0, -753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -753, 0, 0, 0, -753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -753, 0, -753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1125, 0, 0, 0, 0, 0, 0, -135, 0, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -135, -135, -135, -135, 0, 0, 0, 0, 0, -135, 0, -135, -135, 0, 0, -135, 0, -135, 0, 0, 0, 0, 0, -135, -135, 0, -135, 0, 0, -135, 0, -135, -135, 0, -135, -135, -135, 0, -135, 0, 0, -135, -135, 0, 0, 0, -135, 0, 0, -135, 0, 0, 0, -135, -135, 0, -135, -135, -135, -135, // State 1077 - 0, 0, 0, 0, 0, 0, -127, 1105, -127, 0, 0, 0, 0, 0, 0, -127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -127, -127, -127, -127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -127, 0, 0, 0, 0, 0, 0, 0, 0, -127, -127, -127, 0, -127, -127, + 0, 0, 0, 0, 0, 0, 0, -831, 0, -831, 0, 0, 0, -831, 0, 0, -831, 0, 0, 0, -831, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -831, 0, -831, -831, -831, -831, 0, 0, 0, 0, 0, -831, -831, -831, -831, 0, -831, -831, -831, -831, 0, 0, 0, 0, -831, -831, -831, -831, -831, 0, 0, -831, -831, -831, -831, 0, -831, -831, -831, -831, -831, -831, -831, -831, -831, 0, 0, 0, -831, -831, 0, -831, 0, 0, 0, -831, -831, 0, -831, -831, -831, -831, // State 1078 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -193, -193, 0, -193, 0, -193, 0, -193, -193, 0, 0, -193, 0, -193, -193, 0, 0, -193, 0, -193, -193, 0, 0, -220, 0, 0, -193, -193, 0, -193, 0, -193, -193, -193, -193, 0, 0, -193, 0, 0, 0, 0, -193, 0, -193, 0, -193, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -193, 0, -193, -193, 0, 0, 0, -193, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, -193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1079 - 0, 0, 0, 0, 0, 0, 0, -761, 0, 0, 0, 0, 0, 0, -761, 0, 0, 0, 0, 0, 0, 0, 0, 0, -761, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -761, 0, 0, 0, -761, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -761, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -761, 0, -761, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -931, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1080 - 0, 0, 0, 0, 0, 0, -127, 0, -127, 0, 0, 0, 0, 0, 0, -127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -127, -127, -127, -127, -127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -127, 0, 0, 0, 0, 0, 0, 0, 0, -127, -127, -127, 0, -127, -127, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1126, 0, 0, 0, 0, 0, 0, 0, 0, 0, -688, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1081 - 0, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1128, 0, 0, 0, 0, 0, 0, 0, 0, 0, -679, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1082 - 0, 0, 0, 0, 0, 0, 0, -465, 0, 0, 0, 0, 0, 0, -465, 0, 0, 0, 0, 0, 0, 0, 0, 0, -465, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -465, 0, 0, 0, -465, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -465, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -465, 0, -465, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -655, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1083 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -660, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1084 - -348, 0, 0, 0, 0, 0, -348, 0, -348, 0, 0, 0, -348, 0, 0, -348, 0, 0, 0, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -348, 0, -348, -348, -348, -348, 0, 0, 0, 0, 0, -348, -348, -348, -348, 0, -348, -348, -348, -348, 0, -348, -348, -348, -348, -348, -348, -348, -348, 0, 0, -348, -348, -348, -348, 0, -348, -348, -348, -348, -348, -348, -348, -348, -348, 0, 0, 0, -348, -348, 0, 0, 0, -348, -348, -348, -348, -348, -348, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1129, 0, 0, 0, 0, 0, 0, 0, 0, 0, -684, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1085 - 0, 0, 0, 0, 0, 0, -807, 0, -807, 0, 0, 0, -807, 0, 0, -807, 0, 0, 0, -807, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -807, 0, -807, -807, -807, -807, 0, 0, 0, 0, 0, -807, -807, -807, -807, 0, -807, -807, -807, -807, 0, 0, 0, 0, -807, -807, -807, -807, -807, 0, 0, -807, -807, -807, -807, 0, -807, -807, -807, -807, -807, -807, -807, -807, -807, 0, 0, 0, -807, -807, 0, 0, 0, -807, -807, -807, -807, -807, -807, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -651, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1086 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -410, 0, 0, 0, 0, 0, 0, -410, 0, -410, 0, 0, 0, -410, 0, 0, -410, 0, 0, 0, -410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -410, 0, -410, -410, -410, -410, 0, 0, 0, 0, 0, -410, -410, -410, -410, 0, -410, -410, -410, -410, 0, 0, 0, 0, -410, -410, -410, -410, -410, 0, 0, -410, -410, -410, -410, 0, -410, -410, -410, -410, -410, -410, -410, -410, -410, 0, 0, 0, -410, -410, 0, -410, 0, 0, 0, -410, -410, 0, -410, -410, -410, -410, // State 1087 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1116, 0, 0, 0, 0, 0, 0, 0, 0, 0, -660, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -417, 0, 0, 0, 0, 0, 0, -417, 0, -417, 0, 0, 0, -417, 0, 0, -417, 0, 0, 0, -417, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -417, 0, -417, -417, -417, -417, 0, 0, 0, 0, 0, -417, -417, -417, -417, 0, -417, -417, -417, -417, 0, 0, 0, 0, -417, -417, -417, -417, -417, 0, 0, -417, -417, -417, -417, 0, -417, -417, -417, -417, -417, -417, -417, -417, -417, 0, 0, 0, -417, -417, 0, -417, 0, 0, 0, -417, -417, 0, -417, -417, -417, -417, // State 1088 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -627, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -407, 0, 0, 0, 0, 0, 0, -407, 0, -407, 0, 0, 0, -407, 0, 0, -407, 0, 0, 0, -407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -407, 0, -407, -407, -407, -407, 0, 0, 0, 0, 0, -407, -407, -407, -407, 0, -407, -407, -407, -407, 0, 0, 0, 0, -407, -407, -407, -407, -407, 0, 0, -407, -407, -407, -407, 0, -407, -407, -407, -407, -407, -407, -407, -407, -407, 0, 0, 0, -407, -407, 0, -407, 0, 0, 0, -407, -407, 0, -407, -407, -407, -407, // State 1089 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -608, 0, 0, 0, 0, 0, 0, 1132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1090 - -386, 0, 0, 0, 0, 0, -386, 0, -386, 0, 0, 0, -386, 0, 0, -386, 0, 0, 0, -386, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -386, 0, -386, -386, -386, -386, 0, 0, 0, 0, 0, -386, -386, -386, -386, 0, -386, -386, -386, -386, 0, 0, 0, 0, -386, -386, -386, -386, -386, 0, 0, -386, -386, -386, -386, 0, -386, -386, -386, -386, -386, -386, -386, -386, -386, 0, 0, 0, -386, -386, 0, 0, 0, -386, -386, -386, -386, -386, -386, + 0, 0, 0, 0, 0, 0, 0, 0, -599, 0, 0, 0, 0, 0, 0, 1134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1091 - -380, 0, 0, 0, 0, 0, -380, 0, -380, 0, 0, 0, -380, 0, 0, -380, 0, 0, 0, -380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -380, 0, -380, -380, -380, -380, 0, 0, 0, 0, 0, -380, -380, -380, -380, 0, -380, -380, -380, -380, 0, 0, 0, 0, -380, -380, -380, -380, -380, 0, 0, -380, -380, -380, -380, 0, -380, -380, -380, -380, -380, -380, -380, -380, -380, 0, 0, 0, -380, -380, 0, 0, 0, -380, -380, -380, -380, -380, -380, + 0, 0, 0, 0, 0, 0, 0, 0, -575, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1092 - 0, 0, 0, 0, 0, 0, 0, -556, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -631, 0, 0, 0, 0, 0, 0, 1135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1093 - 0, 0, 0, 0, 0, 0, 0, -580, 0, 0, 0, 0, 0, 0, 1117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -627, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1094 - 0, 0, 0, 0, 0, 0, 0, -547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -621, 0, 0, 0, 0, 0, 0, 393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1095 - 0, 0, 0, 0, 0, 0, 0, -603, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -634, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1096 - 0, 0, 0, 0, 0, 0, 0, -597, 0, 0, 0, 0, 0, 0, 384, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -405, 0, 0, 0, 0, 0, 0, -405, 0, -405, 0, 0, 0, -405, 0, 0, -405, 0, 0, 0, -405, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -405, 0, -405, -405, -405, -405, 0, 0, 0, 0, 0, -405, -405, -405, -405, 0, -405, -405, -405, -405, 0, 0, 0, 0, -405, -405, -405, -405, -405, 0, 0, -405, -405, -405, -405, 0, -405, -405, -405, -405, -405, -405, -405, -405, -405, 0, 0, 0, -405, -405, 0, -405, 0, 0, 0, -405, -405, 0, -405, -405, -405, -405, // State 1097 - 0, 0, 0, 0, 0, 0, 0, -593, 0, 0, 0, 0, 0, 0, 386, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -108, 0, 0, 0, 0, 0, 0, -108, 0, -108, 0, 0, 0, -108, 0, 0, -108, 0, 0, 0, -108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -108, 0, -108, -108, -108, -108, 0, 0, 0, 0, 0, -108, -108, -108, -108, 0, -108, -108, -108, -108, -108, -108, 0, 0, -108, -108, -108, -108, -108, 0, 0, -108, -108, -108, -108, 0, -108, -108, -108, -108, -108, -108, -108, -108, -108, 0, 0, 0, -108, -108, 0, -108, 0, 0, 0, -108, -108, 0, -108, -108, -108, -108, // State 1098 - 0, 0, 0, 0, 0, 0, 0, -578, 0, 0, 0, 0, 0, 0, 1122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -894, 0, -894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1099 - 0, 0, 0, 0, 0, 0, 0, -733, 0, 0, 0, 0, 0, 0, -733, 0, 0, 0, 0, 0, 0, 0, 0, 0, -733, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -733, 0, 0, 0, -733, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -733, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -733, 0, -733, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, -153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -153, 0, -153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1100 - 0, 0, 0, 0, 0, 0, 0, -731, 0, 0, 0, 0, 0, 0, -731, 0, 0, 0, 0, 0, 0, 0, 0, 0, -731, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -731, 0, 0, 0, -731, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -731, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -731, 0, -731, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -501, -264, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, -501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1101 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -470, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -538, 0, 0, 0, 0, 0, 0, -538, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1102 - 0, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1139, 0, 0, 0, 0, 0, 0, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1103 - 0, 0, 0, 0, 0, 0, -128, 1130, -128, 0, 0, 0, 0, 0, 0, -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -128, -128, -128, -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -128, 0, 0, 0, 0, 0, 0, 0, 0, -128, -128, -128, 0, -128, -128, + 0, 0, 0, 0, 0, 0, 0, 0, 1140, 0, 0, 0, 0, 0, 0, 397, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1104 - 0, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -546, 0, 0, 0, 0, 0, 0, -546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1105 - 0, 0, 0, 0, 0, 0, -128, 0, -128, 0, 0, 0, 0, 0, 0, -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -128, -128, -128, -128, -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -128, 0, 0, 0, 0, 0, 0, 0, 0, -128, -128, -128, 0, -128, -128, + 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -759, 0, -759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1106 - 0, 0, 0, 0, 0, 0, 0, -760, 0, 0, 0, 0, 0, 0, -760, 0, 0, 0, 0, 0, 0, 0, 0, 0, -760, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -760, 0, 0, 0, -760, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -760, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -760, 0, -760, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -502, -502, 0, 0, 0, 0, 0, 0, -502, 0, 0, 0, -502, 0, 0, 0, 0, 0, -502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -502, 0, 0, 0, -502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -502, 0, -502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1107 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -503, -503, 0, 0, 0, 0, 0, 0, -503, 0, 0, 0, -503, 0, 0, 0, 0, 0, -503, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -503, 0, 0, 0, -503, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -503, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -503, 0, -503, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1108 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1109 - 0, 0, 0, 0, 0, 0, 0, -464, 0, 0, 0, 0, 0, 0, -464, 0, 0, 0, 0, 0, 0, 0, 0, 0, -464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -464, 0, 0, 0, -464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -464, 0, -464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -896, 0, 0, 0, 0, 0, 0, 0, 0, 0, -896, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -896, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1110 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1111 - 0, 0, 0, 0, 0, 0, 0, -467, 0, 0, 0, 0, 0, 0, -467, 0, 0, 0, 0, 0, 0, 0, 0, 0, -467, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -467, 0, 0, 0, -467, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -467, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -467, 0, -467, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -435, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1112 - -853, 0, 0, 0, 0, 0, -853, 0, -853, 0, 0, 0, -853, 0, 0, -853, 0, 0, 0, -853, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -853, 0, -853, -853, -853, -853, 0, 0, 0, 0, 0, -853, -853, -853, -853, 0, -853, -853, -853, -853, 0, 0, 0, 0, -853, -853, -853, -853, -853, 0, 0, -853, -853, -853, -853, 0, -853, -853, -853, -853, -853, -853, -853, -853, -853, 0, 0, 0, -853, -853, 0, 0, 0, -853, -853, -853, -853, -853, -853, + 0, 0, 0, 0, 0, 0, 0, 0, -895, 0, 0, 0, 0, 0, 0, -895, 0, 0, 0, 0, 0, 0, 0, 0, 0, -895, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -895, 0, 0, 0, -895, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -895, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -895, 0, -895, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1113 - -857, 0, 0, 0, 0, 0, -857, 0, -857, 0, 0, 0, -857, 0, 0, -857, 0, 0, 0, -857, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -857, 0, -857, -857, -857, -857, 0, 0, 0, 0, 0, -857, -857, -857, -857, 0, -857, -857, -857, -857, 0, 0, 0, 0, -857, -857, -857, -857, -857, 0, 0, -857, -857, -857, -857, 0, -857, -857, -857, -857, -857, -857, -857, -857, -857, 0, 0, 0, -857, -857, 0, 0, 0, -857, -857, -857, -857, -857, -857, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -897, 0, 0, 0, 0, 0, 0, 0, 0, 0, -897, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -897, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1114 - -352, 0, 0, 0, 0, 0, -352, 0, -352, 0, 0, 0, -352, 0, 0, -352, 0, 0, 0, -352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -352, 0, -352, -352, -352, -352, 0, 0, 0, 0, 0, -352, -352, -352, -352, 0, -352, -352, -352, -352, 0, -352, -352, -352, -352, -352, -352, -352, -352, 0, 0, -352, -352, -352, -352, 0, -352, -352, -352, -352, -352, -352, -352, -352, -352, 0, 0, 0, -352, -352, 0, 0, 0, -352, -352, -352, -352, -352, -352, + 0, 0, 0, 0, 0, 0, 0, 0, 1142, 0, 0, 0, 0, 0, 0, 1143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1115 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -633, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -778, 0, 0, 0, 0, 0, 0, -778, 0, 0, 0, 0, 0, 0, 0, 0, 0, -778, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -778, 0, 0, 0, -778, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -778, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -778, 0, -778, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1116 - 0, 0, 0, 0, 0, 0, 0, -553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -129, 1144, -129, 0, 0, 0, 0, 0, 0, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, -129, -129, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, -129, 0, -129, 0, -129, -129, // State 1117 - 0, 0, 0, 0, 0, 0, 0, -594, 0, 0, 0, 0, 0, 0, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1118 - 0, 0, 0, 0, 0, 0, 0, -579, 0, 0, 0, 0, 0, 0, 1135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -786, 0, 0, 0, 0, 0, 0, -786, 0, 0, 0, 0, 0, 0, 0, 0, 0, -786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -786, 0, 0, 0, -786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -786, 0, -786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1119 - 0, 0, 0, 0, 0, 0, 0, -584, 0, 0, 0, 0, 0, 0, 1136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -129, 0, -129, 0, 0, 0, 0, 0, 0, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, -129, -129, -129, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -129, -129, 0, -129, 0, -129, -129, // State 1120 - 0, 0, 0, 0, 0, 0, 0, -575, 0, 0, 0, 0, 0, 0, 1138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -783, 0, 0, 0, 0, 0, 0, -783, 0, 0, 0, 0, 0, 0, 0, 0, 0, -783, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -783, 0, 0, 0, -783, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -783, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -783, 0, -783, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1121 - 0, 0, 0, 0, 0, 0, 0, -551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -490, 0, 0, 0, 0, 0, 0, -490, 0, 0, 0, 0, 0, 0, 0, 0, 0, -490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -490, 0, 0, 0, -490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -490, 0, -490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1122 - 0, 0, 0, 0, 0, 0, 0, -474, 0, 0, 0, 0, 0, 0, -474, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1123 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -347, 0, 0, 0, 0, 0, 0, -347, 0, -347, 0, 0, 0, -347, 0, 0, -347, 0, 0, 0, -347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -347, 0, -347, -347, -347, -347, 0, 0, 0, 0, 0, -347, -347, -347, -347, 0, -347, -347, -347, -347, 0, -347, -347, -347, -347, -347, -347, -347, -347, 0, 0, -347, -347, -347, -347, 0, -347, -347, -347, -347, -347, -347, -347, -347, -347, 0, 0, 0, -347, -347, 0, -347, 0, 0, 0, -347, -347, 0, -347, -347, -347, -347, // State 1124 - 0, 0, 0, 0, 0, 0, 0, -514, 0, 0, 0, 0, 0, 0, -514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -832, 0, -832, 0, 0, 0, -832, 0, 0, -832, 0, 0, 0, -832, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -832, 0, -832, -832, -832, -832, 0, 0, 0, 0, 0, -832, -832, -832, -832, 0, -832, -832, -832, -832, 0, 0, 0, 0, -832, -832, -832, -832, -832, 0, 0, -832, -832, -832, -832, 0, -832, -832, -832, -832, -832, -832, -832, -832, -832, 0, 0, 0, -832, -832, 0, -832, 0, 0, 0, -832, -832, 0, -832, -832, -832, -832, // State 1125 - 0, 0, 0, 0, 0, 0, 0, -732, 0, 0, 0, 0, 0, 0, -732, 0, 0, 0, 0, 0, 0, 0, 0, 0, -732, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -732, 0, 0, 0, -732, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -732, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -732, 0, -732, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -661, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1126 - 0, 0, 0, 0, 0, 0, 0, 1139, 0, 0, 0, 0, 0, 0, 388, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1155, 0, 0, 0, 0, 0, 0, 0, 0, 0, -685, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1127 - 0, 0, 0, 0, 0, 0, 0, -522, 0, 0, 0, 0, 0, 0, -522, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1128 - 0, 0, 0, 0, 0, 0, 0, -730, 0, 0, 0, 0, 0, 0, -730, 0, 0, 0, 0, 0, 0, 0, 0, 0, -730, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -730, 0, 0, 0, -730, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -730, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -730, 0, -730, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -657, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1129 - 0, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -409, 0, 0, 0, 0, 0, 0, -409, 0, -409, 0, 0, 0, -409, 0, 0, -409, 0, 0, 0, -409, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -409, 0, -409, -409, -409, -409, 0, 0, 0, 0, 0, -409, -409, -409, -409, 0, -409, -409, -409, -409, 0, 0, 0, 0, -409, -409, -409, -409, -409, 0, 0, -409, -409, -409, -409, 0, -409, -409, -409, -409, -409, -409, -409, -409, -409, 0, 0, 0, -409, -409, 0, -409, 0, 0, 0, -409, -409, 0, -409, -409, -409, -409, // State 1130 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -403, 0, 0, 0, 0, 0, 0, -403, 0, -403, 0, 0, 0, -403, 0, 0, -403, 0, 0, 0, -403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -403, 0, -403, -403, -403, -403, 0, 0, 0, 0, 0, -403, -403, -403, -403, 0, -403, -403, -403, -403, 0, 0, 0, 0, -403, -403, -403, -403, -403, 0, 0, -403, -403, -403, -403, 0, -403, -403, -403, -403, -403, -403, -403, -403, -403, 0, 0, 0, -403, -403, 0, -403, 0, 0, 0, -403, -403, 0, -403, -403, -403, -403, // State 1131 - 0, 0, 0, 0, 0, 0, 0, -466, 0, 0, 0, 0, 0, 0, -466, 0, 0, 0, 0, 0, 0, 0, 0, 0, -466, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -466, 0, 0, 0, -466, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -466, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -466, 0, -466, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -581, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1132 - 0, 0, 0, 0, 0, 0, 0, -585, 0, 0, 0, 0, 0, 0, 1142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -605, 0, 0, 0, 0, 0, 0, 1156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1133 - 0, 0, 0, 0, 0, 0, 0, -576, 0, 0, 0, 0, 0, 0, 1144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1134 - 0, 0, 0, 0, 0, 0, 0, -552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1135 - 0, 0, 0, 0, 0, 0, 0, -557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -622, 0, 0, 0, 0, 0, 0, 399, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1136 - 0, 0, 0, 0, 0, 0, 0, -581, 0, 0, 0, 0, 0, 0, 1145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -618, 0, 0, 0, 0, 0, 0, 401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1137 - 0, 0, 0, 0, 0, 0, 0, -548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -603, 0, 0, 0, 0, 0, 0, 1161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1138 - 0, 0, 0, 0, 0, 0, 0, -729, 0, 0, 0, 0, 0, 0, -729, 0, 0, 0, 0, 0, 0, 0, 0, 0, -729, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -729, 0, 0, 0, -729, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -729, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -729, 0, -729, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -758, 0, -758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1139 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -756, 0, -756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1140 - 0, 0, 0, 0, 0, 0, 0, -469, 0, 0, 0, 0, 0, 0, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -469, 0, 0, 0, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -469, 0, -469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1141 - 0, 0, 0, 0, 0, 0, 0, -558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -782, 0, 0, 0, 0, 0, 0, -782, 0, 0, 0, 0, 0, 0, 0, 0, 0, -782, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -782, 0, 0, 0, -782, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -782, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -782, 0, -782, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1142 - 0, 0, 0, 0, 0, 0, 0, -582, 0, 0, 0, 0, 0, 0, 1148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -130, 1169, -130, 0, 0, 0, 0, 0, 0, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, -130, -130, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, -130, 0, -130, 0, -130, -130, // State 1143 - 0, 0, 0, 0, 0, 0, 0, -549, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -780, 0, 0, 0, 0, 0, 0, -780, 0, 0, 0, 0, 0, 0, 0, 0, 0, -780, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -780, 0, 0, 0, -780, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -780, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -780, 0, -780, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1144 - 0, 0, 0, 0, 0, 0, 0, -554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -130, 0, -130, 0, 0, 0, 0, 0, 0, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, -130, -130, -130, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -130, -130, 0, -130, 0, -130, -130, // State 1145 - 0, 0, 0, 0, 0, 0, 0, -728, 0, 0, 0, 0, 0, 0, -728, 0, 0, 0, 0, 0, 0, 0, 0, 0, -728, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -728, 0, 0, 0, -728, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -728, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -728, 0, -728, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -785, 0, 0, 0, 0, 0, 0, -785, 0, 0, 0, 0, 0, 0, 0, 0, 0, -785, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -785, 0, 0, 0, -785, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -785, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -785, 0, -785, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1146 - 0, 0, 0, 0, 0, 0, 0, -468, 0, 0, 0, 0, 0, 0, -468, 0, 0, 0, 0, 0, 0, 0, 0, 0, -468, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -468, 0, 0, 0, -468, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -468, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -468, 0, -468, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 1147 - 0, 0, 0, 0, 0, 0, 0, -555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -541, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -541, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1148 + 0, 0, 0, 0, 0, 0, 0, 0, -489, 0, 0, 0, 0, 0, 0, -489, 0, 0, 0, 0, 0, 0, 0, 0, 0, -489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -489, 0, 0, 0, -489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -489, 0, -489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1149 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1150 + 0, 0, 0, 0, 0, 0, 0, 0, -492, 0, 0, 0, 0, 0, 0, -492, 0, 0, 0, 0, 0, 0, 0, 0, 0, -492, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -492, 0, 0, 0, -492, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -492, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -492, 0, -492, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1151 + -885, 0, 0, 0, 0, 0, 0, -885, 0, -885, 0, 0, 0, -885, 0, 0, -885, 0, 0, 0, -885, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -885, 0, -885, -885, -885, -885, 0, 0, 0, 0, 0, -885, -885, -885, -885, 0, -885, -885, -885, -885, 0, 0, 0, 0, -885, -885, -885, -885, -885, 0, 0, -885, -885, -885, -885, 0, -885, -885, -885, -885, -885, -885, -885, -885, -885, 0, 0, 0, -885, -885, 0, -885, 0, 0, 0, -885, -885, 0, -885, -885, -885, -885, + // State 1152 + -889, 0, 0, 0, 0, 0, 0, -889, 0, -889, 0, 0, 0, -889, 0, 0, -889, 0, 0, 0, -889, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -889, 0, -889, -889, -889, -889, 0, 0, 0, 0, 0, -889, -889, -889, -889, 0, -889, -889, -889, -889, 0, 0, 0, 0, -889, -889, -889, -889, -889, 0, 0, -889, -889, -889, -889, 0, -889, -889, -889, -889, -889, -889, -889, -889, -889, 0, 0, 0, -889, -889, 0, -889, 0, 0, 0, -889, -889, 0, -889, -889, -889, -889, + // State 1153 + -351, 0, 0, 0, 0, 0, 0, -351, 0, -351, 0, 0, 0, -351, 0, 0, -351, 0, 0, 0, -351, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -351, 0, -351, -351, -351, -351, 0, 0, 0, 0, 0, -351, -351, -351, -351, 0, -351, -351, -351, -351, 0, -351, -351, -351, -351, -351, -351, -351, -351, 0, 0, -351, -351, -351, -351, 0, -351, -351, -351, -351, -351, -351, -351, -351, -351, 0, 0, 0, -351, -351, 0, -351, 0, 0, 0, -351, -351, 0, -351, -351, -351, -351, + // State 1154 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -658, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1155 + 0, 0, 0, 0, 0, 0, 0, 0, -578, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1156 + 0, 0, 0, 0, 0, 0, 0, 0, -619, 0, 0, 0, 0, 0, 0, 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1157 + 0, 0, 0, 0, 0, 0, 0, 0, -604, 0, 0, 0, 0, 0, 0, 1174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1158 + 0, 0, 0, 0, 0, 0, 0, 0, -609, 0, 0, 0, 0, 0, 0, 1175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1159 + 0, 0, 0, 0, 0, 0, 0, 0, -600, 0, 0, 0, 0, 0, 0, 1177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1160 + 0, 0, 0, 0, 0, 0, 0, 0, -576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1161 + 0, 0, 0, 0, 0, 0, 0, 0, -499, 0, 0, 0, 0, 0, 0, -499, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1162 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1163 + 0, 0, 0, 0, 0, 0, 0, 0, -539, 0, 0, 0, 0, 0, 0, -539, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1164 + 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -757, 0, -757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1165 + 0, 0, 0, 0, 0, 0, 0, 0, 1178, 0, 0, 0, 0, 0, 0, 403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1166 + 0, 0, 0, 0, 0, 0, 0, 0, -547, 0, 0, 0, 0, 0, 0, -547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1167 + 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -755, 0, -755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1168 + 0, 0, 0, 0, 0, 0, 0, 0, -781, 0, 0, 0, 0, 0, 0, -781, 0, 0, 0, 0, 0, 0, 0, 0, 0, -781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -781, 0, 0, 0, -781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -781, 0, -781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1169 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1170 + 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -491, 0, -491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1171 + 0, 0, 0, 0, 0, 0, 0, 0, -610, 0, 0, 0, 0, 0, 0, 1181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1172 + 0, 0, 0, 0, 0, 0, 0, 0, -601, 0, 0, 0, 0, 0, 0, 1183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1173 + 0, 0, 0, 0, 0, 0, 0, 0, -577, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1174 + 0, 0, 0, 0, 0, 0, 0, 0, -582, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1175 + 0, 0, 0, 0, 0, 0, 0, 0, -606, 0, 0, 0, 0, 0, 0, 1184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1176 + 0, 0, 0, 0, 0, 0, 0, 0, -573, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1177 + 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -754, 0, -754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1178 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1179 + 0, 0, 0, 0, 0, 0, 0, 0, -494, 0, 0, 0, 0, 0, 0, -494, 0, 0, 0, 0, 0, 0, 0, 0, 0, -494, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -494, 0, 0, 0, -494, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -494, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -494, 0, -494, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1180 + 0, 0, 0, 0, 0, 0, 0, 0, -583, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1181 + 0, 0, 0, 0, 0, 0, 0, 0, -607, 0, 0, 0, 0, 0, 0, 1187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1182 + 0, 0, 0, 0, 0, 0, 0, 0, -574, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1183 + 0, 0, 0, 0, 0, 0, 0, 0, -579, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1184 + 0, 0, 0, 0, 0, 0, 0, 0, -753, 0, 0, 0, 0, 0, 0, -753, 0, 0, 0, 0, 0, 0, 0, 0, 0, -753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -753, 0, 0, 0, -753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -753, 0, -753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1185 + 0, 0, 0, 0, 0, 0, 0, 0, -493, 0, 0, 0, 0, 0, 0, -493, 0, 0, 0, 0, 0, 0, 0, 0, 0, -493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -493, 0, 0, 0, -493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -493, 0, -493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 1186 + 0, 0, 0, 0, 0, 0, 0, 0, -580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; fn __action(state: i16, integer: usize) -> i16 { - __ACTION[(state as usize) * 97 + integer] + __ACTION[(state as usize) * 101 + integer] } const __EOF_ACTION: &[i16] = &[ // State 0 @@ -2450,25 +2533,25 @@ mod __parse__Top { // State 1 0, // State 2 - -743, + -768, // State 3 0, // State 4 0, // State 5 - -765, + -790, // State 6 - -249, + -248, // State 7 - -305, + -304, // State 8 - -851, + -883, // State 9 - -156, + -155, // State 10 - -170, + -183, // State 11 - 0, + -169, // State 12 0, // State 13 @@ -2484,11 +2567,11 @@ mod __parse__Top { // State 18 0, // State 19 - -850, + 0, // State 20 0, // State 21 - 0, + -882, // State 22 0, // State 23 @@ -2498,17 +2581,17 @@ mod __parse__Top { // State 25 0, // State 26 - -304, + 0, // State 27 0, // State 28 - 0, + -303, // State 29 - -409, + 0, // State 30 0, // State 31 - 0, + -432, // State 32 0, // State 33 @@ -2524,11 +2607,11 @@ mod __parse__Top { // State 38 0, // State 39 - -248, + 0, // State 40 0, // State 41 - 0, + -247, // State 42 0, // State 43 @@ -2580,23 +2663,23 @@ mod __parse__Top { // State 66 0, // State 67 - -155, + 0, // State 68 - -169, + 0, // State 69 0, // State 70 0, // State 71 - 0, + -154, // State 72 - 0, + -168, // State 73 0, // State 74 0, // State 75 - -764, + 0, // State 76 0, // State 77 @@ -2604,7 +2687,7 @@ mod __parse__Top { // State 78 0, // State 79 - 0, + -789, // State 80 0, // State 81 @@ -2860,11 +2943,11 @@ mod __parse__Top { // State 206 0, // State 207 - -415, + 0, // State 208 - -856, + 0, // State 209 - -860, + 0, // State 210 0, // State 211 @@ -2886,11 +2969,11 @@ mod __parse__Top { // State 219 0, // State 220 - 0, + -438, // State 221 - 0, + -888, // State 222 - 0, + -892, // State 223 0, // State 224 @@ -3222,105 +3305,105 @@ mod __parse__Top { // State 387 0, // State 388 - -917, + 0, // State 389 - -184, + 0, // State 390 - -911, + 0, // State 391 - -534, + 0, // State 392 - -240, + 0, // State 393 - -740, + 0, // State 394 - -496, + 0, // State 395 - -185, + 0, // State 396 - -829, + 0, // State 397 - -186, + 0, // State 398 - -834, + 0, // State 399 - -160, + 0, // State 400 - -410, + 0, // State 401 - -833, + 0, // State 402 - -371, + 0, // State 403 - -846, + -949, // State 404 - -845, + -943, // State 405 - -525, + -559, // State 406 - -356, + -239, // State 407 - 0, + -765, // State 408 - 0, + -521, // State 409 - -212, + -184, // State 410 - -210, + -839, // State 411 - -211, + -861, // State 412 - -209, + -185, // State 413 - 0, + -866, // State 414 - -323, + -159, // State 415 - -322, + -433, // State 416 - -321, + -865, // State 417 - -413, + -394, // State 418 - -139, + -878, // State 419 - -533, + -838, // State 420 - -159, + -840, // State 421 - -140, + -877, // State 422 - 0, + -550, // State 423 - 0, + -355, // State 424 0, // State 425 - -241, - // State 426 0, + // State 426 + -211, // State 427 - 0, + -209, // State 428 - 0, + -210, // State 429 - 0, + -208, // State 430 0, // State 431 - 0, + -322, // State 432 - 0, + -321, // State 433 - 0, + -320, // State 434 - 0, + -436, // State 435 - -852, + -835, // State 436 - -88, + -558, // State 437 - 0, + -158, // State 438 0, // State 439 @@ -3328,7 +3411,7 @@ mod __parse__Top { // State 440 0, // State 441 - 0, + -240, // State 442 0, // State 443 @@ -3336,7 +3419,7 @@ mod __parse__Top { // State 444 0, // State 445 - -370, + 0, // State 446 0, // State 447 @@ -3348,17 +3431,17 @@ mod __parse__Top { // State 450 0, // State 451 - 0, + -884, // State 452 - 0, + -90, // State 453 - -200, + 0, // State 454 - -791, + 0, // State 455 0, // State 456 - 0, + -841, // State 457 0, // State 458 @@ -3368,9 +3451,9 @@ mod __parse__Top { // State 460 0, // State 461 - -188, - // State 462 0, + // State 462 + -393, // State 463 0, // State 464 @@ -3382,13 +3465,13 @@ mod __parse__Top { // State 467 0, // State 468 - -495, + 0, // State 469 0, // State 470 - 0, + -199, // State 471 - 0, + -816, // State 472 0, // State 473 @@ -3398,13 +3481,13 @@ mod __parse__Top { // State 475 0, // State 476 - -205, + 0, // State 477 0, // State 478 - -315, + -187, // State 479 - -744, + 0, // State 480 0, // State 481 @@ -3414,13 +3497,13 @@ mod __parse__Top { // State 483 0, // State 484 - -311, + 0, // State 485 - -314, + -520, // State 486 0, // State 487 - -309, + 0, // State 488 0, // State 489 @@ -3428,41 +3511,41 @@ mod __parse__Top { // State 490 0, // State 491 - -308, + 0, // State 492 0, // State 493 - 0, + -204, // State 494 0, // State 495 0, // State 496 - 0, + -372, // State 497 - -312, + 0, // State 498 0, // State 499 - -310, + -314, // State 500 - -313, + -769, // State 501 0, // State 502 - -749, + 0, // State 503 0, // State 504 0, // State 505 - 0, + -310, // State 506 - 0, + -313, // State 507 0, // State 508 - 0, + -308, // State 509 0, // State 510 @@ -3470,11 +3553,11 @@ mod __parse__Top { // State 511 0, // State 512 - 0, + -307, // State 513 - -164, + 0, // State 514 - -243, + 0, // State 515 0, // State 516 @@ -3482,29 +3565,29 @@ mod __parse__Top { // State 517 0, // State 518 - 0, + -311, // State 519 0, // State 520 - -739, + -309, // State 521 - -142, + -312, // State 522 0, // State 523 - 0, + -774, // State 524 - -355, + 0, // State 525 - -89, + 0, // State 526 - -526, + 0, // State 527 0, // State 528 - -828, + 0, // State 529 - -910, + 0, // State 530 0, // State 531 @@ -3514,39 +3597,39 @@ mod __parse__Top { // State 533 0, // State 534 - -197, + -163, // State 535 - -191, + -242, // State 536 - -201, + 0, // State 537 0, // State 538 0, // State 539 - -187, + 0, // State 540 0, // State 541 - 0, + -764, // State 542 - 0, + -141, // State 543 0, // State 544 0, // State 545 - -445, + -354, // State 546 - 0, + -91, // State 547 - -204, + -551, // State 548 0, // State 549 - -207, + -860, // State 550 - 0, + -942, // State 551 0, // State 552 @@ -3556,17 +3639,17 @@ mod __parse__Top { // State 554 0, // State 555 - 0, + -196, // State 556 - 0, + -190, // State 557 - 0, + -200, // State 558 0, // State 559 0, // State 560 - 0, + -186, // State 561 0, // State 562 @@ -3578,21 +3661,21 @@ mod __parse__Top { // State 565 0, // State 566 - 0, + -470, // State 567 0, // State 568 - 0, + -203, // State 569 0, // State 570 - -747, + -206, // State 571 0, // State 572 0, // State 573 - 0, + -373, // State 574 0, // State 575 @@ -3636,7 +3719,7 @@ mod __parse__Top { // State 594 0, // State 595 - 0, + -772, // State 596 0, // State 597 @@ -3710,9 +3793,9 @@ mod __parse__Top { // State 631 0, // State 632 - -166, + 0, // State 633 - -163, + 0, // State 634 0, // State 635 @@ -3722,45 +3805,45 @@ mod __parse__Top { // State 637 0, // State 638 - -242, + 0, // State 639 0, // State 640 - -143, + 0, // State 641 0, // State 642 - -202, + 0, // State 643 0, // State 644 0, // State 645 - -199, + 0, // State 646 0, // State 647 - -193, + 0, // State 648 0, // State 649 0, // State 650 - -190, + 0, // State 651 - -203, + 0, // State 652 0, // State 653 0, // State 654 - -189, + 0, // State 655 0, // State 656 - 0, + -165, // State 657 - -444, + -162, // State 658 0, // State 659 @@ -3770,45 +3853,45 @@ mod __parse__Top { // State 661 0, // State 662 - -206, + -241, // State 663 - -208, - // State 664 0, + // State 664 + -142, // State 665 0, // State 666 - 0, + -201, // State 667 0, // State 668 - -748, - // State 669 0, + // State 669 + -198, // State 670 0, // State 671 - 0, + -192, // State 672 0, // State 673 0, // State 674 - 0, + -189, // State 675 - 0, + -202, // State 676 0, // State 677 0, // State 678 - -745, + -188, // State 679 0, // State 680 0, // State 681 - 0, + -468, // State 682 0, // State 683 @@ -3818,11 +3901,11 @@ mod __parse__Top { // State 685 0, // State 686 - 0, + -469, // State 687 - 0, + -205, // State 688 - 0, + -207, // State 689 0, // State 690 @@ -3838,7 +3921,7 @@ mod __parse__Top { // State 695 0, // State 696 - 0, + -773, // State 697 0, // State 698 @@ -3854,13 +3937,13 @@ mod __parse__Top { // State 703 0, // State 704 - 0, + -770, // State 705 0, // State 706 0, // State 707 - -165, + 0, // State 708 0, // State 709 @@ -3876,17 +3959,17 @@ mod __parse__Top { // State 714 0, // State 715 - -832, + 0, // State 716 0, // State 717 0, // State 718 - -195, + 0, // State 719 0, // State 720 - -196, + 0, // State 721 0, // State 722 @@ -3902,7 +3985,7 @@ mod __parse__Top { // State 727 0, // State 728 - -746, + 0, // State 729 0, // State 730 @@ -3912,11 +3995,11 @@ mod __parse__Top { // State 732 0, // State 733 - 0, + -164, // State 734 0, // State 735 - -271, + 0, // State 736 0, // State 737 @@ -3928,17 +4011,17 @@ mod __parse__Top { // State 740 0, // State 741 - 0, + -864, // State 742 0, // State 743 0, // State 744 - 0, + -194, // State 745 0, // State 746 - 0, + -195, // State 747 0, // State 748 @@ -3946,7 +4029,7 @@ mod __parse__Top { // State 749 0, // State 750 - 0, + -467, // State 751 0, // State 752 @@ -3970,25 +4053,25 @@ mod __parse__Top { // State 761 0, // State 762 - 0, + -771, // State 763 0, // State 764 0, // State 765 - -825, + 0, // State 766 0, // State 767 - -349, + 0, // State 768 - -353, - // State 769 0, + // State 769 + -270, // State 770 0, // State 771 - -889, + 0, // State 772 0, // State 773 @@ -4008,7 +4091,7 @@ mod __parse__Top { // State 780 0, // State 781 - -909, + 0, // State 782 0, // State 783 @@ -4042,27 +4125,27 @@ mod __parse__Top { // State 797 0, // State 798 - -198, + 0, // State 799 - -192, + -857, // State 800 0, // State 801 - 0, + -348, // State 802 - 0, + -352, // State 803 0, // State 804 0, // State 805 - 0, + -921, // State 806 0, // State 807 0, // State 808 - -273, + 0, // State 809 0, // State 810 @@ -4070,13 +4153,13 @@ mod __parse__Top { // State 811 0, // State 812 - -908, + 0, // State 813 - -267, + 0, // State 814 - -270, - // State 815 0, + // State 815 + -941, // State 816 0, // State 817 @@ -4084,7 +4167,7 @@ mod __parse__Top { // State 818 0, // State 819 - -397, + 0, // State 820 0, // State 821 @@ -4102,7 +4185,7 @@ mod __parse__Top { // State 827 0, // State 828 - -417, + 0, // State 829 0, // State 830 @@ -4110,19 +4193,19 @@ mod __parse__Top { // State 831 0, // State 832 - -826, + -197, // State 833 - 0, + -191, // State 834 - -823, + 0, // State 835 - -350, + 0, // State 836 0, // State 837 0, // State 838 - -354, + 0, // State 839 0, // State 840 @@ -4138,7 +4221,7 @@ mod __parse__Top { // State 845 0, // State 846 - 0, + -272, // State 847 0, // State 848 @@ -4146,11 +4229,11 @@ mod __parse__Top { // State 849 0, // State 850 - 0, + -940, // State 851 - 0, + -266, // State 852 - 0, + -269, // State 853 0, // State 854 @@ -4160,7 +4243,7 @@ mod __parse__Top { // State 856 0, // State 857 - 0, + -420, // State 858 0, // State 859 @@ -4168,7 +4251,7 @@ mod __parse__Top { // State 860 0, // State 861 - -194, + 0, // State 862 0, // State 863 @@ -4178,7 +4261,7 @@ mod __parse__Top { // State 865 0, // State 866 - 0, + -440, // State 867 0, // State 868 @@ -4186,19 +4269,19 @@ mod __parse__Top { // State 869 0, // State 870 - -269, + -858, // State 871 - -272, - // State 872 0, + // State 872 + -855, // State 873 - -399, + -349, // State 874 0, // State 875 - -389, + 0, // State 876 - -266, + -353, // State 877 0, // State 878 @@ -4208,7 +4291,7 @@ mod __parse__Top { // State 880 0, // State 881 - -396, + 0, // State 882 0, // State 883 @@ -4224,7 +4307,7 @@ mod __parse__Top { // State 888 0, // State 889 - -383, + 0, // State 890 0, // State 891 @@ -4240,13 +4323,13 @@ mod __parse__Top { // State 896 0, // State 897 - -824, + 0, // State 898 0, // State 899 - -347, + -193, // State 900 - -861, + 0, // State 901 0, // State 902 @@ -4258,25 +4341,25 @@ mod __parse__Top { // State 905 0, // State 906 - -827, + 0, // State 907 0, // State 908 0, // State 909 - 0, + -268, // State 910 - 0, + -271, // State 911 0, // State 912 - 0, + -422, // State 913 0, // State 914 - 0, + -412, // State 915 - 0, + -265, // State 916 0, // State 917 @@ -4286,7 +4369,7 @@ mod __parse__Top { // State 919 0, // State 920 - 0, + -419, // State 921 0, // State 922 @@ -4296,21 +4379,21 @@ mod __parse__Top { // State 924 0, // State 925 - -391, + 0, // State 926 - -268, + 0, // State 927 0, // State 928 - -398, + -406, // State 929 0, // State 930 - -388, + 0, // State 931 - -381, + 0, // State 932 - -393, + 0, // State 933 0, // State 934 @@ -4318,13 +4401,13 @@ mod __parse__Top { // State 935 0, // State 936 - 0, + -856, // State 937 0, // State 938 - 0, + -346, // State 939 - 0, + -893, // State 940 0, // State 941 @@ -4336,11 +4419,11 @@ mod __parse__Top { // State 944 0, // State 945 - -414, + -859, // State 946 0, // State 947 - -479, + 0, // State 948 0, // State 949 @@ -4374,27 +4457,27 @@ mod __parse__Top { // State 963 0, // State 964 - 0, + -414, // State 965 - 0, + -267, // State 966 0, // State 967 - 0, + -421, // State 968 0, // State 969 - -482, + -411, // State 970 - -854, + -404, // State 971 - -855, + -416, // State 972 - -858, + 0, // State 973 - -859, + 0, // State 974 - -346, + 0, // State 975 0, // State 976 @@ -4410,15 +4493,15 @@ mod __parse__Top { // State 981 0, // State 982 - -888, + 0, // State 983 0, // State 984 - 0, + -437, // State 985 0, // State 986 - 0, + -504, // State 987 0, // State 988 @@ -4434,15 +4517,15 @@ mod __parse__Top { // State 993 0, // State 994 - -390, + 0, // State 995 - -395, + 0, // State 996 - -385, + 0, // State 997 0, // State 998 - -392, + 0, // State 999 0, // State 1000 @@ -4458,21 +4541,21 @@ mod __parse__Top { // State 1005 0, // State 1006 - -416, + 0, // State 1007 - -105, + 0, // State 1008 - -480, + -507, // State 1009 - 0, + -886, // State 1010 - 0, + -887, // State 1011 - 0, + -890, // State 1012 - 0, + -891, // State 1013 - 0, + -345, // State 1014 0, // State 1015 @@ -4488,7 +4571,7 @@ mod __parse__Top { // State 1020 0, // State 1021 - 0, + -920, // State 1022 0, // State 1023 @@ -4506,21 +4589,21 @@ mod __parse__Top { // State 1029 0, // State 1030 - -481, + 0, // State 1031 0, // State 1032 0, // State 1033 - -351, + -413, // State 1034 - 0, + -418, // State 1035 - 0, + -408, // State 1036 0, // State 1037 - 0, + -415, // State 1038 0, // State 1039 @@ -4536,15 +4619,15 @@ mod __parse__Top { // State 1044 0, // State 1045 - 0, + -439, // State 1046 - 0, + -107, // State 1047 - -387, + -505, // State 1048 - -394, + 0, // State 1049 - -384, + 0, // State 1050 0, // State 1051 @@ -4560,9 +4643,9 @@ mod __parse__Top { // State 1056 0, // State 1057 - -382, + 0, // State 1058 - -106, + 0, // State 1059 0, // State 1060 @@ -4584,13 +4667,13 @@ mod __parse__Top { // State 1068 0, // State 1069 - 0, + -506, // State 1070 0, // State 1071 0, // State 1072 - 0, + -350, // State 1073 0, // State 1074 @@ -4614,21 +4697,21 @@ mod __parse__Top { // State 1083 0, // State 1084 - -348, + 0, // State 1085 0, // State 1086 - 0, + -410, // State 1087 - 0, + -417, // State 1088 - 0, + -407, // State 1089 0, // State 1090 - -386, + 0, // State 1091 - -380, + 0, // State 1092 0, // State 1093 @@ -4638,9 +4721,9 @@ mod __parse__Top { // State 1095 0, // State 1096 - 0, + -405, // State 1097 - 0, + -108, // State 1098 0, // State 1099 @@ -4670,11 +4753,11 @@ mod __parse__Top { // State 1111 0, // State 1112 - -853, + 0, // State 1113 - -857, + 0, // State 1114 - -352, + 0, // State 1115 0, // State 1116 @@ -4692,7 +4775,7 @@ mod __parse__Top { // State 1122 0, // State 1123 - 0, + -347, // State 1124 0, // State 1125 @@ -4704,9 +4787,9 @@ mod __parse__Top { // State 1128 0, // State 1129 - 0, + -409, // State 1130 - 0, + -403, // State 1131 0, // State 1132 @@ -4741,809 +4824,921 @@ mod __parse__Top { 0, // State 1147 0, + // State 1148 + 0, + // State 1149 + 0, + // State 1150 + 0, + // State 1151 + -885, + // State 1152 + -889, + // State 1153 + -351, + // State 1154 + 0, + // State 1155 + 0, + // State 1156 + 0, + // State 1157 + 0, + // State 1158 + 0, + // State 1159 + 0, + // State 1160 + 0, + // State 1161 + 0, + // State 1162 + 0, + // State 1163 + 0, + // State 1164 + 0, + // State 1165 + 0, + // State 1166 + 0, + // State 1167 + 0, + // State 1168 + 0, + // State 1169 + 0, + // State 1170 + 0, + // State 1171 + 0, + // State 1172 + 0, + // State 1173 + 0, + // State 1174 + 0, + // State 1175 + 0, + // State 1176 + 0, + // State 1177 + 0, + // State 1178 + 0, + // State 1179 + 0, + // State 1180 + 0, + // State 1181 + 0, + // State 1182 + 0, + // State 1183 + 0, + // State 1184 + 0, + // State 1185 + 0, + // State 1186 + 0, ]; fn __goto(state: i16, nt: usize) -> i16 { match nt { - 9 => match state { - 242 => 886, - 278 => 934, - 279 => 935, - 312 => 999, - 343 => 1055, - 366 => 1096, - 367 => 1097, - 375 => 1117, - _ => 822, + 10 => match state { + 255 => 925, + 291 => 973, + 292 => 974, + 325 => 1038, + 357 => 1094, + 381 => 1135, + 382 => 1136, + 390 => 1156, + _ => 860, }, - 12 => match state { - 86 => 659, - 130 => 722, - 131 => 723, - 186 => 800, - 226 => 867, - 266 => 921, - 267 => 922, - 303 => 988, - _ => 542, + 13 => match state { + 90 => 683, + 137 => 748, + 138 => 749, + 197 => 834, + 239 => 905, + 279 => 960, + 280 => 961, + 316 => 1027, + _ => 563, }, - 21 => match state { - 129 => 719, - 176 => 784, - 259 => 909, - _ => 533, + 22 => match state { + 136 => 745, + 187 => 818, + 272 => 948, + _ => 554, }, - 24 => match state { - 177 => 787, - 260 => 911, - _ => 696, + 25 => match state { + 188 => 821, + 273 => 950, + _ => 722, }, - 28 => 686, - 34 => 554, - 37 => 435, - 48 => 828, - 52 => match state { - 66 | 99 => 106, + 29 => 712, + 35 => 579, + 38 => 451, + 49 => 866, + 53 => match state { + 70 | 105 => 112, _ => 3, }, - 55 => 69, - 57 => match state { - 66 | 99 => 107, + 56 => 73, + 58 => match state { + 70 | 105 => 113, _ => 4, }, - 62 => match state { - 327 => 358, - _ => 357, + 63 => match state { + 341 => 372, + _ => 371, }, - 65 => match state { - 19 => 46, - 211 => 255, - 256 => 298, - _ => 157, + 66 => match state { + 21 => 50, + 224 => 268, + 269 => 311, + _ => 168, }, - 70 => match state { - 66 | 99 => 599, - 289 | 324 | 327 | 346 | 348 | 352 | 355..=358 | 370 | 379 | 381 => 948, - 328 | 371 => 1018, - _ => 389, + 71 => match state { + 116 => 177, + _ => 28, }, - 72 => match state { - 110 => 166, - _ => 26, + 78 => match state { + 114 => 173, + 333 | 373 => 361, + _ => 23, }, 79 => match state { - 108 => 162, - 320 | 359 => 347, - _ => 21, + 342 | 386 => 1058, + _ => 987, }, 80 => match state { - 328 | 371 => 1019, - _ => 949, - }, - 81 => match state { - 33 => 529, - 66 | 99 => 600, - 174 => 782, - _ => 390, + 35 => 550, + 70 | 105 => 624, + 185 => 816, + _ => 404, }, - 82 => 601, - 83 => match state { - 3 => 419, - 106 => 692, - _ => 391, + 81 => 625, + 82 => match state { + 3 => 436, + 112 => 718, + _ => 405, }, - 84 => 602, - 85 => match state { - 100 => 682, - 109 => 694, - 135 => 729, - 140 => 734, - 191 => 807, - _ => 425, + 83 => 626, + 84 => match state { + 106 => 708, + 115 => 720, + 146 => 763, + 151 => 768, + 204 => 845, + _ => 441, }, - 87 => match state { - 31 => 75, - 66 | 99 => 108, - 169 => 215, + 86 => match state { + 33 => 79, + 70 | 105 => 114, + 180 => 228, _ => 5, }, - 88 => 603, - 89 => 950, - 90 => 477, - 91 => match state { - 93 => 671, - 137 => 731, - _ => 556, + 87 => 627, + 88 => 988, + 89 => 498, + 90 => match state { + 99 => 699, + 148 => 765, + _ => 581, }, - 93 => 93, - 95 => 392, - 96 => 604, - 97 => match state { - 15 => 39, - 66 | 99 => 109, - 117 => 180, + 92 => 99, + 94 => 406, + 95 => 628, + 96 => match state { + 16 => 41, + 70 | 105 => 115, + 124 => 191, _ => 6, }, - 98 => 605, - 99 => match state { - 66 | 99 => 606, - _ => 393, + 97 => 629, + 98 => match state { + 70 | 105 => 630, + _ => 407, + }, + 99 => 631, + 100 => 100, + 101 => 989, + 102 => 499, + 103 => 990, + 104 => match state { + 360 => 1098, + 369 => 1112, + _ => 991, }, - 100 => 607, - 101 => 94, - 102 => 951, - 103 => 478, - 104 => 952, - 105 => match state { - 346 => 1059, - 355 => 1073, - _ => 953, + 107 => match state { + 40 => 561, + 45 => 567, + 46 => 569, + 74 => 659, + 186 => 817, + 190 => 826, + 192 => 827, + 193 => 829, + _ => 551, }, - 108 => match state { - 38 => 540, - 43 => 546, - 44 => 548, - 70 => 635, - 175 => 783, - 179 => 792, - 181 => 793, - 182 => 795, - _ => 530, + 109 => match state { + 28 | 177 => 78, + _ => 29, }, - 110 => match state { - 26 | 166 => 74, - _ => 27, + 110 => 408, + 111 => 632, + 112 => match state { + 224 => 881, + 269 => 943, + _ => 500, }, - 111 => 394, - 112 => 608, 113 => match state { - 211 => 843, - 256 => 904, - _ => 479, + 276 | 315 => 953, + _ => 898, }, - 114 => match state { - 263 | 302 => 914, - _ => 860, + 115 => match state { + 275 => 315, + _ => 276, }, 116 => match state { - 262 => 302, - _ => 263, + 70 | 105 => 633, + 302 | 338 | 340..=342 | 360..=362 | 366 | 369..=372 | 385..=386 | 394 | 396 => 992, + _ => 409, }, 117 => match state { - 66 | 99 => 609, - 289 | 324 | 326..=328 | 346..=348 | 352 | 355..=358 | 370..=371 | 379 | 381 => 954, - _ => 395, + 340 => 1055, + 361 => 1099, + _ => 993, }, 118 => match state { - 326 => 1015, - 347 => 1060, - _ => 955, + 342 | 386 => 373, + _ => 333, }, 119 => match state { - 328 | 371 => 359, - _ => 320, + 51 => 577, + _ => 501, }, - 120 => match state { - 47 => 552, - _ => 480, + 121 => 51, + 122 => 502, + 123 => match state { + 93 => 689, + _ => 486, }, - 122 => 47, - 123 => 481, 124 => match state { - 88 => 664, - _ => 469, + 126 => 192, + 93 => 690, + _ => 45, }, 125 => match state { - 119 => 181, - 88 => 665, - _ => 43, + 126 => 730, + _ => 487, }, - 126 => match state { - 119 => 704, - _ => 470, + 127 => match state { + 63 => 615, + 108 => 710, + 164 => 790, + _ => 607, }, - 128 => match state { - 59 => 590, - 102 => 684, - 153 => 756, - _ => 582, + 128 => 862, + 130 => match state { + 221 => 873, + _ => 801, }, - 129 => 824, - 131 => match state { - 208 => 835, - _ => 767, + 131 => 221, + 132 => match state { + 222 => 876, + _ => 802, }, - 132 => 208, - 133 => match state { - 209 => 838, - _ => 768, - }, - 134 => 209, - 135 => match state { - 19 | 46 | 104 | 141 | 151 | 157 | 160 | 173 | 192 | 196..=198 | 202 | 211 | 228..=229 | 231 | 233..=234 | 238 | 244 | 253..=256 | 270..=271 | 273 | 275..=277 | 286 | 292..=296 | 298..=299 | 308..=311 | 317..=318 | 330 | 337..=339 | 344..=345 | 353 | 361 | 363..=364 | 369 | 372..=374 => 48, - 66 | 99 => 110, - 13 => 454, - 27 => 521, - 36 => 537, - 45 => 550, - 54..=55 | 78 | 98 | 127 | 145 | 147 => 574, - 74 => 640, - 171 => 778, - 178 => 790, + 133 => 222, + 134 => match state { + 21 | 50 | 110 | 152 | 162 | 168 | 171 | 184 | 205 | 209..=211 | 215 | 224 | 241..=242 | 244 | 246..=247 | 251 | 257 | 266..=269 | 283..=284 | 286 | 288..=290 | 299 | 305..=309 | 311..=312 | 321..=324 | 330..=331 | 344 | 351..=353 | 358..=359 | 367 | 376 | 378..=379 | 384 | 387..=389 => 52, + 70 | 105 => 116, + 14 => 471, + 29 => 542, + 38 => 558, + 47 => 571, + 58..=59 | 82 | 104 | 134 | 156 | 158 => 599, + 78 => 664, + 182 => 812, + 189 => 824, _ => 7, }, - 136 => 610, - 137 => match state { - 78 => 644, - 98 => 680, - 127 => 716, - _ => 579, - }, - 138 => 575, - 139 => 915, - 140 => match state { - 145 | 147 => 747, - _ => 576, + 135 => 634, + 136 => match state { + 82 => 668, + 104 => 706, + 134 => 742, + _ => 604, }, - 141 => 482, - 142 => match state { - 11 => 445, - 25 => 520, - 32 => 528, - 113 => 695, - 165 => 774, - 170 => 777, - _ => 396, + 137 => 600, + 138 => 954, + 139 => match state { + 156 | 158 => 781, + _ => 601, }, - 143 => 611, - 144 => 483, - 145 => 484, - 146 => 485, - 147 => match state { - 69 => 631, - _ => 511, + 140 => 503, + 141 => match state { + 144 => 202, + _ => 142, }, - 149 => 580, - 150 => match state { - 1 => 8, - 37 => 538, - 63 => 596, - 94..=95 => 672, - 146 => 748, - 195 => 811, - _ => 49, + 143 => 410, + 144 => 759, + 145 => match state { + 142 => 755, + 144 => 760, + 202 => 841, + _ => 693, }, - 151 => 486, - 152 => 1011, - 153 => match state { - 52 => 100, - 53 => 101, - 91 => 135, - 92 => 136, - 97 => 139, - 134 => 190, - 12 | 14 | 18 | 24 | 50 | 58 | 60 | 65 | 79..=80 | 82 | 89 | 115..=116 | 119 | 121 | 123 | 128 | 154..=155 | 164 | 185 | 217..=218 | 222 | 247 | 258 | 285 | 300 | 332 | 354 => 446, - 16 | 83 | 87 | 132..=133 | 187..=189 | 223..=225 | 265 | 268 | 304..=306 | 334..=336 | 362 => 462, - 22 | 69 => 512, - 23 => 514, - 40..=41 | 130 | 226 | 266 => 543, - 57 | 61 => 587, - 64 => 597, - 66 | 99 => 612, - 142 | 236 => 736, - 144 | 240 | 243 | 280 | 282 | 313..=315 | 340..=342 | 365 | 368 | 376..=378 | 383..=386 => 740, - 148 | 205 => 749, - 149 => 753, - 150 => 754, - 152 => 755, - 163 => 772, - 199 => 816, - 200 => 817, - 203 | 278 | 343 | 366 => 823, - 204 => 825, - 206 => 827, - 245 => 890, - 246 | 284 => 891, - 248 => 895, - 289 | 324 | 327 | 346 | 352 | 355..=358 | 370 | 379 => 956, - 297 => 975, - 316 => 1005, - 325 => 1014, - 328 | 371 => 1020, - 331 => 1034, - 348 | 381 => 1061, - 349 => 1067, - 350 => 1068, - 351 => 1069, - 360 => 1083, - 380 | 387 => 1123, - 382 => 1130, - _ => 397, + 147 => match state { + 48 | 201 => 572, + _ => 494, }, - 154 => 487, - 157 => 750, - 158 => match state { - 102 => 685, - _ => 583, + 149 => match state { + 143 => 201, + _ => 48, }, - 160 => 102, - 161 => 584, - 162 => 488, - 163 => 675, - 164 => 489, - 165 => 490, - 166 => match state { - 240 => 883, - 243 => 887, - 280 => 936, - 282 => 939, - 313 => 1000, - 314 => 1001, - 315 => 1003, - 340 => 1050, - 341 => 1051, - 342 => 1053, - 365 => 1093, - 368 => 1098, - 376 => 1118, - 377 => 1119, - 378 => 1120, - 383 => 1132, - 384 => 1133, - 385 => 1136, - 386 => 1142, - _ => 741, + 150 => 495, + 151 => match state { + 12 => 462, + 27 => 541, + 34 => 549, + 120 => 721, + 176 => 808, + 181 => 811, + _ => 411, }, - 167 => match state { - 83 => 655, - 87 => 660, - 132 => 724, - 133 => 726, - 187 => 801, - 188 => 802, - 189 => 804, - 223 => 862, - 224 => 863, - 225 => 865, - 265 => 918, - 268 => 923, - 304 => 989, - 305 => 990, - 306 => 991, - 334 => 1041, - 335 => 1042, - 336 => 1045, - 362 => 1087, - _ => 463, + 152 => 635, + 153 => 504, + 154 => 505, + 155 => 506, + 156 => match state { + 73 => 655, + _ => 532, }, - 168 => match state { - 66 | 99 => 613, - _ => 398, + 158 => 605, + 159 => match state { + 1 => 8, + 39 => 559, + 49 | 100..=101 => 574, + 67 => 621, + 157 => 782, + 208 => 849, + _ => 53, }, - 169 => match state { - 116 => 701, - _ => 455, + 160 => 507, + 161 => 1050, + 162 => match state { + 56 => 106, + 57 => 107, + 97 => 146, + 98 => 147, + 103 => 150, + 145 => 203, + 13 | 15 | 19 | 26 | 54 | 62 | 64 | 69 | 83..=84 | 86 | 94 | 122..=123 | 126 | 128 | 130 | 135 | 165..=166 | 175 | 196 | 230..=231 | 235 | 260 | 271 | 298 | 313 | 346 | 368 => 463, + 17 | 87 | 91 | 140..=141 | 198..=200 | 236..=238 | 278 | 281 | 317..=319 | 348..=350 | 377 => 479, + 24 | 73 => 533, + 25 => 535, + 42..=43 | 137 | 239 | 279 => 564, + 61 | 65 => 612, + 68 => 622, + 70 | 105 => 636, + 153 | 249 => 770, + 155 | 253 | 256 | 293 | 295 | 326..=328 | 354..=356 | 380 | 383 | 391..=393 | 398..=401 => 774, + 159 | 218 => 783, + 160 => 787, + 161 => 788, + 163 => 789, + 174 => 806, + 212 => 854, + 213 => 855, + 216 | 291 | 357 | 381 => 861, + 217 => 863, + 219 => 865, + 258 => 929, + 259 | 297 => 930, + 261 => 934, + 302 | 338 | 341 | 360 | 366 | 369..=372 | 385 | 394 => 994, + 310 => 1014, + 329 => 1044, + 339 => 1054, + 342 | 386 => 1059, + 345 => 1073, + 362 | 396 => 1100, + 363 => 1106, + 364 => 1107, + 365 => 1108, + 375 => 1122, + 395 | 402 => 1162, + 397 => 1169, + _ => 412, }, - 171 => 957, - 172 => 1021, - 173 => 958, - 174 => match state { - 249..=250 | 287 | 290 => 896, - _ => 946, + 163 => 508, + 166 => 784, + 167 => match state { + 108 => 711, + _ => 608, }, + 169 => 108, + 170 => 609, + 171 => 509, + 172 => 701, + 173 => 510, + 174 => 511, 175 => match state { - 250 => 291, - 287 => 319, - 290 => 329, - _ => 288, + 253 => 922, + 256 => 926, + 293 => 975, + 295 => 978, + 326 => 1039, + 327 => 1040, + 328 => 1042, + 354 => 1089, + 355 => 1090, + 356 => 1092, + 380 => 1132, + 383 => 1137, + 391 => 1157, + 392 => 1158, + 393 => 1159, + 398 => 1171, + 399 => 1172, + 400 => 1175, + 401 => 1181, + _ => 775, }, 176 => match state { - 380 | 387 => 1124, - _ => 1062, + 87 => 679, + 91 => 684, + 140 => 751, + 141 => 753, + 198 => 835, + 199 => 836, + 200 => 838, + 236 => 900, + 237 => 901, + 238 => 903, + 278 => 957, + 281 => 962, + 317 => 1028, + 318 => 1029, + 319 => 1030, + 348 => 1080, + 349 => 1081, + 350 => 1084, + 377 => 1126, + _ => 480, }, 177 => match state { - 371 => 1108, - _ => 1022, + 70 | 105 => 637, + _ => 413, }, 178 => match state { - 328 | 371 => 1023, - _ => 321, - }, - 179 => match state { - 328 | 371 => 1024, - _ => 322, + 123 => 727, + _ => 472, }, - 180 => 491, - 181 => match state { - 112 => 170, - _ => 32, + 180 => 995, + 181 => 1060, + 182 => 996, + 183 => match state { + 262..=263 | 300 | 303 => 935, + _ => 985, }, - 182 => match state { - 12 | 115 => 447, - 80 | 218 => 648, - _ => 456, - }, - 183 => 448, 184 => match state { - 12 => 34, - 18 => 44, - 22 | 69 => 70, - 115 => 175, - 119 => 182, - 50 => 572, - 58 => 589, - 65 => 598, - 247 => 894, - 285 => 944, - 354 => 1072, - _ => 457, + 263 => 304, + 300 => 332, + 303 => 343, + _ => 301, }, 185 => match state { - 80 => 129, - 115 => 176, - 218 => 259, - _ => 35, + 395 | 402 => 1163, + _ => 1101, + }, + 186 => match state { + 386 => 1147, + _ => 1061, }, - 186 => 492, 187 => match state { - 4 => 420, - 17 => 468, - 107 => 693, - 118 => 703, - _ => 399, + 342 | 386 => 1062, + _ => 334, }, - 188 => 614, - 189 => 471, + 188 => match state { + 342 | 386 => 1063, + _ => 335, + }, + 189 => 512, 190 => match state { - 54 => 577, - _ => 581, + 119 => 181, + _ => 34, }, 191 => match state { - 61 => 594, - _ => 588, + 13 | 122 => 464, + 84 | 231 => 672, + _ => 473, }, - 192 => 591, + 192 => 465, 193 => match state { - 205 => 826, - _ => 751, + 13 => 36, + 19 => 46, + 24 | 73 => 74, + 122 => 186, + 126 => 193, + 54 => 597, + 62 => 614, + 69 => 623, + 260 => 933, + 298 => 983, + 368 => 1111, + _ => 474, }, 194 => match state { - 381 => 1126, - _ => 1063, - }, - 195 => 1025, - 196 => 742, - 197 => 464, - 198 => 1064, - 199 => match state { - 115 => 697, - _ => 449, + 84 => 136, + 122 => 187, + 231 => 272, + _ => 37, }, - 200 => 400, - 201 => match state { - 18 | 119 => 472, - _ => 458, + 195 => 513, + 196 => match state { + 4 => 437, + 18 => 485, + 113 => 719, + 125 => 729, + _ => 414, }, - 202 => 737, - 203 => 959, - 204 => match state { - 184 => 221, - 220 => 262, - 30 => 527, - 66 | 99 => 615, - 168 => 776, - 264 => 916, - _ => 401, + 197 => 638, + 198 => 488, + 199 => match state { + 58 => 602, + _ => 606, }, - 205 => 616, - 206 => match state { - 144 => 743, - 240 => 884, - 280 | 315 | 340 | 342 | 365 | 377 | 383 | 385..=386 => 937, - _ => 888, + 200 => match state { + 65 => 619, + _ => 613, }, - 207 => match state { - 16 => 465, - 83 => 656, - 87 | 133 | 187..=188 | 224 | 268 | 304 | 306 | 335 => 661, - _ => 725, + 201 => 616, + 202 => match state { + 218 => 864, + _ => 785, }, - 210 => 744, - 211 => 466, - 215 => match state { - 136 => 730, - 139 => 733, - 143 => 739, - 190 => 806, - 193 => 809, - 194 => 810, - 227 => 869, - _ => 683, + 203 => match state { + 396 => 1165, + _ => 1102, }, - 216 => 493, - 217 => match state { - 324 => 1012, - 327 => 1016, - 348 => 1065, - 352 => 1070, - 356 => 1074, - 357 => 1075, - 358 => 1078, - 370 => 1107, - 379 => 1122, - 381 => 1127, - _ => 960, + 204 => 1064, + 205 => 776, + 206 => 481, + 207 => 1103, + 208 => match state { + 122 => 723, + _ => 466, }, - 219 => match state { - 322 => 1010, - _ => 1009, + 209 => 415, + 210 => match state { + 19 | 126 => 489, + _ => 475, }, - 220 => 323, - 221 => 402, - 222 => 617, - 223 => 19, - 224 => 494, - 225 => 961, - 226 => match state { - 119 => 705, - _ => 473, + 211 => 771, + 212 => 997, + 213 => match state { + 195 => 234, + 233 => 275, + 32 => 548, + 70 | 105 => 639, + 179 => 810, + 277 => 955, + _ => 416, }, - 227 => match state { - 20 => 67, - 66 | 99 => 111, - 161 => 213, - _ => 9, + 214 => 640, + 215 => match state { + 155 => 777, + 253 => 923, + 293 | 328 | 354 | 356 | 380 | 392 | 398 | 400..=401 => 976, + _ => 927, }, - 228 => 618, - 229 => match state { - 111 => 169, - _ => 31, + 216 => match state { + 17 => 482, + 87 => 680, + 91 | 141 | 198..=199 | 237 | 281 | 317 | 319 | 349 => 685, + _ => 752, }, - 230 => match state { - 77 => 643, - _ => 531, + 219 => 778, + 220 => 483, + 224 => match state { + 147 => 764, + 150 => 767, + 154 => 773, + 203 => 844, + 206 => 847, + 207 => 848, + 240 => 908, + _ => 709, }, - 231 => 77, - 232 => match state { - 122 => 711, - 124 => 713, - 183 => 797, - _ => 639, + 225 => 514, + 226 => match state { + 338 => 1052, + 341 => 1056, + 362 => 1104, + 366 => 1109, + 370 => 1113, + 371 => 1114, + 372 => 1117, + 385 => 1146, + 394 => 1161, + 396 => 1166, + _ => 998, }, - 234 => match state { - 19 => 495, - 46 => 551, - 157 => 764, - 211 => 844, - 255 => 901, - 256 => 905, - 298 => 979, - _ => 689, + 228 => match state { + 335 => 1049, + _ => 1048, }, + 229 => 336, + 230 => 417, + 231 => 641, + 232 => 21, + 233 => 515, + 234 => 999, 235 => match state { - 12 | 80 | 115 | 218 => 450, - 14 | 18 | 24 | 60 | 79 | 82 | 89 | 116 | 119 | 121 | 123 | 128 | 154..=155 | 164 | 185 | 217 | 222 | 258 | 300 | 332 => 459, - 54..=55 | 78 | 98 | 127 | 145 | 147 => 578, - _ => 403, + 126 => 731, + _ => 490, + }, + 236 => match state { + 22 => 71, + 70 | 105 => 117, + 172 => 226, + _ => 9, }, - 236 => 962, - 237 => match state { - 278 => 312, - 343 => 367, - 366 => 375, - _ => 242, + 237 => 642, + 238 => match state { + 117 => 180, + _ => 33, }, 239 => match state { - 130 => 186, - 226 => 267, - 266 => 303, - 41 => 544, - _ => 86, + 81 => 667, + _ => 552, }, - 241 => 256, - 242 => match state { - 121 => 710, - 123 => 712, - _ => 515, + 240 => 81, + 241 => match state { + 129 => 737, + 131 => 739, + 194 => 831, + _ => 663, }, 243 => match state { - 164 => 773, - _ => 516, + 21 => 516, + 50 => 576, + 168 => 798, + 224 => 882, + 268 => 940, + 269 => 944, + 311 => 1018, + _ => 715, }, 244 => match state { - 151 => 207, - 141 => 735, - 160 => 771, - 173 => 781, - 192 => 808, - 196 => 812, - 197 => 813, - 198 => 814, - 202 => 819, - 228 => 870, - 229 => 871, - 231 => 873, - 233 => 875, - 234 => 876, - 238 => 881, - 244 => 889, - 253 => 899, - 254 => 900, - 270 => 925, - 271 => 926, - 273 => 928, - 275 => 930, - 276 => 931, - 277 => 932, - 286 => 945, - 292 => 970, - 293 => 971, - 294 => 972, - 295 => 973, - 296 => 974, - 299 => 982, - 308 => 994, - 309 => 995, - 310 => 996, - 311 => 998, - 317 => 1006, - 318 => 1007, - 330 => 1033, - 337 => 1047, - 338 => 1048, - 339 => 1049, - 344 => 1057, - 345 => 1058, - 353 => 1071, - 361 => 1084, - 363 => 1090, - 364 => 1091, - 369 => 1101, - 372 => 1112, - 373 => 1113, - 374 => 1114, - _ => 158, + 13 | 84 | 122 | 231 => 467, + 15 | 19 | 26 | 64 | 83 | 86 | 94 | 123 | 126 | 128 | 130 | 135 | 165..=166 | 175 | 196 | 230 | 235 | 271 | 313 | 346 => 476, + 58..=59 | 82 | 104 | 134 | 156 | 158 => 603, + _ => 418, }, - 245 => match state { - 21 => 68, - 66 | 99 => 112, - 162 => 214, - _ => 10, + 245 => 1000, + 246 => match state { + 291 => 325, + 357 => 382, + 381 => 390, + _ => 255, }, - 246 => 619, - 247 => match state { - 73 => 124, - 96 => 137, - 122 => 183, - 1 | 29 | 37 | 63 | 94..=95 | 146 | 195 | 281 => 404, - 12 => 451, - 14 | 22 | 50 | 58 | 60 | 65 | 69 | 79 | 82 | 89 | 116 | 128 | 154..=155 | 185 | 217 | 222 | 247 | 258 | 285 | 300 | 332 | 354 => 460, - 18 | 119 => 474, - 24 | 121 | 123 | 164 => 517, - 42 => 545, - 51 => 573, - 62 => 595, - 66 | 99 | 172 | 216 | 219 | 261 | 301 | 333 => 620, - 71 => 636, - 72 => 637, - 76 => 641, - 80 => 649, - 81 => 652, - 84 => 657, - 85 => 658, - 88 => 666, - 90 => 667, - 115 => 698, - 120 => 709, - 125 => 714, - 126 => 715, - 138 => 732, - 156 => 763, - 159 => 770, - 201 => 818, - 210 | 251 => 842, - 212 => 845, - 218 => 852, - 230 => 872, - 232 => 874, - 235 => 877, - 237 => 880, - 239 => 882, - 241 => 885, - 252 => 898, - 257 => 907, - 269 => 924, - 272 => 927, - 274 => 929, - 283 => 941, - 307 => 993, - _ => 496, + 248 => match state { + 137 => 197, + 239 => 280, + 279 => 316, + 43 => 565, + _ => 90, }, - 249 => 621, - 252 => match state { - 95 => 676, - _ => 673, + 250 => 269, + 251 => match state { + 302 | 338 | 341 | 360 | 362 | 366 | 369..=372 | 385 | 394 | 396 => 1001, + 337 => 1051, + _ => 419, }, + 252 => 337, 253 => match state { - 29 => 526, - 281 => 938, - _ => 405, + 10 | 118 | 374 => 456, + _ => 420, + }, + 254 => match state { + 70 | 105 => 118, + 342 | 386 => 374, + _ => 10, }, 255 => match state { - 14 => 38, - 116 => 179, - 18 | 119 => 475, - 60 => 592, - 79 | 185 | 217 | 300 => 646, - 82 | 89 => 653, - 128 | 222 | 258 | 332 => 717, - 154 => 757, - 155 => 760, - _ => 518, + 128 => 736, + 130 => 738, + _ => 536, }, - 256 => 388, - 257 => 497, - 258 => 963, - 259 => 964, - 260 => 519, - 261 => 593, - 262 => 105, - 263 => 498, - 264 => match state { - 236 => 878, - _ => 738, + 256 => match state { + 175 => 807, + _ => 537, }, - 265 => match state { - 101 => 143, - 135 => 191, - 136 => 193, - 139 => 194, - 190 => 227, - 105 => 691, - _ => 140, + 257 => match state { + 162 => 220, + 152 => 769, + 171 => 805, + 184 => 815, + 205 => 846, + 209 => 850, + 210 => 851, + 211 => 852, + 215 => 857, + 241 => 909, + 242 => 910, + 244 => 912, + 246 => 914, + 247 => 915, + 251 => 920, + 257 => 928, + 266 => 938, + 267 => 939, + 283 => 964, + 284 => 965, + 286 => 967, + 288 => 969, + 289 => 970, + 290 => 971, + 299 => 984, + 305 => 1009, + 306 => 1010, + 307 => 1011, + 308 => 1012, + 309 => 1013, + 312 => 1021, + 321 => 1033, + 322 => 1034, + 323 => 1035, + 324 => 1037, + 330 => 1045, + 331 => 1046, + 344 => 1072, + 351 => 1086, + 352 => 1087, + 353 => 1088, + 358 => 1096, + 359 => 1097, + 367 => 1110, + 376 => 1123, + 378 => 1129, + 379 => 1130, + 384 => 1140, + 387 => 1151, + 388 => 1152, + 389 => 1153, + _ => 169, }, - 267 => 745, - 268 => match state { - 66 | 99 => 113, + 258 => match state { + 23 => 72, + 70 | 105 => 119, + 173 => 227, _ => 11, }, - 269 => 467, - 270 => 965, - 271 => 499, - 272 => match state { - 66 | 99 => 114, - 216 | 261 | 333 => 848, - _ => 779, + 259 => 643, + 260 => match state { + 77 => 131, + 102 => 148, + 129 => 194, + 1 | 31 | 39 | 49 | 67 | 100..=101 | 157 | 208 | 294 => 421, + 13 => 468, + 15 | 24 | 54 | 62 | 64 | 69 | 73 | 83 | 86 | 94 | 123 | 135 | 165..=166 | 196 | 230 | 235 | 260 | 271 | 298 | 313 | 346 | 368 => 477, + 19 | 126 => 491, + 26 | 128 | 130 | 175 => 538, + 44 => 566, + 55 => 598, + 66 => 620, + 70 | 105 | 183 | 229 | 232 | 274 | 314 | 347 => 644, + 75 => 660, + 76 => 661, + 80 => 665, + 84 => 673, + 85 => 676, + 88 => 681, + 89 => 682, + 92 => 686, + 93 => 691, + 95 => 692, + 122 => 724, + 127 => 735, + 132 => 740, + 133 => 741, + 139 => 750, + 149 => 766, + 167 => 797, + 170 => 804, + 214 => 856, + 223 | 264 => 880, + 225 => 883, + 231 => 890, + 243 => 911, + 245 => 913, + 248 => 916, + 250 => 919, + 252 => 921, + 254 => 924, + 265 => 937, + 270 => 946, + 282 => 963, + 285 => 966, + 287 => 968, + 296 => 980, + 320 => 1032, + _ => 517, + }, + 262 => 645, + 265 => match state { + 100 => 700, + 101 => 702, + _ => 96, + }, + 266 => match state { + 31 => 547, + 294 => 977, + _ => 422, }, - 273 => 622, - 274 => match state { - 115 => 177, - 218 => 260, - 66 | 99 => 623, - _ => 780, + 268 => match state { + 15 => 40, + 123 => 190, + 19 | 126 => 492, + 64 => 617, + 83 | 196 | 230 | 313 => 670, + 86 | 94 => 677, + 135 | 235 | 271 | 346 => 743, + 165 => 791, + 166 => 794, + _ => 539, }, - 275 => match state { - 99 => 681, - _ => 624, + 269 => 403, + 270 => 518, + 271 => 1002, + 272 => 1003, + 273 => 540, + 274 => 618, + 275 => 111, + 276 => 519, + 277 => match state { + 249 => 917, + _ => 772, }, - 277 => 500, 278 => match state { - 28 => 524, - 66 | 99 => 625, - 167 => 775, - _ => 406, + 107 => 154, + 146 => 204, + 147 => 206, + 150 => 207, + 203 => 240, + 111 => 717, + _ => 151, }, - 279 => 626, - 280 => match state { - 12 => 452, - 94..=95 => 674, - 115 => 699, - _ => 501, + 280 => 779, + 281 => match state { + 70 | 105 => 120, + _ => 12, + }, + 282 => 484, + 283 => 1004, + 284 => 520, + 285 => match state { + 70 | 105 => 121, + 229 | 274 | 347 => 886, + _ => 813, + }, + 286 => 646, + 287 => match state { + 122 => 188, + 231 => 273, + 70 | 105 => 647, + _ => 814, + }, + 288 => match state { + 105 => 707, + _ => 648, + }, + 290 => 521, + 291 => match state { + 30 => 545, + 70 | 105 => 649, + 178 => 809, + _ => 423, + }, + 292 => 650, + 293 => match state { + 13 => 469, + 49 | 100..=101 => 575, + 122 => 725, + _ => 522, }, _ => 0, } } const __TERMINAL: &[&str] = &[ r###""\n""###, + r###""!""###, r###""!=""###, r###""%""###, r###""%=""###, @@ -5631,11 +5826,14 @@ mod __parse__Top { r###""}""###, r###""~""###, r###"Dedent"###, + r###"FStringEnd"###, + r###"FStringStart"###, r###"Indent"###, r###"StartExpression"###, r###"StartModule"###, r###"complex"###, r###"float"###, + r###"fstring_middle"###, r###"int"###, r###"ipy_escape_command"###, r###"name"###, @@ -5652,6 +5850,7 @@ mod __parse__Top { }).collect() } fn __expected_tokens_from_states< + '__0, >( __states: &[i16], _: core::marker::PhantomData<()>, @@ -5665,13 +5864,14 @@ mod __parse__Top { } }).collect() } - pub(crate) struct __StateMachine<> + pub(crate) struct __StateMachine<'__0> where { + source_code: &'__0 str, mode: Mode, __phantom: core::marker::PhantomData<()>, } - impl<> __state_machine::ParserDefinition for __StateMachine<> + impl<'__0> __state_machine::ParserDefinition for __StateMachine<'__0> where { type Location = TextSize; @@ -5707,7 +5907,7 @@ mod __parse__Top { #[inline] fn error_action(&self, state: i16) -> i16 { - __action(state, 97 - 1) + __action(state, 101 - 1) } #[inline] @@ -5753,6 +5953,7 @@ mod __parse__Top { symbols: &mut alloc::vec::Vec<__state_machine::SymbolTriple>, ) -> Option<__state_machine::ParseResult> { __reduce( + self.source_code, self.mode, action, start_location, @@ -5774,102 +5975,106 @@ mod __parse__Top { { match *__token { token::Tok::Newline if true => Some(0), - token::Tok::NotEqual if true => Some(1), - token::Tok::Percent if true => Some(2), - token::Tok::PercentEqual if true => Some(3), - token::Tok::Amper if true => Some(4), - token::Tok::AmperEqual if true => Some(5), - token::Tok::Lpar if true => Some(6), - token::Tok::Rpar if true => Some(7), - token::Tok::Star if true => Some(8), - token::Tok::DoubleStar if true => Some(9), - token::Tok::DoubleStarEqual if true => Some(10), - token::Tok::StarEqual if true => Some(11), - token::Tok::Plus if true => Some(12), - token::Tok::PlusEqual if true => Some(13), - token::Tok::Comma if true => Some(14), - token::Tok::Minus if true => Some(15), - token::Tok::MinusEqual if true => Some(16), - token::Tok::Rarrow if true => Some(17), - token::Tok::Dot if true => Some(18), - token::Tok::Ellipsis if true => Some(19), - token::Tok::Slash if true => Some(20), - token::Tok::DoubleSlash if true => Some(21), - token::Tok::DoubleSlashEqual if true => Some(22), - token::Tok::SlashEqual if true => Some(23), - token::Tok::Colon if true => Some(24), - token::Tok::ColonEqual if true => Some(25), - token::Tok::Semi if true => Some(26), - token::Tok::Less if true => Some(27), - token::Tok::LeftShift if true => Some(28), - token::Tok::LeftShiftEqual if true => Some(29), - token::Tok::LessEqual if true => Some(30), - token::Tok::Equal if true => Some(31), - token::Tok::EqEqual if true => Some(32), - token::Tok::Greater if true => Some(33), - token::Tok::GreaterEqual if true => Some(34), - token::Tok::RightShift if true => Some(35), - token::Tok::RightShiftEqual if true => Some(36), - token::Tok::Question if true => Some(37), - token::Tok::At if true => Some(38), - token::Tok::AtEqual if true => Some(39), - token::Tok::False if true => Some(40), - token::Tok::None if true => Some(41), - token::Tok::True if true => Some(42), - token::Tok::Lsqb if true => Some(43), - token::Tok::Rsqb if true => Some(44), - token::Tok::CircumFlex if true => Some(45), - token::Tok::CircumflexEqual if true => Some(46), - token::Tok::And if true => Some(47), - token::Tok::As if true => Some(48), - token::Tok::Assert if true => Some(49), - token::Tok::Async if true => Some(50), - token::Tok::Await if true => Some(51), - token::Tok::Break if true => Some(52), - token::Tok::Case if true => Some(53), - token::Tok::Class if true => Some(54), - token::Tok::Continue if true => Some(55), - token::Tok::Def if true => Some(56), - token::Tok::Del if true => Some(57), - token::Tok::Elif if true => Some(58), - token::Tok::Else if true => Some(59), - token::Tok::Except if true => Some(60), - token::Tok::Finally if true => Some(61), - token::Tok::For if true => Some(62), - token::Tok::From if true => Some(63), - token::Tok::Global if true => Some(64), - token::Tok::If if true => Some(65), - token::Tok::Import if true => Some(66), - token::Tok::In if true => Some(67), - token::Tok::Is if true => Some(68), - token::Tok::Lambda if true => Some(69), - token::Tok::Match if true => Some(70), - token::Tok::Nonlocal if true => Some(71), - token::Tok::Not if true => Some(72), - token::Tok::Or if true => Some(73), - token::Tok::Pass if true => Some(74), - token::Tok::Raise if true => Some(75), - token::Tok::Return if true => Some(76), - token::Tok::Try if true => Some(77), - token::Tok::Type if true => Some(78), - token::Tok::While if true => Some(79), - token::Tok::With if true => Some(80), - token::Tok::Yield if true => Some(81), - token::Tok::Lbrace if true => Some(82), - token::Tok::Vbar if true => Some(83), - token::Tok::VbarEqual if true => Some(84), - token::Tok::Rbrace if true => Some(85), - token::Tok::Tilde if true => Some(86), - token::Tok::Dedent if true => Some(87), - token::Tok::Indent if true => Some(88), - token::Tok::StartExpression if true => Some(89), - token::Tok::StartModule if true => Some(90), - token::Tok::Complex { real: _, imag: _ } if true => Some(91), - token::Tok::Float { value: _ } if true => Some(92), - token::Tok::Int { value: _ } if true => Some(93), - token::Tok::IpyEscapeCommand { kind: _, value: _ } if true => Some(94), - token::Tok::Name { name: _ } if true => Some(95), - token::Tok::String { value: _, kind: _, triple_quoted: _ } if true => Some(96), + token::Tok::Exclamation if true => Some(1), + token::Tok::NotEqual if true => Some(2), + token::Tok::Percent if true => Some(3), + token::Tok::PercentEqual if true => Some(4), + token::Tok::Amper if true => Some(5), + token::Tok::AmperEqual if true => Some(6), + token::Tok::Lpar if true => Some(7), + token::Tok::Rpar if true => Some(8), + token::Tok::Star if true => Some(9), + token::Tok::DoubleStar if true => Some(10), + token::Tok::DoubleStarEqual if true => Some(11), + token::Tok::StarEqual if true => Some(12), + token::Tok::Plus if true => Some(13), + token::Tok::PlusEqual if true => Some(14), + token::Tok::Comma if true => Some(15), + token::Tok::Minus if true => Some(16), + token::Tok::MinusEqual if true => Some(17), + token::Tok::Rarrow if true => Some(18), + token::Tok::Dot if true => Some(19), + token::Tok::Ellipsis if true => Some(20), + token::Tok::Slash if true => Some(21), + token::Tok::DoubleSlash if true => Some(22), + token::Tok::DoubleSlashEqual if true => Some(23), + token::Tok::SlashEqual if true => Some(24), + token::Tok::Colon if true => Some(25), + token::Tok::ColonEqual if true => Some(26), + token::Tok::Semi if true => Some(27), + token::Tok::Less if true => Some(28), + token::Tok::LeftShift if true => Some(29), + token::Tok::LeftShiftEqual if true => Some(30), + token::Tok::LessEqual if true => Some(31), + token::Tok::Equal if true => Some(32), + token::Tok::EqEqual if true => Some(33), + token::Tok::Greater if true => Some(34), + token::Tok::GreaterEqual if true => Some(35), + token::Tok::RightShift if true => Some(36), + token::Tok::RightShiftEqual if true => Some(37), + token::Tok::Question if true => Some(38), + token::Tok::At if true => Some(39), + token::Tok::AtEqual if true => Some(40), + token::Tok::False if true => Some(41), + token::Tok::None if true => Some(42), + token::Tok::True if true => Some(43), + token::Tok::Lsqb if true => Some(44), + token::Tok::Rsqb if true => Some(45), + token::Tok::CircumFlex if true => Some(46), + token::Tok::CircumflexEqual if true => Some(47), + token::Tok::And if true => Some(48), + token::Tok::As if true => Some(49), + token::Tok::Assert if true => Some(50), + token::Tok::Async if true => Some(51), + token::Tok::Await if true => Some(52), + token::Tok::Break if true => Some(53), + token::Tok::Case if true => Some(54), + token::Tok::Class if true => Some(55), + token::Tok::Continue if true => Some(56), + token::Tok::Def if true => Some(57), + token::Tok::Del if true => Some(58), + token::Tok::Elif if true => Some(59), + token::Tok::Else if true => Some(60), + token::Tok::Except if true => Some(61), + token::Tok::Finally if true => Some(62), + token::Tok::For if true => Some(63), + token::Tok::From if true => Some(64), + token::Tok::Global if true => Some(65), + token::Tok::If if true => Some(66), + token::Tok::Import if true => Some(67), + token::Tok::In if true => Some(68), + token::Tok::Is if true => Some(69), + token::Tok::Lambda if true => Some(70), + token::Tok::Match if true => Some(71), + token::Tok::Nonlocal if true => Some(72), + token::Tok::Not if true => Some(73), + token::Tok::Or if true => Some(74), + token::Tok::Pass if true => Some(75), + token::Tok::Raise if true => Some(76), + token::Tok::Return if true => Some(77), + token::Tok::Try if true => Some(78), + token::Tok::Type if true => Some(79), + token::Tok::While if true => Some(80), + token::Tok::With if true => Some(81), + token::Tok::Yield if true => Some(82), + token::Tok::Lbrace if true => Some(83), + token::Tok::Vbar if true => Some(84), + token::Tok::VbarEqual if true => Some(85), + token::Tok::Rbrace if true => Some(86), + token::Tok::Tilde if true => Some(87), + token::Tok::Dedent if true => Some(88), + token::Tok::FStringEnd if true => Some(89), + token::Tok::FStringStart if true => Some(90), + token::Tok::Indent if true => Some(91), + token::Tok::StartExpression if true => Some(92), + token::Tok::StartModule if true => Some(93), + token::Tok::Complex { real: _, imag: _ } if true => Some(94), + token::Tok::Float { value: _ } if true => Some(95), + token::Tok::FStringMiddle { value: _, is_raw: _ } if true => Some(96), + token::Tok::Int { value: _ } if true => Some(97), + token::Tok::IpyEscapeCommand { kind: _, value: _ } if true => Some(98), + token::Tok::Name { name: _ } if true => Some(99), + token::Tok::String { value: _, kind: _, triple_quoted: _ } if true => Some(100), _ => None, } } @@ -5881,39 +6086,44 @@ mod __parse__Top { ) -> __Symbol<> { match __token_index { - 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 => __Symbol::Variant0(__token), - 91 => match __token { + 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 => __Symbol::Variant0(__token), + 94 => match __token { token::Tok::Complex { real: __tok0, imag: __tok1 } if true => __Symbol::Variant1((__tok0, __tok1)), _ => unreachable!(), }, - 92 => match __token { + 95 => match __token { token::Tok::Float { value: __tok0 } if true => __Symbol::Variant2(__tok0), _ => unreachable!(), }, - 93 => match __token { - token::Tok::Int { value: __tok0 } if true => __Symbol::Variant3(__tok0), + 96 => match __token { + token::Tok::FStringMiddle { value: __tok0, is_raw: __tok1 } if true => __Symbol::Variant3((__tok0, __tok1)), _ => unreachable!(), }, - 94 => match __token { - token::Tok::IpyEscapeCommand { kind: __tok0, value: __tok1 } if true => __Symbol::Variant4((__tok0, __tok1)), + 97 => match __token { + token::Tok::Int { value: __tok0 } if true => __Symbol::Variant4(__tok0), _ => unreachable!(), }, - 95 => match __token { - token::Tok::Name { name: __tok0 } if true => __Symbol::Variant5(__tok0), + 98 => match __token { + token::Tok::IpyEscapeCommand { kind: __tok0, value: __tok1 } if true => __Symbol::Variant5((__tok0, __tok1)), _ => unreachable!(), }, - 96 => match __token { - token::Tok::String { value: __tok0, kind: __tok1, triple_quoted: __tok2 } if true => __Symbol::Variant6((__tok0, __tok1, __tok2)), + 99 => match __token { + token::Tok::Name { name: __tok0 } if true => __Symbol::Variant6(__tok0), + _ => unreachable!(), + }, + 100 => match __token { + token::Tok::String { value: __tok0, kind: __tok1, triple_quoted: __tok2 } if true => __Symbol::Variant7((__tok0, __tok1, __tok2)), _ => unreachable!(), }, _ => unreachable!(), } } fn __simulate_reduce< + '__0, >( __reduce_index: i16, _: core::marker::PhantomData<()>, - ) -> __state_machine::SimulatedReduce<__StateMachine<>> + ) -> __state_machine::SimulatedReduce<__StateMachine<'__0>> { match __reduce_index { 0 => { @@ -5954,19 +6164,19 @@ mod __parse__Top { } 6 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 1, nonterminal_produced: 3, } } 7 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 4, + states_to_pop: 0, + nonterminal_produced: 3, } } 8 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 2, nonterminal_produced: 4, } } @@ -5978,13 +6188,13 @@ mod __parse__Top { } 10 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 6, + states_to_pop: 0, + nonterminal_produced: 5, } } 11 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 2, nonterminal_produced: 6, } } @@ -5997,24 +6207,24 @@ mod __parse__Top { 13 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 0, - nonterminal_produced: 8, + nonterminal_produced: 7, } } 14 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 8, } } 15 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 0, nonterminal_produced: 9, } } 16 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 1, nonterminal_produced: 9, } } @@ -6026,247 +6236,247 @@ mod __parse__Top { } 18 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 11, + states_to_pop: 3, + nonterminal_produced: 10, } } 19 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 11, } } 20 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 0, nonterminal_produced: 12, } } 21 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 1, nonterminal_produced: 12, } } 22 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, + states_to_pop: 2, nonterminal_produced: 13, } } 23 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, + states_to_pop: 3, nonterminal_produced: 13, } } 24 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 13, + states_to_pop: 5, + nonterminal_produced: 14, } } 25 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 13, + states_to_pop: 4, + nonterminal_produced: 14, } } 26 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 13, + states_to_pop: 6, + nonterminal_produced: 14, } } 27 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 13, + states_to_pop: 5, + nonterminal_produced: 14, } } 28 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 13, + states_to_pop: 3, + nonterminal_produced: 14, } } 29 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 13, + states_to_pop: 2, + nonterminal_produced: 14, } } 30 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, + states_to_pop: 4, nonterminal_produced: 14, } } 31 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, + states_to_pop: 3, nonterminal_produced: 14, } } 32 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 14, + states_to_pop: 5, + nonterminal_produced: 15, } } 33 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 14, + states_to_pop: 4, + nonterminal_produced: 15, } } 34 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 14, + states_to_pop: 6, + nonterminal_produced: 15, } } 35 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 14, + states_to_pop: 5, + nonterminal_produced: 15, } } 36 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 14, + states_to_pop: 3, + nonterminal_produced: 15, } } 37 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 14, + states_to_pop: 2, + nonterminal_produced: 15, } } 38 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 14, + states_to_pop: 4, + nonterminal_produced: 15, } } 39 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, + states_to_pop: 3, nonterminal_produced: 15, } } 40 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, + states_to_pop: 0, nonterminal_produced: 15, } } 41 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 15, + states_to_pop: 5, + nonterminal_produced: 16, } } 42 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 15, + states_to_pop: 4, + nonterminal_produced: 16, } } 43 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 15, + states_to_pop: 6, + nonterminal_produced: 16, } } 44 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 15, + states_to_pop: 5, + nonterminal_produced: 16, } } 45 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 15, + states_to_pop: 3, + nonterminal_produced: 16, } } 46 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 15, + states_to_pop: 2, + nonterminal_produced: 16, } } 47 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, + states_to_pop: 4, nonterminal_produced: 16, } } 48 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, + states_to_pop: 3, nonterminal_produced: 16, } } 49 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 16, + states_to_pop: 5, + nonterminal_produced: 17, } } 50 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 16, + states_to_pop: 4, + nonterminal_produced: 17, } } 51 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 16, + states_to_pop: 6, + nonterminal_produced: 17, } } 52 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 16, + states_to_pop: 5, + nonterminal_produced: 17, } } 53 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 16, + states_to_pop: 3, + nonterminal_produced: 17, } } 54 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 16, + states_to_pop: 2, + nonterminal_produced: 17, } } 55 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 16, + states_to_pop: 4, + nonterminal_produced: 17, } } 56 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 3, nonterminal_produced: 17, } } 57 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 18, + states_to_pop: 0, + nonterminal_produced: 17, } } 58 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 2, nonterminal_produced: 18, } } @@ -6279,24 +6489,24 @@ mod __parse__Top { 60 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 0, - nonterminal_produced: 20, + nonterminal_produced: 19, } } 61 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 20, } } 62 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 0, nonterminal_produced: 21, } } 63 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 1, nonterminal_produced: 21, } } @@ -6308,25 +6518,25 @@ mod __parse__Top { } 65 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 23, + states_to_pop: 3, + nonterminal_produced: 22, } } 66 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 23, } } 67 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 0, nonterminal_produced: 24, } } 68 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 1, nonterminal_produced: 24, } } @@ -6338,13 +6548,13 @@ mod __parse__Top { } 70 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 26, + states_to_pop: 3, + nonterminal_produced: 25, } } 71 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 2, nonterminal_produced: 26, } } @@ -6356,13 +6566,13 @@ mod __parse__Top { } 73 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 28, + states_to_pop: 0, + nonterminal_produced: 27, } } 74 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 2, nonterminal_produced: 28, } } @@ -6374,13 +6584,13 @@ mod __parse__Top { } 76 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 30, + states_to_pop: 3, + nonterminal_produced: 29, } } 77 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 2, nonterminal_produced: 30, } } @@ -6392,31 +6602,31 @@ mod __parse__Top { } 79 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 32, + states_to_pop: 0, + nonterminal_produced: 31, } } 80 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 2, nonterminal_produced: 32, } } 81 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 33, } } 82 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 34, + states_to_pop: 0, + nonterminal_produced: 33, } } 83 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 1, nonterminal_produced: 34, } } @@ -6428,8 +6638,8 @@ mod __parse__Top { } 85 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 36, + states_to_pop: 2, + nonterminal_produced: 35, } } 86 => { @@ -6440,49 +6650,49 @@ mod __parse__Top { } 87 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 0, nonterminal_produced: 37, } } 88 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 1, nonterminal_produced: 37, } } 89 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 1, nonterminal_produced: 38, } } 90 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 39, + nonterminal_produced: 38, } } 91 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 2, nonterminal_produced: 39, } } 92 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 2, nonterminal_produced: 40, } } 93 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 41, + states_to_pop: 0, + nonterminal_produced: 40, } } 94 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 3, nonterminal_produced: 41, } } @@ -6494,97 +6704,97 @@ mod __parse__Top { } 96 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 43, + states_to_pop: 0, + nonterminal_produced: 42, } } 97 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 3, nonterminal_produced: 43, } } 98 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 3, nonterminal_produced: 44, } } 99 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 45, + states_to_pop: 0, + nonterminal_produced: 44, } } 100 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 2, nonterminal_produced: 45, } } 101 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, + states_to_pop: 2, nonterminal_produced: 46, } } 102 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 0, - nonterminal_produced: 47, + nonterminal_produced: 46, } } 103 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 4, nonterminal_produced: 47, } } 104 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, + states_to_pop: 0, nonterminal_produced: 48, } } 105 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, + states_to_pop: 1, nonterminal_produced: 48, } } 106 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 4, nonterminal_produced: 49, } } 107 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 50, + states_to_pop: 5, + nonterminal_produced: 49, } } 108 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 3, nonterminal_produced: 50, } } 109 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 3, nonterminal_produced: 51, } } 110 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 52, + states_to_pop: 0, + nonterminal_produced: 51, } } 111 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 2, nonterminal_produced: 52, } } @@ -6596,25 +6806,25 @@ mod __parse__Top { } 113 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 54, + states_to_pop: 3, + nonterminal_produced: 53, } } 114 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 54, } } 115 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 0, nonterminal_produced: 55, } } 116 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 1, nonterminal_produced: 55, } } @@ -6626,13 +6836,13 @@ mod __parse__Top { } 118 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 57, + states_to_pop: 3, + nonterminal_produced: 56, } } 119 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 2, nonterminal_produced: 57, } } @@ -6644,13 +6854,13 @@ mod __parse__Top { } 121 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 59, + states_to_pop: 3, + nonterminal_produced: 58, } } 122 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 2, nonterminal_produced: 59, } } @@ -6663,24 +6873,24 @@ mod __parse__Top { 124 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 0, - nonterminal_produced: 61, + nonterminal_produced: 60, } } 125 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 61, } } 126 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 0, nonterminal_produced: 62, } } 127 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 1, nonterminal_produced: 62, } } @@ -6692,62 +6902,62 @@ mod __parse__Top { } 129 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 64, + states_to_pop: 3, + nonterminal_produced: 63, } } 130 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 64, } } 131 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 0, nonterminal_produced: 65, } } 132 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 1, nonterminal_produced: 65, } } 133 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 2, nonterminal_produced: 66, } } 134 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 67, + states_to_pop: 3, + nonterminal_produced: 66, } } 135 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 68, + states_to_pop: 3, + nonterminal_produced: 67, } } 136 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 2, nonterminal_produced: 68, } } 137 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 69, } } 138 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 70, + states_to_pop: 0, + nonterminal_produced: 69, } } 139 => { @@ -6764,13 +6974,13 @@ mod __parse__Top { } 141 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 72, + states_to_pop: 3, + nonterminal_produced: 71, } } 142 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 1, nonterminal_produced: 72, } } @@ -6782,13 +6992,13 @@ mod __parse__Top { } 144 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 74, + states_to_pop: 0, + nonterminal_produced: 73, } } 145 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 1, nonterminal_produced: 74, } } @@ -6800,8 +7010,8 @@ mod __parse__Top { } 147 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 76, + states_to_pop: 0, + nonterminal_produced: 75, } } 148 => { @@ -6818,19 +7028,19 @@ mod __parse__Top { } 150 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 1, nonterminal_produced: 78, } } 151 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 79, + nonterminal_produced: 78, } } 152 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 3, nonterminal_produced: 79, } } @@ -6842,122 +7052,122 @@ mod __parse__Top { } 154 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 81, + states_to_pop: 1, + nonterminal_produced: 80, } } 155 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 3, nonterminal_produced: 81, } } 156 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 82, + states_to_pop: 1, + nonterminal_produced: 81, } } 157 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 82, } } 158 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 83, + states_to_pop: 1, + nonterminal_produced: 82, } } 159 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 83, } } 160 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 84, + states_to_pop: 1, + nonterminal_produced: 83, } } 161 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 3, nonterminal_produced: 84, } } 162 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 85, + states_to_pop: 2, + nonterminal_produced: 84, } } 163 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 85, + states_to_pop: 4, + nonterminal_produced: 84, } } 164 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 85, + states_to_pop: 3, + nonterminal_produced: 84, } } 165 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 1, nonterminal_produced: 85, } } 166 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 86, + states_to_pop: 0, + nonterminal_produced: 85, } } 167 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 3, nonterminal_produced: 86, } } 168 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 87, + states_to_pop: 1, + nonterminal_produced: 86, } } 169 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 3, nonterminal_produced: 87, } } 170 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 88, + states_to_pop: 1, + nonterminal_produced: 87, } } 171 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 3, nonterminal_produced: 88, } } 172 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 4, nonterminal_produced: 89, } } 173 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 90, + states_to_pop: 2, + nonterminal_produced: 89, } } 174 => { @@ -6969,19 +7179,19 @@ mod __parse__Top { 175 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 91, + nonterminal_produced: 90, } } 176 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 0, nonterminal_produced: 91, } } 177 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 92, + states_to_pop: 1, + nonterminal_produced: 91, } } 178 => { @@ -6992,194 +7202,194 @@ mod __parse__Top { } 179 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 93, + states_to_pop: 2, + nonterminal_produced: 92, } } 180 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 1, nonterminal_produced: 93, } } 181 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 94, + states_to_pop: 0, + nonterminal_produced: 93, } } 182 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 1, nonterminal_produced: 94, } } 183 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 95, + nonterminal_produced: 94, } } 184 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 95, + nonterminal_produced: 94, } } 185 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 95, + states_to_pop: 3, + nonterminal_produced: 94, } } 186 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 95, + states_to_pop: 2, + nonterminal_produced: 94, } } 187 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 95, + states_to_pop: 4, + nonterminal_produced: 94, } } 188 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 95, + nonterminal_produced: 94, } } 189 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 95, + states_to_pop: 3, + nonterminal_produced: 94, } } 190 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 95, + states_to_pop: 6, + nonterminal_produced: 94, } } 191 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 95, + states_to_pop: 4, + nonterminal_produced: 94, } } 192 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 95, + states_to_pop: 7, + nonterminal_produced: 94, } } 193 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 95, + states_to_pop: 5, + nonterminal_produced: 94, } } 194 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, - nonterminal_produced: 95, + nonterminal_produced: 94, } } 195 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 95, + states_to_pop: 3, + nonterminal_produced: 94, } } 196 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 95, + states_to_pop: 6, + nonterminal_produced: 94, } } 197 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 95, + states_to_pop: 4, + nonterminal_produced: 94, } } 198 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 95, + states_to_pop: 2, + nonterminal_produced: 94, } } 199 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 95, + states_to_pop: 3, + nonterminal_produced: 94, } } 200 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 95, + states_to_pop: 4, + nonterminal_produced: 94, } } 201 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 95, + nonterminal_produced: 94, } } 202 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 95, + states_to_pop: 3, + nonterminal_produced: 94, } } 203 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 95, + states_to_pop: 2, + nonterminal_produced: 94, } } 204 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 95, + states_to_pop: 4, + nonterminal_produced: 94, } } 205 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 95, + states_to_pop: 3, + nonterminal_produced: 94, } } 206 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 95, + states_to_pop: 4, + nonterminal_produced: 94, } } 207 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 95, + states_to_pop: 1, + nonterminal_produced: 94, } } 208 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 95, + nonterminal_produced: 94, } } 209 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 95, + nonterminal_produced: 94, } } 210 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 95, + nonterminal_produced: 94, } } 211 => { @@ -7191,157 +7401,157 @@ mod __parse__Top { 212 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 96, + nonterminal_produced: 95, } } 213 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 96, + nonterminal_produced: 95, } } 214 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 96, + states_to_pop: 3, + nonterminal_produced: 95, } } 215 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 96, + states_to_pop: 2, + nonterminal_produced: 95, } } 216 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 96, + states_to_pop: 4, + nonterminal_produced: 95, } } 217 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 96, + states_to_pop: 6, + nonterminal_produced: 95, } } 218 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 96, + states_to_pop: 4, + nonterminal_produced: 95, } } 219 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 96, + states_to_pop: 7, + nonterminal_produced: 95, } } 220 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 96, + states_to_pop: 5, + nonterminal_produced: 95, } } 221 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, - nonterminal_produced: 96, + nonterminal_produced: 95, } } 222 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 96, + states_to_pop: 3, + nonterminal_produced: 95, } } 223 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 96, + states_to_pop: 6, + nonterminal_produced: 95, } } 224 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 96, + states_to_pop: 4, + nonterminal_produced: 95, } } 225 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 96, + states_to_pop: 2, + nonterminal_produced: 95, } } 226 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 96, + states_to_pop: 3, + nonterminal_produced: 95, } } 227 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 96, + states_to_pop: 4, + nonterminal_produced: 95, } } 228 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 96, + nonterminal_produced: 95, } } 229 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 96, + states_to_pop: 3, + nonterminal_produced: 95, } } 230 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 96, + states_to_pop: 2, + nonterminal_produced: 95, } } 231 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 96, + states_to_pop: 4, + nonterminal_produced: 95, } } 232 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 96, + states_to_pop: 3, + nonterminal_produced: 95, } } 233 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 96, + states_to_pop: 4, + nonterminal_produced: 95, } } 234 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 96, + states_to_pop: 1, + nonterminal_produced: 95, } } 235 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 96, + nonterminal_produced: 95, } } 236 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 96, + nonterminal_produced: 95, } } 237 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 96, + nonterminal_produced: 95, } } 238 => { @@ -7352,68 +7562,68 @@ mod __parse__Top { } 239 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 97, + states_to_pop: 2, + nonterminal_produced: 96, } } 240 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 97, + states_to_pop: 4, + nonterminal_produced: 96, } } 241 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 97, + states_to_pop: 3, + nonterminal_produced: 96, } } 242 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 1, nonterminal_produced: 97, } } 243 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 98, + states_to_pop: 2, + nonterminal_produced: 97, } } 244 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 98, + states_to_pop: 4, + nonterminal_produced: 97, } } 245 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 98, + states_to_pop: 3, + nonterminal_produced: 97, } } 246 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 2, nonterminal_produced: 98, } } 247 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 99, + states_to_pop: 1, + nonterminal_produced: 98, } } 248 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 99, } } 249 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 100, + states_to_pop: 1, + nonterminal_produced: 99, } } 250 => { @@ -7425,73 +7635,73 @@ mod __parse__Top { 251 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 101, + nonterminal_produced: 100, } } 252 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 101, + nonterminal_produced: 100, } } 253 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 101, + nonterminal_produced: 100, } } 254 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 101, + nonterminal_produced: 100, } } 255 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 101, + nonterminal_produced: 100, } } 256 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 101, + nonterminal_produced: 100, } } 257 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 101, + nonterminal_produced: 100, } } 258 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 101, + nonterminal_produced: 100, } } 259 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 101, + nonterminal_produced: 100, } } 260 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 101, + nonterminal_produced: 100, } } 261 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 101, + nonterminal_produced: 100, } } 262 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 101, + nonterminal_produced: 100, } } 263 => { @@ -7502,104 +7712,104 @@ mod __parse__Top { } 264 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 6, nonterminal_produced: 102, } } 265 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 103, + states_to_pop: 5, + nonterminal_produced: 102, } } 266 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 103, + states_to_pop: 7, + nonterminal_produced: 102, } } 267 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 103, + states_to_pop: 6, + nonterminal_produced: 102, } } 268 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 103, + states_to_pop: 5, + nonterminal_produced: 102, } } 269 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 103, + states_to_pop: 4, + nonterminal_produced: 102, } } 270 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 103, + states_to_pop: 6, + nonterminal_produced: 102, } } 271 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 103, + states_to_pop: 5, + nonterminal_produced: 102, } } 272 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, + states_to_pop: 2, nonterminal_produced: 103, } } 273 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 104, + nonterminal_produced: 103, } } 274 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 1, nonterminal_produced: 104, } } 275 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 105, + nonterminal_produced: 104, } } 276 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 105, + nonterminal_produced: 104, } } 277 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 105, + nonterminal_produced: 104, } } 278 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 105, + nonterminal_produced: 104, } } 279 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 105, + nonterminal_produced: 104, } } 280 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 105, + nonterminal_produced: 104, } } 281 => { @@ -7610,20 +7820,20 @@ mod __parse__Top { } 282 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 106, + states_to_pop: 0, + nonterminal_produced: 105, } } 283 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 106, + states_to_pop: 2, + nonterminal_produced: 105, } } 284 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 106, + states_to_pop: 1, + nonterminal_produced: 105, } } 285 => { @@ -7634,20 +7844,20 @@ mod __parse__Top { } 286 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 107, + states_to_pop: 0, + nonterminal_produced: 106, } } 287 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 107, + states_to_pop: 2, + nonterminal_produced: 106, } } 288 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 107, + states_to_pop: 1, + nonterminal_produced: 106, } } 289 => { @@ -7664,68 +7874,68 @@ mod __parse__Top { } 291 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 109, + states_to_pop: 0, + nonterminal_produced: 108, } } 292 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 1, nonterminal_produced: 109, } } 293 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 110, + nonterminal_produced: 109, } } 294 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 110, + nonterminal_produced: 109, } } 295 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 110, + nonterminal_produced: 109, } } 296 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 110, + nonterminal_produced: 109, } } 297 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 110, + nonterminal_produced: 109, } } 298 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 110, + nonterminal_produced: 109, } } 299 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 110, - } + states_to_pop: 2, + nonterminal_produced: 109, + } } 300 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 110, + states_to_pop: 1, + nonterminal_produced: 109, } } 301 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 110, + states_to_pop: 2, + nonterminal_produced: 109, } } 302 => { @@ -7736,20 +7946,20 @@ mod __parse__Top { } 303 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 111, + states_to_pop: 1, + nonterminal_produced: 110, } } 304 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 111, } } 305 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 112, + states_to_pop: 1, + nonterminal_produced: 111, } } 306 => { @@ -7761,61 +7971,61 @@ mod __parse__Top { 307 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 113, + nonterminal_produced: 112, } } 308 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 113, + nonterminal_produced: 112, } } 309 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 113, + nonterminal_produced: 112, } } 310 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 113, + nonterminal_produced: 112, } } 311 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 113, + nonterminal_produced: 112, } } 312 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 113, + nonterminal_produced: 112, } } 313 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 113, + nonterminal_produced: 112, } } 314 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 113, } } 315 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 0, nonterminal_produced: 114, } } 316 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 115, + states_to_pop: 1, + nonterminal_produced: 114, } } 317 => { @@ -7826,26 +8036,26 @@ mod __parse__Top { } 318 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 116, + states_to_pop: 2, + nonterminal_produced: 115, } } 319 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 1, nonterminal_produced: 116, } } 320 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 117, + nonterminal_produced: 116, } } 321 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 117, + nonterminal_produced: 116, } } 322 => { @@ -7862,26 +8072,26 @@ mod __parse__Top { } 324 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 119, + states_to_pop: 2, + nonterminal_produced: 118, } } 325 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 3, nonterminal_produced: 119, } } 326 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 0, nonterminal_produced: 120, } } 327 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 121, + states_to_pop: 1, + nonterminal_produced: 120, } } 328 => { @@ -7892,8 +8102,8 @@ mod __parse__Top { } 329 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 122, + states_to_pop: 2, + nonterminal_produced: 121, } } 330 => { @@ -7904,32 +8114,32 @@ mod __parse__Top { } 331 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 1, nonterminal_produced: 123, } } 332 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 124, + states_to_pop: 2, + nonterminal_produced: 123, } } 333 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 3, nonterminal_produced: 124, } } 334 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 2, nonterminal_produced: 125, } } 335 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 126, + states_to_pop: 1, + nonterminal_produced: 125, } } 336 => { @@ -7940,32 +8150,32 @@ mod __parse__Top { } 337 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 127, + states_to_pop: 0, + nonterminal_produced: 126, } } 338 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 1, nonterminal_produced: 127, } } 339 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 128, + states_to_pop: 2, + nonterminal_produced: 127, } } 340 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 3, nonterminal_produced: 128, } } 341 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 129, + states_to_pop: 1, + nonterminal_produced: 128, } } 342 => { @@ -7976,86 +8186,86 @@ mod __parse__Top { } 343 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 130, + states_to_pop: 0, + nonterminal_produced: 129, } } 344 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 4, nonterminal_produced: 130, } } 345 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 131, + states_to_pop: 3, + nonterminal_produced: 130, } } 346 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 131, + states_to_pop: 6, + nonterminal_produced: 130, } } 347 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, + states_to_pop: 1, nonterminal_produced: 131, } } 348 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 132, + states_to_pop: 2, + nonterminal_produced: 131, } } 349 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 5, nonterminal_produced: 132, } } 350 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 133, + states_to_pop: 7, + nonterminal_produced: 132, } } 351 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, + states_to_pop: 1, nonterminal_produced: 133, } } 352 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 134, + states_to_pop: 2, + nonterminal_produced: 133, } } 353 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 3, nonterminal_produced: 134, } } 354 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 135, + states_to_pop: 1, + nonterminal_produced: 134, } } 355 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 3, nonterminal_produced: 135, } } 356 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 136, + states_to_pop: 1, + nonterminal_produced: 135, } } 357 => { @@ -8066,14 +8276,14 @@ mod __parse__Top { } 358 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 137, } } 359 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 138, + states_to_pop: 1, + nonterminal_produced: 137, } } 360 => { @@ -8091,7 +8301,7 @@ mod __parse__Top { 362 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 140, + nonterminal_produced: 139, } } 363 => { @@ -8102,43 +8312,43 @@ mod __parse__Top { } 364 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 141, + states_to_pop: 2, + nonterminal_produced: 140, } } 365 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 141, + states_to_pop: 3, + nonterminal_produced: 140, } } 366 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 141, + states_to_pop: 4, + nonterminal_produced: 140, } } 367 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 141, + states_to_pop: 3, + nonterminal_produced: 140, } } 368 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 2, nonterminal_produced: 141, } } 369 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 1, nonterminal_produced: 142, } } 370 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 0, nonterminal_produced: 142, } } @@ -8150,13 +8360,13 @@ mod __parse__Top { } 372 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 3, nonterminal_produced: 143, } } 373 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 0, nonterminal_produced: 144, } } @@ -8169,505 +8379,505 @@ mod __parse__Top { 375 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 144, + nonterminal_produced: 145, } } 376 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 144, + nonterminal_produced: 146, } } 377 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 144, + states_to_pop: 0, + nonterminal_produced: 146, } } 378 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 144, + nonterminal_produced: 147, } } 379 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 10, - nonterminal_produced: 145, + states_to_pop: 1, + nonterminal_produced: 147, } } 380 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 145, + states_to_pop: 0, + nonterminal_produced: 148, } } 381 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, - nonterminal_produced: 145, + states_to_pop: 1, + nonterminal_produced: 148, } } 382 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 145, + states_to_pop: 1, + nonterminal_produced: 149, } } 383 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, - nonterminal_produced: 146, + states_to_pop: 2, + nonterminal_produced: 149, } } 384 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 146, + states_to_pop: 6, + nonterminal_produced: 150, } } 385 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 10, - nonterminal_produced: 146, + states_to_pop: 5, + nonterminal_produced: 150, } } 386 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, - nonterminal_produced: 146, + states_to_pop: 5, + nonterminal_produced: 150, } } 387 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 146, + states_to_pop: 4, + nonterminal_produced: 150, } } 388 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 146, + states_to_pop: 5, + nonterminal_produced: 150, } } 389 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 146, + states_to_pop: 4, + nonterminal_produced: 150, } } 390 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 146, + states_to_pop: 4, + nonterminal_produced: 150, } } 391 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 146, + states_to_pop: 3, + nonterminal_produced: 150, } } 392 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 146, + states_to_pop: 2, + nonterminal_produced: 151, } } 393 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, - nonterminal_produced: 146, + states_to_pop: 1, + nonterminal_produced: 151, } } 394 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 146, + states_to_pop: 2, + nonterminal_produced: 152, } } 395 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 146, + states_to_pop: 1, + nonterminal_produced: 152, } } 396 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 146, + states_to_pop: 1, + nonterminal_produced: 153, } } 397 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 146, + states_to_pop: 1, + nonterminal_produced: 153, } } 398 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 146, + states_to_pop: 2, + nonterminal_produced: 153, } } 399 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 147, + states_to_pop: 1, + nonterminal_produced: 153, } } 400 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 147, + nonterminal_produced: 153, } } 401 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 147, + states_to_pop: 1, + nonterminal_produced: 153, } } 402 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 147, + states_to_pop: 10, + nonterminal_produced: 154, } } 403 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 147, + states_to_pop: 7, + nonterminal_produced: 154, } } 404 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 148, + states_to_pop: 9, + nonterminal_produced: 154, } } 405 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 148, + states_to_pop: 6, + nonterminal_produced: 154, } } 406 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 149, + states_to_pop: 9, + nonterminal_produced: 155, } } 407 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 149, + states_to_pop: 8, + nonterminal_produced: 155, } } 408 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 150, + states_to_pop: 10, + nonterminal_produced: 155, } } 409 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 150, + states_to_pop: 9, + nonterminal_produced: 155, } } 410 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 151, + states_to_pop: 7, + nonterminal_produced: 155, } } 411 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 152, + states_to_pop: 6, + nonterminal_produced: 155, } } 412 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 153, + states_to_pop: 8, + nonterminal_produced: 155, } } 413 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, - nonterminal_produced: 154, + nonterminal_produced: 155, } } 414 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 154, + states_to_pop: 8, + nonterminal_produced: 155, } } 415 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 154, + states_to_pop: 7, + nonterminal_produced: 155, } } 416 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 154, + states_to_pop: 9, + nonterminal_produced: 155, } } 417 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 8, nonterminal_produced: 155, } } 418 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 6, nonterminal_produced: 155, } } 419 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 156, + states_to_pop: 5, + nonterminal_produced: 155, } } 420 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 156, + states_to_pop: 7, + nonterminal_produced: 155, } } 421 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 157, + states_to_pop: 6, + nonterminal_produced: 155, } } 422 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 157, + states_to_pop: 2, + nonterminal_produced: 156, } } 423 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 157, + states_to_pop: 1, + nonterminal_produced: 156, } } 424 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 157, + states_to_pop: 3, + nonterminal_produced: 156, } } 425 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 158, + states_to_pop: 2, + nonterminal_produced: 156, } } 426 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 158, + states_to_pop: 2, + nonterminal_produced: 156, } } 427 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 159, + states_to_pop: 1, + nonterminal_produced: 157, } } 428 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 159, + states_to_pop: 0, + nonterminal_produced: 157, } } 429 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 160, + states_to_pop: 2, + nonterminal_produced: 158, } } 430 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 160, + states_to_pop: 1, + nonterminal_produced: 158, } } 431 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 161, + states_to_pop: 2, + nonterminal_produced: 159, } } 432 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 161, + states_to_pop: 1, + nonterminal_produced: 159, } } 433 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 161, + states_to_pop: 2, + nonterminal_produced: 160, } } 434 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 162, + nonterminal_produced: 161, } } 435 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, + states_to_pop: 1, nonterminal_produced: 162, } } 436 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 7, nonterminal_produced: 163, } } 437 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 164, + states_to_pop: 4, + nonterminal_produced: 163, } } 438 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 165, + states_to_pop: 8, + nonterminal_produced: 163, } } 439 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 166, + states_to_pop: 5, + nonterminal_produced: 163, } } 440 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 166, + states_to_pop: 3, + nonterminal_produced: 164, } } 441 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 167, + states_to_pop: 1, + nonterminal_produced: 164, } } 442 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 167, + states_to_pop: 3, + nonterminal_produced: 165, } } 443 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 168, + states_to_pop: 1, + nonterminal_produced: 165, } } 444 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 168, + states_to_pop: 1, + nonterminal_produced: 166, } } 445 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 169, + states_to_pop: 4, + nonterminal_produced: 166, } } 446 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 169, + states_to_pop: 3, + nonterminal_produced: 166, } } 447 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 170, + nonterminal_produced: 166, } } 448 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 170, + states_to_pop: 1, + nonterminal_produced: 167, } } 449 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 171, + nonterminal_produced: 167, } } 450 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 171, + states_to_pop: 0, + nonterminal_produced: 168, } } 451 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 171, + nonterminal_produced: 168, } } 452 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 171, + nonterminal_produced: 169, } } 453 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 171, + states_to_pop: 2, + nonterminal_produced: 169, } } 454 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 171, + nonterminal_produced: 170, } } 455 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 172, + states_to_pop: 2, + nonterminal_produced: 170, } } 456 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 172, + nonterminal_produced: 170, } } 457 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 172, + states_to_pop: 2, + nonterminal_produced: 171, } } 458 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 172, + states_to_pop: 4, + nonterminal_produced: 171, } } 459 => { @@ -8679,133 +8889,133 @@ mod __parse__Top { 460 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 172, + nonterminal_produced: 173, } } 461 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 172, + states_to_pop: 2, + nonterminal_produced: 174, } } 462 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 173, + nonterminal_produced: 175, } } 463 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 173, + states_to_pop: 1, + nonterminal_produced: 175, } } 464 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 173, + states_to_pop: 2, + nonterminal_produced: 176, } } 465 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 173, + states_to_pop: 1, + nonterminal_produced: 176, } } 466 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 173, + states_to_pop: 5, + nonterminal_produced: 177, } } 467 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 173, + states_to_pop: 4, + nonterminal_produced: 177, } } 468 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 173, - } + states_to_pop: 4, + nonterminal_produced: 177, + } } 469 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 174, + states_to_pop: 3, + nonterminal_produced: 177, } } 470 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 174, + states_to_pop: 2, + nonterminal_produced: 178, } } 471 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 175, + nonterminal_produced: 178, } } 472 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 175, + states_to_pop: 1, + nonterminal_produced: 179, } } 473 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 176, + states_to_pop: 0, + nonterminal_produced: 179, } } 474 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 177, + states_to_pop: 1, + nonterminal_produced: 180, } } 475 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 178, + nonterminal_produced: 180, } } 476 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 179, + states_to_pop: 1, + nonterminal_produced: 180, } } 477 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 179, + states_to_pop: 1, + nonterminal_produced: 180, } } 478 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, + states_to_pop: 1, nonterminal_produced: 180, } } 479 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, + states_to_pop: 1, nonterminal_produced: 180, } } 480 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 180, + states_to_pop: 1, + nonterminal_produced: 181, } } 481 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 180, + states_to_pop: 1, + nonterminal_produced: 181, } } 482 => { @@ -8840,2579 +9050,2783 @@ mod __parse__Top { } 487 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, + states_to_pop: 2, nonterminal_produced: 182, } } 488 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 183, + states_to_pop: 4, + nonterminal_produced: 182, } } 489 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 184, + states_to_pop: 3, + nonterminal_produced: 182, } } 490 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 184, + states_to_pop: 5, + nonterminal_produced: 182, } } 491 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 185, + states_to_pop: 4, + nonterminal_produced: 182, } } 492 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 185, + states_to_pop: 7, + nonterminal_produced: 182, } } 493 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 186, + states_to_pop: 6, + nonterminal_produced: 182, } } 494 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 187, + states_to_pop: 5, + nonterminal_produced: 183, } } 495 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 187, + states_to_pop: 4, + nonterminal_produced: 183, } } 496 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 188, + states_to_pop: 1, + nonterminal_produced: 184, } } 497 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 188, + states_to_pop: 2, + nonterminal_produced: 184, } } 498 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 189, + states_to_pop: 3, + nonterminal_produced: 185, } } 499 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 189, + nonterminal_produced: 186, } } 500 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 190, + nonterminal_produced: 187, } } 501 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 190, + nonterminal_produced: 188, } } 502 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 191, + states_to_pop: 3, + nonterminal_produced: 188, } } 503 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 191, + states_to_pop: 7, + nonterminal_produced: 189, } } 504 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 192, + states_to_pop: 8, + nonterminal_produced: 189, } } 505 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 192, + states_to_pop: 8, + nonterminal_produced: 189, } } 506 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 192, + states_to_pop: 7, + nonterminal_produced: 189, } } 507 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 192, + states_to_pop: 1, + nonterminal_produced: 190, } } 508 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 193, + states_to_pop: 1, + nonterminal_produced: 190, } } 509 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 193, + nonterminal_produced: 190, } } 510 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 193, + states_to_pop: 1, + nonterminal_produced: 190, } } 511 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 193, + states_to_pop: 1, + nonterminal_produced: 190, } } 512 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 194, + states_to_pop: 3, + nonterminal_produced: 191, } } 513 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 194, + states_to_pop: 1, + nonterminal_produced: 192, } } 514 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 195, + nonterminal_produced: 193, } } 515 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 195, + states_to_pop: 1, + nonterminal_produced: 193, } } 516 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 196, + nonterminal_produced: 194, } } 517 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 196, + states_to_pop: 1, + nonterminal_produced: 194, } } 518 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 197, + states_to_pop: 2, + nonterminal_produced: 195, } } 519 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 197, + states_to_pop: 2, + nonterminal_produced: 196, } } 520 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 198, + nonterminal_produced: 196, } } 521 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 198, + states_to_pop: 2, + nonterminal_produced: 197, } } 522 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 199, + nonterminal_produced: 197, } } 523 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 199, + states_to_pop: 1, + nonterminal_produced: 198, } } 524 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 200, + states_to_pop: 3, + nonterminal_produced: 198, } } 525 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 200, + states_to_pop: 1, + nonterminal_produced: 199, } } 526 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 201, + states_to_pop: 3, + nonterminal_produced: 199, } } 527 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 201, + states_to_pop: 1, + nonterminal_produced: 200, } } 528 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 202, + states_to_pop: 3, + nonterminal_produced: 200, } } 529 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 202, + nonterminal_produced: 201, } } 530 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 203, + nonterminal_produced: 201, } } 531 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 203, + states_to_pop: 5, + nonterminal_produced: 201, } } 532 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 204, + states_to_pop: 3, + nonterminal_produced: 201, } } 533 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 204, + states_to_pop: 3, + nonterminal_produced: 202, } } 534 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 205, + states_to_pop: 1, + nonterminal_produced: 202, } } 535 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 205, + states_to_pop: 5, + nonterminal_produced: 202, } } 536 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 206, + states_to_pop: 3, + nonterminal_produced: 202, } } 537 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 206, + states_to_pop: 1, + nonterminal_produced: 203, } } 538 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 207, + states_to_pop: 3, + nonterminal_produced: 203, } } 539 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 207, + states_to_pop: 1, + nonterminal_produced: 204, } } 540 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 208, + states_to_pop: 3, + nonterminal_produced: 204, } } 541 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 208, + states_to_pop: 1, + nonterminal_produced: 205, } } 542 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 208, + states_to_pop: 3, + nonterminal_produced: 205, } } 543 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 209, + nonterminal_produced: 206, } } 544 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 209, + nonterminal_produced: 206, } } 545 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 209, + states_to_pop: 1, + nonterminal_produced: 207, } } 546 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 210, + states_to_pop: 3, + nonterminal_produced: 207, } } 547 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, - nonterminal_produced: 210, + states_to_pop: 1, + nonterminal_produced: 208, } } 548 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 10, - nonterminal_produced: 210, + states_to_pop: 3, + nonterminal_produced: 208, } } 549 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 210, + states_to_pop: 1, + nonterminal_produced: 209, } } 550 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 210, + states_to_pop: 3, + nonterminal_produced: 209, } } 551 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, + states_to_pop: 1, nonterminal_produced: 210, } } 552 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, + states_to_pop: 3, nonterminal_produced: 210, } } 553 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 10, - nonterminal_produced: 210, + states_to_pop: 1, + nonterminal_produced: 211, } } 554 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 11, - nonterminal_produced: 210, + states_to_pop: 3, + nonterminal_produced: 211, } } 555 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 210, + states_to_pop: 1, + nonterminal_produced: 212, } } 556 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, - nonterminal_produced: 210, + states_to_pop: 1, + nonterminal_produced: 212, } } 557 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 10, - nonterminal_produced: 210, + states_to_pop: 2, + nonterminal_produced: 213, } } 558 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 210, + states_to_pop: 1, + nonterminal_produced: 213, } } 559 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 210, + states_to_pop: 2, + nonterminal_produced: 214, } } 560 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 210, + states_to_pop: 1, + nonterminal_produced: 214, } } 561 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 210, + states_to_pop: 1, + nonterminal_produced: 215, } } 562 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 210, + states_to_pop: 3, + nonterminal_produced: 215, } } 563 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 210, + states_to_pop: 1, + nonterminal_produced: 216, } } 564 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 210, + states_to_pop: 3, + nonterminal_produced: 216, } } 565 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 210, + states_to_pop: 1, + nonterminal_produced: 217, } } 566 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, - nonterminal_produced: 210, + states_to_pop: 3, + nonterminal_produced: 217, } } 567 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 210, + states_to_pop: 4, + nonterminal_produced: 217, } } 568 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 210, + states_to_pop: 1, + nonterminal_produced: 218, } } 569 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 210, + states_to_pop: 3, + nonterminal_produced: 218, } } 570 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 210, + states_to_pop: 4, + nonterminal_produced: 218, } } 571 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 210, + states_to_pop: 7, + nonterminal_produced: 219, } } 572 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 210, + states_to_pop: 9, + nonterminal_produced: 219, } } 573 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 210, + states_to_pop: 10, + nonterminal_produced: 219, } } 574 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 210, + states_to_pop: 6, + nonterminal_produced: 219, } } 575 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, - nonterminal_produced: 210, + states_to_pop: 8, + nonterminal_produced: 219, } } 576 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 210, + states_to_pop: 9, + nonterminal_produced: 219, } } 577 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 210, + states_to_pop: 8, + nonterminal_produced: 219, } } 578 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 210, + states_to_pop: 10, + nonterminal_produced: 219, } } 579 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 210, + states_to_pop: 11, + nonterminal_produced: 219, } } 580 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, - nonterminal_produced: 210, + states_to_pop: 7, + nonterminal_produced: 219, } } 581 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 10, - nonterminal_produced: 210, + states_to_pop: 9, + nonterminal_produced: 219, } } 582 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 210, + states_to_pop: 10, + nonterminal_produced: 219, } } 583 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 210, + states_to_pop: 5, + nonterminal_produced: 219, } } 584 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, - nonterminal_produced: 210, + states_to_pop: 7, + nonterminal_produced: 219, } } 585 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 210, + states_to_pop: 8, + nonterminal_produced: 219, } } 586 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 210, + states_to_pop: 4, + nonterminal_produced: 219, } } 587 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 210, + states_to_pop: 6, + nonterminal_produced: 219, } } 588 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 210, + states_to_pop: 7, + nonterminal_produced: 219, } } 589 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 210, + states_to_pop: 6, + nonterminal_produced: 219, } } 590 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 210, + states_to_pop: 8, + nonterminal_produced: 219, } } 591 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 210, + states_to_pop: 9, + nonterminal_produced: 219, } } 592 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 210, + states_to_pop: 5, + nonterminal_produced: 219, } } 593 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 210, + states_to_pop: 7, + nonterminal_produced: 219, } } 594 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 210, + states_to_pop: 8, + nonterminal_produced: 219, } } 595 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 210, + states_to_pop: 2, + nonterminal_produced: 219, } } 596 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 210, + states_to_pop: 4, + nonterminal_produced: 219, } } 597 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 210, + states_to_pop: 5, + nonterminal_produced: 219, } } 598 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 210, + states_to_pop: 6, + nonterminal_produced: 219, } } 599 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 210, + states_to_pop: 8, + nonterminal_produced: 219, } } 600 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 210, + states_to_pop: 9, + nonterminal_produced: 219, } } 601 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 210, + states_to_pop: 5, + nonterminal_produced: 219, } } 602 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, - nonterminal_produced: 210, + nonterminal_produced: 219, } } 603 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 210, + states_to_pop: 8, + nonterminal_produced: 219, } } 604 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 210, + states_to_pop: 7, + nonterminal_produced: 219, } } 605 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 210, + states_to_pop: 9, + nonterminal_produced: 219, } } 606 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 210, + states_to_pop: 10, + nonterminal_produced: 219, } } 607 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 210, + states_to_pop: 6, + nonterminal_produced: 219, } } 608 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 210, + states_to_pop: 8, + nonterminal_produced: 219, } } 609 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 210, + states_to_pop: 9, + nonterminal_produced: 219, } } 610 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 210, + states_to_pop: 4, + nonterminal_produced: 219, } } 611 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 210, + states_to_pop: 6, + nonterminal_produced: 219, } } 612 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 210, + states_to_pop: 7, + nonterminal_produced: 219, } } 613 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 210, + nonterminal_produced: 219, } } 614 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 210, + states_to_pop: 5, + nonterminal_produced: 219, } } 615 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 210, + states_to_pop: 6, + nonterminal_produced: 219, } } 616 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, - nonterminal_produced: 210, + nonterminal_produced: 219, } } 617 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 210, + states_to_pop: 7, + nonterminal_produced: 219, } } 618 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 210, + states_to_pop: 8, + nonterminal_produced: 219, } } 619 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 210, + states_to_pop: 4, + nonterminal_produced: 219, } } 620 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 210, + states_to_pop: 6, + nonterminal_produced: 219, } } 621 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 210, + states_to_pop: 7, + nonterminal_produced: 219, } } 622 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 210, + states_to_pop: 1, + nonterminal_produced: 219, } } 623 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 210, + states_to_pop: 3, + nonterminal_produced: 219, } } 624 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 211, + states_to_pop: 4, + nonterminal_produced: 219, } } 625 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, - nonterminal_produced: 211, + states_to_pop: 4, + nonterminal_produced: 219, } } 626 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 10, - nonterminal_produced: 211, + states_to_pop: 6, + nonterminal_produced: 219, } } 627 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 211, + states_to_pop: 7, + nonterminal_produced: 219, } } 628 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 211, + states_to_pop: 3, + nonterminal_produced: 219, } } 629 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, - nonterminal_produced: 211, + states_to_pop: 5, + nonterminal_produced: 219, } } 630 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 211, + states_to_pop: 6, + nonterminal_produced: 219, } } 631 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 10, - nonterminal_produced: 211, + states_to_pop: 5, + nonterminal_produced: 219, } } 632 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 11, - nonterminal_produced: 211, + states_to_pop: 4, + nonterminal_produced: 219, } } 633 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 211, + states_to_pop: 6, + nonterminal_produced: 219, } } 634 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, - nonterminal_produced: 211, + states_to_pop: 5, + nonterminal_produced: 219, } } 635 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 10, - nonterminal_produced: 211, + states_to_pop: 3, + nonterminal_produced: 219, } } 636 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 211, + states_to_pop: 2, + nonterminal_produced: 219, } } 637 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 211, + states_to_pop: 4, + nonterminal_produced: 219, } } 638 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 211, + states_to_pop: 3, + nonterminal_produced: 219, } } 639 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 211, + nonterminal_produced: 219, } } 640 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 211, + states_to_pop: 3, + nonterminal_produced: 219, } } 641 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 211, + states_to_pop: 5, + nonterminal_produced: 219, } } 642 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 211, + states_to_pop: 4, + nonterminal_produced: 219, } } 643 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 211, + states_to_pop: 2, + nonterminal_produced: 219, } } 644 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, - nonterminal_produced: 211, + states_to_pop: 1, + nonterminal_produced: 219, } } 645 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 211, + states_to_pop: 3, + nonterminal_produced: 219, } } 646 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 211, + states_to_pop: 2, + nonterminal_produced: 219, } } 647 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 211, + states_to_pop: 2, + nonterminal_produced: 219, } } 648 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 211, + states_to_pop: 1, + nonterminal_produced: 219, } } 649 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 211, + states_to_pop: 7, + nonterminal_produced: 220, } } 650 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 211, + states_to_pop: 9, + nonterminal_produced: 220, } } 651 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 211, + states_to_pop: 10, + nonterminal_produced: 220, } } 652 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 211, + states_to_pop: 6, + nonterminal_produced: 220, } } 653 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, - nonterminal_produced: 211, + states_to_pop: 8, + nonterminal_produced: 220, } } 654 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 211, + states_to_pop: 9, + nonterminal_produced: 220, } } 655 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 211, + states_to_pop: 8, + nonterminal_produced: 220, } } 656 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 211, + states_to_pop: 10, + nonterminal_produced: 220, } } 657 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 211, + states_to_pop: 11, + nonterminal_produced: 220, } } 658 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, - nonterminal_produced: 211, + states_to_pop: 7, + nonterminal_produced: 220, } } 659 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 10, - nonterminal_produced: 211, + states_to_pop: 9, + nonterminal_produced: 220, } } 660 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 211, + states_to_pop: 10, + nonterminal_produced: 220, } } 661 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 211, + states_to_pop: 5, + nonterminal_produced: 220, } } 662 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 9, - nonterminal_produced: 211, + states_to_pop: 7, + nonterminal_produced: 220, } } 663 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 211, + states_to_pop: 8, + nonterminal_produced: 220, } } 664 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 211, + states_to_pop: 4, + nonterminal_produced: 220, } } 665 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 211, + states_to_pop: 6, + nonterminal_produced: 220, } } 666 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 211, + states_to_pop: 7, + nonterminal_produced: 220, } } 667 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 211, + states_to_pop: 6, + nonterminal_produced: 220, } } 668 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 211, + states_to_pop: 8, + nonterminal_produced: 220, } } 669 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 211, + states_to_pop: 9, + nonterminal_produced: 220, } } 670 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 211, + states_to_pop: 5, + nonterminal_produced: 220, } } 671 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 8, - nonterminal_produced: 211, + states_to_pop: 7, + nonterminal_produced: 220, } } 672 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 211, + states_to_pop: 8, + nonterminal_produced: 220, } } 673 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 211, + states_to_pop: 2, + nonterminal_produced: 220, } } 674 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 7, - nonterminal_produced: 211, + states_to_pop: 4, + nonterminal_produced: 220, } } 675 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 211, + states_to_pop: 5, + nonterminal_produced: 220, } } 676 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 211, + states_to_pop: 6, + nonterminal_produced: 220, } } 677 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 211, + states_to_pop: 8, + nonterminal_produced: 220, } } 678 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 211, + states_to_pop: 9, + nonterminal_produced: 220, } } 679 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 211, + states_to_pop: 5, + nonterminal_produced: 220, } } 680 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, - nonterminal_produced: 211, + nonterminal_produced: 220, } } 681 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 211, + states_to_pop: 8, + nonterminal_produced: 220, } } 682 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 211, + states_to_pop: 7, + nonterminal_produced: 220, } } 683 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 211, + states_to_pop: 9, + nonterminal_produced: 220, } } 684 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 211, + states_to_pop: 10, + nonterminal_produced: 220, } } 685 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 211, + states_to_pop: 6, + nonterminal_produced: 220, } } 686 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 211, + states_to_pop: 8, + nonterminal_produced: 220, } } 687 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 211, + states_to_pop: 9, + nonterminal_produced: 220, } } 688 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 211, + states_to_pop: 4, + nonterminal_produced: 220, } } 689 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 211, + states_to_pop: 6, + nonterminal_produced: 220, } } 690 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 211, + states_to_pop: 7, + nonterminal_produced: 220, } } 691 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 211, + nonterminal_produced: 220, } } 692 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 211, + states_to_pop: 5, + nonterminal_produced: 220, } } 693 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 211, + states_to_pop: 6, + nonterminal_produced: 220, } } 694 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, - nonterminal_produced: 211, + nonterminal_produced: 220, } } 695 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 211, + states_to_pop: 7, + nonterminal_produced: 220, } } 696 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 211, + states_to_pop: 8, + nonterminal_produced: 220, } } 697 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 211, + states_to_pop: 4, + nonterminal_produced: 220, } } 698 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 211, + states_to_pop: 6, + nonterminal_produced: 220, } } 699 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 211, + states_to_pop: 7, + nonterminal_produced: 220, } } 700 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 211, + states_to_pop: 1, + nonterminal_produced: 220, } } 701 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 211, + states_to_pop: 3, + nonterminal_produced: 220, } } 702 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 212, + states_to_pop: 4, + nonterminal_produced: 220, } } 703 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 212, + states_to_pop: 4, + nonterminal_produced: 220, } } 704 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 213, + states_to_pop: 6, + nonterminal_produced: 220, } } 705 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 213, + states_to_pop: 7, + nonterminal_produced: 220, } } 706 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 213, + states_to_pop: 3, + nonterminal_produced: 220, } } 707 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 213, + states_to_pop: 5, + nonterminal_produced: 220, } } 708 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 213, + states_to_pop: 6, + nonterminal_produced: 220, } } 709 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 213, + states_to_pop: 5, + nonterminal_produced: 220, } } 710 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 213, + states_to_pop: 4, + nonterminal_produced: 220, } } 711 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 213, + states_to_pop: 6, + nonterminal_produced: 220, } } 712 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 214, + states_to_pop: 5, + nonterminal_produced: 220, } } 713 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 214, + nonterminal_produced: 220, } } 714 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 214, + states_to_pop: 2, + nonterminal_produced: 220, } } 715 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 214, + nonterminal_produced: 220, } } 716 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 214, + states_to_pop: 3, + nonterminal_produced: 220, } } 717 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 214, + states_to_pop: 4, + nonterminal_produced: 220, } } 718 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 214, + nonterminal_produced: 220, } } 719 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 214, + states_to_pop: 5, + nonterminal_produced: 220, } } 720 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 215, + states_to_pop: 4, + nonterminal_produced: 220, } } 721 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 215, + nonterminal_produced: 220, } } 722 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 216, + nonterminal_produced: 220, } } 723 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 217, + states_to_pop: 3, + nonterminal_produced: 220, } } 724 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 217, + states_to_pop: 2, + nonterminal_produced: 220, } } 725 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 218, + states_to_pop: 2, + nonterminal_produced: 220, } } 726 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 218, + states_to_pop: 1, + nonterminal_produced: 220, } } 727 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 219, + states_to_pop: 1, + nonterminal_produced: 221, } } 728 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 219, + states_to_pop: 0, + nonterminal_produced: 221, } } 729 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 219, + nonterminal_produced: 222, } } 730 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 219, + nonterminal_produced: 222, } } 731 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 219, + states_to_pop: 5, + nonterminal_produced: 222, } } 732 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 219, + states_to_pop: 4, + nonterminal_produced: 222, } } 733 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 219, + nonterminal_produced: 222, } } 734 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 220, + states_to_pop: 1, + nonterminal_produced: 222, } } 735 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 220, + states_to_pop: 3, + nonterminal_produced: 222, } } 736 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 220, + states_to_pop: 2, + nonterminal_produced: 222, } } 737 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 220, + states_to_pop: 4, + nonterminal_produced: 223, } } 738 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 221, + nonterminal_produced: 223, } } 739 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 221, + states_to_pop: 5, + nonterminal_produced: 223, } } 740 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 222, + states_to_pop: 4, + nonterminal_produced: 223, } } 741 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 222, + states_to_pop: 2, + nonterminal_produced: 223, } } 742 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 1, nonterminal_produced: 223, } } 743 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 3, nonterminal_produced: 223, } } 744 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, + states_to_pop: 2, nonterminal_produced: 223, } } 745 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 223, + states_to_pop: 3, + nonterminal_produced: 224, } } 746 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 223, + states_to_pop: 2, + nonterminal_produced: 224, } } 747 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 223, + states_to_pop: 1, + nonterminal_produced: 225, } } 748 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 223, + states_to_pop: 1, + nonterminal_produced: 226, } } 749 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 224, + nonterminal_produced: 226, } } 750 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 224, + states_to_pop: 1, + nonterminal_produced: 227, } } 751 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 224, + states_to_pop: 0, + nonterminal_produced: 227, } } 752 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 225, + states_to_pop: 6, + nonterminal_produced: 228, } } 753 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 225, + states_to_pop: 5, + nonterminal_produced: 228, } } 754 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 225, + nonterminal_produced: 228, } } 755 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 225, + states_to_pop: 3, + nonterminal_produced: 228, } } 756 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 225, + nonterminal_produced: 228, } } 757 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 225, + nonterminal_produced: 228, } } 758 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 225, + nonterminal_produced: 228, } } 759 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 225, + states_to_pop: 2, + nonterminal_produced: 229, } } 760 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 225, + states_to_pop: 2, + nonterminal_produced: 229, } } 761 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 226, + states_to_pop: 1, + nonterminal_produced: 229, } } 762 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 226, + nonterminal_produced: 229, } } 763 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 227, + nonterminal_produced: 230, } } 764 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 227, + nonterminal_produced: 230, } } 765 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 228, + nonterminal_produced: 231, } } 766 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 228, + nonterminal_produced: 231, } } 767 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 229, + states_to_pop: 0, + nonterminal_produced: 232, } } 768 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 229, + states_to_pop: 2, + nonterminal_produced: 232, } } 769 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 230, + states_to_pop: 4, + nonterminal_produced: 232, } } 770 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 230, + states_to_pop: 5, + nonterminal_produced: 232, } } 771 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 230, + states_to_pop: 3, + nonterminal_produced: 232, } } 772 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 230, + states_to_pop: 4, + nonterminal_produced: 232, } } 773 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 231, + states_to_pop: 2, + nonterminal_produced: 232, } } 774 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 231, + states_to_pop: 1, + nonterminal_produced: 233, } } 775 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 232, + states_to_pop: 4, + nonterminal_produced: 233, } } 776 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 232, + states_to_pop: 2, + nonterminal_produced: 233, } } 777 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 233, + states_to_pop: 3, + nonterminal_produced: 234, } } 778 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 233, + states_to_pop: 2, + nonterminal_produced: 234, } } 779 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 4, nonterminal_produced: 234, } } 780 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 5, nonterminal_produced: 234, } } 781 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 4, nonterminal_produced: 234, } } 782 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 3, nonterminal_produced: 234, } } 783 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 2, nonterminal_produced: 234, } } 784 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 4, nonterminal_produced: 234, } } 785 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 3, nonterminal_produced: 234, } } 786 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 234, + states_to_pop: 2, + nonterminal_produced: 235, } } 787 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 234, + nonterminal_produced: 235, } } 788 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 234, + states_to_pop: 3, + nonterminal_produced: 236, } } 789 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 234, + nonterminal_produced: 236, } } 790 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 235, + states_to_pop: 3, + nonterminal_produced: 237, } } 791 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 236, + states_to_pop: 1, + nonterminal_produced: 237, } } 792 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 237, + states_to_pop: 1, + nonterminal_produced: 238, } } 793 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 237, + nonterminal_produced: 238, } } 794 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 238, + states_to_pop: 5, + nonterminal_produced: 239, } } 795 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 238, + states_to_pop: 6, + nonterminal_produced: 239, } } 796 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 4, nonterminal_produced: 239, } } 797 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 240, + states_to_pop: 5, + nonterminal_produced: 239, } } 798 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 1, nonterminal_produced: 240, } } 799 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 241, + states_to_pop: 2, + nonterminal_produced: 240, } } 800 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, + states_to_pop: 2, nonterminal_produced: 241, } } 801 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 1, nonterminal_produced: 241, } } 802 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 241, + states_to_pop: 1, + nonterminal_produced: 242, } } 803 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 241, + states_to_pop: 0, + nonterminal_produced: 242, } } 804 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 241, + states_to_pop: 1, + nonterminal_produced: 243, } } 805 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 241, + states_to_pop: 1, + nonterminal_produced: 243, } } 806 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 241, + states_to_pop: 1, + nonterminal_produced: 243, } } 807 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 241, + states_to_pop: 1, + nonterminal_produced: 243, } } 808 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 241, + states_to_pop: 1, + nonterminal_produced: 243, } } 809 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 242, + nonterminal_produced: 243, } } 810 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 242, + states_to_pop: 1, + nonterminal_produced: 243, } } 811 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 242, + states_to_pop: 1, + nonterminal_produced: 243, } } 812 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 242, + states_to_pop: 1, + nonterminal_produced: 243, } } 813 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 242, + states_to_pop: 1, + nonterminal_produced: 243, } } 814 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 242, + states_to_pop: 1, + nonterminal_produced: 243, } } 815 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 242, + nonterminal_produced: 244, + } + } + 816 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 245, + } + } + 817 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 3, + nonterminal_produced: 246, + } + } + 818 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 246, + } + } + 819 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 247, + } + } + 820 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 0, + nonterminal_produced: 247, + } + } + 821 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 248, + } + } + 822 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 249, + } + } + 823 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 0, + nonterminal_produced: 249, + } + } + 824 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 3, + nonterminal_produced: 250, + } + } + 825 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 4, + nonterminal_produced: 250, + } + } + 826 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 250, + } + } + 827 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 3, + nonterminal_produced: 250, + } + } + 828 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 250, + } + } + 829 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 250, + } + } + 830 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 4, + nonterminal_produced: 250, + } + } + 831 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 5, + nonterminal_produced: 250, + } + } + 832 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 3, + nonterminal_produced: 250, + } + } + 833 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 4, + nonterminal_produced: 250, + } + } + 834 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 251, + } + } + 835 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 252, + } + } + 836 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 252, + } + } + 837 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 253, + } + } + 838 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 253, + } + } + 839 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 254, + } + } + 840 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 254, + } + } + 841 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 255, + } + } + 842 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 4, + nonterminal_produced: 255, + } + } + 843 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 3, + nonterminal_produced: 255, + } + } + 844 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 3, + nonterminal_produced: 255, + } + } + 845 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 255, + } + } + 846 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 3, + nonterminal_produced: 255, + } + } + 847 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 255, } } - 816 => { + 848 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 242, + nonterminal_produced: 255, } } - 817 => { + 849 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 242, + nonterminal_produced: 255, } } - 818 => { + 850 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 243, + nonterminal_produced: 256, } } - 819 => { + 851 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 243, + nonterminal_produced: 256, } } - 820 => { + 852 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 243, + nonterminal_produced: 256, } } - 821 => { + 853 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 243, + nonterminal_produced: 256, } } - 822 => { + 854 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 244, + nonterminal_produced: 257, } } - 823 => { + 855 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 244, + nonterminal_produced: 257, } } - 824 => { + 856 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 244, + nonterminal_produced: 257, } } - 825 => { + 857 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 244, + nonterminal_produced: 257, } } - 826 => { + 858 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 244, + nonterminal_produced: 257, } } - 827 => { + 859 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 245, + nonterminal_produced: 258, } } - 828 => { + 860 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 245, + nonterminal_produced: 258, } } - 829 => { + 861 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 246, + nonterminal_produced: 259, } } - 830 => { + 862 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 246, + nonterminal_produced: 259, } } - 831 => { + 863 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, - nonterminal_produced: 247, + nonterminal_produced: 260, } } - 832 => { + 864 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 247, + nonterminal_produced: 260, } } - 833 => { + 865 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 247, + nonterminal_produced: 260, } } - 834 => { + 866 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 248, + nonterminal_produced: 261, } } - 835 => { + 867 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 0, - nonterminal_produced: 248, + nonterminal_produced: 261, } } - 836 => { + 868 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, - nonterminal_produced: 249, + nonterminal_produced: 262, } } - 837 => { + 869 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 249, + nonterminal_produced: 262, } } - 838 => { + 870 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 249, + nonterminal_produced: 262, } } - 839 => { + 871 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 250, + nonterminal_produced: 263, } } - 840 => { + 872 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 251, + nonterminal_produced: 264, } } - 841 => { + 873 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 0, - nonterminal_produced: 251, + nonterminal_produced: 264, } } - 842 => { + 874 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 252, + nonterminal_produced: 265, } } - 843 => { + 875 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 252, + nonterminal_produced: 265, } } - 844 => { + 876 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 253, + nonterminal_produced: 266, } } - 845 => { + 877 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 253, + nonterminal_produced: 266, } } - 846 => { + 878 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 254, + nonterminal_produced: 267, } } - 847 => { + 879 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 255, + nonterminal_produced: 268, } } - 848 => { + 880 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 255, + nonterminal_produced: 268, } } - 849 => { + 881 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 256, + nonterminal_produced: 269, } } - 850 => { + 882 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 256, + nonterminal_produced: 269, } } - 851 => { + 883 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 256, + nonterminal_produced: 269, } } - 852 => { + 884 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 10, - nonterminal_produced: 257, + nonterminal_produced: 270, } } - 853 => { + 885 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, - nonterminal_produced: 257, + nonterminal_produced: 270, } } - 854 => { + 886 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, - nonterminal_produced: 257, + nonterminal_produced: 270, } } - 855 => { + 887 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 257, + nonterminal_produced: 270, } } - 856 => { + 888 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 10, - nonterminal_produced: 257, + nonterminal_produced: 270, } } - 857 => { + 889 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, - nonterminal_produced: 257, + nonterminal_produced: 270, } } - 858 => { + 890 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, - nonterminal_produced: 257, + nonterminal_produced: 270, } } - 859 => { + 891 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 257, + nonterminal_produced: 270, } } - 860 => { + 892 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, - nonterminal_produced: 257, + nonterminal_produced: 270, } } - 861 => { + 893 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 258, + nonterminal_produced: 271, } } - 862 => { + 894 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 258, + nonterminal_produced: 271, } } - 863 => { + 895 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 259, + nonterminal_produced: 272, } } - 864 => { + 896 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 259, + nonterminal_produced: 272, } } - 865 => { + 897 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 260, + nonterminal_produced: 273, } } - 866 => { + 898 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 260, + nonterminal_produced: 273, } } - 867 => { + 899 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 261, + nonterminal_produced: 274, } } - 868 => { + 900 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 261, + nonterminal_produced: 274, } } - 869 => { + 901 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 262, + nonterminal_produced: 275, } } - 870 => { + 902 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, - nonterminal_produced: 263, + nonterminal_produced: 276, } } - 871 => { + 903 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 263, + nonterminal_produced: 276, } } - 872 => { + 904 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 264, + nonterminal_produced: 277, } } - 873 => { + 905 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 264, + nonterminal_produced: 277, } } - 874 => { + 906 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 264, + nonterminal_produced: 277, } } - 875 => { + 907 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 264, + nonterminal_produced: 277, } } - 876 => { + 908 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 265, + nonterminal_produced: 278, } } - 877 => { + 909 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 265, + nonterminal_produced: 278, } } - 878 => { + 910 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 266, + nonterminal_produced: 279, } } - 879 => { + 911 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 0, - nonterminal_produced: 266, + nonterminal_produced: 279, } } - 880 => { + 912 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 267, + nonterminal_produced: 280, } } - 881 => { + 913 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 267, + nonterminal_produced: 280, } } - 882 => { + 914 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 268, + nonterminal_produced: 281, } } - 883 => { + 915 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 268, + nonterminal_produced: 281, } } - 884 => { + 916 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 268, + nonterminal_produced: 281, } } - 885 => { + 917 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 269, + nonterminal_produced: 282, } } - 886 => { + 918 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 270, + nonterminal_produced: 283, } } - 887 => { + 919 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, - nonterminal_produced: 271, + nonterminal_produced: 284, } } - 888 => { + 920 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 271, + nonterminal_produced: 284, } } - 889 => { + 921 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 272, + nonterminal_produced: 285, } } - 890 => { + 922 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 272, + nonterminal_produced: 285, } } - 891 => { + 923 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 273, + nonterminal_produced: 286, } } - 892 => { + 924 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 273, + nonterminal_produced: 286, } } - 893 => { + 925 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 274, + nonterminal_produced: 287, } } - 894 => { + 926 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 275, + nonterminal_produced: 288, } } - 895 => { + 927 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 275, + nonterminal_produced: 288, } } - 896 => { + 928 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, - nonterminal_produced: 275, + nonterminal_produced: 288, } } - 897 => { + 929 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 275, + nonterminal_produced: 288, } } - 898 => { + 930 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 7, - nonterminal_produced: 275, + nonterminal_produced: 288, } } - 899 => { + 931 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, - nonterminal_produced: 275, + nonterminal_produced: 288, } } - 900 => { + 932 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, - nonterminal_produced: 275, + nonterminal_produced: 288, } } - 901 => { + 933 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 275, + nonterminal_produced: 288, } } - 902 => { + 934 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, - nonterminal_produced: 275, + nonterminal_produced: 288, } } - 903 => { + 935 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 275, + nonterminal_produced: 288, } } - 904 => { + 936 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 275, + nonterminal_produced: 288, } } - 905 => { + 937 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 275, + nonterminal_produced: 288, } } - 906 => { + 938 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 276, + nonterminal_produced: 289, } } - 907 => { + 939 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, - nonterminal_produced: 277, + nonterminal_produced: 290, } } - 908 => { + 940 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 4, - nonterminal_produced: 277, + nonterminal_produced: 290, } } - 909 => { + 941 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 278, + nonterminal_produced: 291, } } - 910 => { + 942 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 278, + nonterminal_produced: 291, } } - 911 => { + 943 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 279, + nonterminal_produced: 292, } } - 912 => { + 944 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 279, + nonterminal_produced: 292, } } - 913 => { + 945 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 2, - nonterminal_produced: 280, + nonterminal_produced: 293, } } - 914 => { + 946 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 280, + nonterminal_produced: 293, } } - 915 => { + 947 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 3, - nonterminal_produced: 280, + nonterminal_produced: 293, + } + } + 948 => __state_machine::SimulatedReduce::Accept, + 949 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 295, + } + } + 950 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 0, + nonterminal_produced: 295, } } - 916 => __state_machine::SimulatedReduce::Accept, _ => panic!("invalid reduction index {}", __reduce_index) } } @@ -11433,6 +11847,7 @@ mod __parse__Top { __TOKENS: IntoIterator, >( &self, + source_code: &str, mode: Mode, __tokens0: __TOKENS, ) -> Result> @@ -11441,6 +11856,7 @@ mod __parse__Top { let mut __tokens = __tokens.map(|t| __ToTriple::to_triple(t)); __state_machine::Parser::drive( __StateMachine { + source_code, mode, __phantom: core::marker::PhantomData::<()>, }, @@ -11449,6 +11865,7 @@ mod __parse__Top { } } fn __accepts< + '__0, >( __error_state: Option, __states: &[i16], @@ -11482,6 +11899,7 @@ mod __parse__Top { } pub(crate) fn __reduce< >( + source_code: &str, mode: Mode, __action: i16, __lookahead_start: Option<&TextSize>, @@ -11492,6054 +11910,6320 @@ mod __parse__Top { { let (__pop_states, __nonterminal) = match __action { 0 => { - __reduce0(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce0(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 1 => { - __reduce1(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce1(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 2 => { - __reduce2(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce2(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 3 => { - __reduce3(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce3(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 4 => { - __reduce4(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce4(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 5 => { - __reduce5(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce5(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 6 => { - __reduce6(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce6(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 7 => { - __reduce7(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce7(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 8 => { - __reduce8(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce8(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 9 => { - __reduce9(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce9(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 10 => { - __reduce10(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce10(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 11 => { - __reduce11(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce11(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 12 => { - __reduce12(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce12(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 13 => { - __reduce13(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce13(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 14 => { - __reduce14(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce14(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 15 => { - __reduce15(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce15(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 16 => { - __reduce16(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce16(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 17 => { - __reduce17(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce17(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 18 => { - __reduce18(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce18(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 19 => { - __reduce19(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce19(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 20 => { - __reduce20(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce20(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 21 => { - __reduce21(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce21(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 22 => { - // ("," >) = ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(935); + __reduce22(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 23 => { + __reduce23(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 24 => { + // ("," >) = ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(966); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant64(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action935::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action966::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (5, 13) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (5, 14) } - 23 => { - // ("," >) = ",", "*", ",", KwargParameter => ActionFn(936); + 25 => { + // ("," >) = ",", "*", ",", KwargParameter => ActionFn(967); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action936::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action967::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (4, 13) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (4, 14) } - 24 => { - // ("," >) = ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(937); + 26 => { + // ("," >) = ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(968); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant8(__symbols); + let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); - let __sym2 = __pop_Variant65(__symbols); + let __sym3 = __pop_Variant12(__symbols); + let __sym2 = __pop_Variant64(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action937::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action968::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (6, 13) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (6, 14) } - 25 => { - // ("," >) = ",", "*", ("," >)+, ",", KwargParameter => ActionFn(938); + 27 => { + // ("," >) = ",", "*", ("," >)+, ",", KwargParameter => ActionFn(969); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant11(__symbols); + let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action938::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action969::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (5, 13) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (5, 14) } - 26 => { - // ("," >) = ",", "*", StarTypedParameter => ActionFn(939); + 28 => { + // ("," >) = ",", "*", StarTypedParameter => ActionFn(970); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant64(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action939::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action970::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (3, 13) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (3, 14) } - 27 => { - // ("," >) = ",", "*" => ActionFn(940); + 29 => { + // ("," >) = ",", "*" => ActionFn(971); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action940::<>(mode, __sym0, __sym1) { + let __nt = match super::__action971::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (2, 13) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (2, 14) } - 28 => { - // ("," >) = ",", "*", StarTypedParameter, ("," >)+ => ActionFn(941); + 30 => { + // ("," >) = ",", "*", StarTypedParameter, ("," >)+ => ActionFn(972); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant11(__symbols); - let __sym2 = __pop_Variant65(__symbols); + let __sym3 = __pop_Variant12(__symbols); + let __sym2 = __pop_Variant64(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action941::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action972::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (4, 13) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (4, 14) } - 29 => { - // ("," >) = ",", "*", ("," >)+ => ActionFn(942); + 31 => { + // ("," >) = ",", "*", ("," >)+ => ActionFn(973); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant11(__symbols); + let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action942::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action973::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (3, 13) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (3, 14) } - 30 => { - // ("," >)? = ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(959); + 32 => { + // ("," >)? = ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(990); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant64(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action959::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action990::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (5, 14) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (5, 15) } - 31 => { - // ("," >)? = ",", "*", ",", KwargParameter => ActionFn(960); + 33 => { + // ("," >)? = ",", "*", ",", KwargParameter => ActionFn(991); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action960::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action991::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (4, 14) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (4, 15) } - 32 => { - // ("," >)? = ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(961); + 34 => { + // ("," >)? = ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(992); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant8(__symbols); + let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); - let __sym2 = __pop_Variant65(__symbols); + let __sym3 = __pop_Variant12(__symbols); + let __sym2 = __pop_Variant64(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action961::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action992::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (6, 14) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (6, 15) } - 33 => { - // ("," >)? = ",", "*", ("," >)+, ",", KwargParameter => ActionFn(962); + 35 => { + // ("," >)? = ",", "*", ("," >)+, ",", KwargParameter => ActionFn(993); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant11(__symbols); + let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action962::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action993::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (5, 14) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (5, 15) } - 34 => { - // ("," >)? = ",", "*", StarTypedParameter => ActionFn(963); + 36 => { + // ("," >)? = ",", "*", StarTypedParameter => ActionFn(994); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant64(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action963::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action994::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (3, 14) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (3, 15) } - 35 => { - // ("," >)? = ",", "*" => ActionFn(964); + 37 => { + // ("," >)? = ",", "*" => ActionFn(995); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action964::<>(mode, __sym0, __sym1) { + let __nt = match super::__action995::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (2, 14) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (2, 15) } - 36 => { - // ("," >)? = ",", "*", StarTypedParameter, ("," >)+ => ActionFn(965); + 38 => { + // ("," >)? = ",", "*", StarTypedParameter, ("," >)+ => ActionFn(996); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant11(__symbols); - let __sym2 = __pop_Variant65(__symbols); + let __sym3 = __pop_Variant12(__symbols); + let __sym2 = __pop_Variant64(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action965::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action996::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (4, 14) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (4, 15) } - 37 => { - // ("," >)? = ",", "*", ("," >)+ => ActionFn(966); + 39 => { + // ("," >)? = ",", "*", ("," >)+ => ActionFn(997); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant11(__symbols); + let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action966::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action997::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (3, 14) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (3, 15) } - 38 => { - __reduce38(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + 40 => { + __reduce40(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } - 39 => { - // ("," >) = ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(995); + 41 => { + // ("," >) = ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1026); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant64(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action995::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1026::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (5, 15) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (5, 16) } - 40 => { - // ("," >) = ",", "*", ",", KwargParameter => ActionFn(996); + 42 => { + // ("," >) = ",", "*", ",", KwargParameter => ActionFn(1027); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action996::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1027::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (4, 15) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (4, 16) } - 41 => { - // ("," >) = ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(997); + 43 => { + // ("," >) = ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1028); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant8(__symbols); + let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); - let __sym2 = __pop_Variant65(__symbols); + let __sym3 = __pop_Variant12(__symbols); + let __sym2 = __pop_Variant64(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action997::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1028::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (6, 15) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (6, 16) } - 42 => { - // ("," >) = ",", "*", ("," >)+, ",", KwargParameter => ActionFn(998); + 44 => { + // ("," >) = ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1029); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant11(__symbols); + let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action998::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1029::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (5, 15) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (5, 16) } - 43 => { - // ("," >) = ",", "*", StarUntypedParameter => ActionFn(999); + 45 => { + // ("," >) = ",", "*", StarUntypedParameter => ActionFn(1030); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant64(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action999::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1030::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (3, 15) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (3, 16) } - 44 => { - // ("," >) = ",", "*" => ActionFn(1000); + 46 => { + // ("," >) = ",", "*" => ActionFn(1031); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1000::<>(mode, __sym0, __sym1) { + let __nt = match super::__action1031::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (2, 15) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (2, 16) } - 45 => { - // ("," >) = ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1001); + 47 => { + // ("," >) = ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1032); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant11(__symbols); - let __sym2 = __pop_Variant65(__symbols); + let __sym3 = __pop_Variant12(__symbols); + let __sym2 = __pop_Variant64(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1001::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1032::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (4, 15) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (4, 16) } - 46 => { - // ("," >) = ",", "*", ("," >)+ => ActionFn(1002); + 48 => { + // ("," >) = ",", "*", ("," >)+ => ActionFn(1033); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant11(__symbols); + let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1002::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1033::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (3, 15) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (3, 16) } - 47 => { - // ("," >)? = ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1019); + 49 => { + // ("," >)? = ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1050); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant64(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1019::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1050::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (5, 16) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (5, 17) } - 48 => { - // ("," >)? = ",", "*", ",", KwargParameter => ActionFn(1020); + 50 => { + // ("," >)? = ",", "*", ",", KwargParameter => ActionFn(1051); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1020::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1051::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (4, 16) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (4, 17) } - 49 => { - // ("," >)? = ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1021); + 51 => { + // ("," >)? = ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1052); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant8(__symbols); + let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); - let __sym2 = __pop_Variant65(__symbols); + let __sym3 = __pop_Variant12(__symbols); + let __sym2 = __pop_Variant64(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1021::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1052::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (6, 16) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (6, 17) } - 50 => { - // ("," >)? = ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1022); + 52 => { + // ("," >)? = ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1053); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant11(__symbols); + let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1022::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1053::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (5, 16) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (5, 17) } - 51 => { - // ("," >)? = ",", "*", StarUntypedParameter => ActionFn(1023); + 53 => { + // ("," >)? = ",", "*", StarUntypedParameter => ActionFn(1054); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant64(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1023::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1054::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (3, 16) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (3, 17) } - 52 => { - // ("," >)? = ",", "*" => ActionFn(1024); + 54 => { + // ("," >)? = ",", "*" => ActionFn(1055); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1024::<>(mode, __sym0, __sym1) { + let __nt = match super::__action1055::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (2, 16) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (2, 17) } - 53 => { - // ("," >)? = ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1025); + 55 => { + // ("," >)? = ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1056); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant11(__symbols); - let __sym2 = __pop_Variant65(__symbols); + let __sym3 = __pop_Variant12(__symbols); + let __sym2 = __pop_Variant64(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1025::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1056::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (4, 16) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (4, 17) } - 54 => { - // ("," >)? = ",", "*", ("," >)+ => ActionFn(1026); + 56 => { + // ("," >)? = ",", "*", ("," >)+ => ActionFn(1057); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant11(__symbols); + let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1026::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1057::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (3, 16) - } - 55 => { - __reduce55(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 56 => { - __reduce56(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (3, 17) } 57 => { - __reduce57(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce57(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 58 => { - __reduce58(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce58(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 59 => { - __reduce59(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce59(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 60 => { - __reduce60(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce60(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 61 => { - __reduce61(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce61(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 62 => { - __reduce62(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce62(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 63 => { - __reduce63(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce63(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 64 => { - __reduce64(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce64(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 65 => { - __reduce65(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce65(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 66 => { - __reduce66(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce66(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 67 => { - __reduce67(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce67(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 68 => { - __reduce68(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce68(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 69 => { - __reduce69(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce69(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 70 => { - __reduce70(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce70(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 71 => { - __reduce71(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce71(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 72 => { - __reduce72(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce72(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 73 => { - __reduce73(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce73(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 74 => { - __reduce74(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce74(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 75 => { - __reduce75(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce75(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 76 => { - __reduce76(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce76(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 77 => { - __reduce77(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce77(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 78 => { - __reduce78(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce78(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 79 => { - __reduce79(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce79(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 80 => { - __reduce80(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce80(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 81 => { - __reduce81(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce81(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 82 => { - __reduce82(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce82(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 83 => { - __reduce83(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce83(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 84 => { - __reduce84(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce84(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 85 => { - __reduce85(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce85(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 86 => { - __reduce86(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce86(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 87 => { - __reduce87(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce87(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 88 => { - __reduce88(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce88(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 89 => { - __reduce89(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce89(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 90 => { - __reduce90(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce90(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 91 => { - __reduce91(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce91(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 92 => { - __reduce92(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce92(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 93 => { - __reduce93(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce93(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 94 => { - __reduce94(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce94(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 95 => { - __reduce95(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce95(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 96 => { - __reduce96(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce96(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 97 => { - __reduce97(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce97(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 98 => { - __reduce98(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce98(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 99 => { - __reduce99(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce99(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 100 => { - __reduce100(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce100(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 101 => { - __reduce101(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce101(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 102 => { - __reduce102(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce102(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 103 => { - __reduce103(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce103(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 104 => { - __reduce104(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce104(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 105 => { - __reduce105(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce105(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 106 => { - __reduce106(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce106(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 107 => { - __reduce107(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce107(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 108 => { - __reduce108(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce108(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 109 => { - __reduce109(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce109(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 110 => { - __reduce110(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce110(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 111 => { - __reduce111(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce111(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 112 => { - __reduce112(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce112(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 113 => { - __reduce113(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce113(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 114 => { - __reduce114(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce114(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 115 => { - __reduce115(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce115(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 116 => { - __reduce116(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce116(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 117 => { - __reduce117(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce117(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 118 => { - __reduce118(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce118(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 119 => { - __reduce119(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce119(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 120 => { - __reduce120(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce120(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 121 => { - __reduce121(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce121(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 122 => { - __reduce122(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce122(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 123 => { - __reduce123(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce123(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 124 => { - __reduce124(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce124(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 125 => { - __reduce125(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce125(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 126 => { - __reduce126(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce126(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 127 => { - __reduce127(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce127(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 128 => { - __reduce128(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce128(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 129 => { - __reduce129(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce129(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 130 => { - __reduce130(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce130(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 131 => { - __reduce131(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce131(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 132 => { - __reduce132(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce132(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 133 => { - __reduce133(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce133(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 134 => { - __reduce134(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce134(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 135 => { - __reduce135(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce135(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 136 => { - __reduce136(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce136(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 137 => { - __reduce137(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce137(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 138 => { - __reduce138(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce138(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 139 => { - __reduce139(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce139(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 140 => { - __reduce140(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce140(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 141 => { - __reduce141(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce141(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 142 => { - __reduce142(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce142(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 143 => { - __reduce143(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce143(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 144 => { - __reduce144(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce144(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 145 => { - __reduce145(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce145(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 146 => { - __reduce146(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce146(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 147 => { - __reduce147(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce147(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 148 => { - __reduce148(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce148(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 149 => { - __reduce149(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce149(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 150 => { - __reduce150(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce150(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 151 => { - __reduce151(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce151(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 152 => { - __reduce152(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce152(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 153 => { - __reduce153(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce153(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 154 => { - __reduce154(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce154(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 155 => { - __reduce155(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce155(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 156 => { - __reduce156(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce156(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 157 => { - __reduce157(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce157(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 158 => { - __reduce158(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce158(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 159 => { - __reduce159(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce159(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 160 => { - __reduce160(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce160(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 161 => { - __reduce161(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 162 => { - // Arguments = "(", FunctionArgument, ")" => ActionFn(1498); + // Arguments = "(", FunctionArgument, ")" => ActionFn(1537); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant30(__symbols); + let __sym1 = __pop_Variant31(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1498::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1537::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant51(__nt), __end)); - (3, 85) + __symbols.push((__start, __Symbol::Variant50(__nt), __end)); + (3, 84) } - 163 => { - // Arguments = "(", ")" => ActionFn(1499); + 162 => { + // Arguments = "(", ")" => ActionFn(1538); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1499::<>(mode, __sym0, __sym1) { + let __nt = match super::__action1538::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant51(__nt), __end)); - (2, 85) + __symbols.push((__start, __Symbol::Variant50(__nt), __end)); + (2, 84) } - 164 => { - // Arguments = "(", ( ",")+, FunctionArgument, ")" => ActionFn(1500); + 163 => { + // Arguments = "(", ( ",")+, FunctionArgument, ")" => ActionFn(1539); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant30(__symbols); - let __sym1 = __pop_Variant31(__symbols); + let __sym2 = __pop_Variant31(__symbols); + let __sym1 = __pop_Variant32(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1500::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1539::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant51(__nt), __end)); - (4, 85) + __symbols.push((__start, __Symbol::Variant50(__nt), __end)); + (4, 84) } - 165 => { - // Arguments = "(", ( ",")+, ")" => ActionFn(1501); + 164 => { + // Arguments = "(", ( ",")+, ")" => ActionFn(1540); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant31(__symbols); + let __sym1 = __pop_Variant32(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1501::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1540::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant51(__nt), __end)); - (3, 85) + __symbols.push((__start, __Symbol::Variant50(__nt), __end)); + (3, 84) + } + 165 => { + __reduce165(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 166 => { - __reduce166(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce166(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 167 => { - __reduce167(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce167(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 168 => { - __reduce168(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce168(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 169 => { - __reduce169(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce169(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 170 => { - __reduce170(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce170(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 171 => { - __reduce171(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 172 => { - // AsPattern = OrPattern, "as", Identifier => ActionFn(1195); + // AsPattern = OrPattern, "as", Identifier => ActionFn(1233); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant34(__symbols); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1195::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1233::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (3, 89) + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (3, 88) + } + 172 => { + __reduce172(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 173 => { - __reduce173(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce173(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 174 => { - __reduce174(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce174(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 175 => { - __reduce175(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce175(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 176 => { - __reduce176(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce176(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 177 => { - __reduce177(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce177(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 178 => { - __reduce178(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce178(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 179 => { - __reduce179(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce179(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 180 => { - __reduce180(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce180(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 181 => { - __reduce181(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce181(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 182 => { - __reduce182(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 183 => { - // Atom<"all"> = (@L string @R)+ => ActionFn(708); - let __sym0 = __pop_Variant42(__symbols); + // Atom<"all"> = StringLiteralOrFString+ => ActionFn(1236); + let __sym0 = __pop_Variant95(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action708::<>(mode, __sym0) { + let __nt = match super::__action1236::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 95) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 94) + } + 183 => { + __reduce183(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 184 => { - __reduce184(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce184(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 185 => { - __reduce185(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce185(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 186 => { - __reduce186(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce186(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 187 => { - __reduce187(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce187(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 188 => { - __reduce188(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce188(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 189 => { - __reduce189(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce189(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 190 => { - __reduce190(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 191 => { - // Atom<"all"> = "(", OneOrMore>, ",", NamedOrStarExpr, ",", ")" => ActionFn(1204); + // Atom<"all"> = "(", OneOrMore>, ",", NamedOrStarExpr, ",", ")" => ActionFn(1243); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant14(__symbols); + let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1204::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1243::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (6, 95) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (6, 94) } - 192 => { - // Atom<"all"> = "(", NamedOrStarExpr, ",", ")" => ActionFn(1205); + 191 => { + // Atom<"all"> = "(", NamedOrStarExpr, ",", ")" => ActionFn(1244); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1205::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1244::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 95) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 94) } - 193 => { - // Atom<"all"> = "(", OneOrMore>, ",", NamedOrStarExpr, ("," )+, ",", ")" => ActionFn(1206); + 192 => { + // Atom<"all"> = "(", OneOrMore>, ",", NamedOrStarExpr, ("," )+, ",", ")" => ActionFn(1245); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant16(__symbols); - let __sym3 = __pop_Variant14(__symbols); + let __sym4 = __pop_Variant17(__symbols); + let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1206::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1245::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (7, 95) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (7, 94) } - 194 => { - // Atom<"all"> = "(", NamedOrStarExpr, ("," )+, ",", ")" => ActionFn(1207); + 193 => { + // Atom<"all"> = "(", NamedOrStarExpr, ("," )+, ",", ")" => ActionFn(1246); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant16(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant17(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1207::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1246::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (5, 95) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (5, 94) } - 195 => { - // Atom<"all"> = "(", OneOrMore>, ",", NamedOrStarExpr, ")" => ActionFn(1208); + 194 => { + // Atom<"all"> = "(", OneOrMore>, ",", NamedOrStarExpr, ")" => ActionFn(1247); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant14(__symbols); + let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1208::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1247::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (5, 95) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (5, 94) } - 196 => { - // Atom<"all"> = "(", NamedOrStarExpr, ")" => ActionFn(1209); + 195 => { + // Atom<"all"> = "(", NamedOrStarExpr, ")" => ActionFn(1248); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1209::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1248::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 95) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 94) } - 197 => { - // Atom<"all"> = "(", OneOrMore>, ",", NamedOrStarExpr, ("," )+, ")" => ActionFn(1210); + 196 => { + // Atom<"all"> = "(", OneOrMore>, ",", NamedOrStarExpr, ("," )+, ")" => ActionFn(1249); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant16(__symbols); - let __sym3 = __pop_Variant14(__symbols); + let __sym4 = __pop_Variant17(__symbols); + let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1210::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1249::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (6, 95) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (6, 94) } - 198 => { - // Atom<"all"> = "(", NamedOrStarExpr, ("," )+, ")" => ActionFn(1211); + 197 => { + // Atom<"all"> = "(", NamedOrStarExpr, ("," )+, ")" => ActionFn(1250); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant16(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant17(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1211::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1250::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 95) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 94) + } + 198 => { + __reduce198(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 199 => { - __reduce199(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce199(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 200 => { - __reduce200(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce200(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 201 => { - __reduce201(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 202 => { - // Atom<"all"> = "(", "**", Expression<"all">, ")" => ActionFn(1215); + // Atom<"all"> = "(", "**", Expression<"all">, ")" => ActionFn(1254); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1215::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1254::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 95) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 94) + } + 202 => { + __reduce202(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 203 => { - __reduce203(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce203(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 204 => { - __reduce204(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce204(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 205 => { - __reduce205(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce205(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 206 => { - __reduce206(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce206(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 207 => { - __reduce207(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce207(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 208 => { - __reduce208(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce208(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 209 => { - __reduce209(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce209(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 210 => { - __reduce210(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce210(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 211 => { - __reduce211(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 212 => { - // Atom<"no-withitems"> = (@L string @R)+ => ActionFn(729); - let __sym0 = __pop_Variant42(__symbols); + // Atom<"no-withitems"> = StringLiteralOrFString+ => ActionFn(1263); + let __sym0 = __pop_Variant95(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action729::<>(mode, __sym0) { + let __nt = match super::__action1263::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 96) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 95) + } + 212 => { + __reduce212(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 213 => { - __reduce213(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce213(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 214 => { - __reduce214(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce214(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 215 => { - __reduce215(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce215(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 216 => { - __reduce216(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce216(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 217 => { - __reduce217(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 218 => { - // Atom<"no-withitems"> = "(", OneOrMore>, ",", NamedOrStarExpr, ",", ")" => ActionFn(1228); + // Atom<"no-withitems"> = "(", OneOrMore>, ",", NamedOrStarExpr, ",", ")" => ActionFn(1268); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant14(__symbols); + let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1228::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1268::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (6, 96) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (6, 95) } - 219 => { - // Atom<"no-withitems"> = "(", NamedOrStarExpr, ",", ")" => ActionFn(1229); + 218 => { + // Atom<"no-withitems"> = "(", NamedOrStarExpr, ",", ")" => ActionFn(1269); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1229::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1269::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 96) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 95) } - 220 => { - // Atom<"no-withitems"> = "(", OneOrMore>, ",", NamedOrStarExpr, ("," )+, ",", ")" => ActionFn(1230); + 219 => { + // Atom<"no-withitems"> = "(", OneOrMore>, ",", NamedOrStarExpr, ("," )+, ",", ")" => ActionFn(1270); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant16(__symbols); - let __sym3 = __pop_Variant14(__symbols); + let __sym4 = __pop_Variant17(__symbols); + let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1230::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1270::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (7, 96) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (7, 95) } - 221 => { - // Atom<"no-withitems"> = "(", NamedOrStarExpr, ("," )+, ",", ")" => ActionFn(1231); + 220 => { + // Atom<"no-withitems"> = "(", NamedOrStarExpr, ("," )+, ",", ")" => ActionFn(1271); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant16(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant17(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1231::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1271::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (5, 96) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (5, 95) } - 222 => { - // Atom<"no-withitems"> = "(", OneOrMore>, ",", NamedOrStarExpr, ")" => ActionFn(1232); + 221 => { + // Atom<"no-withitems"> = "(", OneOrMore>, ",", NamedOrStarExpr, ")" => ActionFn(1272); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant14(__symbols); + let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1232::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1272::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (5, 96) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (5, 95) } - 223 => { - // Atom<"no-withitems"> = "(", NamedOrStarExpr, ")" => ActionFn(1233); + 222 => { + // Atom<"no-withitems"> = "(", NamedOrStarExpr, ")" => ActionFn(1273); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1233::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1273::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 96) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 95) } - 224 => { - // Atom<"no-withitems"> = "(", OneOrMore>, ",", NamedOrStarExpr, ("," )+, ")" => ActionFn(1234); + 223 => { + // Atom<"no-withitems"> = "(", OneOrMore>, ",", NamedOrStarExpr, ("," )+, ")" => ActionFn(1274); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant16(__symbols); - let __sym3 = __pop_Variant14(__symbols); + let __sym4 = __pop_Variant17(__symbols); + let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1234::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1274::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (6, 96) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (6, 95) } - 225 => { - // Atom<"no-withitems"> = "(", NamedOrStarExpr, ("," )+, ")" => ActionFn(1235); + 224 => { + // Atom<"no-withitems"> = "(", NamedOrStarExpr, ("," )+, ")" => ActionFn(1275); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant16(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant17(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1235::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1275::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 96) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 95) + } + 225 => { + __reduce225(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 226 => { - __reduce226(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce226(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 227 => { - __reduce227(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce227(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 228 => { - __reduce228(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 229 => { - // Atom<"no-withitems"> = "(", "**", Expression<"all">, ")" => ActionFn(1239); + // Atom<"no-withitems"> = "(", "**", Expression<"all">, ")" => ActionFn(1279); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1239::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1279::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 96) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 95) + } + 229 => { + __reduce229(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 230 => { - __reduce230(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce230(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 231 => { - __reduce231(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce231(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 232 => { - __reduce232(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce232(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 233 => { - __reduce233(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce233(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 234 => { - __reduce234(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce234(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 235 => { - __reduce235(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce235(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 236 => { - __reduce236(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce236(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 237 => { - __reduce237(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce237(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 238 => { - __reduce238(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce238(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 239 => { - __reduce239(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce239(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 240 => { - __reduce240(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce240(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 241 => { - __reduce241(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce241(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 242 => { - __reduce242(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce242(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 243 => { - __reduce243(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce243(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 244 => { - __reduce244(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce244(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 245 => { - __reduce245(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce245(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 246 => { - __reduce246(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce246(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 247 => { - __reduce247(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce247(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 248 => { - __reduce248(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce248(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 249 => { - __reduce249(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce249(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 250 => { - __reduce250(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce250(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 251 => { - __reduce251(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce251(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 252 => { - __reduce252(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce252(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 253 => { - __reduce253(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce253(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 254 => { - __reduce254(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce254(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 255 => { - __reduce255(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce255(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 256 => { - __reduce256(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce256(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 257 => { - __reduce257(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce257(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 258 => { - __reduce258(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce258(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 259 => { - __reduce259(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce259(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 260 => { - __reduce260(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce260(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 261 => { - __reduce261(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce261(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 262 => { - __reduce262(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce262(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 263 => { - __reduce263(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce263(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 264 => { - __reduce264(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce264(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 265 => { - __reduce265(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce265(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 266 => { - __reduce266(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce266(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 267 => { - __reduce267(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce267(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 268 => { - __reduce268(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce268(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 269 => { - __reduce269(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce269(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 270 => { - __reduce270(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce270(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 271 => { - __reduce271(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce271(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 272 => { - __reduce272(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce272(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 273 => { - __reduce273(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce273(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 274 => { - __reduce274(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce274(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 275 => { - __reduce275(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce275(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 276 => { - __reduce276(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce276(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 277 => { - __reduce277(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce277(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 278 => { - __reduce278(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce278(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 279 => { - __reduce279(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce279(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 280 => { - __reduce280(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce280(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 281 => { - __reduce281(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce281(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 282 => { - __reduce282(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce282(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 283 => { - __reduce283(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce283(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 284 => { - __reduce284(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce284(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 285 => { - __reduce285(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce285(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 286 => { - __reduce286(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce286(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 287 => { - __reduce287(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce287(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 288 => { - __reduce288(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce288(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 289 => { - __reduce289(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce289(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 290 => { - __reduce290(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce290(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 291 => { - __reduce291(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce291(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 292 => { - __reduce292(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce292(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 293 => { - __reduce293(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce293(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 294 => { - __reduce294(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce294(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 295 => { - __reduce295(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce295(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 296 => { - __reduce296(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce296(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 297 => { - __reduce297(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce297(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 298 => { - __reduce298(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce298(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 299 => { - __reduce299(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce299(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 300 => { - __reduce300(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce300(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 301 => { - __reduce301(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce301(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 302 => { - __reduce302(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce302(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 303 => { - __reduce303(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce303(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 304 => { - __reduce304(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce304(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 305 => { - __reduce305(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce305(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 306 => { - __reduce306(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce306(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 307 => { - __reduce307(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce307(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 308 => { - __reduce308(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce308(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 309 => { - __reduce309(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce309(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 310 => { - __reduce310(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce310(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 311 => { - __reduce311(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce311(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 312 => { - __reduce312(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce312(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 313 => { - __reduce313(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce313(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 314 => { - __reduce314(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce314(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 315 => { - __reduce315(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce315(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 316 => { - __reduce316(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce316(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 317 => { - __reduce317(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce317(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 318 => { - __reduce318(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce318(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 319 => { - __reduce319(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce319(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 320 => { - __reduce320(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce320(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 321 => { - __reduce321(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce321(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 322 => { - __reduce322(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce322(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 323 => { - __reduce323(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce323(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 324 => { - __reduce324(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce324(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 325 => { - __reduce325(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce325(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 326 => { - __reduce326(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce326(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 327 => { - __reduce327(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce327(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 328 => { - __reduce328(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce328(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 329 => { - __reduce329(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce329(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 330 => { - __reduce330(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce330(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 331 => { - __reduce331(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce331(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 332 => { - __reduce332(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce332(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 333 => { - __reduce333(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce333(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 334 => { - __reduce334(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce334(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 335 => { - __reduce335(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce335(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 336 => { - __reduce336(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce336(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 337 => { - __reduce337(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce337(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 338 => { - __reduce338(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce338(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 339 => { - __reduce339(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce339(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 340 => { - __reduce340(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce340(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 341 => { - __reduce341(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce341(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 342 => { - __reduce342(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce342(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 343 => { - __reduce343(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce343(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 344 => { - __reduce344(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce344(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 345 => { - __reduce345(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce345(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 346 => { - __reduce346(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce346(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 347 => { - __reduce347(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce347(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 348 => { - __reduce348(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce348(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 349 => { - __reduce349(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce349(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 350 => { - __reduce350(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce350(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 351 => { - __reduce351(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce351(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 352 => { - __reduce352(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce352(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 353 => { - __reduce353(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce353(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 354 => { - __reduce354(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce354(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 355 => { - __reduce355(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce355(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 356 => { - __reduce356(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce356(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 357 => { - __reduce357(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce357(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 358 => { - __reduce358(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce358(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 359 => { - __reduce359(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce359(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 360 => { - __reduce360(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce360(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 361 => { - __reduce361(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce361(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 362 => { - __reduce362(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce362(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 363 => { - __reduce363(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce363(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 364 => { - __reduce364(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce364(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 365 => { - __reduce365(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce365(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 366 => { - __reduce366(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce366(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 367 => { - __reduce367(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce367(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 368 => { - __reduce368(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // FStringConversion = "!", name => ActionFn(802); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant6(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym1.2; + let __nt = match super::__action802::<>(source_code, mode, __sym0, __sym1) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant68(__nt), __end)); + (2, 141) } 369 => { - __reduce369(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce369(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 370 => { - __reduce370(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce370(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 371 => { - __reduce371(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce371(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 372 => { - __reduce372(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce372(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 373 => { - __reduce373(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce373(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 374 => { - __reduce374(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce374(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 375 => { - __reduce375(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce375(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 376 => { - __reduce376(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce376(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 377 => { - __reduce377(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce377(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 378 => { - __reduce378(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce378(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 379 => { - __reduce379(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // FStringMiddlePattern = fstring_middle => ActionFn(805); + let __sym0 = __pop_Variant3(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = match super::__action805::<>(source_code, mode, __sym0) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (1, 147) } 380 => { - __reduce380(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce380(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 381 => { - __reduce381(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce381(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 382 => { - __reduce382(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce382(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 383 => { - __reduce383(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce383(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 384 => { - __reduce384(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // FStringReplacementField = "{", TestListOrYieldExpr, "=", FStringConversion, FStringFormatSpecSuffix, "}" => ActionFn(1577); + assert!(__symbols.len() >= 6); + let __sym5 = __pop_Variant0(__symbols); + let __sym4 = __pop_Variant44(__symbols); + let __sym3 = __pop_Variant68(__symbols); + let __sym2 = __pop_Variant0(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym5.2; + let __nt = match super::__action1577::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (6, 150) } 385 => { - __reduce385(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // FStringReplacementField = "{", TestListOrYieldExpr, "=", FStringConversion, "}" => ActionFn(1578); + assert!(__symbols.len() >= 5); + let __sym4 = __pop_Variant0(__symbols); + let __sym3 = __pop_Variant68(__symbols); + let __sym2 = __pop_Variant0(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym4.2; + let __nt = match super::__action1578::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (5, 150) } 386 => { - __reduce386(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // FStringReplacementField = "{", TestListOrYieldExpr, "=", FStringFormatSpecSuffix, "}" => ActionFn(1579); + assert!(__symbols.len() >= 5); + let __sym4 = __pop_Variant0(__symbols); + let __sym3 = __pop_Variant44(__symbols); + let __sym2 = __pop_Variant0(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym4.2; + let __nt = match super::__action1579::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (5, 150) } 387 => { - __reduce387(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // FStringReplacementField = "{", TestListOrYieldExpr, "=", "}" => ActionFn(1580); + assert!(__symbols.len() >= 4); + let __sym3 = __pop_Variant0(__symbols); + let __sym2 = __pop_Variant0(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym3.2; + let __nt = match super::__action1580::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (4, 150) } 388 => { - __reduce388(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // FStringReplacementField = "{", TestListOrYieldExpr, FStringConversion, FStringFormatSpecSuffix, "}" => ActionFn(1581); + assert!(__symbols.len() >= 5); + let __sym4 = __pop_Variant0(__symbols); + let __sym3 = __pop_Variant44(__symbols); + let __sym2 = __pop_Variant68(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym4.2; + let __nt = match super::__action1581::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (5, 150) } 389 => { - __reduce389(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // FStringReplacementField = "{", TestListOrYieldExpr, FStringConversion, "}" => ActionFn(1582); + assert!(__symbols.len() >= 4); + let __sym3 = __pop_Variant0(__symbols); + let __sym2 = __pop_Variant68(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym3.2; + let __nt = match super::__action1582::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (4, 150) } 390 => { - __reduce390(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // FStringReplacementField = "{", TestListOrYieldExpr, FStringFormatSpecSuffix, "}" => ActionFn(1583); + assert!(__symbols.len() >= 4); + let __sym3 = __pop_Variant0(__symbols); + let __sym2 = __pop_Variant44(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym3.2; + let __nt = match super::__action1583::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (4, 150) } 391 => { - __reduce391(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // FStringReplacementField = "{", TestListOrYieldExpr, "}" => ActionFn(1584); + assert!(__symbols.len() >= 3); + let __sym2 = __pop_Variant0(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym2.2; + let __nt = match super::__action1584::<>(source_code, mode, __sym0, __sym1, __sym2) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (3, 150) } 392 => { - __reduce392(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce392(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 393 => { - __reduce393(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce393(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 394 => { - __reduce394(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce394(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 395 => { - __reduce395(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce395(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 396 => { - __reduce396(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce396(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 397 => { - __reduce397(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce397(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 398 => { - __reduce398(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce398(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 399 => { - __reduce399(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce399(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 400 => { - __reduce400(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce400(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 401 => { - __reduce401(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce401(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 402 => { - __reduce402(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce402(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 403 => { - __reduce403(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce403(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 404 => { - __reduce404(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce404(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 405 => { - __reduce405(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce405(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 406 => { - __reduce406(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce406(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 407 => { - __reduce407(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce407(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 408 => { - __reduce408(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce408(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 409 => { - __reduce409(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce409(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 410 => { - __reduce410(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce410(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 411 => { - __reduce411(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce411(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 412 => { - __reduce412(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce412(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 413 => { - __reduce413(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce413(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 414 => { - __reduce414(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce414(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 415 => { - __reduce415(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce415(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 416 => { - __reduce416(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce416(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 417 => { - __reduce417(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce417(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 418 => { - __reduce418(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce418(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 419 => { - __reduce419(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce419(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 420 => { - __reduce420(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce420(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 421 => { - __reduce421(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce421(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 422 => { - __reduce422(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce422(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 423 => { - __reduce423(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce423(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 424 => { - __reduce424(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce424(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 425 => { - __reduce425(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce425(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 426 => { - __reduce426(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce426(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 427 => { - __reduce427(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce427(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 428 => { - __reduce428(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce428(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 429 => { - __reduce429(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce429(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 430 => { - __reduce430(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce430(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 431 => { - __reduce431(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce431(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 432 => { - __reduce432(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce432(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 433 => { - __reduce433(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce433(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 434 => { - __reduce434(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce434(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 435 => { - __reduce435(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce435(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 436 => { - // IpyEscapeCommandExpr = ipy_escape_command => ActionFn(1300); - let __sym0 = __pop_Variant4(__symbols); - let __start = __sym0.0; - let __end = __sym0.2; - let __nt = match super::__action1300::<>(mode, __sym0) { - Ok(v) => v, - Err(e) => return Some(Err(e)), - }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 163) + __reduce436(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 437 => { - // IpyEscapeCommandStatement = ipy_escape_command => ActionFn(1301); - let __sym0 = __pop_Variant4(__symbols); - let __start = __sym0.0; - let __end = __sym0.2; - let __nt = match super::__action1301::<>(mode, __sym0) { - Ok(v) => v, - Err(e) => return Some(Err(e)), - }; - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 164) + __reduce437(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 438 => { - // IpyHelpEndEscapeCommandStatement = Expression<"all">, ("?")+ => ActionFn(1302); - assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant21(__symbols); - let __sym0 = __pop_Variant14(__symbols); - let __start = __sym0.0; - let __end = __sym1.2; - let __nt = match super::__action1302::<>(mode, __sym0, __sym1) { - Ok(v) => v, - Err(e) => return Some(Err(e)), - }; - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (2, 165) + __reduce438(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 439 => { - __reduce439(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce439(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 440 => { - __reduce440(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce440(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 441 => { - __reduce441(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce441(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 442 => { - __reduce442(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce442(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 443 => { - // LambdaDef = "lambda", ParameterList, ":", Test<"all"> => ActionFn(1668); - assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant14(__symbols); - let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant47(__symbols); - let __sym0 = __pop_Variant0(__symbols); - let __start = __sym0.0; - let __end = __sym3.2; - let __nt = match super::__action1668::<>(mode, __sym0, __sym1, __sym2, __sym3) { - Ok(v) => v, - Err(e) => return Some(Err(e)), - }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 168) + __reduce443(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 444 => { - // LambdaDef = "lambda", ":", Test<"all"> => ActionFn(1669); - assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant0(__symbols); - let __start = __sym0.0; - let __end = __sym2.2; - let __nt = match super::__action1669::<>(mode, __sym0, __sym1, __sym2) { - Ok(v) => v, - Err(e) => return Some(Err(e)), - }; - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 168) + __reduce444(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 445 => { - __reduce445(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce445(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 446 => { - __reduce446(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce446(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 447 => { - __reduce447(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce447(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 448 => { - __reduce448(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce448(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 449 => { - __reduce449(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce449(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 450 => { - __reduce450(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce450(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 451 => { - __reduce451(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce451(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 452 => { - __reduce452(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce452(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 453 => { - __reduce453(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce453(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 454 => { - // LiteralPattern = (@L string @R)+ => ActionFn(1309); - let __sym0 = __pop_Variant42(__symbols); - let __start = __sym0.0; - let __end = __sym0.2; - let __nt = match super::__action1309::<>(mode, __sym0) { - Ok(v) => v, - Err(e) => return Some(Err(e)), - }; - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 171) + __reduce454(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 455 => { - __reduce455(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce455(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 456 => { - __reduce456(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce456(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 457 => { - __reduce457(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce457(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 458 => { - __reduce458(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce458(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 459 => { - __reduce459(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // IpyEscapeCommandExpr = ipy_escape_command => ActionFn(1344); + let __sym0 = __pop_Variant5(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = match super::__action1344::<>(source_code, mode, __sym0) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 172) } 460 => { - __reduce460(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // IpyEscapeCommandStatement = ipy_escape_command => ActionFn(1345); + let __sym0 = __pop_Variant5(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = match super::__action1345::<>(source_code, mode, __sym0) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 173) } 461 => { - // MappingKey = (@L string @R)+ => ActionFn(820); - let __sym0 = __pop_Variant42(__symbols); + // IpyHelpEndEscapeCommandStatement = Expression<"all">, ("?")+ => ActionFn(1346); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant22(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; - let __end = __sym0.2; - let __nt = match super::__action820::<>(mode, __sym0) { + let __end = __sym1.2; + let __nt = match super::__action1346::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant45(__nt), __end)); - (1, 172) + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (2, 174) } 462 => { - __reduce462(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce462(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 463 => { - __reduce463(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce463(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 464 => { - __reduce464(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce464(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 465 => { - __reduce465(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce465(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 466 => { - __reduce466(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // LambdaDef = "lambda", ParameterList, ":", fstring_middle, Test<"all"> => ActionFn(1781); + assert!(__symbols.len() >= 5); + let __sym4 = __pop_Variant15(__symbols); + let __sym3 = __pop_Variant3(__symbols); + let __sym2 = __pop_Variant0(__symbols); + let __sym1 = __pop_Variant46(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym4.2; + let __nt = match super::__action1781::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (5, 177) } 467 => { - __reduce467(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // LambdaDef = "lambda", ParameterList, ":", Test<"all"> => ActionFn(1782); + assert!(__symbols.len() >= 4); + let __sym3 = __pop_Variant15(__symbols); + let __sym2 = __pop_Variant0(__symbols); + let __sym1 = __pop_Variant46(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym3.2; + let __nt = match super::__action1782::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 177) } 468 => { - __reduce468(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // LambdaDef = "lambda", ":", fstring_middle, Test<"all"> => ActionFn(1783); + assert!(__symbols.len() >= 4); + let __sym3 = __pop_Variant15(__symbols); + let __sym2 = __pop_Variant3(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym3.2; + let __nt = match super::__action1783::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 177) } 469 => { - __reduce469(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // LambdaDef = "lambda", ":", Test<"all"> => ActionFn(1784); + assert!(__symbols.len() >= 3); + let __sym2 = __pop_Variant15(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym2.2; + let __nt = match super::__action1784::<>(source_code, mode, __sym0, __sym1, __sym2) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 177) } 470 => { - __reduce470(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce470(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 471 => { - __reduce471(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce471(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 472 => { - __reduce472(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce472(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 473 => { - __reduce473(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce473(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 474 => { - __reduce474(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce474(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 475 => { - __reduce475(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce475(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 476 => { - __reduce476(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce476(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 477 => { - __reduce477(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce477(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 478 => { - __reduce478(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce478(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 479 => { - __reduce479(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // LiteralPattern = StringLiteral+ => ActionFn(1353); + let __sym0 = __pop_Variant95(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = match super::__action1353::<>(source_code, mode, __sym0) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 180) } 480 => { - __reduce480(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce480(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 481 => { - __reduce481(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce481(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 482 => { - __reduce482(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce482(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 483 => { - __reduce483(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce483(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 484 => { - __reduce484(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce484(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 485 => { - __reduce485(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce485(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 486 => { - __reduce486(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // MappingKey = StringLiteralOrFString+ => ActionFn(1357); + let __sym0 = __pop_Variant95(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = match super::__action1357::<>(source_code, mode, __sym0) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (1, 181) } 487 => { - __reduce487(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce487(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 488 => { - __reduce488(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce488(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 489 => { - __reduce489(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce489(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 490 => { - __reduce490(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce490(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 491 => { - __reduce491(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce491(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 492 => { - __reduce492(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce492(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 493 => { - __reduce493(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce493(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 494 => { - __reduce494(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce494(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 495 => { - __reduce495(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce495(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 496 => { - __reduce496(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce496(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 497 => { - __reduce497(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce497(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 498 => { - __reduce498(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce498(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 499 => { - __reduce499(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce499(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 500 => { - __reduce500(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce500(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 501 => { - __reduce501(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce501(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 502 => { - __reduce502(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce502(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 503 => { - __reduce503(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce503(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 504 => { - __reduce504(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce504(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 505 => { - __reduce505(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce505(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 506 => { - __reduce506(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce506(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 507 => { - __reduce507(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce507(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 508 => { - __reduce508(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce508(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 509 => { - __reduce509(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce509(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 510 => { - __reduce510(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce510(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 511 => { - __reduce511(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce511(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 512 => { - __reduce512(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce512(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 513 => { - __reduce513(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce513(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 514 => { - __reduce514(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce514(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 515 => { - __reduce515(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce515(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 516 => { - __reduce516(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce516(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 517 => { - __reduce517(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce517(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 518 => { - __reduce518(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce518(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 519 => { - __reduce519(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce519(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 520 => { - __reduce520(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce520(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 521 => { - __reduce521(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce521(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 522 => { - __reduce522(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce522(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 523 => { - __reduce523(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce523(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 524 => { - __reduce524(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce524(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 525 => { - __reduce525(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce525(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 526 => { - __reduce526(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce526(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 527 => { - __reduce527(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce527(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 528 => { - __reduce528(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce528(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 529 => { - __reduce529(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce529(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 530 => { - __reduce530(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce530(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 531 => { - __reduce531(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce531(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 532 => { - __reduce532(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce532(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 533 => { - __reduce533(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce533(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 534 => { - __reduce534(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce534(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 535 => { - __reduce535(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce535(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 536 => { - __reduce536(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce536(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 537 => { - __reduce537(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce537(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 538 => { - __reduce538(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce538(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 539 => { - __reduce539(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce539(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 540 => { - __reduce540(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce540(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 541 => { - __reduce541(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce541(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 542 => { - __reduce542(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce542(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 543 => { - __reduce543(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce543(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 544 => { - __reduce544(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce544(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 545 => { - __reduce545(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce545(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 546 => { - // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ",", KwargParameter, "," => ActionFn(1548); + __reduce546(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 547 => { + __reduce547(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 548 => { + __reduce548(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 549 => { + __reduce549(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 550 => { + __reduce550(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 551 => { + __reduce551(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 552 => { + __reduce552(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 553 => { + __reduce553(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 554 => { + __reduce554(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 555 => { + __reduce555(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 556 => { + __reduce556(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 557 => { + __reduce557(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 558 => { + __reduce558(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 559 => { + __reduce559(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 560 => { + __reduce560(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 561 => { + __reduce561(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 562 => { + __reduce562(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 563 => { + __reduce563(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 564 => { + __reduce564(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 565 => { + __reduce565(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 566 => { + __reduce566(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 567 => { + __reduce567(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 568 => { + __reduce568(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 569 => { + __reduce569(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 570 => { + __reduce570(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 571 => { + // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ",", KwargParameter, "," => ActionFn(1603); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant8(__symbols); + let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant65(__symbols); + let __sym3 = __pop_Variant64(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1548::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1603::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 219) } - 547 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ",", KwargParameter, "," => ActionFn(1549); + 572 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ",", KwargParameter, "," => ActionFn(1604); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant0(__symbols); - let __sym7 = __pop_Variant8(__symbols); + let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant65(__symbols); + let __sym5 = __pop_Variant64(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1549::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1604::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (9, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (9, 219) } - 548 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ",", KwargParameter, "," => ActionFn(1550); + 573 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ",", KwargParameter, "," => ActionFn(1605); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant0(__symbols); - let __sym8 = __pop_Variant8(__symbols); + let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant65(__symbols); + let __sym6 = __pop_Variant64(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = match super::__action1550::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { + let __nt = match super::__action1605::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (10, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (10, 219) } - 549 => { - // ParameterList = OneOrMore>, ",", "*", ",", KwargParameter, "," => ActionFn(1551); + 574 => { + // ParameterList = OneOrMore>, ",", "*", ",", KwargParameter, "," => ActionFn(1606); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1551::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1606::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 219) } - 550 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ",", KwargParameter, "," => ActionFn(1552); + 575 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ",", KwargParameter, "," => ActionFn(1607); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant8(__symbols); + let __sym6 = __pop_Variant9(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1552::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1607::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 219) } - 551 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ",", KwargParameter, "," => ActionFn(1553); + 576 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ",", KwargParameter, "," => ActionFn(1608); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant0(__symbols); - let __sym7 = __pop_Variant8(__symbols); + let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1553::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1608::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (9, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (9, 219) } - 552 => { - // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1554); + 577 => { + // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1609); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant8(__symbols); + let __sym6 = __pop_Variant9(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant11(__symbols); - let __sym3 = __pop_Variant65(__symbols); + let __sym4 = __pop_Variant12(__symbols); + let __sym3 = __pop_Variant64(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1554::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1609::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 219) } - 553 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1555); + 578 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1610); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant0(__symbols); - let __sym8 = __pop_Variant8(__symbols); + let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant11(__symbols); - let __sym5 = __pop_Variant65(__symbols); + let __sym6 = __pop_Variant12(__symbols); + let __sym5 = __pop_Variant64(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = match super::__action1555::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { + let __nt = match super::__action1610::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (10, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (10, 219) } - 554 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1556); + 579 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1611); assert!(__symbols.len() >= 11); let __sym10 = __pop_Variant0(__symbols); - let __sym9 = __pop_Variant8(__symbols); + let __sym9 = __pop_Variant9(__symbols); let __sym8 = __pop_Variant0(__symbols); - let __sym7 = __pop_Variant11(__symbols); - let __sym6 = __pop_Variant65(__symbols); + let __sym7 = __pop_Variant12(__symbols); + let __sym6 = __pop_Variant64(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym10.2; - let __nt = match super::__action1556::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9, __sym10) { + let __nt = match super::__action1611::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9, __sym10) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (11, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (11, 219) } - 555 => { - // ParameterList = OneOrMore>, ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1557); + 580 => { + // ParameterList = OneOrMore>, ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1612); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant8(__symbols); + let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1557::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1612::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 219) } - 556 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1558); + 581 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1613); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant0(__symbols); - let __sym7 = __pop_Variant8(__symbols); + let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant11(__symbols); + let __sym5 = __pop_Variant12(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1558::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1613::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (9, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (9, 219) } - 557 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1559); + 582 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1614); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant0(__symbols); - let __sym8 = __pop_Variant8(__symbols); + let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant11(__symbols); + let __sym6 = __pop_Variant12(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = match super::__action1559::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { + let __nt = match super::__action1614::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (10, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (10, 219) } - 558 => { - // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, "," => ActionFn(1560); + 583 => { + // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, "," => ActionFn(1615); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant65(__symbols); + let __sym3 = __pop_Variant64(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1560::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1615::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 219) } - 559 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, "," => ActionFn(1561); + 584 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, "," => ActionFn(1616); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant65(__symbols); + let __sym5 = __pop_Variant64(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1561::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1616::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 219) } - 560 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, "," => ActionFn(1562); + 585 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, "," => ActionFn(1617); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant65(__symbols); + let __sym6 = __pop_Variant64(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1562::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1617::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 219) } - 561 => { - // ParameterList = OneOrMore>, ",", "*", "," => ActionFn(1563); + 586 => { + // ParameterList = OneOrMore>, ",", "*", "," => ActionFn(1618); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1563::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1618::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 219) } - 562 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", "," => ActionFn(1564); + 587 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", "," => ActionFn(1619); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1564::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1619::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 219) } - 563 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", "," => ActionFn(1565); + 588 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", "," => ActionFn(1620); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1565::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1620::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 219) } - 564 => { - // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ("," >)+, "," => ActionFn(1566); + 589 => { + // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ("," >)+, "," => ActionFn(1621); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant11(__symbols); - let __sym3 = __pop_Variant65(__symbols); + let __sym4 = __pop_Variant12(__symbols); + let __sym3 = __pop_Variant64(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1566::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1621::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 219) } - 565 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ("," >)+, "," => ActionFn(1567); + 590 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ("," >)+, "," => ActionFn(1622); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant11(__symbols); - let __sym5 = __pop_Variant65(__symbols); + let __sym6 = __pop_Variant12(__symbols); + let __sym5 = __pop_Variant64(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1567::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1622::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 219) } - 566 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ("," >)+, "," => ActionFn(1568); + 591 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ("," >)+, "," => ActionFn(1623); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant0(__symbols); - let __sym7 = __pop_Variant11(__symbols); - let __sym6 = __pop_Variant65(__symbols); + let __sym7 = __pop_Variant12(__symbols); + let __sym6 = __pop_Variant64(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1568::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1623::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (9, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (9, 219) } - 567 => { - // ParameterList = OneOrMore>, ",", "*", ("," >)+, "," => ActionFn(1569); + 592 => { + // ParameterList = OneOrMore>, ",", "*", ("," >)+, "," => ActionFn(1624); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1569::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1624::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 219) } - 568 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, "," => ActionFn(1570); + 593 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, "," => ActionFn(1625); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant11(__symbols); + let __sym5 = __pop_Variant12(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1570::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1625::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 219) } - 569 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, "," => ActionFn(1571); + 594 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, "," => ActionFn(1626); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant11(__symbols); + let __sym6 = __pop_Variant12(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1571::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1626::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 219) } - 570 => { - // ParameterList = OneOrMore>, "," => ActionFn(1572); + 595 => { + // ParameterList = OneOrMore>, "," => ActionFn(1627); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1572::<>(mode, __sym0, __sym1) { + let __nt = match super::__action1627::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (2, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (2, 219) } - 571 => { - // ParameterList = OneOrMore>, ",", "/", "," => ActionFn(1573); + 596 => { + // ParameterList = OneOrMore>, ",", "/", "," => ActionFn(1628); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1573::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1628::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 219) } - 572 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, "," => ActionFn(1574); + 597 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, "," => ActionFn(1629); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1574::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1629::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 219) } - 573 => { - // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(1575); + 598 => { + // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(1630); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant8(__symbols); + let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant65(__symbols); + let __sym3 = __pop_Variant64(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1575::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1630::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 219) } - 574 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(1576); + 599 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(1631); assert!(__symbols.len() >= 8); - let __sym7 = __pop_Variant8(__symbols); + let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant65(__symbols); + let __sym5 = __pop_Variant64(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1576::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1631::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 219) } - 575 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(1577); + 600 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ",", KwargParameter => ActionFn(1632); assert!(__symbols.len() >= 9); - let __sym8 = __pop_Variant8(__symbols); + let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant65(__symbols); + let __sym6 = __pop_Variant64(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1577::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1632::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (9, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (9, 219) } - 576 => { - // ParameterList = OneOrMore>, ",", "*", ",", KwargParameter => ActionFn(1578); + 601 => { + // ParameterList = OneOrMore>, ",", "*", ",", KwargParameter => ActionFn(1633); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1578::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1633::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 219) } - 577 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ",", KwargParameter => ActionFn(1579); + 602 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ",", KwargParameter => ActionFn(1634); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant8(__symbols); + let __sym6 = __pop_Variant9(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1579::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1634::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 219) } - 578 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ",", KwargParameter => ActionFn(1580); + 603 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ",", KwargParameter => ActionFn(1635); assert!(__symbols.len() >= 8); - let __sym7 = __pop_Variant8(__symbols); + let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1580::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1635::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 219) } - 579 => { - // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1581); + 604 => { + // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1636); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant8(__symbols); + let __sym6 = __pop_Variant9(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant11(__symbols); - let __sym3 = __pop_Variant65(__symbols); + let __sym4 = __pop_Variant12(__symbols); + let __sym3 = __pop_Variant64(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1581::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1636::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 219) } - 580 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1582); + 605 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1637); assert!(__symbols.len() >= 9); - let __sym8 = __pop_Variant8(__symbols); + let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant11(__symbols); - let __sym5 = __pop_Variant65(__symbols); + let __sym6 = __pop_Variant12(__symbols); + let __sym5 = __pop_Variant64(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1582::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1637::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (9, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (9, 219) } - 581 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1583); + 606 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1638); assert!(__symbols.len() >= 10); - let __sym9 = __pop_Variant8(__symbols); + let __sym9 = __pop_Variant9(__symbols); let __sym8 = __pop_Variant0(__symbols); - let __sym7 = __pop_Variant11(__symbols); - let __sym6 = __pop_Variant65(__symbols); + let __sym7 = __pop_Variant12(__symbols); + let __sym6 = __pop_Variant64(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = match super::__action1583::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { + let __nt = match super::__action1638::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (10, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (10, 219) } - 582 => { - // ParameterList = OneOrMore>, ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1584); + 607 => { + // ParameterList = OneOrMore>, ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1639); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant8(__symbols); + let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1584::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1639::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 219) } - 583 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1585); + 608 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1640); assert!(__symbols.len() >= 8); - let __sym7 = __pop_Variant8(__symbols); + let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant11(__symbols); + let __sym5 = __pop_Variant12(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1585::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1640::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 219) } - 584 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1586); + 609 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1641); assert!(__symbols.len() >= 9); - let __sym8 = __pop_Variant8(__symbols); + let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant11(__symbols); + let __sym6 = __pop_Variant12(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1586::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1641::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (9, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (9, 219) } - 585 => { - // ParameterList = OneOrMore>, ",", "*", StarTypedParameter => ActionFn(1587); + 610 => { + // ParameterList = OneOrMore>, ",", "*", StarTypedParameter => ActionFn(1642); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant65(__symbols); + let __sym3 = __pop_Variant64(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1587::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1642::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 219) } - 586 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter => ActionFn(1588); + 611 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter => ActionFn(1643); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant65(__symbols); + let __sym5 = __pop_Variant64(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1588::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1643::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 219) } - 587 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter => ActionFn(1589); + 612 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter => ActionFn(1644); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant65(__symbols); + let __sym6 = __pop_Variant64(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1589::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1644::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 219) } - 588 => { - // ParameterList = OneOrMore>, ",", "*" => ActionFn(1590); + 613 => { + // ParameterList = OneOrMore>, ",", "*" => ActionFn(1645); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1590::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1645::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (3, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (3, 219) } - 589 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*" => ActionFn(1591); + 614 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*" => ActionFn(1646); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1591::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1646::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 219) } - 590 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*" => ActionFn(1592); + 615 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*" => ActionFn(1647); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1592::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1647::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 219) } - 591 => { - // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ("," >)+ => ActionFn(1593); + 616 => { + // ParameterList = OneOrMore>, ",", "*", StarTypedParameter, ("," >)+ => ActionFn(1648); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant11(__symbols); - let __sym3 = __pop_Variant65(__symbols); + let __sym4 = __pop_Variant12(__symbols); + let __sym3 = __pop_Variant64(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1593::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1648::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 219) } - 592 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ("," >)+ => ActionFn(1594); + 617 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarTypedParameter, ("," >)+ => ActionFn(1649); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant11(__symbols); - let __sym5 = __pop_Variant65(__symbols); + let __sym6 = __pop_Variant12(__symbols); + let __sym5 = __pop_Variant64(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1594::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1649::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 219) } - 593 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ("," >)+ => ActionFn(1595); + 618 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarTypedParameter, ("," >)+ => ActionFn(1650); assert!(__symbols.len() >= 8); - let __sym7 = __pop_Variant11(__symbols); - let __sym6 = __pop_Variant65(__symbols); + let __sym7 = __pop_Variant12(__symbols); + let __sym6 = __pop_Variant64(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1595::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1650::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 219) } - 594 => { - // ParameterList = OneOrMore>, ",", "*", ("," >)+ => ActionFn(1596); + 619 => { + // ParameterList = OneOrMore>, ",", "*", ("," >)+ => ActionFn(1651); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1596::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1651::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 219) } - 595 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+ => ActionFn(1597); + 620 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+ => ActionFn(1652); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant11(__symbols); + let __sym5 = __pop_Variant12(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1597::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1652::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 219) } - 596 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+ => ActionFn(1598); + 621 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+ => ActionFn(1653); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant11(__symbols); + let __sym6 = __pop_Variant12(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1598::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1653::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 219) } - 597 => { - // ParameterList = OneOrMore> => ActionFn(1599); - let __sym0 = __pop_Variant82(__symbols); + 622 => { + // ParameterList = OneOrMore> => ActionFn(1654); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action1599::<>(mode, __sym0) { + let __nt = match super::__action1654::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (1, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (1, 219) } - 598 => { - // ParameterList = OneOrMore>, ",", "/" => ActionFn(1600); + 623 => { + // ParameterList = OneOrMore>, ",", "/" => ActionFn(1655); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1600::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1655::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (3, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (3, 219) } - 599 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+ => ActionFn(1601); + 624 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+ => ActionFn(1656); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1601::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1656::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 219) } - 600 => { - // ParameterList = OneOrMore>, ",", KwargParameter, "," => ActionFn(1602); + 625 => { + // ParameterList = OneOrMore>, ",", KwargParameter, "," => ActionFn(1657); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant8(__symbols); + let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1602::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1657::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 219) } - 601 => { - // ParameterList = OneOrMore>, ",", "/", ",", KwargParameter, "," => ActionFn(1603); + 626 => { + // ParameterList = OneOrMore>, ",", "/", ",", KwargParameter, "," => ActionFn(1658); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1603::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1658::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 219) } - 602 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", KwargParameter, "," => ActionFn(1604); + 627 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", KwargParameter, "," => ActionFn(1659); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant8(__symbols); + let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1604::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1659::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 219) } - 603 => { - // ParameterList = OneOrMore>, ",", KwargParameter => ActionFn(1605); + 628 => { + // ParameterList = OneOrMore>, ",", KwargParameter => ActionFn(1660); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant8(__symbols); + let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1605::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1660::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (3, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (3, 219) } - 604 => { - // ParameterList = OneOrMore>, ",", "/", ",", KwargParameter => ActionFn(1606); + 629 => { + // ParameterList = OneOrMore>, ",", "/", ",", KwargParameter => ActionFn(1661); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1606::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1661::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 219) } - 605 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", KwargParameter => ActionFn(1607); + 630 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", KwargParameter => ActionFn(1662); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant8(__symbols); + let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1607::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1662::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 219) } - 606 => { - // ParameterList = "*", StarTypedParameter, ",", KwargParameter, "," => ActionFn(1354); + 631 => { + // ParameterList = "*", StarTypedParameter, ",", KwargParameter, "," => ActionFn(1402); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1354::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1402::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 219) } - 607 => { - // ParameterList = "*", ",", KwargParameter, "," => ActionFn(1355); + 632 => { + // ParameterList = "*", ",", KwargParameter, "," => ActionFn(1403); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant8(__symbols); + let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1355::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1403::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 219) } - 608 => { - // ParameterList = "*", StarTypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1356); + 633 => { + // ParameterList = "*", StarTypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1404); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant11(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant12(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1356::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1404::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 219) } - 609 => { - // ParameterList = "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1357); + 634 => { + // ParameterList = "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1405); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant11(__symbols); + let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1357::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1405::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 219) } - 610 => { - // ParameterList = "*", StarTypedParameter, "," => ActionFn(1358); + 635 => { + // ParameterList = "*", StarTypedParameter, "," => ActionFn(1406); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1358::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1406::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (3, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (3, 219) } - 611 => { - // ParameterList = "*", "," => ActionFn(1359); + 636 => { + // ParameterList = "*", "," => ActionFn(1407); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1359::<>(mode, __sym0, __sym1) { + let __nt = match super::__action1407::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (2, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (2, 219) } - 612 => { - // ParameterList = "*", StarTypedParameter, ("," >)+, "," => ActionFn(1360); + 637 => { + // ParameterList = "*", StarTypedParameter, ("," >)+, "," => ActionFn(1408); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant11(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant12(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1360::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1408::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 219) } - 613 => { - // ParameterList = "*", ("," >)+, "," => ActionFn(1361); + 638 => { + // ParameterList = "*", ("," >)+, "," => ActionFn(1409); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant11(__symbols); + let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1361::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1409::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (3, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (3, 219) } - 614 => { - // ParameterList = "*", StarTypedParameter, ",", KwargParameter => ActionFn(1362); + 639 => { + // ParameterList = "*", StarTypedParameter, ",", KwargParameter => ActionFn(1410); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1362::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1410::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 219) } - 615 => { - // ParameterList = "*", ",", KwargParameter => ActionFn(1363); + 640 => { + // ParameterList = "*", ",", KwargParameter => ActionFn(1411); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant8(__symbols); + let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1363::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1411::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (3, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (3, 219) } - 616 => { - // ParameterList = "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1364); + 641 => { + // ParameterList = "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1412); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant11(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant12(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1364::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1412::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 219) } - 617 => { - // ParameterList = "*", ("," >)+, ",", KwargParameter => ActionFn(1365); + 642 => { + // ParameterList = "*", ("," >)+, ",", KwargParameter => ActionFn(1413); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant11(__symbols); + let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1365::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1413::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 219) } - 618 => { - // ParameterList = "*", StarTypedParameter => ActionFn(1366); + 643 => { + // ParameterList = "*", StarTypedParameter => ActionFn(1414); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant65(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1366::<>(mode, __sym0, __sym1) { + let __nt = match super::__action1414::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (2, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (2, 219) } - 619 => { - // ParameterList = "*" => ActionFn(1367); + 644 => { + // ParameterList = "*" => ActionFn(1415); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action1367::<>(mode, __sym0) { + let __nt = match super::__action1415::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (1, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (1, 219) } - 620 => { - // ParameterList = "*", StarTypedParameter, ("," >)+ => ActionFn(1368); + 645 => { + // ParameterList = "*", StarTypedParameter, ("," >)+ => ActionFn(1416); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant11(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant12(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1368::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1416::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (3, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (3, 219) } - 621 => { - // ParameterList = "*", ("," >)+ => ActionFn(1369); + 646 => { + // ParameterList = "*", ("," >)+ => ActionFn(1417); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant11(__symbols); + let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1369::<>(mode, __sym0, __sym1) { + let __nt = match super::__action1417::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (2, 210) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (2, 219) } - 622 => { - __reduce622(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + 647 => { + __reduce647(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } - 623 => { - __reduce623(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + 648 => { + __reduce648(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } - 624 => { - // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ",", KwargParameter, "," => ActionFn(1608); + 649 => { + // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ",", KwargParameter, "," => ActionFn(1663); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant8(__symbols); + let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant65(__symbols); + let __sym3 = __pop_Variant64(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1608::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1663::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 220) } - 625 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ",", KwargParameter, "," => ActionFn(1609); + 650 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ",", KwargParameter, "," => ActionFn(1664); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant0(__symbols); - let __sym7 = __pop_Variant8(__symbols); + let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant65(__symbols); + let __sym5 = __pop_Variant64(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1609::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1664::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (9, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (9, 220) } - 626 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ",", KwargParameter, "," => ActionFn(1610); + 651 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ",", KwargParameter, "," => ActionFn(1665); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant0(__symbols); - let __sym8 = __pop_Variant8(__symbols); + let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant65(__symbols); + let __sym6 = __pop_Variant64(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = match super::__action1610::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { + let __nt = match super::__action1665::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (10, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (10, 220) } - 627 => { - // ParameterList = OneOrMore>, ",", "*", ",", KwargParameter, "," => ActionFn(1611); + 652 => { + // ParameterList = OneOrMore>, ",", "*", ",", KwargParameter, "," => ActionFn(1666); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1611::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1666::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 220) } - 628 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ",", KwargParameter, "," => ActionFn(1612); + 653 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ",", KwargParameter, "," => ActionFn(1667); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant8(__symbols); + let __sym6 = __pop_Variant9(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1612::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1667::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 220) } - 629 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ",", KwargParameter, "," => ActionFn(1613); + 654 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ",", KwargParameter, "," => ActionFn(1668); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant0(__symbols); - let __sym7 = __pop_Variant8(__symbols); + let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1613::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1668::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (9, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (9, 220) } - 630 => { - // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1614); + 655 => { + // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1669); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant8(__symbols); + let __sym6 = __pop_Variant9(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant11(__symbols); - let __sym3 = __pop_Variant65(__symbols); + let __sym4 = __pop_Variant12(__symbols); + let __sym3 = __pop_Variant64(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1614::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1669::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 220) } - 631 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1615); + 656 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1670); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant0(__symbols); - let __sym8 = __pop_Variant8(__symbols); + let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant11(__symbols); - let __sym5 = __pop_Variant65(__symbols); + let __sym6 = __pop_Variant12(__symbols); + let __sym5 = __pop_Variant64(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = match super::__action1615::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { + let __nt = match super::__action1670::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (10, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (10, 220) } - 632 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1616); + 657 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1671); assert!(__symbols.len() >= 11); let __sym10 = __pop_Variant0(__symbols); - let __sym9 = __pop_Variant8(__symbols); + let __sym9 = __pop_Variant9(__symbols); let __sym8 = __pop_Variant0(__symbols); - let __sym7 = __pop_Variant11(__symbols); - let __sym6 = __pop_Variant65(__symbols); + let __sym7 = __pop_Variant12(__symbols); + let __sym6 = __pop_Variant64(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym10.2; - let __nt = match super::__action1616::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9, __sym10) { + let __nt = match super::__action1671::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9, __sym10) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (11, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (11, 220) } - 633 => { - // ParameterList = OneOrMore>, ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1617); + 658 => { + // ParameterList = OneOrMore>, ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1672); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant8(__symbols); + let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1617::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1672::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 220) } - 634 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1618); + 659 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1673); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant0(__symbols); - let __sym7 = __pop_Variant8(__symbols); + let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant11(__symbols); + let __sym5 = __pop_Variant12(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1618::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1673::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (9, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (9, 220) } - 635 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1619); + 660 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1674); assert!(__symbols.len() >= 10); let __sym9 = __pop_Variant0(__symbols); - let __sym8 = __pop_Variant8(__symbols); + let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant11(__symbols); + let __sym6 = __pop_Variant12(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = match super::__action1619::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { + let __nt = match super::__action1674::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (10, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (10, 220) } - 636 => { - // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, "," => ActionFn(1620); + 661 => { + // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, "," => ActionFn(1675); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant65(__symbols); + let __sym3 = __pop_Variant64(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1620::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1675::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 220) } - 637 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, "," => ActionFn(1621); + 662 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, "," => ActionFn(1676); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant65(__symbols); + let __sym5 = __pop_Variant64(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1621::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1676::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 220) } - 638 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, "," => ActionFn(1622); + 663 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, "," => ActionFn(1677); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant65(__symbols); + let __sym6 = __pop_Variant64(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1622::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1677::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 220) } - 639 => { - // ParameterList = OneOrMore>, ",", "*", "," => ActionFn(1623); + 664 => { + // ParameterList = OneOrMore>, ",", "*", "," => ActionFn(1678); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1623::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1678::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 220) } - 640 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", "," => ActionFn(1624); + 665 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", "," => ActionFn(1679); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1624::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1679::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 220) } - 641 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", "," => ActionFn(1625); + 666 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", "," => ActionFn(1680); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1625::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1680::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 220) } - 642 => { - // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ("," >)+, "," => ActionFn(1626); + 667 => { + // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ("," >)+, "," => ActionFn(1681); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant11(__symbols); - let __sym3 = __pop_Variant65(__symbols); + let __sym4 = __pop_Variant12(__symbols); + let __sym3 = __pop_Variant64(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1626::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1681::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 220) } - 643 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ("," >)+, "," => ActionFn(1627); + 668 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ("," >)+, "," => ActionFn(1682); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant11(__symbols); - let __sym5 = __pop_Variant65(__symbols); + let __sym6 = __pop_Variant12(__symbols); + let __sym5 = __pop_Variant64(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1627::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1682::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 220) } - 644 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ("," >)+, "," => ActionFn(1628); + 669 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ("," >)+, "," => ActionFn(1683); assert!(__symbols.len() >= 9); let __sym8 = __pop_Variant0(__symbols); - let __sym7 = __pop_Variant11(__symbols); - let __sym6 = __pop_Variant65(__symbols); + let __sym7 = __pop_Variant12(__symbols); + let __sym6 = __pop_Variant64(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1628::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1683::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (9, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (9, 220) } - 645 => { - // ParameterList = OneOrMore>, ",", "*", ("," >)+, "," => ActionFn(1629); + 670 => { + // ParameterList = OneOrMore>, ",", "*", ("," >)+, "," => ActionFn(1684); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1629::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1684::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 220) } - 646 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, "," => ActionFn(1630); + 671 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, "," => ActionFn(1685); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant11(__symbols); + let __sym5 = __pop_Variant12(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1630::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1685::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 220) } - 647 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, "," => ActionFn(1631); + 672 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, "," => ActionFn(1686); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant11(__symbols); + let __sym6 = __pop_Variant12(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1631::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1686::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 220) } - 648 => { - // ParameterList = OneOrMore>, "," => ActionFn(1632); + 673 => { + // ParameterList = OneOrMore>, "," => ActionFn(1687); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1632::<>(mode, __sym0, __sym1) { + let __nt = match super::__action1687::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (2, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (2, 220) } - 649 => { - // ParameterList = OneOrMore>, ",", "/", "," => ActionFn(1633); + 674 => { + // ParameterList = OneOrMore>, ",", "/", "," => ActionFn(1688); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1633::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1688::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 220) } - 650 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, "," => ActionFn(1634); + 675 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, "," => ActionFn(1689); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1634::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1689::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 220) } - 651 => { - // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1635); + 676 => { + // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1690); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant8(__symbols); + let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant65(__symbols); + let __sym3 = __pop_Variant64(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1635::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1690::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 220) } - 652 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1636); + 677 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1691); assert!(__symbols.len() >= 8); - let __sym7 = __pop_Variant8(__symbols); + let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant65(__symbols); + let __sym5 = __pop_Variant64(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1636::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1691::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 220) } - 653 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1637); + 678 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1692); assert!(__symbols.len() >= 9); - let __sym8 = __pop_Variant8(__symbols); + let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant65(__symbols); + let __sym6 = __pop_Variant64(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1637::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1692::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (9, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (9, 220) } - 654 => { - // ParameterList = OneOrMore>, ",", "*", ",", KwargParameter => ActionFn(1638); + 679 => { + // ParameterList = OneOrMore>, ",", "*", ",", KwargParameter => ActionFn(1693); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1638::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1693::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 220) } - 655 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ",", KwargParameter => ActionFn(1639); + 680 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ",", KwargParameter => ActionFn(1694); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant8(__symbols); + let __sym6 = __pop_Variant9(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1639::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1694::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 220) } - 656 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ",", KwargParameter => ActionFn(1640); + 681 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ",", KwargParameter => ActionFn(1695); assert!(__symbols.len() >= 8); - let __sym7 = __pop_Variant8(__symbols); + let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1640::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1695::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 220) } - 657 => { - // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1641); + 682 => { + // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1696); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant8(__symbols); + let __sym6 = __pop_Variant9(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant11(__symbols); - let __sym3 = __pop_Variant65(__symbols); + let __sym4 = __pop_Variant12(__symbols); + let __sym3 = __pop_Variant64(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1641::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1696::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 220) } - 658 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1642); + 683 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1697); assert!(__symbols.len() >= 9); - let __sym8 = __pop_Variant8(__symbols); + let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant11(__symbols); - let __sym5 = __pop_Variant65(__symbols); + let __sym6 = __pop_Variant12(__symbols); + let __sym5 = __pop_Variant64(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1642::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1697::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (9, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (9, 220) } - 659 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1643); + 684 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1698); assert!(__symbols.len() >= 10); - let __sym9 = __pop_Variant8(__symbols); + let __sym9 = __pop_Variant9(__symbols); let __sym8 = __pop_Variant0(__symbols); - let __sym7 = __pop_Variant11(__symbols); - let __sym6 = __pop_Variant65(__symbols); + let __sym7 = __pop_Variant12(__symbols); + let __sym6 = __pop_Variant64(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = match super::__action1643::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { + let __nt = match super::__action1698::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (10, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (10, 220) } - 660 => { - // ParameterList = OneOrMore>, ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1644); + 685 => { + // ParameterList = OneOrMore>, ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1699); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant8(__symbols); + let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1644::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1699::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 220) } - 661 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1645); + 686 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1700); assert!(__symbols.len() >= 8); - let __sym7 = __pop_Variant8(__symbols); + let __sym7 = __pop_Variant9(__symbols); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant11(__symbols); + let __sym5 = __pop_Variant12(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1645::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1700::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 220) } - 662 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1646); + 687 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+, ",", KwargParameter => ActionFn(1701); assert!(__symbols.len() >= 9); - let __sym8 = __pop_Variant8(__symbols); + let __sym8 = __pop_Variant9(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant11(__symbols); + let __sym6 = __pop_Variant12(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = match super::__action1646::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { + let __nt = match super::__action1701::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (9, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (9, 220) } - 663 => { - // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter => ActionFn(1647); + 688 => { + // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter => ActionFn(1702); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant65(__symbols); + let __sym3 = __pop_Variant64(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1647::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1702::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 220) } - 664 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter => ActionFn(1648); + 689 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter => ActionFn(1703); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant65(__symbols); + let __sym5 = __pop_Variant64(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1648::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1703::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 220) } - 665 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter => ActionFn(1649); + 690 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter => ActionFn(1704); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant65(__symbols); + let __sym6 = __pop_Variant64(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1649::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1704::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 220) } - 666 => { - // ParameterList = OneOrMore>, ",", "*" => ActionFn(1650); + 691 => { + // ParameterList = OneOrMore>, ",", "*" => ActionFn(1705); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1650::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1705::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (3, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (3, 220) } - 667 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*" => ActionFn(1651); + 692 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*" => ActionFn(1706); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1651::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1706::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 220) } - 668 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*" => ActionFn(1652); + 693 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*" => ActionFn(1707); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1652::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1707::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 220) } - 669 => { - // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1653); + 694 => { + // ParameterList = OneOrMore>, ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1708); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant11(__symbols); - let __sym3 = __pop_Variant65(__symbols); + let __sym4 = __pop_Variant12(__symbols); + let __sym3 = __pop_Variant64(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1653::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1708::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 220) } - 670 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1654); + 695 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1709); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant11(__symbols); - let __sym5 = __pop_Variant65(__symbols); + let __sym6 = __pop_Variant12(__symbols); + let __sym5 = __pop_Variant64(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1654::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1709::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 220) } - 671 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1655); + 696 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", StarUntypedParameter, ("," >)+ => ActionFn(1710); assert!(__symbols.len() >= 8); - let __sym7 = __pop_Variant11(__symbols); - let __sym6 = __pop_Variant65(__symbols); + let __sym7 = __pop_Variant12(__symbols); + let __sym6 = __pop_Variant64(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = match super::__action1655::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { + let __nt = match super::__action1710::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (8, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (8, 220) } - 672 => { - // ParameterList = OneOrMore>, ",", "*", ("," >)+ => ActionFn(1656); + 697 => { + // ParameterList = OneOrMore>, ",", "*", ("," >)+ => ActionFn(1711); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1656::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1711::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 220) } - 673 => { - // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+ => ActionFn(1657); + 698 => { + // ParameterList = OneOrMore>, ",", "/", ",", "*", ("," >)+ => ActionFn(1712); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant11(__symbols); + let __sym5 = __pop_Variant12(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1657::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1712::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 220) } - 674 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+ => ActionFn(1658); + 699 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", "*", ("," >)+ => ActionFn(1713); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant11(__symbols); + let __sym6 = __pop_Variant12(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1658::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1713::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 220) } - 675 => { - // ParameterList = OneOrMore> => ActionFn(1659); - let __sym0 = __pop_Variant82(__symbols); + 700 => { + // ParameterList = OneOrMore> => ActionFn(1714); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action1659::<>(mode, __sym0) { + let __nt = match super::__action1714::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (1, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (1, 220) } - 676 => { - // ParameterList = OneOrMore>, ",", "/" => ActionFn(1660); + 701 => { + // ParameterList = OneOrMore>, ",", "/" => ActionFn(1715); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1660::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1715::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (3, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (3, 220) } - 677 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+ => ActionFn(1661); + 702 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+ => ActionFn(1716); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1661::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1716::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 220) } - 678 => { - // ParameterList = OneOrMore>, ",", KwargParameter, "," => ActionFn(1662); + 703 => { + // ParameterList = OneOrMore>, ",", KwargParameter, "," => ActionFn(1717); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant8(__symbols); + let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1662::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1717::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 220) } - 679 => { - // ParameterList = OneOrMore>, ",", "/", ",", KwargParameter, "," => ActionFn(1663); + 704 => { + // ParameterList = OneOrMore>, ",", "/", ",", KwargParameter, "," => ActionFn(1718); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1663::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1718::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 220) } - 680 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", KwargParameter, "," => ActionFn(1664); + 705 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", KwargParameter, "," => ActionFn(1719); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant8(__symbols); + let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = match super::__action1664::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { + let __nt = match super::__action1719::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (7, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (7, 220) } - 681 => { - // ParameterList = OneOrMore>, ",", KwargParameter => ActionFn(1665); + 706 => { + // ParameterList = OneOrMore>, ",", KwargParameter => ActionFn(1720); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant8(__symbols); + let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1665::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1720::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (3, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (3, 220) } - 682 => { - // ParameterList = OneOrMore>, ",", "/", ",", KwargParameter => ActionFn(1666); + 707 => { + // ParameterList = OneOrMore>, ",", "/", ",", KwargParameter => ActionFn(1721); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1666::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1721::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 220) } - 683 => { - // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", KwargParameter => ActionFn(1667); + 708 => { + // ParameterList = OneOrMore>, ",", "/", ("," >)+, ",", KwargParameter => ActionFn(1722); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant8(__symbols); + let __sym5 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1667::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1722::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 220) } - 684 => { - // ParameterList = "*", StarUntypedParameter, ",", KwargParameter, "," => ActionFn(1392); + 709 => { + // ParameterList = "*", StarUntypedParameter, ",", KwargParameter, "," => ActionFn(1440); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1392::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1440::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 220) } - 685 => { - // ParameterList = "*", ",", KwargParameter, "," => ActionFn(1393); + 710 => { + // ParameterList = "*", ",", KwargParameter, "," => ActionFn(1441); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant8(__symbols); + let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1393::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1441::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 220) } - 686 => { - // ParameterList = "*", StarUntypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1394); + 711 => { + // ParameterList = "*", StarUntypedParameter, ("," >)+, ",", KwargParameter, "," => ActionFn(1442); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant11(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant12(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = match super::__action1394::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { + let __nt = match super::__action1442::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (6, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (6, 220) } - 687 => { - // ParameterList = "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1395); + 712 => { + // ParameterList = "*", ("," >)+, ",", KwargParameter, "," => ActionFn(1443); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant11(__symbols); + let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1395::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1443::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 220) } - 688 => { - // ParameterList = "*", StarUntypedParameter, "," => ActionFn(1396); + 713 => { + // ParameterList = "*", StarUntypedParameter, "," => ActionFn(1444); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1396::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1444::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (3, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (3, 220) } - 689 => { - // ParameterList = "*", "," => ActionFn(1397); + 714 => { + // ParameterList = "*", "," => ActionFn(1445); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1397::<>(mode, __sym0, __sym1) { + let __nt = match super::__action1445::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (2, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (2, 220) } - 690 => { - // ParameterList = "*", StarUntypedParameter, ("," >)+, "," => ActionFn(1398); + 715 => { + // ParameterList = "*", StarUntypedParameter, ("," >)+, "," => ActionFn(1446); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant11(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant12(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1398::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1446::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 220) } - 691 => { - // ParameterList = "*", ("," >)+, "," => ActionFn(1399); + 716 => { + // ParameterList = "*", ("," >)+, "," => ActionFn(1447); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant11(__symbols); + let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1399::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1447::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (3, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (3, 220) } - 692 => { - // ParameterList = "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1400); + 717 => { + // ParameterList = "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1448); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1400::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1448::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 220) } - 693 => { - // ParameterList = "*", ",", KwargParameter => ActionFn(1401); + 718 => { + // ParameterList = "*", ",", KwargParameter => ActionFn(1449); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant8(__symbols); + let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1401::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1449::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (3, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (3, 220) } - 694 => { - // ParameterList = "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1402); + 719 => { + // ParameterList = "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1450); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant11(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant12(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action1402::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1450::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (5, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (5, 220) } - 695 => { - // ParameterList = "*", ("," >)+, ",", KwargParameter => ActionFn(1403); + 720 => { + // ParameterList = "*", ("," >)+, ",", KwargParameter => ActionFn(1451); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant11(__symbols); + let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action1403::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1451::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (4, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (4, 220) } - 696 => { - // ParameterList = "*", StarUntypedParameter => ActionFn(1404); + 721 => { + // ParameterList = "*", StarUntypedParameter => ActionFn(1452); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant65(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1404::<>(mode, __sym0, __sym1) { + let __nt = match super::__action1452::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (2, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (2, 220) } - 697 => { - // ParameterList = "*" => ActionFn(1405); + 722 => { + // ParameterList = "*" => ActionFn(1453); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action1405::<>(mode, __sym0) { + let __nt = match super::__action1453::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (1, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (1, 220) } - 698 => { - // ParameterList = "*", StarUntypedParameter, ("," >)+ => ActionFn(1406); + 723 => { + // ParameterList = "*", StarUntypedParameter, ("," >)+ => ActionFn(1454); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant11(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant12(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1406::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1454::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (3, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (3, 220) } - 699 => { - // ParameterList = "*", ("," >)+ => ActionFn(1407); + 724 => { + // ParameterList = "*", ("," >)+ => ActionFn(1455); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant11(__symbols); + let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1407::<>(mode, __sym0, __sym1) { + let __nt = match super::__action1455::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (2, 211) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (2, 220) } - 700 => { - __reduce700(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + 725 => { + __reduce725(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } - 701 => { - __reduce701(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + 726 => { + __reduce726(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } - 702 => { - __reduce702(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + 727 => { + __reduce727(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } - 703 => { - __reduce703(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + 728 => { + __reduce728(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } - 704 => { - // ParameterListStarArgs = "*", StarTypedParameter, ",", KwargParameter => ActionFn(861); + 729 => { + // ParameterListStarArgs = "*", StarTypedParameter, ",", KwargParameter => ActionFn(891); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action861::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action891::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (4, 213) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (4, 222) } - 705 => { - // ParameterListStarArgs = "*", ",", KwargParameter => ActionFn(862); + 730 => { + // ParameterListStarArgs = "*", ",", KwargParameter => ActionFn(892); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant8(__symbols); + let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action862::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action892::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (3, 213) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (3, 222) } - 706 => { - // ParameterListStarArgs = "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(863); + 731 => { + // ParameterListStarArgs = "*", StarTypedParameter, ("," >)+, ",", KwargParameter => ActionFn(893); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant11(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant12(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action863::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action893::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (5, 213) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (5, 222) } - 707 => { - // ParameterListStarArgs = "*", ("," >)+, ",", KwargParameter => ActionFn(864); + 732 => { + // ParameterListStarArgs = "*", ("," >)+, ",", KwargParameter => ActionFn(894); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant11(__symbols); + let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action864::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action894::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (4, 213) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (4, 222) } - 708 => { - // ParameterListStarArgs = "*", StarTypedParameter => ActionFn(865); + 733 => { + // ParameterListStarArgs = "*", StarTypedParameter => ActionFn(895); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant65(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action865::<>(mode, __sym0, __sym1) { + let __nt = match super::__action895::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (2, 213) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (2, 222) } - 709 => { - // ParameterListStarArgs = "*" => ActionFn(866); + 734 => { + // ParameterListStarArgs = "*" => ActionFn(896); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action866::<>(mode, __sym0) { + let __nt = match super::__action896::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (1, 213) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (1, 222) } - 710 => { - // ParameterListStarArgs = "*", StarTypedParameter, ("," >)+ => ActionFn(867); + 735 => { + // ParameterListStarArgs = "*", StarTypedParameter, ("," >)+ => ActionFn(897); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant11(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant12(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action867::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action897::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (3, 213) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (3, 222) } - 711 => { - // ParameterListStarArgs = "*", ("," >)+ => ActionFn(868); + 736 => { + // ParameterListStarArgs = "*", ("," >)+ => ActionFn(898); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant11(__symbols); + let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action868::<>(mode, __sym0, __sym1) { + let __nt = match super::__action898::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (2, 213) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (2, 222) } - 712 => { - // ParameterListStarArgs = "*", StarUntypedParameter, ",", KwargParameter => ActionFn(987); + 737 => { + // ParameterListStarArgs = "*", StarUntypedParameter, ",", KwargParameter => ActionFn(1018); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action987::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1018::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (4, 214) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (4, 223) } - 713 => { - // ParameterListStarArgs = "*", ",", KwargParameter => ActionFn(988); + 738 => { + // ParameterListStarArgs = "*", ",", KwargParameter => ActionFn(1019); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant8(__symbols); + let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action988::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1019::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (3, 214) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (3, 223) } - 714 => { - // ParameterListStarArgs = "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(989); + 739 => { + // ParameterListStarArgs = "*", StarUntypedParameter, ("," >)+, ",", KwargParameter => ActionFn(1020); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant11(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant12(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = match super::__action989::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4) { + let __nt = match super::__action1020::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (5, 214) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (5, 223) } - 715 => { - // ParameterListStarArgs = "*", ("," >)+, ",", KwargParameter => ActionFn(990); + 740 => { + // ParameterListStarArgs = "*", ("," >)+, ",", KwargParameter => ActionFn(1021); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant11(__symbols); + let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = match super::__action990::<>(mode, __sym0, __sym1, __sym2, __sym3) { + let __nt = match super::__action1021::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (4, 214) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (4, 223) } - 716 => { - // ParameterListStarArgs = "*", StarUntypedParameter => ActionFn(991); + 741 => { + // ParameterListStarArgs = "*", StarUntypedParameter => ActionFn(1022); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant65(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action991::<>(mode, __sym0, __sym1) { + let __nt = match super::__action1022::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (2, 214) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (2, 223) } - 717 => { - // ParameterListStarArgs = "*" => ActionFn(992); + 742 => { + // ParameterListStarArgs = "*" => ActionFn(1023); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = match super::__action992::<>(mode, __sym0) { + let __nt = match super::__action1023::<>(source_code, mode, __sym0) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (1, 214) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (1, 223) } - 718 => { - // ParameterListStarArgs = "*", StarUntypedParameter, ("," >)+ => ActionFn(993); + 743 => { + // ParameterListStarArgs = "*", StarUntypedParameter, ("," >)+ => ActionFn(1024); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant11(__symbols); - let __sym1 = __pop_Variant65(__symbols); + let __sym2 = __pop_Variant12(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action993::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1024::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (3, 214) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (3, 223) } - 719 => { - // ParameterListStarArgs = "*", ("," >)+ => ActionFn(994); + 744 => { + // ParameterListStarArgs = "*", ("," >)+ => ActionFn(1025); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant11(__symbols); + let __sym1 = __pop_Variant12(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action994::<>(mode, __sym0, __sym1) { + let __nt = match super::__action1025::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (2, 214) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (2, 223) } - 720 => { - // Parameters = "(", ParameterList, ")" => ActionFn(1486); + 745 => { + // Parameters = "(", ParameterList, ")" => ActionFn(1458); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant47(__symbols); + let __sym1 = __pop_Variant46(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = match super::__action1486::<>(mode, __sym0, __sym1, __sym2) { + let __nt = match super::__action1458::<>(source_code, mode, __sym0, __sym1, __sym2) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (3, 215) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (3, 224) } - 721 => { - // Parameters = "(", ")" => ActionFn(1487); + 746 => { + // Parameters = "(", ")" => ActionFn(1459); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = match super::__action1487::<>(mode, __sym0, __sym1) { + let __nt = match super::__action1459::<>(source_code, mode, __sym0, __sym1) { Ok(v) => v, Err(e) => return Some(Err(e)), }; - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (2, 215) - } - 722 => { - __reduce722(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 723 => { - __reduce723(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 724 => { - __reduce724(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 725 => { - __reduce725(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 726 => { - __reduce726(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 727 => { - __reduce727(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 728 => { - __reduce728(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 729 => { - __reduce729(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 730 => { - __reduce730(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 731 => { - __reduce731(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 732 => { - __reduce732(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 733 => { - __reduce733(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 734 => { - __reduce734(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 735 => { - __reduce735(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 736 => { - __reduce736(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 737 => { - __reduce737(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 738 => { - __reduce738(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 739 => { - __reduce739(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 740 => { - __reduce740(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 741 => { - __reduce741(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 742 => { - __reduce742(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 743 => { - __reduce743(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 744 => { - __reduce744(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 745 => { - __reduce745(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) - } - 746 => { - __reduce746(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (2, 224) } 747 => { - __reduce747(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce747(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 748 => { - __reduce748(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce748(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 749 => { - __reduce749(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce749(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 750 => { - __reduce750(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce750(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 751 => { - __reduce751(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce751(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 752 => { - __reduce752(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce752(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 753 => { - __reduce753(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce753(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 754 => { - __reduce754(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce754(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 755 => { - __reduce755(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce755(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 756 => { - __reduce756(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce756(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 757 => { - __reduce757(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce757(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 758 => { - __reduce758(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce758(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 759 => { - __reduce759(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce759(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 760 => { - __reduce760(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce760(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 761 => { - __reduce761(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce761(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 762 => { - __reduce762(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce762(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 763 => { - __reduce763(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce763(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 764 => { - __reduce764(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce764(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 765 => { - __reduce765(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce765(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 766 => { - __reduce766(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce766(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 767 => { - __reduce767(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce767(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 768 => { - __reduce768(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce768(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 769 => { - __reduce769(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce769(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 770 => { - __reduce770(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce770(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 771 => { - __reduce771(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce771(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 772 => { - __reduce772(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce772(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 773 => { - __reduce773(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce773(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 774 => { - __reduce774(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce774(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 775 => { - __reduce775(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce775(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 776 => { - __reduce776(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce776(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 777 => { - __reduce777(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce777(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 778 => { - __reduce778(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce778(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 779 => { - __reduce779(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce779(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 780 => { - __reduce780(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce780(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 781 => { - __reduce781(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce781(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 782 => { - __reduce782(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce782(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 783 => { - __reduce783(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce783(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 784 => { - __reduce784(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce784(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 785 => { - __reduce785(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce785(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 786 => { - __reduce786(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce786(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 787 => { - __reduce787(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce787(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 788 => { - __reduce788(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce788(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 789 => { - __reduce789(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce789(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 790 => { - __reduce790(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce790(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 791 => { - __reduce791(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce791(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 792 => { - __reduce792(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce792(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 793 => { - __reduce793(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce793(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 794 => { - __reduce794(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce794(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 795 => { - __reduce795(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce795(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 796 => { - __reduce796(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce796(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 797 => { - __reduce797(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce797(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 798 => { - __reduce798(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce798(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 799 => { - __reduce799(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce799(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 800 => { - __reduce800(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce800(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 801 => { - __reduce801(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce801(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 802 => { - __reduce802(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce802(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 803 => { - __reduce803(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce803(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 804 => { - __reduce804(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce804(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 805 => { - __reduce805(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce805(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 806 => { - __reduce806(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce806(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 807 => { - __reduce807(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce807(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 808 => { - __reduce808(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce808(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 809 => { - __reduce809(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce809(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 810 => { - __reduce810(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce810(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 811 => { - __reduce811(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce811(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 812 => { - __reduce812(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce812(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 813 => { - __reduce813(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce813(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 814 => { - __reduce814(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce814(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 815 => { - __reduce815(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce815(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 816 => { - __reduce816(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce816(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 817 => { - __reduce817(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce817(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 818 => { - __reduce818(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce818(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 819 => { - __reduce819(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce819(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 820 => { - __reduce820(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce820(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 821 => { - __reduce821(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce821(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 822 => { - __reduce822(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce822(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 823 => { - __reduce823(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce823(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 824 => { - __reduce824(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce824(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 825 => { - __reduce825(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce825(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 826 => { - __reduce826(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce826(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 827 => { - __reduce827(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce827(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 828 => { - __reduce828(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce828(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 829 => { - __reduce829(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce829(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 830 => { - __reduce830(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce830(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 831 => { - __reduce831(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce831(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 832 => { - __reduce832(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce832(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 833 => { - __reduce833(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce833(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 834 => { - __reduce834(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + // StringLiteral = string => ActionFn(934); + let __sym0 = __pop_Variant7(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = match super::__action934::<>(source_code, mode, __sym0) { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + __symbols.push((__start, __Symbol::Variant70(__nt), __end)); + (1, 251) } 835 => { - __reduce835(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce835(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 836 => { - __reduce836(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce836(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 837 => { - __reduce837(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce837(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 838 => { - __reduce838(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce838(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 839 => { - __reduce839(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce839(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 840 => { - __reduce840(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce840(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 841 => { - __reduce841(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce841(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 842 => { - __reduce842(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce842(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 843 => { - __reduce843(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce843(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 844 => { - __reduce844(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce844(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 845 => { - __reduce845(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce845(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 846 => { - __reduce846(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce846(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 847 => { - __reduce847(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce847(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 848 => { - __reduce848(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce848(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 849 => { - __reduce849(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce849(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 850 => { - __reduce850(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce850(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 851 => { - __reduce851(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce851(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 852 => { - __reduce852(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce852(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 853 => { - __reduce853(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce853(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 854 => { - __reduce854(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce854(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 855 => { - __reduce855(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce855(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 856 => { - __reduce856(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce856(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 857 => { - __reduce857(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce857(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 858 => { - __reduce858(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce858(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 859 => { - __reduce859(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce859(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 860 => { - __reduce860(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce860(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 861 => { - __reduce861(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce861(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 862 => { - __reduce862(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce862(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 863 => { - __reduce863(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce863(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 864 => { - __reduce864(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce864(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 865 => { - __reduce865(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce865(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 866 => { - __reduce866(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce866(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 867 => { - __reduce867(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce867(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 868 => { - __reduce868(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce868(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 869 => { - __reduce869(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce869(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 870 => { - __reduce870(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce870(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 871 => { - __reduce871(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce871(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 872 => { - __reduce872(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce872(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 873 => { - __reduce873(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce873(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 874 => { - __reduce874(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce874(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 875 => { - __reduce875(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce875(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 876 => { - __reduce876(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce876(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 877 => { - __reduce877(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce877(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 878 => { - __reduce878(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce878(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 879 => { - __reduce879(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce879(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 880 => { - __reduce880(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce880(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 881 => { - __reduce881(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce881(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 882 => { - __reduce882(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce882(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 883 => { - __reduce883(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce883(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 884 => { - __reduce884(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce884(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 885 => { - __reduce885(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce885(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 886 => { - __reduce886(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce886(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 887 => { - __reduce887(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce887(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 888 => { - __reduce888(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce888(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 889 => { - __reduce889(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce889(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 890 => { - __reduce890(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce890(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 891 => { - __reduce891(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce891(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 892 => { - __reduce892(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce892(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 893 => { - __reduce893(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce893(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 894 => { - __reduce894(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce894(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 895 => { - __reduce895(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce895(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 896 => { - __reduce896(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce896(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 897 => { - __reduce897(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce897(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 898 => { - __reduce898(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce898(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 899 => { - __reduce899(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce899(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 900 => { - __reduce900(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce900(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 901 => { - __reduce901(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce901(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 902 => { - __reduce902(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce902(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 903 => { - __reduce903(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce903(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 904 => { - __reduce904(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce904(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 905 => { - __reduce905(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce905(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 906 => { - __reduce906(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce906(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 907 => { - __reduce907(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce907(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 908 => { - __reduce908(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce908(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 909 => { - __reduce909(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce909(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 910 => { - __reduce910(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce910(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 911 => { - __reduce911(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce911(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 912 => { - __reduce912(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce912(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 913 => { - __reduce913(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce913(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 914 => { - __reduce914(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce914(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 915 => { - __reduce915(mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + __reduce915(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) } 916 => { + __reduce916(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 917 => { + __reduce917(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 918 => { + __reduce918(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 919 => { + __reduce919(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 920 => { + __reduce920(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 921 => { + __reduce921(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 922 => { + __reduce922(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 923 => { + __reduce923(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 924 => { + __reduce924(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 925 => { + __reduce925(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 926 => { + __reduce926(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 927 => { + __reduce927(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 928 => { + __reduce928(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 929 => { + __reduce929(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 930 => { + __reduce930(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 931 => { + __reduce931(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 932 => { + __reduce932(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 933 => { + __reduce933(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 934 => { + __reduce934(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 935 => { + __reduce935(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 936 => { + __reduce936(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 937 => { + __reduce937(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 938 => { + __reduce938(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 939 => { + __reduce939(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 940 => { + __reduce940(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 941 => { + __reduce941(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 942 => { + __reduce942(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 943 => { + __reduce943(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 944 => { + __reduce944(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 945 => { + __reduce945(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 946 => { + __reduce946(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 947 => { + __reduce947(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 948 => { // __Top = Top => ActionFn(0); - let __sym0 = __pop_Variant92(__symbols); + let __sym0 = __pop_Variant96(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action0::<>(mode, __sym0); + let __nt = super::__action0::<>(source_code, mode, __sym0); return Some(Ok(__nt)); } + 949 => { + __reduce949(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } + 950 => { + __reduce950(source_code, mode, __lookahead_start, __symbols, core::marker::PhantomData::<()>) + } _ => panic!("invalid action code {}", __action) }; let __states_len = __states.len(); @@ -17553,143 +18237,153 @@ mod __parse__Top { fn __symbol_type_mismatch() -> ! { panic!("symbol type mismatch") } - fn __pop_Variant4< + fn __pop_Variant5< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, (IpyEscapeKind, String), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant4(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant5(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant30< + fn __pop_Variant31< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, (Option<(TextSize, TextSize, Option)>, ast::Expr), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant30(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant31(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant12< + fn __pop_Variant13< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, (Option>, Vec, Option>), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant12(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant13(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant61< + fn __pop_Variant60< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, (Option>, ast::ParenthesizedExpr), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant61(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant60(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant74< + fn __pop_Variant77< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, (Option, Option), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant74(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant77(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant6< + fn __pop_Variant7< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, (String, StringKind, bool), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant6(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant7(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant41< + fn __pop_Variant3< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, (TextSize, (String, StringKind, bool), TextSize), TextSize) + ) -> (TextSize, (String, bool), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant41(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant3(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant26< + fn __pop_Variant68< + >( + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> + ) -> (TextSize, (TextSize, ast::ConversionFlag), TextSize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant68(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant27< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, (TextSize, ast::ParenthesizedExpr, ast::Suite), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant26(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant27(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant28< + fn __pop_Variant29< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, (TextSize, ast::Suite), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant28(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant29(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant84< + fn __pop_Variant87< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, (Vec, Vec), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant84(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant87(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant43< + fn __pop_Variant42< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, (ast::CmpOp, ast::ParenthesizedExpr), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant43(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant42(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant78< + fn __pop_Variant81< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, (ast::Expr, ast::Pattern), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant78(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant81(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant38< + fn __pop_Variant39< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, (ast::ParenthesizedExpr, ast::Identifier), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant38(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant39(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant62< + fn __pop_Variant61< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, (ast::ParenthesizedExpr, ast::ParenthesizedExpr), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant62(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant61(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -17703,793 +18397,833 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant19< + fn __pop_Variant20< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, (token::Tok, ast::Identifier), TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant19(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant20(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant3< + fn __pop_Variant4< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, BigInt, TextSize) + ) -> (TextSize, Int, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant3(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant4(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant8< + fn __pop_Variant9< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Option>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant8(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant9(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant89< + fn __pop_Variant92< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Option, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant89(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant92(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant5< + fn __pop_Variant6< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, String, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant5(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant6(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant49< + fn __pop_Variant70< + >( + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> + ) -> (TextSize, StringType, TextSize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant70(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant48< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, TextSize, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant49(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant48(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant53< + fn __pop_Variant52< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant53(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant52(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant63< + fn __pop_Variant62< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Vec<(Option>, ast::ParenthesizedExpr)>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant63(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant62(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant81< + fn __pop_Variant84< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Vec<(ast::Expr, ast::Pattern)>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant81(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant84(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant71< + fn __pop_Variant74< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant71(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant74(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant55< + fn __pop_Variant54< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant55(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant54(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant79< + fn __pop_Variant82< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant79(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant82(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant82< + fn __pop_Variant85< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant82(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant85(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant32< + fn __pop_Variant33< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant32(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant33(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant54< + fn __pop_Variant53< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant54(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant53(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant80< + fn __pop_Variant83< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant80(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant83(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant91< + fn __pop_Variant94< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant91(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant94(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant83< + fn __pop_Variant86< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant83(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant86(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant39< + fn __pop_Variant40< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant39(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant40(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant31< + fn __pop_Variant32< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, alloc::vec::Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant31(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant32(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant42< + fn __pop_Variant28< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, alloc::vec::Vec<(TextSize, (String, StringKind, bool), TextSize)>, TextSize) + ) -> (TextSize, alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant42(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant28(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant27< + fn __pop_Variant43< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)>, TextSize) + ) -> (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant27(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant43(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant44< + fn __pop_Variant21< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize) + ) -> (TextSize, alloc::vec::Vec<(token::Tok, ast::Identifier)>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant44(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant21(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant20< + fn __pop_Variant95< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> - ) -> (TextSize, alloc::vec::Vec<(token::Tok, ast::Identifier)>, TextSize) + ) -> (TextSize, alloc::vec::Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant20(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant95(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant88< + fn __pop_Variant91< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, alloc::vec::Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant88(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant91(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant60< + fn __pop_Variant59< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, alloc::vec::Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant60(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant59(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant68< + fn __pop_Variant67< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, alloc::vec::Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant68(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant67(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant76< + fn __pop_Variant71< + >( + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> + ) -> (TextSize, alloc::vec::Vec, TextSize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant71(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant79< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, alloc::vec::Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant76(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant79(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant11< + fn __pop_Variant12< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, alloc::vec::Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant11(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant12(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant16< + fn __pop_Variant17< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, alloc::vec::Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant16(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant17(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant35< + fn __pop_Variant36< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, alloc::vec::Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant35(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant36(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant37< + fn __pop_Variant38< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, alloc::vec::Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant37(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant38(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant18< + fn __pop_Variant19< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, alloc::vec::Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant18(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant19(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant21< + fn __pop_Variant22< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, alloc::vec::Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant21(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant22(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant73< + fn __pop_Variant76< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, alloc::vec::Vec, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant73(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant76(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant70< + fn __pop_Variant73< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Alias, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant70(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant73(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant51< + fn __pop_Variant50< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Arguments, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant51(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant50(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant57< + fn __pop_Variant56< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::CmpOp, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant57(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant56(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant87< + fn __pop_Variant90< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Comprehension, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant87(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant90(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant58< + fn __pop_Variant57< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Constant, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant58(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant57(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant59< + fn __pop_Variant58< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Decorator, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant59(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant58(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant67< + fn __pop_Variant66< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::ExceptHandler, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant67(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant66(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant45< + fn __pop_Variant44< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Expr, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant45(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant44(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant22< + fn __pop_Variant23< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Identifier, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant22(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant23(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant75< + fn __pop_Variant78< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::MatchCase, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant75(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant78(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant92< + fn __pop_Variant96< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Mod, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant92(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant96(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant50< + fn __pop_Variant49< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Operator, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant50(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant49(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant65< + fn __pop_Variant64< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Parameter, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant65(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant64(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant10< + fn __pop_Variant11< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::ParameterWithDefault, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant10(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant11(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant47< + fn __pop_Variant46< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Parameters, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant47(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant46(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant14< + fn __pop_Variant15< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::ParenthesizedExpr, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant14(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant15(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant34< + fn __pop_Variant35< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Pattern, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant34(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant35(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant86< + fn __pop_Variant89< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::PatternArguments, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant86(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant89(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant77< + fn __pop_Variant80< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::PatternKeyword, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant77(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant80(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant36< + fn __pop_Variant37< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Stmt, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant36(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant37(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant24< + fn __pop_Variant25< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::Suite, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant24(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant25(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant93< + fn __pop_Variant97< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::TypeParam, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant93(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant97(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant94< + fn __pop_Variant98< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::TypeParams, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant94(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant98(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant96< + fn __pop_Variant100< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::UnaryOp, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant96(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant100(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant17< + fn __pop_Variant18< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, ast::WithItem, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant17(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant18(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant69< + fn __pop_Variant72< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant69(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant72(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant13< + fn __pop_Variant14< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option<(Option>, Vec, Option>)>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant13(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant14(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant29< + fn __pop_Variant101< + >( + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> + ) -> (TextSize, core::option::Option<(String, bool)>, TextSize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant101(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant69< + >( + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> + ) -> (TextSize, core::option::Option<(TextSize, ast::ConversionFlag)>, TextSize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant69(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant30< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option<(TextSize, ast::Suite)>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant29(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant30(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant9< + fn __pop_Variant10< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option>>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant9(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant10(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant90< + fn __pop_Variant93< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant90(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant93(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant64< + fn __pop_Variant63< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option>, ast::ParenthesizedExpr)>>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant64(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant63(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant56< + fn __pop_Variant55< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant56(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant55(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant33< + fn __pop_Variant34< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant33(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant34(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant40< + fn __pop_Variant41< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option>, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant40(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant41(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant52< + fn __pop_Variant51< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant52(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant51(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant46< + fn __pop_Variant45< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant46(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant45(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant23< + fn __pop_Variant24< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant23(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant24(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant66< + fn __pop_Variant65< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant66(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant65(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant48< + fn __pop_Variant47< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant48(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant47(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant15< + fn __pop_Variant16< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant15(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant16(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant85< + fn __pop_Variant88< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant85(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant88(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant25< + fn __pop_Variant26< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant25(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant26(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant95< + fn __pop_Variant99< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant95(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant99(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant7< + fn __pop_Variant8< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, core::option::Option, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant7(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant8(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -18513,2048 +19247,2148 @@ mod __parse__Top { _ => __symbol_type_mismatch() } } - fn __pop_Variant72< + fn __pop_Variant75< >( __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)> ) -> (TextSize, u32, TextSize) { match __symbols.pop() { - Some((__l, __Symbol::Variant72(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant75(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } pub(crate) fn __reduce0< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ","? = "," => ActionFn(360); + // ","? = "," => ActionFn(381); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action360::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant7(__nt), __end)); + let __nt = super::__action381::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant8(__nt), __end)); (1, 0) } pub(crate) fn __reduce1< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ","? = => ActionFn(361); + // ","? = => ActionFn(382); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action361::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant7(__nt), __end)); + let __nt = super::__action382::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant8(__nt), __end)); (0, 0) } pub(crate) fn __reduce2< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ";"? = ";" => ActionFn(384); + // ";"? = ";" => ActionFn(405); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action384::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant7(__nt), __end)); + let __nt = super::__action405::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant8(__nt), __end)); (1, 1) } pub(crate) fn __reduce3< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ";"? = => ActionFn(385); + // ";"? = => ActionFn(406); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action385::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant7(__nt), __end)); + let __nt = super::__action406::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant8(__nt), __end)); (0, 1) } pub(crate) fn __reduce4< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // "async"? = "async" => ActionFn(312); + // "="? = "=" => ActionFn(268); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action312::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant7(__nt), __end)); + let __nt = super::__action268::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant8(__nt), __end)); (1, 2) } pub(crate) fn __reduce5< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // "async"? = => ActionFn(313); + // "="? = => ActionFn(269); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action313::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant7(__nt), __end)); + let __nt = super::__action269::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant8(__nt), __end)); (0, 2) } pub(crate) fn __reduce6< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >) = ",", KwargParameter => ActionFn(416); - assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant8(__symbols); + // "async"? = "async" => ActionFn(332); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; - let __end = __sym1.2; - let __nt = super::__action416::<>(mode, __sym0, __sym1); + let __end = __sym0.2; + let __nt = super::__action332::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant8(__nt), __end)); - (2, 3) + (1, 3) } pub(crate) fn __reduce7< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)? = ",", KwargParameter => ActionFn(661); - assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant8(__symbols); - let __sym0 = __pop_Variant0(__symbols); - let __start = __sym0.0; - let __end = __sym1.2; - let __nt = super::__action661::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (2, 4) + // "async"? = => ActionFn(333); + let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); + let __end = __start.clone(); + let __nt = super::__action333::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant8(__nt), __end)); + (0, 3) } pub(crate) fn __reduce8< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)? = => ActionFn(467); - let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); - let __end = __start.clone(); - let __nt = super::__action467::<>(mode, &__start, &__end); + // ("," >) = ",", KwargParameter => ActionFn(437); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant9(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym1.2; + let __nt = super::__action437::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (0, 4) + (2, 4) } pub(crate) fn __reduce9< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >) = ",", KwargParameter => ActionFn(424); + // ("," >)? = ",", KwargParameter => ActionFn(686); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant8(__symbols); + let __sym1 = __pop_Variant9(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action424::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant8(__nt), __end)); + let __nt = super::__action686::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant10(__nt), __end)); (2, 5) } pub(crate) fn __reduce10< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)? = ",", KwargParameter => ActionFn(666); - assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant8(__symbols); - let __sym0 = __pop_Variant0(__symbols); - let __start = __sym0.0; - let __end = __sym1.2; - let __nt = super::__action666::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (2, 6) + // ("," >)? = => ActionFn(490); + let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); + let __end = __start.clone(); + let __nt = super::__action490::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant10(__nt), __end)); + (0, 5) } pub(crate) fn __reduce11< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)? = => ActionFn(456); - let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); - let __end = __start.clone(); - let __nt = super::__action456::<>(mode, &__start, &__end); + // ("," >) = ",", KwargParameter => ActionFn(445); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant9(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym1.2; + let __nt = super::__action445::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (0, 6) + (2, 6) } pub(crate) fn __reduce12< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >) = ",", ParameterDef => ActionFn(470); + // ("," >)? = ",", KwargParameter => ActionFn(691); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant10(__symbols); + let __sym1 = __pop_Variant9(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action470::<>(mode, __sym0, __sym1); + let __nt = super::__action691::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant10(__nt), __end)); (2, 7) } pub(crate) fn __reduce13< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)* = => ActionFn(468); + // ("," >)? = => ActionFn(479); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action468::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant11(__nt), __end)); - (0, 8) + let __nt = super::__action479::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant10(__nt), __end)); + (0, 7) } pub(crate) fn __reduce14< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)* = ("," >)+ => ActionFn(469); - let __sym0 = __pop_Variant11(__symbols); + // ("," >) = ",", ParameterDef => ActionFn(493); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant11(__symbols); + let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; - let __end = __sym0.2; - let __nt = super::__action469::<>(mode, __sym0); + let __end = __sym1.2; + let __nt = super::__action493::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant11(__nt), __end)); - (1, 8) + (2, 8) } pub(crate) fn __reduce15< >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // ("," >)* = => ActionFn(491); + let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); + let __end = __start.clone(); + let __nt = super::__action491::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (0, 9) + } + pub(crate) fn __reduce16< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // ("," >)* = ("," >)+ => ActionFn(492); + let __sym0 = __pop_Variant12(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = super::__action492::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (1, 9) + } + pub(crate) fn __reduce17< + >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)+ = ",", ParameterDef => ActionFn(671); + // ("," >)+ = ",", ParameterDef => ActionFn(696); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant10(__symbols); + let __sym1 = __pop_Variant11(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action671::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant11(__nt), __end)); - (2, 9) + let __nt = super::__action696::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (2, 10) } - pub(crate) fn __reduce16< + pub(crate) fn __reduce18< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)+ = ("," >)+, ",", ParameterDef => ActionFn(672); + // ("," >)+ = ("," >)+, ",", ParameterDef => ActionFn(697); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant10(__symbols); + let __sym2 = __pop_Variant11(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant11(__symbols); + let __sym0 = __pop_Variant12(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action672::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant11(__nt), __end)); - (3, 9) + let __nt = super::__action697::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (3, 10) } - pub(crate) fn __reduce17< + pub(crate) fn __reduce19< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >) = ",", ParameterDef => ActionFn(459); + // ("," >) = ",", ParameterDef => ActionFn(482); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant10(__symbols); + let __sym1 = __pop_Variant11(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action459::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant10(__nt), __end)); - (2, 10) + let __nt = super::__action482::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (2, 11) } - pub(crate) fn __reduce18< + pub(crate) fn __reduce20< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)* = => ActionFn(457); + // ("," >)* = => ActionFn(480); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action457::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant11(__nt), __end)); - (0, 11) + let __nt = super::__action480::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (0, 12) } - pub(crate) fn __reduce19< + pub(crate) fn __reduce21< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)* = ("," >)+ => ActionFn(458); - let __sym0 = __pop_Variant11(__symbols); + // ("," >)* = ("," >)+ => ActionFn(481); + let __sym0 = __pop_Variant12(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action458::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant11(__nt), __end)); - (1, 11) + let __nt = super::__action481::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (1, 12) } - pub(crate) fn __reduce20< + pub(crate) fn __reduce22< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)+ = ",", ParameterDef => ActionFn(679); + // ("," >)+ = ",", ParameterDef => ActionFn(704); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant10(__symbols); + let __sym1 = __pop_Variant11(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action679::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant11(__nt), __end)); - (2, 12) + let __nt = super::__action704::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (2, 13) } - pub(crate) fn __reduce21< + pub(crate) fn __reduce23< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)+ = ("," >)+, ",", ParameterDef => ActionFn(680); + // ("," >)+ = ("," >)+, ",", ParameterDef => ActionFn(705); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant10(__symbols); + let __sym2 = __pop_Variant11(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant11(__symbols); + let __sym0 = __pop_Variant12(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action680::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant11(__nt), __end)); - (3, 12) + let __nt = super::__action705::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (3, 13) } - pub(crate) fn __reduce38< + pub(crate) fn __reduce40< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)? = => ActionFn(419); + // ("," >)? = => ActionFn(440); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action419::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (0, 14) + let __nt = super::__action440::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (0, 15) } - pub(crate) fn __reduce55< + pub(crate) fn __reduce57< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)? = => ActionFn(427); + // ("," >)? = => ActionFn(448); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action427::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (0, 16) + let __nt = super::__action448::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (0, 17) } - pub(crate) fn __reduce56< + pub(crate) fn __reduce58< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >) = ",", Test<"all"> => ActionFn(354); + // ("," >) = ",", Test<"all"> => ActionFn(375); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action354::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 17) + let __nt = super::__action375::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 18) } - pub(crate) fn __reduce57< + pub(crate) fn __reduce59< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)? = ",", Test<"all"> => ActionFn(1045); + // ("," >)? = ",", Test<"all"> => ActionFn(1076); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1045::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (2, 18) + let __nt = super::__action1076::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (2, 19) } - pub(crate) fn __reduce58< + pub(crate) fn __reduce60< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)? = => ActionFn(353); + // ("," >)? = => ActionFn(374); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action353::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (0, 18) + let __nt = super::__action374::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (0, 19) } - pub(crate) fn __reduce59< + pub(crate) fn __reduce61< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," ) = ",", TestOrStarNamedExpr => ActionFn(545); + // ("," ) = ",", TestOrStarNamedExpr => ActionFn(568); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action545::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 19) + let __nt = super::__action568::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 20) } - pub(crate) fn __reduce60< + pub(crate) fn __reduce62< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," )* = => ActionFn(543); + // ("," )* = => ActionFn(566); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action543::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (0, 20) + let __nt = super::__action566::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (0, 21) } - pub(crate) fn __reduce61< + pub(crate) fn __reduce63< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," )* = ("," )+ => ActionFn(544); - let __sym0 = __pop_Variant16(__symbols); + // ("," )* = ("," )+ => ActionFn(567); + let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action544::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (1, 20) + let __nt = super::__action567::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (1, 21) } - pub(crate) fn __reduce62< + pub(crate) fn __reduce64< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," )+ = ",", TestOrStarNamedExpr => ActionFn(1048); + // ("," )+ = ",", TestOrStarNamedExpr => ActionFn(1079); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1048::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (2, 21) + let __nt = super::__action1079::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (2, 22) } - pub(crate) fn __reduce63< + pub(crate) fn __reduce65< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," )+ = ("," )+, ",", TestOrStarNamedExpr => ActionFn(1049); + // ("," )+ = ("," )+, ",", TestOrStarNamedExpr => ActionFn(1080); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant16(__symbols); + let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1049::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (3, 21) + let __nt = super::__action1080::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (3, 22) } - pub(crate) fn __reduce64< + pub(crate) fn __reduce66< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >) = ",", WithItem<"all"> => ActionFn(296); + // ("," >) = ",", WithItem<"all"> => ActionFn(316); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant17(__symbols); + let __sym1 = __pop_Variant18(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action296::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant17(__nt), __end)); - (2, 22) + let __nt = super::__action316::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant18(__nt), __end)); + (2, 23) } - pub(crate) fn __reduce65< + pub(crate) fn __reduce67< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)* = => ActionFn(294); + // ("," >)* = => ActionFn(314); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action294::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant18(__nt), __end)); - (0, 23) + let __nt = super::__action314::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant19(__nt), __end)); + (0, 24) } - pub(crate) fn __reduce66< + pub(crate) fn __reduce68< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)* = ("," >)+ => ActionFn(295); - let __sym0 = __pop_Variant18(__symbols); + // ("," >)* = ("," >)+ => ActionFn(315); + let __sym0 = __pop_Variant19(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action295::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant18(__nt), __end)); - (1, 23) + let __nt = super::__action315::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant19(__nt), __end)); + (1, 24) } - pub(crate) fn __reduce67< + pub(crate) fn __reduce69< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)+ = ",", WithItem<"all"> => ActionFn(1058); + // ("," >)+ = ",", WithItem<"all"> => ActionFn(1089); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant17(__symbols); + let __sym1 = __pop_Variant18(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1058::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant18(__nt), __end)); - (2, 24) + let __nt = super::__action1089::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant19(__nt), __end)); + (2, 25) } - pub(crate) fn __reduce68< + pub(crate) fn __reduce70< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("," >)+ = ("," >)+, ",", WithItem<"all"> => ActionFn(1059); + // ("," >)+ = ("," >)+, ",", WithItem<"all"> => ActionFn(1090); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant17(__symbols); + let __sym2 = __pop_Variant18(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant18(__symbols); + let __sym0 = __pop_Variant19(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1059::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant18(__nt), __end)); - (3, 24) + let __nt = super::__action1090::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant19(__nt), __end)); + (3, 25) } - pub(crate) fn __reduce69< + pub(crate) fn __reduce71< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("->" >) = "->", Test<"all"> => ActionFn(283); + // ("->" >) = "->", Test<"all"> => ActionFn(303); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action283::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 25) + let __nt = super::__action303::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 26) } - pub(crate) fn __reduce70< + pub(crate) fn __reduce72< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("->" >)? = "->", Test<"all"> => ActionFn(1064); + // ("->" >)? = "->", Test<"all"> => ActionFn(1095); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1064::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (2, 26) + let __nt = super::__action1095::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (2, 27) } - pub(crate) fn __reduce71< + pub(crate) fn __reduce73< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("->" >)? = => ActionFn(282); + // ("->" >)? = => ActionFn(302); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action282::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (0, 26) + let __nt = super::__action302::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (0, 27) } - pub(crate) fn __reduce72< + pub(crate) fn __reduce74< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("." Identifier) = ".", Identifier => ActionFn(359); + // ("." Identifier) = ".", Identifier => ActionFn(380); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant22(__symbols); + let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action359::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant19(__nt), __end)); - (2, 27) + let __nt = super::__action380::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant20(__nt), __end)); + (2, 28) } - pub(crate) fn __reduce73< + pub(crate) fn __reduce75< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("." Identifier)+ = ".", Identifier => ActionFn(1069); + // ("." Identifier)+ = ".", Identifier => ActionFn(1100); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant22(__symbols); + let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1069::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant20(__nt), __end)); - (2, 28) + let __nt = super::__action1100::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant21(__nt), __end)); + (2, 29) } - pub(crate) fn __reduce74< + pub(crate) fn __reduce76< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("." Identifier)+ = ("." Identifier)+, ".", Identifier => ActionFn(1070); + // ("." Identifier)+ = ("." Identifier)+, ".", Identifier => ActionFn(1101); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant20(__symbols); + let __sym0 = __pop_Variant21(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1070::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant20(__nt), __end)); - (3, 28) + let __nt = super::__action1101::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant21(__nt), __end)); + (3, 29) } - pub(crate) fn __reduce75< + pub(crate) fn __reduce77< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (":" >) = ":", Test<"all"> => ActionFn(273); + // (":" >) = ":", Test<"all"> => ActionFn(293); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action273::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 29) + let __nt = super::__action293::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 30) } - pub(crate) fn __reduce76< + pub(crate) fn __reduce78< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (":" >)? = ":", Test<"all"> => ActionFn(1071); + // (":" >)? = ":", Test<"all"> => ActionFn(1102); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1071::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (2, 30) + let __nt = super::__action1102::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (2, 31) } - pub(crate) fn __reduce77< + pub(crate) fn __reduce79< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (":" >)? = => ActionFn(272); + // (":" >)? = => ActionFn(292); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action272::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (0, 30) + let __nt = super::__action292::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (0, 31) } - pub(crate) fn __reduce78< + pub(crate) fn __reduce80< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (":" ) = ":", TestOrStarExpr => ActionFn(270); + // (":" ) = ":", TestOrStarExpr => ActionFn(290); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action270::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 31) + let __nt = super::__action290::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 32) } - pub(crate) fn __reduce79< + pub(crate) fn __reduce81< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (":" )? = ":", TestOrStarExpr => ActionFn(1078); + // (":" )? = ":", TestOrStarExpr => ActionFn(1109); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1078::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (2, 32) + let __nt = super::__action1109::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (2, 33) } - pub(crate) fn __reduce80< + pub(crate) fn __reduce82< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (":" )? = => ActionFn(269); + // (":" )? = => ActionFn(289); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action269::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (0, 32) + let __nt = super::__action289::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (0, 33) } - pub(crate) fn __reduce81< + pub(crate) fn __reduce83< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("?") = "?" => ActionFn(349); + // ("?") = "?" => ActionFn(370); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action349::<>(mode, __sym0); + let __nt = super::__action370::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant0(__nt), __end)); - (1, 33) + (1, 34) } - pub(crate) fn __reduce82< + pub(crate) fn __reduce84< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("?")+ = "?" => ActionFn(1081); + // ("?")+ = "?" => ActionFn(1112); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1081::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant21(__nt), __end)); - (1, 34) + let __nt = super::__action1112::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant22(__nt), __end)); + (1, 35) } - pub(crate) fn __reduce83< + pub(crate) fn __reduce85< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("?")+ = ("?")+, "?" => ActionFn(1082); + // ("?")+ = ("?")+, "?" => ActionFn(1113); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant21(__symbols); + let __sym0 = __pop_Variant22(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1082::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant21(__nt), __end)); - (2, 34) + let __nt = super::__action1113::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant22(__nt), __end)); + (2, 35) } - pub(crate) fn __reduce84< + pub(crate) fn __reduce86< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("\n") = "\n" => ActionFn(391); + // ("\n") = "\n" => ActionFn(412); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action391::<>(mode, __sym0); + let __nt = super::__action412::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant0(__nt), __end)); - (1, 35) + (1, 36) } - pub(crate) fn __reduce85< + pub(crate) fn __reduce87< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("\n")* = => ActionFn(389); + // ("\n")* = => ActionFn(410); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action389::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant21(__nt), __end)); - (0, 36) + let __nt = super::__action410::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant22(__nt), __end)); + (0, 37) } - pub(crate) fn __reduce86< + pub(crate) fn __reduce88< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("\n")* = ("\n")+ => ActionFn(390); - let __sym0 = __pop_Variant21(__symbols); + // ("\n")* = ("\n")+ => ActionFn(411); + let __sym0 = __pop_Variant22(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action390::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant21(__nt), __end)); - (1, 36) + let __nt = super::__action411::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant22(__nt), __end)); + (1, 37) } - pub(crate) fn __reduce87< + pub(crate) fn __reduce89< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("\n")+ = "\n" => ActionFn(1083); + // ("\n")+ = "\n" => ActionFn(1114); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1083::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant21(__nt), __end)); - (1, 37) + let __nt = super::__action1114::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant22(__nt), __end)); + (1, 38) } - pub(crate) fn __reduce88< + pub(crate) fn __reduce90< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("\n")+ = ("\n")+, "\n" => ActionFn(1084); + // ("\n")+ = ("\n")+, "\n" => ActionFn(1115); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant21(__symbols); + let __sym0 = __pop_Variant22(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1084::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant21(__nt), __end)); - (2, 37) + let __nt = super::__action1115::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant22(__nt), __end)); + (2, 38) } - pub(crate) fn __reduce89< + pub(crate) fn __reduce91< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("as" ) = "as", Identifier => ActionFn(402); + // ("as" ) = "as", Identifier => ActionFn(423); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant22(__symbols); + let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action402::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant22(__nt), __end)); - (2, 38) + let __nt = super::__action423::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant23(__nt), __end)); + (2, 39) } - pub(crate) fn __reduce90< + pub(crate) fn __reduce92< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("as" )? = "as", Identifier => ActionFn(1087); + // ("as" )? = "as", Identifier => ActionFn(1118); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant22(__symbols); + let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1087::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant23(__nt), __end)); - (2, 39) + let __nt = super::__action1118::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant24(__nt), __end)); + (2, 40) } - pub(crate) fn __reduce91< + pub(crate) fn __reduce93< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("as" )? = => ActionFn(401); + // ("as" )? = => ActionFn(422); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action401::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant23(__nt), __end)); - (0, 39) + let __nt = super::__action422::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant24(__nt), __end)); + (0, 40) } - pub(crate) fn __reduce92< + pub(crate) fn __reduce94< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("else" ":" ) = "else", ":", Suite => ActionFn(316); + // ("else" ":" ) = "else", ":", Suite => ActionFn(336); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant24(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action316::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant24(__nt), __end)); - (3, 40) + let __nt = super::__action336::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant25(__nt), __end)); + (3, 41) } - pub(crate) fn __reduce93< + pub(crate) fn __reduce95< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("else" ":" )? = "else", ":", Suite => ActionFn(1092); + // ("else" ":" )? = "else", ":", Suite => ActionFn(1123); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant24(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1092::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant25(__nt), __end)); - (3, 41) + let __nt = super::__action1123::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant26(__nt), __end)); + (3, 42) } - pub(crate) fn __reduce94< + pub(crate) fn __reduce96< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("else" ":" )? = => ActionFn(315); + // ("else" ":" )? = => ActionFn(335); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action315::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant25(__nt), __end)); - (0, 41) + let __nt = super::__action335::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant26(__nt), __end)); + (0, 42) } - pub(crate) fn __reduce95< + pub(crate) fn __reduce97< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("finally" ":" ) = "finally", ":", Suite => ActionFn(309); + // ("finally" ":" ) = "finally", ":", Suite => ActionFn(329); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant24(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action309::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant24(__nt), __end)); - (3, 42) + let __nt = super::__action329::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant25(__nt), __end)); + (3, 43) } - pub(crate) fn __reduce96< + pub(crate) fn __reduce98< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("finally" ":" )? = "finally", ":", Suite => ActionFn(1103); + // ("finally" ":" )? = "finally", ":", Suite => ActionFn(1134); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant24(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1103::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant25(__nt), __end)); - (3, 43) + let __nt = super::__action1134::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant26(__nt), __end)); + (3, 44) } - pub(crate) fn __reduce97< + pub(crate) fn __reduce99< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("finally" ":" )? = => ActionFn(308); + // ("finally" ":" )? = => ActionFn(328); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action308::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant25(__nt), __end)); - (0, 43) + let __nt = super::__action328::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant26(__nt), __end)); + (0, 44) } - pub(crate) fn __reduce98< + pub(crate) fn __reduce100< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("from" >) = "from", Test<"all"> => ActionFn(374); + // ("from" >) = "from", Test<"all"> => ActionFn(395); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action374::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 44) + let __nt = super::__action395::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 45) } - pub(crate) fn __reduce99< + pub(crate) fn __reduce101< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("from" >)? = "from", Test<"all"> => ActionFn(1113); + // ("from" >)? = "from", Test<"all"> => ActionFn(1144); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1113::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (2, 45) + let __nt = super::__action1144::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (2, 46) } - pub(crate) fn __reduce100< + pub(crate) fn __reduce102< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ("from" >)? = => ActionFn(373); + // ("from" >)? = => ActionFn(394); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action373::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (0, 45) + let __nt = super::__action394::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (0, 46) } - pub(crate) fn __reduce101< + pub(crate) fn __reduce103< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (<@L> "elif" ":" ) = "elif", NamedExpressionTest, ":", Suite => ActionFn(695); + // (<@L> "elif" ":" ) = "elif", NamedExpressionTest, ":", Suite => ActionFn(720); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action695::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant26(__nt), __end)); - (4, 46) + let __nt = super::__action720::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant27(__nt), __end)); + (4, 47) } - pub(crate) fn __reduce102< + pub(crate) fn __reduce104< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (<@L> "elif" ":" )* = => ActionFn(320); + // (<@L> "elif" ":" )* = => ActionFn(340); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action320::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant27(__nt), __end)); - (0, 47) + let __nt = super::__action340::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant28(__nt), __end)); + (0, 48) } - pub(crate) fn __reduce103< + pub(crate) fn __reduce105< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (<@L> "elif" ":" )* = (<@L> "elif" ":" )+ => ActionFn(321); - let __sym0 = __pop_Variant27(__symbols); + // (<@L> "elif" ":" )* = (<@L> "elif" ":" )+ => ActionFn(341); + let __sym0 = __pop_Variant28(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action321::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant27(__nt), __end)); - (1, 47) + let __nt = super::__action341::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant28(__nt), __end)); + (1, 48) } - pub(crate) fn __reduce104< + pub(crate) fn __reduce106< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (<@L> "elif" ":" )+ = "elif", NamedExpressionTest, ":", Suite => ActionFn(1116); + // (<@L> "elif" ":" )+ = "elif", NamedExpressionTest, ":", Suite => ActionFn(1147); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1116::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant27(__nt), __end)); - (4, 48) + let __nt = super::__action1147::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant28(__nt), __end)); + (4, 49) } - pub(crate) fn __reduce105< + pub(crate) fn __reduce107< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (<@L> "elif" ":" )+ = (<@L> "elif" ":" )+, "elif", NamedExpressionTest, ":", Suite => ActionFn(1117); + // (<@L> "elif" ":" )+ = (<@L> "elif" ":" )+, "elif", NamedExpressionTest, ":", Suite => ActionFn(1148); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant24(__symbols); + let __sym4 = __pop_Variant25(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant27(__symbols); + let __sym0 = __pop_Variant28(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1117::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant27(__nt), __end)); - (5, 48) + let __nt = super::__action1148::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant28(__nt), __end)); + (5, 49) } - pub(crate) fn __reduce106< + pub(crate) fn __reduce108< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (<@L> "else" ":" ) = "else", ":", Suite => ActionFn(696); + // (<@L> "else" ":" ) = "else", ":", Suite => ActionFn(721); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant24(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action696::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant28(__nt), __end)); - (3, 49) + let __nt = super::__action721::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant29(__nt), __end)); + (3, 50) } - pub(crate) fn __reduce107< + pub(crate) fn __reduce109< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (<@L> "else" ":" )? = "else", ":", Suite => ActionFn(1120); + // (<@L> "else" ":" )? = "else", ":", Suite => ActionFn(1151); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant24(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1120::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant29(__nt), __end)); - (3, 50) + let __nt = super::__action1151::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant30(__nt), __end)); + (3, 51) } - pub(crate) fn __reduce108< + pub(crate) fn __reduce110< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (<@L> "else" ":" )? = => ActionFn(318); + // (<@L> "else" ":" )? = => ActionFn(338); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action318::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant29(__nt), __end)); - (0, 50) + let __nt = super::__action338::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant30(__nt), __end)); + (0, 51) } - pub(crate) fn __reduce109< + pub(crate) fn __reduce111< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (> "or") = AndTest<"all">, "or" => ActionFn(436); + // (> "or") = AndTest<"all">, "or" => ActionFn(459); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action436::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 51) + let __nt = super::__action459::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 52) } - pub(crate) fn __reduce110< + pub(crate) fn __reduce112< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (> "or")+ = AndTest<"all">, "or" => ActionFn(1125); + // (> "or")+ = AndTest<"all">, "or" => ActionFn(1156); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1125::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (2, 52) + let __nt = super::__action1156::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (2, 53) } - pub(crate) fn __reduce111< + pub(crate) fn __reduce113< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (> "or")+ = (> "or")+, AndTest<"all">, "or" => ActionFn(1126); + // (> "or")+ = (> "or")+, AndTest<"all">, "or" => ActionFn(1157); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); - let __sym0 = __pop_Variant16(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1126::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (3, 52) + let __nt = super::__action1157::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (3, 53) } - pub(crate) fn __reduce112< + pub(crate) fn __reduce114< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",") = FunctionArgument, "," => ActionFn(445); + // ( ",") = FunctionArgument, "," => ActionFn(468); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant30(__symbols); + let __sym0 = __pop_Variant31(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action445::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant30(__nt), __end)); - (2, 53) + let __nt = super::__action468::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant31(__nt), __end)); + (2, 54) } - pub(crate) fn __reduce113< + pub(crate) fn __reduce115< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")* = => ActionFn(443); + // ( ",")* = => ActionFn(466); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action443::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant31(__nt), __end)); - (0, 54) + let __nt = super::__action466::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant32(__nt), __end)); + (0, 55) } - pub(crate) fn __reduce114< + pub(crate) fn __reduce116< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")* = ( ",")+ => ActionFn(444); - let __sym0 = __pop_Variant31(__symbols); + // ( ",")* = ( ",")+ => ActionFn(467); + let __sym0 = __pop_Variant32(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action444::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant31(__nt), __end)); - (1, 54) + let __nt = super::__action467::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant32(__nt), __end)); + (1, 55) } - pub(crate) fn __reduce115< + pub(crate) fn __reduce117< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")+ = FunctionArgument, "," => ActionFn(1127); + // ( ",")+ = FunctionArgument, "," => ActionFn(1158); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant30(__symbols); + let __sym0 = __pop_Variant31(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1127::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant31(__nt), __end)); - (2, 55) + let __nt = super::__action1158::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant32(__nt), __end)); + (2, 56) } - pub(crate) fn __reduce116< + pub(crate) fn __reduce118< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")+ = ( ",")+, FunctionArgument, "," => ActionFn(1128); + // ( ",")+ = ( ",")+, FunctionArgument, "," => ActionFn(1159); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant30(__symbols); - let __sym0 = __pop_Variant31(__symbols); + let __sym1 = __pop_Variant31(__symbols); + let __sym0 = __pop_Variant32(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1128::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant31(__nt), __end)); - (3, 55) + let __nt = super::__action1159::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant32(__nt), __end)); + (3, 56) } - pub(crate) fn __reduce117< + pub(crate) fn __reduce119< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (> "and") = NotTest<"all">, "and" => ActionFn(450); + // (> "and") = NotTest<"all">, "and" => ActionFn(473); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action450::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 56) + let __nt = super::__action473::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 57) } - pub(crate) fn __reduce118< + pub(crate) fn __reduce120< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (> "and")+ = NotTest<"all">, "and" => ActionFn(1131); + // (> "and")+ = NotTest<"all">, "and" => ActionFn(1162); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1131::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (2, 57) + let __nt = super::__action1162::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (2, 58) } - pub(crate) fn __reduce119< + pub(crate) fn __reduce121< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (> "and")+ = (> "and")+, NotTest<"all">, "and" => ActionFn(1132); + // (> "and")+ = (> "and")+, NotTest<"all">, "and" => ActionFn(1163); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); - let __sym0 = __pop_Variant16(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1132::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (3, 57) + let __nt = super::__action1163::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (3, 58) } - pub(crate) fn __reduce120< + pub(crate) fn __reduce122< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (>> ",") = OneOrMore>, "," => ActionFn(548); + // (>> ",") = OneOrMore>, "," => ActionFn(571); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant32(__symbols); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action548::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (2, 58) + let __nt = super::__action571::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (2, 59) } - pub(crate) fn __reduce121< + pub(crate) fn __reduce123< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (>> ",")? = OneOrMore>, "," => ActionFn(1133); + // (>> ",")? = OneOrMore>, "," => ActionFn(1164); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant32(__symbols); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1133::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant33(__nt), __end)); - (2, 59) + let __nt = super::__action1164::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant34(__nt), __end)); + (2, 60) } - pub(crate) fn __reduce122< + pub(crate) fn __reduce124< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (>> ",")? = => ActionFn(547); + // (>> ",")? = => ActionFn(570); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action547::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant33(__nt), __end)); - (0, 59) + let __nt = super::__action570::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant34(__nt), __end)); + (0, 60) } - pub(crate) fn __reduce123< + pub(crate) fn __reduce125< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",") = Pattern, "," => ActionFn(335); + // ( ",") = Pattern, "," => ActionFn(356); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant34(__symbols); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action335::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (2, 60) + let __nt = super::__action356::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (2, 61) } - pub(crate) fn __reduce124< + pub(crate) fn __reduce126< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")* = => ActionFn(407); + // ( ",")* = => ActionFn(428); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action407::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant35(__nt), __end)); - (0, 61) + let __nt = super::__action428::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant36(__nt), __end)); + (0, 62) } - pub(crate) fn __reduce125< + pub(crate) fn __reduce127< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")* = ( ",")+ => ActionFn(408); - let __sym0 = __pop_Variant35(__symbols); + // ( ",")* = ( ",")+ => ActionFn(429); + let __sym0 = __pop_Variant36(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action408::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant35(__nt), __end)); - (1, 61) + let __nt = super::__action429::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant36(__nt), __end)); + (1, 62) } - pub(crate) fn __reduce126< + pub(crate) fn __reduce128< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")+ = Pattern, "," => ActionFn(1150); + // ( ",")+ = Pattern, "," => ActionFn(1181); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant34(__symbols); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1150::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant35(__nt), __end)); - (2, 62) + let __nt = super::__action1181::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant36(__nt), __end)); + (2, 63) } - pub(crate) fn __reduce127< + pub(crate) fn __reduce129< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")+ = ( ",")+, Pattern, "," => ActionFn(1151); + // ( ",")+ = ( ",")+, Pattern, "," => ActionFn(1182); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant34(__symbols); - let __sym0 = __pop_Variant35(__symbols); + let __sym1 = __pop_Variant35(__symbols); + let __sym0 = __pop_Variant36(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1151::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant35(__nt), __end)); - (3, 62) + let __nt = super::__action1182::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant36(__nt), __end)); + (3, 63) } - pub(crate) fn __reduce128< + pub(crate) fn __reduce130< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ";") = SmallStatement, ";" => ActionFn(388); + // ( ";") = SmallStatement, ";" => ActionFn(409); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action388::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (2, 63) + let __nt = super::__action409::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (2, 64) } - pub(crate) fn __reduce129< + pub(crate) fn __reduce131< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ";")* = => ActionFn(386); + // ( ";")* = => ActionFn(407); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action386::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (0, 64) + let __nt = super::__action407::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant38(__nt), __end)); + (0, 65) } - pub(crate) fn __reduce130< + pub(crate) fn __reduce132< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ";")* = ( ";")+ => ActionFn(387); - let __sym0 = __pop_Variant37(__symbols); + // ( ";")* = ( ";")+ => ActionFn(408); + let __sym0 = __pop_Variant38(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action387::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (1, 64) + let __nt = super::__action408::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant38(__nt), __end)); + (1, 65) } - pub(crate) fn __reduce131< + pub(crate) fn __reduce133< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ";")+ = SmallStatement, ";" => ActionFn(1154); + // ( ";")+ = SmallStatement, ";" => ActionFn(1185); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1154::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (2, 65) + let __nt = super::__action1185::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant38(__nt), __end)); + (2, 66) } - pub(crate) fn __reduce132< + pub(crate) fn __reduce134< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ";")+ = ( ";")+, SmallStatement, ";" => ActionFn(1155); + // ( ";")+ = ( ";")+, SmallStatement, ";" => ActionFn(1186); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant36(__symbols); - let __sym0 = __pop_Variant37(__symbols); - let __start = __sym0.0; - let __end = __sym2.2; - let __nt = super::__action1155::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant37(__nt), __end)); - (3, 65) - } - pub(crate) fn __reduce133< - >( - mode: Mode, - __lookahead_start: Option<&TextSize>, - __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, - _: core::marker::PhantomData<()>, - ) -> (usize, usize) - { - // (> "as" ) = Test<"all">, "as", Identifier => ActionFn(304); - assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant22(__symbols); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant37(__symbols); + let __sym0 = __pop_Variant38(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action304::<>(mode, __sym0, __sym1, __sym2); + let __nt = super::__action1186::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant38(__nt), __end)); (3, 66) } - pub(crate) fn __reduce134< + pub(crate) fn __reduce135< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",") = OneOrMore>, "," => ActionFn(1174); - assert!(__symbols.len() >= 2); + // (> "as" ) = Test<"all">, "as", Identifier => ActionFn(324); + assert!(__symbols.len() >= 3); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant32(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; - let __end = __sym1.2; - let __nt = super::__action1174::<>(mode, __sym0, __sym1); + let __end = __sym2.2; + let __nt = super::__action324::<>(source_code, mode, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant39(__nt), __end)); - (2, 67) + (3, 67) } - pub(crate) fn __reduce135< + pub(crate) fn __reduce136< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ( ",")? = OneOrMore>, "," => ActionFn(1177); + // ( ",") = OneOrMore>, "," => ActionFn(1205); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant32(__symbols); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1177::<>(mode, __sym0, __sym1); + let __nt = super::__action1205::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant40(__nt), __end)); (2, 68) } - pub(crate) fn __reduce136< - >( - mode: Mode, - __lookahead_start: Option<&TextSize>, - __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, - _: core::marker::PhantomData<()>, - ) -> (usize, usize) - { - // ( ",")? = => ActionFn(300); - let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); - let __end = __start.clone(); - let __nt = super::__action300::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant40(__nt), __end)); - (0, 68) - } pub(crate) fn __reduce137< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (@L string @R) = string => ActionFn(1186); - let __sym0 = __pop_Variant6(__symbols); + // ( ",")? = OneOrMore>, "," => ActionFn(1208); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; - let __end = __sym0.2; - let __nt = super::__action1186::<>(mode, __sym0); + let __end = __sym1.2; + let __nt = super::__action1208::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant41(__nt), __end)); - (1, 69) + (2, 69) } pub(crate) fn __reduce138< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (@L string @R)+ = string => ActionFn(1478); - let __sym0 = __pop_Variant6(__symbols); - let __start = __sym0.0; - let __end = __sym0.2; - let __nt = super::__action1478::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant42(__nt), __end)); - (1, 70) + // ( ",")? = => ActionFn(320); + let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); + let __end = __start.clone(); + let __nt = super::__action320::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant41(__nt), __end)); + (0, 69) } pub(crate) fn __reduce139< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (@L string @R)+ = (@L string @R)+, string => ActionFn(1479); + // (CompOp Expression<"all">) = CompOp, Expression<"all"> => ActionFn(516); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant6(__symbols); - let __sym0 = __pop_Variant42(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant56(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1479::<>(mode, __sym0, __sym1); + let __nt = super::__action516::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant42(__nt), __end)); (2, 70) } pub(crate) fn __reduce140< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (CompOp Expression<"all">) = CompOp, Expression<"all"> => ActionFn(493); + // (CompOp Expression<"all">)+ = CompOp, Expression<"all"> => ActionFn(1217); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); - let __sym0 = __pop_Variant57(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant56(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action493::<>(mode, __sym0, __sym1); + let __nt = super::__action1217::<>(source_code, mode, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant43(__nt), __end)); (2, 71) } pub(crate) fn __reduce141< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (CompOp Expression<"all">)+ = CompOp, Expression<"all"> => ActionFn(1480); - assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); - let __sym0 = __pop_Variant57(__symbols); + // (CompOp Expression<"all">)+ = (CompOp Expression<"all">)+, CompOp, Expression<"all"> => ActionFn(1218); + assert!(__symbols.len() >= 3); + let __sym2 = __pop_Variant15(__symbols); + let __sym1 = __pop_Variant56(__symbols); + let __sym0 = __pop_Variant43(__symbols); let __start = __sym0.0; - let __end = __sym1.2; - let __nt = super::__action1480::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant44(__nt), __end)); - (2, 72) + let __end = __sym2.2; + let __nt = super::__action1218::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant43(__nt), __end)); + (3, 71) } pub(crate) fn __reduce142< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (CompOp Expression<"all">)+ = (CompOp Expression<"all">)+, CompOp, Expression<"all"> => ActionFn(1481); - assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); - let __sym1 = __pop_Variant57(__symbols); + // (Guard) = Guard => ActionFn(363); let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; - let __end = __sym2.2; - let __nt = super::__action1481::<>(mode, __sym0, __sym1, __sym2); + let __end = __sym0.2; + let __nt = super::__action363::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant44(__nt), __end)); - (3, 72) + (1, 72) } pub(crate) fn __reduce143< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (Guard) = Guard => ActionFn(342); - let __sym0 = __pop_Variant45(__symbols); + // (Guard)? = Guard => ActionFn(1219); + let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action342::<>(mode, __sym0); + let __nt = super::__action1219::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant45(__nt), __end)); (1, 73) } pub(crate) fn __reduce144< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (Guard)? = Guard => ActionFn(1482); - let __sym0 = __pop_Variant45(__symbols); - let __start = __sym0.0; - let __end = __sym0.2; - let __nt = super::__action1482::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant46(__nt), __end)); - (1, 74) + // (Guard)? = => ActionFn(362); + let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); + let __end = __start.clone(); + let __nt = super::__action362::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant45(__nt), __end)); + (0, 73) } pub(crate) fn __reduce145< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (Guard)? = => ActionFn(341); - let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); - let __end = __start.clone(); - let __nt = super::__action341::<>(mode, &__start, &__end); + // (ParameterList) = ParameterList => ActionFn(296); + let __sym0 = __pop_Variant46(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = super::__action296::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant46(__nt), __end)); - (0, 74) + (1, 74) } pub(crate) fn __reduce146< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (ParameterList) = ParameterList => ActionFn(276); - let __sym0 = __pop_Variant47(__symbols); + // (ParameterList)? = ParameterList => ActionFn(1222); + let __sym0 = __pop_Variant46(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action276::<>(mode, __sym0); + let __nt = super::__action1222::<>(source_code, mode, __sym0); __symbols.push((__start, __Symbol::Variant47(__nt), __end)); (1, 75) } pub(crate) fn __reduce147< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (ParameterList)? = ParameterList => ActionFn(1485); - let __sym0 = __pop_Variant47(__symbols); - let __start = __sym0.0; - let __end = __sym0.2; - let __nt = super::__action1485::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant48(__nt), __end)); - (1, 76) + // (ParameterList)? = => ActionFn(295); + let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); + let __end = __start.clone(); + let __nt = super::__action295::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant47(__nt), __end)); + (0, 75) } pub(crate) fn __reduce148< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // (ParameterList)? = => ActionFn(275); + // @L = => ActionFn(414); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action275::<>(mode, &__start, &__end); + let __nt = super::__action414::<>(source_code, mode, &__start, &__end); __symbols.push((__start, __Symbol::Variant48(__nt), __end)); (0, 76) } pub(crate) fn __reduce149< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // @L = => ActionFn(393); + // @R = => ActionFn(413); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action393::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + let __nt = super::__action413::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant48(__nt), __end)); (0, 77) } pub(crate) fn __reduce150< >( - mode: Mode, - __lookahead_start: Option<&TextSize>, - __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, - _: core::marker::PhantomData<()>, - ) -> (usize, usize) - { - // @R = => ActionFn(392); - let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); - let __end = __start.clone(); - let __nt = super::__action392::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant49(__nt), __end)); - (0, 78) - } - pub(crate) fn __reduce151< - >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -20565,12 +21399,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action196::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 79) + let __nt = super::__action196::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 78) } - pub(crate) fn __reduce152< + pub(crate) fn __reduce151< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -20581,308 +21416,326 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action197::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 79) + let __nt = super::__action197::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 78) } - pub(crate) fn __reduce153< + pub(crate) fn __reduce152< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AddOpExpr = ConstantExpr, AddOp, ConstantAtom => ActionFn(1187); + // AddOpExpr = ConstantExpr, AddOp, ConstantAtom => ActionFn(1225); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); - let __sym1 = __pop_Variant50(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); + let __sym1 = __pop_Variant49(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1187::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 80) + let __nt = super::__action1225::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 79) } - pub(crate) fn __reduce154< + pub(crate) fn __reduce153< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AndExpression<"all"> = AndExpression<"all">, "&", ShiftExpression<"all"> => ActionFn(1188); + // AndExpression<"all"> = AndExpression<"all">, "&", ShiftExpression<"all"> => ActionFn(1226); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1188::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 81) + let __nt = super::__action1226::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 80) } - pub(crate) fn __reduce155< + pub(crate) fn __reduce154< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AndExpression<"all"> = ShiftExpression<"all"> => ActionFn(480); - let __sym0 = __pop_Variant14(__symbols); + // AndExpression<"all"> = ShiftExpression<"all"> => ActionFn(503); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action480::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 81) + let __nt = super::__action503::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 80) } - pub(crate) fn __reduce156< + pub(crate) fn __reduce155< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AndExpression<"no-withitems"> = AndExpression<"all">, "&", ShiftExpression<"all"> => ActionFn(1189); + // AndExpression<"no-withitems"> = AndExpression<"all">, "&", ShiftExpression<"all"> => ActionFn(1227); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1189::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 82) + let __nt = super::__action1227::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 81) } - pub(crate) fn __reduce157< + pub(crate) fn __reduce156< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AndExpression<"no-withitems"> = ShiftExpression<"no-withitems"> => ActionFn(511); - let __sym0 = __pop_Variant14(__symbols); + // AndExpression<"no-withitems"> = ShiftExpression<"no-withitems"> => ActionFn(534); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action511::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 82) + let __nt = super::__action534::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 81) } - pub(crate) fn __reduce158< + pub(crate) fn __reduce157< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AndTest<"all"> = (> "and")+, NotTest<"all"> => ActionFn(1190); + // AndTest<"all"> = (> "and")+, NotTest<"all"> => ActionFn(1228); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); - let __sym0 = __pop_Variant16(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1190::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 83) + let __nt = super::__action1228::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 82) } - pub(crate) fn __reduce159< + pub(crate) fn __reduce158< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AndTest<"all"> = NotTest<"all"> => ActionFn(438); - let __sym0 = __pop_Variant14(__symbols); + // AndTest<"all"> = NotTest<"all"> => ActionFn(461); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action438::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 83) + let __nt = super::__action461::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 82) } - pub(crate) fn __reduce160< + pub(crate) fn __reduce159< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AndTest<"no-withitems"> = (> "and")+, NotTest<"all"> => ActionFn(1191); + // AndTest<"no-withitems"> = (> "and")+, NotTest<"all"> => ActionFn(1229); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); - let __sym0 = __pop_Variant16(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1191::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 84) + let __nt = super::__action1229::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 83) } - pub(crate) fn __reduce161< + pub(crate) fn __reduce160< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AndTest<"no-withitems"> = NotTest<"no-withitems"> => ActionFn(484); - let __sym0 = __pop_Variant14(__symbols); + // AndTest<"no-withitems"> = NotTest<"no-withitems"> => ActionFn(507); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action484::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 84) + let __nt = super::__action507::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 83) } - pub(crate) fn __reduce166< + pub(crate) fn __reduce165< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Arguments? = Arguments => ActionFn(266); - let __sym0 = __pop_Variant51(__symbols); + // Arguments? = Arguments => ActionFn(286); + let __sym0 = __pop_Variant50(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action266::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant52(__nt), __end)); - (1, 86) + let __nt = super::__action286::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant51(__nt), __end)); + (1, 85) } - pub(crate) fn __reduce167< + pub(crate) fn __reduce166< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Arguments? = => ActionFn(267); + // Arguments? = => ActionFn(287); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action267::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant52(__nt), __end)); - (0, 86) + let __nt = super::__action287::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant51(__nt), __end)); + (0, 85) } - pub(crate) fn __reduce168< + pub(crate) fn __reduce167< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ArithmeticExpression<"all"> = ArithmeticExpression<"all">, AddOp, Term<"all"> => ActionFn(1193); + // ArithmeticExpression<"all"> = ArithmeticExpression<"all">, AddOp, Term<"all"> => ActionFn(1231); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); - let __sym1 = __pop_Variant50(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); + let __sym1 = __pop_Variant49(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1193::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 87) + let __nt = super::__action1231::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 86) } - pub(crate) fn __reduce169< + pub(crate) fn __reduce168< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ArithmeticExpression<"all"> = Term<"all"> => ActionFn(497); - let __sym0 = __pop_Variant14(__symbols); + // ArithmeticExpression<"all"> = Term<"all"> => ActionFn(520); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action497::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 87) + let __nt = super::__action520::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 86) } - pub(crate) fn __reduce170< + pub(crate) fn __reduce169< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ArithmeticExpression<"no-withitems"> = ArithmeticExpression<"all">, AddOp, Term<"all"> => ActionFn(1194); + // ArithmeticExpression<"no-withitems"> = ArithmeticExpression<"all">, AddOp, Term<"all"> => ActionFn(1232); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); - let __sym1 = __pop_Variant50(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); + let __sym1 = __pop_Variant49(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1194::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 88) + let __nt = super::__action1232::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 87) } - pub(crate) fn __reduce171< + pub(crate) fn __reduce170< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ArithmeticExpression<"no-withitems"> = Term<"no-withitems"> => ActionFn(521); - let __sym0 = __pop_Variant14(__symbols); + // ArithmeticExpression<"no-withitems"> = Term<"no-withitems"> => ActionFn(544); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action521::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 88) + let __nt = super::__action544::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 87) } - pub(crate) fn __reduce173< + pub(crate) fn __reduce172< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AssertStatement = "assert", Test<"all">, ",", Test<"all"> => ActionFn(1196); + // AssertStatement = "assert", Test<"all">, ",", Test<"all"> => ActionFn(1234); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant14(__symbols); + let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1196::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (4, 90) + let __nt = super::__action1234::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (4, 89) } - pub(crate) fn __reduce174< + pub(crate) fn __reduce173< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AssertStatement = "assert", Test<"all"> => ActionFn(1197); + // AssertStatement = "assert", Test<"all"> => ActionFn(1235); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1197::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (2, 90) + let __nt = super::__action1235::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (2, 89) } - pub(crate) fn __reduce175< + pub(crate) fn __reduce174< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -20891,16 +21744,17 @@ mod __parse__Top { { // AssignSuffix = "=", TestListOrYieldExpr => ActionFn(29); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action29::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 91) + let __nt = super::__action29::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 90) } - pub(crate) fn __reduce176< + pub(crate) fn __reduce175< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -20909,977 +21763,1032 @@ mod __parse__Top { { // AssignSuffix = "=", IpyEscapeCommandExpr => ActionFn(30); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action30::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 91) + let __nt = super::__action30::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 90) } - pub(crate) fn __reduce177< + pub(crate) fn __reduce176< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AssignSuffix* = => ActionFn(382); + // AssignSuffix* = => ActionFn(403); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action382::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (0, 92) + let __nt = super::__action403::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (0, 91) } - pub(crate) fn __reduce178< + pub(crate) fn __reduce177< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AssignSuffix* = AssignSuffix+ => ActionFn(383); - let __sym0 = __pop_Variant16(__symbols); + // AssignSuffix* = AssignSuffix+ => ActionFn(404); + let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action383::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (1, 92) + let __nt = super::__action404::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (1, 91) } - pub(crate) fn __reduce179< + pub(crate) fn __reduce178< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AssignSuffix+ = AssignSuffix => ActionFn(398); - let __sym0 = __pop_Variant14(__symbols); + // AssignSuffix+ = AssignSuffix => ActionFn(419); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action398::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (1, 93) + let __nt = super::__action419::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (1, 92) } - pub(crate) fn __reduce180< + pub(crate) fn __reduce179< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AssignSuffix+ = AssignSuffix+, AssignSuffix => ActionFn(399); + // AssignSuffix+ = AssignSuffix+, AssignSuffix => ActionFn(420); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); - let __sym0 = __pop_Variant16(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action399::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (2, 93) + let __nt = super::__action420::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (2, 92) } - pub(crate) fn __reduce181< + pub(crate) fn __reduce180< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AssignSuffix? = AssignSuffix => ActionFn(377); - let __sym0 = __pop_Variant14(__symbols); + // AssignSuffix? = AssignSuffix => ActionFn(398); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action377::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 94) + let __nt = super::__action398::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (1, 93) } - pub(crate) fn __reduce182< + pub(crate) fn __reduce181< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AssignSuffix? = => ActionFn(378); + // AssignSuffix? = => ActionFn(399); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action378::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (0, 94) + let __nt = super::__action399::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (0, 93) } - pub(crate) fn __reduce184< + pub(crate) fn __reduce183< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = Constant => ActionFn(1198); - let __sym0 = __pop_Variant58(__symbols); + // Atom<"all"> = Constant => ActionFn(1237); + let __sym0 = __pop_Variant57(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1198::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 95) + let __nt = super::__action1237::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 94) } - pub(crate) fn __reduce185< + pub(crate) fn __reduce184< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = Identifier => ActionFn(1199); - let __sym0 = __pop_Variant22(__symbols); + // Atom<"all"> = Identifier => ActionFn(1238); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1199::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 95) + let __nt = super::__action1238::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 94) } - pub(crate) fn __reduce186< + pub(crate) fn __reduce185< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "[", ListLiteralValues, "]" => ActionFn(1544); + // Atom<"all"> = "[", ListLiteralValues, "]" => ActionFn(1599); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1544::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 95) + let __nt = super::__action1599::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 94) } - pub(crate) fn __reduce187< + pub(crate) fn __reduce186< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "[", "]" => ActionFn(1545); + // Atom<"all"> = "[", "]" => ActionFn(1600); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1545::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 95) + let __nt = super::__action1600::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 94) } - pub(crate) fn __reduce188< + pub(crate) fn __reduce187< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "[", TestOrStarNamedExpr, CompFor, "]" => ActionFn(1201); + // Atom<"all"> = "[", TestOrStarNamedExpr, CompFor, "]" => ActionFn(1240); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant55(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant54(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1201::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 95) + let __nt = super::__action1240::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 94) } - pub(crate) fn __reduce189< + pub(crate) fn __reduce188< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "(", OneOrMore>, ",", ")" => ActionFn(1202); + // Atom<"all"> = "(", OneOrMore>, ",", ")" => ActionFn(1241); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1202::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 95) + let __nt = super::__action1241::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 94) } - pub(crate) fn __reduce190< + pub(crate) fn __reduce189< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "(", OneOrMore>, ")" => ActionFn(1203); + // Atom<"all"> = "(", OneOrMore>, ")" => ActionFn(1242); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1203::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 95) + let __nt = super::__action1242::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 94) } - pub(crate) fn __reduce199< + pub(crate) fn __reduce198< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "(", ")" => ActionFn(1212); + // Atom<"all"> = "(", ")" => ActionFn(1251); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1212::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 95) + let __nt = super::__action1251::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 94) } - pub(crate) fn __reduce200< + pub(crate) fn __reduce199< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "(", YieldExpr, ")" => ActionFn(1213); + // Atom<"all"> = "(", YieldExpr, ")" => ActionFn(1252); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1213::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 95) + let __nt = super::__action1252::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 94) } - pub(crate) fn __reduce201< + pub(crate) fn __reduce200< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "(", NamedExpressionTest, CompFor, ")" => ActionFn(1214); + // Atom<"all"> = "(", NamedExpressionTest, CompFor, ")" => ActionFn(1253); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant55(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant54(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1214::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 95) + let __nt = super::__action1253::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 94) } - pub(crate) fn __reduce203< + pub(crate) fn __reduce202< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "{", DictLiteralValues, "}" => ActionFn(1528); + // Atom<"all"> = "{", DictLiteralValues, "}" => ActionFn(1567); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant63(__symbols); + let __sym1 = __pop_Variant62(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1528::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 95) + let __nt = super::__action1567::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 94) } - pub(crate) fn __reduce204< + pub(crate) fn __reduce203< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "{", "}" => ActionFn(1529); + // Atom<"all"> = "{", "}" => ActionFn(1568); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1529::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 95) + let __nt = super::__action1568::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 94) } - pub(crate) fn __reduce205< + pub(crate) fn __reduce204< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "{", DictEntry, CompFor, "}" => ActionFn(1217); + // Atom<"all"> = "{", DictEntry, CompFor, "}" => ActionFn(1256); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant55(__symbols); - let __sym1 = __pop_Variant62(__symbols); + let __sym2 = __pop_Variant54(__symbols); + let __sym1 = __pop_Variant61(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1217::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 95) + let __nt = super::__action1256::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 94) } - pub(crate) fn __reduce206< + pub(crate) fn __reduce205< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "{", SetLiteralValues, "}" => ActionFn(1218); + // Atom<"all"> = "{", SetLiteralValues, "}" => ActionFn(1257); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1218::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 95) + let __nt = super::__action1257::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 94) } - pub(crate) fn __reduce207< + pub(crate) fn __reduce206< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "{", NamedExpressionTest, CompFor, "}" => ActionFn(1219); + // Atom<"all"> = "{", NamedExpressionTest, CompFor, "}" => ActionFn(1258); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant55(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant54(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1219::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 95) + let __nt = super::__action1258::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 94) } - pub(crate) fn __reduce208< + pub(crate) fn __reduce207< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "True" => ActionFn(1220); + // Atom<"all"> = "True" => ActionFn(1259); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1220::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 95) + let __nt = super::__action1259::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 94) } - pub(crate) fn __reduce209< + pub(crate) fn __reduce208< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "False" => ActionFn(1221); + // Atom<"all"> = "False" => ActionFn(1260); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1221::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 95) + let __nt = super::__action1260::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 94) } - pub(crate) fn __reduce210< + pub(crate) fn __reduce209< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "None" => ActionFn(1222); + // Atom<"all"> = "None" => ActionFn(1261); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1222::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 95) + let __nt = super::__action1261::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 94) } - pub(crate) fn __reduce211< + pub(crate) fn __reduce210< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"all"> = "..." => ActionFn(1223); + // Atom<"all"> = "..." => ActionFn(1262); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1223::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 95) + let __nt = super::__action1262::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 94) } - pub(crate) fn __reduce213< + pub(crate) fn __reduce212< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = Constant => ActionFn(1224); - let __sym0 = __pop_Variant58(__symbols); + // Atom<"no-withitems"> = Constant => ActionFn(1264); + let __sym0 = __pop_Variant57(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1224::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 96) + let __nt = super::__action1264::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 95) } - pub(crate) fn __reduce214< + pub(crate) fn __reduce213< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = Identifier => ActionFn(1225); - let __sym0 = __pop_Variant22(__symbols); + // Atom<"no-withitems"> = Identifier => ActionFn(1265); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1225::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 96) + let __nt = super::__action1265::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 95) } - pub(crate) fn __reduce215< + pub(crate) fn __reduce214< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "[", ListLiteralValues, "]" => ActionFn(1546); + // Atom<"no-withitems"> = "[", ListLiteralValues, "]" => ActionFn(1601); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1546::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 96) + let __nt = super::__action1601::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 95) } - pub(crate) fn __reduce216< + pub(crate) fn __reduce215< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "[", "]" => ActionFn(1547); + // Atom<"no-withitems"> = "[", "]" => ActionFn(1602); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1547::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 96) + let __nt = super::__action1602::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 95) } - pub(crate) fn __reduce217< + pub(crate) fn __reduce216< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "[", TestOrStarNamedExpr, CompFor, "]" => ActionFn(1227); + // Atom<"no-withitems"> = "[", TestOrStarNamedExpr, CompFor, "]" => ActionFn(1267); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant55(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant54(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1227::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 96) + let __nt = super::__action1267::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 95) } - pub(crate) fn __reduce226< + pub(crate) fn __reduce225< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "(", ")" => ActionFn(1236); + // Atom<"no-withitems"> = "(", ")" => ActionFn(1276); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1236::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 96) + let __nt = super::__action1276::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 95) } - pub(crate) fn __reduce227< + pub(crate) fn __reduce226< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "(", YieldExpr, ")" => ActionFn(1237); + // Atom<"no-withitems"> = "(", YieldExpr, ")" => ActionFn(1277); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1237::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 96) + let __nt = super::__action1277::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 95) } - pub(crate) fn __reduce228< + pub(crate) fn __reduce227< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "(", NamedExpressionTest, CompFor, ")" => ActionFn(1238); + // Atom<"no-withitems"> = "(", NamedExpressionTest, CompFor, ")" => ActionFn(1278); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant55(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant54(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1238::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 96) + let __nt = super::__action1278::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 95) } - pub(crate) fn __reduce230< + pub(crate) fn __reduce229< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "{", DictLiteralValues, "}" => ActionFn(1530); + // Atom<"no-withitems"> = "{", DictLiteralValues, "}" => ActionFn(1569); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant63(__symbols); + let __sym1 = __pop_Variant62(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1530::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 96) + let __nt = super::__action1569::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 95) } - pub(crate) fn __reduce231< + pub(crate) fn __reduce230< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "{", "}" => ActionFn(1531); + // Atom<"no-withitems"> = "{", "}" => ActionFn(1570); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1531::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 96) + let __nt = super::__action1570::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 95) } - pub(crate) fn __reduce232< + pub(crate) fn __reduce231< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "{", DictEntry, CompFor, "}" => ActionFn(1241); + // Atom<"no-withitems"> = "{", DictEntry, CompFor, "}" => ActionFn(1281); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant55(__symbols); - let __sym1 = __pop_Variant62(__symbols); + let __sym2 = __pop_Variant54(__symbols); + let __sym1 = __pop_Variant61(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1241::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 96) + let __nt = super::__action1281::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 95) } - pub(crate) fn __reduce233< + pub(crate) fn __reduce232< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "{", SetLiteralValues, "}" => ActionFn(1242); + // Atom<"no-withitems"> = "{", SetLiteralValues, "}" => ActionFn(1282); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1242::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 96) + let __nt = super::__action1282::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 95) } - pub(crate) fn __reduce234< + pub(crate) fn __reduce233< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "{", NamedExpressionTest, CompFor, "}" => ActionFn(1243); + // Atom<"no-withitems"> = "{", NamedExpressionTest, CompFor, "}" => ActionFn(1283); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant55(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant54(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1243::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 96) + let __nt = super::__action1283::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 95) } - pub(crate) fn __reduce235< + pub(crate) fn __reduce234< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "True" => ActionFn(1244); + // Atom<"no-withitems"> = "True" => ActionFn(1284); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1244::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 96) + let __nt = super::__action1284::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 95) } - pub(crate) fn __reduce236< + pub(crate) fn __reduce235< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "False" => ActionFn(1245); + // Atom<"no-withitems"> = "False" => ActionFn(1285); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1245::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 96) + let __nt = super::__action1285::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 95) } - pub(crate) fn __reduce237< + pub(crate) fn __reduce236< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "None" => ActionFn(1246); + // Atom<"no-withitems"> = "None" => ActionFn(1286); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1246::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 96) + let __nt = super::__action1286::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 95) } - pub(crate) fn __reduce238< + pub(crate) fn __reduce237< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Atom<"no-withitems"> = "..." => ActionFn(1247); + // Atom<"no-withitems"> = "..." => ActionFn(1287); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1247::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 96) + let __nt = super::__action1287::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 95) } - pub(crate) fn __reduce239< + pub(crate) fn __reduce238< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr2<"all"> = Atom<"all"> => ActionFn(514); - let __sym0 = __pop_Variant14(__symbols); + // AtomExpr2<"all"> = Atom<"all"> => ActionFn(537); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action514::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 97) + let __nt = super::__action537::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 96) } - pub(crate) fn __reduce240< + pub(crate) fn __reduce239< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr2<"all"> = AtomExpr2<"all">, Arguments => ActionFn(1248); + // AtomExpr2<"all"> = AtomExpr2<"all">, Arguments => ActionFn(1288); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant51(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant50(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1248::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 97) + let __nt = super::__action1288::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 96) } - pub(crate) fn __reduce241< + pub(crate) fn __reduce240< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr2<"all"> = AtomExpr2<"all">, "[", SubscriptList, "]" => ActionFn(1249); + // AtomExpr2<"all"> = AtomExpr2<"all">, "[", SubscriptList, "]" => ActionFn(1289); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1249::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 97) + let __nt = super::__action1289::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 96) } - pub(crate) fn __reduce242< + pub(crate) fn __reduce241< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr2<"all"> = AtomExpr2<"all">, ".", Identifier => ActionFn(1250); + // AtomExpr2<"all"> = AtomExpr2<"all">, ".", Identifier => ActionFn(1290); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1250::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 97) + let __nt = super::__action1290::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 96) } - pub(crate) fn __reduce243< + pub(crate) fn __reduce242< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr2<"no-withitems"> = Atom<"no-withitems"> => ActionFn(561); - let __sym0 = __pop_Variant14(__symbols); + // AtomExpr2<"no-withitems"> = Atom<"no-withitems"> => ActionFn(584); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action561::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 98) + let __nt = super::__action584::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 97) } - pub(crate) fn __reduce244< + pub(crate) fn __reduce243< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr2<"no-withitems"> = AtomExpr2<"all">, Arguments => ActionFn(1251); + // AtomExpr2<"no-withitems"> = AtomExpr2<"all">, Arguments => ActionFn(1291); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant51(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant50(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1251::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 98) + let __nt = super::__action1291::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 97) } - pub(crate) fn __reduce245< + pub(crate) fn __reduce244< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr2<"no-withitems"> = AtomExpr2<"all">, "[", SubscriptList, "]" => ActionFn(1252); + // AtomExpr2<"no-withitems"> = AtomExpr2<"all">, "[", SubscriptList, "]" => ActionFn(1292); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1252::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 98) + let __nt = super::__action1292::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 97) } - pub(crate) fn __reduce246< + pub(crate) fn __reduce245< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr2<"no-withitems"> = AtomExpr2<"all">, ".", Identifier => ActionFn(1253); + // AtomExpr2<"no-withitems"> = AtomExpr2<"all">, ".", Identifier => ActionFn(1293); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1253::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 98) + let __nt = super::__action1293::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 97) } - pub(crate) fn __reduce247< + pub(crate) fn __reduce246< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr<"all"> = "await", AtomExpr2<"all"> => ActionFn(1254); + // AtomExpr<"all"> = "await", AtomExpr2<"all"> => ActionFn(1294); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1254::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 99) + let __nt = super::__action1294::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 98) } - pub(crate) fn __reduce248< + pub(crate) fn __reduce247< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr<"all"> = AtomExpr2<"all"> => ActionFn(513); - let __sym0 = __pop_Variant14(__symbols); + // AtomExpr<"all"> = AtomExpr2<"all"> => ActionFn(536); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action513::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 99) + let __nt = super::__action536::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 98) } - pub(crate) fn __reduce249< + pub(crate) fn __reduce248< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr<"no-withitems"> = "await", AtomExpr2<"all"> => ActionFn(1255); + // AtomExpr<"no-withitems"> = "await", AtomExpr2<"all"> => ActionFn(1295); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1255::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 100) + let __nt = super::__action1295::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 99) } - pub(crate) fn __reduce250< + pub(crate) fn __reduce249< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // AtomExpr<"no-withitems"> = AtomExpr2<"no-withitems"> => ActionFn(560); - let __sym0 = __pop_Variant14(__symbols); + // AtomExpr<"no-withitems"> = AtomExpr2<"no-withitems"> => ActionFn(583); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action560::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 100) + let __nt = super::__action583::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 99) } - pub(crate) fn __reduce251< + pub(crate) fn __reduce250< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -21890,12 +22799,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action40::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 101) + let __nt = super::__action40::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 100) } - pub(crate) fn __reduce252< + pub(crate) fn __reduce251< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -21906,12 +22816,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action41::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 101) + let __nt = super::__action41::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 100) } - pub(crate) fn __reduce253< + pub(crate) fn __reduce252< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -21922,12 +22833,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action42::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 101) + let __nt = super::__action42::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 100) } - pub(crate) fn __reduce254< + pub(crate) fn __reduce253< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -21938,12 +22850,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action43::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 101) + let __nt = super::__action43::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 100) } - pub(crate) fn __reduce255< + pub(crate) fn __reduce254< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -21954,12 +22867,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action44::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 101) + let __nt = super::__action44::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 100) } - pub(crate) fn __reduce256< + pub(crate) fn __reduce255< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -21970,12 +22884,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action45::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 101) + let __nt = super::__action45::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 100) } - pub(crate) fn __reduce257< + pub(crate) fn __reduce256< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -21986,12 +22901,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action46::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 101) + let __nt = super::__action46::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 100) } - pub(crate) fn __reduce258< + pub(crate) fn __reduce257< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22002,12 +22918,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action47::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 101) + let __nt = super::__action47::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 100) } - pub(crate) fn __reduce259< + pub(crate) fn __reduce258< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22018,12 +22935,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action48::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 101) + let __nt = super::__action48::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 100) } - pub(crate) fn __reduce260< + pub(crate) fn __reduce259< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22034,12 +22952,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action49::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 101) + let __nt = super::__action49::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 100) } - pub(crate) fn __reduce261< + pub(crate) fn __reduce260< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22050,12 +22969,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action50::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 101) + let __nt = super::__action50::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 100) } - pub(crate) fn __reduce262< + pub(crate) fn __reduce261< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22066,12 +22986,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action51::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 101) + let __nt = super::__action51::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 100) } - pub(crate) fn __reduce263< + pub(crate) fn __reduce262< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22082,236 +23003,248 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action52::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 101) + let __nt = super::__action52::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 100) } - pub(crate) fn __reduce264< + pub(crate) fn __reduce263< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CapturePattern = Identifier => ActionFn(1256); - let __sym0 = __pop_Variant22(__symbols); + // CapturePattern = Identifier => ActionFn(1296); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1256::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 102) + let __nt = super::__action1296::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 101) } - pub(crate) fn __reduce265< + pub(crate) fn __reduce264< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassDef = "class", Identifier, TypeParams, Arguments, ":", Suite => ActionFn(1700); + // ClassDef = "class", Identifier, TypeParams, Arguments, ":", Suite => ActionFn(1755); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant24(__symbols); + let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant51(__symbols); - let __sym2 = __pop_Variant94(__symbols); - let __sym1 = __pop_Variant22(__symbols); + let __sym3 = __pop_Variant50(__symbols); + let __sym2 = __pop_Variant98(__symbols); + let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1700::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (6, 103) + let __nt = super::__action1755::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (6, 102) } - pub(crate) fn __reduce266< + pub(crate) fn __reduce265< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassDef = "class", Identifier, Arguments, ":", Suite => ActionFn(1701); + // ClassDef = "class", Identifier, Arguments, ":", Suite => ActionFn(1756); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant24(__symbols); + let __sym4 = __pop_Variant25(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant51(__symbols); - let __sym1 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant50(__symbols); + let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1701::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (5, 103) + let __nt = super::__action1756::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (5, 102) } - pub(crate) fn __reduce267< + pub(crate) fn __reduce266< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassDef = Decorator+, "class", Identifier, TypeParams, Arguments, ":", Suite => ActionFn(1702); + // ClassDef = Decorator+, "class", Identifier, TypeParams, Arguments, ":", Suite => ActionFn(1757); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant24(__symbols); + let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant51(__symbols); - let __sym3 = __pop_Variant94(__symbols); - let __sym2 = __pop_Variant22(__symbols); + let __sym4 = __pop_Variant50(__symbols); + let __sym3 = __pop_Variant98(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant60(__symbols); + let __sym0 = __pop_Variant59(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1702::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (7, 103) + let __nt = super::__action1757::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (7, 102) } - pub(crate) fn __reduce268< + pub(crate) fn __reduce267< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassDef = Decorator+, "class", Identifier, Arguments, ":", Suite => ActionFn(1703); + // ClassDef = Decorator+, "class", Identifier, Arguments, ":", Suite => ActionFn(1758); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant24(__symbols); + let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant51(__symbols); - let __sym2 = __pop_Variant22(__symbols); + let __sym3 = __pop_Variant50(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant60(__symbols); + let __sym0 = __pop_Variant59(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1703::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (6, 103) + let __nt = super::__action1758::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (6, 102) } - pub(crate) fn __reduce269< + pub(crate) fn __reduce268< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassDef = "class", Identifier, TypeParams, ":", Suite => ActionFn(1704); + // ClassDef = "class", Identifier, TypeParams, ":", Suite => ActionFn(1759); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant24(__symbols); + let __sym4 = __pop_Variant25(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant94(__symbols); - let __sym1 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant98(__symbols); + let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1704::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (5, 103) + let __nt = super::__action1759::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (5, 102) } - pub(crate) fn __reduce270< + pub(crate) fn __reduce269< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassDef = "class", Identifier, ":", Suite => ActionFn(1705); + // ClassDef = "class", Identifier, ":", Suite => ActionFn(1760); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant22(__symbols); + let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1705::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (4, 103) + let __nt = super::__action1760::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (4, 102) } - pub(crate) fn __reduce271< + pub(crate) fn __reduce270< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassDef = Decorator+, "class", Identifier, TypeParams, ":", Suite => ActionFn(1706); + // ClassDef = Decorator+, "class", Identifier, TypeParams, ":", Suite => ActionFn(1761); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant24(__symbols); + let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant94(__symbols); - let __sym2 = __pop_Variant22(__symbols); + let __sym3 = __pop_Variant98(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant60(__symbols); + let __sym0 = __pop_Variant59(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1706::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (6, 103) + let __nt = super::__action1761::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (6, 102) } - pub(crate) fn __reduce272< + pub(crate) fn __reduce271< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassDef = Decorator+, "class", Identifier, ":", Suite => ActionFn(1707); + // ClassDef = Decorator+, "class", Identifier, ":", Suite => ActionFn(1762); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant24(__symbols); + let __sym4 = __pop_Variant25(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant60(__symbols); + let __sym0 = __pop_Variant59(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1707::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (5, 103) + let __nt = super::__action1762::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (5, 102) } - pub(crate) fn __reduce273< + pub(crate) fn __reduce272< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassPattern = MatchName, PatternArguments => ActionFn(1257); + // ClassPattern = MatchName, PatternArguments => ActionFn(1297); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant86(__symbols); - let __sym0 = __pop_Variant45(__symbols); + let __sym1 = __pop_Variant89(__symbols); + let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1257::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (2, 104) + let __nt = super::__action1297::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (2, 103) } - pub(crate) fn __reduce274< + pub(crate) fn __reduce273< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ClassPattern = MatchNameOrAttr, PatternArguments => ActionFn(1258); + // ClassPattern = MatchNameOrAttr, PatternArguments => ActionFn(1298); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant86(__symbols); - let __sym0 = __pop_Variant45(__symbols); + let __sym1 = __pop_Variant89(__symbols); + let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1258::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (2, 104) + let __nt = super::__action1298::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (2, 103) } - pub(crate) fn __reduce275< + pub(crate) fn __reduce274< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22319,15 +23252,16 @@ mod __parse__Top { ) -> (usize, usize) { // ClosedPattern = LiteralPattern => ActionFn(98); - let __sym0 = __pop_Variant34(__symbols); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action98::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 105) + let __nt = super::__action98::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 104) } - pub(crate) fn __reduce276< + pub(crate) fn __reduce275< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22335,15 +23269,16 @@ mod __parse__Top { ) -> (usize, usize) { // ClosedPattern = CapturePattern => ActionFn(99); - let __sym0 = __pop_Variant34(__symbols); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action99::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 105) + let __nt = super::__action99::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 104) } - pub(crate) fn __reduce277< + pub(crate) fn __reduce276< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22351,15 +23286,16 @@ mod __parse__Top { ) -> (usize, usize) { // ClosedPattern = StarPattern => ActionFn(100); - let __sym0 = __pop_Variant34(__symbols); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action100::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 105) + let __nt = super::__action100::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 104) } - pub(crate) fn __reduce278< + pub(crate) fn __reduce277< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22367,15 +23303,16 @@ mod __parse__Top { ) -> (usize, usize) { // ClosedPattern = ValuePattern => ActionFn(101); - let __sym0 = __pop_Variant34(__symbols); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action101::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 105) + let __nt = super::__action101::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 104) } - pub(crate) fn __reduce279< + pub(crate) fn __reduce278< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22383,15 +23320,16 @@ mod __parse__Top { ) -> (usize, usize) { // ClosedPattern = SequencePattern => ActionFn(102); - let __sym0 = __pop_Variant34(__symbols); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action102::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 105) + let __nt = super::__action102::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 104) } - pub(crate) fn __reduce280< + pub(crate) fn __reduce279< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22399,15 +23337,16 @@ mod __parse__Top { ) -> (usize, usize) { // ClosedPattern = MappingPattern => ActionFn(103); - let __sym0 = __pop_Variant34(__symbols); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action103::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 105) + let __nt = super::__action103::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 104) } - pub(crate) fn __reduce281< + pub(crate) fn __reduce280< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22415,192 +23354,204 @@ mod __parse__Top { ) -> (usize, usize) { // ClosedPattern = ClassPattern => ActionFn(104); - let __sym0 = __pop_Variant34(__symbols); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action104::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 105) + let __nt = super::__action104::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 104) } - pub(crate) fn __reduce282< + pub(crate) fn __reduce281< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comma = FunctionArgument => ActionFn(1494); - let __sym0 = __pop_Variant30(__symbols); + // Comma = FunctionArgument => ActionFn(1533); + let __sym0 = __pop_Variant31(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1494::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant53(__nt), __end)); - (1, 106) + let __nt = super::__action1533::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant52(__nt), __end)); + (1, 105) } - pub(crate) fn __reduce283< + pub(crate) fn __reduce282< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comma = => ActionFn(1495); + // Comma = => ActionFn(1534); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action1495::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant53(__nt), __end)); - (0, 106) + let __nt = super::__action1534::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant52(__nt), __end)); + (0, 105) } - pub(crate) fn __reduce284< + pub(crate) fn __reduce283< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comma = ( ",")+, FunctionArgument => ActionFn(1496); + // Comma = ( ",")+, FunctionArgument => ActionFn(1535); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant30(__symbols); - let __sym0 = __pop_Variant31(__symbols); + let __sym1 = __pop_Variant31(__symbols); + let __sym0 = __pop_Variant32(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1496::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant53(__nt), __end)); - (2, 106) + let __nt = super::__action1535::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant52(__nt), __end)); + (2, 105) } - pub(crate) fn __reduce285< + pub(crate) fn __reduce284< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comma = ( ",")+ => ActionFn(1497); - let __sym0 = __pop_Variant31(__symbols); + // Comma = ( ",")+ => ActionFn(1536); + let __sym0 = __pop_Variant32(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1497::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant53(__nt), __end)); - (1, 106) + let __nt = super::__action1536::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant52(__nt), __end)); + (1, 105) } - pub(crate) fn __reduce286< + pub(crate) fn __reduce285< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comma = Pattern => ActionFn(1502); - let __sym0 = __pop_Variant34(__symbols); + // Comma = Pattern => ActionFn(1541); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1502::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant54(__nt), __end)); - (1, 107) + let __nt = super::__action1541::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant53(__nt), __end)); + (1, 106) } - pub(crate) fn __reduce287< + pub(crate) fn __reduce286< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comma = => ActionFn(1503); + // Comma = => ActionFn(1542); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action1503::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant54(__nt), __end)); - (0, 107) + let __nt = super::__action1542::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant53(__nt), __end)); + (0, 106) } - pub(crate) fn __reduce288< + pub(crate) fn __reduce287< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comma = ( ",")+, Pattern => ActionFn(1504); + // Comma = ( ",")+, Pattern => ActionFn(1543); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant34(__symbols); - let __sym0 = __pop_Variant35(__symbols); + let __sym1 = __pop_Variant35(__symbols); + let __sym0 = __pop_Variant36(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1504::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant54(__nt), __end)); - (2, 107) + let __nt = super::__action1543::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant53(__nt), __end)); + (2, 106) } - pub(crate) fn __reduce289< + pub(crate) fn __reduce288< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comma = ( ",")+ => ActionFn(1505); - let __sym0 = __pop_Variant35(__symbols); + // Comma = ( ",")+ => ActionFn(1544); + let __sym0 = __pop_Variant36(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1505::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant54(__nt), __end)); - (1, 107) + let __nt = super::__action1544::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant53(__nt), __end)); + (1, 106) } - pub(crate) fn __reduce290< + pub(crate) fn __reduce289< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CompFor = SingleForComprehension+ => ActionFn(224); - let __sym0 = __pop_Variant88(__symbols); + // CompFor = SingleForComprehension+ => ActionFn(234); + let __sym0 = __pop_Variant91(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action224::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant55(__nt), __end)); - (1, 108) + let __nt = super::__action234::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant54(__nt), __end)); + (1, 107) } - pub(crate) fn __reduce291< + pub(crate) fn __reduce290< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CompFor? = CompFor => ActionFn(237); - let __sym0 = __pop_Variant55(__symbols); + // CompFor? = CompFor => ActionFn(247); + let __sym0 = __pop_Variant54(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action237::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant56(__nt), __end)); - (1, 109) + let __nt = super::__action247::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant55(__nt), __end)); + (1, 108) } - pub(crate) fn __reduce292< + pub(crate) fn __reduce291< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // CompFor? = => ActionFn(238); + // CompFor? = => ActionFn(248); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action238::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant56(__nt), __end)); - (0, 109) + let __nt = super::__action248::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant55(__nt), __end)); + (0, 108) } - pub(crate) fn __reduce293< + pub(crate) fn __reduce292< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22611,12 +23562,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action184::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant57(__nt), __end)); - (1, 110) + let __nt = super::__action184::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant56(__nt), __end)); + (1, 109) } - pub(crate) fn __reduce294< + pub(crate) fn __reduce293< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22627,12 +23579,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action185::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant57(__nt), __end)); - (1, 110) + let __nt = super::__action185::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant56(__nt), __end)); + (1, 109) } - pub(crate) fn __reduce295< + pub(crate) fn __reduce294< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22643,12 +23596,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action186::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant57(__nt), __end)); - (1, 110) + let __nt = super::__action186::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant56(__nt), __end)); + (1, 109) } - pub(crate) fn __reduce296< + pub(crate) fn __reduce295< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22659,12 +23613,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action187::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant57(__nt), __end)); - (1, 110) + let __nt = super::__action187::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant56(__nt), __end)); + (1, 109) } - pub(crate) fn __reduce297< + pub(crate) fn __reduce296< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22675,12 +23630,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action188::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant57(__nt), __end)); - (1, 110) + let __nt = super::__action188::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant56(__nt), __end)); + (1, 109) } - pub(crate) fn __reduce298< + pub(crate) fn __reduce297< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22691,12 +23647,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action189::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant57(__nt), __end)); - (1, 110) + let __nt = super::__action189::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant56(__nt), __end)); + (1, 109) } - pub(crate) fn __reduce299< + pub(crate) fn __reduce298< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22707,12 +23664,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action190::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant57(__nt), __end)); - (1, 110) + let __nt = super::__action190::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant56(__nt), __end)); + (1, 109) } - pub(crate) fn __reduce300< + pub(crate) fn __reduce299< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22725,12 +23683,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action191::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant57(__nt), __end)); - (2, 110) + let __nt = super::__action191::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant56(__nt), __end)); + (2, 109) } - pub(crate) fn __reduce301< + pub(crate) fn __reduce300< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22741,12 +23700,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action192::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant57(__nt), __end)); - (1, 110) + let __nt = super::__action192::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant56(__nt), __end)); + (1, 109) } - pub(crate) fn __reduce302< + pub(crate) fn __reduce301< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22759,80 +23719,85 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action193::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant57(__nt), __end)); - (2, 110) + let __nt = super::__action193::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant56(__nt), __end)); + (2, 109) } - pub(crate) fn __reduce303< + pub(crate) fn __reduce302< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comparison<"all"> = Expression<"all">, (CompOp Expression<"all">)+ => ActionFn(1259); + // Comparison<"all"> = Expression<"all">, (CompOp Expression<"all">)+ => ActionFn(1299); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant44(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant43(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1259::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 111) + let __nt = super::__action1299::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 110) } - pub(crate) fn __reduce304< + pub(crate) fn __reduce303< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comparison<"all"> = Expression<"all"> => ActionFn(490); - let __sym0 = __pop_Variant14(__symbols); + // Comparison<"all"> = Expression<"all"> => ActionFn(513); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action490::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 111) + let __nt = super::__action513::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 110) } - pub(crate) fn __reduce305< + pub(crate) fn __reduce304< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comparison<"no-withitems"> = Expression<"all">, (CompOp Expression<"all">)+ => ActionFn(1260); + // Comparison<"no-withitems"> = Expression<"all">, (CompOp Expression<"all">)+ => ActionFn(1300); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant44(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant43(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1260::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 112) + let __nt = super::__action1300::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 111) } - pub(crate) fn __reduce306< + pub(crate) fn __reduce305< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Comparison<"no-withitems"> = Expression<"no-withitems"> => ActionFn(501); - let __sym0 = __pop_Variant14(__symbols); + // Comparison<"no-withitems"> = Expression<"no-withitems"> => ActionFn(524); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action501::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 112) + let __nt = super::__action524::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 111) } - pub(crate) fn __reduce307< + pub(crate) fn __reduce306< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22840,15 +23805,16 @@ mod __parse__Top { ) -> (usize, usize) { // CompoundStatement = MatchStatement => ActionFn(77); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action77::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 113) + let __nt = super::__action77::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 112) } - pub(crate) fn __reduce308< + pub(crate) fn __reduce307< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22856,15 +23822,16 @@ mod __parse__Top { ) -> (usize, usize) { // CompoundStatement = IfStatement => ActionFn(78); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action78::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 113) + let __nt = super::__action78::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 112) } - pub(crate) fn __reduce309< + pub(crate) fn __reduce308< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22872,15 +23839,16 @@ mod __parse__Top { ) -> (usize, usize) { // CompoundStatement = WhileStatement => ActionFn(79); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action79::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 113) + let __nt = super::__action79::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 112) } - pub(crate) fn __reduce310< + pub(crate) fn __reduce309< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22888,15 +23856,16 @@ mod __parse__Top { ) -> (usize, usize) { // CompoundStatement = ForStatement => ActionFn(80); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action80::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 113) + let __nt = super::__action80::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 112) } - pub(crate) fn __reduce311< + pub(crate) fn __reduce310< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22904,15 +23873,16 @@ mod __parse__Top { ) -> (usize, usize) { // CompoundStatement = TryStatement => ActionFn(81); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action81::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 113) + let __nt = super::__action81::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 112) } - pub(crate) fn __reduce312< + pub(crate) fn __reduce311< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22920,15 +23890,16 @@ mod __parse__Top { ) -> (usize, usize) { // CompoundStatement = WithStatement => ActionFn(82); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action82::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 113) + let __nt = super::__action82::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 112) } - pub(crate) fn __reduce313< + pub(crate) fn __reduce312< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22936,15 +23907,16 @@ mod __parse__Top { ) -> (usize, usize) { // CompoundStatement = FuncDef => ActionFn(83); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action83::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 113) + let __nt = super::__action83::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 112) } - pub(crate) fn __reduce314< + pub(crate) fn __reduce313< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -22952,162 +23924,172 @@ mod __parse__Top { ) -> (usize, usize) { // CompoundStatement = ClassDef => ActionFn(84); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action84::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 113) + let __nt = super::__action84::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 112) } - pub(crate) fn __reduce315< + pub(crate) fn __reduce314< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ComprehensionIf = "if", ExpressionNoCond => ActionFn(227); + // ComprehensionIf = "if", ExpressionNoCond => ActionFn(237); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action227::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 114) + let __nt = super::__action237::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 113) } - pub(crate) fn __reduce316< + pub(crate) fn __reduce315< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ComprehensionIf* = => ActionFn(240); + // ComprehensionIf* = => ActionFn(250); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action240::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (0, 115) + let __nt = super::__action250::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (0, 114) } - pub(crate) fn __reduce317< + pub(crate) fn __reduce316< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ComprehensionIf* = ComprehensionIf+ => ActionFn(241); - let __sym0 = __pop_Variant16(__symbols); + // ComprehensionIf* = ComprehensionIf+ => ActionFn(251); + let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action241::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (1, 115) + let __nt = super::__action251::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (1, 114) } - pub(crate) fn __reduce318< + pub(crate) fn __reduce317< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ComprehensionIf+ = ComprehensionIf => ActionFn(439); - let __sym0 = __pop_Variant14(__symbols); + // ComprehensionIf+ = ComprehensionIf => ActionFn(462); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action439::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (1, 116) + let __nt = super::__action462::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (1, 115) } - pub(crate) fn __reduce319< + pub(crate) fn __reduce318< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ComprehensionIf+ = ComprehensionIf+, ComprehensionIf => ActionFn(440); + // ComprehensionIf+ = ComprehensionIf+, ComprehensionIf => ActionFn(463); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); - let __sym0 = __pop_Variant16(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action440::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (2, 116) + let __nt = super::__action463::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (2, 115) } - pub(crate) fn __reduce320< + pub(crate) fn __reduce319< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Constant = int => ActionFn(233); - let __sym0 = __pop_Variant3(__symbols); + // Constant = int => ActionFn(243); + let __sym0 = __pop_Variant4(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action233::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant58(__nt), __end)); - (1, 117) + let __nt = super::__action243::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant57(__nt), __end)); + (1, 116) } - pub(crate) fn __reduce321< + pub(crate) fn __reduce320< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Constant = float => ActionFn(234); + // Constant = float => ActionFn(244); let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action234::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant58(__nt), __end)); - (1, 117) + let __nt = super::__action244::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant57(__nt), __end)); + (1, 116) } - pub(crate) fn __reduce322< + pub(crate) fn __reduce321< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Constant = complex => ActionFn(235); + // Constant = complex => ActionFn(245); let __sym0 = __pop_Variant1(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action235::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant58(__nt), __end)); - (1, 117) + let __nt = super::__action245::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant57(__nt), __end)); + (1, 116) } - pub(crate) fn __reduce323< + pub(crate) fn __reduce322< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ConstantAtom = Constant => ActionFn(1261); - let __sym0 = __pop_Variant58(__symbols); + // ConstantAtom = Constant => ActionFn(1301); + let __sym0 = __pop_Variant57(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1261::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 118) + let __nt = super::__action1301::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 117) } - pub(crate) fn __reduce324< + pub(crate) fn __reduce323< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -23115,936 +24097,1233 @@ mod __parse__Top { ) -> (usize, usize) { // ConstantExpr = ConstantAtom => ActionFn(112); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action112::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 119) + let __nt = super::__action112::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 118) } - pub(crate) fn __reduce325< + pub(crate) fn __reduce324< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ConstantExpr = "-", ConstantAtom => ActionFn(1262); + // ConstantExpr = "-", ConstantAtom => ActionFn(1302); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1262::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 119) + let __nt = super::__action1302::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 118) } - pub(crate) fn __reduce326< + pub(crate) fn __reduce325< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Decorator = "@", NamedExpressionTest, "\n" => ActionFn(1263); + // Decorator = "@", NamedExpressionTest, "\n" => ActionFn(1303); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1263::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant59(__nt), __end)); - (3, 120) + let __nt = super::__action1303::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant58(__nt), __end)); + (3, 119) } - pub(crate) fn __reduce327< + pub(crate) fn __reduce326< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Decorator* = => ActionFn(286); + // Decorator* = => ActionFn(306); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action286::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant60(__nt), __end)); - (0, 121) + let __nt = super::__action306::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant59(__nt), __end)); + (0, 120) } - pub(crate) fn __reduce328< + pub(crate) fn __reduce327< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Decorator* = Decorator+ => ActionFn(287); - let __sym0 = __pop_Variant60(__symbols); + // Decorator* = Decorator+ => ActionFn(307); + let __sym0 = __pop_Variant59(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action287::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant60(__nt), __end)); - (1, 121) + let __nt = super::__action307::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant59(__nt), __end)); + (1, 120) } - pub(crate) fn __reduce329< + pub(crate) fn __reduce328< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Decorator+ = Decorator => ActionFn(414); - let __sym0 = __pop_Variant59(__symbols); + // Decorator+ = Decorator => ActionFn(435); + let __sym0 = __pop_Variant58(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action414::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant60(__nt), __end)); - (1, 122) + let __nt = super::__action435::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant59(__nt), __end)); + (1, 121) } - pub(crate) fn __reduce330< + pub(crate) fn __reduce329< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Decorator+ = Decorator+, Decorator => ActionFn(415); + // Decorator+ = Decorator+, Decorator => ActionFn(436); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant59(__symbols); - let __sym0 = __pop_Variant60(__symbols); + let __sym1 = __pop_Variant58(__symbols); + let __sym0 = __pop_Variant59(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action415::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant60(__nt), __end)); - (2, 122) + let __nt = super::__action436::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant59(__nt), __end)); + (2, 121) } - pub(crate) fn __reduce331< + pub(crate) fn __reduce330< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DelStatement = "del", ExpressionList2 => ActionFn(1264); + // DelStatement = "del", ExpressionList2 => ActionFn(1304); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1264::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (2, 123) + let __nt = super::__action1304::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (2, 122) } - pub(crate) fn __reduce332< + pub(crate) fn __reduce331< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DictElement = DictEntry => ActionFn(215); - let __sym0 = __pop_Variant62(__symbols); + // DictElement = DictEntry => ActionFn(225); + let __sym0 = __pop_Variant61(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action215::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant61(__nt), __end)); - (1, 124) + let __nt = super::__action225::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant60(__nt), __end)); + (1, 123) } - pub(crate) fn __reduce333< + pub(crate) fn __reduce332< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DictElement = "**", Expression<"all"> => ActionFn(216); + // DictElement = "**", Expression<"all"> => ActionFn(226); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action216::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant61(__nt), __end)); - (2, 124) + let __nt = super::__action226::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant60(__nt), __end)); + (2, 123) } - pub(crate) fn __reduce334< + pub(crate) fn __reduce333< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DictEntry = Test<"all">, ":", Test<"all"> => ActionFn(214); + // DictEntry = Test<"all">, ":", Test<"all"> => ActionFn(224); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action214::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant62(__nt), __end)); - (3, 125) + let __nt = super::__action224::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant61(__nt), __end)); + (3, 124) } - pub(crate) fn __reduce335< + pub(crate) fn __reduce334< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DictLiteralValues = OneOrMore, "," => ActionFn(589); + // DictLiteralValues = OneOrMore, "," => ActionFn(612); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant63(__symbols); + let __sym0 = __pop_Variant62(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action589::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant63(__nt), __end)); - (2, 126) + let __nt = super::__action612::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant62(__nt), __end)); + (2, 125) } - pub(crate) fn __reduce336< + pub(crate) fn __reduce335< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DictLiteralValues = OneOrMore => ActionFn(590); - let __sym0 = __pop_Variant63(__symbols); + // DictLiteralValues = OneOrMore => ActionFn(613); + let __sym0 = __pop_Variant62(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action590::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant63(__nt), __end)); - (1, 126) + let __nt = super::__action613::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant62(__nt), __end)); + (1, 125) } - pub(crate) fn __reduce337< + pub(crate) fn __reduce336< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DictLiteralValues? = DictLiteralValues => ActionFn(541); - let __sym0 = __pop_Variant63(__symbols); + // DictLiteralValues? = DictLiteralValues => ActionFn(564); + let __sym0 = __pop_Variant62(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action541::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant64(__nt), __end)); - (1, 127) + let __nt = super::__action564::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant63(__nt), __end)); + (1, 126) } - pub(crate) fn __reduce338< + pub(crate) fn __reduce337< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DictLiteralValues? = => ActionFn(542); + // DictLiteralValues? = => ActionFn(565); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action542::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant64(__nt), __end)); - (0, 127) + let __nt = super::__action565::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant63(__nt), __end)); + (0, 126) } - pub(crate) fn __reduce339< + pub(crate) fn __reduce338< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DottedName = name => ActionFn(1265); - let __sym0 = __pop_Variant5(__symbols); + // DottedName = name => ActionFn(1305); + let __sym0 = __pop_Variant6(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1265::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant22(__nt), __end)); - (1, 128) + let __nt = super::__action1305::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant23(__nt), __end)); + (1, 127) } - pub(crate) fn __reduce340< + pub(crate) fn __reduce339< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DottedName = name, ("." Identifier)+ => ActionFn(1266); + // DottedName = name, ("." Identifier)+ => ActionFn(1306); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant20(__symbols); - let __sym0 = __pop_Variant5(__symbols); + let __sym1 = __pop_Variant21(__symbols); + let __sym0 = __pop_Variant6(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1266::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant22(__nt), __end)); - (2, 128) + let __nt = super::__action1306::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant23(__nt), __end)); + (2, 127) } - pub(crate) fn __reduce341< + pub(crate) fn __reduce340< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DoubleStarTypedParameter = Identifier, ":", Test<"all"> => ActionFn(1267); + // DoubleStarTypedParameter = Identifier, ":", Test<"all"> => ActionFn(1307); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant22(__symbols); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1267::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant65(__nt), __end)); - (3, 129) + let __nt = super::__action1307::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant64(__nt), __end)); + (3, 128) } - pub(crate) fn __reduce342< + pub(crate) fn __reduce341< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DoubleStarTypedParameter = Identifier => ActionFn(1268); - let __sym0 = __pop_Variant22(__symbols); + // DoubleStarTypedParameter = Identifier => ActionFn(1308); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1268::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant65(__nt), __end)); - (1, 129) + let __nt = super::__action1308::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant64(__nt), __end)); + (1, 128) } - pub(crate) fn __reduce343< + pub(crate) fn __reduce342< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DoubleStarTypedParameter? = DoubleStarTypedParameter => ActionFn(475); - let __sym0 = __pop_Variant65(__symbols); + // DoubleStarTypedParameter? = DoubleStarTypedParameter => ActionFn(498); + let __sym0 = __pop_Variant64(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action475::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant66(__nt), __end)); - (1, 130) + let __nt = super::__action498::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant65(__nt), __end)); + (1, 129) } - pub(crate) fn __reduce344< + pub(crate) fn __reduce343< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // DoubleStarTypedParameter? = => ActionFn(476); + // DoubleStarTypedParameter? = => ActionFn(499); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action476::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant66(__nt), __end)); - (0, 130) + let __nt = super::__action499::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant65(__nt), __end)); + (0, 129) } - pub(crate) fn __reduce345< + pub(crate) fn __reduce344< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptClause = "except", Test<"all">, ":", Suite => ActionFn(1672); + // ExceptClause = "except", Test<"all">, ":", Suite => ActionFn(1727); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1672::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant67(__nt), __end)); - (4, 131) + let __nt = super::__action1727::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant66(__nt), __end)); + (4, 130) } - pub(crate) fn __reduce346< + pub(crate) fn __reduce345< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptClause = "except", ":", Suite => ActionFn(1673); + // ExceptClause = "except", ":", Suite => ActionFn(1728); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant24(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1673::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant67(__nt), __end)); - (3, 131) + let __nt = super::__action1728::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant66(__nt), __end)); + (3, 130) } - pub(crate) fn __reduce347< + pub(crate) fn __reduce346< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptClause = "except", Test<"all">, "as", Identifier, ":", Suite => ActionFn(1172); + // ExceptClause = "except", Test<"all">, "as", Identifier, ":", Suite => ActionFn(1203); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant24(__symbols); + let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant22(__symbols); + let __sym3 = __pop_Variant23(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1172::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant67(__nt), __end)); - (6, 131) + let __nt = super::__action1203::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant66(__nt), __end)); + (6, 130) } - pub(crate) fn __reduce348< + pub(crate) fn __reduce347< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptClause+ = ExceptClause => ActionFn(310); - let __sym0 = __pop_Variant67(__symbols); + // ExceptClause+ = ExceptClause => ActionFn(330); + let __sym0 = __pop_Variant66(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action310::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant68(__nt), __end)); - (1, 132) + let __nt = super::__action330::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant67(__nt), __end)); + (1, 131) } - pub(crate) fn __reduce349< + pub(crate) fn __reduce348< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptClause+ = ExceptClause+, ExceptClause => ActionFn(311); + // ExceptClause+ = ExceptClause+, ExceptClause => ActionFn(331); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant67(__symbols); - let __sym0 = __pop_Variant68(__symbols); + let __sym1 = __pop_Variant66(__symbols); + let __sym0 = __pop_Variant67(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action311::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant68(__nt), __end)); - (2, 132) + let __nt = super::__action331::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant67(__nt), __end)); + (2, 131) } - pub(crate) fn __reduce350< + pub(crate) fn __reduce349< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptStarClause = "except", "*", Test<"all">, ":", Suite => ActionFn(771); + // ExceptStarClause = "except", "*", Test<"all">, ":", Suite => ActionFn(795); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant24(__symbols); + let __sym4 = __pop_Variant25(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action771::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant67(__nt), __end)); - (5, 133) + let __nt = super::__action795::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant66(__nt), __end)); + (5, 132) } - pub(crate) fn __reduce351< + pub(crate) fn __reduce350< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptStarClause = "except", "*", Test<"all">, "as", Identifier, ":", Suite => ActionFn(1173); + // ExceptStarClause = "except", "*", Test<"all">, "as", Identifier, ":", Suite => ActionFn(1204); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant24(__symbols); + let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant22(__symbols); + let __sym4 = __pop_Variant23(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1173::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant67(__nt), __end)); - (7, 133) + let __nt = super::__action1204::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant66(__nt), __end)); + (7, 132) } - pub(crate) fn __reduce352< + pub(crate) fn __reduce351< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptStarClause+ = ExceptStarClause => ActionFn(305); - let __sym0 = __pop_Variant67(__symbols); + // ExceptStarClause+ = ExceptStarClause => ActionFn(325); + let __sym0 = __pop_Variant66(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action305::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant68(__nt), __end)); - (1, 134) + let __nt = super::__action325::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant67(__nt), __end)); + (1, 133) } - pub(crate) fn __reduce353< + pub(crate) fn __reduce352< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExceptStarClause+ = ExceptStarClause+, ExceptStarClause => ActionFn(306); + // ExceptStarClause+ = ExceptStarClause+, ExceptStarClause => ActionFn(326); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant67(__symbols); - let __sym0 = __pop_Variant68(__symbols); + let __sym1 = __pop_Variant66(__symbols); + let __sym0 = __pop_Variant67(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action306::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant68(__nt), __end)); - (2, 134) + let __nt = super::__action326::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant67(__nt), __end)); + (2, 133) } - pub(crate) fn __reduce354< + pub(crate) fn __reduce353< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Expression<"all"> = Expression<"all">, "|", XorExpression<"all"> => ActionFn(1269); + // Expression<"all"> = Expression<"all">, "|", XorExpression<"all"> => ActionFn(1309); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1269::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 135) + let __nt = super::__action1309::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 134) } - pub(crate) fn __reduce355< + pub(crate) fn __reduce354< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Expression<"all"> = XorExpression<"all"> => ActionFn(351); - let __sym0 = __pop_Variant14(__symbols); + // Expression<"all"> = XorExpression<"all"> => ActionFn(372); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action351::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 135) + let __nt = super::__action372::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 134) } - pub(crate) fn __reduce356< + pub(crate) fn __reduce355< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Expression<"no-withitems"> = Expression<"all">, "|", XorExpression<"all"> => ActionFn(1270); + // Expression<"no-withitems"> = Expression<"all">, "|", XorExpression<"all"> => ActionFn(1310); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1270::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 136) + let __nt = super::__action1310::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 135) } - pub(crate) fn __reduce357< + pub(crate) fn __reduce356< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Expression<"no-withitems"> = XorExpression<"no-withitems"> => ActionFn(503); - let __sym0 = __pop_Variant14(__symbols); + // Expression<"no-withitems"> = XorExpression<"no-withitems"> => ActionFn(526); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action503::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 136) + let __nt = super::__action526::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 135) } - pub(crate) fn __reduce358< + pub(crate) fn __reduce357< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExpressionList = GenericList => ActionFn(220); - let __sym0 = __pop_Variant14(__symbols); + // ExpressionList = GenericList => ActionFn(230); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action220::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 137) + let __nt = super::__action230::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 136) } - pub(crate) fn __reduce359< + pub(crate) fn __reduce358< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExpressionList2 = OneOrMore, "," => ActionFn(591); + // ExpressionList2 = OneOrMore, "," => ActionFn(614); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant32(__symbols); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action591::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (2, 138) + let __nt = super::__action614::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (2, 137) + } + pub(crate) fn __reduce359< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // ExpressionList2 = OneOrMore => ActionFn(615); + let __sym0 = __pop_Variant33(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = super::__action615::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (1, 137) } pub(crate) fn __reduce360< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExpressionList2 = OneOrMore => ActionFn(592); - let __sym0 = __pop_Variant32(__symbols); + // ExpressionNoCond = OrTest<"all"> => ActionFn(236); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action592::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); + let __nt = super::__action236::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 138) } pub(crate) fn __reduce361< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExpressionNoCond = OrTest<"all"> => ActionFn(226); - let __sym0 = __pop_Variant14(__symbols); + // ExpressionOrStarExpression = Expression<"all"> => ActionFn(228); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action226::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + let __nt = super::__action228::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); (1, 139) } pub(crate) fn __reduce362< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExpressionOrStarExpression = Expression<"all"> => ActionFn(218); - let __sym0 = __pop_Variant14(__symbols); + // ExpressionOrStarExpression = StarExpr => ActionFn(229); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action218::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 140) + let __nt = super::__action229::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 139) } pub(crate) fn __reduce363< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExpressionOrStarExpression = StarExpr => ActionFn(219); - let __sym0 = __pop_Variant14(__symbols); + // ExpressionStatement = GenericList => ActionFn(1752); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action219::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + let __nt = super::__action1752::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); (1, 140) } pub(crate) fn __reduce364< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExpressionStatement = GenericList => ActionFn(1697); - let __sym0 = __pop_Variant14(__symbols); + // ExpressionStatement = GenericList, AssignSuffix+ => ActionFn(1753); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant17(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; - let __end = __sym0.2; - let __nt = super::__action1697::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 141) + let __end = __sym1.2; + let __nt = super::__action1753::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (2, 140) } pub(crate) fn __reduce365< >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // ExpressionStatement = GenericList, AugAssign, TestListOrYieldExpr => ActionFn(1754); + assert!(__symbols.len() >= 3); + let __sym2 = __pop_Variant15(__symbols); + let __sym1 = __pop_Variant49(__symbols); + let __sym0 = __pop_Variant15(__symbols); + let __start = __sym0.0; + let __end = __sym2.2; + let __nt = super::__action1754::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (3, 140) + } + pub(crate) fn __reduce366< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // ExpressionStatement = Test<"all">, ":", Test<"all">, AssignSuffix => ActionFn(1531); + assert!(__symbols.len() >= 4); + let __sym3 = __pop_Variant15(__symbols); + let __sym2 = __pop_Variant15(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant15(__symbols); + let __start = __sym0.0; + let __end = __sym3.2; + let __nt = super::__action1531::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (4, 140) + } + pub(crate) fn __reduce367< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // ExpressionStatement = Test<"all">, ":", Test<"all"> => ActionFn(1532); + assert!(__symbols.len() >= 3); + let __sym2 = __pop_Variant15(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant15(__symbols); + let __start = __sym0.0; + let __end = __sym2.2; + let __nt = super::__action1532::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (3, 140) + } + pub(crate) fn __reduce369< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // FStringConversion? = FStringConversion => ActionFn(266); + let __sym0 = __pop_Variant68(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = super::__action266::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant69(__nt), __end)); + (1, 142) + } + pub(crate) fn __reduce370< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // FStringConversion? = => ActionFn(267); + let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); + let __end = __start.clone(); + let __nt = super::__action267::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant69(__nt), __end)); + (0, 142) + } + pub(crate) fn __reduce371< + >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExpressionStatement = GenericList, AssignSuffix+ => ActionFn(1698); + // FStringExpr = FStringStart, FStringEnd => ActionFn(1585); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant16(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1698::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (2, 141) + let __nt = super::__action1585::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant70(__nt), __end)); + (2, 143) } - pub(crate) fn __reduce366< + pub(crate) fn __reduce372< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExpressionStatement = GenericList, AugAssign, TestListOrYieldExpr => ActionFn(1699); + // FStringExpr = FStringStart, FStringMiddlePattern+, FStringEnd => ActionFn(1586); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); - let __sym1 = __pop_Variant50(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant0(__symbols); + let __sym1 = __pop_Variant71(__symbols); + let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1699::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (3, 141) + let __nt = super::__action1586::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant70(__nt), __end)); + (3, 143) + } + pub(crate) fn __reduce373< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // FStringFormatSpec = => ActionFn(1587); + let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); + let __end = __start.clone(); + let __nt = super::__action1587::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (0, 144) + } + pub(crate) fn __reduce374< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // FStringFormatSpec = FStringMiddlePattern+ => ActionFn(1588); + let __sym0 = __pop_Variant71(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = super::__action1588::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (1, 144) + } + pub(crate) fn __reduce375< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // FStringFormatSpecSuffix = ":", FStringFormatSpec => ActionFn(219); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant44(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0; + let __end = __sym1.2; + let __nt = super::__action219::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (2, 145) + } + pub(crate) fn __reduce376< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // FStringFormatSpecSuffix? = FStringFormatSpecSuffix => ActionFn(264); + let __sym0 = __pop_Variant44(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = super::__action264::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant45(__nt), __end)); + (1, 146) + } + pub(crate) fn __reduce377< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // FStringFormatSpecSuffix? = => ActionFn(265); + let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); + let __end = __start.clone(); + let __nt = super::__action265::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant45(__nt), __end)); + (0, 146) + } + pub(crate) fn __reduce378< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // FStringMiddlePattern = FStringReplacementField => ActionFn(216); + let __sym0 = __pop_Variant44(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = super::__action216::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (1, 147) + } + pub(crate) fn __reduce380< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // FStringMiddlePattern* = => ActionFn(270); + let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); + let __end = __start.clone(); + let __nt = super::__action270::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant71(__nt), __end)); + (0, 148) + } + pub(crate) fn __reduce381< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // FStringMiddlePattern* = FStringMiddlePattern+ => ActionFn(271); + let __sym0 = __pop_Variant71(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = super::__action271::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant71(__nt), __end)); + (1, 148) } - pub(crate) fn __reduce367< + pub(crate) fn __reduce382< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExpressionStatement = Test<"all">, ":", Test<"all">, AssignSuffix => ActionFn(1492); - assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant14(__symbols); - let __sym2 = __pop_Variant14(__symbols); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + // FStringMiddlePattern+ = FStringMiddlePattern => ActionFn(453); + let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; - let __end = __sym3.2; - let __nt = super::__action1492::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (4, 141) + let __end = __sym0.2; + let __nt = super::__action453::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant71(__nt), __end)); + (1, 149) } - pub(crate) fn __reduce368< + pub(crate) fn __reduce383< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ExpressionStatement = Test<"all">, ":", Test<"all"> => ActionFn(1493); - assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + // FStringMiddlePattern+ = FStringMiddlePattern+, FStringMiddlePattern => ActionFn(454); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant44(__symbols); + let __sym0 = __pop_Variant71(__symbols); let __start = __sym0.0; - let __end = __sym2.2; - let __nt = super::__action1493::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (3, 141) + let __end = __sym1.2; + let __nt = super::__action454::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant71(__nt), __end)); + (2, 149) } - pub(crate) fn __reduce369< + pub(crate) fn __reduce392< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Factor<"all"> = UnaryOp, Factor<"all"> => ActionFn(1274); + // Factor<"all"> = UnaryOp, Factor<"all"> => ActionFn(1318); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); - let __sym0 = __pop_Variant96(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant100(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1274::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 142) + let __nt = super::__action1318::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 151) } - pub(crate) fn __reduce370< + pub(crate) fn __reduce393< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Factor<"all"> = Power<"all"> => ActionFn(505); - let __sym0 = __pop_Variant14(__symbols); + // Factor<"all"> = Power<"all"> => ActionFn(528); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action505::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 142) + let __nt = super::__action528::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 151) } - pub(crate) fn __reduce371< + pub(crate) fn __reduce394< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Factor<"no-withitems"> = UnaryOp, Factor<"all"> => ActionFn(1275); + // Factor<"no-withitems"> = UnaryOp, Factor<"all"> => ActionFn(1319); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); - let __sym0 = __pop_Variant96(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant100(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1275::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 143) + let __nt = super::__action1319::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 152) } - pub(crate) fn __reduce372< + pub(crate) fn __reduce395< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Factor<"no-withitems"> = Power<"no-withitems"> => ActionFn(554); - let __sym0 = __pop_Variant14(__symbols); + // Factor<"no-withitems"> = Power<"no-withitems"> => ActionFn(577); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action554::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 143) + let __nt = super::__action577::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 152) } - pub(crate) fn __reduce373< + pub(crate) fn __reduce396< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FlowStatement = "break" => ActionFn(1276); + // FlowStatement = "break" => ActionFn(1320); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1276::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 144) + let __nt = super::__action1320::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 153) } - pub(crate) fn __reduce374< + pub(crate) fn __reduce397< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FlowStatement = "continue" => ActionFn(1277); + // FlowStatement = "continue" => ActionFn(1321); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1277::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 144) + let __nt = super::__action1321::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 153) } - pub(crate) fn __reduce375< + pub(crate) fn __reduce398< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FlowStatement = "return", GenericList => ActionFn(1693); + // FlowStatement = "return", GenericList => ActionFn(1748); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1693::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (2, 144) + let __nt = super::__action1748::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (2, 153) } - pub(crate) fn __reduce376< + pub(crate) fn __reduce399< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FlowStatement = "return" => ActionFn(1694); + // FlowStatement = "return" => ActionFn(1749); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1694::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 144) + let __nt = super::__action1749::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 153) } - pub(crate) fn __reduce377< + pub(crate) fn __reduce400< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FlowStatement = YieldExpr => ActionFn(1279); - let __sym0 = __pop_Variant14(__symbols); + // FlowStatement = YieldExpr => ActionFn(1323); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1279::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 144) + let __nt = super::__action1323::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 153) } - pub(crate) fn __reduce378< + pub(crate) fn __reduce401< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -24052,693 +25331,726 @@ mod __parse__Top { ) -> (usize, usize) { // FlowStatement = RaiseStatement => ActionFn(57); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action57::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 144) + let __nt = super::__action57::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 153) } - pub(crate) fn __reduce379< + pub(crate) fn __reduce402< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ForStatement = "async", "for", ExpressionList, "in", GenericList, ":", Suite, "else", ":", Suite => ActionFn(1684); + // ForStatement = "async", "for", ExpressionList, "in", GenericList, ":", Suite, "else", ":", Suite => ActionFn(1739); assert!(__symbols.len() >= 10); - let __sym9 = __pop_Variant24(__symbols); + let __sym9 = __pop_Variant25(__symbols); let __sym8 = __pop_Variant0(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant24(__symbols); + let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant14(__symbols); + let __sym4 = __pop_Variant15(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = super::__action1684::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (10, 145) + let __nt = super::__action1739::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (10, 154) } - pub(crate) fn __reduce380< + pub(crate) fn __reduce403< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ForStatement = "async", "for", ExpressionList, "in", GenericList, ":", Suite => ActionFn(1685); + // ForStatement = "async", "for", ExpressionList, "in", GenericList, ":", Suite => ActionFn(1740); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant24(__symbols); + let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant14(__symbols); + let __sym4 = __pop_Variant15(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1685::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (7, 145) + let __nt = super::__action1740::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (7, 154) } - pub(crate) fn __reduce381< + pub(crate) fn __reduce404< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ForStatement = "for", ExpressionList, "in", GenericList, ":", Suite, "else", ":", Suite => ActionFn(1686); + // ForStatement = "for", ExpressionList, "in", GenericList, ":", Suite, "else", ":", Suite => ActionFn(1741); assert!(__symbols.len() >= 9); - let __sym8 = __pop_Variant24(__symbols); + let __sym8 = __pop_Variant25(__symbols); let __sym7 = __pop_Variant0(__symbols); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant24(__symbols); + let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant14(__symbols); + let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = super::__action1686::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (9, 145) + let __nt = super::__action1741::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (9, 154) } - pub(crate) fn __reduce382< + pub(crate) fn __reduce405< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ForStatement = "for", ExpressionList, "in", GenericList, ":", Suite => ActionFn(1687); + // ForStatement = "for", ExpressionList, "in", GenericList, ":", Suite => ActionFn(1742); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant24(__symbols); + let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant14(__symbols); + let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1687::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (6, 145) + let __nt = super::__action1742::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (6, 154) } - pub(crate) fn __reduce383< + pub(crate) fn __reduce406< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = "async", "def", Identifier, TypeParams, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1708); + // FuncDef = "async", "def", Identifier, TypeParams, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1763); assert!(__symbols.len() >= 9); - let __sym8 = __pop_Variant24(__symbols); + let __sym8 = __pop_Variant25(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant14(__symbols); + let __sym6 = __pop_Variant15(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant47(__symbols); - let __sym3 = __pop_Variant94(__symbols); - let __sym2 = __pop_Variant22(__symbols); + let __sym4 = __pop_Variant46(__symbols); + let __sym3 = __pop_Variant98(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = super::__action1708::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (9, 146) + let __nt = super::__action1763::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (9, 155) } - pub(crate) fn __reduce384< + pub(crate) fn __reduce407< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = "async", "def", Identifier, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1709); + // FuncDef = "async", "def", Identifier, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1764); assert!(__symbols.len() >= 8); - let __sym7 = __pop_Variant24(__symbols); + let __sym7 = __pop_Variant25(__symbols); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant14(__symbols); + let __sym5 = __pop_Variant15(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant47(__symbols); - let __sym2 = __pop_Variant22(__symbols); + let __sym3 = __pop_Variant46(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = super::__action1709::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (8, 146) + let __nt = super::__action1764::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (8, 155) } - pub(crate) fn __reduce385< + pub(crate) fn __reduce408< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = Decorator+, "async", "def", Identifier, TypeParams, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1710); + // FuncDef = Decorator+, "async", "def", Identifier, TypeParams, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1765); assert!(__symbols.len() >= 10); - let __sym9 = __pop_Variant24(__symbols); + let __sym9 = __pop_Variant25(__symbols); let __sym8 = __pop_Variant0(__symbols); - let __sym7 = __pop_Variant14(__symbols); + let __sym7 = __pop_Variant15(__symbols); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant47(__symbols); - let __sym4 = __pop_Variant94(__symbols); - let __sym3 = __pop_Variant22(__symbols); + let __sym5 = __pop_Variant46(__symbols); + let __sym4 = __pop_Variant98(__symbols); + let __sym3 = __pop_Variant23(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant60(__symbols); + let __sym0 = __pop_Variant59(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = super::__action1710::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (10, 146) + let __nt = super::__action1765::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (10, 155) } - pub(crate) fn __reduce386< + pub(crate) fn __reduce409< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = Decorator+, "async", "def", Identifier, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1711); + // FuncDef = Decorator+, "async", "def", Identifier, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1766); assert!(__symbols.len() >= 9); - let __sym8 = __pop_Variant24(__symbols); + let __sym8 = __pop_Variant25(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant14(__symbols); + let __sym6 = __pop_Variant15(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant47(__symbols); - let __sym3 = __pop_Variant22(__symbols); + let __sym4 = __pop_Variant46(__symbols); + let __sym3 = __pop_Variant23(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant60(__symbols); + let __sym0 = __pop_Variant59(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = super::__action1711::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (9, 146) + let __nt = super::__action1766::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (9, 155) } - pub(crate) fn __reduce387< + pub(crate) fn __reduce410< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = "async", "def", Identifier, TypeParams, Parameters, ":", Suite => ActionFn(1712); + // FuncDef = "async", "def", Identifier, TypeParams, Parameters, ":", Suite => ActionFn(1767); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant24(__symbols); + let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant47(__symbols); - let __sym3 = __pop_Variant94(__symbols); - let __sym2 = __pop_Variant22(__symbols); + let __sym4 = __pop_Variant46(__symbols); + let __sym3 = __pop_Variant98(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1712::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (7, 146) + let __nt = super::__action1767::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (7, 155) } - pub(crate) fn __reduce388< + pub(crate) fn __reduce411< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = "async", "def", Identifier, Parameters, ":", Suite => ActionFn(1713); + // FuncDef = "async", "def", Identifier, Parameters, ":", Suite => ActionFn(1768); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant24(__symbols); + let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant47(__symbols); - let __sym2 = __pop_Variant22(__symbols); + let __sym3 = __pop_Variant46(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1713::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (6, 146) + let __nt = super::__action1768::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (6, 155) } - pub(crate) fn __reduce389< + pub(crate) fn __reduce412< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = Decorator+, "async", "def", Identifier, TypeParams, Parameters, ":", Suite => ActionFn(1714); + // FuncDef = Decorator+, "async", "def", Identifier, TypeParams, Parameters, ":", Suite => ActionFn(1769); assert!(__symbols.len() >= 8); - let __sym7 = __pop_Variant24(__symbols); + let __sym7 = __pop_Variant25(__symbols); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant47(__symbols); - let __sym4 = __pop_Variant94(__symbols); - let __sym3 = __pop_Variant22(__symbols); + let __sym5 = __pop_Variant46(__symbols); + let __sym4 = __pop_Variant98(__symbols); + let __sym3 = __pop_Variant23(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant60(__symbols); + let __sym0 = __pop_Variant59(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = super::__action1714::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (8, 146) + let __nt = super::__action1769::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (8, 155) } - pub(crate) fn __reduce390< + pub(crate) fn __reduce413< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = Decorator+, "async", "def", Identifier, Parameters, ":", Suite => ActionFn(1715); + // FuncDef = Decorator+, "async", "def", Identifier, Parameters, ":", Suite => ActionFn(1770); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant24(__symbols); + let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant47(__symbols); - let __sym3 = __pop_Variant22(__symbols); + let __sym4 = __pop_Variant46(__symbols); + let __sym3 = __pop_Variant23(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant60(__symbols); + let __sym0 = __pop_Variant59(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1715::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (7, 146) + let __nt = super::__action1770::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (7, 155) } - pub(crate) fn __reduce391< + pub(crate) fn __reduce414< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = "def", Identifier, TypeParams, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1716); + // FuncDef = "def", Identifier, TypeParams, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1771); assert!(__symbols.len() >= 8); - let __sym7 = __pop_Variant24(__symbols); + let __sym7 = __pop_Variant25(__symbols); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant14(__symbols); + let __sym5 = __pop_Variant15(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant47(__symbols); - let __sym2 = __pop_Variant94(__symbols); - let __sym1 = __pop_Variant22(__symbols); + let __sym3 = __pop_Variant46(__symbols); + let __sym2 = __pop_Variant98(__symbols); + let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = super::__action1716::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (8, 146) + let __nt = super::__action1771::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (8, 155) } - pub(crate) fn __reduce392< + pub(crate) fn __reduce415< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = "def", Identifier, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1717); + // FuncDef = "def", Identifier, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1772); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant24(__symbols); + let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant14(__symbols); + let __sym4 = __pop_Variant15(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant47(__symbols); - let __sym1 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant46(__symbols); + let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1717::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (7, 146) + let __nt = super::__action1772::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (7, 155) } - pub(crate) fn __reduce393< + pub(crate) fn __reduce416< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = Decorator+, "def", Identifier, TypeParams, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1718); + // FuncDef = Decorator+, "def", Identifier, TypeParams, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1773); assert!(__symbols.len() >= 9); - let __sym8 = __pop_Variant24(__symbols); + let __sym8 = __pop_Variant25(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant14(__symbols); + let __sym6 = __pop_Variant15(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant47(__symbols); - let __sym3 = __pop_Variant94(__symbols); - let __sym2 = __pop_Variant22(__symbols); + let __sym4 = __pop_Variant46(__symbols); + let __sym3 = __pop_Variant98(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant60(__symbols); + let __sym0 = __pop_Variant59(__symbols); let __start = __sym0.0; let __end = __sym8.2; - let __nt = super::__action1718::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (9, 146) + let __nt = super::__action1773::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (9, 155) } - pub(crate) fn __reduce394< + pub(crate) fn __reduce417< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = Decorator+, "def", Identifier, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1719); + // FuncDef = Decorator+, "def", Identifier, Parameters, "->", Test<"all">, ":", Suite => ActionFn(1774); assert!(__symbols.len() >= 8); - let __sym7 = __pop_Variant24(__symbols); + let __sym7 = __pop_Variant25(__symbols); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant14(__symbols); + let __sym5 = __pop_Variant15(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant47(__symbols); - let __sym2 = __pop_Variant22(__symbols); + let __sym3 = __pop_Variant46(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant60(__symbols); + let __sym0 = __pop_Variant59(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = super::__action1719::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (8, 146) + let __nt = super::__action1774::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (8, 155) } - pub(crate) fn __reduce395< + pub(crate) fn __reduce418< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = "def", Identifier, TypeParams, Parameters, ":", Suite => ActionFn(1720); + // FuncDef = "def", Identifier, TypeParams, Parameters, ":", Suite => ActionFn(1775); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant24(__symbols); + let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant47(__symbols); - let __sym2 = __pop_Variant94(__symbols); - let __sym1 = __pop_Variant22(__symbols); + let __sym3 = __pop_Variant46(__symbols); + let __sym2 = __pop_Variant98(__symbols); + let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1720::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (6, 146) + let __nt = super::__action1775::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (6, 155) } - pub(crate) fn __reduce396< + pub(crate) fn __reduce419< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = "def", Identifier, Parameters, ":", Suite => ActionFn(1721); + // FuncDef = "def", Identifier, Parameters, ":", Suite => ActionFn(1776); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant24(__symbols); + let __sym4 = __pop_Variant25(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant47(__symbols); - let __sym1 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant46(__symbols); + let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1721::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (5, 146) + let __nt = super::__action1776::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (5, 155) } - pub(crate) fn __reduce397< + pub(crate) fn __reduce420< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = Decorator+, "def", Identifier, TypeParams, Parameters, ":", Suite => ActionFn(1722); + // FuncDef = Decorator+, "def", Identifier, TypeParams, Parameters, ":", Suite => ActionFn(1777); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant24(__symbols); + let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant47(__symbols); - let __sym3 = __pop_Variant94(__symbols); - let __sym2 = __pop_Variant22(__symbols); + let __sym4 = __pop_Variant46(__symbols); + let __sym3 = __pop_Variant98(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant60(__symbols); + let __sym0 = __pop_Variant59(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1722::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (7, 146) + let __nt = super::__action1777::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (7, 155) } - pub(crate) fn __reduce398< + pub(crate) fn __reduce421< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FuncDef = Decorator+, "def", Identifier, Parameters, ":", Suite => ActionFn(1723); + // FuncDef = Decorator+, "def", Identifier, Parameters, ":", Suite => ActionFn(1778); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant24(__symbols); + let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant47(__symbols); - let __sym2 = __pop_Variant22(__symbols); + let __sym3 = __pop_Variant46(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant60(__symbols); + let __sym0 = __pop_Variant59(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1723::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (6, 146) + let __nt = super::__action1778::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (6, 155) } - pub(crate) fn __reduce399< + pub(crate) fn __reduce422< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FunctionArgument = NamedExpressionTest, CompFor => ActionFn(1510); + // FunctionArgument = NamedExpressionTest, CompFor => ActionFn(1549); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant55(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant54(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1510::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant30(__nt), __end)); - (2, 147) + let __nt = super::__action1549::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant31(__nt), __end)); + (2, 156) } - pub(crate) fn __reduce400< + pub(crate) fn __reduce423< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FunctionArgument = NamedExpressionTest => ActionFn(1511); - let __sym0 = __pop_Variant14(__symbols); + // FunctionArgument = NamedExpressionTest => ActionFn(1550); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1511::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant30(__nt), __end)); - (1, 147) + let __nt = super::__action1550::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant31(__nt), __end)); + (1, 156) } - pub(crate) fn __reduce401< + pub(crate) fn __reduce424< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FunctionArgument = Identifier, "=", Test<"all"> => ActionFn(1281); + // FunctionArgument = Identifier, "=", Test<"all"> => ActionFn(1325); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant22(__symbols); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1281::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant30(__nt), __end)); - (3, 147) + let __nt = super::__action1325::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant31(__nt), __end)); + (3, 156) } - pub(crate) fn __reduce402< + pub(crate) fn __reduce425< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FunctionArgument = "*", Test<"all"> => ActionFn(1282); + // FunctionArgument = "*", Test<"all"> => ActionFn(1326); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1282::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant30(__nt), __end)); - (2, 147) + let __nt = super::__action1326::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant31(__nt), __end)); + (2, 156) } - pub(crate) fn __reduce403< + pub(crate) fn __reduce426< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FunctionArgument = "**", Test<"all"> => ActionFn(1283); + // FunctionArgument = "**", Test<"all"> => ActionFn(1327); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1283::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant30(__nt), __end)); - (2, 147) + let __nt = super::__action1327::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant31(__nt), __end)); + (2, 156) } - pub(crate) fn __reduce404< + pub(crate) fn __reduce427< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FunctionArgument? = FunctionArgument => ActionFn(441); - let __sym0 = __pop_Variant30(__symbols); + // FunctionArgument? = FunctionArgument => ActionFn(464); + let __sym0 = __pop_Variant31(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action441::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant69(__nt), __end)); - (1, 148) + let __nt = super::__action464::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant72(__nt), __end)); + (1, 157) } - pub(crate) fn __reduce405< + pub(crate) fn __reduce428< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // FunctionArgument? = => ActionFn(442); + // FunctionArgument? = => ActionFn(465); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action442::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant69(__nt), __end)); - (0, 148) + let __nt = super::__action465::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant72(__nt), __end)); + (0, 157) } - pub(crate) fn __reduce406< + pub(crate) fn __reduce429< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // GenericList = OneOrMore, "," => ActionFn(1284); + // GenericList = OneOrMore, "," => ActionFn(1328); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant32(__symbols); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1284::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 149) + let __nt = super::__action1328::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 158) } - pub(crate) fn __reduce407< + pub(crate) fn __reduce430< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // GenericList = OneOrMore => ActionFn(1285); - let __sym0 = __pop_Variant32(__symbols); + // GenericList = OneOrMore => ActionFn(1329); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1285::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 149) + let __nt = super::__action1329::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 158) } - pub(crate) fn __reduce408< + pub(crate) fn __reduce431< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // GenericList = OneOrMore, "," => ActionFn(1286); + // GenericList = OneOrMore, "," => ActionFn(1330); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant32(__symbols); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1286::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 150) + let __nt = super::__action1330::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 159) } - pub(crate) fn __reduce409< + pub(crate) fn __reduce432< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // GenericList = OneOrMore => ActionFn(1287); - let __sym0 = __pop_Variant32(__symbols); + // GenericList = OneOrMore => ActionFn(1331); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1287::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 150) + let __nt = super::__action1331::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 159) } - pub(crate) fn __reduce410< + pub(crate) fn __reduce433< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // GlobalStatement = "global", OneOrMore => ActionFn(1288); + // GlobalStatement = "global", OneOrMore => ActionFn(1332); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant79(__symbols); + let __sym1 = __pop_Variant82(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1288::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (2, 151) + let __nt = super::__action1332::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (2, 160) } - pub(crate) fn __reduce411< + pub(crate) fn __reduce434< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -24747,261 +26059,275 @@ mod __parse__Top { { // Guard = "if", NamedExpressionTest => ActionFn(89); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action89::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant45(__nt), __end)); - (2, 152) + let __nt = super::__action89::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (2, 161) } - pub(crate) fn __reduce412< + pub(crate) fn __reduce435< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Identifier = name => ActionFn(1289); - let __sym0 = __pop_Variant5(__symbols); + // Identifier = name => ActionFn(1333); + let __sym0 = __pop_Variant6(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1289::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant22(__nt), __end)); - (1, 153) + let __nt = super::__action1333::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant23(__nt), __end)); + (1, 162) } - pub(crate) fn __reduce413< + pub(crate) fn __reduce436< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // IfStatement = "if", NamedExpressionTest, ":", Suite, "else", ":", Suite => ActionFn(1121); + // IfStatement = "if", NamedExpressionTest, ":", Suite, "else", ":", Suite => ActionFn(1152); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant24(__symbols); + let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1121::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (7, 154) + let __nt = super::__action1152::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (7, 163) } - pub(crate) fn __reduce414< + pub(crate) fn __reduce437< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // IfStatement = "if", NamedExpressionTest, ":", Suite => ActionFn(1122); + // IfStatement = "if", NamedExpressionTest, ":", Suite => ActionFn(1153); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1122::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (4, 154) + let __nt = super::__action1153::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (4, 163) } - pub(crate) fn __reduce415< + pub(crate) fn __reduce438< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // IfStatement = "if", NamedExpressionTest, ":", Suite, (<@L> "elif" ":" )+, "else", ":", Suite => ActionFn(1123); + // IfStatement = "if", NamedExpressionTest, ":", Suite, (<@L> "elif" ":" )+, "else", ":", Suite => ActionFn(1154); assert!(__symbols.len() >= 8); - let __sym7 = __pop_Variant24(__symbols); + let __sym7 = __pop_Variant25(__symbols); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant27(__symbols); - let __sym3 = __pop_Variant24(__symbols); + let __sym4 = __pop_Variant28(__symbols); + let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = super::__action1123::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (8, 154) + let __nt = super::__action1154::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (8, 163) } - pub(crate) fn __reduce416< + pub(crate) fn __reduce439< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // IfStatement = "if", NamedExpressionTest, ":", Suite, (<@L> "elif" ":" )+ => ActionFn(1124); + // IfStatement = "if", NamedExpressionTest, ":", Suite, (<@L> "elif" ":" )+ => ActionFn(1155); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant27(__symbols); - let __sym3 = __pop_Variant24(__symbols); + let __sym4 = __pop_Variant28(__symbols); + let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1124::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (5, 154) + let __nt = super::__action1155::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (5, 163) } - pub(crate) fn __reduce417< + pub(crate) fn __reduce440< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportAsAlias = DottedName, "as", Identifier => ActionFn(1290); + // ImportAsAlias = DottedName, "as", Identifier => ActionFn(1334); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant22(__symbols); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1290::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant70(__nt), __end)); - (3, 155) + let __nt = super::__action1334::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant73(__nt), __end)); + (3, 164) } - pub(crate) fn __reduce418< + pub(crate) fn __reduce441< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportAsAlias = DottedName => ActionFn(1291); - let __sym0 = __pop_Variant22(__symbols); + // ImportAsAlias = DottedName => ActionFn(1335); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1291::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant70(__nt), __end)); - (1, 155) + let __nt = super::__action1335::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant73(__nt), __end)); + (1, 164) } - pub(crate) fn __reduce419< + pub(crate) fn __reduce442< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportAsAlias = Identifier, "as", Identifier => ActionFn(1292); + // ImportAsAlias = Identifier, "as", Identifier => ActionFn(1336); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant22(__symbols); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1292::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant70(__nt), __end)); - (3, 156) + let __nt = super::__action1336::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant73(__nt), __end)); + (3, 165) } - pub(crate) fn __reduce420< + pub(crate) fn __reduce443< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportAsAlias = Identifier => ActionFn(1293); - let __sym0 = __pop_Variant22(__symbols); + // ImportAsAlias = Identifier => ActionFn(1337); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1293::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant70(__nt), __end)); - (1, 156) + let __nt = super::__action1337::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant73(__nt), __end)); + (1, 165) } - pub(crate) fn __reduce421< + pub(crate) fn __reduce444< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportAsNames = OneOrMore> => ActionFn(1294); - let __sym0 = __pop_Variant71(__symbols); + // ImportAsNames = OneOrMore> => ActionFn(1338); + let __sym0 = __pop_Variant74(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1294::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant71(__nt), __end)); - (1, 157) + let __nt = super::__action1338::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant74(__nt), __end)); + (1, 166) } - pub(crate) fn __reduce422< + pub(crate) fn __reduce445< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportAsNames = "(", OneOrMore>, ",", ")" => ActionFn(1295); + // ImportAsNames = "(", OneOrMore>, ",", ")" => ActionFn(1339); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant71(__symbols); + let __sym1 = __pop_Variant74(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1295::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant71(__nt), __end)); - (4, 157) + let __nt = super::__action1339::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant74(__nt), __end)); + (4, 166) } - pub(crate) fn __reduce423< + pub(crate) fn __reduce446< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportAsNames = "(", OneOrMore>, ")" => ActionFn(1296); + // ImportAsNames = "(", OneOrMore>, ")" => ActionFn(1340); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant71(__symbols); + let __sym1 = __pop_Variant74(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1296::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant71(__nt), __end)); - (3, 157) + let __nt = super::__action1340::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant74(__nt), __end)); + (3, 166) } - pub(crate) fn __reduce424< + pub(crate) fn __reduce447< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportAsNames = "*" => ActionFn(1297); + // ImportAsNames = "*" => ActionFn(1341); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1297::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant71(__nt), __end)); - (1, 157) + let __nt = super::__action1341::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant74(__nt), __end)); + (1, 166) } - pub(crate) fn __reduce425< + pub(crate) fn __reduce448< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -25012,12 +26338,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action64::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant72(__nt), __end)); - (1, 158) + let __nt = super::__action64::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant75(__nt), __end)); + (1, 167) } - pub(crate) fn __reduce426< + pub(crate) fn __reduce449< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -25028,111 +26355,118 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action65::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant72(__nt), __end)); - (1, 158) + let __nt = super::__action65::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant75(__nt), __end)); + (1, 167) } - pub(crate) fn __reduce427< + pub(crate) fn __reduce450< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportDots* = => ActionFn(367); + // ImportDots* = => ActionFn(388); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action367::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant73(__nt), __end)); - (0, 159) + let __nt = super::__action388::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant76(__nt), __end)); + (0, 168) } - pub(crate) fn __reduce428< + pub(crate) fn __reduce451< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportDots* = ImportDots+ => ActionFn(368); - let __sym0 = __pop_Variant73(__symbols); + // ImportDots* = ImportDots+ => ActionFn(389); + let __sym0 = __pop_Variant76(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action368::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant73(__nt), __end)); - (1, 159) + let __nt = super::__action389::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant76(__nt), __end)); + (1, 168) } - pub(crate) fn __reduce429< + pub(crate) fn __reduce452< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportDots+ = ImportDots => ActionFn(365); - let __sym0 = __pop_Variant72(__symbols); + // ImportDots+ = ImportDots => ActionFn(386); + let __sym0 = __pop_Variant75(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action365::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant73(__nt), __end)); - (1, 160) + let __nt = super::__action386::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant76(__nt), __end)); + (1, 169) } - pub(crate) fn __reduce430< + pub(crate) fn __reduce453< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportDots+ = ImportDots+, ImportDots => ActionFn(366); + // ImportDots+ = ImportDots+, ImportDots => ActionFn(387); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant72(__symbols); - let __sym0 = __pop_Variant73(__symbols); + let __sym1 = __pop_Variant75(__symbols); + let __sym0 = __pop_Variant76(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action366::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant73(__nt), __end)); - (2, 160) + let __nt = super::__action387::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant76(__nt), __end)); + (2, 169) } - pub(crate) fn __reduce431< + pub(crate) fn __reduce454< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportFromLocation = DottedName => ActionFn(1542); - let __sym0 = __pop_Variant22(__symbols); + // ImportFromLocation = DottedName => ActionFn(1597); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1542::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant74(__nt), __end)); - (1, 161) + let __nt = super::__action1597::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant77(__nt), __end)); + (1, 170) } - pub(crate) fn __reduce432< + pub(crate) fn __reduce455< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportFromLocation = ImportDots+, DottedName => ActionFn(1543); + // ImportFromLocation = ImportDots+, DottedName => ActionFn(1598); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant22(__symbols); - let __sym0 = __pop_Variant73(__symbols); + let __sym1 = __pop_Variant23(__symbols); + let __sym0 = __pop_Variant76(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1543::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant74(__nt), __end)); - (2, 161) + let __nt = super::__action1598::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant77(__nt), __end)); + (2, 170) } - pub(crate) fn __reduce433< + pub(crate) fn __reduce456< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -25140,266 +26474,282 @@ mod __parse__Top { ) -> (usize, usize) { // ImportFromLocation = ImportDots+ => ActionFn(63); - let __sym0 = __pop_Variant73(__symbols); + let __sym0 = __pop_Variant76(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action63::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant74(__nt), __end)); - (1, 161) + let __nt = super::__action63::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant77(__nt), __end)); + (1, 170) } - pub(crate) fn __reduce434< + pub(crate) fn __reduce457< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportStatement = "import", OneOrMore> => ActionFn(1298); + // ImportStatement = "import", OneOrMore> => ActionFn(1342); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant71(__symbols); + let __sym1 = __pop_Variant74(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1298::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (2, 162) + let __nt = super::__action1342::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (2, 171) } - pub(crate) fn __reduce435< + pub(crate) fn __reduce458< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ImportStatement = "from", ImportFromLocation, "import", ImportAsNames => ActionFn(1299); + // ImportStatement = "from", ImportFromLocation, "import", ImportAsNames => ActionFn(1343); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant71(__symbols); + let __sym3 = __pop_Variant74(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant74(__symbols); + let __sym1 = __pop_Variant77(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1299::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (4, 162) + let __nt = super::__action1343::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (4, 171) } - pub(crate) fn __reduce439< + pub(crate) fn __reduce462< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // KwargParameter = "**", DoubleStarTypedParameter => ActionFn(1532); + // KwargParameter = "**", DoubleStarTypedParameter => ActionFn(1571); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant65(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1532::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant8(__nt), __end)); - (2, 166) + let __nt = super::__action1571::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (2, 175) } - pub(crate) fn __reduce440< + pub(crate) fn __reduce463< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // KwargParameter = "**" => ActionFn(1533); + // KwargParameter = "**" => ActionFn(1572); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1533::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant8(__nt), __end)); - (1, 166) + let __nt = super::__action1572::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 175) } - pub(crate) fn __reduce441< + pub(crate) fn __reduce464< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // KwargParameter = "**", StarUntypedParameter => ActionFn(985); + // KwargParameter = "**", StarUntypedParameter => ActionFn(1016); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant65(__symbols); + let __sym1 = __pop_Variant64(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action985::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant8(__nt), __end)); - (2, 167) + let __nt = super::__action1016::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (2, 176) } - pub(crate) fn __reduce442< + pub(crate) fn __reduce465< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // KwargParameter = "**" => ActionFn(986); + // KwargParameter = "**" => ActionFn(1017); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action986::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant8(__nt), __end)); - (1, 167) + let __nt = super::__action1017::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 176) } - pub(crate) fn __reduce445< + pub(crate) fn __reduce470< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ListLiteralValues = OneOrMore, "," => ActionFn(599); + // ListLiteralValues = OneOrMore, "," => ActionFn(622); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant32(__symbols); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action599::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (2, 169) + let __nt = super::__action622::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (2, 178) } - pub(crate) fn __reduce446< + pub(crate) fn __reduce471< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ListLiteralValues = OneOrMore => ActionFn(600); - let __sym0 = __pop_Variant32(__symbols); + // ListLiteralValues = OneOrMore => ActionFn(623); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action600::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (1, 169) + let __nt = super::__action623::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (1, 178) } - pub(crate) fn __reduce447< + pub(crate) fn __reduce472< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ListLiteralValues? = ListLiteralValues => ActionFn(549); - let __sym0 = __pop_Variant32(__symbols); + // ListLiteralValues? = ListLiteralValues => ActionFn(572); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action549::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant33(__nt), __end)); - (1, 170) + let __nt = super::__action572::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant34(__nt), __end)); + (1, 179) } - pub(crate) fn __reduce448< + pub(crate) fn __reduce473< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ListLiteralValues? = => ActionFn(550); + // ListLiteralValues? = => ActionFn(573); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action550::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant33(__nt), __end)); - (0, 170) + let __nt = super::__action573::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant34(__nt), __end)); + (0, 179) } - pub(crate) fn __reduce449< + pub(crate) fn __reduce474< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // LiteralPattern = "None" => ActionFn(1304); + // LiteralPattern = "None" => ActionFn(1348); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1304::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 171) + let __nt = super::__action1348::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 180) } - pub(crate) fn __reduce450< + pub(crate) fn __reduce475< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // LiteralPattern = "True" => ActionFn(1305); + // LiteralPattern = "True" => ActionFn(1349); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1305::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 171) + let __nt = super::__action1349::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 180) } - pub(crate) fn __reduce451< + pub(crate) fn __reduce476< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // LiteralPattern = "False" => ActionFn(1306); + // LiteralPattern = "False" => ActionFn(1350); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1306::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 171) + let __nt = super::__action1350::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 180) } - pub(crate) fn __reduce452< + pub(crate) fn __reduce477< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // LiteralPattern = ConstantExpr => ActionFn(1307); - let __sym0 = __pop_Variant14(__symbols); + // LiteralPattern = ConstantExpr => ActionFn(1351); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1307::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 171) + let __nt = super::__action1351::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 180) } - pub(crate) fn __reduce453< + pub(crate) fn __reduce478< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // LiteralPattern = AddOpExpr => ActionFn(1308); - let __sym0 = __pop_Variant14(__symbols); + // LiteralPattern = AddOpExpr => ActionFn(1352); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1308::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 171) + let __nt = super::__action1352::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 180) } - pub(crate) fn __reduce455< + pub(crate) fn __reduce480< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -25407,15 +26757,16 @@ mod __parse__Top { ) -> (usize, usize) { // MappingKey = MatchNameOrAttr => ActionFn(126); - let __sym0 = __pop_Variant45(__symbols); + let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action126::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant45(__nt), __end)); - (1, 172) + let __nt = super::__action126::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (1, 181) } - pub(crate) fn __reduce456< + pub(crate) fn __reduce481< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -25423,15 +26774,16 @@ mod __parse__Top { ) -> (usize, usize) { // MappingKey = ConstantExpr => ActionFn(127); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action127::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant45(__nt), __end)); - (1, 172) + let __nt = super::__action127::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (1, 181) } - pub(crate) fn __reduce457< + pub(crate) fn __reduce482< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -25439,300 +26791,316 @@ mod __parse__Top { ) -> (usize, usize) { // MappingKey = AddOpExpr => ActionFn(128); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action128::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant45(__nt), __end)); - (1, 172) + let __nt = super::__action128::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (1, 181) } - pub(crate) fn __reduce458< + pub(crate) fn __reduce483< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingKey = "None" => ActionFn(1310); + // MappingKey = "None" => ActionFn(1354); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1310::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant45(__nt), __end)); - (1, 172) + let __nt = super::__action1354::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (1, 181) } - pub(crate) fn __reduce459< + pub(crate) fn __reduce484< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingKey = "True" => ActionFn(1311); + // MappingKey = "True" => ActionFn(1355); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1311::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant45(__nt), __end)); - (1, 172) + let __nt = super::__action1355::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (1, 181) } - pub(crate) fn __reduce460< + pub(crate) fn __reduce485< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingKey = "False" => ActionFn(1312); + // MappingKey = "False" => ActionFn(1356); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1312::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant45(__nt), __end)); - (1, 172) + let __nt = super::__action1356::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (1, 181) } - pub(crate) fn __reduce462< + pub(crate) fn __reduce487< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingPattern = "{", "}" => ActionFn(1313); + // MappingPattern = "{", "}" => ActionFn(1358); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1313::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (2, 173) + let __nt = super::__action1358::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (2, 182) } - pub(crate) fn __reduce463< + pub(crate) fn __reduce488< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingPattern = "{", OneOrMore, ",", "}" => ActionFn(1314); + // MappingPattern = "{", OneOrMore, ",", "}" => ActionFn(1359); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant81(__symbols); + let __sym1 = __pop_Variant84(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1314::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (4, 173) + let __nt = super::__action1359::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (4, 182) } - pub(crate) fn __reduce464< + pub(crate) fn __reduce489< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingPattern = "{", OneOrMore, "}" => ActionFn(1315); + // MappingPattern = "{", OneOrMore, "}" => ActionFn(1360); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant81(__symbols); + let __sym1 = __pop_Variant84(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1315::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (3, 173) + let __nt = super::__action1360::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (3, 182) } - pub(crate) fn __reduce465< + pub(crate) fn __reduce490< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingPattern = "{", "**", Identifier, ",", "}" => ActionFn(1316); + // MappingPattern = "{", "**", Identifier, ",", "}" => ActionFn(1361); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1316::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (5, 173) + let __nt = super::__action1361::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (5, 182) } - pub(crate) fn __reduce466< + pub(crate) fn __reduce491< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingPattern = "{", "**", Identifier, "}" => ActionFn(1317); + // MappingPattern = "{", "**", Identifier, "}" => ActionFn(1362); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1317::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (4, 173) + let __nt = super::__action1362::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (4, 182) } - pub(crate) fn __reduce467< + pub(crate) fn __reduce492< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingPattern = "{", OneOrMore, ",", "**", Identifier, ",", "}" => ActionFn(1318); + // MappingPattern = "{", OneOrMore, ",", "**", Identifier, ",", "}" => ActionFn(1363); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant22(__symbols); + let __sym4 = __pop_Variant23(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant81(__symbols); + let __sym1 = __pop_Variant84(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1318::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (7, 173) + let __nt = super::__action1363::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (7, 182) } - pub(crate) fn __reduce468< + pub(crate) fn __reduce493< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MappingPattern = "{", OneOrMore, ",", "**", Identifier, "}" => ActionFn(1319); + // MappingPattern = "{", OneOrMore, ",", "**", Identifier, "}" => ActionFn(1364); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant22(__symbols); + let __sym4 = __pop_Variant23(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant81(__symbols); + let __sym1 = __pop_Variant84(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1319::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (6, 173) + let __nt = super::__action1364::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (6, 182) } - pub(crate) fn __reduce469< + pub(crate) fn __reduce494< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchCase = "case", Patterns, Guard, ":", Suite => ActionFn(1483); + // MatchCase = "case", Patterns, Guard, ":", Suite => ActionFn(1220); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant24(__symbols); + let __sym4 = __pop_Variant25(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant45(__symbols); - let __sym1 = __pop_Variant34(__symbols); + let __sym2 = __pop_Variant44(__symbols); + let __sym1 = __pop_Variant35(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1483::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant75(__nt), __end)); - (5, 174) + let __nt = super::__action1220::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant78(__nt), __end)); + (5, 183) } - pub(crate) fn __reduce470< + pub(crate) fn __reduce495< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchCase = "case", Patterns, ":", Suite => ActionFn(1484); + // MatchCase = "case", Patterns, ":", Suite => ActionFn(1221); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant34(__symbols); + let __sym1 = __pop_Variant35(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1484::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant75(__nt), __end)); - (4, 174) + let __nt = super::__action1221::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant78(__nt), __end)); + (4, 183) } - pub(crate) fn __reduce471< + pub(crate) fn __reduce496< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchCase+ = MatchCase => ActionFn(345); - let __sym0 = __pop_Variant75(__symbols); + // MatchCase+ = MatchCase => ActionFn(366); + let __sym0 = __pop_Variant78(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action345::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant76(__nt), __end)); - (1, 175) + let __nt = super::__action366::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant79(__nt), __end)); + (1, 184) } - pub(crate) fn __reduce472< + pub(crate) fn __reduce497< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchCase+ = MatchCase+, MatchCase => ActionFn(346); + // MatchCase+ = MatchCase+, MatchCase => ActionFn(367); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant75(__symbols); - let __sym0 = __pop_Variant76(__symbols); + let __sym1 = __pop_Variant78(__symbols); + let __sym0 = __pop_Variant79(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action346::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant76(__nt), __end)); - (2, 175) + let __nt = super::__action367::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant79(__nt), __end)); + (2, 184) } - pub(crate) fn __reduce473< + pub(crate) fn __reduce498< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchKeywordEntry = Identifier, "=", Pattern => ActionFn(1320); + // MatchKeywordEntry = Identifier, "=", Pattern => ActionFn(1365); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant34(__symbols); + let __sym2 = __pop_Variant35(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant22(__symbols); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1320::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant77(__nt), __end)); - (3, 176) + let __nt = super::__action1365::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant80(__nt), __end)); + (3, 185) } - pub(crate) fn __reduce474< + pub(crate) fn __reduce499< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -25741,165 +27109,173 @@ mod __parse__Top { { // MatchMappingEntry = MappingKey, ":", Pattern => ActionFn(133); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant34(__symbols); + let __sym2 = __pop_Variant35(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant45(__symbols); + let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action133::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant78(__nt), __end)); - (3, 177) + let __nt = super::__action133::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant81(__nt), __end)); + (3, 186) } - pub(crate) fn __reduce475< + pub(crate) fn __reduce500< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchName = Identifier => ActionFn(1321); - let __sym0 = __pop_Variant22(__symbols); + // MatchName = Identifier => ActionFn(1366); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1321::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant45(__nt), __end)); - (1, 178) + let __nt = super::__action1366::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (1, 187) } - pub(crate) fn __reduce476< + pub(crate) fn __reduce501< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchNameOrAttr = MatchName, ".", Identifier => ActionFn(1322); + // MatchNameOrAttr = MatchName, ".", Identifier => ActionFn(1367); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant45(__symbols); + let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1322::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant45(__nt), __end)); - (3, 179) + let __nt = super::__action1367::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (3, 188) } - pub(crate) fn __reduce477< + pub(crate) fn __reduce502< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchNameOrAttr = MatchNameOrAttr, ".", Identifier => ActionFn(1323); + // MatchNameOrAttr = MatchNameOrAttr, ".", Identifier => ActionFn(1368); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant45(__symbols); + let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1323::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant45(__nt), __end)); - (3, 179) + let __nt = super::__action1368::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (3, 188) } - pub(crate) fn __reduce478< + pub(crate) fn __reduce503< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchStatement = "match", TestOrStarNamedExpr, ":", "\n", Indent, MatchCase+, Dedent => ActionFn(833); + // MatchStatement = "match", TestOrStarNamedExpr, ":", "\n", Indent, MatchCase+, Dedent => ActionFn(863); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant76(__symbols); + let __sym5 = __pop_Variant79(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action833::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (7, 180) + let __nt = super::__action863::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (7, 189) } - pub(crate) fn __reduce479< + pub(crate) fn __reduce504< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchStatement = "match", TestOrStarNamedExpr, ",", ":", "\n", Indent, MatchCase+, Dedent => ActionFn(834); + // MatchStatement = "match", TestOrStarNamedExpr, ",", ":", "\n", Indent, MatchCase+, Dedent => ActionFn(1369); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant76(__symbols); + let __sym6 = __pop_Variant79(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = super::__action834::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (8, 180) + let __nt = super::__action1369::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (8, 189) } - pub(crate) fn __reduce480< + pub(crate) fn __reduce505< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchStatement = "match", TwoOrMore, ",", ":", "\n", Indent, MatchCase+, Dedent => ActionFn(835); + // MatchStatement = "match", TwoOrMore, ",", ":", "\n", Indent, MatchCase+, Dedent => ActionFn(1370); assert!(__symbols.len() >= 8); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant76(__symbols); + let __sym6 = __pop_Variant79(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym7.2; - let __nt = super::__action835::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (8, 180) + let __nt = super::__action1370::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (8, 189) } - pub(crate) fn __reduce481< + pub(crate) fn __reduce506< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // MatchStatement = "match", TwoOrMore, ":", "\n", Indent, MatchCase+, Dedent => ActionFn(836); + // MatchStatement = "match", TwoOrMore, ":", "\n", Indent, MatchCase+, Dedent => ActionFn(1371); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant76(__symbols); + let __sym5 = __pop_Variant79(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action836::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (7, 180) + let __nt = super::__action1371::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (7, 189) } - pub(crate) fn __reduce482< + pub(crate) fn __reduce507< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -25910,12 +27286,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action198::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 181) + let __nt = super::__action198::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 190) } - pub(crate) fn __reduce483< + pub(crate) fn __reduce508< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -25926,12 +27303,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action199::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 181) + let __nt = super::__action199::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 190) } - pub(crate) fn __reduce484< + pub(crate) fn __reduce509< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -25942,12 +27320,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action200::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 181) + let __nt = super::__action200::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 190) } - pub(crate) fn __reduce485< + pub(crate) fn __reduce510< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -25958,12 +27337,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action201::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 181) + let __nt = super::__action201::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 190) } - pub(crate) fn __reduce486< + pub(crate) fn __reduce511< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -25974,47 +27354,50 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action202::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 181) + let __nt = super::__action202::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 190) } - pub(crate) fn __reduce487< + pub(crate) fn __reduce512< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NamedExpression = NamedExpressionName, ":=", Test<"all"> => ActionFn(1324); + // NamedExpression = NamedExpressionName, ":=", Test<"all"> => ActionFn(1372); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1324::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 182) + let __nt = super::__action1372::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 191) } - pub(crate) fn __reduce488< + pub(crate) fn __reduce513< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NamedExpressionName = Identifier => ActionFn(1325); - let __sym0 = __pop_Variant22(__symbols); + // NamedExpressionName = Identifier => ActionFn(1373); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1325::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 183) + let __nt = super::__action1373::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 192) } - pub(crate) fn __reduce489< + pub(crate) fn __reduce514< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -26022,15 +27405,16 @@ mod __parse__Top { ) -> (usize, usize) { // NamedExpressionTest = NamedExpression => ActionFn(179); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action179::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 184) + let __nt = super::__action179::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 193) } - pub(crate) fn __reduce490< + pub(crate) fn __reduce515< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -26038,15 +27422,16 @@ mod __parse__Top { ) -> (usize, usize) { // NamedExpressionTest = Test<"all"> => ActionFn(180); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action180::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 184) + let __nt = super::__action180::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 193) } - pub(crate) fn __reduce491< + pub(crate) fn __reduce516< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -26054,15 +27439,16 @@ mod __parse__Top { ) -> (usize, usize) { // NamedOrStarExpr = NamedExpression => ActionFn(36); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action36::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 185) + let __nt = super::__action36::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 194) } - pub(crate) fn __reduce492< + pub(crate) fn __reduce517< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -26070,671 +27456,709 @@ mod __parse__Top { ) -> (usize, usize) { // NamedOrStarExpr = StarExpr => ActionFn(37); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action37::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 185) + let __nt = super::__action37::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 194) } - pub(crate) fn __reduce493< + pub(crate) fn __reduce518< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NonlocalStatement = "nonlocal", OneOrMore => ActionFn(1326); + // NonlocalStatement = "nonlocal", OneOrMore => ActionFn(1374); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant79(__symbols); + let __sym1 = __pop_Variant82(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1326::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (2, 186) + let __nt = super::__action1374::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (2, 195) } - pub(crate) fn __reduce494< + pub(crate) fn __reduce519< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NotTest<"all"> = "not", NotTest<"all"> => ActionFn(1327); + // NotTest<"all"> = "not", NotTest<"all"> => ActionFn(1375); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1327::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 187) + let __nt = super::__action1375::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 196) } - pub(crate) fn __reduce495< + pub(crate) fn __reduce520< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NotTest<"all"> = Comparison<"all"> => ActionFn(452); - let __sym0 = __pop_Variant14(__symbols); + // NotTest<"all"> = Comparison<"all"> => ActionFn(475); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action452::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 187) + let __nt = super::__action475::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 196) } - pub(crate) fn __reduce496< + pub(crate) fn __reduce521< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NotTest<"no-withitems"> = "not", NotTest<"all"> => ActionFn(1328); + // NotTest<"no-withitems"> = "not", NotTest<"all"> => ActionFn(1376); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1328::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 188) + let __nt = super::__action1376::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 197) } - pub(crate) fn __reduce497< + pub(crate) fn __reduce522< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // NotTest<"no-withitems"> = Comparison<"no-withitems"> => ActionFn(495); - let __sym0 = __pop_Variant14(__symbols); + // NotTest<"no-withitems"> = Comparison<"no-withitems"> => ActionFn(518); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action495::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 188) + let __nt = super::__action518::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 197) } - pub(crate) fn __reduce498< + pub(crate) fn __reduce523< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = DictElement => ActionFn(250); - let __sym0 = __pop_Variant61(__symbols); + // OneOrMore = DictElement => ActionFn(260); + let __sym0 = __pop_Variant60(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action250::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant63(__nt), __end)); - (1, 189) + let __nt = super::__action260::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant62(__nt), __end)); + (1, 198) } - pub(crate) fn __reduce499< + pub(crate) fn __reduce524< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", DictElement => ActionFn(251); + // OneOrMore = OneOrMore, ",", DictElement => ActionFn(261); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant61(__symbols); + let __sym2 = __pop_Variant60(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant63(__symbols); + let __sym0 = __pop_Variant62(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action251::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant63(__nt), __end)); - (3, 189) + let __nt = super::__action261::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant62(__nt), __end)); + (3, 198) } - pub(crate) fn __reduce500< + pub(crate) fn __reduce525< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = ExpressionOrStarExpression => ActionFn(247); - let __sym0 = __pop_Variant14(__symbols); + // OneOrMore = ExpressionOrStarExpression => ActionFn(257); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action247::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (1, 190) + let __nt = super::__action257::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (1, 199) } - pub(crate) fn __reduce501< + pub(crate) fn __reduce526< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", ExpressionOrStarExpression => ActionFn(248); + // OneOrMore = OneOrMore, ",", ExpressionOrStarExpression => ActionFn(258); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant32(__symbols); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action248::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (3, 190) + let __nt = super::__action258::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (3, 199) } - pub(crate) fn __reduce502< + pub(crate) fn __reduce527< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = Identifier => ActionFn(355); - let __sym0 = __pop_Variant22(__symbols); + // OneOrMore = Identifier => ActionFn(376); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action355::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant79(__nt), __end)); - (1, 191) + let __nt = super::__action376::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant82(__nt), __end)); + (1, 200) } - pub(crate) fn __reduce503< + pub(crate) fn __reduce528< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", Identifier => ActionFn(356); + // OneOrMore = OneOrMore, ",", Identifier => ActionFn(377); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant79(__symbols); + let __sym0 = __pop_Variant82(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action356::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant79(__nt), __end)); - (3, 191) + let __nt = super::__action377::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant82(__nt), __end)); + (3, 200) } - pub(crate) fn __reduce504< + pub(crate) fn __reduce529< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = DottedName, "as", Identifier => ActionFn(1534); + // OneOrMore> = DottedName, "as", Identifier => ActionFn(1589); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant22(__symbols); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1534::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant71(__nt), __end)); - (3, 192) + let __nt = super::__action1589::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant74(__nt), __end)); + (3, 201) } - pub(crate) fn __reduce505< + pub(crate) fn __reduce530< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = DottedName => ActionFn(1535); - let __sym0 = __pop_Variant22(__symbols); + // OneOrMore> = DottedName => ActionFn(1590); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1535::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant71(__nt), __end)); - (1, 192) + let __nt = super::__action1590::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant74(__nt), __end)); + (1, 201) } - pub(crate) fn __reduce506< + pub(crate) fn __reduce531< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = OneOrMore>, ",", DottedName, "as", Identifier => ActionFn(1536); + // OneOrMore> = OneOrMore>, ",", DottedName, "as", Identifier => ActionFn(1591); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant22(__symbols); + let __sym4 = __pop_Variant23(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant71(__symbols); + let __sym0 = __pop_Variant74(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1536::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant71(__nt), __end)); - (5, 192) + let __nt = super::__action1591::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant74(__nt), __end)); + (5, 201) } - pub(crate) fn __reduce507< + pub(crate) fn __reduce532< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = OneOrMore>, ",", DottedName => ActionFn(1537); + // OneOrMore> = OneOrMore>, ",", DottedName => ActionFn(1592); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant71(__symbols); + let __sym0 = __pop_Variant74(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1537::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant71(__nt), __end)); - (3, 192) + let __nt = super::__action1592::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant74(__nt), __end)); + (3, 201) } - pub(crate) fn __reduce508< + pub(crate) fn __reduce533< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = Identifier, "as", Identifier => ActionFn(1538); + // OneOrMore> = Identifier, "as", Identifier => ActionFn(1593); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant22(__symbols); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1538::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant71(__nt), __end)); - (3, 193) + let __nt = super::__action1593::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant74(__nt), __end)); + (3, 202) } - pub(crate) fn __reduce509< + pub(crate) fn __reduce534< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = Identifier => ActionFn(1539); - let __sym0 = __pop_Variant22(__symbols); + // OneOrMore> = Identifier => ActionFn(1594); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1539::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant71(__nt), __end)); - (1, 193) + let __nt = super::__action1594::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant74(__nt), __end)); + (1, 202) } - pub(crate) fn __reduce510< + pub(crate) fn __reduce535< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = OneOrMore>, ",", Identifier, "as", Identifier => ActionFn(1540); + // OneOrMore> = OneOrMore>, ",", Identifier, "as", Identifier => ActionFn(1595); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant22(__symbols); + let __sym4 = __pop_Variant23(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant71(__symbols); + let __sym0 = __pop_Variant74(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1540::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant71(__nt), __end)); - (5, 193) + let __nt = super::__action1595::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant74(__nt), __end)); + (5, 202) } - pub(crate) fn __reduce511< + pub(crate) fn __reduce536< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = OneOrMore>, ",", Identifier => ActionFn(1541); + // OneOrMore> = OneOrMore>, ",", Identifier => ActionFn(1596); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant22(__symbols); + let __sym2 = __pop_Variant23(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant71(__symbols); + let __sym0 = __pop_Variant74(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1541::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant71(__nt), __end)); - (3, 193) + let __nt = super::__action1596::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant74(__nt), __end)); + (3, 202) } - pub(crate) fn __reduce512< + pub(crate) fn __reduce537< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = MatchKeywordEntry => ActionFn(323); - let __sym0 = __pop_Variant77(__symbols); + // OneOrMore = MatchKeywordEntry => ActionFn(343); + let __sym0 = __pop_Variant80(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action323::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant80(__nt), __end)); - (1, 194) + let __nt = super::__action343::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant83(__nt), __end)); + (1, 203) } - pub(crate) fn __reduce513< + pub(crate) fn __reduce538< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", MatchKeywordEntry => ActionFn(324); + // OneOrMore = OneOrMore, ",", MatchKeywordEntry => ActionFn(344); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant77(__symbols); + let __sym2 = __pop_Variant80(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant80(__symbols); + let __sym0 = __pop_Variant83(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action324::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant80(__nt), __end)); - (3, 194) + let __nt = super::__action344::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant83(__nt), __end)); + (3, 203) } - pub(crate) fn __reduce514< + pub(crate) fn __reduce539< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = MatchMappingEntry => ActionFn(327); - let __sym0 = __pop_Variant78(__symbols); + // OneOrMore = MatchMappingEntry => ActionFn(347); + let __sym0 = __pop_Variant81(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action327::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant81(__nt), __end)); - (1, 195) + let __nt = super::__action347::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant84(__nt), __end)); + (1, 204) } - pub(crate) fn __reduce515< + pub(crate) fn __reduce540< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", MatchMappingEntry => ActionFn(328); + // OneOrMore = OneOrMore, ",", MatchMappingEntry => ActionFn(348); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant78(__symbols); + let __sym2 = __pop_Variant81(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant81(__symbols); + let __sym0 = __pop_Variant84(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action328::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant81(__nt), __end)); - (3, 195) + let __nt = super::__action348::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant84(__nt), __end)); + (3, 204) } - pub(crate) fn __reduce516< + pub(crate) fn __reduce541< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = ParameterDef => ActionFn(464); - let __sym0 = __pop_Variant10(__symbols); + // OneOrMore> = ParameterDef => ActionFn(487); + let __sym0 = __pop_Variant11(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action464::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant82(__nt), __end)); - (1, 196) + let __nt = super::__action487::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant85(__nt), __end)); + (1, 205) } - pub(crate) fn __reduce517< + pub(crate) fn __reduce542< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = OneOrMore>, ",", ParameterDef => ActionFn(465); + // OneOrMore> = OneOrMore>, ",", ParameterDef => ActionFn(488); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant10(__symbols); + let __sym2 = __pop_Variant11(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action465::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant82(__nt), __end)); - (3, 196) + let __nt = super::__action488::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant85(__nt), __end)); + (3, 205) } - pub(crate) fn __reduce518< + pub(crate) fn __reduce543< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = ParameterDef => ActionFn(453); - let __sym0 = __pop_Variant10(__symbols); + // OneOrMore> = ParameterDef => ActionFn(476); + let __sym0 = __pop_Variant11(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action453::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant82(__nt), __end)); - (1, 197) + let __nt = super::__action476::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant85(__nt), __end)); + (1, 206) } - pub(crate) fn __reduce519< + pub(crate) fn __reduce544< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = OneOrMore>, ",", ParameterDef => ActionFn(454); + // OneOrMore> = OneOrMore>, ",", ParameterDef => ActionFn(477); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant10(__symbols); + let __sym2 = __pop_Variant11(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action454::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant82(__nt), __end)); - (3, 197) + let __nt = super::__action477::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant85(__nt), __end)); + (3, 206) } - pub(crate) fn __reduce520< + pub(crate) fn __reduce545< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = Pattern => ActionFn(325); - let __sym0 = __pop_Variant34(__symbols); + // OneOrMore = Pattern => ActionFn(345); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action325::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant54(__nt), __end)); - (1, 198) + let __nt = super::__action345::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant53(__nt), __end)); + (1, 207) } - pub(crate) fn __reduce521< + pub(crate) fn __reduce546< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", Pattern => ActionFn(326); + // OneOrMore = OneOrMore, ",", Pattern => ActionFn(346); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant34(__symbols); + let __sym2 = __pop_Variant35(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant54(__symbols); + let __sym0 = __pop_Variant53(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action326::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant54(__nt), __end)); - (3, 198) + let __nt = super::__action346::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant53(__nt), __end)); + (3, 207) } - pub(crate) fn __reduce522< + pub(crate) fn __reduce547< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = Test<"all"> => ActionFn(288); - let __sym0 = __pop_Variant14(__symbols); + // OneOrMore> = Test<"all"> => ActionFn(308); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action288::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (1, 199) + let __nt = super::__action308::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (1, 208) } - pub(crate) fn __reduce523< + pub(crate) fn __reduce548< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore> = OneOrMore>, ",", Test<"all"> => ActionFn(289); + // OneOrMore> = OneOrMore>, ",", Test<"all"> => ActionFn(309); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant32(__symbols); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action289::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (3, 199) + let __nt = super::__action309::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (3, 208) } - pub(crate) fn __reduce524< + pub(crate) fn __reduce549< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = TestOrStarExpr => ActionFn(432); - let __sym0 = __pop_Variant14(__symbols); + // OneOrMore = TestOrStarExpr => ActionFn(455); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action432::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (1, 200) + let __nt = super::__action455::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (1, 209) } - pub(crate) fn __reduce525< + pub(crate) fn __reduce550< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", TestOrStarExpr => ActionFn(433); + // OneOrMore = OneOrMore, ",", TestOrStarExpr => ActionFn(456); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant32(__symbols); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action433::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (3, 200) + let __nt = super::__action456::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (3, 209) } - pub(crate) fn __reduce526< + pub(crate) fn __reduce551< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = TestOrStarNamedExpr => ActionFn(252); - let __sym0 = __pop_Variant14(__symbols); + // OneOrMore = TestOrStarNamedExpr => ActionFn(262); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action252::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (1, 201) + let __nt = super::__action262::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (1, 210) } - pub(crate) fn __reduce527< + pub(crate) fn __reduce552< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", TestOrStarNamedExpr => ActionFn(253); + // OneOrMore = OneOrMore, ",", TestOrStarNamedExpr => ActionFn(263); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant32(__symbols); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action253::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (3, 201) + let __nt = super::__action263::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (3, 210) } - pub(crate) fn __reduce528< + pub(crate) fn __reduce553< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = TypeParam => ActionFn(264); - let __sym0 = __pop_Variant93(__symbols); + // OneOrMore = TypeParam => ActionFn(284); + let __sym0 = __pop_Variant97(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action264::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant83(__nt), __end)); - (1, 202) + let __nt = super::__action284::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant86(__nt), __end)); + (1, 211) } - pub(crate) fn __reduce529< + pub(crate) fn __reduce554< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OneOrMore = OneOrMore, ",", TypeParam => ActionFn(265); + // OneOrMore = OneOrMore, ",", TypeParam => ActionFn(285); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant93(__symbols); + let __sym2 = __pop_Variant97(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant83(__symbols); + let __sym0 = __pop_Variant86(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action265::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant83(__nt), __end)); - (3, 202) + let __nt = super::__action285::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant86(__nt), __end)); + (3, 211) } - pub(crate) fn __reduce530< + pub(crate) fn __reduce555< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -26742,394 +28166,417 @@ mod __parse__Top { ) -> (usize, usize) { // OrPattern = ClosedPattern => ActionFn(96); - let __sym0 = __pop_Variant34(__symbols); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action96::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 203) + let __nt = super::__action96::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 212) } - pub(crate) fn __reduce531< + pub(crate) fn __reduce556< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OrPattern = TwoOrMore => ActionFn(1329); - let __sym0 = __pop_Variant54(__symbols); + // OrPattern = TwoOrMore => ActionFn(1377); + let __sym0 = __pop_Variant53(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1329::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 203) + let __nt = super::__action1377::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 212) } - pub(crate) fn __reduce532< + pub(crate) fn __reduce557< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OrTest<"all"> = (> "or")+, AndTest<"all"> => ActionFn(1330); + // OrTest<"all"> = (> "or")+, AndTest<"all"> => ActionFn(1378); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); - let __sym0 = __pop_Variant16(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1330::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 204) + let __nt = super::__action1378::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 213) } - pub(crate) fn __reduce533< + pub(crate) fn __reduce558< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OrTest<"all"> = AndTest<"all"> => ActionFn(243); - let __sym0 = __pop_Variant14(__symbols); + // OrTest<"all"> = AndTest<"all"> => ActionFn(253); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action243::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 204) + let __nt = super::__action253::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 213) } - pub(crate) fn __reduce534< + pub(crate) fn __reduce559< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OrTest<"no-withitems"> = (> "or")+, AndTest<"all"> => ActionFn(1331); + // OrTest<"no-withitems"> = (> "or")+, AndTest<"all"> => ActionFn(1379); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); - let __sym0 = __pop_Variant16(__symbols); + let __sym1 = __pop_Variant15(__symbols); + let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1331::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 205) + let __nt = super::__action1379::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 214) } - pub(crate) fn __reduce535< + pub(crate) fn __reduce560< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // OrTest<"no-withitems"> = AndTest<"no-withitems"> => ActionFn(478); - let __sym0 = __pop_Variant14(__symbols); + // OrTest<"no-withitems"> = AndTest<"no-withitems"> => ActionFn(501); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action478::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 205) + let __nt = super::__action501::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 214) } - pub(crate) fn __reduce536< + pub(crate) fn __reduce561< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDef = TypedParameter => ActionFn(471); - let __sym0 = __pop_Variant10(__symbols); + // ParameterDef = TypedParameter => ActionFn(494); + let __sym0 = __pop_Variant11(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action471::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant10(__nt), __end)); - (1, 206) + let __nt = super::__action494::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (1, 215) } - pub(crate) fn __reduce537< + pub(crate) fn __reduce562< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDef = TypedParameter, "=", Test<"all"> => ActionFn(1332); + // ParameterDef = TypedParameter, "=", Test<"all"> => ActionFn(1380); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant10(__symbols); + let __sym0 = __pop_Variant11(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1332::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant10(__nt), __end)); - (3, 206) + let __nt = super::__action1380::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (3, 215) } - pub(crate) fn __reduce538< + pub(crate) fn __reduce563< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDef = UntypedParameter => ActionFn(460); - let __sym0 = __pop_Variant10(__symbols); + // ParameterDef = UntypedParameter => ActionFn(483); + let __sym0 = __pop_Variant11(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action460::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant10(__nt), __end)); - (1, 207) + let __nt = super::__action483::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (1, 216) } - pub(crate) fn __reduce539< + pub(crate) fn __reduce564< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDef = UntypedParameter, "=", Test<"all"> => ActionFn(1333); + // ParameterDef = UntypedParameter, "=", Test<"all"> => ActionFn(1381); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant10(__symbols); + let __sym0 = __pop_Variant11(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1333::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant10(__nt), __end)); - (3, 207) + let __nt = super::__action1381::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (3, 216) } - pub(crate) fn __reduce540< + pub(crate) fn __reduce565< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDefs = OneOrMore> => ActionFn(422); - let __sym0 = __pop_Variant82(__symbols); + // ParameterDefs = OneOrMore> => ActionFn(443); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action422::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant84(__nt), __end)); - (1, 208) + let __nt = super::__action443::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant87(__nt), __end)); + (1, 217) } - pub(crate) fn __reduce541< + pub(crate) fn __reduce566< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDefs = OneOrMore>, ",", "/" => ActionFn(673); + // ParameterDefs = OneOrMore>, ",", "/" => ActionFn(698); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action673::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant84(__nt), __end)); - (3, 208) + let __nt = super::__action698::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant87(__nt), __end)); + (3, 217) } - pub(crate) fn __reduce542< + pub(crate) fn __reduce567< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDefs = OneOrMore>, ",", "/", ("," >)+ => ActionFn(674); + // ParameterDefs = OneOrMore>, ",", "/", ("," >)+ => ActionFn(699); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action674::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant84(__nt), __end)); - (4, 208) + let __nt = super::__action699::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant87(__nt), __end)); + (4, 217) } - pub(crate) fn __reduce543< + pub(crate) fn __reduce568< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDefs = OneOrMore> => ActionFn(430); - let __sym0 = __pop_Variant82(__symbols); + // ParameterDefs = OneOrMore> => ActionFn(451); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action430::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant84(__nt), __end)); - (1, 209) + let __nt = super::__action451::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant87(__nt), __end)); + (1, 218) } - pub(crate) fn __reduce544< + pub(crate) fn __reduce569< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDefs = OneOrMore>, ",", "/" => ActionFn(681); + // ParameterDefs = OneOrMore>, ",", "/" => ActionFn(706); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action681::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant84(__nt), __end)); - (3, 209) + let __nt = super::__action706::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant87(__nt), __end)); + (3, 218) } - pub(crate) fn __reduce545< + pub(crate) fn __reduce570< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterDefs = OneOrMore>, ",", "/", ("," >)+ => ActionFn(682); + // ParameterDefs = OneOrMore>, ",", "/", ("," >)+ => ActionFn(707); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant11(__symbols); + let __sym3 = __pop_Variant12(__symbols); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant82(__symbols); + let __sym0 = __pop_Variant85(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action682::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant84(__nt), __end)); - (4, 209) + let __nt = super::__action707::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant87(__nt), __end)); + (4, 218) } - pub(crate) fn __reduce622< + pub(crate) fn __reduce647< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterList = KwargParameter, "," => ActionFn(1370); + // ParameterList = KwargParameter, "," => ActionFn(1418); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant8(__symbols); + let __sym0 = __pop_Variant9(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1370::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (2, 210) + let __nt = super::__action1418::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (2, 219) } - pub(crate) fn __reduce623< + pub(crate) fn __reduce648< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterList = KwargParameter => ActionFn(1371); - let __sym0 = __pop_Variant8(__symbols); + // ParameterList = KwargParameter => ActionFn(1419); + let __sym0 = __pop_Variant9(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1371::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (1, 210) + let __nt = super::__action1419::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (1, 219) } - pub(crate) fn __reduce700< + pub(crate) fn __reduce725< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterList = KwargParameter, "," => ActionFn(1408); + // ParameterList = KwargParameter, "," => ActionFn(1456); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant8(__symbols); + let __sym0 = __pop_Variant9(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1408::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (2, 211) + let __nt = super::__action1456::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (2, 220) } - pub(crate) fn __reduce701< + pub(crate) fn __reduce726< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterList = KwargParameter => ActionFn(1409); - let __sym0 = __pop_Variant8(__symbols); + // ParameterList = KwargParameter => ActionFn(1457); + let __sym0 = __pop_Variant9(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1409::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant47(__nt), __end)); - (1, 211) + let __nt = super::__action1457::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant46(__nt), __end)); + (1, 220) } - pub(crate) fn __reduce702< + pub(crate) fn __reduce727< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterList? = ParameterList => ActionFn(258); - let __sym0 = __pop_Variant47(__symbols); + // ParameterList? = ParameterList => ActionFn(278); + let __sym0 = __pop_Variant46(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action258::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant48(__nt), __end)); - (1, 212) + let __nt = super::__action278::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant47(__nt), __end)); + (1, 221) } - pub(crate) fn __reduce703< + pub(crate) fn __reduce728< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ParameterList? = => ActionFn(259); + // ParameterList? = => ActionFn(279); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action259::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant48(__nt), __end)); - (0, 212) + let __nt = super::__action279::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant47(__nt), __end)); + (0, 221) } - pub(crate) fn __reduce722< + pub(crate) fn __reduce747< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // PassStatement = "pass" => ActionFn(1411); + // PassStatement = "pass" => ActionFn(1460); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1411::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 216) + let __nt = super::__action1460::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 225) } - pub(crate) fn __reduce723< + pub(crate) fn __reduce748< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -27137,15 +28584,16 @@ mod __parse__Top { ) -> (usize, usize) { // Pattern = AsPattern => ActionFn(93); - let __sym0 = __pop_Variant34(__symbols); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action93::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 217) + let __nt = super::__action93::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 226) } - pub(crate) fn __reduce724< + pub(crate) fn __reduce749< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -27153,237 +28601,250 @@ mod __parse__Top { ) -> (usize, usize) { // Pattern = OrPattern => ActionFn(94); - let __sym0 = __pop_Variant34(__symbols); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action94::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 217) + let __nt = super::__action94::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 226) } - pub(crate) fn __reduce725< + pub(crate) fn __reduce750< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Pattern? = Pattern => ActionFn(405); - let __sym0 = __pop_Variant34(__symbols); + // Pattern? = Pattern => ActionFn(426); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action405::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant85(__nt), __end)); - (1, 218) + let __nt = super::__action426::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant88(__nt), __end)); + (1, 227) } - pub(crate) fn __reduce726< + pub(crate) fn __reduce751< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Pattern? = => ActionFn(406); + // Pattern? = => ActionFn(427); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action406::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant85(__nt), __end)); - (0, 218) + let __nt = super::__action427::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant88(__nt), __end)); + (0, 227) } - pub(crate) fn __reduce727< + pub(crate) fn __reduce752< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // PatternArguments = "(", OneOrMore, ",", OneOrMore, ",", ")" => ActionFn(1412); + // PatternArguments = "(", OneOrMore, ",", OneOrMore, ",", ")" => ActionFn(1461); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant80(__symbols); + let __sym3 = __pop_Variant83(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant54(__symbols); + let __sym1 = __pop_Variant53(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1412::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant86(__nt), __end)); - (6, 219) + let __nt = super::__action1461::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant89(__nt), __end)); + (6, 228) } - pub(crate) fn __reduce728< + pub(crate) fn __reduce753< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // PatternArguments = "(", OneOrMore, ",", OneOrMore, ")" => ActionFn(1413); + // PatternArguments = "(", OneOrMore, ",", OneOrMore, ")" => ActionFn(1462); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant80(__symbols); + let __sym3 = __pop_Variant83(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant54(__symbols); + let __sym1 = __pop_Variant53(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1413::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant86(__nt), __end)); - (5, 219) + let __nt = super::__action1462::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant89(__nt), __end)); + (5, 228) } - pub(crate) fn __reduce729< + pub(crate) fn __reduce754< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // PatternArguments = "(", OneOrMore, ",", ")" => ActionFn(1414); + // PatternArguments = "(", OneOrMore, ",", ")" => ActionFn(1463); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant54(__symbols); + let __sym1 = __pop_Variant53(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1414::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant86(__nt), __end)); - (4, 219) + let __nt = super::__action1463::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant89(__nt), __end)); + (4, 228) } - pub(crate) fn __reduce730< + pub(crate) fn __reduce755< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // PatternArguments = "(", OneOrMore, ")" => ActionFn(1415); + // PatternArguments = "(", OneOrMore, ")" => ActionFn(1464); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant54(__symbols); + let __sym1 = __pop_Variant53(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1415::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant86(__nt), __end)); - (3, 219) + let __nt = super::__action1464::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant89(__nt), __end)); + (3, 228) } - pub(crate) fn __reduce731< + pub(crate) fn __reduce756< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // PatternArguments = "(", OneOrMore, ",", ")" => ActionFn(1416); + // PatternArguments = "(", OneOrMore, ",", ")" => ActionFn(1465); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant80(__symbols); + let __sym1 = __pop_Variant83(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1416::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant86(__nt), __end)); - (4, 219) + let __nt = super::__action1465::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant89(__nt), __end)); + (4, 228) } - pub(crate) fn __reduce732< + pub(crate) fn __reduce757< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // PatternArguments = "(", OneOrMore, ")" => ActionFn(1417); + // PatternArguments = "(", OneOrMore, ")" => ActionFn(1466); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant80(__symbols); + let __sym1 = __pop_Variant83(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1417::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant86(__nt), __end)); - (3, 219) + let __nt = super::__action1466::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant89(__nt), __end)); + (3, 228) } - pub(crate) fn __reduce733< + pub(crate) fn __reduce758< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // PatternArguments = "(", ")" => ActionFn(1418); + // PatternArguments = "(", ")" => ActionFn(1467); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1418::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant86(__nt), __end)); - (2, 219) + let __nt = super::__action1467::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant89(__nt), __end)); + (2, 228) } - pub(crate) fn __reduce734< + pub(crate) fn __reduce759< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Patterns = Pattern, "," => ActionFn(1419); + // Patterns = Pattern, "," => ActionFn(1468); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant34(__symbols); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1419::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (2, 220) + let __nt = super::__action1468::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (2, 229) } - pub(crate) fn __reduce735< + pub(crate) fn __reduce760< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Patterns = TwoOrMore, "," => ActionFn(1420); + // Patterns = TwoOrMore, "," => ActionFn(1469); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant54(__symbols); + let __sym0 = __pop_Variant53(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1420::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (2, 220) + let __nt = super::__action1469::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (2, 229) } - pub(crate) fn __reduce736< + pub(crate) fn __reduce761< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Patterns = TwoOrMore => ActionFn(1421); - let __sym0 = __pop_Variant54(__symbols); + // Patterns = TwoOrMore => ActionFn(1470); + let __sym0 = __pop_Variant53(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1421::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 220) + let __nt = super::__action1470::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 229) } - pub(crate) fn __reduce737< + pub(crate) fn __reduce762< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -27391,85 +28852,90 @@ mod __parse__Top { ) -> (usize, usize) { // Patterns = Pattern => ActionFn(92); - let __sym0 = __pop_Variant34(__symbols); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action92::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 220) + let __nt = super::__action92::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 229) } - pub(crate) fn __reduce738< + pub(crate) fn __reduce763< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Power<"all"> = AtomExpr<"all">, "**", Factor<"all"> => ActionFn(1422); + // Power<"all"> = AtomExpr<"all">, "**", Factor<"all"> => ActionFn(1471); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1422::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 221) + let __nt = super::__action1471::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 230) } - pub(crate) fn __reduce739< + pub(crate) fn __reduce764< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Power<"all"> = AtomExpr<"all"> => ActionFn(507); - let __sym0 = __pop_Variant14(__symbols); + // Power<"all"> = AtomExpr<"all"> => ActionFn(530); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action507::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 221) + let __nt = super::__action530::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 230) } - pub(crate) fn __reduce740< + pub(crate) fn __reduce765< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Power<"no-withitems"> = AtomExpr<"all">, "**", Factor<"all"> => ActionFn(1423); + // Power<"no-withitems"> = AtomExpr<"all">, "**", Factor<"all"> => ActionFn(1472); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1423::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 222) + let __nt = super::__action1472::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 231) } - pub(crate) fn __reduce741< + pub(crate) fn __reduce766< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Power<"no-withitems"> = AtomExpr<"no-withitems"> => ActionFn(558); - let __sym0 = __pop_Variant14(__symbols); + // Power<"no-withitems"> = AtomExpr<"no-withitems"> => ActionFn(581); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action558::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 222) + let __nt = super::__action581::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 231) } - pub(crate) fn __reduce742< + pub(crate) fn __reduce767< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -27479,12 +28945,13 @@ mod __parse__Top { // Program = => ActionFn(3); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action3::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant24(__nt), __end)); - (0, 223) + let __nt = super::__action3::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant25(__nt), __end)); + (0, 232) } - pub(crate) fn __reduce743< + pub(crate) fn __reduce768< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -27493,96 +28960,101 @@ mod __parse__Top { { // Program = Program, CompoundStatement => ActionFn(4); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant36(__symbols); - let __sym0 = __pop_Variant24(__symbols); + let __sym1 = __pop_Variant37(__symbols); + let __sym0 = __pop_Variant25(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action4::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant24(__nt), __end)); - (2, 223) + let __nt = super::__action4::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant25(__nt), __end)); + (2, 232) } - pub(crate) fn __reduce744< + pub(crate) fn __reduce769< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Program = Program, SmallStatement, ";", "\n" => ActionFn(1156); + // Program = Program, SmallStatement, ";", "\n" => ActionFn(1187); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant36(__symbols); - let __sym0 = __pop_Variant24(__symbols); + let __sym1 = __pop_Variant37(__symbols); + let __sym0 = __pop_Variant25(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1156::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant24(__nt), __end)); - (4, 223) + let __nt = super::__action1187::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant25(__nt), __end)); + (4, 232) } - pub(crate) fn __reduce745< + pub(crate) fn __reduce770< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Program = Program, ( ";")+, SmallStatement, ";", "\n" => ActionFn(1157); + // Program = Program, ( ";")+, SmallStatement, ";", "\n" => ActionFn(1188); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant36(__symbols); - let __sym1 = __pop_Variant37(__symbols); - let __sym0 = __pop_Variant24(__symbols); + let __sym2 = __pop_Variant37(__symbols); + let __sym1 = __pop_Variant38(__symbols); + let __sym0 = __pop_Variant25(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1157::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant24(__nt), __end)); - (5, 223) + let __nt = super::__action1188::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant25(__nt), __end)); + (5, 232) } - pub(crate) fn __reduce746< + pub(crate) fn __reduce771< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Program = Program, SmallStatement, "\n" => ActionFn(1158); + // Program = Program, SmallStatement, "\n" => ActionFn(1189); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant36(__symbols); - let __sym0 = __pop_Variant24(__symbols); + let __sym1 = __pop_Variant37(__symbols); + let __sym0 = __pop_Variant25(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1158::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant24(__nt), __end)); - (3, 223) + let __nt = super::__action1189::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant25(__nt), __end)); + (3, 232) } - pub(crate) fn __reduce747< + pub(crate) fn __reduce772< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Program = Program, ( ";")+, SmallStatement, "\n" => ActionFn(1159); + // Program = Program, ( ";")+, SmallStatement, "\n" => ActionFn(1190); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant36(__symbols); - let __sym1 = __pop_Variant37(__symbols); - let __sym0 = __pop_Variant24(__symbols); + let __sym2 = __pop_Variant37(__symbols); + let __sym1 = __pop_Variant38(__symbols); + let __sym0 = __pop_Variant25(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1159::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant24(__nt), __end)); - (4, 223) + let __nt = super::__action1190::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant25(__nt), __end)); + (4, 232) } - pub(crate) fn __reduce748< + pub(crate) fn __reduce773< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -27592,347 +29064,366 @@ mod __parse__Top { // Program = Program, "\n" => ActionFn(6); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant24(__symbols); + let __sym0 = __pop_Variant25(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action6::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant24(__nt), __end)); - (2, 223) + let __nt = super::__action6::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant25(__nt), __end)); + (2, 232) } - pub(crate) fn __reduce749< + pub(crate) fn __reduce774< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // RaiseStatement = "raise" => ActionFn(1424); + // RaiseStatement = "raise" => ActionFn(1473); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1424::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 224) + let __nt = super::__action1473::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 233) } - pub(crate) fn __reduce750< + pub(crate) fn __reduce775< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // RaiseStatement = "raise", Test<"all">, "from", Test<"all"> => ActionFn(1425); + // RaiseStatement = "raise", Test<"all">, "from", Test<"all"> => ActionFn(1474); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant14(__symbols); + let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1425::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (4, 224) + let __nt = super::__action1474::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (4, 233) } - pub(crate) fn __reduce751< + pub(crate) fn __reduce776< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // RaiseStatement = "raise", Test<"all"> => ActionFn(1426); + // RaiseStatement = "raise", Test<"all"> => ActionFn(1475); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1426::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (2, 224) + let __nt = super::__action1475::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (2, 233) } - pub(crate) fn __reduce752< + pub(crate) fn __reduce777< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "(", Pattern, ")" => ActionFn(1427); + // SequencePattern = "(", Pattern, ")" => ActionFn(1476); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant34(__symbols); + let __sym1 = __pop_Variant35(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1427::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (3, 225) + let __nt = super::__action1476::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (3, 234) } - pub(crate) fn __reduce753< + pub(crate) fn __reduce778< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "(", ")" => ActionFn(1428); + // SequencePattern = "(", ")" => ActionFn(1477); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1428::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (2, 225) + let __nt = super::__action1477::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (2, 234) } - pub(crate) fn __reduce754< + pub(crate) fn __reduce779< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "(", Pattern, ",", ")" => ActionFn(1429); + // SequencePattern = "(", Pattern, ",", ")" => ActionFn(1478); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant34(__symbols); + let __sym1 = __pop_Variant35(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1429::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (4, 225) + let __nt = super::__action1478::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (4, 234) } - pub(crate) fn __reduce755< + pub(crate) fn __reduce780< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "(", ( ",")+, Pattern, ",", ")" => ActionFn(1430); + // SequencePattern = "(", ( ",")+, Pattern, ",", ")" => ActionFn(1479); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant34(__symbols); - let __sym1 = __pop_Variant35(__symbols); + let __sym2 = __pop_Variant35(__symbols); + let __sym1 = __pop_Variant36(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1430::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (5, 225) + let __nt = super::__action1479::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (5, 234) } - pub(crate) fn __reduce756< + pub(crate) fn __reduce781< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "(", ( ",")+, Pattern, ")" => ActionFn(1431); + // SequencePattern = "(", ( ",")+, Pattern, ")" => ActionFn(1480); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant34(__symbols); - let __sym1 = __pop_Variant35(__symbols); + let __sym2 = __pop_Variant35(__symbols); + let __sym1 = __pop_Variant36(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1431::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (4, 225) + let __nt = super::__action1480::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (4, 234) } - pub(crate) fn __reduce757< + pub(crate) fn __reduce782< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "[", Pattern, "]" => ActionFn(1506); + // SequencePattern = "[", Pattern, "]" => ActionFn(1545); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant34(__symbols); + let __sym1 = __pop_Variant35(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1506::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (3, 225) + let __nt = super::__action1545::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (3, 234) } - pub(crate) fn __reduce758< + pub(crate) fn __reduce783< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "[", "]" => ActionFn(1507); + // SequencePattern = "[", "]" => ActionFn(1546); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1507::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (2, 225) + let __nt = super::__action1546::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (2, 234) } - pub(crate) fn __reduce759< + pub(crate) fn __reduce784< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "[", ( ",")+, Pattern, "]" => ActionFn(1508); + // SequencePattern = "[", ( ",")+, Pattern, "]" => ActionFn(1547); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant34(__symbols); - let __sym1 = __pop_Variant35(__symbols); + let __sym2 = __pop_Variant35(__symbols); + let __sym1 = __pop_Variant36(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1508::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (4, 225) + let __nt = super::__action1547::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (4, 234) } - pub(crate) fn __reduce760< + pub(crate) fn __reduce785< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SequencePattern = "[", ( ",")+, "]" => ActionFn(1509); + // SequencePattern = "[", ( ",")+, "]" => ActionFn(1548); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant35(__symbols); + let __sym1 = __pop_Variant36(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1509::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (3, 225) + let __nt = super::__action1548::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (3, 234) } - pub(crate) fn __reduce761< + pub(crate) fn __reduce786< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SetLiteralValues = OneOrMore, "," => ActionFn(635); + // SetLiteralValues = OneOrMore, "," => ActionFn(658); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant32(__symbols); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action635::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (2, 226) + let __nt = super::__action658::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (2, 235) } - pub(crate) fn __reduce762< + pub(crate) fn __reduce787< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SetLiteralValues = OneOrMore => ActionFn(636); - let __sym0 = __pop_Variant32(__symbols); + // SetLiteralValues = OneOrMore => ActionFn(659); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action636::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (1, 226) + let __nt = super::__action659::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (1, 235) } - pub(crate) fn __reduce763< + pub(crate) fn __reduce788< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ShiftExpression<"all"> = ShiftExpression<"all">, ShiftOp, ArithmeticExpression<"all"> => ActionFn(1433); + // ShiftExpression<"all"> = ShiftExpression<"all">, ShiftOp, ArithmeticExpression<"all"> => ActionFn(1482); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); - let __sym1 = __pop_Variant50(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); + let __sym1 = __pop_Variant49(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1433::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 227) + let __nt = super::__action1482::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 236) } - pub(crate) fn __reduce764< + pub(crate) fn __reduce789< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ShiftExpression<"all"> = ArithmeticExpression<"all"> => ActionFn(482); - let __sym0 = __pop_Variant14(__symbols); + // ShiftExpression<"all"> = ArithmeticExpression<"all"> => ActionFn(505); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action482::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 227) + let __nt = super::__action505::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 236) } - pub(crate) fn __reduce765< + pub(crate) fn __reduce790< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ShiftExpression<"no-withitems"> = ShiftExpression<"all">, ShiftOp, ArithmeticExpression<"all"> => ActionFn(1434); + // ShiftExpression<"no-withitems"> = ShiftExpression<"all">, ShiftOp, ArithmeticExpression<"all"> => ActionFn(1483); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); - let __sym1 = __pop_Variant50(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); + let __sym1 = __pop_Variant49(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1434::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 228) + let __nt = super::__action1483::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 237) } - pub(crate) fn __reduce766< + pub(crate) fn __reduce791< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ShiftExpression<"no-withitems"> = ArithmeticExpression<"no-withitems"> => ActionFn(519); - let __sym0 = __pop_Variant14(__symbols); + // ShiftExpression<"no-withitems"> = ArithmeticExpression<"no-withitems"> => ActionFn(542); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action519::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 228) + let __nt = super::__action542::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 237) } - pub(crate) fn __reduce767< + pub(crate) fn __reduce792< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -27943,12 +29434,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action194::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 229) + let __nt = super::__action194::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 238) } - pub(crate) fn __reduce768< + pub(crate) fn __reduce793< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -27959,195 +29451,206 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action195::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant50(__nt), __end)); - (1, 229) + let __nt = super::__action195::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant49(__nt), __end)); + (1, 238) } - pub(crate) fn __reduce769< + pub(crate) fn __reduce794< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SingleForComprehension = "async", "for", ExpressionList, "in", OrTest<"all"> => ActionFn(1512); + // SingleForComprehension = "async", "for", ExpressionList, "in", OrTest<"all"> => ActionFn(1551); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant14(__symbols); + let __sym4 = __pop_Variant15(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1512::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant87(__nt), __end)); - (5, 230) + let __nt = super::__action1551::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant90(__nt), __end)); + (5, 239) } - pub(crate) fn __reduce770< + pub(crate) fn __reduce795< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SingleForComprehension = "async", "for", ExpressionList, "in", OrTest<"all">, ComprehensionIf+ => ActionFn(1513); + // SingleForComprehension = "async", "for", ExpressionList, "in", OrTest<"all">, ComprehensionIf+ => ActionFn(1552); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant16(__symbols); - let __sym4 = __pop_Variant14(__symbols); + let __sym5 = __pop_Variant17(__symbols); + let __sym4 = __pop_Variant15(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1513::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant87(__nt), __end)); - (6, 230) + let __nt = super::__action1552::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant90(__nt), __end)); + (6, 239) } - pub(crate) fn __reduce771< + pub(crate) fn __reduce796< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SingleForComprehension = "for", ExpressionList, "in", OrTest<"all"> => ActionFn(1514); + // SingleForComprehension = "for", ExpressionList, "in", OrTest<"all"> => ActionFn(1553); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant14(__symbols); + let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1514::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant87(__nt), __end)); - (4, 230) + let __nt = super::__action1553::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant90(__nt), __end)); + (4, 239) } - pub(crate) fn __reduce772< + pub(crate) fn __reduce797< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SingleForComprehension = "for", ExpressionList, "in", OrTest<"all">, ComprehensionIf+ => ActionFn(1515); + // SingleForComprehension = "for", ExpressionList, "in", OrTest<"all">, ComprehensionIf+ => ActionFn(1554); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant16(__symbols); - let __sym3 = __pop_Variant14(__symbols); + let __sym4 = __pop_Variant17(__symbols); + let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1515::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant87(__nt), __end)); - (5, 230) + let __nt = super::__action1554::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant90(__nt), __end)); + (5, 239) } - pub(crate) fn __reduce773< + pub(crate) fn __reduce798< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SingleForComprehension+ = SingleForComprehension => ActionFn(244); - let __sym0 = __pop_Variant87(__symbols); + // SingleForComprehension+ = SingleForComprehension => ActionFn(254); + let __sym0 = __pop_Variant90(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action244::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant88(__nt), __end)); - (1, 231) + let __nt = super::__action254::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant91(__nt), __end)); + (1, 240) } - pub(crate) fn __reduce774< + pub(crate) fn __reduce799< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SingleForComprehension+ = SingleForComprehension+, SingleForComprehension => ActionFn(245); + // SingleForComprehension+ = SingleForComprehension+, SingleForComprehension => ActionFn(255); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant87(__symbols); - let __sym0 = __pop_Variant88(__symbols); + let __sym1 = __pop_Variant90(__symbols); + let __sym0 = __pop_Variant91(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action245::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant88(__nt), __end)); - (2, 231) + let __nt = super::__action255::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant91(__nt), __end)); + (2, 240) } - pub(crate) fn __reduce775< + pub(crate) fn __reduce800< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SliceOp = ":", Test<"all"> => ActionFn(1674); + // SliceOp = ":", Test<"all"> => ActionFn(1729); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1674::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant89(__nt), __end)); - (2, 232) + let __nt = super::__action1729::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant92(__nt), __end)); + (2, 241) } - pub(crate) fn __reduce776< + pub(crate) fn __reduce801< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SliceOp = ":" => ActionFn(1675); + // SliceOp = ":" => ActionFn(1730); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1675::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant89(__nt), __end)); - (1, 232) + let __nt = super::__action1730::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant92(__nt), __end)); + (1, 241) } - pub(crate) fn __reduce777< + pub(crate) fn __reduce802< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SliceOp? = SliceOp => ActionFn(254); - let __sym0 = __pop_Variant89(__symbols); + // SliceOp? = SliceOp => ActionFn(272); + let __sym0 = __pop_Variant92(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action254::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant90(__nt), __end)); - (1, 233) + let __nt = super::__action272::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant93(__nt), __end)); + (1, 242) } - pub(crate) fn __reduce778< + pub(crate) fn __reduce803< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SliceOp? = => ActionFn(255); + // SliceOp? = => ActionFn(273); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action255::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant90(__nt), __end)); - (0, 233) + let __nt = super::__action273::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant93(__nt), __end)); + (0, 242) } - pub(crate) fn __reduce779< + pub(crate) fn __reduce804< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -28155,15 +29658,16 @@ mod __parse__Top { ) -> (usize, usize) { // SmallStatement = ExpressionStatement => ActionFn(13); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action13::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 234) + let __nt = super::__action13::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 243) } - pub(crate) fn __reduce780< + pub(crate) fn __reduce805< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -28171,15 +29675,16 @@ mod __parse__Top { ) -> (usize, usize) { // SmallStatement = PassStatement => ActionFn(14); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action14::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 234) + let __nt = super::__action14::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 243) } - pub(crate) fn __reduce781< + pub(crate) fn __reduce806< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -28187,15 +29692,16 @@ mod __parse__Top { ) -> (usize, usize) { // SmallStatement = DelStatement => ActionFn(15); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action15::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 234) + let __nt = super::__action15::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 243) } - pub(crate) fn __reduce782< + pub(crate) fn __reduce807< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -28203,15 +29709,16 @@ mod __parse__Top { ) -> (usize, usize) { // SmallStatement = FlowStatement => ActionFn(16); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action16::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 234) + let __nt = super::__action16::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 243) } - pub(crate) fn __reduce783< + pub(crate) fn __reduce808< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -28219,15 +29726,16 @@ mod __parse__Top { ) -> (usize, usize) { // SmallStatement = ImportStatement => ActionFn(17); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action17::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 234) + let __nt = super::__action17::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 243) } - pub(crate) fn __reduce784< + pub(crate) fn __reduce809< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -28235,15 +29743,16 @@ mod __parse__Top { ) -> (usize, usize) { // SmallStatement = GlobalStatement => ActionFn(18); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action18::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 234) + let __nt = super::__action18::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 243) } - pub(crate) fn __reduce785< + pub(crate) fn __reduce810< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -28251,15 +29760,16 @@ mod __parse__Top { ) -> (usize, usize) { // SmallStatement = NonlocalStatement => ActionFn(19); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action19::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 234) + let __nt = super::__action19::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 243) } - pub(crate) fn __reduce786< + pub(crate) fn __reduce811< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -28267,15 +29777,16 @@ mod __parse__Top { ) -> (usize, usize) { // SmallStatement = AssertStatement => ActionFn(20); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action20::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 234) + let __nt = super::__action20::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 243) } - pub(crate) fn __reduce787< + pub(crate) fn __reduce812< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -28283,15 +29794,16 @@ mod __parse__Top { ) -> (usize, usize) { // SmallStatement = TypeAliasStatement => ActionFn(21); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action21::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 234) + let __nt = super::__action21::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 243) } - pub(crate) fn __reduce788< + pub(crate) fn __reduce813< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -28299,15 +29811,16 @@ mod __parse__Top { ) -> (usize, usize) { // SmallStatement = IpyEscapeCommandStatement => ActionFn(22); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action22::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 234) + let __nt = super::__action22::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 243) } - pub(crate) fn __reduce789< + pub(crate) fn __reduce814< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -28315,240 +29828,254 @@ mod __parse__Top { ) -> (usize, usize) { // SmallStatement = IpyHelpEndEscapeCommandStatement => ActionFn(23); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action23::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (1, 234) + let __nt = super::__action23::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (1, 243) } - pub(crate) fn __reduce790< + pub(crate) fn __reduce815< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarExpr = "*", Expression<"all"> => ActionFn(1437); + // StarExpr = "*", Expression<"all"> => ActionFn(1486); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1437::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 235) + let __nt = super::__action1486::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 244) } - pub(crate) fn __reduce791< + pub(crate) fn __reduce816< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarPattern = "*", Identifier => ActionFn(1438); + // StarPattern = "*", Identifier => ActionFn(1487); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant22(__symbols); + let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1438::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (2, 236) + let __nt = super::__action1487::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (2, 245) } - pub(crate) fn __reduce792< + pub(crate) fn __reduce817< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarTypedParameter = Identifier, ":", TestOrStarExpr => ActionFn(1439); + // StarTypedParameter = Identifier, ":", TestOrStarExpr => ActionFn(1488); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant22(__symbols); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1439::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant65(__nt), __end)); - (3, 237) + let __nt = super::__action1488::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant64(__nt), __end)); + (3, 246) } - pub(crate) fn __reduce793< + pub(crate) fn __reduce818< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarTypedParameter = Identifier => ActionFn(1440); - let __sym0 = __pop_Variant22(__symbols); + // StarTypedParameter = Identifier => ActionFn(1489); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1440::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant65(__nt), __end)); - (1, 237) + let __nt = super::__action1489::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant64(__nt), __end)); + (1, 246) } - pub(crate) fn __reduce794< + pub(crate) fn __reduce819< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarTypedParameter? = StarTypedParameter => ActionFn(473); - let __sym0 = __pop_Variant65(__symbols); + // StarTypedParameter? = StarTypedParameter => ActionFn(496); + let __sym0 = __pop_Variant64(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action473::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant66(__nt), __end)); - (1, 238) + let __nt = super::__action496::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant65(__nt), __end)); + (1, 247) } - pub(crate) fn __reduce795< + pub(crate) fn __reduce820< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarTypedParameter? = => ActionFn(474); + // StarTypedParameter? = => ActionFn(497); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action474::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant66(__nt), __end)); - (0, 238) + let __nt = super::__action497::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant65(__nt), __end)); + (0, 247) } - pub(crate) fn __reduce796< + pub(crate) fn __reduce821< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarUntypedParameter = Identifier => ActionFn(1441); - let __sym0 = __pop_Variant22(__symbols); + // StarUntypedParameter = Identifier => ActionFn(1490); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1441::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant65(__nt), __end)); - (1, 239) + let __nt = super::__action1490::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant64(__nt), __end)); + (1, 248) } - pub(crate) fn __reduce797< + pub(crate) fn __reduce822< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarUntypedParameter? = StarUntypedParameter => ActionFn(462); - let __sym0 = __pop_Variant65(__symbols); + // StarUntypedParameter? = StarUntypedParameter => ActionFn(485); + let __sym0 = __pop_Variant64(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action462::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant66(__nt), __end)); - (1, 240) + let __nt = super::__action485::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant65(__nt), __end)); + (1, 249) } - pub(crate) fn __reduce798< + pub(crate) fn __reduce823< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // StarUntypedParameter? = => ActionFn(463); + // StarUntypedParameter? = => ActionFn(486); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action463::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant66(__nt), __end)); - (0, 240) + let __nt = super::__action486::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant65(__nt), __end)); + (0, 249) } - pub(crate) fn __reduce799< + pub(crate) fn __reduce824< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Statements = SmallStatement, ";", "\n" => ActionFn(1160); + // Statements = SmallStatement, ";", "\n" => ActionFn(1191); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1160::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant91(__nt), __end)); - (3, 241) + let __nt = super::__action1191::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + (3, 250) } - pub(crate) fn __reduce800< + pub(crate) fn __reduce825< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Statements = ( ";")+, SmallStatement, ";", "\n" => ActionFn(1161); + // Statements = ( ";")+, SmallStatement, ";", "\n" => ActionFn(1192); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant36(__symbols); - let __sym0 = __pop_Variant37(__symbols); + let __sym1 = __pop_Variant37(__symbols); + let __sym0 = __pop_Variant38(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1161::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant91(__nt), __end)); - (4, 241) + let __nt = super::__action1192::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + (4, 250) } - pub(crate) fn __reduce801< + pub(crate) fn __reduce826< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Statements = SmallStatement, "\n" => ActionFn(1162); + // Statements = SmallStatement, "\n" => ActionFn(1193); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1162::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant91(__nt), __end)); - (2, 241) + let __nt = super::__action1193::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + (2, 250) } - pub(crate) fn __reduce802< + pub(crate) fn __reduce827< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Statements = ( ";")+, SmallStatement, "\n" => ActionFn(1163); + // Statements = ( ";")+, SmallStatement, "\n" => ActionFn(1194); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant36(__symbols); - let __sym0 = __pop_Variant37(__symbols); + let __sym1 = __pop_Variant37(__symbols); + let __sym0 = __pop_Variant38(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1163::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant91(__nt), __end)); - (3, 241) + let __nt = super::__action1194::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + (3, 250) } - pub(crate) fn __reduce803< + pub(crate) fn __reduce828< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -28556,15 +30083,16 @@ mod __parse__Top { ) -> (usize, usize) { // Statements = CompoundStatement => ActionFn(10); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action10::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant91(__nt), __end)); - (1, 241) + let __nt = super::__action10::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + (1, 250) } - pub(crate) fn __reduce804< + pub(crate) fn __reduce829< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -28573,96 +30101,207 @@ mod __parse__Top { { // Statements = Statements, CompoundStatement => ActionFn(11); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant36(__symbols); - let __sym0 = __pop_Variant91(__symbols); + let __sym1 = __pop_Variant37(__symbols); + let __sym0 = __pop_Variant94(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action11::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant91(__nt), __end)); - (2, 241) + let __nt = super::__action11::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + (2, 250) } - pub(crate) fn __reduce805< + pub(crate) fn __reduce830< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Statements = Statements, SmallStatement, ";", "\n" => ActionFn(1164); + // Statements = Statements, SmallStatement, ";", "\n" => ActionFn(1195); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant36(__symbols); - let __sym0 = __pop_Variant91(__symbols); + let __sym1 = __pop_Variant37(__symbols); + let __sym0 = __pop_Variant94(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1164::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant91(__nt), __end)); - (4, 241) + let __nt = super::__action1195::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + (4, 250) } - pub(crate) fn __reduce806< + pub(crate) fn __reduce831< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Statements = Statements, ( ";")+, SmallStatement, ";", "\n" => ActionFn(1165); + // Statements = Statements, ( ";")+, SmallStatement, ";", "\n" => ActionFn(1196); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant36(__symbols); - let __sym1 = __pop_Variant37(__symbols); - let __sym0 = __pop_Variant91(__symbols); + let __sym2 = __pop_Variant37(__symbols); + let __sym1 = __pop_Variant38(__symbols); + let __sym0 = __pop_Variant94(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1165::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant91(__nt), __end)); - (5, 241) + let __nt = super::__action1196::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + (5, 250) } - pub(crate) fn __reduce807< + pub(crate) fn __reduce832< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Statements = Statements, SmallStatement, "\n" => ActionFn(1166); + // Statements = Statements, SmallStatement, "\n" => ActionFn(1197); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant36(__symbols); - let __sym0 = __pop_Variant91(__symbols); + let __sym1 = __pop_Variant37(__symbols); + let __sym0 = __pop_Variant94(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1166::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant91(__nt), __end)); - (3, 241) + let __nt = super::__action1197::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + (3, 250) } - pub(crate) fn __reduce808< + pub(crate) fn __reduce833< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Statements = Statements, ( ";")+, SmallStatement, "\n" => ActionFn(1167); + // Statements = Statements, ( ";")+, SmallStatement, "\n" => ActionFn(1198); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant36(__symbols); - let __sym1 = __pop_Variant37(__symbols); - let __sym0 = __pop_Variant91(__symbols); + let __sym2 = __pop_Variant37(__symbols); + let __sym1 = __pop_Variant38(__symbols); + let __sym0 = __pop_Variant94(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1167::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant91(__nt), __end)); - (4, 241) + let __nt = super::__action1198::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant94(__nt), __end)); + (4, 250) } - pub(crate) fn __reduce809< + pub(crate) fn __reduce835< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // StringLiteral+ = StringLiteral => ActionFn(351); + let __sym0 = __pop_Variant70(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = super::__action351::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant95(__nt), __end)); + (1, 252) + } + pub(crate) fn __reduce836< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // StringLiteral+ = StringLiteral+, StringLiteral => ActionFn(352); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant70(__symbols); + let __sym0 = __pop_Variant95(__symbols); + let __start = __sym0.0; + let __end = __sym1.2; + let __nt = super::__action352::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant95(__nt), __end)); + (2, 252) + } + pub(crate) fn __reduce837< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // StringLiteralOrFString = StringLiteral => ActionFn(212); + let __sym0 = __pop_Variant70(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = super::__action212::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant70(__nt), __end)); + (1, 253) + } + pub(crate) fn __reduce838< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // StringLiteralOrFString = FStringExpr => ActionFn(213); + let __sym0 = __pop_Variant70(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = super::__action213::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant70(__nt), __end)); + (1, 253) + } + pub(crate) fn __reduce839< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // StringLiteralOrFString+ = StringLiteralOrFString => ActionFn(349); + let __sym0 = __pop_Variant70(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = super::__action349::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant95(__nt), __end)); + (1, 254) + } + pub(crate) fn __reduce840< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // StringLiteralOrFString+ = StringLiteralOrFString+, StringLiteralOrFString => ActionFn(350); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant70(__symbols); + let __sym0 = __pop_Variant95(__symbols); + let __start = __sym0.0; + let __end = __sym1.2; + let __nt = super::__action350::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant95(__nt), __end)); + (2, 254) + } + pub(crate) fn __reduce841< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -28670,162 +30309,171 @@ mod __parse__Top { ) -> (usize, usize) { // Subscript = TestOrStarNamedExpr => ActionFn(209); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action209::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 242) + let __nt = super::__action209::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 255) } - pub(crate) fn __reduce810< + pub(crate) fn __reduce842< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Subscript = Test<"all">, ":", Test<"all">, SliceOp => ActionFn(1676); + // Subscript = Test<"all">, ":", Test<"all">, SliceOp => ActionFn(1731); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant89(__symbols); - let __sym2 = __pop_Variant14(__symbols); + let __sym3 = __pop_Variant92(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1676::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (4, 242) + let __nt = super::__action1731::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (4, 255) } - pub(crate) fn __reduce811< + pub(crate) fn __reduce843< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Subscript = Test<"all">, ":", SliceOp => ActionFn(1677); + // Subscript = Test<"all">, ":", SliceOp => ActionFn(1732); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant89(__symbols); + let __sym2 = __pop_Variant92(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1677::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 242) + let __nt = super::__action1732::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 255) } - pub(crate) fn __reduce812< + pub(crate) fn __reduce844< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Subscript = ":", Test<"all">, SliceOp => ActionFn(1678); + // Subscript = ":", Test<"all">, SliceOp => ActionFn(1733); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant89(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant92(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1678::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 242) + let __nt = super::__action1733::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 255) } - pub(crate) fn __reduce813< + pub(crate) fn __reduce845< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Subscript = ":", SliceOp => ActionFn(1679); + // Subscript = ":", SliceOp => ActionFn(1734); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant89(__symbols); + let __sym1 = __pop_Variant92(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1679::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 242) + let __nt = super::__action1734::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 255) } - pub(crate) fn __reduce814< + pub(crate) fn __reduce846< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Subscript = Test<"all">, ":", Test<"all"> => ActionFn(1680); + // Subscript = Test<"all">, ":", Test<"all"> => ActionFn(1735); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1680::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 242) + let __nt = super::__action1735::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 255) } - pub(crate) fn __reduce815< + pub(crate) fn __reduce847< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Subscript = Test<"all">, ":" => ActionFn(1681); + // Subscript = Test<"all">, ":" => ActionFn(1736); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1681::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 242) + let __nt = super::__action1736::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 255) } - pub(crate) fn __reduce816< + pub(crate) fn __reduce848< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Subscript = ":", Test<"all"> => ActionFn(1682); + // Subscript = ":", Test<"all"> => ActionFn(1737); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1682::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 242) + let __nt = super::__action1737::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 255) } - pub(crate) fn __reduce817< + pub(crate) fn __reduce849< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Subscript = ":" => ActionFn(1683); + // Subscript = ":" => ActionFn(1738); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1683::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 242) + let __nt = super::__action1738::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 255) } - pub(crate) fn __reduce818< + pub(crate) fn __reduce850< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -28833,143 +30481,151 @@ mod __parse__Top { ) -> (usize, usize) { // SubscriptList = Subscript => ActionFn(206); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action206::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 243) + let __nt = super::__action206::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 256) } - pub(crate) fn __reduce819< + pub(crate) fn __reduce851< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SubscriptList = Subscript, "," => ActionFn(1443); + // SubscriptList = Subscript, "," => ActionFn(1492); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1443::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 243) + let __nt = super::__action1492::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 256) } - pub(crate) fn __reduce820< + pub(crate) fn __reduce852< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SubscriptList = TwoOrMore, "," => ActionFn(1444); + // SubscriptList = TwoOrMore, "," => ActionFn(1493); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant32(__symbols); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1444::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 243) + let __nt = super::__action1493::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 256) } - pub(crate) fn __reduce821< + pub(crate) fn __reduce853< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // SubscriptList = TwoOrMore => ActionFn(1445); - let __sym0 = __pop_Variant32(__symbols); + // SubscriptList = TwoOrMore => ActionFn(1494); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1445::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 243) + let __nt = super::__action1494::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 256) } - pub(crate) fn __reduce822< + pub(crate) fn __reduce854< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Suite = SmallStatement, ";", "\n" => ActionFn(1168); + // Suite = SmallStatement, ";", "\n" => ActionFn(1199); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1168::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant24(__nt), __end)); - (3, 244) + let __nt = super::__action1199::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant25(__nt), __end)); + (3, 257) } - pub(crate) fn __reduce823< + pub(crate) fn __reduce855< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Suite = ( ";")+, SmallStatement, ";", "\n" => ActionFn(1169); + // Suite = ( ";")+, SmallStatement, ";", "\n" => ActionFn(1200); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant36(__symbols); - let __sym0 = __pop_Variant37(__symbols); + let __sym1 = __pop_Variant37(__symbols); + let __sym0 = __pop_Variant38(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1169::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant24(__nt), __end)); - (4, 244) + let __nt = super::__action1200::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant25(__nt), __end)); + (4, 257) } - pub(crate) fn __reduce824< + pub(crate) fn __reduce856< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Suite = SmallStatement, "\n" => ActionFn(1170); + // Suite = SmallStatement, "\n" => ActionFn(1201); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant36(__symbols); + let __sym0 = __pop_Variant37(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1170::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant24(__nt), __end)); - (2, 244) + let __nt = super::__action1201::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant25(__nt), __end)); + (2, 257) } - pub(crate) fn __reduce825< + pub(crate) fn __reduce857< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Suite = ( ";")+, SmallStatement, "\n" => ActionFn(1171); + // Suite = ( ";")+, SmallStatement, "\n" => ActionFn(1202); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant36(__symbols); - let __sym0 = __pop_Variant37(__symbols); + let __sym1 = __pop_Variant37(__symbols); + let __sym0 = __pop_Variant38(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1171::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant24(__nt), __end)); - (3, 244) + let __nt = super::__action1202::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant25(__nt), __end)); + (3, 257) } - pub(crate) fn __reduce826< + pub(crate) fn __reduce858< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -28979,287 +30635,304 @@ mod __parse__Top { // Suite = "\n", Indent, Statements, Dedent => ActionFn(8); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant91(__symbols); + let __sym2 = __pop_Variant94(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action8::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant24(__nt), __end)); - (4, 244) + let __nt = super::__action8::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant25(__nt), __end)); + (4, 257) } - pub(crate) fn __reduce827< + pub(crate) fn __reduce859< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Term<"all"> = Term<"all">, MulOp, Factor<"all"> => ActionFn(1446); + // Term<"all"> = Term<"all">, MulOp, Factor<"all"> => ActionFn(1495); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); - let __sym1 = __pop_Variant50(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); + let __sym1 = __pop_Variant49(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1446::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 245) + let __nt = super::__action1495::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 258) } - pub(crate) fn __reduce828< + pub(crate) fn __reduce860< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Term<"all"> = Factor<"all"> => ActionFn(499); - let __sym0 = __pop_Variant14(__symbols); + // Term<"all"> = Factor<"all"> => ActionFn(522); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action499::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 245) + let __nt = super::__action522::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 258) } - pub(crate) fn __reduce829< + pub(crate) fn __reduce861< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Term<"no-withitems"> = Term<"all">, MulOp, Factor<"all"> => ActionFn(1447); + // Term<"no-withitems"> = Term<"all">, MulOp, Factor<"all"> => ActionFn(1496); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); - let __sym1 = __pop_Variant50(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); + let __sym1 = __pop_Variant49(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1447::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 246) + let __nt = super::__action1496::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 259) } - pub(crate) fn __reduce830< + pub(crate) fn __reduce862< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Term<"no-withitems"> = Factor<"no-withitems"> => ActionFn(552); - let __sym0 = __pop_Variant14(__symbols); + // Term<"no-withitems"> = Factor<"no-withitems"> => ActionFn(575); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action552::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 246) + let __nt = super::__action575::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 259) } - pub(crate) fn __reduce831< + pub(crate) fn __reduce863< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Test<"all"> = OrTest<"all">, "if", OrTest<"all">, "else", Test<"all"> => ActionFn(1448); + // Test<"all"> = OrTest<"all">, "if", OrTest<"all">, "else", Test<"all"> => ActionFn(1497); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant14(__symbols); + let __sym4 = __pop_Variant15(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1448::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (5, 247) + let __nt = super::__action1497::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (5, 260) } - pub(crate) fn __reduce832< + pub(crate) fn __reduce864< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Test<"all"> = OrTest<"all"> => ActionFn(380); - let __sym0 = __pop_Variant14(__symbols); + // Test<"all"> = OrTest<"all"> => ActionFn(401); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action380::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 247) + let __nt = super::__action401::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 260) } - pub(crate) fn __reduce833< + pub(crate) fn __reduce865< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Test<"all"> = LambdaDef => ActionFn(381); - let __sym0 = __pop_Variant14(__symbols); + // Test<"all"> = LambdaDef => ActionFn(402); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action381::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 247) + let __nt = super::__action402::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 260) } - pub(crate) fn __reduce834< + pub(crate) fn __reduce866< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Test<"all">? = Test<"all"> => ActionFn(302); - let __sym0 = __pop_Variant14(__symbols); + // Test<"all">? = Test<"all"> => ActionFn(322); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action302::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 248) + let __nt = super::__action322::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (1, 261) } - pub(crate) fn __reduce835< + pub(crate) fn __reduce867< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Test<"all">? = => ActionFn(303); + // Test<"all">? = => ActionFn(323); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action303::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (0, 248) + let __nt = super::__action323::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (0, 261) } - pub(crate) fn __reduce836< + pub(crate) fn __reduce868< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Test<"no-withitems"> = OrTest<"all">, "if", OrTest<"all">, "else", Test<"all"> => ActionFn(1449); + // Test<"no-withitems"> = OrTest<"all">, "if", OrTest<"all">, "else", Test<"all"> => ActionFn(1498); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant14(__symbols); + let __sym4 = __pop_Variant15(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1449::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (5, 249) + let __nt = super::__action1498::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (5, 262) } - pub(crate) fn __reduce837< + pub(crate) fn __reduce869< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Test<"no-withitems"> = OrTest<"no-withitems"> => ActionFn(412); - let __sym0 = __pop_Variant14(__symbols); + // Test<"no-withitems"> = OrTest<"no-withitems"> => ActionFn(433); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action412::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 249) + let __nt = super::__action433::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 262) } - pub(crate) fn __reduce838< + pub(crate) fn __reduce870< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Test<"no-withitems"> = LambdaDef => ActionFn(413); - let __sym0 = __pop_Variant14(__symbols); + // Test<"no-withitems"> = LambdaDef => ActionFn(434); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action413::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 249) + let __nt = super::__action434::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 262) } - pub(crate) fn __reduce839< + pub(crate) fn __reduce871< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TestList = GenericList => ActionFn(222); - let __sym0 = __pop_Variant14(__symbols); + // TestList = GenericList => ActionFn(232); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action222::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 250) + let __nt = super::__action232::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 263) } - pub(crate) fn __reduce840< + pub(crate) fn __reduce872< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TestList? = GenericList => ActionFn(1688); - let __sym0 = __pop_Variant14(__symbols); + // TestList? = GenericList => ActionFn(1743); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1688::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 251) + let __nt = super::__action1743::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (1, 264) } - pub(crate) fn __reduce841< + pub(crate) fn __reduce873< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TestList? = => ActionFn(376); + // TestList? = => ActionFn(397); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action376::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (0, 251) + let __nt = super::__action397::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (0, 264) } - pub(crate) fn __reduce842< + pub(crate) fn __reduce874< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TestListOrYieldExpr = GenericList => ActionFn(1689); - let __sym0 = __pop_Variant14(__symbols); + // TestListOrYieldExpr = GenericList => ActionFn(1744); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1689::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 252) + let __nt = super::__action1744::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 265) } - pub(crate) fn __reduce843< + pub(crate) fn __reduce875< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -29267,15 +30940,16 @@ mod __parse__Top { ) -> (usize, usize) { // TestListOrYieldExpr = YieldExpr => ActionFn(32); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action32::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 252) + let __nt = super::__action32::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 265) } - pub(crate) fn __reduce844< + pub(crate) fn __reduce876< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -29283,15 +30957,16 @@ mod __parse__Top { ) -> (usize, usize) { // TestOrStarExpr = Test<"all"> => ActionFn(34); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action34::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 253) + let __nt = super::__action34::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 266) } - pub(crate) fn __reduce845< + pub(crate) fn __reduce877< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -29299,31 +30974,33 @@ mod __parse__Top { ) -> (usize, usize) { // TestOrStarExpr = StarExpr => ActionFn(35); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action35::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 253) + let __nt = super::__action35::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 266) } - pub(crate) fn __reduce846< + pub(crate) fn __reduce878< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TestOrStarExprList = GenericList => ActionFn(1690); - let __sym0 = __pop_Variant14(__symbols); + // TestOrStarExprList = GenericList => ActionFn(1745); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1690::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 254) + let __nt = super::__action1745::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 267) } - pub(crate) fn __reduce847< + pub(crate) fn __reduce879< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -29331,15 +31008,16 @@ mod __parse__Top { ) -> (usize, usize) { // TestOrStarNamedExpr = NamedExpressionTest => ActionFn(38); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action38::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 255) + let __nt = super::__action38::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 268) } - pub(crate) fn __reduce848< + pub(crate) fn __reduce880< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -29347,661 +31025,695 @@ mod __parse__Top { ) -> (usize, usize) { // TestOrStarNamedExpr = StarExpr => ActionFn(39); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action39::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 255) + let __nt = super::__action39::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 268) } - pub(crate) fn __reduce849< + pub(crate) fn __reduce881< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Top = StartModule, Program => ActionFn(1450); + // Top = StartModule, Program => ActionFn(1499); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant24(__symbols); + let __sym1 = __pop_Variant25(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1450::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant92(__nt), __end)); - (2, 256) + let __nt = super::__action1499::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant96(__nt), __end)); + (2, 269) } - pub(crate) fn __reduce850< + pub(crate) fn __reduce882< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Top = StartExpression, GenericList => ActionFn(1691); + // Top = StartExpression, GenericList => ActionFn(1746); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1691::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant92(__nt), __end)); - (2, 256) + let __nt = super::__action1746::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant96(__nt), __end)); + (2, 269) } - pub(crate) fn __reduce851< + pub(crate) fn __reduce883< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // Top = StartExpression, GenericList, ("\n")+ => ActionFn(1692); + // Top = StartExpression, GenericList, ("\n")+ => ActionFn(1747); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant21(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant22(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1692::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant92(__nt), __end)); - (3, 256) + let __nt = super::__action1747::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant96(__nt), __end)); + (3, 269) } - pub(crate) fn __reduce852< + pub(crate) fn __reduce884< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, ExceptClause+, "else", ":", Suite, "finally", ":", Suite => ActionFn(1453); + // TryStatement = "try", ":", Suite, ExceptClause+, "else", ":", Suite, "finally", ":", Suite => ActionFn(1502); assert!(__symbols.len() >= 10); - let __sym9 = __pop_Variant24(__symbols); + let __sym9 = __pop_Variant25(__symbols); let __sym8 = __pop_Variant0(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant24(__symbols); + let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant68(__symbols); - let __sym2 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant67(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = super::__action1453::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (10, 257) + let __nt = super::__action1502::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (10, 270) } - pub(crate) fn __reduce853< + pub(crate) fn __reduce885< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, ExceptClause+, "else", ":", Suite => ActionFn(1454); + // TryStatement = "try", ":", Suite, ExceptClause+, "else", ":", Suite => ActionFn(1503); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant24(__symbols); + let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant68(__symbols); - let __sym2 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant67(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1454::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (7, 257) + let __nt = super::__action1503::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (7, 270) } - pub(crate) fn __reduce854< + pub(crate) fn __reduce886< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, ExceptClause+, "finally", ":", Suite => ActionFn(1455); + // TryStatement = "try", ":", Suite, ExceptClause+, "finally", ":", Suite => ActionFn(1504); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant24(__symbols); + let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant68(__symbols); - let __sym2 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant67(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1455::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (7, 257) + let __nt = super::__action1504::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (7, 270) } - pub(crate) fn __reduce855< + pub(crate) fn __reduce887< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, ExceptClause+ => ActionFn(1456); + // TryStatement = "try", ":", Suite, ExceptClause+ => ActionFn(1505); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant68(__symbols); - let __sym2 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant67(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1456::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (4, 257) + let __nt = super::__action1505::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (4, 270) } - pub(crate) fn __reduce856< + pub(crate) fn __reduce888< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, ExceptStarClause+, "else", ":", Suite, "finally", ":", Suite => ActionFn(1457); + // TryStatement = "try", ":", Suite, ExceptStarClause+, "else", ":", Suite, "finally", ":", Suite => ActionFn(1506); assert!(__symbols.len() >= 10); - let __sym9 = __pop_Variant24(__symbols); + let __sym9 = __pop_Variant25(__symbols); let __sym8 = __pop_Variant0(__symbols); let __sym7 = __pop_Variant0(__symbols); - let __sym6 = __pop_Variant24(__symbols); + let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant68(__symbols); - let __sym2 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant67(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym9.2; - let __nt = super::__action1457::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (10, 257) + let __nt = super::__action1506::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6, __sym7, __sym8, __sym9); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (10, 270) } - pub(crate) fn __reduce857< + pub(crate) fn __reduce889< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, ExceptStarClause+, "else", ":", Suite => ActionFn(1458); + // TryStatement = "try", ":", Suite, ExceptStarClause+, "else", ":", Suite => ActionFn(1507); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant24(__symbols); + let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant68(__symbols); - let __sym2 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant67(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1458::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (7, 257) + let __nt = super::__action1507::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (7, 270) } - pub(crate) fn __reduce858< + pub(crate) fn __reduce890< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, ExceptStarClause+, "finally", ":", Suite => ActionFn(1459); + // TryStatement = "try", ":", Suite, ExceptStarClause+, "finally", ":", Suite => ActionFn(1508); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant24(__symbols); + let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant68(__symbols); - let __sym2 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant67(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1459::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (7, 257) + let __nt = super::__action1508::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (7, 270) } - pub(crate) fn __reduce859< + pub(crate) fn __reduce891< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, ExceptStarClause+ => ActionFn(1460); + // TryStatement = "try", ":", Suite, ExceptStarClause+ => ActionFn(1509); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant68(__symbols); - let __sym2 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant67(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1460::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (4, 257) + let __nt = super::__action1509::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (4, 270) } - pub(crate) fn __reduce860< + pub(crate) fn __reduce892< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TryStatement = "try", ":", Suite, "finally", ":", Suite => ActionFn(1104); + // TryStatement = "try", ":", Suite, "finally", ":", Suite => ActionFn(1135); assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant24(__symbols); + let __sym5 = __pop_Variant25(__symbols); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant24(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1104::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (6, 257) + let __nt = super::__action1135::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (6, 270) } - pub(crate) fn __reduce861< + pub(crate) fn __reduce893< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TwoOrMore = ClosedPattern, "|", ClosedPattern => ActionFn(336); + // TwoOrMore = ClosedPattern, "|", ClosedPattern => ActionFn(357); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant34(__symbols); + let __sym2 = __pop_Variant35(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant34(__symbols); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action336::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant54(__nt), __end)); - (3, 258) + let __nt = super::__action357::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant53(__nt), __end)); + (3, 271) } - pub(crate) fn __reduce862< + pub(crate) fn __reduce894< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TwoOrMore = TwoOrMore, "|", ClosedPattern => ActionFn(337); + // TwoOrMore = TwoOrMore, "|", ClosedPattern => ActionFn(358); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant34(__symbols); + let __sym2 = __pop_Variant35(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant54(__symbols); + let __sym0 = __pop_Variant53(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action337::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant54(__nt), __end)); - (3, 258) + let __nt = super::__action358::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant53(__nt), __end)); + (3, 271) } - pub(crate) fn __reduce863< + pub(crate) fn __reduce895< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TwoOrMore = Pattern, ",", Pattern => ActionFn(338); + // TwoOrMore = Pattern, ",", Pattern => ActionFn(359); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant34(__symbols); + let __sym2 = __pop_Variant35(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant34(__symbols); + let __sym0 = __pop_Variant35(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action338::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant54(__nt), __end)); - (3, 259) + let __nt = super::__action359::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant53(__nt), __end)); + (3, 272) } - pub(crate) fn __reduce864< + pub(crate) fn __reduce896< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TwoOrMore = TwoOrMore, ",", Pattern => ActionFn(339); + // TwoOrMore = TwoOrMore, ",", Pattern => ActionFn(360); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant34(__symbols); + let __sym2 = __pop_Variant35(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant54(__symbols); + let __sym0 = __pop_Variant53(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action339::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant54(__nt), __end)); - (3, 259) + let __nt = super::__action360::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant53(__nt), __end)); + (3, 272) } - pub(crate) fn __reduce865< + pub(crate) fn __reduce897< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TwoOrMore = Subscript, ",", Subscript => ActionFn(256); + // TwoOrMore = Subscript, ",", Subscript => ActionFn(274); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action256::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (3, 260) + let __nt = super::__action274::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (3, 273) } - pub(crate) fn __reduce866< + pub(crate) fn __reduce898< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TwoOrMore = TwoOrMore, ",", Subscript => ActionFn(257); + // TwoOrMore = TwoOrMore, ",", Subscript => ActionFn(275); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant32(__symbols); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action257::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (3, 260) + let __nt = super::__action275::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (3, 273) } - pub(crate) fn __reduce867< + pub(crate) fn __reduce899< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TwoOrMore = TestOrStarNamedExpr, ",", TestOrStarNamedExpr => ActionFn(343); + // TwoOrMore = TestOrStarNamedExpr, ",", TestOrStarNamedExpr => ActionFn(364); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action343::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (3, 261) + let __nt = super::__action364::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (3, 274) } - pub(crate) fn __reduce868< + pub(crate) fn __reduce900< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TwoOrMore = TwoOrMore, ",", TestOrStarNamedExpr => ActionFn(344); + // TwoOrMore = TwoOrMore, ",", TestOrStarNamedExpr => ActionFn(365); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant32(__symbols); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action344::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant32(__nt), __end)); - (3, 261) + let __nt = super::__action365::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant33(__nt), __end)); + (3, 274) } - pub(crate) fn __reduce869< + pub(crate) fn __reduce901< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeAliasName = Identifier => ActionFn(1461); - let __sym0 = __pop_Variant22(__symbols); + // TypeAliasName = Identifier => ActionFn(1510); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1461::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant45(__nt), __end)); - (1, 262) + let __nt = super::__action1510::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant44(__nt), __end)); + (1, 275) } - pub(crate) fn __reduce870< + pub(crate) fn __reduce902< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeAliasStatement = "type", TypeAliasName, TypeParams, "=", Test<"all"> => ActionFn(1724); + // TypeAliasStatement = "type", TypeAliasName, TypeParams, "=", Test<"all"> => ActionFn(1779); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant14(__symbols); + let __sym4 = __pop_Variant15(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant94(__symbols); - let __sym1 = __pop_Variant45(__symbols); + let __sym2 = __pop_Variant98(__symbols); + let __sym1 = __pop_Variant44(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1724::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (5, 263) + let __nt = super::__action1779::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (5, 276) } - pub(crate) fn __reduce871< + pub(crate) fn __reduce903< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeAliasStatement = "type", TypeAliasName, "=", Test<"all"> => ActionFn(1725); + // TypeAliasStatement = "type", TypeAliasName, "=", Test<"all"> => ActionFn(1780); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant14(__symbols); + let __sym3 = __pop_Variant15(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant45(__symbols); + let __sym1 = __pop_Variant44(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1725::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (4, 263) + let __nt = super::__action1780::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (4, 276) } - pub(crate) fn __reduce872< + pub(crate) fn __reduce904< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeParam = Identifier, ":", Test<"all"> => ActionFn(1463); + // TypeParam = Identifier, ":", Test<"all"> => ActionFn(1512); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant22(__symbols); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1463::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant93(__nt), __end)); - (3, 264) + let __nt = super::__action1512::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant97(__nt), __end)); + (3, 277) } - pub(crate) fn __reduce873< + pub(crate) fn __reduce905< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeParam = Identifier => ActionFn(1464); - let __sym0 = __pop_Variant22(__symbols); + // TypeParam = Identifier => ActionFn(1513); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1464::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant93(__nt), __end)); - (1, 264) + let __nt = super::__action1513::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant97(__nt), __end)); + (1, 277) } - pub(crate) fn __reduce874< + pub(crate) fn __reduce906< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeParam = "*", Identifier => ActionFn(1465); + // TypeParam = "*", Identifier => ActionFn(1514); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant22(__symbols); + let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1465::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant93(__nt), __end)); - (2, 264) + let __nt = super::__action1514::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant97(__nt), __end)); + (2, 277) } - pub(crate) fn __reduce875< + pub(crate) fn __reduce907< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeParam = "**", Identifier => ActionFn(1466); + // TypeParam = "**", Identifier => ActionFn(1515); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant22(__symbols); + let __sym1 = __pop_Variant23(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1466::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant93(__nt), __end)); - (2, 264) + let __nt = super::__action1515::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant97(__nt), __end)); + (2, 277) } - pub(crate) fn __reduce876< + pub(crate) fn __reduce908< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeParams = "[", OneOrMore, ",", "]" => ActionFn(1467); + // TypeParams = "[", OneOrMore, ",", "]" => ActionFn(1516); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant83(__symbols); + let __sym1 = __pop_Variant86(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1467::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant94(__nt), __end)); - (4, 265) + let __nt = super::__action1516::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant98(__nt), __end)); + (4, 278) } - pub(crate) fn __reduce877< + pub(crate) fn __reduce909< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeParams = "[", OneOrMore, "]" => ActionFn(1468); + // TypeParams = "[", OneOrMore, "]" => ActionFn(1517); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant83(__symbols); + let __sym1 = __pop_Variant86(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1468::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant94(__nt), __end)); - (3, 265) + let __nt = super::__action1517::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant98(__nt), __end)); + (3, 278) } - pub(crate) fn __reduce878< + pub(crate) fn __reduce910< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeParams? = TypeParams => ActionFn(284); - let __sym0 = __pop_Variant94(__symbols); + // TypeParams? = TypeParams => ActionFn(304); + let __sym0 = __pop_Variant98(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action284::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant95(__nt), __end)); - (1, 266) + let __nt = super::__action304::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant99(__nt), __end)); + (1, 279) } - pub(crate) fn __reduce879< + pub(crate) fn __reduce911< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypeParams? = => ActionFn(285); + // TypeParams? = => ActionFn(305); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action285::<>(mode, &__start, &__end); - __symbols.push((__start, __Symbol::Variant95(__nt), __end)); - (0, 266) + let __nt = super::__action305::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant99(__nt), __end)); + (0, 279) } - pub(crate) fn __reduce880< + pub(crate) fn __reduce912< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypedParameter = Identifier, ":", Test<"all"> => ActionFn(1469); + // TypedParameter = Identifier, ":", Test<"all"> => ActionFn(1518); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant22(__symbols); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1469::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant10(__nt), __end)); - (3, 267) + let __nt = super::__action1518::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (3, 280) } - pub(crate) fn __reduce881< + pub(crate) fn __reduce913< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // TypedParameter = Identifier => ActionFn(1470); - let __sym0 = __pop_Variant22(__symbols); + // TypedParameter = Identifier => ActionFn(1519); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1470::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant10(__nt), __end)); - (1, 267) + let __nt = super::__action1519::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (1, 280) } - pub(crate) fn __reduce882< + pub(crate) fn __reduce914< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -30012,12 +31724,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action203::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant96(__nt), __end)); - (1, 268) + let __nt = super::__action203::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant100(__nt), __end)); + (1, 281) } - pub(crate) fn __reduce883< + pub(crate) fn __reduce915< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -30028,12 +31741,13 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action204::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant96(__nt), __end)); - (1, 268) + let __nt = super::__action204::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant100(__nt), __end)); + (1, 281) } - pub(crate) fn __reduce884< + pub(crate) fn __reduce916< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -30044,377 +31758,397 @@ mod __parse__Top { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action205::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant96(__nt), __end)); - (1, 268) + let __nt = super::__action205::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant100(__nt), __end)); + (1, 281) } - pub(crate) fn __reduce885< + pub(crate) fn __reduce917< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // UntypedParameter = Identifier => ActionFn(1471); - let __sym0 = __pop_Variant22(__symbols); + // UntypedParameter = Identifier => ActionFn(1520); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1471::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant10(__nt), __end)); - (1, 269) + let __nt = super::__action1520::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (1, 282) } - pub(crate) fn __reduce886< + pub(crate) fn __reduce918< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // ValuePattern = MatchNameOrAttr => ActionFn(1472); - let __sym0 = __pop_Variant45(__symbols); + // ValuePattern = MatchNameOrAttr => ActionFn(1521); + let __sym0 = __pop_Variant44(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1472::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant34(__nt), __end)); - (1, 270) + let __nt = super::__action1521::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant35(__nt), __end)); + (1, 283) } - pub(crate) fn __reduce887< + pub(crate) fn __reduce919< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WhileStatement = "while", NamedExpressionTest, ":", Suite, "else", ":", Suite => ActionFn(1101); + // WhileStatement = "while", NamedExpressionTest, ":", Suite, "else", ":", Suite => ActionFn(1132); assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant24(__symbols); + let __sym6 = __pop_Variant25(__symbols); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1101::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (7, 271) + let __nt = super::__action1132::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (7, 284) } - pub(crate) fn __reduce888< + pub(crate) fn __reduce920< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WhileStatement = "while", NamedExpressionTest, ":", Suite => ActionFn(1102); + // WhileStatement = "while", NamedExpressionTest, ":", Suite => ActionFn(1133); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1102::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (4, 271) + let __nt = super::__action1133::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (4, 284) } - pub(crate) fn __reduce889< + pub(crate) fn __reduce921< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItem<"all"> = Test<"all"> => ActionFn(297); - let __sym0 = __pop_Variant14(__symbols); + // WithItem<"all"> = Test<"all"> => ActionFn(317); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action297::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant17(__nt), __end)); - (1, 272) + let __nt = super::__action317::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant18(__nt), __end)); + (1, 285) } - pub(crate) fn __reduce890< + pub(crate) fn __reduce922< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItem<"all"> = WithItemAs => ActionFn(298); - let __sym0 = __pop_Variant17(__symbols); + // WithItem<"all"> = WithItemAs => ActionFn(318); + let __sym0 = __pop_Variant18(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action298::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant17(__nt), __end)); - (1, 272) + let __nt = super::__action318::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant18(__nt), __end)); + (1, 285) } - pub(crate) fn __reduce891< + pub(crate) fn __reduce923< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItem<"no-withitems"> = Test<"no-withitems"> => ActionFn(292); - let __sym0 = __pop_Variant14(__symbols); + // WithItem<"no-withitems"> = Test<"no-withitems"> => ActionFn(312); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action292::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant17(__nt), __end)); - (1, 273) + let __nt = super::__action312::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant18(__nt), __end)); + (1, 286) } - pub(crate) fn __reduce892< + pub(crate) fn __reduce924< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItem<"no-withitems"> = WithItemAs => ActionFn(293); - let __sym0 = __pop_Variant17(__symbols); + // WithItem<"no-withitems"> = WithItemAs => ActionFn(313); + let __sym0 = __pop_Variant18(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action293::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant17(__nt), __end)); - (1, 273) + let __nt = super::__action313::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant18(__nt), __end)); + (1, 286) } - pub(crate) fn __reduce893< + pub(crate) fn __reduce925< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItemAs = Test<"all">, "as", Expression<"all"> => ActionFn(1473); + // WithItemAs = Test<"all">, "as", Expression<"all"> => ActionFn(1522); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1473::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant17(__nt), __end)); - (3, 274) + let __nt = super::__action1522::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant18(__nt), __end)); + (3, 287) } - pub(crate) fn __reduce894< + pub(crate) fn __reduce926< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", OneOrMore>, ",", ")" => ActionFn(1175); + // WithItems = "(", OneOrMore>, ",", ")" => ActionFn(1206); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1175::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant39(__nt), __end)); - (4, 275) + let __nt = super::__action1206::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant40(__nt), __end)); + (4, 288) } - pub(crate) fn __reduce895< + pub(crate) fn __reduce927< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", OneOrMore>, ")" => ActionFn(1176); + // WithItems = "(", OneOrMore>, ")" => ActionFn(1207); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1176::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant39(__nt), __end)); - (3, 275) + let __nt = super::__action1207::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant40(__nt), __end)); + (3, 288) } - pub(crate) fn __reduce896< + pub(crate) fn __reduce928< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", OneOrMore>, ",", WithItemAs, ",", ")" => ActionFn(1178); + // WithItems = "(", OneOrMore>, ",", WithItemAs, ",", ")" => ActionFn(1209); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant17(__symbols); + let __sym3 = __pop_Variant18(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1178::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant39(__nt), __end)); - (6, 275) + let __nt = super::__action1209::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant40(__nt), __end)); + (6, 288) } - pub(crate) fn __reduce897< + pub(crate) fn __reduce929< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", WithItemAs, ",", ")" => ActionFn(1179); + // WithItems = "(", WithItemAs, ",", ")" => ActionFn(1210); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant17(__symbols); + let __sym1 = __pop_Variant18(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1179::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant39(__nt), __end)); - (4, 275) + let __nt = super::__action1210::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant40(__nt), __end)); + (4, 288) } - pub(crate) fn __reduce898< + pub(crate) fn __reduce930< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", OneOrMore>, ",", WithItemAs, ("," >)+, ",", ")" => ActionFn(1180); + // WithItems = "(", OneOrMore>, ",", WithItemAs, ("," >)+, ",", ")" => ActionFn(1211); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant18(__symbols); - let __sym3 = __pop_Variant17(__symbols); + let __sym4 = __pop_Variant19(__symbols); + let __sym3 = __pop_Variant18(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym6.2; - let __nt = super::__action1180::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant39(__nt), __end)); - (7, 275) + let __nt = super::__action1211::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant40(__nt), __end)); + (7, 288) } - pub(crate) fn __reduce899< + pub(crate) fn __reduce931< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", WithItemAs, ("," >)+, ",", ")" => ActionFn(1181); + // WithItems = "(", WithItemAs, ("," >)+, ",", ")" => ActionFn(1212); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant18(__symbols); - let __sym1 = __pop_Variant17(__symbols); + let __sym2 = __pop_Variant19(__symbols); + let __sym1 = __pop_Variant18(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1181::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant39(__nt), __end)); - (5, 275) + let __nt = super::__action1212::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant40(__nt), __end)); + (5, 288) } - pub(crate) fn __reduce900< + pub(crate) fn __reduce932< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", OneOrMore>, ",", WithItemAs, ")" => ActionFn(1182); + // WithItems = "(", OneOrMore>, ",", WithItemAs, ")" => ActionFn(1213); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant17(__symbols); + let __sym3 = __pop_Variant18(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action1182::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant39(__nt), __end)); - (5, 275) + let __nt = super::__action1213::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant40(__nt), __end)); + (5, 288) } - pub(crate) fn __reduce901< + pub(crate) fn __reduce933< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", WithItemAs, ")" => ActionFn(1183); + // WithItems = "(", WithItemAs, ")" => ActionFn(1214); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant17(__symbols); + let __sym1 = __pop_Variant18(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1183::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant39(__nt), __end)); - (3, 275) + let __nt = super::__action1214::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant40(__nt), __end)); + (3, 288) } - pub(crate) fn __reduce902< + pub(crate) fn __reduce934< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", OneOrMore>, ",", WithItemAs, ("," >)+, ")" => ActionFn(1184); + // WithItems = "(", OneOrMore>, ",", WithItemAs, ("," >)+, ")" => ActionFn(1215); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant18(__symbols); - let __sym3 = __pop_Variant17(__symbols); + let __sym4 = __pop_Variant19(__symbols); + let __sym3 = __pop_Variant18(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant32(__symbols); + let __sym1 = __pop_Variant33(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym5.2; - let __nt = super::__action1184::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant39(__nt), __end)); - (6, 275) + let __nt = super::__action1215::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant40(__nt), __end)); + (6, 288) } - pub(crate) fn __reduce903< + pub(crate) fn __reduce935< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithItems = "(", WithItemAs, ("," >)+, ")" => ActionFn(1185); + // WithItems = "(", WithItemAs, ("," >)+, ")" => ActionFn(1216); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant18(__symbols); - let __sym1 = __pop_Variant17(__symbols); + let __sym2 = __pop_Variant19(__symbols); + let __sym1 = __pop_Variant18(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action1185::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant39(__nt), __end)); - (4, 275) + let __nt = super::__action1216::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant40(__nt), __end)); + (4, 288) } - pub(crate) fn __reduce904< + pub(crate) fn __reduce936< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -30422,15 +32156,16 @@ mod __parse__Top { ) -> (usize, usize) { // WithItems = WithItem<"no-withitems"> => ActionFn(158); - let __sym0 = __pop_Variant17(__symbols); + let __sym0 = __pop_Variant18(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action158::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant39(__nt), __end)); - (1, 275) + let __nt = super::__action158::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant40(__nt), __end)); + (1, 288) } - pub(crate) fn __reduce905< + pub(crate) fn __reduce937< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -30439,16 +32174,17 @@ mod __parse__Top { { // WithItems = WithItem<"all">, ("," >)+ => ActionFn(159); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant18(__symbols); - let __sym0 = __pop_Variant17(__symbols); + let __sym1 = __pop_Variant19(__symbols); + let __sym0 = __pop_Variant18(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action159::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant39(__nt), __end)); - (2, 275) + let __nt = super::__action159::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant40(__nt), __end)); + (2, 288) } - pub(crate) fn __reduce906< + pub(crate) fn __reduce938< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, @@ -30456,176 +32192,218 @@ mod __parse__Top { ) -> (usize, usize) { // WithItemsNoAs = OneOrMore> => ActionFn(160); - let __sym0 = __pop_Variant32(__symbols); + let __sym0 = __pop_Variant33(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action160::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant39(__nt), __end)); - (1, 276) + let __nt = super::__action160::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant40(__nt), __end)); + (1, 289) } - pub(crate) fn __reduce907< + pub(crate) fn __reduce939< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithStatement = "async", "with", WithItems, ":", Suite => ActionFn(929); + // WithStatement = "async", "with", WithItems, ":", Suite => ActionFn(960); assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant24(__symbols); + let __sym4 = __pop_Variant25(__symbols); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant39(__symbols); + let __sym2 = __pop_Variant40(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym4.2; - let __nt = super::__action929::<>(mode, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (5, 277) + let __nt = super::__action960::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (5, 290) } - pub(crate) fn __reduce908< + pub(crate) fn __reduce940< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // WithStatement = "with", WithItems, ":", Suite => ActionFn(930); + // WithStatement = "with", WithItems, ":", Suite => ActionFn(961); assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant24(__symbols); + let __sym3 = __pop_Variant25(__symbols); let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant39(__symbols); + let __sym1 = __pop_Variant40(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym3.2; - let __nt = super::__action930::<>(mode, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant36(__nt), __end)); - (4, 277) + let __nt = super::__action961::<>(source_code, mode, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant37(__nt), __end)); + (4, 290) } - pub(crate) fn __reduce909< + pub(crate) fn __reduce941< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // XorExpression<"all"> = XorExpression<"all">, "^", AndExpression<"all"> => ActionFn(1474); + // XorExpression<"all"> = XorExpression<"all">, "^", AndExpression<"all"> => ActionFn(1523); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1474::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 278) + let __nt = super::__action1523::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 291) } - pub(crate) fn __reduce910< + pub(crate) fn __reduce942< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // XorExpression<"all"> = AndExpression<"all"> => ActionFn(404); - let __sym0 = __pop_Variant14(__symbols); + // XorExpression<"all"> = AndExpression<"all"> => ActionFn(425); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action404::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 278) + let __nt = super::__action425::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 291) } - pub(crate) fn __reduce911< + pub(crate) fn __reduce943< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // XorExpression<"no-withitems"> = XorExpression<"all">, "^", AndExpression<"all"> => ActionFn(1475); + // XorExpression<"no-withitems"> = XorExpression<"all">, "^", AndExpression<"all"> => ActionFn(1524); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant14(__symbols); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1475::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 279) + let __nt = super::__action1524::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 292) } - pub(crate) fn __reduce912< + pub(crate) fn __reduce944< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // XorExpression<"no-withitems"> = AndExpression<"no-withitems"> => ActionFn(509); - let __sym0 = __pop_Variant14(__symbols); + // XorExpression<"no-withitems"> = AndExpression<"no-withitems"> => ActionFn(532); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action509::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 279) + let __nt = super::__action532::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 292) } - pub(crate) fn __reduce913< + pub(crate) fn __reduce945< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // YieldExpr = "yield", GenericList => ActionFn(1695); + // YieldExpr = "yield", GenericList => ActionFn(1750); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant14(__symbols); + let __sym1 = __pop_Variant15(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym1.2; - let __nt = super::__action1695::<>(mode, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (2, 280) + let __nt = super::__action1750::<>(source_code, mode, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 293) } - pub(crate) fn __reduce914< + pub(crate) fn __reduce946< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // YieldExpr = "yield" => ActionFn(1696); + // YieldExpr = "yield" => ActionFn(1751); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym0.2; - let __nt = super::__action1696::<>(mode, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 280) + let __nt = super::__action1751::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 293) } - pub(crate) fn __reduce915< + pub(crate) fn __reduce947< >( + source_code: &str, mode: Mode, __lookahead_start: Option<&TextSize>, __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, _: core::marker::PhantomData<()>, ) -> (usize, usize) { - // YieldExpr = "yield", "from", Test<"all"> => ActionFn(1477); + // YieldExpr = "yield", "from", Test<"all"> => ActionFn(1526); assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant15(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0; let __end = __sym2.2; - let __nt = super::__action1477::<>(mode, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (3, 280) + let __nt = super::__action1526::<>(source_code, mode, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 293) + } + pub(crate) fn __reduce949< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // fstring_middle? = fstring_middle => ActionFn(276); + let __sym0 = __pop_Variant3(__symbols); + let __start = __sym0.0; + let __end = __sym0.2; + let __nt = super::__action276::<>(source_code, mode, __sym0); + __symbols.push((__start, __Symbol::Variant101(__nt), __end)); + (1, 295) + } + pub(crate) fn __reduce950< + >( + source_code: &str, + mode: Mode, + __lookahead_start: Option<&TextSize>, + __symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>, + _: core::marker::PhantomData<()>, + ) -> (usize, usize) + { + // fstring_middle? = => ActionFn(277); + let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); + let __end = __start.clone(); + let __nt = super::__action277::<>(source_code, mode, &__start, &__end); + __symbols.push((__start, __Symbol::Variant101(__nt), __end)); + (0, 295) } } pub(crate) use self::__parse__Top::TopParser; @@ -30634,6 +32412,7 @@ pub(crate) use self::__parse__Top::TopParser; #[allow(clippy::too_many_arguments)] fn __action0< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Mod, TextSize), ) -> ast::Mod @@ -30645,6 +32424,7 @@ fn __action0< #[allow(clippy::too_many_arguments)] fn __action1< >( + source_code: &str, mode: Mode, (_, start, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -30659,6 +32439,7 @@ fn __action1< #[allow(clippy::too_many_arguments)] fn __action2< >( + source_code: &str, mode: Mode, (_, start, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -30674,6 +32455,7 @@ fn __action2< #[allow(clippy::too_many_arguments)] fn __action3< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -30686,6 +32468,7 @@ fn __action3< #[allow(clippy::too_many_arguments)] fn __action4< >( + source_code: &str, mode: Mode, (_, mut statements, _): (TextSize, ast::Suite, TextSize), (_, next, _): (TextSize, ast::Stmt, TextSize), @@ -30701,6 +32484,7 @@ fn __action4< #[allow(clippy::too_many_arguments)] fn __action5< >( + source_code: &str, mode: Mode, (_, mut statements, _): (TextSize, ast::Suite, TextSize), (_, small, _): (TextSize, alloc::vec::Vec, TextSize), @@ -30720,6 +32504,7 @@ fn __action5< #[allow(clippy::too_many_arguments)] fn __action6< >( + source_code: &str, mode: Mode, (_, s, _): (TextSize, ast::Suite, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -30732,6 +32517,7 @@ fn __action6< #[allow(clippy::too_many_arguments)] fn __action7< >( + source_code: &str, mode: Mode, (_, mut statements, _): (TextSize, alloc::vec::Vec, TextSize), (_, last, _): (TextSize, ast::Stmt, TextSize), @@ -30749,6 +32535,7 @@ fn __action7< #[allow(clippy::too_many_arguments)] fn __action8< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -30763,6 +32550,7 @@ fn __action8< #[allow(clippy::too_many_arguments)] fn __action9< >( + source_code: &str, mode: Mode, (_, mut head, _): (TextSize, alloc::vec::Vec, TextSize), (_, last, _): (TextSize, ast::Stmt, TextSize), @@ -30780,6 +32568,7 @@ fn __action9< #[allow(clippy::too_many_arguments)] fn __action10< >( + source_code: &str, mode: Mode, (_, s, _): (TextSize, ast::Stmt, TextSize), ) -> Vec @@ -30791,6 +32580,7 @@ fn __action10< #[allow(clippy::too_many_arguments)] fn __action11< >( + source_code: &str, mode: Mode, (_, mut statements, _): (TextSize, Vec, TextSize), (_, next, _): (TextSize, ast::Stmt, TextSize), @@ -30806,6 +32596,7 @@ fn __action11< #[allow(clippy::too_many_arguments)] fn __action12< >( + source_code: &str, mode: Mode, (_, mut statements, _): (TextSize, Vec, TextSize), (_, small, _): (TextSize, alloc::vec::Vec, TextSize), @@ -30825,6 +32616,7 @@ fn __action12< #[allow(clippy::too_many_arguments)] fn __action13< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -30836,6 +32628,7 @@ fn __action13< #[allow(clippy::too_many_arguments)] fn __action14< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -30847,6 +32640,7 @@ fn __action14< #[allow(clippy::too_many_arguments)] fn __action15< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -30858,6 +32652,7 @@ fn __action15< #[allow(clippy::too_many_arguments)] fn __action16< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -30869,6 +32664,7 @@ fn __action16< #[allow(clippy::too_many_arguments)] fn __action17< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -30880,6 +32676,7 @@ fn __action17< #[allow(clippy::too_many_arguments)] fn __action18< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -30891,6 +32688,7 @@ fn __action18< #[allow(clippy::too_many_arguments)] fn __action19< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -30902,6 +32700,7 @@ fn __action19< #[allow(clippy::too_many_arguments)] fn __action20< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -30913,6 +32712,7 @@ fn __action20< #[allow(clippy::too_many_arguments)] fn __action21< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -30924,6 +32724,7 @@ fn __action21< #[allow(clippy::too_many_arguments)] fn __action22< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -30935,6 +32736,7 @@ fn __action22< #[allow(clippy::too_many_arguments)] fn __action23< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -30946,6 +32748,7 @@ fn __action23< #[allow(clippy::too_many_arguments)] fn __action24< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -30961,6 +32764,7 @@ fn __action24< #[allow(clippy::too_many_arguments)] fn __action25< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -30979,6 +32783,7 @@ fn __action25< #[allow(clippy::too_many_arguments)] fn __action26< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, expression, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -31013,6 +32818,7 @@ fn __action26< #[allow(clippy::too_many_arguments)] fn __action27< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, target, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -31037,6 +32843,7 @@ fn __action27< #[allow(clippy::too_many_arguments)] fn __action28< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, target, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -31064,6 +32871,7 @@ fn __action28< #[allow(clippy::too_many_arguments)] fn __action29< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -31076,6 +32884,7 @@ fn __action29< #[allow(clippy::too_many_arguments)] fn __action30< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -31088,6 +32897,7 @@ fn __action30< #[allow(clippy::too_many_arguments)] fn __action31< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -31099,6 +32909,7 @@ fn __action31< #[allow(clippy::too_many_arguments)] fn __action32< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -31110,6 +32921,7 @@ fn __action32< #[allow(clippy::too_many_arguments)] fn __action33< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -31121,6 +32933,7 @@ fn __action33< #[allow(clippy::too_many_arguments)] fn __action34< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -31132,6 +32945,7 @@ fn __action34< #[allow(clippy::too_many_arguments)] fn __action35< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -31143,6 +32957,7 @@ fn __action35< #[allow(clippy::too_many_arguments)] fn __action36< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -31154,6 +32969,7 @@ fn __action36< #[allow(clippy::too_many_arguments)] fn __action37< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -31165,6 +32981,7 @@ fn __action37< #[allow(clippy::too_many_arguments)] fn __action38< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -31176,6 +32993,7 @@ fn __action38< #[allow(clippy::too_many_arguments)] fn __action39< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -31187,6 +33005,7 @@ fn __action39< #[allow(clippy::too_many_arguments)] fn __action40< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -31198,6 +33017,7 @@ fn __action40< #[allow(clippy::too_many_arguments)] fn __action41< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -31209,6 +33029,7 @@ fn __action41< #[allow(clippy::too_many_arguments)] fn __action42< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -31220,6 +33041,7 @@ fn __action42< #[allow(clippy::too_many_arguments)] fn __action43< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -31231,6 +33053,7 @@ fn __action43< #[allow(clippy::too_many_arguments)] fn __action44< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -31242,6 +33065,7 @@ fn __action44< #[allow(clippy::too_many_arguments)] fn __action45< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -31253,6 +33077,7 @@ fn __action45< #[allow(clippy::too_many_arguments)] fn __action46< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -31264,6 +33089,7 @@ fn __action46< #[allow(clippy::too_many_arguments)] fn __action47< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -31275,6 +33101,7 @@ fn __action47< #[allow(clippy::too_many_arguments)] fn __action48< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -31286,6 +33113,7 @@ fn __action48< #[allow(clippy::too_many_arguments)] fn __action49< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -31297,6 +33125,7 @@ fn __action49< #[allow(clippy::too_many_arguments)] fn __action50< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -31308,6 +33137,7 @@ fn __action50< #[allow(clippy::too_many_arguments)] fn __action51< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -31319,6 +33149,7 @@ fn __action51< #[allow(clippy::too_many_arguments)] fn __action52< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -31330,6 +33161,7 @@ fn __action52< #[allow(clippy::too_many_arguments)] fn __action53< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -31346,6 +33178,7 @@ fn __action53< #[allow(clippy::too_many_arguments)] fn __action54< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -31361,6 +33194,7 @@ fn __action54< #[allow(clippy::too_many_arguments)] fn __action55< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -31379,6 +33213,7 @@ fn __action55< #[allow(clippy::too_many_arguments)] fn __action56< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, expression, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -31396,6 +33231,7 @@ fn __action56< #[allow(clippy::too_many_arguments)] fn __action57< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -31407,6 +33243,7 @@ fn __action57< #[allow(clippy::too_many_arguments)] fn __action58< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -31424,6 +33261,7 @@ fn __action58< #[allow(clippy::too_many_arguments)] fn __action59< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -31443,6 +33281,7 @@ fn __action59< #[allow(clippy::too_many_arguments)] fn __action60< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -31461,6 +33300,7 @@ fn __action60< #[allow(clippy::too_many_arguments)] fn __action61< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -31487,6 +33327,7 @@ fn __action61< #[allow(clippy::too_many_arguments)] fn __action62< >( + source_code: &str, mode: Mode, (_, dots, _): (TextSize, alloc::vec::Vec, TextSize), (_, name, _): (TextSize, ast::Identifier, TextSize), @@ -31501,6 +33342,7 @@ fn __action62< #[allow(clippy::too_many_arguments)] fn __action63< >( + source_code: &str, mode: Mode, (_, dots, _): (TextSize, alloc::vec::Vec, TextSize), ) -> (Option, Option) @@ -31514,6 +33356,7 @@ fn __action63< #[allow(clippy::too_many_arguments)] fn __action64< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> u32 @@ -31525,6 +33368,7 @@ fn __action64< #[allow(clippy::too_many_arguments)] fn __action65< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> u32 @@ -31536,6 +33380,7 @@ fn __action65< #[allow(clippy::too_many_arguments)] fn __action66< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, i, _): (TextSize, Vec, TextSize), @@ -31549,6 +33394,7 @@ fn __action66< #[allow(clippy::too_many_arguments)] fn __action67< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -31565,6 +33411,7 @@ fn __action67< #[allow(clippy::too_many_arguments)] fn __action68< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -31581,6 +33428,7 @@ fn __action68< #[allow(clippy::too_many_arguments)] fn __action69< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, n, _): (TextSize, String, TextSize), @@ -31594,6 +33442,7 @@ fn __action69< #[allow(clippy::too_many_arguments)] fn __action70< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, n, _): (TextSize, String, TextSize), @@ -31615,6 +33464,7 @@ fn __action70< #[allow(clippy::too_many_arguments)] fn __action71< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -31633,6 +33483,7 @@ fn __action71< #[allow(clippy::too_many_arguments)] fn __action72< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -31651,6 +33502,7 @@ fn __action72< #[allow(clippy::too_many_arguments)] fn __action73< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -31674,6 +33526,7 @@ fn __action73< #[allow(clippy::too_many_arguments)] fn __action74< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, c, _): (TextSize, (IpyEscapeKind, String), TextSize), @@ -31702,6 +33555,7 @@ fn __action74< #[allow(clippy::too_many_arguments)] fn __action75< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, c, _): (TextSize, (IpyEscapeKind, String), TextSize), @@ -31735,6 +33589,7 @@ fn __action75< #[allow(clippy::too_many_arguments)] fn __action76< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -31814,6 +33669,7 @@ fn __action76< #[allow(clippy::too_many_arguments)] fn __action77< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -31825,6 +33681,7 @@ fn __action77< #[allow(clippy::too_many_arguments)] fn __action78< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -31836,6 +33693,7 @@ fn __action78< #[allow(clippy::too_many_arguments)] fn __action79< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -31847,6 +33705,7 @@ fn __action79< #[allow(clippy::too_many_arguments)] fn __action80< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -31858,6 +33717,7 @@ fn __action80< #[allow(clippy::too_many_arguments)] fn __action81< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -31869,6 +33729,7 @@ fn __action81< #[allow(clippy::too_many_arguments)] fn __action82< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -31880,6 +33741,7 @@ fn __action82< #[allow(clippy::too_many_arguments)] fn __action83< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -31891,6 +33753,7 @@ fn __action83< #[allow(clippy::too_many_arguments)] fn __action84< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> ast::Stmt @@ -31902,6 +33765,7 @@ fn __action84< #[allow(clippy::too_many_arguments)] fn __action85< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -31935,11 +33799,14 @@ fn __action85< #[allow(clippy::too_many_arguments)] fn __action86< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), + (_, tuple_location, _): (TextSize, TextSize, TextSize), (_, subject, _): (TextSize, ast::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), + (_, tuple_end_location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -31957,7 +33824,13 @@ fn __action86< .end(); ast::Stmt::Match( ast::StmtMatch { - subject: Box::new(subject.into()), + subject: Box::new(ast::Expr::Tuple( + ast::ExprTuple { + elts: vec![subject.into()], + ctx: ast::ExprContext::Load, + range: (tuple_location..tuple_end_location).into() + }, + )), cases, range: (location..end_location).into() } @@ -31969,11 +33842,14 @@ fn __action86< #[allow(clippy::too_many_arguments)] fn __action87< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), + (_, tuple_location, _): (TextSize, TextSize, TextSize), (_, elts, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, core::option::Option, TextSize), + (_, tuple_end_location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -31996,7 +33872,7 @@ fn __action87< ast::ExprTuple { elts, ctx: ast::ExprContext::Load, - range: (location..end_location).into() + range: (tuple_location..tuple_end_location).into() }, )), cases, @@ -32010,6 +33886,7 @@ fn __action87< #[allow(clippy::too_many_arguments)] fn __action88< >( + source_code: &str, mode: Mode, (_, start, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32035,6 +33912,7 @@ fn __action88< #[allow(clippy::too_many_arguments)] fn __action89< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, guard, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -32049,6 +33927,7 @@ fn __action89< #[allow(clippy::too_many_arguments)] fn __action90< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, pattern, _): (TextSize, ast::Pattern, TextSize), @@ -32068,6 +33947,7 @@ fn __action90< #[allow(clippy::too_many_arguments)] fn __action91< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, patterns, _): (TextSize, Vec, TextSize), @@ -32089,6 +33969,7 @@ fn __action91< #[allow(clippy::too_many_arguments)] fn __action92< >( + source_code: &str, mode: Mode, (_, pattern, _): (TextSize, ast::Pattern, TextSize), ) -> ast::Pattern @@ -32100,6 +33981,7 @@ fn __action92< #[allow(clippy::too_many_arguments)] fn __action93< >( + source_code: &str, mode: Mode, (_, pattern, _): (TextSize, ast::Pattern, TextSize), ) -> ast::Pattern @@ -32111,6 +33993,7 @@ fn __action93< #[allow(clippy::too_many_arguments)] fn __action94< >( + source_code: &str, mode: Mode, (_, pattern, _): (TextSize, ast::Pattern, TextSize), ) -> ast::Pattern @@ -32122,6 +34005,7 @@ fn __action94< #[allow(clippy::too_many_arguments)] fn __action95< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, pattern, _): (TextSize, ast::Pattern, TextSize), @@ -32152,6 +34036,7 @@ fn __action95< #[allow(clippy::too_many_arguments)] fn __action96< >( + source_code: &str, mode: Mode, (_, pattern, _): (TextSize, ast::Pattern, TextSize), ) -> ast::Pattern @@ -32163,6 +34048,7 @@ fn __action96< #[allow(clippy::too_many_arguments)] fn __action97< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, patterns, _): (TextSize, Vec, TextSize), @@ -32180,6 +34066,7 @@ fn __action97< #[allow(clippy::too_many_arguments)] fn __action98< >( + source_code: &str, mode: Mode, (_, node, _): (TextSize, ast::Pattern, TextSize), ) -> ast::Pattern @@ -32191,6 +34078,7 @@ fn __action98< #[allow(clippy::too_many_arguments)] fn __action99< >( + source_code: &str, mode: Mode, (_, node, _): (TextSize, ast::Pattern, TextSize), ) -> ast::Pattern @@ -32202,6 +34090,7 @@ fn __action99< #[allow(clippy::too_many_arguments)] fn __action100< >( + source_code: &str, mode: Mode, (_, node, _): (TextSize, ast::Pattern, TextSize), ) -> ast::Pattern @@ -32213,6 +34102,7 @@ fn __action100< #[allow(clippy::too_many_arguments)] fn __action101< >( + source_code: &str, mode: Mode, (_, node, _): (TextSize, ast::Pattern, TextSize), ) -> ast::Pattern @@ -32224,6 +34114,7 @@ fn __action101< #[allow(clippy::too_many_arguments)] fn __action102< >( + source_code: &str, mode: Mode, (_, node, _): (TextSize, ast::Pattern, TextSize), ) -> ast::Pattern @@ -32235,6 +34126,7 @@ fn __action102< #[allow(clippy::too_many_arguments)] fn __action103< >( + source_code: &str, mode: Mode, (_, node, _): (TextSize, ast::Pattern, TextSize), ) -> ast::Pattern @@ -32246,6 +34138,7 @@ fn __action103< #[allow(clippy::too_many_arguments)] fn __action104< >( + source_code: &str, mode: Mode, (_, node, _): (TextSize, ast::Pattern, TextSize), ) -> ast::Pattern @@ -32257,6 +34150,7 @@ fn __action104< #[allow(clippy::too_many_arguments)] fn __action105< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32272,6 +34166,7 @@ fn __action105< #[allow(clippy::too_many_arguments)] fn __action106< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32289,6 +34184,7 @@ fn __action106< #[allow(clippy::too_many_arguments)] fn __action107< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32310,6 +34206,7 @@ fn __action107< #[allow(clippy::too_many_arguments)] fn __action108< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32334,6 +34231,7 @@ fn __action108< #[allow(clippy::too_many_arguments)] fn __action109< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32352,6 +34250,7 @@ fn __action109< #[allow(clippy::too_many_arguments)] fn __action110< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32369,6 +34268,7 @@ fn __action110< #[allow(clippy::too_many_arguments)] fn __action111< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, value, _): (TextSize, ast::Constant, TextSize), @@ -32384,6 +34284,7 @@ fn __action111< #[allow(clippy::too_many_arguments)] fn __action112< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -32395,6 +34296,7 @@ fn __action112< #[allow(clippy::too_many_arguments)] fn __action113< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32415,6 +34317,7 @@ fn __action113< #[allow(clippy::too_many_arguments)] fn __action114< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -32435,6 +34338,7 @@ fn __action114< #[allow(clippy::too_many_arguments)] fn __action115< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32451,6 +34355,7 @@ fn __action115< #[allow(clippy::too_many_arguments)] fn __action116< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32467,6 +34372,7 @@ fn __action116< #[allow(clippy::too_many_arguments)] fn __action117< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32483,6 +34389,7 @@ fn __action117< #[allow(clippy::too_many_arguments)] fn __action118< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -32499,6 +34406,7 @@ fn __action118< #[allow(clippy::too_many_arguments)] fn __action119< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -32515,14 +34423,15 @@ fn __action119< #[allow(clippy::too_many_arguments)] fn __action120< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, s, _): (TextSize, alloc::vec::Vec<(TextSize, (String, StringKind, bool), TextSize)>, TextSize), + (_, strings, _): (TextSize, alloc::vec::Vec, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> Result> { Ok(ast::PatternMatchValue { - value: Box::new(parse_strings(s)?), + value: Box::new(concatenate_strings(strings, (location..end_location).into())?), range: (location..end_location).into() }.into()) } @@ -32531,6 +34440,7 @@ fn __action120< #[allow(clippy::too_many_arguments)] fn __action121< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, name, _): (TextSize, ast::Identifier, TextSize), @@ -32548,6 +34458,7 @@ fn __action121< #[allow(clippy::too_many_arguments)] fn __action122< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, id, _): (TextSize, ast::Identifier, TextSize), @@ -32563,6 +34474,7 @@ fn __action122< #[allow(clippy::too_many_arguments)] fn __action123< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, name, _): (TextSize, ast::Expr, TextSize), @@ -32583,6 +34495,7 @@ fn __action123< #[allow(clippy::too_many_arguments)] fn __action124< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, e, _): (TextSize, ast::Expr, TextSize), @@ -32603,6 +34516,7 @@ fn __action124< #[allow(clippy::too_many_arguments)] fn __action125< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, e, _): (TextSize, ast::Expr, TextSize), @@ -32619,6 +34533,7 @@ fn __action125< #[allow(clippy::too_many_arguments)] fn __action126< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Expr, TextSize), ) -> ast::Expr @@ -32630,6 +34545,7 @@ fn __action126< #[allow(clippy::too_many_arguments)] fn __action127< >( + source_code: &str, mode: Mode, (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::Expr @@ -32641,6 +34557,7 @@ fn __action127< #[allow(clippy::too_many_arguments)] fn __action128< >( + source_code: &str, mode: Mode, (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::Expr @@ -32652,6 +34569,7 @@ fn __action128< #[allow(clippy::too_many_arguments)] fn __action129< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32668,6 +34586,7 @@ fn __action129< #[allow(clippy::too_many_arguments)] fn __action130< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32684,6 +34603,7 @@ fn __action130< #[allow(clippy::too_many_arguments)] fn __action131< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32700,18 +34620,21 @@ fn __action131< #[allow(clippy::too_many_arguments)] fn __action132< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, s, _): (TextSize, alloc::vec::Vec<(TextSize, (String, StringKind, bool), TextSize)>, TextSize), + (_, strings, _): (TextSize, alloc::vec::Vec, TextSize), + (_, end_location, _): (TextSize, TextSize, TextSize), ) -> Result> { - Ok(parse_strings(s)?) + Ok(concatenate_strings(strings, (location..end_location).into())?) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] fn __action133< >( + source_code: &str, mode: Mode, (_, k, _): (TextSize, ast::Expr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32725,6 +34648,7 @@ fn __action133< #[allow(clippy::too_many_arguments)] fn __action134< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32746,6 +34670,7 @@ fn __action134< #[allow(clippy::too_many_arguments)] fn __action135< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32772,6 +34697,7 @@ fn __action135< #[allow(clippy::too_many_arguments)] fn __action136< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32796,6 +34722,7 @@ fn __action136< #[allow(clippy::too_many_arguments)] fn __action137< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32825,6 +34752,7 @@ fn __action137< #[allow(clippy::too_many_arguments)] fn __action138< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, attr, _): (TextSize, ast::Identifier, TextSize), @@ -32844,6 +34772,7 @@ fn __action138< #[allow(clippy::too_many_arguments)] fn __action139< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, cls, _): (TextSize, ast::Expr, TextSize), @@ -32864,6 +34793,7 @@ fn __action139< #[allow(clippy::too_many_arguments)] fn __action140< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, cls, _): (TextSize, ast::Expr, TextSize), @@ -32884,6 +34814,7 @@ fn __action140< #[allow(clippy::too_many_arguments)] fn __action141< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32908,6 +34839,7 @@ fn __action141< #[allow(clippy::too_many_arguments)] fn __action142< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32930,6 +34862,7 @@ fn __action142< #[allow(clippy::too_many_arguments)] fn __action143< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32952,6 +34885,7 @@ fn __action143< #[allow(clippy::too_many_arguments)] fn __action144< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -32972,6 +34906,7 @@ fn __action144< #[allow(clippy::too_many_arguments)] fn __action145< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33007,6 +34942,7 @@ fn __action145< #[allow(clippy::too_many_arguments)] fn __action146< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33038,6 +34974,7 @@ fn __action146< #[allow(clippy::too_many_arguments)] fn __action147< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, is_async, _): (TextSize, core::option::Option, TextSize), @@ -33067,6 +35004,7 @@ fn __action147< #[allow(clippy::too_many_arguments)] fn __action148< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33104,6 +35042,7 @@ fn __action148< #[allow(clippy::too_many_arguments)] fn __action149< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33141,6 +35080,7 @@ fn __action149< #[allow(clippy::too_many_arguments)] fn __action150< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33170,6 +35110,7 @@ fn __action150< #[allow(clippy::too_many_arguments)] fn __action151< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33196,6 +35137,7 @@ fn __action151< #[allow(clippy::too_many_arguments)] fn __action152< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33222,6 +35164,7 @@ fn __action152< #[allow(clippy::too_many_arguments)] fn __action153< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33247,6 +35190,7 @@ fn __action153< #[allow(clippy::too_many_arguments)] fn __action154< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33272,6 +35216,7 @@ fn __action154< #[allow(clippy::too_many_arguments)] fn __action155< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, is_async, _): (TextSize, core::option::Option, TextSize), @@ -33291,6 +35236,7 @@ fn __action155< #[allow(clippy::too_many_arguments)] fn __action156< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, __0, _): (TextSize, Vec, TextSize), @@ -33305,6 +35251,7 @@ fn __action156< #[allow(clippy::too_many_arguments)] fn __action157< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, left, _): (TextSize, core::option::Option>, TextSize), @@ -33323,6 +35270,7 @@ fn __action157< #[allow(clippy::too_many_arguments)] fn __action158< >( + source_code: &str, mode: Mode, (_, item, _): (TextSize, ast::WithItem, TextSize), ) -> Vec @@ -33352,6 +35300,7 @@ fn __action158< #[allow(clippy::too_many_arguments)] fn __action159< >( + source_code: &str, mode: Mode, (_, item, _): (TextSize, ast::WithItem, TextSize), (_, items, _): (TextSize, alloc::vec::Vec, TextSize), @@ -33366,6 +35315,7 @@ fn __action159< #[allow(clippy::too_many_arguments)] fn __action160< >( + source_code: &str, mode: Mode, (_, all, _): (TextSize, Vec, TextSize), ) -> Vec @@ -33383,6 +35333,7 @@ fn __action160< #[allow(clippy::too_many_arguments)] fn __action161< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, context_expr, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -33405,6 +35356,7 @@ fn __action161< #[allow(clippy::too_many_arguments)] fn __action162< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, decorator_list, _): (TextSize, alloc::vec::Vec, TextSize), @@ -33439,6 +35391,7 @@ fn __action162< #[allow(clippy::too_many_arguments)] fn __action163< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, name, _): (TextSize, ast::Identifier, TextSize), @@ -33456,6 +35409,7 @@ fn __action163< #[allow(clippy::too_many_arguments)] fn __action164< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33482,6 +35436,7 @@ fn __action164< #[allow(clippy::too_many_arguments)] fn __action165< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33508,6 +35463,7 @@ fn __action165< #[allow(clippy::too_many_arguments)] fn __action166< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, name, _): (TextSize, ast::Identifier, TextSize), @@ -33524,6 +35480,7 @@ fn __action166< #[allow(clippy::too_many_arguments)] fn __action167< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, arg, _): (TextSize, ast::Identifier, TextSize), @@ -33537,6 +35494,7 @@ fn __action167< #[allow(clippy::too_many_arguments)] fn __action168< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, name, _): (TextSize, ast::Identifier, TextSize), @@ -33555,6 +35513,7 @@ fn __action168< #[allow(clippy::too_many_arguments)] fn __action169< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, name, _): (TextSize, ast::Identifier, TextSize), @@ -33572,6 +35531,7 @@ fn __action169< #[allow(clippy::too_many_arguments)] fn __action170< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, name, _): (TextSize, ast::Identifier, TextSize), @@ -33589,6 +35549,7 @@ fn __action170< #[allow(clippy::too_many_arguments)] fn __action171< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, decorator_list, _): (TextSize, alloc::vec::Vec, TextSize), @@ -33619,6 +35580,7 @@ fn __action171< #[allow(clippy::too_many_arguments)] fn __action172< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33640,6 +35602,7 @@ fn __action172< #[allow(clippy::too_many_arguments)] fn __action173< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, name, _): (TextSize, ast::Identifier, TextSize), @@ -33658,6 +35621,7 @@ fn __action173< #[allow(clippy::too_many_arguments)] fn __action174< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33676,6 +35640,7 @@ fn __action174< #[allow(clippy::too_many_arguments)] fn __action175< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33694,6 +35659,7 @@ fn __action175< #[allow(clippy::too_many_arguments)] fn __action176< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33711,6 +35677,7 @@ fn __action176< #[allow(clippy::too_many_arguments)] fn __action177< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33728,6 +35695,7 @@ fn __action177< #[allow(clippy::too_many_arguments)] fn __action178< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33746,6 +35714,7 @@ fn __action178< #[allow(clippy::too_many_arguments)] fn __action179< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -33757,6 +35726,7 @@ fn __action179< #[allow(clippy::too_many_arguments)] fn __action180< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -33768,6 +35738,7 @@ fn __action180< #[allow(clippy::too_many_arguments)] fn __action181< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, id, _): (TextSize, ast::Identifier, TextSize), @@ -33785,6 +35756,7 @@ fn __action181< #[allow(clippy::too_many_arguments)] fn __action182< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, target, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -33806,6 +35778,7 @@ fn __action182< #[allow(clippy::too_many_arguments)] fn __action183< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -33813,11 +35786,18 @@ fn __action183< (_, parameters, _): (TextSize, core::option::Option, TextSize), (_, end_location_args, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), + (_, fstring_middle, _): (TextSize, core::option::Option<(String, bool)>, TextSize), (_, body, _): (TextSize, ast::ParenthesizedExpr, TextSize), (_, end_location, _): (TextSize, TextSize, TextSize), ) -> Result> { { + if fstring_middle.is_some() { + return Err(LexicalError { + error: LexicalErrorType::FStringError(FStringErrorType::LambdaWithoutParentheses), + location, + })?; + } parameters.as_ref().map(validate_arguments).transpose()?; Ok(ast::ExprLambda { @@ -33832,6 +35812,7 @@ fn __action183< #[allow(clippy::too_many_arguments)] fn __action184< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::CmpOp @@ -33843,6 +35824,7 @@ fn __action184< #[allow(clippy::too_many_arguments)] fn __action185< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::CmpOp @@ -33854,6 +35836,7 @@ fn __action185< #[allow(clippy::too_many_arguments)] fn __action186< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::CmpOp @@ -33865,6 +35848,7 @@ fn __action186< #[allow(clippy::too_many_arguments)] fn __action187< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::CmpOp @@ -33876,6 +35860,7 @@ fn __action187< #[allow(clippy::too_many_arguments)] fn __action188< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::CmpOp @@ -33887,6 +35872,7 @@ fn __action188< #[allow(clippy::too_many_arguments)] fn __action189< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::CmpOp @@ -33898,6 +35884,7 @@ fn __action189< #[allow(clippy::too_many_arguments)] fn __action190< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::CmpOp @@ -33909,6 +35896,7 @@ fn __action190< #[allow(clippy::too_many_arguments)] fn __action191< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), (_, __1, _): (TextSize, token::Tok, TextSize), @@ -33921,6 +35909,7 @@ fn __action191< #[allow(clippy::too_many_arguments)] fn __action192< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::CmpOp @@ -33932,6 +35921,7 @@ fn __action192< #[allow(clippy::too_many_arguments)] fn __action193< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), (_, __1, _): (TextSize, token::Tok, TextSize), @@ -33944,6 +35934,7 @@ fn __action193< #[allow(clippy::too_many_arguments)] fn __action194< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -33955,6 +35946,7 @@ fn __action194< #[allow(clippy::too_many_arguments)] fn __action195< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -33966,6 +35958,7 @@ fn __action195< #[allow(clippy::too_many_arguments)] fn __action196< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -33977,6 +35970,7 @@ fn __action196< #[allow(clippy::too_many_arguments)] fn __action197< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -33988,6 +35982,7 @@ fn __action197< #[allow(clippy::too_many_arguments)] fn __action198< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -33999,6 +35994,7 @@ fn __action198< #[allow(clippy::too_many_arguments)] fn __action199< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -34010,6 +36006,7 @@ fn __action199< #[allow(clippy::too_many_arguments)] fn __action200< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -34021,6 +36018,7 @@ fn __action200< #[allow(clippy::too_many_arguments)] fn __action201< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -34032,6 +36030,7 @@ fn __action201< #[allow(clippy::too_many_arguments)] fn __action202< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::Operator @@ -34043,6 +36042,7 @@ fn __action202< #[allow(clippy::too_many_arguments)] fn __action203< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::UnaryOp @@ -34054,6 +36054,7 @@ fn __action203< #[allow(clippy::too_many_arguments)] fn __action204< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::UnaryOp @@ -34065,6 +36066,7 @@ fn __action204< #[allow(clippy::too_many_arguments)] fn __action205< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> ast::UnaryOp @@ -34076,6 +36078,7 @@ fn __action205< #[allow(clippy::too_many_arguments)] fn __action206< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -34087,6 +36090,7 @@ fn __action206< #[allow(clippy::too_many_arguments)] fn __action207< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, s1, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -34107,6 +36111,7 @@ fn __action207< #[allow(clippy::too_many_arguments)] fn __action208< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, elts, _): (TextSize, Vec, TextSize), @@ -34128,6 +36133,7 @@ fn __action208< #[allow(clippy::too_many_arguments)] fn __action209< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -34139,6 +36145,7 @@ fn __action209< #[allow(clippy::too_many_arguments)] fn __action210< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, lower, _): (TextSize, core::option::Option, TextSize), @@ -34162,6 +36169,7 @@ fn __action210< #[allow(clippy::too_many_arguments)] fn __action211< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -34175,6 +36183,209 @@ fn __action211< #[allow(clippy::too_many_arguments)] fn __action212< >( + source_code: &str, + mode: Mode, + (_, __0, _): (TextSize, StringType, TextSize), +) -> StringType +{ + __0 +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action213< +>( + source_code: &str, + mode: Mode, + (_, __0, _): (TextSize, StringType, TextSize), +) -> StringType +{ + __0 +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action214< +>( + source_code: &str, + mode: Mode, + (_, start_location, _): (TextSize, TextSize, TextSize), + (_, string, _): (TextSize, (String, StringKind, bool), TextSize), +) -> Result> +{ + { + let (source, kind, triple_quoted) = string; + Ok(parse_string_literal(&source, kind, triple_quoted, start_location)?) + } +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action215< +>( + source_code: &str, + mode: Mode, + (_, location, _): (TextSize, TextSize, TextSize), + (_, _, _): (TextSize, token::Tok, TextSize), + (_, values, _): (TextSize, alloc::vec::Vec, TextSize), + (_, _, _): (TextSize, token::Tok, TextSize), + (_, end_location, _): (TextSize, TextSize, TextSize), +) -> StringType +{ + { + StringType::FString(ast::ExprFString { + values, + implicit_concatenated: false, + range: (location..end_location).into() + }) + } +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action216< +>( + source_code: &str, + mode: Mode, + (_, __0, _): (TextSize, ast::Expr, TextSize), +) -> ast::Expr +{ + __0 +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action217< +>( + source_code: &str, + mode: Mode, + (_, start_location, _): (TextSize, TextSize, TextSize), + (_, fstring_middle, _): (TextSize, (String, bool), TextSize), +) -> Result> +{ + { + let (source, is_raw) = fstring_middle; + Ok(parse_fstring_middle(&source, is_raw, start_location)?) + } +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action218< +>( + source_code: &str, + mode: Mode, + (_, location, _): (TextSize, TextSize, TextSize), + (_, _, _): (TextSize, token::Tok, TextSize), + (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), + (_, debug, _): (TextSize, core::option::Option, TextSize), + (_, conversion, _): (TextSize, core::option::Option<(TextSize, ast::ConversionFlag)>, TextSize), + (_, format_spec, _): (TextSize, core::option::Option, TextSize), + (_, _, _): (TextSize, token::Tok, TextSize), + (_, end_location, _): (TextSize, TextSize, TextSize), +) -> Result> +{ + { + if value.expr.is_lambda_expr() && !value.is_parenthesized() { + return Err(LexicalError { + error: LexicalErrorType::FStringError(FStringErrorType::LambdaWithoutParentheses), + location: value.start(), + })?; + } + let debug_text = debug.map(|_| { + let start_offset = location + "{".text_len(); + let end_offset = if let Some((conversion_start, _)) = conversion { + conversion_start + } else { + format_spec.as_ref().map_or_else( + || end_location - "}".text_len(), + |spec| spec.range().start() - ":".text_len(), + ) + }; + ast::DebugText { + leading: source_code[TextRange::new(start_offset, value.range().start())].to_string(), + trailing: source_code[TextRange::new(value.range().end(), end_offset)].to_string(), + } + }); + Ok( + ast::ExprFormattedValue { + value: Box::new(value.into()), + debug_text, + conversion: conversion.map_or(ast::ConversionFlag::None, |(_, conversion_flag)| { + conversion_flag + }), + format_spec: format_spec.map(Box::new), + range: (location..end_location).into(), + } + .into() + ) + } +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action219< +>( + source_code: &str, + mode: Mode, + (_, _, _): (TextSize, token::Tok, TextSize), + (_, format_spec, _): (TextSize, ast::Expr, TextSize), +) -> ast::Expr +{ + format_spec +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action220< +>( + source_code: &str, + mode: Mode, + (_, location, _): (TextSize, TextSize, TextSize), + (_, values, _): (TextSize, alloc::vec::Vec, TextSize), + (_, end_location, _): (TextSize, TextSize, TextSize), +) -> ast::Expr +{ + { + ast::ExprFString { + values, + implicit_concatenated: false, + range: (location..end_location).into() + }.into() + } +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action221< +>( + source_code: &str, + mode: Mode, + (_, location, _): (TextSize, TextSize, TextSize), + (_, _, _): (TextSize, token::Tok, TextSize), + (_, name_location, _): (TextSize, TextSize, TextSize), + (_, s, _): (TextSize, String, TextSize), +) -> Result<(TextSize, ast::ConversionFlag),__lalrpop_util::ParseError> +{ + { + let conversion = match s.as_str() { + "s" => ast::ConversionFlag::Str, + "r" => ast::ConversionFlag::Repr, + "a" => ast::ConversionFlag::Ascii, + _ => Err(LexicalError { + error: LexicalErrorType::FStringError(FStringErrorType::InvalidConversionFlag), + location: name_location, + })? + }; + Ok((location, conversion)) + } +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action222< +>( + source_code: &str, mode: Mode, (_, e, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, core::option::Option, TextSize), @@ -34185,8 +36396,9 @@ fn __action212< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action213< +fn __action223< >( + source_code: &str, mode: Mode, (_, elements, _): (TextSize, Vec<(Option>, ast::ParenthesizedExpr)>, TextSize), (_, _, _): (TextSize, core::option::Option, TextSize), @@ -34197,8 +36409,9 @@ fn __action213< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action214< +fn __action224< >( + source_code: &str, mode: Mode, (_, e1, _): (TextSize, ast::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -34210,8 +36423,9 @@ fn __action214< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action215< +fn __action225< >( + source_code: &str, mode: Mode, (_, e, _): (TextSize, (ast::ParenthesizedExpr, ast::ParenthesizedExpr), TextSize), ) -> (Option>, ast::ParenthesizedExpr) @@ -34221,8 +36435,9 @@ fn __action215< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action216< +fn __action226< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -34233,8 +36448,9 @@ fn __action216< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action217< +fn __action227< >( + source_code: &str, mode: Mode, (_, e1, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, core::option::Option, TextSize), @@ -34245,8 +36461,9 @@ fn __action217< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action218< +fn __action228< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -34256,8 +36473,9 @@ fn __action218< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action219< +fn __action229< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -34267,8 +36485,9 @@ fn __action219< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action220< +fn __action230< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -34278,8 +36497,9 @@ fn __action220< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action221< +fn __action231< >( + source_code: &str, mode: Mode, (_, elements, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, core::option::Option, TextSize), @@ -34290,8 +36510,9 @@ fn __action221< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action222< +fn __action232< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -34301,8 +36522,9 @@ fn __action222< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action223< +fn __action233< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -34319,8 +36541,9 @@ fn __action223< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action224< +fn __action234< >( + source_code: &str, mode: Mode, (_, c, _): (TextSize, alloc::vec::Vec, TextSize), ) -> Vec @@ -34330,8 +36553,9 @@ fn __action224< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action225< +fn __action235< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, is_async, _): (TextSize, core::option::Option, TextSize), @@ -34358,8 +36582,9 @@ fn __action225< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action226< +fn __action236< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -34369,8 +36594,9 @@ fn __action226< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action227< +fn __action237< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, c, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -34381,8 +36607,9 @@ fn __action227< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action228< +fn __action238< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -34403,8 +36630,9 @@ fn __action228< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action229< +fn __action239< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, elt, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -34429,8 +36657,9 @@ fn __action229< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action230< +fn __action240< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, i, _): (TextSize, ast::Identifier, TextSize), @@ -34444,8 +36673,9 @@ fn __action230< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action231< +fn __action241< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -34463,8 +36693,9 @@ fn __action231< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action232< +fn __action242< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -34477,10 +36708,11 @@ fn __action232< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action233< +fn __action243< >( + source_code: &str, mode: Mode, - (_, value, _): (TextSize, BigInt, TextSize), + (_, value, _): (TextSize, Int, TextSize), ) -> ast::Constant { ast::Constant::Int(value) @@ -34488,8 +36720,9 @@ fn __action233< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action234< +fn __action244< >( + source_code: &str, mode: Mode, (_, value, _): (TextSize, f64, TextSize), ) -> ast::Constant @@ -34499,8 +36732,9 @@ fn __action234< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action235< +fn __action245< >( + source_code: &str, mode: Mode, (_, s, _): (TextSize, (f64, f64), TextSize), ) -> ast::Constant @@ -34510,8 +36744,9 @@ fn __action235< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action236< +fn __action246< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, s, _): (TextSize, String, TextSize), @@ -34523,8 +36758,9 @@ fn __action236< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action237< +fn __action247< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, Vec, TextSize), ) -> core::option::Option> @@ -34534,8 +36770,9 @@ fn __action237< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action238< +fn __action248< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -34546,8 +36783,9 @@ fn __action238< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action239< +fn __action249< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, alloc::vec::Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize), (_, last, _): (TextSize, core::option::Option<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize), @@ -34563,8 +36801,9 @@ fn __action239< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action240< +fn __action250< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -34575,8 +36814,9 @@ fn __action240< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action241< +fn __action251< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), ) -> alloc::vec::Vec @@ -34586,8 +36826,9 @@ fn __action241< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action242< +fn __action252< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, values, _): (TextSize, alloc::vec::Vec, TextSize), @@ -34603,8 +36844,9 @@ fn __action242< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action243< +fn __action253< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -34614,8 +36856,9 @@ fn __action243< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action244< +fn __action254< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Comprehension, TextSize), ) -> alloc::vec::Vec @@ -34625,8 +36868,9 @@ fn __action244< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action245< +fn __action255< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, ast::Comprehension, TextSize), @@ -34637,8 +36881,9 @@ fn __action245< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action246< +fn __action256< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, elts, _): (TextSize, Vec, TextSize), @@ -34661,8 +36906,9 @@ fn __action246< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action247< +fn __action257< >( + source_code: &str, mode: Mode, (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> Vec @@ -34672,8 +36918,9 @@ fn __action247< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action248< +fn __action258< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -34688,8 +36935,9 @@ fn __action248< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action249< +fn __action259< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, elts, _): (TextSize, Vec, TextSize), @@ -34712,8 +36960,9 @@ fn __action249< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action250< +fn __action260< >( + source_code: &str, mode: Mode, (_, e, _): (TextSize, (Option>, ast::ParenthesizedExpr), TextSize), ) -> Vec<(Option>, ast::ParenthesizedExpr)> @@ -34723,8 +36972,9 @@ fn __action250< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action251< +fn __action261< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec<(Option>, ast::ParenthesizedExpr)>, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -34739,8 +36989,9 @@ fn __action251< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action252< +fn __action262< >( + source_code: &str, mode: Mode, (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> Vec @@ -34750,8 +37001,9 @@ fn __action252< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action253< +fn __action263< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -34766,8 +37018,109 @@ fn __action253< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action254< +fn __action264< +>( + source_code: &str, + mode: Mode, + (_, __0, _): (TextSize, ast::Expr, TextSize), +) -> core::option::Option +{ + Some(__0) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action265< +>( + source_code: &str, + mode: Mode, + __lookbehind: &TextSize, + __lookahead: &TextSize, +) -> core::option::Option +{ + None +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action266< +>( + source_code: &str, + mode: Mode, + (_, __0, _): (TextSize, (TextSize, ast::ConversionFlag), TextSize), +) -> core::option::Option<(TextSize, ast::ConversionFlag)> +{ + Some(__0) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action267< >( + source_code: &str, + mode: Mode, + __lookbehind: &TextSize, + __lookahead: &TextSize, +) -> core::option::Option<(TextSize, ast::ConversionFlag)> +{ + None +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action268< +>( + source_code: &str, + mode: Mode, + (_, __0, _): (TextSize, token::Tok, TextSize), +) -> core::option::Option +{ + Some(__0) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action269< +>( + source_code: &str, + mode: Mode, + __lookbehind: &TextSize, + __lookahead: &TextSize, +) -> core::option::Option +{ + None +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action270< +>( + source_code: &str, + mode: Mode, + __lookbehind: &TextSize, + __lookahead: &TextSize, +) -> alloc::vec::Vec +{ + alloc::vec![] +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action271< +>( + source_code: &str, + mode: Mode, + (_, v, _): (TextSize, alloc::vec::Vec, TextSize), +) -> alloc::vec::Vec +{ + v +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action272< +>( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, Option, TextSize), ) -> core::option::Option> @@ -34777,8 +37130,9 @@ fn __action254< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action255< +fn __action273< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -34789,8 +37143,9 @@ fn __action255< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action256< +fn __action274< >( + source_code: &str, mode: Mode, (_, e1, _): (TextSize, ast::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -34802,8 +37157,9 @@ fn __action256< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action257< +fn __action275< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -34818,8 +37174,34 @@ fn __action257< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action258< +fn __action276< >( + source_code: &str, + mode: Mode, + (_, __0, _): (TextSize, (String, bool), TextSize), +) -> core::option::Option<(String, bool)> +{ + Some(__0) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action277< +>( + source_code: &str, + mode: Mode, + __lookbehind: &TextSize, + __lookahead: &TextSize, +) -> core::option::Option<(String, bool)> +{ + None +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action278< +>( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Parameters, TextSize), ) -> core::option::Option @@ -34829,8 +37211,9 @@ fn __action258< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action259< +fn __action279< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -34841,8 +37224,9 @@ fn __action259< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action260< +fn __action280< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, param1, _): (TextSize, (Vec, Vec), TextSize), @@ -34871,8 +37255,9 @@ fn __action260< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action261< +fn __action281< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, param1, _): (TextSize, (Vec, Vec), TextSize), @@ -34903,8 +37288,9 @@ fn __action261< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action262< +fn __action282< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, params, _): (TextSize, (Option>, Vec, Option>), TextSize), @@ -34927,8 +37313,9 @@ fn __action262< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action263< +fn __action283< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, kwarg, _): (TextSize, Option>, TextSize), @@ -34950,8 +37337,9 @@ fn __action263< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action264< +fn __action284< >( + source_code: &str, mode: Mode, (_, e, _): (TextSize, ast::TypeParam, TextSize), ) -> Vec @@ -34961,8 +37349,9 @@ fn __action264< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action265< +fn __action285< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -34977,8 +37366,9 @@ fn __action265< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action266< +fn __action286< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Arguments, TextSize), ) -> core::option::Option @@ -34988,8 +37378,9 @@ fn __action266< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action267< +fn __action287< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -35000,8 +37391,9 @@ fn __action267< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action268< +fn __action288< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> core::option::Option @@ -35011,8 +37403,9 @@ fn __action268< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action269< +fn __action289< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -35023,8 +37416,9 @@ fn __action269< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action270< +fn __action290< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -35035,8 +37429,9 @@ fn __action270< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action271< +fn __action291< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> core::option::Option @@ -35046,8 +37441,9 @@ fn __action271< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action272< +fn __action292< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -35058,8 +37454,9 @@ fn __action272< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action273< +fn __action293< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -35070,8 +37467,9 @@ fn __action273< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action274< +fn __action294< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Parameters, TextSize), ) -> core::option::Option @@ -35081,8 +37479,9 @@ fn __action274< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action275< +fn __action295< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -35093,8 +37492,9 @@ fn __action275< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action276< +fn __action296< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Parameters, TextSize), ) -> ast::Parameters @@ -35104,8 +37504,9 @@ fn __action276< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action277< +fn __action297< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, param1, _): (TextSize, (Vec, Vec), TextSize), @@ -35134,8 +37535,9 @@ fn __action277< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action278< +fn __action298< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, param1, _): (TextSize, (Vec, Vec), TextSize), @@ -35166,8 +37568,9 @@ fn __action278< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action279< +fn __action299< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, params, _): (TextSize, (Option>, Vec, Option>), TextSize), @@ -35190,8 +37593,9 @@ fn __action279< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action280< +fn __action300< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, kwarg, _): (TextSize, Option>, TextSize), @@ -35213,8 +37617,9 @@ fn __action280< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action281< +fn __action301< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> core::option::Option @@ -35224,8 +37629,9 @@ fn __action281< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action282< +fn __action302< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -35236,8 +37642,9 @@ fn __action282< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action283< +fn __action303< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -35248,8 +37655,9 @@ fn __action283< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action284< +fn __action304< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::TypeParams, TextSize), ) -> core::option::Option @@ -35259,8 +37667,9 @@ fn __action284< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action285< +fn __action305< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -35271,8 +37680,9 @@ fn __action285< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action286< +fn __action306< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -35283,8 +37693,9 @@ fn __action286< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action287< +fn __action307< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), ) -> alloc::vec::Vec @@ -35294,8 +37705,9 @@ fn __action287< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action288< +fn __action308< >( + source_code: &str, mode: Mode, (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> Vec @@ -35305,8 +37717,9 @@ fn __action288< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action289< +fn __action309< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -35321,8 +37734,9 @@ fn __action289< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action290< +fn __action310< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::WithItem, TextSize), ) -> alloc::vec::Vec @@ -35332,8 +37746,9 @@ fn __action290< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action291< +fn __action311< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, ast::WithItem, TextSize), @@ -35344,8 +37759,9 @@ fn __action291< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action292< +fn __action312< >( + source_code: &str, mode: Mode, (_, context_expr, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::WithItem @@ -35361,8 +37777,9 @@ fn __action292< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action293< +fn __action313< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::WithItem, TextSize), ) -> ast::WithItem @@ -35372,8 +37789,9 @@ fn __action293< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action294< +fn __action314< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -35384,8 +37802,9 @@ fn __action294< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action295< +fn __action315< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), ) -> alloc::vec::Vec @@ -35395,8 +37814,9 @@ fn __action295< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action296< +fn __action316< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, __0, _): (TextSize, ast::WithItem, TextSize), @@ -35407,8 +37827,9 @@ fn __action296< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action297< +fn __action317< >( + source_code: &str, mode: Mode, (_, context_expr, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::WithItem @@ -35424,8 +37845,9 @@ fn __action297< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action298< +fn __action318< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::WithItem, TextSize), ) -> ast::WithItem @@ -35435,8 +37857,9 @@ fn __action298< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action299< +fn __action319< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, Vec, TextSize), ) -> core::option::Option> @@ -35446,8 +37869,9 @@ fn __action299< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action300< +fn __action320< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -35458,8 +37882,9 @@ fn __action300< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action301< +fn __action321< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -35470,8 +37895,9 @@ fn __action301< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action302< +fn __action322< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> core::option::Option @@ -35481,8 +37907,9 @@ fn __action302< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action303< +fn __action323< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -35493,8 +37920,9 @@ fn __action303< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action304< +fn __action324< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -35506,8 +37934,9 @@ fn __action304< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action305< +fn __action325< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ExceptHandler, TextSize), ) -> alloc::vec::Vec @@ -35517,8 +37946,9 @@ fn __action305< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action306< +fn __action326< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, ast::ExceptHandler, TextSize), @@ -35529,8 +37959,9 @@ fn __action306< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action307< +fn __action327< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Suite, TextSize), ) -> core::option::Option @@ -35540,8 +37971,9 @@ fn __action307< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action308< +fn __action328< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -35552,8 +37984,9 @@ fn __action308< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action309< +fn __action329< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -35565,8 +37998,9 @@ fn __action309< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action310< +fn __action330< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ExceptHandler, TextSize), ) -> alloc::vec::Vec @@ -35576,8 +38010,9 @@ fn __action310< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action311< +fn __action331< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, ast::ExceptHandler, TextSize), @@ -35588,8 +38023,9 @@ fn __action311< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action312< +fn __action332< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> core::option::Option @@ -35599,8 +38035,9 @@ fn __action312< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action313< +fn __action333< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -35611,8 +38048,9 @@ fn __action313< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action314< +fn __action334< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Suite, TextSize), ) -> core::option::Option @@ -35622,8 +38060,9 @@ fn __action314< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action315< +fn __action335< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -35634,8 +38073,9 @@ fn __action315< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action316< +fn __action336< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -35647,8 +38087,9 @@ fn __action316< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action317< +fn __action337< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, (TextSize, ast::Suite), TextSize), ) -> core::option::Option<(TextSize, ast::Suite)> @@ -35658,8 +38099,9 @@ fn __action317< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action318< +fn __action338< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -35670,8 +38112,9 @@ fn __action318< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action319< +fn __action339< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -35684,8 +38127,9 @@ fn __action319< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action320< +fn __action340< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -35696,8 +38140,9 @@ fn __action320< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action321< +fn __action341< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)>, TextSize), ) -> alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)> @@ -35707,8 +38152,9 @@ fn __action321< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action322< +fn __action342< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -35722,8 +38168,9 @@ fn __action322< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action323< +fn __action343< >( + source_code: &str, mode: Mode, (_, e, _): (TextSize, ast::PatternKeyword, TextSize), ) -> Vec @@ -35733,8 +38180,9 @@ fn __action323< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action324< +fn __action344< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -35749,8 +38197,9 @@ fn __action324< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action325< +fn __action345< >( + source_code: &str, mode: Mode, (_, e, _): (TextSize, ast::Pattern, TextSize), ) -> Vec @@ -35760,8 +38209,9 @@ fn __action325< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action326< +fn __action346< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -35776,8 +38226,9 @@ fn __action326< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action327< +fn __action347< >( + source_code: &str, mode: Mode, (_, e, _): (TextSize, (ast::Expr, ast::Pattern), TextSize), ) -> Vec<(ast::Expr, ast::Pattern)> @@ -35787,8 +38238,9 @@ fn __action327< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action328< +fn __action348< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec<(ast::Expr, ast::Pattern)>, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -35803,44 +38255,59 @@ fn __action328< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action329< +fn __action349< >( + source_code: &str, mode: Mode, - (_, __0, _): (TextSize, (TextSize, (String, StringKind, bool), TextSize), TextSize), -) -> alloc::vec::Vec<(TextSize, (String, StringKind, bool), TextSize)> + (_, __0, _): (TextSize, StringType, TextSize), +) -> alloc::vec::Vec { alloc::vec![__0] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action330< +fn __action350< >( + source_code: &str, mode: Mode, - (_, v, _): (TextSize, alloc::vec::Vec<(TextSize, (String, StringKind, bool), TextSize)>, TextSize), - (_, e, _): (TextSize, (TextSize, (String, StringKind, bool), TextSize), TextSize), -) -> alloc::vec::Vec<(TextSize, (String, StringKind, bool), TextSize)> + (_, v, _): (TextSize, alloc::vec::Vec, TextSize), + (_, e, _): (TextSize, StringType, TextSize), +) -> alloc::vec::Vec { { let mut v = v; v.push(e); v } } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action331< +fn __action351< >( + source_code: &str, mode: Mode, - (_, __0, _): (TextSize, TextSize, TextSize), - (_, __1, _): (TextSize, (String, StringKind, bool), TextSize), - (_, __2, _): (TextSize, TextSize, TextSize), -) -> (TextSize, (String, StringKind, bool), TextSize) + (_, __0, _): (TextSize, StringType, TextSize), +) -> alloc::vec::Vec { - (__0, __1, __2) + alloc::vec![__0] } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action332< +fn __action352< >( + source_code: &str, + mode: Mode, + (_, v, _): (TextSize, alloc::vec::Vec, TextSize), + (_, e, _): (TextSize, StringType, TextSize), +) -> alloc::vec::Vec +{ + { let mut v = v; v.push(e); v } +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action353< +>( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, alloc::vec::Vec, TextSize), (_, last, _): (TextSize, core::option::Option, TextSize), @@ -35856,8 +38323,9 @@ fn __action332< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action333< +fn __action354< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Pattern, TextSize), ) -> alloc::vec::Vec @@ -35867,8 +38335,9 @@ fn __action333< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action334< +fn __action355< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, ast::Pattern, TextSize), @@ -35879,8 +38348,9 @@ fn __action334< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action335< +fn __action356< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Pattern, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -35891,8 +38361,9 @@ fn __action335< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action336< +fn __action357< >( + source_code: &str, mode: Mode, (_, e1, _): (TextSize, ast::Pattern, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -35904,8 +38375,9 @@ fn __action336< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action337< +fn __action358< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -35920,8 +38392,9 @@ fn __action337< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action338< +fn __action359< >( + source_code: &str, mode: Mode, (_, e1, _): (TextSize, ast::Pattern, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -35933,8 +38406,9 @@ fn __action338< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action339< +fn __action360< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -35949,8 +38423,9 @@ fn __action339< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action340< +fn __action361< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Expr, TextSize), ) -> core::option::Option @@ -35960,8 +38435,9 @@ fn __action340< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action341< +fn __action362< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -35972,8 +38448,9 @@ fn __action341< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action342< +fn __action363< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Expr, TextSize), ) -> ast::Expr @@ -35983,8 +38460,9 @@ fn __action342< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action343< +fn __action364< >( + source_code: &str, mode: Mode, (_, e1, _): (TextSize, ast::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -35996,8 +38474,9 @@ fn __action343< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action344< +fn __action365< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -36012,8 +38491,9 @@ fn __action344< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action345< +fn __action366< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::MatchCase, TextSize), ) -> alloc::vec::Vec @@ -36023,8 +38503,9 @@ fn __action345< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action346< +fn __action367< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, ast::MatchCase, TextSize), @@ -36035,8 +38516,9 @@ fn __action346< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action347< +fn __action368< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> alloc::vec::Vec @@ -36046,8 +38528,9 @@ fn __action347< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action348< +fn __action369< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, token::Tok, TextSize), @@ -36058,8 +38541,9 @@ fn __action348< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action349< +fn __action370< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> token::Tok @@ -36069,8 +38553,9 @@ fn __action349< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action350< +fn __action371< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -36089,8 +38574,9 @@ fn __action350< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action351< +fn __action372< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -36100,8 +38586,9 @@ fn __action351< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action352< +fn __action373< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> core::option::Option @@ -36111,8 +38598,9 @@ fn __action352< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action353< +fn __action374< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -36123,8 +38611,9 @@ fn __action353< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action354< +fn __action375< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -36135,8 +38624,9 @@ fn __action354< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action355< +fn __action376< >( + source_code: &str, mode: Mode, (_, e, _): (TextSize, ast::Identifier, TextSize), ) -> Vec @@ -36146,8 +38636,9 @@ fn __action355< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action356< +fn __action377< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -36162,8 +38653,9 @@ fn __action356< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action357< +fn __action378< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, (token::Tok, ast::Identifier), TextSize), ) -> alloc::vec::Vec<(token::Tok, ast::Identifier)> @@ -36173,8 +38665,9 @@ fn __action357< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action358< +fn __action379< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec<(token::Tok, ast::Identifier)>, TextSize), (_, e, _): (TextSize, (token::Tok, ast::Identifier), TextSize), @@ -36185,8 +38678,9 @@ fn __action358< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action359< +fn __action380< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), (_, __1, _): (TextSize, ast::Identifier, TextSize), @@ -36197,8 +38691,9 @@ fn __action359< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action360< +fn __action381< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> core::option::Option @@ -36208,8 +38703,9 @@ fn __action360< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action361< +fn __action382< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -36220,8 +38716,9 @@ fn __action361< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action362< +fn __action383< >( + source_code: &str, mode: Mode, (_, e, _): (TextSize, ast::Alias, TextSize), ) -> Vec @@ -36231,8 +38728,9 @@ fn __action362< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action363< +fn __action384< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -36247,8 +38745,9 @@ fn __action363< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action364< +fn __action385< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, name, _): (TextSize, ast::Identifier, TextSize), @@ -36261,8 +38760,9 @@ fn __action364< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action365< +fn __action386< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, u32, TextSize), ) -> alloc::vec::Vec @@ -36272,8 +38772,9 @@ fn __action365< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action366< +fn __action387< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, u32, TextSize), @@ -36284,8 +38785,9 @@ fn __action366< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action367< +fn __action388< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -36296,8 +38798,9 @@ fn __action367< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action368< +fn __action389< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), ) -> alloc::vec::Vec @@ -36307,8 +38810,9 @@ fn __action368< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action369< +fn __action390< >( + source_code: &str, mode: Mode, (_, e, _): (TextSize, ast::Alias, TextSize), ) -> Vec @@ -36318,8 +38822,9 @@ fn __action369< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action370< +fn __action391< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -36334,8 +38839,9 @@ fn __action370< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action371< +fn __action392< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, name, _): (TextSize, ast::Identifier, TextSize), @@ -36348,8 +38854,9 @@ fn __action371< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action372< +fn __action393< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> core::option::Option @@ -36359,8 +38866,9 @@ fn __action372< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action373< +fn __action394< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -36371,8 +38879,9 @@ fn __action373< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action374< +fn __action395< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -36383,8 +38892,9 @@ fn __action374< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action375< +fn __action396< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> core::option::Option @@ -36394,8 +38904,9 @@ fn __action375< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action376< +fn __action397< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -36406,8 +38917,9 @@ fn __action376< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action377< +fn __action398< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> core::option::Option @@ -36417,8 +38929,9 @@ fn __action377< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action378< +fn __action399< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -36429,8 +38942,9 @@ fn __action378< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action379< +fn __action400< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, body, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -36451,8 +38965,9 @@ fn __action379< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action380< +fn __action401< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -36462,8 +38977,9 @@ fn __action380< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action381< +fn __action402< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -36473,8 +38989,9 @@ fn __action381< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action382< +fn __action403< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -36485,8 +39002,9 @@ fn __action382< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action383< +fn __action404< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), ) -> alloc::vec::Vec @@ -36496,8 +39014,9 @@ fn __action383< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action384< +fn __action405< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> core::option::Option @@ -36507,8 +39026,9 @@ fn __action384< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action385< +fn __action406< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -36519,8 +39039,9 @@ fn __action385< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action386< +fn __action407< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -36531,8 +39052,9 @@ fn __action386< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action387< +fn __action408< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), ) -> alloc::vec::Vec @@ -36542,8 +39064,9 @@ fn __action387< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action388< +fn __action409< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -36554,8 +39077,9 @@ fn __action388< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action389< +fn __action410< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -36566,8 +39090,9 @@ fn __action389< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action390< +fn __action411< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), ) -> alloc::vec::Vec @@ -36577,8 +39102,9 @@ fn __action390< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action391< +fn __action412< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> token::Tok @@ -36587,8 +39113,9 @@ fn __action391< } #[allow(unused_variables)] -fn __action392< +fn __action413< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -36598,8 +39125,9 @@ fn __action392< } #[allow(unused_variables)] -fn __action393< +fn __action414< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -36610,8 +39138,9 @@ fn __action393< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action394< +fn __action415< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, token::Tok, TextSize), ) -> alloc::vec::Vec @@ -36621,8 +39150,9 @@ fn __action394< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action395< +fn __action416< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, token::Tok, TextSize), @@ -36633,8 +39163,9 @@ fn __action395< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action396< +fn __action417< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Stmt, TextSize), ) -> alloc::vec::Vec @@ -36644,8 +39175,9 @@ fn __action396< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action397< +fn __action418< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, ast::Stmt, TextSize), @@ -36656,8 +39188,9 @@ fn __action397< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action398< +fn __action419< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> alloc::vec::Vec @@ -36667,8 +39200,9 @@ fn __action398< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action399< +fn __action420< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -36679,8 +39213,9 @@ fn __action399< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action400< +fn __action421< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Identifier, TextSize), ) -> core::option::Option @@ -36690,8 +39225,9 @@ fn __action400< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action401< +fn __action422< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -36702,8 +39238,9 @@ fn __action401< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action402< +fn __action423< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, __0, _): (TextSize, ast::Identifier, TextSize), @@ -36714,8 +39251,9 @@ fn __action402< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action403< +fn __action424< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -36734,8 +39272,9 @@ fn __action403< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action404< +fn __action425< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -36745,8 +39284,9 @@ fn __action404< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action405< +fn __action426< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Pattern, TextSize), ) -> core::option::Option @@ -36756,8 +39296,9 @@ fn __action405< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action406< +fn __action427< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -36768,8 +39309,9 @@ fn __action406< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action407< +fn __action428< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -36780,8 +39322,9 @@ fn __action407< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action408< +fn __action429< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), ) -> alloc::vec::Vec @@ -36791,8 +39334,9 @@ fn __action408< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action409< +fn __action430< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, (TextSize, ast::ParenthesizedExpr, ast::Suite), TextSize), ) -> alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)> @@ -36802,8 +39346,9 @@ fn __action409< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action410< +fn __action431< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)>, TextSize), (_, e, _): (TextSize, (TextSize, ast::ParenthesizedExpr, ast::Suite), TextSize), @@ -36814,8 +39359,9 @@ fn __action410< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action411< +fn __action432< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, body, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -36836,8 +39382,9 @@ fn __action411< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action412< +fn __action433< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -36847,8 +39394,9 @@ fn __action412< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action413< +fn __action434< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -36858,8 +39406,9 @@ fn __action413< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action414< +fn __action435< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Decorator, TextSize), ) -> alloc::vec::Vec @@ -36869,8 +39418,9 @@ fn __action414< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action415< +fn __action436< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, ast::Decorator, TextSize), @@ -36881,8 +39431,9 @@ fn __action415< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action416< +fn __action437< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, __0, _): (TextSize, Option>, TextSize), @@ -36893,8 +39444,9 @@ fn __action416< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action417< +fn __action438< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, kwarg, _): (TextSize, core::option::Option, TextSize), @@ -36907,8 +39459,9 @@ fn __action417< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action418< +fn __action439< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, (Option>, Vec, Option>), TextSize), ) -> core::option::Option<(Option>, Vec, Option>)> @@ -36918,8 +39471,9 @@ fn __action418< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action419< +fn __action440< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -36930,8 +39484,9 @@ fn __action419< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action420< +fn __action441< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, __0, _): (TextSize, (Option>, Vec, Option>), TextSize), @@ -36942,8 +39497,9 @@ fn __action420< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action421< +fn __action442< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -36969,8 +39525,9 @@ fn __action421< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action422< +fn __action443< >( + source_code: &str, mode: Mode, (_, args, _): (TextSize, Vec, TextSize), ) -> (Vec, Vec) @@ -36982,8 +39539,9 @@ fn __action422< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action423< +fn __action444< >( + source_code: &str, mode: Mode, (_, posonlyargs, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -36998,8 +39556,9 @@ fn __action423< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action424< +fn __action445< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, __0, _): (TextSize, Option>, TextSize), @@ -37010,8 +39569,9 @@ fn __action424< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action425< +fn __action446< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, kwarg, _): (TextSize, core::option::Option, TextSize), @@ -37024,8 +39584,9 @@ fn __action425< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action426< +fn __action447< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, (Option>, Vec, Option>), TextSize), ) -> core::option::Option<(Option>, Vec, Option>)> @@ -37035,8 +39596,9 @@ fn __action426< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action427< +fn __action448< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -37047,8 +39609,9 @@ fn __action427< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action428< +fn __action449< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, __0, _): (TextSize, (Option>, Vec, Option>), TextSize), @@ -37059,8 +39622,9 @@ fn __action428< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action429< +fn __action450< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -37086,8 +39650,9 @@ fn __action429< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action430< +fn __action451< >( + source_code: &str, mode: Mode, (_, args, _): (TextSize, Vec, TextSize), ) -> (Vec, Vec) @@ -37099,8 +39664,9 @@ fn __action430< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action431< +fn __action452< >( + source_code: &str, mode: Mode, (_, posonlyargs, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -37115,8 +39681,34 @@ fn __action431< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action432< +fn __action453< >( + source_code: &str, + mode: Mode, + (_, __0, _): (TextSize, ast::Expr, TextSize), +) -> alloc::vec::Vec +{ + alloc::vec![__0] +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action454< +>( + source_code: &str, + mode: Mode, + (_, v, _): (TextSize, alloc::vec::Vec, TextSize), + (_, e, _): (TextSize, ast::Expr, TextSize), +) -> alloc::vec::Vec +{ + { let mut v = v; v.push(e); v } +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action455< +>( + source_code: &str, mode: Mode, (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> Vec @@ -37126,8 +39718,9 @@ fn __action432< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action433< +fn __action456< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -37142,8 +39735,9 @@ fn __action433< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action434< +fn __action457< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> alloc::vec::Vec @@ -37153,8 +39747,9 @@ fn __action434< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action435< +fn __action458< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -37165,8 +39760,9 @@ fn __action435< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action436< +fn __action459< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -37177,8 +39773,9 @@ fn __action436< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action437< +fn __action460< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, values, _): (TextSize, alloc::vec::Vec, TextSize), @@ -37194,8 +39791,9 @@ fn __action437< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action438< +fn __action461< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -37205,8 +39803,9 @@ fn __action438< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action439< +fn __action462< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> alloc::vec::Vec @@ -37216,8 +39815,9 @@ fn __action439< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action440< +fn __action463< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -37228,8 +39828,9 @@ fn __action440< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action441< +fn __action464< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, (Option<(TextSize, TextSize, Option)>, ast::Expr), TextSize), ) -> core::option::Option<(Option<(TextSize, TextSize, Option)>, ast::Expr)> @@ -37239,8 +39840,9 @@ fn __action441< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action442< +fn __action465< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -37251,8 +39853,9 @@ fn __action442< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action443< +fn __action466< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -37263,8 +39866,9 @@ fn __action443< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action444< +fn __action467< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize), ) -> alloc::vec::Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)> @@ -37274,8 +39878,9 @@ fn __action444< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action445< +fn __action468< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, (Option<(TextSize, TextSize, Option)>, ast::Expr), TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -37286,8 +39891,9 @@ fn __action445< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action446< +fn __action469< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, (Option<(TextSize, TextSize, Option)>, ast::Expr), TextSize), ) -> alloc::vec::Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)> @@ -37297,8 +39903,9 @@ fn __action446< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action447< +fn __action470< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize), (_, e, _): (TextSize, (Option<(TextSize, TextSize, Option)>, ast::Expr), TextSize), @@ -37309,8 +39916,9 @@ fn __action447< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action448< +fn __action471< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> alloc::vec::Vec @@ -37320,8 +39928,9 @@ fn __action448< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action449< +fn __action472< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -37332,8 +39941,9 @@ fn __action449< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action450< +fn __action473< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -37344,8 +39954,9 @@ fn __action450< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action451< +fn __action474< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -37362,8 +39973,9 @@ fn __action451< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action452< +fn __action475< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -37373,8 +39985,9 @@ fn __action452< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action453< +fn __action476< >( + source_code: &str, mode: Mode, (_, e, _): (TextSize, ast::ParameterWithDefault, TextSize), ) -> Vec @@ -37384,8 +39997,9 @@ fn __action453< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action454< +fn __action477< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -37400,8 +40014,9 @@ fn __action454< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action455< +fn __action478< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, Option>, TextSize), ) -> core::option::Option>> @@ -37411,8 +40026,9 @@ fn __action455< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action456< +fn __action479< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -37423,8 +40039,9 @@ fn __action456< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action457< +fn __action480< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -37435,8 +40052,9 @@ fn __action457< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action458< +fn __action481< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), ) -> alloc::vec::Vec @@ -37446,8 +40064,9 @@ fn __action458< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action459< +fn __action482< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, __0, _): (TextSize, ast::ParameterWithDefault, TextSize), @@ -37458,8 +40077,9 @@ fn __action459< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action460< +fn __action483< >( + source_code: &str, mode: Mode, (_, i, _): (TextSize, ast::ParameterWithDefault, TextSize), ) -> ast::ParameterWithDefault @@ -37469,8 +40089,9 @@ fn __action460< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action461< +fn __action484< >( + source_code: &str, mode: Mode, (_, mut i, _): (TextSize, ast::ParameterWithDefault, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -37487,8 +40108,9 @@ fn __action461< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action462< +fn __action485< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Parameter, TextSize), ) -> core::option::Option @@ -37498,8 +40120,9 @@ fn __action462< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action463< +fn __action486< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -37510,8 +40133,9 @@ fn __action463< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action464< +fn __action487< >( + source_code: &str, mode: Mode, (_, e, _): (TextSize, ast::ParameterWithDefault, TextSize), ) -> Vec @@ -37521,8 +40145,9 @@ fn __action464< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action465< +fn __action488< >( + source_code: &str, mode: Mode, (_, mut v, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -37537,8 +40162,9 @@ fn __action465< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action466< +fn __action489< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, Option>, TextSize), ) -> core::option::Option>> @@ -37548,8 +40174,9 @@ fn __action466< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action467< +fn __action490< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -37560,8 +40187,9 @@ fn __action467< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action468< +fn __action491< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -37572,8 +40200,9 @@ fn __action468< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action469< +fn __action492< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), ) -> alloc::vec::Vec @@ -37583,8 +40212,9 @@ fn __action469< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action470< +fn __action493< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, __0, _): (TextSize, ast::ParameterWithDefault, TextSize), @@ -37595,8 +40225,9 @@ fn __action470< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action471< +fn __action494< >( + source_code: &str, mode: Mode, (_, i, _): (TextSize, ast::ParameterWithDefault, TextSize), ) -> ast::ParameterWithDefault @@ -37606,8 +40237,9 @@ fn __action471< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action472< +fn __action495< >( + source_code: &str, mode: Mode, (_, mut i, _): (TextSize, ast::ParameterWithDefault, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -37624,8 +40256,9 @@ fn __action472< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action473< +fn __action496< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Parameter, TextSize), ) -> core::option::Option @@ -37635,8 +40268,9 @@ fn __action473< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action474< +fn __action497< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -37647,8 +40281,9 @@ fn __action474< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action475< +fn __action498< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::Parameter, TextSize), ) -> core::option::Option @@ -37658,8 +40293,9 @@ fn __action475< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action476< +fn __action499< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -37670,8 +40306,9 @@ fn __action476< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action477< +fn __action500< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, values, _): (TextSize, alloc::vec::Vec, TextSize), @@ -37687,8 +40324,9 @@ fn __action477< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action478< +fn __action501< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -37698,8 +40336,9 @@ fn __action478< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action479< +fn __action502< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -37718,8 +40357,9 @@ fn __action479< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action480< +fn __action503< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -37729,8 +40369,9 @@ fn __action480< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action481< +fn __action504< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -37749,8 +40390,9 @@ fn __action481< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action482< +fn __action505< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -37760,8 +40402,9 @@ fn __action482< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action483< +fn __action506< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, values, _): (TextSize, alloc::vec::Vec, TextSize), @@ -37777,8 +40420,9 @@ fn __action483< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action484< +fn __action507< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -37788,8 +40432,9 @@ fn __action484< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action485< +fn __action508< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParameterWithDefault, TextSize), ) -> alloc::vec::Vec @@ -37799,8 +40444,9 @@ fn __action485< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action486< +fn __action509< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, ast::ParameterWithDefault, TextSize), @@ -37811,8 +40457,9 @@ fn __action486< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action487< +fn __action510< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParameterWithDefault, TextSize), ) -> alloc::vec::Vec @@ -37822,8 +40469,9 @@ fn __action487< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action488< +fn __action511< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, ast::ParameterWithDefault, TextSize), @@ -37834,8 +40482,9 @@ fn __action488< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action489< +fn __action512< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -37851,8 +40500,9 @@ fn __action489< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action490< +fn __action513< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -37862,8 +40512,9 @@ fn __action490< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action491< +fn __action514< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, (ast::CmpOp, ast::ParenthesizedExpr), TextSize), ) -> alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)> @@ -37873,8 +40524,9 @@ fn __action491< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action492< +fn __action515< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize), (_, e, _): (TextSize, (ast::CmpOp, ast::ParenthesizedExpr), TextSize), @@ -37885,8 +40537,9 @@ fn __action492< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action493< +fn __action516< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::CmpOp, TextSize), (_, __1, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -37897,8 +40550,9 @@ fn __action493< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action494< +fn __action517< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -37915,8 +40569,9 @@ fn __action494< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action495< +fn __action518< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -37926,8 +40581,9 @@ fn __action495< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action496< +fn __action519< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -37946,8 +40602,9 @@ fn __action496< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action497< +fn __action520< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -37957,8 +40614,9 @@ fn __action497< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action498< +fn __action521< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -37977,8 +40635,9 @@ fn __action498< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action499< +fn __action522< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -37988,8 +40647,9 @@ fn __action499< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action500< +fn __action523< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -38005,8 +40665,9 @@ fn __action500< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action501< +fn __action524< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -38016,8 +40677,9 @@ fn __action501< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action502< +fn __action525< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -38036,8 +40698,9 @@ fn __action502< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action503< +fn __action526< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -38047,8 +40710,9 @@ fn __action503< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action504< +fn __action527< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, op, _): (TextSize, ast::UnaryOp, TextSize), @@ -38065,8 +40729,9 @@ fn __action504< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action505< +fn __action528< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -38076,8 +40741,9 @@ fn __action505< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action506< +fn __action529< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -38096,8 +40762,9 @@ fn __action506< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action507< +fn __action530< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -38107,8 +40774,9 @@ fn __action507< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action508< +fn __action531< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -38127,8 +40795,9 @@ fn __action508< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action509< +fn __action532< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -38138,8 +40807,9 @@ fn __action509< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action510< +fn __action533< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -38158,8 +40828,9 @@ fn __action510< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action511< +fn __action534< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -38169,8 +40840,9 @@ fn __action511< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action512< +fn __action535< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38185,8 +40857,9 @@ fn __action512< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action513< +fn __action536< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -38196,8 +40869,9 @@ fn __action513< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action514< +fn __action537< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -38207,8 +40881,9 @@ fn __action514< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action515< +fn __action538< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, func, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -38225,8 +40900,9 @@ fn __action515< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action516< +fn __action539< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -38246,8 +40922,9 @@ fn __action516< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action517< +fn __action540< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -38266,8 +40943,9 @@ fn __action517< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action518< +fn __action541< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -38286,8 +40964,9 @@ fn __action518< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action519< +fn __action542< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -38297,8 +40976,9 @@ fn __action519< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action520< +fn __action543< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -38317,8 +40997,9 @@ fn __action520< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action521< +fn __action544< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -38328,20 +41009,23 @@ fn __action521< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action522< +fn __action545< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, s, _): (TextSize, alloc::vec::Vec<(TextSize, (String, StringKind, bool), TextSize)>, TextSize), + (_, strings, _): (TextSize, alloc::vec::Vec, TextSize), + (_, end_location, _): (TextSize, TextSize, TextSize), ) -> Result> { - Ok(parse_strings(s)?.into()) + Ok(concatenate_strings(strings, (location..end_location).into())?.into()) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action523< +fn __action546< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, value, _): (TextSize, ast::Constant, TextSize), @@ -38356,8 +41040,9 @@ fn __action523< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action524< +fn __action547< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, id, _): (TextSize, ast::Identifier, TextSize), @@ -38373,8 +41058,9 @@ fn __action524< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action525< +fn __action548< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38391,8 +41077,9 @@ fn __action525< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action526< +fn __action549< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38409,8 +41096,9 @@ fn __action526< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action527< +fn __action550< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38435,8 +41123,9 @@ fn __action527< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action528< +fn __action551< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38469,8 +41158,9 @@ fn __action528< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action529< +fn __action552< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38487,8 +41177,9 @@ fn __action529< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action530< +fn __action553< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38505,8 +41196,9 @@ fn __action530< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action531< +fn __action554< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38525,8 +41217,9 @@ fn __action531< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action532< +fn __action555< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, location, _): (TextSize, TextSize, TextSize), @@ -38546,8 +41239,9 @@ fn __action532< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action533< +fn __action556< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38568,8 +41262,9 @@ fn __action533< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action534< +fn __action557< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38591,8 +41286,9 @@ fn __action534< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action535< +fn __action558< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38612,8 +41308,9 @@ fn __action535< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action536< +fn __action559< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38632,8 +41329,9 @@ fn __action536< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action537< +fn __action560< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38645,8 +41343,9 @@ fn __action537< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action538< +fn __action561< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38658,8 +41357,9 @@ fn __action538< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action539< +fn __action562< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38671,8 +41371,9 @@ fn __action539< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action540< +fn __action563< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38684,8 +41385,9 @@ fn __action540< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action541< +fn __action564< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, Vec<(Option>, ast::ParenthesizedExpr)>, TextSize), ) -> core::option::Option>, ast::ParenthesizedExpr)>> @@ -38695,8 +41397,9 @@ fn __action541< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action542< +fn __action565< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -38707,8 +41410,9 @@ fn __action542< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action543< +fn __action566< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -38719,8 +41423,9 @@ fn __action543< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action544< +fn __action567< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), ) -> alloc::vec::Vec @@ -38730,8 +41435,9 @@ fn __action544< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action545< +fn __action568< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -38742,8 +41448,9 @@ fn __action545< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action546< +fn __action569< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, Vec, TextSize), ) -> core::option::Option> @@ -38753,8 +41460,9 @@ fn __action546< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action547< +fn __action570< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -38765,8 +41473,9 @@ fn __action547< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action548< +fn __action571< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, Vec, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38777,8 +41486,9 @@ fn __action548< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action549< +fn __action572< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, Vec, TextSize), ) -> core::option::Option> @@ -38788,8 +41498,9 @@ fn __action549< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action550< +fn __action573< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -38800,8 +41511,9 @@ fn __action550< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action551< +fn __action574< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -38820,8 +41532,9 @@ fn __action551< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action552< +fn __action575< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -38831,8 +41544,9 @@ fn __action552< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action553< +fn __action576< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, op, _): (TextSize, ast::UnaryOp, TextSize), @@ -38849,8 +41563,9 @@ fn __action553< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action554< +fn __action577< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -38860,8 +41575,9 @@ fn __action554< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action555< +fn __action578< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> alloc::vec::Vec @@ -38871,8 +41587,9 @@ fn __action555< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action556< +fn __action579< >( + source_code: &str, mode: Mode, (_, v, _): (TextSize, alloc::vec::Vec, TextSize), (_, e, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -38883,8 +41600,9 @@ fn __action556< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action557< +fn __action580< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, left, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -38903,8 +41621,9 @@ fn __action557< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action558< +fn __action581< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -38914,8 +41633,9 @@ fn __action558< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action559< +fn __action582< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -38930,8 +41650,9 @@ fn __action559< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action560< +fn __action583< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -38941,8 +41662,9 @@ fn __action560< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action561< +fn __action584< >( + source_code: &str, mode: Mode, (_, __0, _): (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr @@ -38952,8 +41674,9 @@ fn __action561< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action562< +fn __action585< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, func, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -38970,8 +41693,9 @@ fn __action562< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action563< +fn __action586< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -38991,8 +41715,9 @@ fn __action563< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action564< +fn __action587< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, value, _): (TextSize, ast::ParenthesizedExpr, TextSize), @@ -39011,20 +41736,23 @@ fn __action564< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action565< +fn __action588< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), - (_, s, _): (TextSize, alloc::vec::Vec<(TextSize, (String, StringKind, bool), TextSize)>, TextSize), + (_, strings, _): (TextSize, alloc::vec::Vec, TextSize), + (_, end_location, _): (TextSize, TextSize, TextSize), ) -> Result> { - Ok(parse_strings(s)?.into()) + Ok(concatenate_strings(strings, (location..end_location).into())?.into()) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action566< +fn __action589< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, value, _): (TextSize, ast::Constant, TextSize), @@ -39039,8 +41767,9 @@ fn __action566< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action567< +fn __action590< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, id, _): (TextSize, ast::Identifier, TextSize), @@ -39056,8 +41785,9 @@ fn __action567< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action568< +fn __action591< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -39074,8 +41804,9 @@ fn __action568< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action569< +fn __action592< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -39092,8 +41823,9 @@ fn __action569< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action570< +fn __action593< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -39126,8 +41858,9 @@ fn __action570< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action571< +fn __action594< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -39144,8 +41877,9 @@ fn __action571< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action572< +fn __action595< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -39162,8 +41896,9 @@ fn __action572< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action573< +fn __action596< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -39182,8 +41917,9 @@ fn __action573< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action574< +fn __action597< >( + source_code: &str, mode: Mode, (_, _, _): (TextSize, token::Tok, TextSize), (_, location, _): (TextSize, TextSize, TextSize), @@ -39203,8 +41939,9 @@ fn __action574< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action575< +fn __action598< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -39225,8 +41962,9 @@ fn __action575< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action576< +fn __action599< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -39248,8 +41986,9 @@ fn __action576< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action577< +fn __action600< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -39269,8 +42008,9 @@ fn __action577< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action578< +fn __action601< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -39289,8 +42029,9 @@ fn __action578< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action579< +fn __action602< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -39302,8 +42043,9 @@ fn __action579< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action580< +fn __action603< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -39315,8 +42057,9 @@ fn __action580< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action581< +fn __action604< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -39328,8 +42071,9 @@ fn __action581< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action582< +fn __action605< >( + source_code: &str, mode: Mode, (_, location, _): (TextSize, TextSize, TextSize), (_, _, _): (TextSize, token::Tok, TextSize), @@ -39341,8 +42085,9 @@ fn __action582< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action583< +fn __action606< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -39354,12 +42099,14 @@ fn __action583< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action527( + __action550( + source_code, mode, __0, __1, @@ -39372,8 +42119,9 @@ fn __action583< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action584< +fn __action607< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -39384,13 +42132,15 @@ fn __action584< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action527( + __action550( + source_code, mode, __0, __1, @@ -39403,8 +42153,9 @@ fn __action584< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action585< +fn __action608< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -39418,12 +42169,14 @@ fn __action585< { let __start0 = __5.0; let __end0 = __5.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __5, ); let __temp0 = (__start0, __temp0, __end0); - __action528( + __action551( + source_code, mode, __0, __1, @@ -39438,8 +42191,9 @@ fn __action585< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action586< +fn __action609< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -39452,13 +42206,15 @@ fn __action586< { let __start0 = __4.2; let __end0 = __5.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action528( + __action551( + source_code, mode, __0, __1, @@ -39473,8 +42229,9 @@ fn __action586< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action587< +fn __action610< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -39488,12 +42245,14 @@ fn __action587< { let __start0 = __5.0; let __end0 = __5.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __5, ); let __temp0 = (__start0, __temp0, __end0); - __action570( + __action593( + source_code, mode, __0, __1, @@ -39508,8 +42267,9 @@ fn __action587< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action588< +fn __action611< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -39522,13 +42282,15 @@ fn __action588< { let __start0 = __4.2; let __end0 = __5.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action570( + __action593( + source_code, mode, __0, __1, @@ -39543,8 +42305,9 @@ fn __action588< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action589< +fn __action612< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec<(Option>, ast::ParenthesizedExpr)>, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -39552,12 +42315,14 @@ fn __action589< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action213( + __action223( + source_code, mode, __0, __temp0, @@ -39566,21 +42331,24 @@ fn __action589< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action590< +fn __action613< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec<(Option>, ast::ParenthesizedExpr)>, TextSize), ) -> Vec<(Option>, ast::ParenthesizedExpr)> { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action213( + __action223( + source_code, mode, __0, __temp0, @@ -39589,8 +42357,9 @@ fn __action590< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action591< +fn __action614< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -39598,12 +42367,14 @@ fn __action591< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action221( + __action231( + source_code, mode, __0, __temp0, @@ -39612,21 +42383,24 @@ fn __action591< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action592< +fn __action615< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), ) -> Vec { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action221( + __action231( + source_code, mode, __0, __temp0, @@ -39635,8 +42409,9 @@ fn __action592< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action593< +fn __action616< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, Vec, TextSize), @@ -39646,12 +42421,14 @@ fn __action593< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action249( + __action259( + source_code, mode, __0, __1, @@ -39662,8 +42439,9 @@ fn __action593< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action594< +fn __action617< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, Vec, TextSize), @@ -39672,13 +42450,15 @@ fn __action594< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action249( + __action259( + source_code, mode, __0, __1, @@ -39689,8 +42469,9 @@ fn __action594< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action595< +fn __action618< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, Vec, TextSize), @@ -39700,12 +42481,14 @@ fn __action595< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action246( + __action256( + source_code, mode, __0, __1, @@ -39716,8 +42499,9 @@ fn __action595< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action596< +fn __action619< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, Vec, TextSize), @@ -39726,13 +42510,15 @@ fn __action596< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action246( + __action256( + source_code, mode, __0, __1, @@ -39743,8 +42529,9 @@ fn __action596< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action597< +fn __action620< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -39756,12 +42543,14 @@ fn __action597< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); __action67( + source_code, mode, __0, __1, @@ -39774,8 +42563,9 @@ fn __action597< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action598< +fn __action621< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -39786,13 +42576,15 @@ fn __action598< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action67( + source_code, mode, __0, __1, @@ -39805,8 +42597,9 @@ fn __action598< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action599< +fn __action622< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -39814,12 +42607,14 @@ fn __action599< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action212( + __action222( + source_code, mode, __0, __temp0, @@ -39828,21 +42623,24 @@ fn __action599< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action600< +fn __action623< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), ) -> Vec { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action212( + __action222( + source_code, mode, __0, __temp0, @@ -39851,8 +42649,9 @@ fn __action600< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action601< +fn __action624< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -39864,12 +42663,14 @@ fn __action601< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); __action135( + source_code, mode, __0, __1, @@ -39882,8 +42683,9 @@ fn __action601< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action602< +fn __action625< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -39894,13 +42696,15 @@ fn __action602< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action135( + source_code, mode, __0, __1, @@ -39913,8 +42717,9 @@ fn __action602< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action603< +fn __action626< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -39927,12 +42732,14 @@ fn __action603< { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); __action136( + source_code, mode, __0, __1, @@ -39946,8 +42753,9 @@ fn __action603< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action604< +fn __action627< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -39959,13 +42767,15 @@ fn __action604< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action136( + source_code, mode, __0, __1, @@ -39979,8 +42789,9 @@ fn __action604< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action605< +fn __action628< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -39995,12 +42806,14 @@ fn __action605< { let __start0 = __6.0; let __end0 = __6.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __6, ); let __temp0 = (__start0, __temp0, __end0); __action137( + source_code, mode, __0, __1, @@ -40016,8 +42829,9 @@ fn __action605< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action606< +fn __action629< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -40031,13 +42845,15 @@ fn __action606< { let __start0 = __5.2; let __end0 = __6.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action137( + source_code, mode, __0, __1, @@ -40053,82 +42869,97 @@ fn __action606< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action607< +fn __action630< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, Vec, TextSize), - __3: (TextSize, token::Tok, TextSize), + __2: (TextSize, TextSize, TextSize), + __3: (TextSize, Vec, TextSize), __4: (TextSize, token::Tok, TextSize), - __5: (TextSize, token::Tok, TextSize), + __5: (TextSize, TextSize, TextSize), __6: (TextSize, token::Tok, TextSize), - __7: (TextSize, alloc::vec::Vec, TextSize), + __7: (TextSize, token::Tok, TextSize), __8: (TextSize, token::Tok, TextSize), + __9: (TextSize, alloc::vec::Vec, TextSize), + __10: (TextSize, token::Tok, TextSize), ) -> ast::Stmt { - let __start0 = __3.0; - let __end0 = __3.2; - let __temp0 = __action360( + let __start0 = __4.0; + let __end0 = __4.2; + let __temp0 = __action381( + source_code, mode, - __3, + __4, ); let __temp0 = (__start0, __temp0, __end0); __action87( + source_code, mode, __0, __1, __2, + __3, __temp0, - __4, __5, __6, __7, __8, + __9, + __10, ) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action608< +fn __action631< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, Vec, TextSize), - __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, token::Tok, TextSize), + __2: (TextSize, TextSize, TextSize), + __3: (TextSize, Vec, TextSize), + __4: (TextSize, TextSize, TextSize), __5: (TextSize, token::Tok, TextSize), - __6: (TextSize, alloc::vec::Vec, TextSize), + __6: (TextSize, token::Tok, TextSize), __7: (TextSize, token::Tok, TextSize), + __8: (TextSize, alloc::vec::Vec, TextSize), + __9: (TextSize, token::Tok, TextSize), ) -> ast::Stmt { - let __start0 = __2.2; - let __end0 = __3.0; - let __temp0 = __action361( + let __start0 = __3.2; + let __end0 = __4.0; + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action87( + source_code, mode, __0, __1, __2, - __temp0, __3, + __temp0, __4, __5, __6, __7, + __8, + __9, ) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action609< +fn __action632< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, (Vec, Vec), TextSize), @@ -40139,12 +42970,14 @@ fn __action609< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action277( + __action297( + source_code, mode, __0, __1, @@ -40156,8 +42989,9 @@ fn __action609< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action610< +fn __action633< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, (Vec, Vec), TextSize), @@ -40167,13 +43001,15 @@ fn __action610< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action277( + __action297( + source_code, mode, __0, __1, @@ -40185,8 +43021,9 @@ fn __action610< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action611< +fn __action634< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, (Vec, Vec), TextSize), @@ -40197,12 +43034,14 @@ fn __action611< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action278( + __action298( + source_code, mode, __0, __1, @@ -40214,8 +43053,9 @@ fn __action611< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action612< +fn __action635< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, (Vec, Vec), TextSize), @@ -40225,13 +43065,15 @@ fn __action612< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action278( + __action298( + source_code, mode, __0, __1, @@ -40243,8 +43085,9 @@ fn __action612< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action613< +fn __action636< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, (Option>, Vec, Option>), TextSize), @@ -40254,12 +43097,14 @@ fn __action613< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action279( + __action299( + source_code, mode, __0, __1, @@ -40270,8 +43115,9 @@ fn __action613< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action614< +fn __action637< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, (Option>, Vec, Option>), TextSize), @@ -40280,13 +43126,15 @@ fn __action614< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action279( + __action299( + source_code, mode, __0, __1, @@ -40297,8 +43145,9 @@ fn __action614< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action615< +fn __action638< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, Option>, TextSize), @@ -40308,12 +43157,14 @@ fn __action615< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action280( + __action300( + source_code, mode, __0, __1, @@ -40324,8 +43175,9 @@ fn __action615< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action616< +fn __action639< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, Option>, TextSize), @@ -40334,13 +43186,15 @@ fn __action616< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action280( + __action300( + source_code, mode, __0, __1, @@ -40351,8 +43205,9 @@ fn __action616< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action617< +fn __action640< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, (Vec, Vec), TextSize), @@ -40363,12 +43218,14 @@ fn __action617< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action260( + __action280( + source_code, mode, __0, __1, @@ -40380,8 +43237,9 @@ fn __action617< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action618< +fn __action641< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, (Vec, Vec), TextSize), @@ -40391,13 +43249,15 @@ fn __action618< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action260( + __action280( + source_code, mode, __0, __1, @@ -40409,8 +43269,9 @@ fn __action618< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action619< +fn __action642< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, (Vec, Vec), TextSize), @@ -40421,12 +43282,14 @@ fn __action619< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action261( + __action281( + source_code, mode, __0, __1, @@ -40438,8 +43301,9 @@ fn __action619< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action620< +fn __action643< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, (Vec, Vec), TextSize), @@ -40449,13 +43313,15 @@ fn __action620< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action261( + __action281( + source_code, mode, __0, __1, @@ -40467,8 +43333,9 @@ fn __action620< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action621< +fn __action644< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, (Option>, Vec, Option>), TextSize), @@ -40478,12 +43345,14 @@ fn __action621< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action262( + __action282( + source_code, mode, __0, __1, @@ -40494,8 +43363,9 @@ fn __action621< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action622< +fn __action645< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, (Option>, Vec, Option>), TextSize), @@ -40504,13 +43374,15 @@ fn __action622< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action262( + __action282( + source_code, mode, __0, __1, @@ -40521,8 +43393,9 @@ fn __action622< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action623< +fn __action646< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, Option>, TextSize), @@ -40532,12 +43405,14 @@ fn __action623< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action263( + __action283( + source_code, mode, __0, __1, @@ -40548,8 +43423,9 @@ fn __action623< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action624< +fn __action647< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, Option>, TextSize), @@ -40558,13 +43434,15 @@ fn __action624< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action263( + __action283( + source_code, mode, __0, __1, @@ -40575,8 +43453,9 @@ fn __action624< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action625< +fn __action648< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -40590,12 +43469,14 @@ fn __action625< { let __start0 = __5.0; let __end0 = __5.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __5, ); let __temp0 = (__start0, __temp0, __end0); __action141( + source_code, mode, __0, __1, @@ -40610,8 +43491,9 @@ fn __action625< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action626< +fn __action649< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -40624,13 +43506,15 @@ fn __action626< { let __start0 = __4.2; let __end0 = __5.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action141( + source_code, mode, __0, __1, @@ -40645,8 +43529,9 @@ fn __action626< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action627< +fn __action650< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -40658,12 +43543,14 @@ fn __action627< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); __action142( + source_code, mode, __0, __1, @@ -40676,8 +43563,9 @@ fn __action627< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action628< +fn __action651< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -40688,13 +43576,15 @@ fn __action628< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action142( + source_code, mode, __0, __1, @@ -40707,8 +43597,9 @@ fn __action628< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action629< +fn __action652< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -40720,12 +43611,14 @@ fn __action629< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); __action143( + source_code, mode, __0, __1, @@ -40738,8 +43631,9 @@ fn __action629< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action630< +fn __action653< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -40750,13 +43644,15 @@ fn __action630< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action143( + source_code, mode, __0, __1, @@ -40769,8 +43665,9 @@ fn __action630< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action631< +fn __action654< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, Vec, TextSize), @@ -40780,12 +43677,14 @@ fn __action631< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); __action91( + source_code, mode, __0, __1, @@ -40796,8 +43695,9 @@ fn __action631< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action632< +fn __action655< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, Vec, TextSize), @@ -40806,13 +43706,15 @@ fn __action632< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action91( + source_code, mode, __0, __1, @@ -40823,8 +43725,9 @@ fn __action632< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action633< +fn __action656< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -40837,12 +43740,14 @@ fn __action633< { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); __action108( + source_code, mode, __0, __1, @@ -40856,8 +43761,9 @@ fn __action633< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action634< +fn __action657< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -40869,13 +43775,15 @@ fn __action634< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action108( + source_code, mode, __0, __1, @@ -40889,8 +43797,9 @@ fn __action634< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action635< +fn __action658< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -40898,12 +43807,14 @@ fn __action635< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action217( + __action227( + source_code, mode, __0, __temp0, @@ -40912,21 +43823,24 @@ fn __action635< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action636< +fn __action659< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), ) -> Vec { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action217( + __action227( + source_code, mode, __0, __temp0, @@ -40935,8 +43849,9 @@ fn __action636< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action637< +fn __action660< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, Vec, TextSize), @@ -40946,12 +43861,14 @@ fn __action637< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); __action208( + source_code, mode, __0, __1, @@ -40962,8 +43879,9 @@ fn __action637< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action638< +fn __action661< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, Vec, TextSize), @@ -40972,13 +43890,15 @@ fn __action638< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action208( + source_code, mode, __0, __1, @@ -40989,8 +43909,9 @@ fn __action638< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action639< +fn __action662< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -41002,12 +43923,14 @@ fn __action639< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); __action172( + source_code, mode, __0, __1, @@ -41020,8 +43943,9 @@ fn __action639< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action640< +fn __action663< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -41032,13 +43956,15 @@ fn __action640< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action172( + source_code, mode, __0, __1, @@ -41051,8 +43977,9 @@ fn __action640< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action641< +fn __action664< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -41062,12 +43989,14 @@ fn __action641< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); __action156( + source_code, mode, __0, __1, @@ -41078,8 +44007,9 @@ fn __action641< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action642< +fn __action665< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -41088,13 +44018,15 @@ fn __action642< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action156( + source_code, mode, __0, __1, @@ -41105,8 +44037,9 @@ fn __action642< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action643< +fn __action666< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -41118,12 +44051,14 @@ fn __action643< { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action360( + let __temp0 = __action381( + source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); __action157( + source_code, mode, __0, __1, @@ -41136,8 +44071,9 @@ fn __action643< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action644< +fn __action667< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -41148,13 +44084,15 @@ fn __action644< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action361( + let __temp0 = __action382( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action157( + source_code, mode, __0, __1, @@ -41167,8 +44105,9 @@ fn __action644< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action645< +fn __action668< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Suite, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -41179,12 +44118,14 @@ fn __action645< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action384( + let __temp0 = __action405( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); __action5( + source_code, mode, __0, __1, @@ -41196,8 +44137,9 @@ fn __action645< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action646< +fn __action669< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Suite, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -41207,13 +44149,15 @@ fn __action646< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action385( + let __temp0 = __action406( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action5( + source_code, mode, __0, __1, @@ -41225,8 +44169,9 @@ fn __action646< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action647< +fn __action670< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::Stmt, TextSize), @@ -41236,12 +44181,14 @@ fn __action647< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action384( + let __temp0 = __action405( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); __action9( + source_code, mode, __0, __1, @@ -41252,8 +44199,9 @@ fn __action647< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action648< +fn __action671< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::Stmt, TextSize), @@ -41262,13 +44210,15 @@ fn __action648< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action385( + let __temp0 = __action406( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action9( + source_code, mode, __0, __1, @@ -41279,8 +44229,9 @@ fn __action648< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action649< +fn __action672< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -41291,12 +44242,14 @@ fn __action649< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action384( + let __temp0 = __action405( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); __action12( + source_code, mode, __0, __1, @@ -41308,8 +44261,9 @@ fn __action649< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action650< +fn __action673< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -41319,13 +44273,15 @@ fn __action650< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action385( + let __temp0 = __action406( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action12( + source_code, mode, __0, __1, @@ -41337,8 +44293,9 @@ fn __action650< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action651< +fn __action674< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::Stmt, TextSize), @@ -41348,12 +44305,14 @@ fn __action651< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action384( + let __temp0 = __action405( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); __action7( + source_code, mode, __0, __1, @@ -41364,8 +44323,9 @@ fn __action651< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action652< +fn __action675< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::Stmt, TextSize), @@ -41374,13 +44334,15 @@ fn __action652< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action385( + let __temp0 = __action406( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action7( + source_code, mode, __0, __1, @@ -41391,8 +44353,85 @@ fn __action652< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action653< +fn __action676< >( + source_code: &str, + mode: Mode, + __0: (TextSize, TextSize, TextSize), + __1: (TextSize, token::Tok, TextSize), + __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, token::Tok, TextSize), + __4: (TextSize, core::option::Option<(TextSize, ast::ConversionFlag)>, TextSize), + __5: (TextSize, core::option::Option, TextSize), + __6: (TextSize, token::Tok, TextSize), + __7: (TextSize, TextSize, TextSize), +) -> Result> +{ + let __start0 = __3.0; + let __end0 = __3.2; + let __temp0 = __action268( + source_code, + mode, + __3, + ); + let __temp0 = (__start0, __temp0, __end0); + __action218( + source_code, + mode, + __0, + __1, + __2, + __temp0, + __4, + __5, + __6, + __7, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action677< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, TextSize, TextSize), + __1: (TextSize, token::Tok, TextSize), + __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, core::option::Option<(TextSize, ast::ConversionFlag)>, TextSize), + __4: (TextSize, core::option::Option, TextSize), + __5: (TextSize, token::Tok, TextSize), + __6: (TextSize, TextSize, TextSize), +) -> Result> +{ + let __start0 = __2.2; + let __end0 = __3.0; + let __temp0 = __action269( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action218( + source_code, + mode, + __0, + __1, + __2, + __temp0, + __3, + __4, + __5, + __6, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action678< +>( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -41407,12 +44446,14 @@ fn __action653< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action312( + let __temp0 = __action332( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); __action147( + source_code, mode, __0, __temp0, @@ -41428,8 +44469,9 @@ fn __action653< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action654< +fn __action679< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -41443,13 +44485,15 @@ fn __action654< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action313( + let __temp0 = __action333( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action147( + source_code, mode, __0, __temp0, @@ -41465,8 +44509,9 @@ fn __action654< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action655< +fn __action680< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -41482,12 +44527,14 @@ fn __action655< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action312( + let __temp0 = __action332( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); __action162( + source_code, mode, __0, __1, @@ -41504,8 +44551,9 @@ fn __action655< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action656< +fn __action681< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -41520,13 +44568,15 @@ fn __action656< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action313( + let __temp0 = __action333( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action162( + source_code, mode, __0, __1, @@ -41543,8 +44593,9 @@ fn __action656< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action657< +fn __action682< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -41558,12 +44609,14 @@ fn __action657< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action312( + let __temp0 = __action332( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action225( + __action235( + source_code, mode, __0, __temp0, @@ -41578,8 +44631,9 @@ fn __action657< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action658< +fn __action683< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -41592,13 +44646,15 @@ fn __action658< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action313( + let __temp0 = __action333( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action225( + __action235( + source_code, mode, __0, __temp0, @@ -41613,8 +44669,9 @@ fn __action658< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action659< +fn __action684< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -41626,12 +44683,14 @@ fn __action659< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action312( + let __temp0 = __action332( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); __action155( + source_code, mode, __0, __temp0, @@ -41644,8 +44703,9 @@ fn __action659< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action660< +fn __action685< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -41656,13 +44716,15 @@ fn __action660< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action313( + let __temp0 = __action333( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action155( + source_code, mode, __0, __temp0, @@ -41675,8 +44737,9 @@ fn __action660< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action661< +fn __action686< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Option>, TextSize), @@ -41684,13 +44747,15 @@ fn __action661< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action416( + let __temp0 = __action437( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action466( + __action489( + source_code, mode, __temp0, ) @@ -41698,8 +44763,9 @@ fn __action661< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action662< +fn __action687< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, (Vec, Vec), TextSize), @@ -41711,13 +44777,15 @@ fn __action662< { let __start0 = __2.0; let __end0 = __3.2; - let __temp0 = __action416( + let __temp0 = __action437( + source_code, mode, __2, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action611( + __action634( + source_code, mode, __0, __1, @@ -41729,8 +44797,9 @@ fn __action662< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action663< +fn __action688< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, (Vec, Vec), TextSize), @@ -41741,13 +44810,15 @@ fn __action663< { let __start0 = __2.0; let __end0 = __3.2; - let __temp0 = __action416( + let __temp0 = __action437( + source_code, mode, __2, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action612( + __action635( + source_code, mode, __0, __1, @@ -41758,8 +44829,9 @@ fn __action663< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action664< +fn __action689< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -41771,13 +44843,15 @@ fn __action664< { let __start0 = __4.0; let __end0 = __5.2; - let __temp0 = __action661( + let __temp0 = __action686( + source_code, mode, __4, __5, ); let __temp0 = (__start0, __temp0, __end0); - __action421( + __action442( + source_code, mode, __0, __1, @@ -41789,8 +44863,9 @@ fn __action664< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action665< +fn __action690< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -41800,13 +44875,15 @@ fn __action665< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action467( + let __temp0 = __action490( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action421( + __action442( + source_code, mode, __0, __1, @@ -41818,8 +44895,9 @@ fn __action665< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action666< +fn __action691< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Option>, TextSize), @@ -41827,13 +44905,15 @@ fn __action666< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action424( + let __temp0 = __action445( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action455( + __action478( + source_code, mode, __temp0, ) @@ -41841,8 +44921,9 @@ fn __action666< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action667< +fn __action692< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, (Vec, Vec), TextSize), @@ -41854,13 +44935,15 @@ fn __action667< { let __start0 = __2.0; let __end0 = __3.2; - let __temp0 = __action424( + let __temp0 = __action445( + source_code, mode, __2, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action619( + __action642( + source_code, mode, __0, __1, @@ -41872,8 +44955,9 @@ fn __action667< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action668< +fn __action693< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, (Vec, Vec), TextSize), @@ -41884,13 +44968,15 @@ fn __action668< { let __start0 = __2.0; let __end0 = __3.2; - let __temp0 = __action424( + let __temp0 = __action445( + source_code, mode, __2, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action620( + __action643( + source_code, mode, __0, __1, @@ -41901,8 +44987,9 @@ fn __action668< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action669< +fn __action694< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -41914,13 +45001,15 @@ fn __action669< { let __start0 = __4.0; let __end0 = __5.2; - let __temp0 = __action666( + let __temp0 = __action691( + source_code, mode, __4, __5, ); let __temp0 = (__start0, __temp0, __end0); - __action429( + __action450( + source_code, mode, __0, __1, @@ -41932,8 +45021,9 @@ fn __action669< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action670< +fn __action695< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -41943,13 +45033,15 @@ fn __action670< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action456( + let __temp0 = __action479( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action429( + __action450( + source_code, mode, __0, __1, @@ -41961,8 +45053,9 @@ fn __action670< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action671< +fn __action696< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParameterWithDefault, TextSize), @@ -41970,13 +45063,15 @@ fn __action671< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action470( + let __temp0 = __action493( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action485( + __action508( + source_code, mode, __temp0, ) @@ -41984,8 +45079,9 @@ fn __action671< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action672< +fn __action697< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -41994,13 +45090,15 @@ fn __action672< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action470( + let __temp0 = __action493( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action486( + __action509( + source_code, mode, __0, __temp0, @@ -42009,8 +45107,9 @@ fn __action672< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action673< +fn __action698< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42019,13 +45118,15 @@ fn __action673< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action468( + let __temp0 = __action491( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action423( + __action444( + source_code, mode, __0, __1, @@ -42036,8 +45137,9 @@ fn __action673< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action674< +fn __action699< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42047,12 +45149,14 @@ fn __action674< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action469( + let __temp0 = __action492( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action423( + __action444( + source_code, mode, __0, __1, @@ -42063,8 +45167,9 @@ fn __action674< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action675< +fn __action700< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42075,13 +45180,15 @@ fn __action675< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action468( + let __temp0 = __action491( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action664( + __action689( + source_code, mode, __0, __1, @@ -42094,8 +45201,9 @@ fn __action675< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action676< +fn __action701< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42107,12 +45215,14 @@ fn __action676< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action469( + let __temp0 = __action492( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action664( + __action689( + source_code, mode, __0, __1, @@ -42125,8 +45235,9 @@ fn __action676< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action677< +fn __action702< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42135,13 +45246,15 @@ fn __action677< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action468( + let __temp0 = __action491( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action665( + __action690( + source_code, mode, __0, __1, @@ -42152,8 +45265,9 @@ fn __action677< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action678< +fn __action703< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42163,12 +45277,14 @@ fn __action678< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action469( + let __temp0 = __action492( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action665( + __action690( + source_code, mode, __0, __1, @@ -42179,8 +45295,9 @@ fn __action678< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action679< +fn __action704< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParameterWithDefault, TextSize), @@ -42188,13 +45305,15 @@ fn __action679< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action459( + let __temp0 = __action482( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action487( + __action510( + source_code, mode, __temp0, ) @@ -42202,8 +45321,9 @@ fn __action679< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action680< +fn __action705< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42212,13 +45332,15 @@ fn __action680< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action459( + let __temp0 = __action482( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action488( + __action511( + source_code, mode, __0, __temp0, @@ -42227,8 +45349,9 @@ fn __action680< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action681< +fn __action706< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42237,13 +45360,15 @@ fn __action681< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action457( + let __temp0 = __action480( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action431( + __action452( + source_code, mode, __0, __1, @@ -42254,8 +45379,9 @@ fn __action681< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action682< +fn __action707< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42265,12 +45391,14 @@ fn __action682< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action458( + let __temp0 = __action481( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action431( + __action452( + source_code, mode, __0, __1, @@ -42281,8 +45409,9 @@ fn __action682< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action683< +fn __action708< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42293,13 +45422,15 @@ fn __action683< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action457( + let __temp0 = __action480( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action669( + __action694( + source_code, mode, __0, __1, @@ -42312,8 +45443,9 @@ fn __action683< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action684< +fn __action709< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42325,12 +45457,14 @@ fn __action684< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action458( + let __temp0 = __action481( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action669( + __action694( + source_code, mode, __0, __1, @@ -42343,8 +45477,9 @@ fn __action684< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action685< +fn __action710< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42353,13 +45488,15 @@ fn __action685< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action457( + let __temp0 = __action480( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action670( + __action695( + source_code, mode, __0, __1, @@ -42370,8 +45507,9 @@ fn __action685< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action686< +fn __action711< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42381,12 +45519,14 @@ fn __action686< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action458( + let __temp0 = __action481( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action670( + __action695( + source_code, mode, __0, __1, @@ -42397,8 +45537,9 @@ fn __action686< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action687< +fn __action712< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42409,12 +45550,14 @@ fn __action687< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action473( + let __temp0 = __action496( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action675( + __action700( + source_code, mode, __0, __1, @@ -42426,8 +45569,9 @@ fn __action687< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action688< +fn __action713< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42437,13 +45581,15 @@ fn __action688< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action474( + let __temp0 = __action497( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action675( + __action700( + source_code, mode, __0, __1, @@ -42455,8 +45601,9 @@ fn __action688< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action689< +fn __action714< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42468,12 +45615,14 @@ fn __action689< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action473( + let __temp0 = __action496( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action676( + __action701( + source_code, mode, __0, __1, @@ -42486,8 +45635,9 @@ fn __action689< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action690< +fn __action715< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42498,13 +45648,15 @@ fn __action690< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action474( + let __temp0 = __action497( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action676( + __action701( + source_code, mode, __0, __1, @@ -42517,8 +45669,9 @@ fn __action690< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action691< +fn __action716< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42527,12 +45680,14 @@ fn __action691< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action473( + let __temp0 = __action496( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action677( + __action702( + source_code, mode, __0, __1, @@ -42542,8 +45697,9 @@ fn __action691< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action692< +fn __action717< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42551,13 +45707,15 @@ fn __action692< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action474( + let __temp0 = __action497( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action677( + __action702( + source_code, mode, __0, __1, @@ -42567,8 +45725,9 @@ fn __action692< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action693< +fn __action718< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42578,12 +45737,14 @@ fn __action693< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action473( + let __temp0 = __action496( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action678( + __action703( + source_code, mode, __0, __1, @@ -42594,8 +45755,9 @@ fn __action693< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action694< +fn __action719< >( + source_code: &str, mode: Mode, __0: (TextSize, TextSize, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42604,13 +45766,15 @@ fn __action694< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action474( + let __temp0 = __action497( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action678( + __action703( + source_code, mode, __0, __1, @@ -42621,8 +45785,9 @@ fn __action694< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action695< +fn __action720< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -42632,13 +45797,15 @@ fn __action695< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action322( + __action342( + source_code, mode, __temp0, __0, @@ -42650,8 +45817,9 @@ fn __action695< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action696< +fn __action721< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42660,13 +45828,15 @@ fn __action696< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action319( + __action339( + source_code, mode, __temp0, __0, @@ -42677,33 +45847,9 @@ fn __action696< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action697< ->( - mode: Mode, - __0: (TextSize, (String, StringKind, bool), TextSize), - __1: (TextSize, TextSize, TextSize), -) -> (TextSize, (String, StringKind, bool), TextSize) -{ - let __start0 = __0.0; - let __end0 = __0.0; - let __temp0 = __action393( - mode, - &__start0, - &__end0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action331( - mode, - __temp0, - __0, - __1, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action698< +fn __action722< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), @@ -42713,13 +45859,15 @@ fn __action698< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action114( + source_code, mode, __temp0, __0, @@ -42731,8 +45879,9 @@ fn __action698< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action699< +fn __action723< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42742,13 +45891,15 @@ fn __action699< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action479( + __action502( + source_code, mode, __temp0, __0, @@ -42760,8 +45911,9 @@ fn __action699< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action700< +fn __action724< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42771,13 +45923,15 @@ fn __action700< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action510( + __action533( + source_code, mode, __temp0, __0, @@ -42789,8 +45943,9 @@ fn __action700< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action701< +fn __action725< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -42799,13 +45954,15 @@ fn __action701< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action437( + __action460( + source_code, mode, __temp0, __0, @@ -42816,8 +45973,9 @@ fn __action701< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action702< +fn __action726< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -42826,13 +45984,15 @@ fn __action702< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action483( + __action506( + source_code, mode, __temp0, __0, @@ -42843,8 +46003,9 @@ fn __action702< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action703< +fn __action727< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize), @@ -42854,13 +46015,15 @@ fn __action703< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action228( + __action238( + source_code, mode, __temp0, __0, @@ -42872,8 +46035,9 @@ fn __action703< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action704< +fn __action728< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), @@ -42883,13 +46047,15 @@ fn __action704< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action496( + __action519( + source_code, mode, __temp0, __0, @@ -42901,8 +46067,9 @@ fn __action704< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action705< +fn __action729< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), @@ -42912,13 +46079,15 @@ fn __action705< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action520( + __action543( + source_code, mode, __temp0, __0, @@ -42930,8 +46099,9 @@ fn __action705< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action706< +fn __action730< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Pattern, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -42941,13 +46111,15 @@ fn __action706< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action95( + source_code, mode, __temp0, __0, @@ -42959,8 +46131,9 @@ fn __action706< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action707< +fn __action731< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -42970,13 +46143,15 @@ fn __action707< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action73( + source_code, mode, __temp0, __0, @@ -42988,31 +46163,37 @@ fn __action707< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action708< +fn __action732< >( + source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec<(TextSize, (String, StringKind, bool), TextSize)>, TextSize), + __0: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, TextSize, TextSize), ) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action522( + __action545( + source_code, mode, __temp0, __0, + __1, ) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action709< +fn __action733< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Constant, TextSize), __1: (TextSize, TextSize, TextSize), @@ -43020,13 +46201,15 @@ fn __action709< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action523( + __action546( + source_code, mode, __temp0, __0, @@ -43036,8 +46219,9 @@ fn __action709< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action710< +fn __action734< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, TextSize, TextSize), @@ -43045,13 +46229,15 @@ fn __action710< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action524( + __action547( + source_code, mode, __temp0, __0, @@ -43061,8 +46247,9 @@ fn __action710< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action711< +fn __action735< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -43072,13 +46259,15 @@ fn __action711< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action525( + __action548( + source_code, mode, __temp0, __0, @@ -43090,8 +46279,9 @@ fn __action711< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action712< +fn __action736< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -43102,13 +46292,15 @@ fn __action712< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action526( + __action549( + source_code, mode, __temp0, __0, @@ -43121,8 +46313,9 @@ fn __action712< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action713< +fn __action737< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -43133,13 +46326,15 @@ fn __action713< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action583( + __action606( + source_code, mode, __temp0, __0, @@ -43152,8 +46347,9 @@ fn __action713< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action714< +fn __action738< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -43163,13 +46359,15 @@ fn __action714< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action584( + __action607( + source_code, mode, __temp0, __0, @@ -43181,8 +46379,9 @@ fn __action714< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action715< +fn __action739< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -43195,13 +46394,15 @@ fn __action715< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action585( + __action608( + source_code, mode, __temp0, __0, @@ -43216,8 +46417,9 @@ fn __action715< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action716< +fn __action740< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -43229,13 +46431,15 @@ fn __action716< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action586( + __action609( + source_code, mode, __temp0, __0, @@ -43249,8 +46453,9 @@ fn __action716< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action717< +fn __action741< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -43259,13 +46464,15 @@ fn __action717< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action529( + __action552( + source_code, mode, __temp0, __0, @@ -43276,8 +46483,9 @@ fn __action717< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action718< +fn __action742< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -43287,13 +46495,15 @@ fn __action718< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action530( + __action553( + source_code, mode, __temp0, __0, @@ -43305,8 +46515,9 @@ fn __action718< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action719< +fn __action743< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -43317,13 +46528,15 @@ fn __action719< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action531( + __action554( + source_code, mode, __temp0, __0, @@ -43336,8 +46549,9 @@ fn __action719< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action720< +fn __action744< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -43348,13 +46562,15 @@ fn __action720< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action532( + __action555( + source_code, mode, __0, __temp0, @@ -43367,8 +46583,9 @@ fn __action720< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action721< +fn __action745< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, ast::ParenthesizedExpr)>>, TextSize), @@ -43378,13 +46595,15 @@ fn __action721< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action533( + __action556( + source_code, mode, __temp0, __0, @@ -43396,8 +46615,9 @@ fn __action721< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action722< +fn __action746< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, (ast::ParenthesizedExpr, ast::ParenthesizedExpr), TextSize), @@ -43408,13 +46628,15 @@ fn __action722< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action534( + __action557( + source_code, mode, __temp0, __0, @@ -43427,8 +46649,9 @@ fn __action722< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action723< +fn __action747< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -43438,13 +46661,15 @@ fn __action723< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action535( + __action558( + source_code, mode, __temp0, __0, @@ -43456,8 +46681,9 @@ fn __action723< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action724< +fn __action748< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -43468,13 +46694,15 @@ fn __action724< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action536( + __action559( + source_code, mode, __temp0, __0, @@ -43487,8 +46715,9 @@ fn __action724< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action725< +fn __action749< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -43496,13 +46725,15 @@ fn __action725< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action537( + __action560( + source_code, mode, __temp0, __0, @@ -43512,8 +46743,9 @@ fn __action725< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action726< +fn __action750< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -43521,13 +46753,15 @@ fn __action726< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action538( + __action561( + source_code, mode, __temp0, __0, @@ -43537,8 +46771,9 @@ fn __action726< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action727< +fn __action751< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -43546,13 +46781,15 @@ fn __action727< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action539( + __action562( + source_code, mode, __temp0, __0, @@ -43562,8 +46799,9 @@ fn __action727< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action728< +fn __action752< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -43571,13 +46809,15 @@ fn __action728< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action540( + __action563( + source_code, mode, __temp0, __0, @@ -43587,31 +46827,37 @@ fn __action728< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action729< +fn __action753< >( + source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec<(TextSize, (String, StringKind, bool), TextSize)>, TextSize), + __0: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, TextSize, TextSize), ) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action565( + __action588( + source_code, mode, __temp0, __0, + __1, ) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action730< +fn __action754< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Constant, TextSize), __1: (TextSize, TextSize, TextSize), @@ -43619,13 +46865,15 @@ fn __action730< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action566( + __action589( + source_code, mode, __temp0, __0, @@ -43635,8 +46883,9 @@ fn __action730< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action731< +fn __action755< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, TextSize, TextSize), @@ -43644,13 +46893,15 @@ fn __action731< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action567( + __action590( + source_code, mode, __temp0, __0, @@ -43660,8 +46911,9 @@ fn __action731< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action732< +fn __action756< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -43671,13 +46923,15 @@ fn __action732< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action568( + __action591( + source_code, mode, __temp0, __0, @@ -43689,8 +46943,9 @@ fn __action732< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action733< +fn __action757< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -43701,13 +46956,15 @@ fn __action733< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action569( + __action592( + source_code, mode, __temp0, __0, @@ -43720,8 +46977,9 @@ fn __action733< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action734< +fn __action758< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -43734,13 +46992,15 @@ fn __action734< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action587( + __action610( + source_code, mode, __temp0, __0, @@ -43755,8 +47015,9 @@ fn __action734< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action735< +fn __action759< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -43768,13 +47029,15 @@ fn __action735< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action588( + __action611( + source_code, mode, __temp0, __0, @@ -43788,8 +47051,9 @@ fn __action735< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action736< +fn __action760< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -43798,13 +47062,15 @@ fn __action736< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action571( + __action594( + source_code, mode, __temp0, __0, @@ -43815,8 +47081,9 @@ fn __action736< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action737< +fn __action761< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -43826,13 +47093,15 @@ fn __action737< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action572( + __action595( + source_code, mode, __temp0, __0, @@ -43844,8 +47113,9 @@ fn __action737< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action738< +fn __action762< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -43856,13 +47126,15 @@ fn __action738< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action573( + __action596( + source_code, mode, __temp0, __0, @@ -43875,8 +47147,9 @@ fn __action738< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action739< +fn __action763< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -43887,13 +47160,15 @@ fn __action739< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action574( + __action597( + source_code, mode, __0, __temp0, @@ -43906,8 +47181,9 @@ fn __action739< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action740< +fn __action764< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, ast::ParenthesizedExpr)>>, TextSize), @@ -43917,13 +47193,15 @@ fn __action740< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action575( + __action598( + source_code, mode, __temp0, __0, @@ -43935,8 +47213,9 @@ fn __action740< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action741< +fn __action765< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, (ast::ParenthesizedExpr, ast::ParenthesizedExpr), TextSize), @@ -43947,13 +47226,15 @@ fn __action741< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action576( + __action599( + source_code, mode, __temp0, __0, @@ -43966,8 +47247,9 @@ fn __action741< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action742< +fn __action766< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -43977,13 +47259,15 @@ fn __action742< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action577( + __action600( + source_code, mode, __temp0, __0, @@ -43995,8 +47279,9 @@ fn __action742< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action743< +fn __action767< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -44007,13 +47292,15 @@ fn __action743< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action578( + __action601( + source_code, mode, __temp0, __0, @@ -44026,8 +47313,9 @@ fn __action743< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action744< +fn __action768< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -44035,13 +47323,15 @@ fn __action744< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action579( + __action602( + source_code, mode, __temp0, __0, @@ -44051,8 +47341,9 @@ fn __action744< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action745< +fn __action769< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -44060,13 +47351,15 @@ fn __action745< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action580( + __action603( + source_code, mode, __temp0, __0, @@ -44076,8 +47369,9 @@ fn __action745< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action746< +fn __action770< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -44085,13 +47379,15 @@ fn __action746< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action581( + __action604( + source_code, mode, __temp0, __0, @@ -44101,8 +47397,9 @@ fn __action746< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action747< +fn __action771< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -44110,13 +47407,15 @@ fn __action747< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action582( + __action605( + source_code, mode, __temp0, __0, @@ -44126,8 +47425,9 @@ fn __action747< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action748< +fn __action772< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Arguments, TextSize), @@ -44136,13 +47436,15 @@ fn __action748< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action515( + __action538( + source_code, mode, __temp0, __0, @@ -44153,8 +47455,9 @@ fn __action748< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action749< +fn __action773< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -44165,13 +47468,15 @@ fn __action749< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action516( + __action539( + source_code, mode, __temp0, __0, @@ -44184,8 +47489,9 @@ fn __action749< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action750< +fn __action774< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -44195,13 +47501,15 @@ fn __action750< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action517( + __action540( + source_code, mode, __temp0, __0, @@ -44213,8 +47521,9 @@ fn __action750< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action751< +fn __action775< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Arguments, TextSize), @@ -44223,13 +47532,15 @@ fn __action751< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action562( + __action585( + source_code, mode, __temp0, __0, @@ -44240,8 +47551,9 @@ fn __action751< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action752< +fn __action776< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -44252,13 +47564,15 @@ fn __action752< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action563( + __action586( + source_code, mode, __temp0, __0, @@ -44271,8 +47585,9 @@ fn __action752< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action753< +fn __action777< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -44282,13 +47597,15 @@ fn __action753< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action564( + __action587( + source_code, mode, __temp0, __0, @@ -44300,8 +47617,9 @@ fn __action753< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action754< +fn __action778< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -44310,13 +47628,15 @@ fn __action754< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action512( + __action535( + source_code, mode, __temp0, __0, @@ -44327,8 +47647,9 @@ fn __action754< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action755< +fn __action779< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -44337,13 +47658,15 @@ fn __action755< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action559( + __action582( + source_code, mode, __temp0, __0, @@ -44354,8 +47677,9 @@ fn __action755< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action756< +fn __action780< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, TextSize, TextSize), @@ -44363,13 +47687,15 @@ fn __action756< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action121( + source_code, mode, __temp0, __0, @@ -44379,8 +47705,9 @@ fn __action756< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action757< +fn __action781< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -44393,13 +47720,15 @@ fn __action757< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action171( + source_code, mode, __temp0, __0, @@ -44414,8 +47743,9 @@ fn __action757< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action758< +fn __action782< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Expr, TextSize), __1: (TextSize, ast::PatternArguments, TextSize), @@ -44424,13 +47754,15 @@ fn __action758< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action139( + source_code, mode, __temp0, __0, @@ -44441,8 +47773,9 @@ fn __action758< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action759< +fn __action783< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Expr, TextSize), __1: (TextSize, ast::PatternArguments, TextSize), @@ -44451,13 +47784,15 @@ fn __action759< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action140( + source_code, mode, __temp0, __0, @@ -44468,8 +47803,9 @@ fn __action759< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action760< +fn __action784< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize), @@ -44478,13 +47814,15 @@ fn __action760< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action489( + __action512( + source_code, mode, __temp0, __0, @@ -44495,8 +47833,9 @@ fn __action760< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action761< +fn __action785< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize), @@ -44505,13 +47844,15 @@ fn __action761< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action500( + __action523( + source_code, mode, __temp0, __0, @@ -44522,8 +47863,9 @@ fn __action761< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action762< +fn __action786< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Constant, TextSize), __1: (TextSize, TextSize, TextSize), @@ -44531,13 +47873,15 @@ fn __action762< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action111( + source_code, mode, __temp0, __0, @@ -44547,8 +47891,9 @@ fn __action762< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action763< +fn __action787< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -44557,13 +47902,15 @@ fn __action763< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action113( + source_code, mode, __temp0, __0, @@ -44574,8 +47921,9 @@ fn __action763< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action764< +fn __action788< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -44585,13 +47933,15 @@ fn __action764< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action176( + source_code, mode, __temp0, __0, @@ -44603,8 +47953,9 @@ fn __action764< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action765< +fn __action789< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -44613,13 +47964,15 @@ fn __action765< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action25( + source_code, mode, __temp0, __0, @@ -44630,8 +47983,9 @@ fn __action765< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action766< +fn __action790< >( + source_code: &str, mode: Mode, __0: (TextSize, String, TextSize), __1: (TextSize, TextSize, TextSize), @@ -44639,13 +47993,15 @@ fn __action766< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action69( + source_code, mode, __temp0, __0, @@ -44655,8 +48011,9 @@ fn __action766< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action767< +fn __action791< >( + source_code: &str, mode: Mode, __0: (TextSize, String, TextSize), __1: (TextSize, alloc::vec::Vec<(token::Tok, ast::Identifier)>, TextSize), @@ -44665,13 +48022,15 @@ fn __action767< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action70( + source_code, mode, __temp0, __0, @@ -44682,8 +48041,9 @@ fn __action767< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action768< +fn __action792< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -44692,13 +48052,15 @@ fn __action768< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action170( + source_code, mode, __temp0, __0, @@ -44709,8 +48071,9 @@ fn __action768< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action769< +fn __action793< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -44720,13 +48083,15 @@ fn __action769< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action153( + source_code, mode, __temp0, __0, @@ -44738,8 +48103,9 @@ fn __action769< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action770< +fn __action794< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, (ast::ParenthesizedExpr, ast::Identifier), TextSize), @@ -44749,13 +48115,15 @@ fn __action770< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action154( + source_code, mode, __temp0, __0, @@ -44767,8 +48135,9 @@ fn __action770< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action771< +fn __action795< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -44779,13 +48148,15 @@ fn __action771< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action151( + source_code, mode, __temp0, __0, @@ -44798,8 +48169,9 @@ fn __action771< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action772< +fn __action796< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -44810,13 +48182,15 @@ fn __action772< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action152( + source_code, mode, __temp0, __0, @@ -44829,8 +48203,9 @@ fn __action772< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action773< +fn __action797< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -44840,13 +48215,15 @@ fn __action773< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action350( + __action371( + source_code, mode, __temp0, __0, @@ -44858,8 +48235,9 @@ fn __action773< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action774< +fn __action798< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -44869,13 +48247,15 @@ fn __action774< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action502( + __action525( + source_code, mode, __temp0, __0, @@ -44887,8 +48267,9 @@ fn __action774< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action775< +fn __action799< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -44897,13 +48278,15 @@ fn __action775< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action26( + source_code, mode, __temp0, __0, @@ -44914,8 +48297,9 @@ fn __action775< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action776< +fn __action800< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), @@ -44925,13 +48309,15 @@ fn __action776< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action27( + source_code, mode, __temp0, __0, @@ -44943,8 +48329,9 @@ fn __action776< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action777< +fn __action801< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -44955,13 +48342,15 @@ fn __action777< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action28( + source_code, mode, __temp0, __0, @@ -44974,8 +48363,207 @@ fn __action777< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action778< +fn __action802< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, String, TextSize), +) -> Result<(TextSize, ast::ConversionFlag),__lalrpop_util::ParseError> +{ + let __start0 = __0.0; + let __end0 = __0.0; + let __start1 = __0.2; + let __end1 = __1.0; + let __temp0 = __action414( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + let __temp1 = __action414( + source_code, + mode, + &__start1, + &__end1, + ); + let __temp1 = (__start1, __temp1, __end1); + __action221( + source_code, + mode, + __temp0, + __0, + __temp1, + __1, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action803< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, alloc::vec::Vec, TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, TextSize, TextSize), +) -> StringType +{ + let __start0 = __0.0; + let __end0 = __0.0; + let __temp0 = __action414( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action215( + source_code, + mode, + __temp0, + __0, + __1, + __2, + __3, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action804< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, TextSize, TextSize), +) -> ast::Expr +{ + let __start0 = __0.0; + let __end0 = __0.0; + let __temp0 = __action414( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action220( + source_code, + mode, + __temp0, + __0, + __1, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action805< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, (String, bool), TextSize), +) -> Result> +{ + let __start0 = __0.0; + let __end0 = __0.0; + let __temp0 = __action414( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action217( + source_code, + mode, + __temp0, + __0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action806< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, core::option::Option<(TextSize, ast::ConversionFlag)>, TextSize), + __4: (TextSize, core::option::Option, TextSize), + __5: (TextSize, token::Tok, TextSize), + __6: (TextSize, TextSize, TextSize), +) -> Result> +{ + let __start0 = __0.0; + let __end0 = __0.0; + let __temp0 = __action414( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action676( + source_code, + mode, + __temp0, + __0, + __1, + __2, + __3, + __4, + __5, + __6, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action807< >( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, core::option::Option<(TextSize, ast::ConversionFlag)>, TextSize), + __3: (TextSize, core::option::Option, TextSize), + __4: (TextSize, token::Tok, TextSize), + __5: (TextSize, TextSize, TextSize), +) -> Result> +{ + let __start0 = __0.0; + let __end0 = __0.0; + let __temp0 = __action414( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action677( + source_code, + mode, + __temp0, + __0, + __1, + __2, + __3, + __4, + __5, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action808< +>( + source_code: &str, mode: Mode, __0: (TextSize, ast::UnaryOp, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -44984,13 +48572,15 @@ fn __action778< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action504( + __action527( + source_code, mode, __temp0, __0, @@ -45001,8 +48591,9 @@ fn __action778< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action779< +fn __action809< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::UnaryOp, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -45011,13 +48602,15 @@ fn __action779< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action553( + __action576( + source_code, mode, __temp0, __0, @@ -45028,8 +48621,9 @@ fn __action779< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action780< +fn __action810< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -45037,13 +48631,15 @@ fn __action780< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action53( + source_code, mode, __temp0, __0, @@ -45053,8 +48649,9 @@ fn __action780< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action781< +fn __action811< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -45062,13 +48659,15 @@ fn __action781< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action54( + source_code, mode, __temp0, __0, @@ -45078,8 +48677,9 @@ fn __action781< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action782< +fn __action812< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -45088,13 +48688,15 @@ fn __action782< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action55( + source_code, mode, __temp0, __0, @@ -45105,8 +48707,9 @@ fn __action782< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action783< +fn __action813< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, TextSize, TextSize), @@ -45114,13 +48717,15 @@ fn __action783< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action56( + source_code, mode, __temp0, __0, @@ -45130,8 +48735,9 @@ fn __action783< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action784< +fn __action814< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -45145,13 +48751,15 @@ fn __action784< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action653( + __action678( + source_code, mode, __temp0, __0, @@ -45167,8 +48775,9 @@ fn __action784< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action785< +fn __action815< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -45181,13 +48790,15 @@ fn __action785< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action654( + __action679( + source_code, mode, __temp0, __0, @@ -45202,8 +48813,9 @@ fn __action785< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action786< +fn __action816< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -45218,13 +48830,15 @@ fn __action786< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action655( + __action680( + source_code, mode, __temp0, __0, @@ -45241,8 +48855,9 @@ fn __action786< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action787< +fn __action817< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -45256,13 +48871,15 @@ fn __action787< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action656( + __action681( + source_code, mode, __temp0, __0, @@ -45278,8 +48895,9 @@ fn __action787< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action788< +fn __action818< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -45288,13 +48906,15 @@ fn __action788< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action229( + __action239( + source_code, mode, __temp0, __0, @@ -45305,8 +48925,9 @@ fn __action788< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action789< +fn __action819< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -45316,13 +48937,15 @@ fn __action789< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action230( + __action240( + source_code, mode, __temp0, __0, @@ -45334,8 +48957,9 @@ fn __action789< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action790< +fn __action820< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -45344,13 +48968,15 @@ fn __action790< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action231( + __action241( + source_code, mode, __temp0, __0, @@ -45361,8 +48987,9 @@ fn __action790< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action791< +fn __action821< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -45371,13 +48998,15 @@ fn __action791< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action232( + __action242( + source_code, mode, __temp0, __0, @@ -45388,8 +49017,9 @@ fn __action791< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action792< +fn __action822< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -45398,13 +49028,15 @@ fn __action792< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action593( + __action616( + source_code, mode, __temp0, __0, @@ -45415,8 +49047,9 @@ fn __action792< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action793< +fn __action823< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, TextSize, TextSize), @@ -45424,13 +49057,15 @@ fn __action793< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action594( + __action617( + source_code, mode, __temp0, __0, @@ -45440,8 +49075,9 @@ fn __action793< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action794< +fn __action824< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -45450,13 +49086,15 @@ fn __action794< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action595( + __action618( + source_code, mode, __temp0, __0, @@ -45467,8 +49105,9 @@ fn __action794< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action795< +fn __action825< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, TextSize, TextSize), @@ -45476,13 +49115,15 @@ fn __action795< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action596( + __action619( + source_code, mode, __temp0, __0, @@ -45492,8 +49133,9 @@ fn __action795< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action796< +fn __action826< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -45502,13 +49144,15 @@ fn __action796< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action71( + source_code, mode, __temp0, __0, @@ -45519,8 +49163,9 @@ fn __action796< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action797< +fn __action827< >( + source_code: &str, mode: Mode, __0: (TextSize, String, TextSize), __1: (TextSize, TextSize, TextSize), @@ -45528,13 +49173,15 @@ fn __action797< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action236( + __action246( + source_code, mode, __temp0, __0, @@ -45544,8 +49191,9 @@ fn __action797< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action798< +fn __action828< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -45557,13 +49205,15 @@ fn __action798< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action145( + source_code, mode, __temp0, __0, @@ -45577,8 +49227,9 @@ fn __action798< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action799< +fn __action829< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -45587,13 +49238,15 @@ fn __action799< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action371( + __action392( + source_code, mode, __temp0, __0, @@ -45604,8 +49257,9 @@ fn __action799< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action800< +fn __action830< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -45614,13 +49268,15 @@ fn __action800< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action364( + __action385( + source_code, mode, __temp0, __0, @@ -45631,8 +49287,9 @@ fn __action800< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action801< +fn __action831< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, TextSize, TextSize), @@ -45640,13 +49297,15 @@ fn __action801< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action66( + source_code, mode, __temp0, __0, @@ -45656,8 +49315,9 @@ fn __action801< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action802< +fn __action832< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -45668,13 +49328,15 @@ fn __action802< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action597( + __action620( + source_code, mode, __temp0, __0, @@ -45687,8 +49349,9 @@ fn __action802< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action803< +fn __action833< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -45698,13 +49361,15 @@ fn __action803< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action598( + __action621( + source_code, mode, __temp0, __0, @@ -45716,8 +49381,9 @@ fn __action803< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action804< +fn __action834< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -45725,13 +49391,15 @@ fn __action804< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action68( + source_code, mode, __temp0, __0, @@ -45741,8 +49409,9 @@ fn __action804< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action805< +fn __action835< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -45751,13 +49420,15 @@ fn __action805< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action60( + source_code, mode, __temp0, __0, @@ -45768,8 +49439,9 @@ fn __action805< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action806< +fn __action836< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, (Option, Option), TextSize), @@ -45780,13 +49452,15 @@ fn __action806< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action61( + source_code, mode, __temp0, __0, @@ -45799,8 +49473,9 @@ fn __action806< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action807< +fn __action837< >( + source_code: &str, mode: Mode, __0: (TextSize, (IpyEscapeKind, String), TextSize), __1: (TextSize, TextSize, TextSize), @@ -45808,13 +49483,15 @@ fn __action807< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action75( + source_code, mode, __temp0, __0, @@ -45824,8 +49501,9 @@ fn __action807< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action808< +fn __action838< >( + source_code: &str, mode: Mode, __0: (TextSize, (IpyEscapeKind, String), TextSize), __1: (TextSize, TextSize, TextSize), @@ -45833,13 +49511,15 @@ fn __action808< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action74( + source_code, mode, __temp0, __0, @@ -45849,8 +49529,9 @@ fn __action808< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action809< +fn __action839< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -45859,13 +49540,15 @@ fn __action809< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action76( + source_code, mode, __temp0, __0, @@ -45876,34 +49559,39 @@ fn __action809< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action810< +fn __action840< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option, TextSize), __2: (TextSize, TextSize, TextSize), __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::ParenthesizedExpr, TextSize), - __5: (TextSize, TextSize, TextSize), + __4: (TextSize, core::option::Option<(String, bool)>, TextSize), + __5: (TextSize, ast::ParenthesizedExpr, TextSize), + __6: (TextSize, TextSize, TextSize), ) -> Result> { let __start0 = __0.0; let __end0 = __0.0; let __start1 = __0.2; let __end1 = __1.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action393( + let __temp1 = __action414( + source_code, mode, &__start1, &__end1, ); let __temp1 = (__start1, __temp1, __end1); __action183( + source_code, mode, __temp0, __0, @@ -45913,13 +49601,15 @@ fn __action810< __3, __4, __5, + __6, ) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action811< +fn __action841< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -45927,13 +49617,15 @@ fn __action811< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action115( + source_code, mode, __temp0, __0, @@ -45943,8 +49635,9 @@ fn __action811< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action812< +fn __action842< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -45952,13 +49645,15 @@ fn __action812< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action116( + source_code, mode, __temp0, __0, @@ -45968,8 +49663,9 @@ fn __action812< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action813< +fn __action843< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -45977,13 +49673,15 @@ fn __action813< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action117( + source_code, mode, __temp0, __0, @@ -45993,8 +49691,9 @@ fn __action813< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action814< +fn __action844< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, TextSize, TextSize), @@ -46002,13 +49701,15 @@ fn __action814< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action118( + source_code, mode, __temp0, __0, @@ -46018,8 +49719,9 @@ fn __action814< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action815< +fn __action845< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, TextSize, TextSize), @@ -46027,13 +49729,15 @@ fn __action815< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action119( + source_code, mode, __temp0, __0, @@ -46043,22 +49747,25 @@ fn __action815< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action816< +fn __action846< >( + source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec<(TextSize, (String, StringKind, bool), TextSize)>, TextSize), + __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, TextSize, TextSize), ) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action120( + source_code, mode, __temp0, __0, @@ -46068,8 +49775,9 @@ fn __action816< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action817< +fn __action847< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -46077,13 +49785,15 @@ fn __action817< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action129( + source_code, mode, __temp0, __0, @@ -46093,8 +49803,9 @@ fn __action817< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action818< +fn __action848< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -46102,13 +49813,15 @@ fn __action818< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action130( + source_code, mode, __temp0, __0, @@ -46118,8 +49831,9 @@ fn __action818< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action819< +fn __action849< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -46127,13 +49841,15 @@ fn __action819< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action131( + source_code, mode, __temp0, __0, @@ -46143,31 +49859,37 @@ fn __action819< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action820< +fn __action850< >( + source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec<(TextSize, (String, StringKind, bool), TextSize)>, TextSize), + __0: (TextSize, alloc::vec::Vec, TextSize), + __1: (TextSize, TextSize, TextSize), ) -> Result> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action132( + source_code, mode, __temp0, __0, + __1, ) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action821< +fn __action851< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -46176,13 +49898,15 @@ fn __action821< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action134( + source_code, mode, __temp0, __0, @@ -46193,8 +49917,9 @@ fn __action821< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action822< +fn __action852< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec<(ast::Expr, ast::Pattern)>, TextSize), @@ -46205,13 +49930,15 @@ fn __action822< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action601( + __action624( + source_code, mode, __temp0, __0, @@ -46224,8 +49951,9 @@ fn __action822< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action823< +fn __action853< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec<(ast::Expr, ast::Pattern)>, TextSize), @@ -46235,13 +49963,15 @@ fn __action823< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action602( + __action625( + source_code, mode, __temp0, __0, @@ -46253,8 +49983,9 @@ fn __action823< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action824< +fn __action854< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -46266,13 +49997,15 @@ fn __action824< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action603( + __action626( + source_code, mode, __temp0, __0, @@ -46286,8 +50019,9 @@ fn __action824< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action825< +fn __action855< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -46298,13 +50032,15 @@ fn __action825< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action604( + __action627( + source_code, mode, __temp0, __0, @@ -46317,8 +50053,9 @@ fn __action825< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action826< +fn __action856< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec<(ast::Expr, ast::Pattern)>, TextSize), @@ -46332,13 +50069,15 @@ fn __action826< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action605( + __action628( + source_code, mode, __temp0, __0, @@ -46354,8 +50093,9 @@ fn __action826< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action827< +fn __action857< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec<(ast::Expr, ast::Pattern)>, TextSize), @@ -46368,13 +50108,15 @@ fn __action827< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action606( + __action629( + source_code, mode, __temp0, __0, @@ -46389,8 +50131,9 @@ fn __action827< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action828< +fn __action858< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Pattern, TextSize), @@ -46401,13 +50144,15 @@ fn __action828< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action88( + source_code, mode, __temp0, __0, @@ -46420,8 +50165,9 @@ fn __action828< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action829< +fn __action859< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -46431,13 +50177,15 @@ fn __action829< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action138( + source_code, mode, __temp0, __0, @@ -46449,8 +50197,9 @@ fn __action829< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action830< +fn __action860< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, TextSize, TextSize), @@ -46458,13 +50207,15 @@ fn __action830< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action122( + source_code, mode, __temp0, __0, @@ -46474,8 +50225,9 @@ fn __action830< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action831< +fn __action861< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Expr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -46485,13 +50237,15 @@ fn __action831< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action123( + source_code, mode, __temp0, __0, @@ -46503,8 +50257,9 @@ fn __action831< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action832< +fn __action862< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Expr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -46514,13 +50269,15 @@ fn __action832< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action124( + source_code, mode, __temp0, __0, @@ -46532,8 +50289,9 @@ fn __action832< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action833< +fn __action863< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -46546,13 +50304,15 @@ fn __action833< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action85( + source_code, mode, __temp0, __0, @@ -46567,31 +50327,45 @@ fn __action833< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action834< +fn __action864< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, token::Tok, TextSize), + __3: (TextSize, TextSize, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, token::Tok, TextSize), - __6: (TextSize, alloc::vec::Vec, TextSize), - __7: (TextSize, token::Tok, TextSize), + __6: (TextSize, token::Tok, TextSize), + __7: (TextSize, alloc::vec::Vec, TextSize), + __8: (TextSize, token::Tok, TextSize), ) -> ast::Stmt { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __start1 = __0.2; + let __end1 = __1.0; + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); + let __temp1 = __action414( + source_code, + mode, + &__start1, + &__end1, + ); + let __temp1 = (__start1, __temp1, __end1); __action86( + source_code, mode, __temp0, __0, + __temp1, __1, __2, __3, @@ -46599,36 +50373,51 @@ fn __action834< __5, __6, __7, + __8, ) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action835< +fn __action865< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, token::Tok, TextSize), + __3: (TextSize, TextSize, TextSize), __4: (TextSize, token::Tok, TextSize), __5: (TextSize, token::Tok, TextSize), - __6: (TextSize, alloc::vec::Vec, TextSize), - __7: (TextSize, token::Tok, TextSize), + __6: (TextSize, token::Tok, TextSize), + __7: (TextSize, alloc::vec::Vec, TextSize), + __8: (TextSize, token::Tok, TextSize), ) -> ast::Stmt { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __start1 = __0.2; + let __end1 = __1.0; + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action607( + let __temp1 = __action414( + source_code, + mode, + &__start1, + &__end1, + ); + let __temp1 = (__start1, __temp1, __end1); + __action630( + source_code, mode, __temp0, __0, + __temp1, __1, __2, __3, @@ -46636,48 +50425,65 @@ fn __action835< __5, __6, __7, + __8, ) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action836< +fn __action866< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), - __2: (TextSize, token::Tok, TextSize), + __2: (TextSize, TextSize, TextSize), __3: (TextSize, token::Tok, TextSize), __4: (TextSize, token::Tok, TextSize), - __5: (TextSize, alloc::vec::Vec, TextSize), - __6: (TextSize, token::Tok, TextSize), + __5: (TextSize, token::Tok, TextSize), + __6: (TextSize, alloc::vec::Vec, TextSize), + __7: (TextSize, token::Tok, TextSize), ) -> ast::Stmt { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __start1 = __0.2; + let __end1 = __1.0; + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action608( + let __temp1 = __action414( + source_code, + mode, + &__start1, + &__end1, + ); + let __temp1 = (__start1, __temp1, __end1); + __action631( + source_code, mode, __temp0, __0, + __temp1, __1, __2, __3, __4, __5, __6, + __7, ) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action837< +fn __action867< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -46687,13 +50493,15 @@ fn __action837< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action182( + source_code, mode, __temp0, __0, @@ -46705,8 +50513,9 @@ fn __action837< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action838< +fn __action868< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, TextSize, TextSize), @@ -46714,13 +50523,15 @@ fn __action838< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action181( + source_code, mode, __temp0, __0, @@ -46730,8 +50541,9 @@ fn __action838< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action839< +fn __action869< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -46740,13 +50552,15 @@ fn __action839< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action72( + source_code, mode, __temp0, __0, @@ -46757,8 +50571,9 @@ fn __action839< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action840< +fn __action870< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -46767,13 +50582,15 @@ fn __action840< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action451( + __action474( + source_code, mode, __temp0, __0, @@ -46784,8 +50601,9 @@ fn __action840< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action841< +fn __action871< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -46794,13 +50612,15 @@ fn __action841< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action494( + __action517( + source_code, mode, __temp0, __0, @@ -46811,8 +50631,9 @@ fn __action841< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action842< +fn __action872< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, TextSize, TextSize), @@ -46820,13 +50641,15 @@ fn __action842< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action97( + source_code, mode, __temp0, __0, @@ -46836,8 +50659,9 @@ fn __action842< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action843< +fn __action873< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -46846,13 +50670,15 @@ fn __action843< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action242( + __action252( + source_code, mode, __temp0, __0, @@ -46863,8 +50689,9 @@ fn __action843< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action844< +fn __action874< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -46873,13 +50700,15 @@ fn __action844< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action477( + __action500( + source_code, mode, __temp0, __0, @@ -46890,8 +50719,9 @@ fn __action844< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action845< +fn __action875< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, core::option::Option<(Option>, Vec, Option>)>, TextSize), @@ -46901,13 +50731,15 @@ fn __action845< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action609( + __action632( + source_code, mode, __temp0, __0, @@ -46919,8 +50751,9 @@ fn __action845< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action846< +fn __action876< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, core::option::Option<(Option>, Vec, Option>)>, TextSize), @@ -46929,13 +50762,15 @@ fn __action846< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action610( + __action633( + source_code, mode, __temp0, __0, @@ -46946,8 +50781,9 @@ fn __action846< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action847< +fn __action877< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -46958,13 +50794,15 @@ fn __action847< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action662( + __action687( + source_code, mode, __temp0, __0, @@ -46977,8 +50815,9 @@ fn __action847< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action848< +fn __action878< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -46988,13 +50827,15 @@ fn __action848< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action663( + __action688( + source_code, mode, __temp0, __0, @@ -47006,8 +50847,9 @@ fn __action848< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action849< +fn __action879< >( + source_code: &str, mode: Mode, __0: (TextSize, (Option>, Vec, Option>), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -47016,13 +50858,15 @@ fn __action849< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action613( + __action636( + source_code, mode, __temp0, __0, @@ -47033,8 +50877,9 @@ fn __action849< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action850< +fn __action880< >( + source_code: &str, mode: Mode, __0: (TextSize, (Option>, Vec, Option>), TextSize), __1: (TextSize, TextSize, TextSize), @@ -47042,13 +50887,15 @@ fn __action850< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action614( + __action637( + source_code, mode, __temp0, __0, @@ -47058,8 +50905,9 @@ fn __action850< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action851< +fn __action881< >( + source_code: &str, mode: Mode, __0: (TextSize, Option>, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -47068,13 +50916,15 @@ fn __action851< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action615( + __action638( + source_code, mode, __temp0, __0, @@ -47085,8 +50935,9 @@ fn __action851< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action852< +fn __action882< >( + source_code: &str, mode: Mode, __0: (TextSize, Option>, TextSize), __1: (TextSize, TextSize, TextSize), @@ -47094,13 +50945,15 @@ fn __action852< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action616( + __action639( + source_code, mode, __temp0, __0, @@ -47110,8 +50963,9 @@ fn __action852< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action853< +fn __action883< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, core::option::Option<(Option>, Vec, Option>)>, TextSize), @@ -47121,13 +50975,15 @@ fn __action853< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action617( + __action640( + source_code, mode, __temp0, __0, @@ -47139,8 +50995,9 @@ fn __action853< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action854< +fn __action884< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, core::option::Option<(Option>, Vec, Option>)>, TextSize), @@ -47149,13 +51006,15 @@ fn __action854< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action618( + __action641( + source_code, mode, __temp0, __0, @@ -47166,8 +51025,9 @@ fn __action854< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action855< +fn __action885< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -47178,13 +51038,15 @@ fn __action855< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action667( + __action692( + source_code, mode, __temp0, __0, @@ -47197,8 +51059,9 @@ fn __action855< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action856< +fn __action886< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -47208,13 +51071,15 @@ fn __action856< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action668( + __action693( + source_code, mode, __temp0, __0, @@ -47226,8 +51091,9 @@ fn __action856< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action857< +fn __action887< >( + source_code: &str, mode: Mode, __0: (TextSize, (Option>, Vec, Option>), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -47236,13 +51102,15 @@ fn __action857< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action621( + __action644( + source_code, mode, __temp0, __0, @@ -47253,8 +51121,9 @@ fn __action857< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action858< +fn __action888< >( + source_code: &str, mode: Mode, __0: (TextSize, (Option>, Vec, Option>), TextSize), __1: (TextSize, TextSize, TextSize), @@ -47262,13 +51131,15 @@ fn __action858< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action622( + __action645( + source_code, mode, __temp0, __0, @@ -47278,8 +51149,9 @@ fn __action858< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action859< +fn __action889< >( + source_code: &str, mode: Mode, __0: (TextSize, Option>, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -47288,13 +51160,15 @@ fn __action859< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action623( + __action646( + source_code, mode, __temp0, __0, @@ -47305,8 +51179,9 @@ fn __action859< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action860< +fn __action890< >( + source_code: &str, mode: Mode, __0: (TextSize, Option>, TextSize), __1: (TextSize, TextSize, TextSize), @@ -47314,13 +51189,15 @@ fn __action860< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action624( + __action647( + source_code, mode, __temp0, __0, @@ -47330,8 +51207,9 @@ fn __action860< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action861< +fn __action891< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -47341,13 +51219,15 @@ fn __action861< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action687( + __action712( + source_code, mode, __temp0, __0, @@ -47359,8 +51239,9 @@ fn __action861< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action862< +fn __action892< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -47369,13 +51250,15 @@ fn __action862< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action688( + __action713( + source_code, mode, __temp0, __0, @@ -47386,8 +51269,9 @@ fn __action862< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action863< +fn __action893< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -47398,13 +51282,15 @@ fn __action863< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action689( + __action714( + source_code, mode, __temp0, __0, @@ -47417,8 +51303,9 @@ fn __action863< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action864< +fn __action894< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -47428,13 +51315,15 @@ fn __action864< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action690( + __action715( + source_code, mode, __temp0, __0, @@ -47446,8 +51335,9 @@ fn __action864< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action865< +fn __action895< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -47455,13 +51345,15 @@ fn __action865< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action691( + __action716( + source_code, mode, __temp0, __0, @@ -47471,21 +51363,24 @@ fn __action865< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action866< +fn __action896< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> Result<(Option>, Vec, Option>),__lalrpop_util::ParseError> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action692( + __action717( + source_code, mode, __temp0, __0, @@ -47494,8 +51389,9 @@ fn __action866< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action867< +fn __action897< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -47504,13 +51400,15 @@ fn __action867< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action693( + __action718( + source_code, mode, __temp0, __0, @@ -47521,8 +51419,9 @@ fn __action867< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action868< +fn __action898< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -47530,13 +51429,15 @@ fn __action868< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action694( + __action719( + source_code, mode, __temp0, __0, @@ -47546,8 +51447,9 @@ fn __action868< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action869< +fn __action899< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -47557,13 +51459,15 @@ fn __action869< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action683( + __action708( + source_code, mode, __temp0, __0, @@ -47575,8 +51479,9 @@ fn __action869< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action870< +fn __action900< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -47587,13 +51492,15 @@ fn __action870< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action684( + __action709( + source_code, mode, __temp0, __0, @@ -47606,8 +51513,9 @@ fn __action870< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action871< +fn __action901< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -47615,13 +51523,15 @@ fn __action871< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action685( + __action710( + source_code, mode, __temp0, __0, @@ -47631,8 +51541,9 @@ fn __action871< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action872< +fn __action902< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -47641,13 +51552,15 @@ fn __action872< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action686( + __action711( + source_code, mode, __temp0, __0, @@ -47658,8 +51571,9 @@ fn __action872< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action873< +fn __action903< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -47669,13 +51583,15 @@ fn __action873< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action165( + source_code, mode, __temp0, __0, @@ -47687,8 +51603,9 @@ fn __action873< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action874< +fn __action904< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -47696,13 +51613,15 @@ fn __action874< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action24( + source_code, mode, __temp0, __0, @@ -47712,8 +51631,9 @@ fn __action874< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action875< +fn __action905< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -47726,13 +51646,15 @@ fn __action875< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action625( + __action648( + source_code, mode, __temp0, __0, @@ -47747,8 +51669,9 @@ fn __action875< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action876< +fn __action906< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -47760,13 +51683,15 @@ fn __action876< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action626( + __action649( + source_code, mode, __temp0, __0, @@ -47780,8 +51705,9 @@ fn __action876< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action877< +fn __action907< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -47792,13 +51718,15 @@ fn __action877< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action627( + __action650( + source_code, mode, __temp0, __0, @@ -47811,8 +51739,9 @@ fn __action877< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action878< +fn __action908< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -47822,13 +51751,15 @@ fn __action878< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action628( + __action651( + source_code, mode, __temp0, __0, @@ -47840,8 +51771,9 @@ fn __action878< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action879< +fn __action909< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -47852,13 +51784,15 @@ fn __action879< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action629( + __action652( + source_code, mode, __temp0, __0, @@ -47871,8 +51805,9 @@ fn __action879< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action880< +fn __action910< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -47882,13 +51817,15 @@ fn __action880< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action630( + __action653( + source_code, mode, __temp0, __0, @@ -47900,8 +51837,9 @@ fn __action880< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action881< +fn __action911< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -47910,13 +51848,15 @@ fn __action881< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action144( + source_code, mode, __temp0, __0, @@ -47927,8 +51867,9 @@ fn __action881< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action882< +fn __action912< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Pattern, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -47937,13 +51878,15 @@ fn __action882< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action90( + source_code, mode, __temp0, __0, @@ -47954,8 +51897,9 @@ fn __action882< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action883< +fn __action913< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -47964,13 +51908,15 @@ fn __action883< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action631( + __action654( + source_code, mode, __temp0, __0, @@ -47981,8 +51927,9 @@ fn __action883< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action884< +fn __action914< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, TextSize, TextSize), @@ -47990,13 +51937,15 @@ fn __action884< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action632( + __action655( + source_code, mode, __temp0, __0, @@ -48006,8 +51955,9 @@ fn __action884< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action885< +fn __action915< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -48017,13 +51967,15 @@ fn __action885< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action506( + __action529( + source_code, mode, __temp0, __0, @@ -48035,8 +51987,9 @@ fn __action885< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action886< +fn __action916< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -48046,13 +51999,15 @@ fn __action886< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action557( + __action580( + source_code, mode, __temp0, __0, @@ -48064,8 +52019,9 @@ fn __action886< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action887< +fn __action917< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -48073,13 +52029,15 @@ fn __action887< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action58( + source_code, mode, __temp0, __0, @@ -48089,8 +52047,9 @@ fn __action887< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action888< +fn __action918< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -48100,13 +52059,15 @@ fn __action888< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action59( + source_code, mode, __temp0, __0, @@ -48118,8 +52079,9 @@ fn __action888< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action889< +fn __action919< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Pattern, TextSize), @@ -48129,13 +52091,15 @@ fn __action889< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action105( + source_code, mode, __temp0, __0, @@ -48147,8 +52111,9 @@ fn __action889< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action890< +fn __action920< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -48157,13 +52122,15 @@ fn __action890< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action106( + source_code, mode, __temp0, __0, @@ -48174,8 +52141,9 @@ fn __action890< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action891< +fn __action921< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Pattern, TextSize), @@ -48186,13 +52154,15 @@ fn __action891< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action107( + source_code, mode, __temp0, __0, @@ -48205,8 +52175,9 @@ fn __action891< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action892< +fn __action922< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -48218,13 +52189,15 @@ fn __action892< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action633( + __action656( + source_code, mode, __temp0, __0, @@ -48238,8 +52211,9 @@ fn __action892< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action893< +fn __action923< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -48250,13 +52224,15 @@ fn __action893< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action634( + __action657( + source_code, mode, __temp0, __0, @@ -48269,8 +52245,9 @@ fn __action893< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action894< +fn __action924< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -48280,13 +52257,15 @@ fn __action894< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action109( + source_code, mode, __temp0, __0, @@ -48298,8 +52277,9 @@ fn __action894< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action895< +fn __action925< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), @@ -48309,13 +52289,15 @@ fn __action895< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action481( + __action504( + source_code, mode, __temp0, __0, @@ -48327,8 +52309,9 @@ fn __action895< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action896< +fn __action926< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), @@ -48338,13 +52321,15 @@ fn __action896< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action518( + __action541( + source_code, mode, __temp0, __0, @@ -48356,8 +52341,9 @@ fn __action896< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action897< +fn __action927< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -48370,13 +52356,15 @@ fn __action897< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action657( + __action682( + source_code, mode, __temp0, __0, @@ -48391,8 +52379,9 @@ fn __action897< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action898< +fn __action928< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -48404,13 +52393,15 @@ fn __action898< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action658( + __action683( + source_code, mode, __temp0, __0, @@ -48424,8 +52415,9 @@ fn __action898< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action899< +fn __action929< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -48433,13 +52425,15 @@ fn __action899< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action211( + source_code, mode, __temp0, __0, @@ -48449,8 +52443,9 @@ fn __action899< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action900< +fn __action930< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -48459,13 +52454,15 @@ fn __action900< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action223( + __action233( + source_code, mode, __temp0, __0, @@ -48476,8 +52473,9 @@ fn __action900< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action901< +fn __action931< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -48486,13 +52484,15 @@ fn __action901< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action110( + source_code, mode, __temp0, __0, @@ -48503,8 +52503,9 @@ fn __action901< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action902< +fn __action932< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -48513,13 +52514,15 @@ fn __action902< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action169( + source_code, mode, __temp0, __0, @@ -48530,8 +52533,9 @@ fn __action902< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action903< +fn __action933< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, TextSize, TextSize), @@ -48539,13 +52543,15 @@ fn __action903< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action167( + source_code, mode, __temp0, __0, @@ -48555,8 +52561,35 @@ fn __action903< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action904< +fn __action934< >( + source_code: &str, + mode: Mode, + __0: (TextSize, (String, StringKind, bool), TextSize), +) -> Result> +{ + let __start0 = __0.0; + let __end0 = __0.0; + let __temp0 = __action414( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action214( + source_code, + mode, + __temp0, + __0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action935< +>( + source_code: &str, mode: Mode, __0: (TextSize, core::option::Option, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -48567,13 +52600,15 @@ fn __action904< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action210( + source_code, mode, __temp0, __0, @@ -48586,8 +52621,9 @@ fn __action904< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action905< +fn __action936< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -48596,13 +52632,15 @@ fn __action905< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action207( + source_code, mode, __temp0, __0, @@ -48613,8 +52651,9 @@ fn __action905< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action906< +fn __action937< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -48623,13 +52662,15 @@ fn __action906< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action637( + __action660( + source_code, mode, __temp0, __0, @@ -48640,8 +52681,9 @@ fn __action906< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action907< +fn __action938< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, TextSize, TextSize), @@ -48649,13 +52691,15 @@ fn __action907< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action638( + __action661( + source_code, mode, __temp0, __0, @@ -48665,8 +52709,9 @@ fn __action907< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action908< +fn __action939< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), @@ -48676,13 +52721,15 @@ fn __action908< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action498( + __action521( + source_code, mode, __temp0, __0, @@ -48694,8 +52741,9 @@ fn __action908< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action909< +fn __action940< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), @@ -48705,13 +52753,15 @@ fn __action909< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action551( + __action574( + source_code, mode, __temp0, __0, @@ -48723,8 +52773,9 @@ fn __action909< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action910< +fn __action941< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -48736,13 +52787,15 @@ fn __action910< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action379( + __action400( + source_code, mode, __temp0, __0, @@ -48756,8 +52809,9 @@ fn __action910< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action911< +fn __action942< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -48769,13 +52823,15 @@ fn __action911< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action411( + __action432( + source_code, mode, __temp0, __0, @@ -48789,8 +52845,9 @@ fn __action911< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action912< +fn __action943< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Suite, TextSize), @@ -48799,13 +52856,15 @@ fn __action912< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action1( + source_code, mode, __temp0, __0, @@ -48816,8 +52875,9 @@ fn __action912< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action913< +fn __action944< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -48827,13 +52887,15 @@ fn __action913< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action2( + source_code, mode, __temp0, __0, @@ -48845,8 +52907,9 @@ fn __action913< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action914< +fn __action945< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -48859,13 +52922,15 @@ fn __action914< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action148( + source_code, mode, __temp0, __0, @@ -48880,8 +52945,9 @@ fn __action914< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action915< +fn __action946< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -48894,13 +52960,15 @@ fn __action915< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action149( + source_code, mode, __temp0, __0, @@ -48915,8 +52983,9 @@ fn __action915< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action916< +fn __action947< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -48926,13 +52995,15 @@ fn __action916< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action150( + source_code, mode, __temp0, __0, @@ -48944,8 +53015,9 @@ fn __action916< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action917< +fn __action948< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, TextSize, TextSize), @@ -48953,13 +53025,15 @@ fn __action917< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action163( + source_code, mode, __temp0, __0, @@ -48969,8 +53043,9 @@ fn __action917< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action918< +fn __action949< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Expr, TextSize), @@ -48982,13 +53057,15 @@ fn __action918< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action164( + source_code, mode, __temp0, __0, @@ -49002,8 +53079,9 @@ fn __action918< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action919< +fn __action950< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -49012,13 +53090,15 @@ fn __action919< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action173( + source_code, mode, __temp0, __0, @@ -49029,8 +53109,9 @@ fn __action919< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action920< +fn __action951< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -49039,13 +53120,15 @@ fn __action920< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action174( + source_code, mode, __temp0, __0, @@ -49056,8 +53139,9 @@ fn __action920< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action921< +fn __action952< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -49066,13 +53150,15 @@ fn __action921< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action175( + source_code, mode, __temp0, __0, @@ -49083,8 +53169,9 @@ fn __action921< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action922< +fn __action953< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -49095,13 +53182,15 @@ fn __action922< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action639( + __action662( + source_code, mode, __temp0, __0, @@ -49114,8 +53203,9 @@ fn __action922< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action923< +fn __action954< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -49125,13 +53215,15 @@ fn __action923< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action640( + __action663( + source_code, mode, __temp0, __0, @@ -49143,8 +53235,9 @@ fn __action923< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action924< +fn __action955< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -49153,13 +53246,15 @@ fn __action924< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action168( + source_code, mode, __temp0, __0, @@ -49170,8 +53265,9 @@ fn __action924< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action925< +fn __action956< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, TextSize, TextSize), @@ -49179,13 +53275,15 @@ fn __action925< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action166( + source_code, mode, __temp0, __0, @@ -49195,8 +53293,9 @@ fn __action925< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action926< +fn __action957< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Expr, TextSize), __1: (TextSize, TextSize, TextSize), @@ -49204,13 +53303,15 @@ fn __action926< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action125( + source_code, mode, __temp0, __0, @@ -49220,8 +53321,9 @@ fn __action926< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action927< +fn __action958< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -49232,13 +53334,15 @@ fn __action927< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action146( + source_code, mode, __temp0, __0, @@ -49251,8 +53355,9 @@ fn __action927< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action928< +fn __action959< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -49262,13 +53367,15 @@ fn __action928< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action161( + source_code, mode, __temp0, __0, @@ -49280,8 +53387,9 @@ fn __action928< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action929< +fn __action960< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -49292,13 +53400,15 @@ fn __action929< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action659( + __action684( + source_code, mode, __temp0, __0, @@ -49311,8 +53421,9 @@ fn __action929< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action930< +fn __action961< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -49322,13 +53433,15 @@ fn __action930< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action660( + __action685( + source_code, mode, __temp0, __0, @@ -49340,8 +53453,9 @@ fn __action930< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action931< +fn __action962< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -49351,13 +53465,15 @@ fn __action931< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action403( + __action424( + source_code, mode, __temp0, __0, @@ -49369,8 +53485,9 @@ fn __action931< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action932< +fn __action963< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -49380,13 +53497,15 @@ fn __action932< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action508( + __action531( + source_code, mode, __temp0, __0, @@ -49398,8 +53517,9 @@ fn __action932< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action933< +fn __action964< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -49408,13 +53528,15 @@ fn __action933< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action177( + source_code, mode, __temp0, __0, @@ -49425,8 +53547,9 @@ fn __action933< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action934< +fn __action965< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -49436,13 +53559,15 @@ fn __action934< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action393( + let __temp0 = __action414( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action178( + source_code, mode, __temp0, __0, @@ -49454,8 +53579,9 @@ fn __action934< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action935< +fn __action966< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -49466,7 +53592,8 @@ fn __action935< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action861( + let __temp0 = __action891( + source_code, mode, __1, __2, @@ -49474,7 +53601,8 @@ fn __action935< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action420( + Ok(__action441( + source_code, mode, __0, __temp0, @@ -49483,8 +53611,9 @@ fn __action935< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action936< +fn __action967< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -49494,14 +53623,16 @@ fn __action936< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action862( + let __temp0 = __action892( + source_code, mode, __1, __2, __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action420( + Ok(__action441( + source_code, mode, __0, __temp0, @@ -49510,8 +53641,9 @@ fn __action936< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action937< +fn __action968< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -49523,7 +53655,8 @@ fn __action937< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action863( + let __temp0 = __action893( + source_code, mode, __1, __2, @@ -49532,7 +53665,8 @@ fn __action937< __5, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action420( + Ok(__action441( + source_code, mode, __0, __temp0, @@ -49541,8 +53675,9 @@ fn __action937< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action938< +fn __action969< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -49553,7 +53688,8 @@ fn __action938< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action864( + let __temp0 = __action894( + source_code, mode, __1, __2, @@ -49561,7 +53697,8 @@ fn __action938< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action420( + Ok(__action441( + source_code, mode, __0, __temp0, @@ -49570,8 +53707,9 @@ fn __action938< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action939< +fn __action970< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -49580,13 +53718,15 @@ fn __action939< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action865( + let __temp0 = __action895( + source_code, mode, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action420( + Ok(__action441( + source_code, mode, __0, __temp0, @@ -49595,8 +53735,9 @@ fn __action939< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action940< +fn __action971< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -49604,12 +53745,14 @@ fn __action940< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action866( + let __temp0 = __action896( + source_code, mode, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action420( + Ok(__action441( + source_code, mode, __0, __temp0, @@ -49618,8 +53761,9 @@ fn __action940< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action941< +fn __action972< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -49629,14 +53773,16 @@ fn __action941< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action867( + let __temp0 = __action897( + source_code, mode, __1, __2, __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action420( + Ok(__action441( + source_code, mode, __0, __temp0, @@ -49645,8 +53791,9 @@ fn __action941< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action942< +fn __action973< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -49655,13 +53802,15 @@ fn __action942< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action868( + let __temp0 = __action898( + source_code, mode, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action420( + Ok(__action441( + source_code, mode, __0, __temp0, @@ -49670,8 +53819,9 @@ fn __action942< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action943< +fn __action974< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -49683,7 +53833,8 @@ fn __action943< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action861( + let __temp0 = __action891( + source_code, mode, __0, __1, @@ -49691,7 +53842,8 @@ fn __action943< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action849( + Ok(__action879( + source_code, mode, __temp0, __4, @@ -49701,8 +53853,9 @@ fn __action943< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action944< +fn __action975< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -49713,14 +53866,16 @@ fn __action944< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action862( + let __temp0 = __action892( + source_code, mode, __0, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action849( + Ok(__action879( + source_code, mode, __temp0, __3, @@ -49730,8 +53885,9 @@ fn __action944< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action945< +fn __action976< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -49744,7 +53900,8 @@ fn __action945< { let __start0 = __0.0; let __end0 = __4.2; - let __temp0 = __action863( + let __temp0 = __action893( + source_code, mode, __0, __1, @@ -49753,7 +53910,8 @@ fn __action945< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action849( + Ok(__action879( + source_code, mode, __temp0, __5, @@ -49763,8 +53921,9 @@ fn __action945< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action946< +fn __action977< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -49776,7 +53935,8 @@ fn __action946< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action864( + let __temp0 = __action894( + source_code, mode, __0, __1, @@ -49784,7 +53944,8 @@ fn __action946< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action849( + Ok(__action879( + source_code, mode, __temp0, __4, @@ -49794,8 +53955,9 @@ fn __action946< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action947< +fn __action978< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -49805,13 +53967,15 @@ fn __action947< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action865( + let __temp0 = __action895( + source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action849( + Ok(__action879( + source_code, mode, __temp0, __2, @@ -49821,8 +53985,9 @@ fn __action947< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action948< +fn __action979< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -49831,12 +53996,14 @@ fn __action948< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action866( + let __temp0 = __action896( + source_code, mode, __0, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action849( + Ok(__action879( + source_code, mode, __temp0, __1, @@ -49846,8 +54013,9 @@ fn __action948< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action949< +fn __action980< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -49858,14 +54026,16 @@ fn __action949< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action867( + let __temp0 = __action897( + source_code, mode, __0, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action849( + Ok(__action879( + source_code, mode, __temp0, __3, @@ -49875,8 +54045,9 @@ fn __action949< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action950< +fn __action981< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -49886,13 +54057,15 @@ fn __action950< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action868( + let __temp0 = __action898( + source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action849( + Ok(__action879( + source_code, mode, __temp0, __2, @@ -49902,8 +54075,9 @@ fn __action950< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action951< +fn __action982< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -49914,7 +54088,8 @@ fn __action951< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action861( + let __temp0 = __action891( + source_code, mode, __0, __1, @@ -49922,7 +54097,8 @@ fn __action951< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action850( + Ok(__action880( + source_code, mode, __temp0, __4, @@ -49931,8 +54107,9 @@ fn __action951< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action952< +fn __action983< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -49942,14 +54119,16 @@ fn __action952< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action862( + let __temp0 = __action892( + source_code, mode, __0, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action850( + Ok(__action880( + source_code, mode, __temp0, __3, @@ -49958,8 +54137,9 @@ fn __action952< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action953< +fn __action984< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -49971,7 +54151,8 @@ fn __action953< { let __start0 = __0.0; let __end0 = __4.2; - let __temp0 = __action863( + let __temp0 = __action893( + source_code, mode, __0, __1, @@ -49980,7 +54161,8 @@ fn __action953< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action850( + Ok(__action880( + source_code, mode, __temp0, __5, @@ -49989,8 +54171,9 @@ fn __action953< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action954< +fn __action985< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -50001,7 +54184,8 @@ fn __action954< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action864( + let __temp0 = __action894( + source_code, mode, __0, __1, @@ -50009,7 +54193,8 @@ fn __action954< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action850( + Ok(__action880( + source_code, mode, __temp0, __4, @@ -50018,8 +54203,9 @@ fn __action954< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action955< +fn __action986< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -50028,13 +54214,15 @@ fn __action955< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action865( + let __temp0 = __action895( + source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action850( + Ok(__action880( + source_code, mode, __temp0, __2, @@ -50043,8 +54231,9 @@ fn __action955< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action956< +fn __action987< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -50052,12 +54241,14 @@ fn __action956< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action866( + let __temp0 = __action896( + source_code, mode, __0, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action850( + Ok(__action880( + source_code, mode, __temp0, __1, @@ -50066,8 +54257,9 @@ fn __action956< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action957< +fn __action988< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -50077,14 +54269,16 @@ fn __action957< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action867( + let __temp0 = __action897( + source_code, mode, __0, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action850( + Ok(__action880( + source_code, mode, __temp0, __3, @@ -50093,8 +54287,9 @@ fn __action957< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action958< +fn __action989< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -50103,13 +54298,15 @@ fn __action958< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action868( + let __temp0 = __action898( + source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action850( + Ok(__action880( + source_code, mode, __temp0, __2, @@ -50118,8 +54315,9 @@ fn __action958< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action959< +fn __action990< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50130,7 +54328,8 @@ fn __action959< { let __start0 = __0.0; let __end0 = __4.2; - let __temp0 = __action935( + let __temp0 = __action966( + source_code, mode, __0, __1, @@ -50139,7 +54338,8 @@ fn __action959< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action418( + Ok(__action439( + source_code, mode, __temp0, )) @@ -50147,8 +54347,9 @@ fn __action959< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action960< +fn __action991< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50158,7 +54359,8 @@ fn __action960< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action936( + let __temp0 = __action967( + source_code, mode, __0, __1, @@ -50166,7 +54368,8 @@ fn __action960< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action418( + Ok(__action439( + source_code, mode, __temp0, )) @@ -50174,8 +54377,9 @@ fn __action960< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action961< +fn __action992< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50187,7 +54391,8 @@ fn __action961< { let __start0 = __0.0; let __end0 = __5.2; - let __temp0 = __action937( + let __temp0 = __action968( + source_code, mode, __0, __1, @@ -50197,7 +54402,8 @@ fn __action961< __5, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action418( + Ok(__action439( + source_code, mode, __temp0, )) @@ -50205,8 +54411,9 @@ fn __action961< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action962< +fn __action993< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50217,7 +54424,8 @@ fn __action962< { let __start0 = __0.0; let __end0 = __4.2; - let __temp0 = __action938( + let __temp0 = __action969( + source_code, mode, __0, __1, @@ -50226,7 +54434,8 @@ fn __action962< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action418( + Ok(__action439( + source_code, mode, __temp0, )) @@ -50234,8 +54443,9 @@ fn __action962< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action963< +fn __action994< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50244,14 +54454,16 @@ fn __action963< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action939( + let __temp0 = __action970( + source_code, mode, __0, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action418( + Ok(__action439( + source_code, mode, __temp0, )) @@ -50259,8 +54471,9 @@ fn __action963< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action964< +fn __action995< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50268,13 +54481,15 @@ fn __action964< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action940( + let __temp0 = __action971( + source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action418( + Ok(__action439( + source_code, mode, __temp0, )) @@ -50282,8 +54497,9 @@ fn __action964< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action965< +fn __action996< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50293,7 +54509,8 @@ fn __action965< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action941( + let __temp0 = __action972( + source_code, mode, __0, __1, @@ -50301,7 +54518,8 @@ fn __action965< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action418( + Ok(__action439( + source_code, mode, __temp0, )) @@ -50309,8 +54527,9 @@ fn __action965< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action966< +fn __action997< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50319,14 +54538,16 @@ fn __action966< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action942( + let __temp0 = __action973( + source_code, mode, __0, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action418( + Ok(__action439( + source_code, mode, __temp0, )) @@ -50334,8 +54555,9 @@ fn __action966< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action967< +fn __action998< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50349,7 +54571,8 @@ fn __action967< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action959( + let __temp0 = __action990( + source_code, mode, __1, __2, @@ -50358,7 +54581,8 @@ fn __action967< __5, )?; let __temp0 = (__start0, __temp0, __end0); - __action845( + __action875( + source_code, mode, __0, __temp0, @@ -50369,8 +54593,9 @@ fn __action967< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action968< +fn __action999< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50383,7 +54608,8 @@ fn __action968< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action960( + let __temp0 = __action991( + source_code, mode, __1, __2, @@ -50391,7 +54617,8 @@ fn __action968< __4, )?; let __temp0 = (__start0, __temp0, __end0); - __action845( + __action875( + source_code, mode, __0, __temp0, @@ -50402,8 +54629,9 @@ fn __action968< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action969< +fn __action1000< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50418,7 +54646,8 @@ fn __action969< { let __start0 = __1.0; let __end0 = __6.2; - let __temp0 = __action961( + let __temp0 = __action992( + source_code, mode, __1, __2, @@ -50428,7 +54657,8 @@ fn __action969< __6, )?; let __temp0 = (__start0, __temp0, __end0); - __action845( + __action875( + source_code, mode, __0, __temp0, @@ -50439,8 +54669,9 @@ fn __action969< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action970< +fn __action1001< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50454,7 +54685,8 @@ fn __action970< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action962( + let __temp0 = __action993( + source_code, mode, __1, __2, @@ -50463,7 +54695,8 @@ fn __action970< __5, )?; let __temp0 = (__start0, __temp0, __end0); - __action845( + __action875( + source_code, mode, __0, __temp0, @@ -50474,8 +54707,9 @@ fn __action970< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action971< +fn __action1002< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50487,14 +54721,16 @@ fn __action971< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action963( + let __temp0 = __action994( + source_code, mode, __1, __2, __3, )?; let __temp0 = (__start0, __temp0, __end0); - __action845( + __action875( + source_code, mode, __0, __temp0, @@ -50505,8 +54741,9 @@ fn __action971< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action972< +fn __action1003< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50517,13 +54754,15 @@ fn __action972< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action964( + let __temp0 = __action995( + source_code, mode, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - __action845( + __action875( + source_code, mode, __0, __temp0, @@ -50534,8 +54773,9 @@ fn __action972< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action973< +fn __action1004< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50548,7 +54788,8 @@ fn __action973< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action965( + let __temp0 = __action996( + source_code, mode, __1, __2, @@ -50556,7 +54797,8 @@ fn __action973< __4, )?; let __temp0 = (__start0, __temp0, __end0); - __action845( + __action875( + source_code, mode, __0, __temp0, @@ -50567,8 +54809,9 @@ fn __action973< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action974< +fn __action1005< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50580,14 +54823,16 @@ fn __action974< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action966( + let __temp0 = __action997( + source_code, mode, __1, __2, __3, )?; let __temp0 = (__start0, __temp0, __end0); - __action845( + __action875( + source_code, mode, __0, __temp0, @@ -50598,8 +54843,9 @@ fn __action974< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action975< +fn __action1006< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50608,13 +54854,15 @@ fn __action975< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action419( + let __temp0 = __action440( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action845( + __action875( + source_code, mode, __0, __temp0, @@ -50625,8 +54873,9 @@ fn __action975< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action976< +fn __action1007< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50639,7 +54888,8 @@ fn __action976< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action959( + let __temp0 = __action990( + source_code, mode, __1, __2, @@ -50648,7 +54898,8 @@ fn __action976< __5, )?; let __temp0 = (__start0, __temp0, __end0); - __action846( + __action876( + source_code, mode, __0, __temp0, @@ -50658,8 +54909,9 @@ fn __action976< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action977< +fn __action1008< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50671,7 +54923,8 @@ fn __action977< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action960( + let __temp0 = __action991( + source_code, mode, __1, __2, @@ -50679,7 +54932,8 @@ fn __action977< __4, )?; let __temp0 = (__start0, __temp0, __end0); - __action846( + __action876( + source_code, mode, __0, __temp0, @@ -50689,8 +54943,9 @@ fn __action977< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action978< +fn __action1009< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50704,7 +54959,8 @@ fn __action978< { let __start0 = __1.0; let __end0 = __6.2; - let __temp0 = __action961( + let __temp0 = __action992( + source_code, mode, __1, __2, @@ -50714,7 +54970,8 @@ fn __action978< __6, )?; let __temp0 = (__start0, __temp0, __end0); - __action846( + __action876( + source_code, mode, __0, __temp0, @@ -50724,8 +54981,9 @@ fn __action978< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action979< +fn __action1010< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50738,7 +54996,8 @@ fn __action979< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action962( + let __temp0 = __action993( + source_code, mode, __1, __2, @@ -50747,7 +55006,8 @@ fn __action979< __5, )?; let __temp0 = (__start0, __temp0, __end0); - __action846( + __action876( + source_code, mode, __0, __temp0, @@ -50757,8 +55017,9 @@ fn __action979< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action980< +fn __action1011< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50769,14 +55030,16 @@ fn __action980< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action963( + let __temp0 = __action994( + source_code, mode, __1, __2, __3, )?; let __temp0 = (__start0, __temp0, __end0); - __action846( + __action876( + source_code, mode, __0, __temp0, @@ -50786,8 +55049,9 @@ fn __action980< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action981< +fn __action1012< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50797,13 +55061,15 @@ fn __action981< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action964( + let __temp0 = __action995( + source_code, mode, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - __action846( + __action876( + source_code, mode, __0, __temp0, @@ -50813,8 +55079,9 @@ fn __action981< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action982< +fn __action1013< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50826,7 +55093,8 @@ fn __action982< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action965( + let __temp0 = __action996( + source_code, mode, __1, __2, @@ -50834,7 +55102,8 @@ fn __action982< __4, )?; let __temp0 = (__start0, __temp0, __end0); - __action846( + __action876( + source_code, mode, __0, __temp0, @@ -50844,8 +55113,9 @@ fn __action982< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action983< +fn __action1014< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50856,14 +55126,16 @@ fn __action983< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action966( + let __temp0 = __action997( + source_code, mode, __1, __2, __3, )?; let __temp0 = (__start0, __temp0, __end0); - __action846( + __action876( + source_code, mode, __0, __temp0, @@ -50873,8 +55145,9 @@ fn __action983< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action984< +fn __action1015< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, TextSize, TextSize), @@ -50882,13 +55155,15 @@ fn __action984< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action419( + let __temp0 = __action440( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action846( + __action876( + source_code, mode, __0, __temp0, @@ -50898,8 +55173,9 @@ fn __action984< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action985< +fn __action1016< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -50907,12 +55183,14 @@ fn __action985< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action462( + let __temp0 = __action485( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action425( + __action446( + source_code, mode, __0, __temp0, @@ -50921,21 +55199,24 @@ fn __action985< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action986< +fn __action1017< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> Option> { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action463( + let __temp0 = __action486( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action425( + __action446( + source_code, mode, __0, __temp0, @@ -50944,8 +55225,9 @@ fn __action986< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action987< +fn __action1018< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -50955,12 +55237,14 @@ fn __action987< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action462( + let __temp0 = __action485( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action869( + __action899( + source_code, mode, __0, __temp0, @@ -50971,8 +55255,9 @@ fn __action987< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action988< +fn __action1019< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -50981,13 +55266,15 @@ fn __action988< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action463( + let __temp0 = __action486( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action869( + __action899( + source_code, mode, __0, __temp0, @@ -50998,8 +55285,9 @@ fn __action988< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action989< +fn __action1020< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -51010,12 +55298,14 @@ fn __action989< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action462( + let __temp0 = __action485( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action870( + __action900( + source_code, mode, __0, __temp0, @@ -51027,8 +55317,9 @@ fn __action989< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action990< +fn __action1021< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -51038,13 +55329,15 @@ fn __action990< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action463( + let __temp0 = __action486( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action870( + __action900( + source_code, mode, __0, __temp0, @@ -51056,8 +55349,9 @@ fn __action990< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action991< +fn __action1022< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -51065,12 +55359,14 @@ fn __action991< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action462( + let __temp0 = __action485( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action871( + __action901( + source_code, mode, __0, __temp0, @@ -51079,21 +55375,24 @@ fn __action991< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action992< +fn __action1023< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> Result<(Option>, Vec, Option>),__lalrpop_util::ParseError> { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action463( + let __temp0 = __action486( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action871( + __action901( + source_code, mode, __0, __temp0, @@ -51102,8 +55401,9 @@ fn __action992< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action993< +fn __action1024< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -51112,12 +55412,14 @@ fn __action993< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action462( + let __temp0 = __action485( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action872( + __action902( + source_code, mode, __0, __temp0, @@ -51127,8 +55429,9 @@ fn __action993< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action994< +fn __action1025< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -51136,13 +55439,15 @@ fn __action994< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action463( + let __temp0 = __action486( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action872( + __action902( + source_code, mode, __0, __temp0, @@ -51152,8 +55457,9 @@ fn __action994< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action995< +fn __action1026< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51164,7 +55470,8 @@ fn __action995< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action987( + let __temp0 = __action1018( + source_code, mode, __1, __2, @@ -51172,7 +55479,8 @@ fn __action995< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action428( + Ok(__action449( + source_code, mode, __0, __temp0, @@ -51181,8 +55489,9 @@ fn __action995< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action996< +fn __action1027< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51192,14 +55501,16 @@ fn __action996< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action988( + let __temp0 = __action1019( + source_code, mode, __1, __2, __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action428( + Ok(__action449( + source_code, mode, __0, __temp0, @@ -51208,8 +55519,9 @@ fn __action996< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action997< +fn __action1028< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51221,7 +55533,8 @@ fn __action997< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action989( + let __temp0 = __action1020( + source_code, mode, __1, __2, @@ -51230,7 +55543,8 @@ fn __action997< __5, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action428( + Ok(__action449( + source_code, mode, __0, __temp0, @@ -51239,8 +55553,9 @@ fn __action997< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action998< +fn __action1029< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51251,7 +55566,8 @@ fn __action998< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action990( + let __temp0 = __action1021( + source_code, mode, __1, __2, @@ -51259,7 +55575,8 @@ fn __action998< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action428( + Ok(__action449( + source_code, mode, __0, __temp0, @@ -51268,8 +55585,9 @@ fn __action998< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action999< +fn __action1030< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51278,13 +55596,15 @@ fn __action999< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action991( + let __temp0 = __action1022( + source_code, mode, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action428( + Ok(__action449( + source_code, mode, __0, __temp0, @@ -51293,8 +55613,9 @@ fn __action999< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1000< +fn __action1031< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51302,12 +55623,14 @@ fn __action1000< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action992( + let __temp0 = __action1023( + source_code, mode, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action428( + Ok(__action449( + source_code, mode, __0, __temp0, @@ -51316,8 +55639,9 @@ fn __action1000< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1001< +fn __action1032< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51327,14 +55651,16 @@ fn __action1001< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action993( + let __temp0 = __action1024( + source_code, mode, __1, __2, __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action428( + Ok(__action449( + source_code, mode, __0, __temp0, @@ -51343,8 +55669,9 @@ fn __action1001< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1002< +fn __action1033< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51353,13 +55680,15 @@ fn __action1002< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action994( + let __temp0 = __action1025( + source_code, mode, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action428( + Ok(__action449( + source_code, mode, __0, __temp0, @@ -51368,8 +55697,9 @@ fn __action1002< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1003< +fn __action1034< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -51381,7 +55711,8 @@ fn __action1003< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action987( + let __temp0 = __action1018( + source_code, mode, __0, __1, @@ -51389,7 +55720,8 @@ fn __action1003< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action857( + Ok(__action887( + source_code, mode, __temp0, __4, @@ -51399,8 +55731,9 @@ fn __action1003< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1004< +fn __action1035< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51411,14 +55744,16 @@ fn __action1004< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action988( + let __temp0 = __action1019( + source_code, mode, __0, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action857( + Ok(__action887( + source_code, mode, __temp0, __3, @@ -51428,8 +55763,9 @@ fn __action1004< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1005< +fn __action1036< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -51442,7 +55778,8 @@ fn __action1005< { let __start0 = __0.0; let __end0 = __4.2; - let __temp0 = __action989( + let __temp0 = __action1020( + source_code, mode, __0, __1, @@ -51451,7 +55788,8 @@ fn __action1005< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action857( + Ok(__action887( + source_code, mode, __temp0, __5, @@ -51461,8 +55799,9 @@ fn __action1005< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1006< +fn __action1037< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -51474,7 +55813,8 @@ fn __action1006< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action990( + let __temp0 = __action1021( + source_code, mode, __0, __1, @@ -51482,7 +55822,8 @@ fn __action1006< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action857( + Ok(__action887( + source_code, mode, __temp0, __4, @@ -51492,8 +55833,9 @@ fn __action1006< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1007< +fn __action1038< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -51503,13 +55845,15 @@ fn __action1007< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action991( + let __temp0 = __action1022( + source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action857( + Ok(__action887( + source_code, mode, __temp0, __2, @@ -51519,8 +55863,9 @@ fn __action1007< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1008< +fn __action1039< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51529,12 +55874,14 @@ fn __action1008< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action992( + let __temp0 = __action1023( + source_code, mode, __0, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action857( + Ok(__action887( + source_code, mode, __temp0, __1, @@ -51544,8 +55891,9 @@ fn __action1008< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1009< +fn __action1040< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -51556,14 +55904,16 @@ fn __action1009< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action993( + let __temp0 = __action1024( + source_code, mode, __0, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action857( + Ok(__action887( + source_code, mode, __temp0, __3, @@ -51573,8 +55923,9 @@ fn __action1009< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1010< +fn __action1041< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -51584,13 +55935,15 @@ fn __action1010< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action994( + let __temp0 = __action1025( + source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action857( + Ok(__action887( + source_code, mode, __temp0, __2, @@ -51600,8 +55953,9 @@ fn __action1010< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1011< +fn __action1042< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -51612,7 +55966,8 @@ fn __action1011< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action987( + let __temp0 = __action1018( + source_code, mode, __0, __1, @@ -51620,7 +55975,8 @@ fn __action1011< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action858( + Ok(__action888( + source_code, mode, __temp0, __4, @@ -51629,8 +55985,9 @@ fn __action1011< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1012< +fn __action1043< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51640,14 +55997,16 @@ fn __action1012< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action988( + let __temp0 = __action1019( + source_code, mode, __0, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action858( + Ok(__action888( + source_code, mode, __temp0, __3, @@ -51656,8 +56015,9 @@ fn __action1012< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1013< +fn __action1044< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -51669,7 +56029,8 @@ fn __action1013< { let __start0 = __0.0; let __end0 = __4.2; - let __temp0 = __action989( + let __temp0 = __action1020( + source_code, mode, __0, __1, @@ -51678,7 +56039,8 @@ fn __action1013< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action858( + Ok(__action888( + source_code, mode, __temp0, __5, @@ -51687,8 +56049,9 @@ fn __action1013< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1014< +fn __action1045< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -51699,7 +56062,8 @@ fn __action1014< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action990( + let __temp0 = __action1021( + source_code, mode, __0, __1, @@ -51707,7 +56071,8 @@ fn __action1014< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action858( + Ok(__action888( + source_code, mode, __temp0, __4, @@ -51716,8 +56081,9 @@ fn __action1014< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1015< +fn __action1046< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -51726,13 +56092,15 @@ fn __action1015< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action991( + let __temp0 = __action1022( + source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action858( + Ok(__action888( + source_code, mode, __temp0, __2, @@ -51741,8 +56109,9 @@ fn __action1015< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1016< +fn __action1047< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, TextSize, TextSize), @@ -51750,12 +56119,14 @@ fn __action1016< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action992( + let __temp0 = __action1023( + source_code, mode, __0, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action858( + Ok(__action888( + source_code, mode, __temp0, __1, @@ -51764,8 +56135,9 @@ fn __action1016< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1017< +fn __action1048< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -51775,14 +56147,16 @@ fn __action1017< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action993( + let __temp0 = __action1024( + source_code, mode, __0, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action858( + Ok(__action888( + source_code, mode, __temp0, __3, @@ -51791,8 +56165,9 @@ fn __action1017< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1018< +fn __action1049< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -51801,13 +56176,15 @@ fn __action1018< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action994( + let __temp0 = __action1025( + source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action858( + Ok(__action888( + source_code, mode, __temp0, __2, @@ -51816,8 +56193,9 @@ fn __action1018< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1019< +fn __action1050< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51828,7 +56206,8 @@ fn __action1019< { let __start0 = __0.0; let __end0 = __4.2; - let __temp0 = __action995( + let __temp0 = __action1026( + source_code, mode, __0, __1, @@ -51837,7 +56216,8 @@ fn __action1019< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action426( + Ok(__action447( + source_code, mode, __temp0, )) @@ -51845,8 +56225,9 @@ fn __action1019< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1020< +fn __action1051< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51856,7 +56237,8 @@ fn __action1020< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action996( + let __temp0 = __action1027( + source_code, mode, __0, __1, @@ -51864,7 +56246,8 @@ fn __action1020< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action426( + Ok(__action447( + source_code, mode, __temp0, )) @@ -51872,8 +56255,9 @@ fn __action1020< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1021< +fn __action1052< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51885,7 +56269,8 @@ fn __action1021< { let __start0 = __0.0; let __end0 = __5.2; - let __temp0 = __action997( + let __temp0 = __action1028( + source_code, mode, __0, __1, @@ -51895,7 +56280,8 @@ fn __action1021< __5, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action426( + Ok(__action447( + source_code, mode, __temp0, )) @@ -51903,8 +56289,9 @@ fn __action1021< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1022< +fn __action1053< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51915,7 +56302,8 @@ fn __action1022< { let __start0 = __0.0; let __end0 = __4.2; - let __temp0 = __action998( + let __temp0 = __action1029( + source_code, mode, __0, __1, @@ -51924,7 +56312,8 @@ fn __action1022< __4, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action426( + Ok(__action447( + source_code, mode, __temp0, )) @@ -51932,8 +56321,9 @@ fn __action1022< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1023< +fn __action1054< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51942,14 +56332,16 @@ fn __action1023< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action999( + let __temp0 = __action1030( + source_code, mode, __0, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action426( + Ok(__action447( + source_code, mode, __temp0, )) @@ -51957,8 +56349,9 @@ fn __action1023< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1024< +fn __action1055< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51966,13 +56359,15 @@ fn __action1024< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action1000( + let __temp0 = __action1031( + source_code, mode, __0, __1, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action426( + Ok(__action447( + source_code, mode, __temp0, )) @@ -51980,8 +56375,9 @@ fn __action1024< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1025< +fn __action1056< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -51991,7 +56387,8 @@ fn __action1025< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action1001( + let __temp0 = __action1032( + source_code, mode, __0, __1, @@ -51999,7 +56396,8 @@ fn __action1025< __3, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action426( + Ok(__action447( + source_code, mode, __temp0, )) @@ -52007,8 +56405,9 @@ fn __action1025< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1026< +fn __action1057< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52017,14 +56416,16 @@ fn __action1026< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action1002( + let __temp0 = __action1033( + source_code, mode, __0, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - Ok(__action426( + Ok(__action447( + source_code, mode, __temp0, )) @@ -52032,8 +56433,9 @@ fn __action1026< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1027< +fn __action1058< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52047,7 +56449,8 @@ fn __action1027< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action1019( + let __temp0 = __action1050( + source_code, mode, __1, __2, @@ -52056,7 +56459,8 @@ fn __action1027< __5, )?; let __temp0 = (__start0, __temp0, __end0); - __action853( + __action883( + source_code, mode, __0, __temp0, @@ -52067,8 +56471,9 @@ fn __action1027< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1028< +fn __action1059< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52081,7 +56486,8 @@ fn __action1028< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action1020( + let __temp0 = __action1051( + source_code, mode, __1, __2, @@ -52089,7 +56495,8 @@ fn __action1028< __4, )?; let __temp0 = (__start0, __temp0, __end0); - __action853( + __action883( + source_code, mode, __0, __temp0, @@ -52100,8 +56507,9 @@ fn __action1028< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1029< +fn __action1060< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52116,7 +56524,8 @@ fn __action1029< { let __start0 = __1.0; let __end0 = __6.2; - let __temp0 = __action1021( + let __temp0 = __action1052( + source_code, mode, __1, __2, @@ -52126,7 +56535,8 @@ fn __action1029< __6, )?; let __temp0 = (__start0, __temp0, __end0); - __action853( + __action883( + source_code, mode, __0, __temp0, @@ -52137,8 +56547,9 @@ fn __action1029< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1030< +fn __action1061< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52152,7 +56563,8 @@ fn __action1030< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action1022( + let __temp0 = __action1053( + source_code, mode, __1, __2, @@ -52161,7 +56573,8 @@ fn __action1030< __5, )?; let __temp0 = (__start0, __temp0, __end0); - __action853( + __action883( + source_code, mode, __0, __temp0, @@ -52172,8 +56585,9 @@ fn __action1030< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1031< +fn __action1062< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52185,14 +56599,16 @@ fn __action1031< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action1023( + let __temp0 = __action1054( + source_code, mode, __1, __2, __3, )?; let __temp0 = (__start0, __temp0, __end0); - __action853( + __action883( + source_code, mode, __0, __temp0, @@ -52203,8 +56619,9 @@ fn __action1031< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1032< +fn __action1063< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52215,13 +56632,15 @@ fn __action1032< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1024( + let __temp0 = __action1055( + source_code, mode, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - __action853( + __action883( + source_code, mode, __0, __temp0, @@ -52232,8 +56651,9 @@ fn __action1032< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1033< +fn __action1064< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52246,7 +56666,8 @@ fn __action1033< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action1025( + let __temp0 = __action1056( + source_code, mode, __1, __2, @@ -52254,7 +56675,8 @@ fn __action1033< __4, )?; let __temp0 = (__start0, __temp0, __end0); - __action853( + __action883( + source_code, mode, __0, __temp0, @@ -52265,8 +56687,9 @@ fn __action1033< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1034< +fn __action1065< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52278,14 +56701,16 @@ fn __action1034< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action1026( + let __temp0 = __action1057( + source_code, mode, __1, __2, __3, )?; let __temp0 = (__start0, __temp0, __end0); - __action853( + __action883( + source_code, mode, __0, __temp0, @@ -52296,8 +56721,9 @@ fn __action1034< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1035< +fn __action1066< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52306,13 +56732,15 @@ fn __action1035< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action427( + let __temp0 = __action448( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action853( + __action883( + source_code, mode, __0, __temp0, @@ -52323,8 +56751,9 @@ fn __action1035< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1036< +fn __action1067< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52337,7 +56766,8 @@ fn __action1036< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action1019( + let __temp0 = __action1050( + source_code, mode, __1, __2, @@ -52346,7 +56776,8 @@ fn __action1036< __5, )?; let __temp0 = (__start0, __temp0, __end0); - __action854( + __action884( + source_code, mode, __0, __temp0, @@ -52356,8 +56787,9 @@ fn __action1036< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1037< +fn __action1068< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52369,7 +56801,8 @@ fn __action1037< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action1020( + let __temp0 = __action1051( + source_code, mode, __1, __2, @@ -52377,7 +56810,8 @@ fn __action1037< __4, )?; let __temp0 = (__start0, __temp0, __end0); - __action854( + __action884( + source_code, mode, __0, __temp0, @@ -52387,8 +56821,9 @@ fn __action1037< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1038< +fn __action1069< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52402,7 +56837,8 @@ fn __action1038< { let __start0 = __1.0; let __end0 = __6.2; - let __temp0 = __action1021( + let __temp0 = __action1052( + source_code, mode, __1, __2, @@ -52412,7 +56848,8 @@ fn __action1038< __6, )?; let __temp0 = (__start0, __temp0, __end0); - __action854( + __action884( + source_code, mode, __0, __temp0, @@ -52422,8 +56859,9 @@ fn __action1038< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1039< +fn __action1070< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52436,7 +56874,8 @@ fn __action1039< { let __start0 = __1.0; let __end0 = __5.2; - let __temp0 = __action1022( + let __temp0 = __action1053( + source_code, mode, __1, __2, @@ -52445,7 +56884,8 @@ fn __action1039< __5, )?; let __temp0 = (__start0, __temp0, __end0); - __action854( + __action884( + source_code, mode, __0, __temp0, @@ -52455,8 +56895,9 @@ fn __action1039< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1040< +fn __action1071< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52467,14 +56908,16 @@ fn __action1040< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action1023( + let __temp0 = __action1054( + source_code, mode, __1, __2, __3, )?; let __temp0 = (__start0, __temp0, __end0); - __action854( + __action884( + source_code, mode, __0, __temp0, @@ -52484,8 +56927,9 @@ fn __action1040< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1041< +fn __action1072< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52495,13 +56939,15 @@ fn __action1041< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1024( + let __temp0 = __action1055( + source_code, mode, __1, __2, )?; let __temp0 = (__start0, __temp0, __end0); - __action854( + __action884( + source_code, mode, __0, __temp0, @@ -52511,8 +56957,9 @@ fn __action1041< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1042< +fn __action1073< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52524,7 +56971,8 @@ fn __action1042< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action1025( + let __temp0 = __action1056( + source_code, mode, __1, __2, @@ -52532,7 +56980,8 @@ fn __action1042< __4, )?; let __temp0 = (__start0, __temp0, __end0); - __action854( + __action884( + source_code, mode, __0, __temp0, @@ -52542,8 +56991,9 @@ fn __action1042< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1043< +fn __action1074< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52554,14 +57004,16 @@ fn __action1043< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action1026( + let __temp0 = __action1057( + source_code, mode, __1, __2, __3, )?; let __temp0 = (__start0, __temp0, __end0); - __action854( + __action884( + source_code, mode, __0, __temp0, @@ -52571,8 +57023,9 @@ fn __action1043< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1044< +fn __action1075< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, TextSize, TextSize), @@ -52580,13 +57033,15 @@ fn __action1044< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action427( + let __temp0 = __action448( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action854( + __action884( + source_code, mode, __0, __temp0, @@ -52596,8 +57051,9 @@ fn __action1044< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1045< +fn __action1076< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -52605,13 +57061,15 @@ fn __action1045< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action354( + let __temp0 = __action375( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action352( + __action373( + source_code, mode, __temp0, ) @@ -52619,8 +57077,9 @@ fn __action1045< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1046< +fn __action1077< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -52631,13 +57090,15 @@ fn __action1046< { let __start0 = __2.0; let __end0 = __3.2; - let __temp0 = __action1045( + let __temp0 = __action1076( + source_code, mode, __2, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action707( + __action731( + source_code, mode, __0, __1, @@ -52648,8 +57109,9 @@ fn __action1046< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1047< +fn __action1078< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -52658,13 +57120,15 @@ fn __action1047< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action353( + let __temp0 = __action374( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action707( + __action731( + source_code, mode, __0, __1, @@ -52675,8 +57139,9 @@ fn __action1047< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1048< +fn __action1079< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -52684,13 +57149,15 @@ fn __action1048< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action545( + let __temp0 = __action568( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action555( + __action578( + source_code, mode, __temp0, ) @@ -52698,8 +57165,9 @@ fn __action1048< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1049< +fn __action1080< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -52708,13 +57176,15 @@ fn __action1049< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action545( + let __temp0 = __action568( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action556( + __action579( + source_code, mode, __0, __temp0, @@ -52723,8 +57193,9 @@ fn __action1049< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1050< +fn __action1081< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -52736,13 +57207,15 @@ fn __action1050< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action543( + let __temp0 = __action566( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action715( + __action739( + source_code, mode, __0, __1, @@ -52756,8 +57229,9 @@ fn __action1050< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1051< +fn __action1082< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -52770,12 +57244,14 @@ fn __action1051< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action544( + let __temp0 = __action567( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action715( + __action739( + source_code, mode, __0, __1, @@ -52789,8 +57265,9 @@ fn __action1051< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1052< +fn __action1083< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -52801,13 +57278,15 @@ fn __action1052< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action543( + let __temp0 = __action566( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action716( + __action740( + source_code, mode, __0, __1, @@ -52820,8 +57299,9 @@ fn __action1052< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1053< +fn __action1084< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -52833,12 +57313,14 @@ fn __action1053< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action544( + let __temp0 = __action567( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action716( + __action740( + source_code, mode, __0, __1, @@ -52851,8 +57333,9 @@ fn __action1053< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1054< +fn __action1085< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -52864,13 +57347,15 @@ fn __action1054< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action543( + let __temp0 = __action566( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action734( + __action758( + source_code, mode, __0, __1, @@ -52884,8 +57369,9 @@ fn __action1054< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1055< +fn __action1086< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -52898,12 +57384,14 @@ fn __action1055< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action544( + let __temp0 = __action567( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action734( + __action758( + source_code, mode, __0, __1, @@ -52917,8 +57405,9 @@ fn __action1055< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1056< +fn __action1087< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -52929,13 +57418,15 @@ fn __action1056< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action543( + let __temp0 = __action566( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action735( + __action759( + source_code, mode, __0, __1, @@ -52948,8 +57439,9 @@ fn __action1056< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1057< +fn __action1088< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -52961,12 +57453,14 @@ fn __action1057< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action544( + let __temp0 = __action567( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action735( + __action759( + source_code, mode, __0, __1, @@ -52979,8 +57473,9 @@ fn __action1057< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1058< +fn __action1089< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::WithItem, TextSize), @@ -52988,13 +57483,15 @@ fn __action1058< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action296( + let __temp0 = __action316( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action290( + __action310( + source_code, mode, __temp0, ) @@ -53002,8 +57499,9 @@ fn __action1058< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1059< +fn __action1090< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -53012,13 +57510,15 @@ fn __action1059< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action296( + let __temp0 = __action316( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action291( + __action311( + source_code, mode, __0, __temp0, @@ -53027,8 +57527,9 @@ fn __action1059< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1060< +fn __action1091< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -53039,13 +57540,15 @@ fn __action1060< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action294( + let __temp0 = __action314( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action643( + __action666( + source_code, mode, __0, __1, @@ -53058,8 +57561,9 @@ fn __action1060< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1061< +fn __action1092< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -53071,12 +57575,14 @@ fn __action1061< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action295( + let __temp0 = __action315( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action643( + __action666( + source_code, mode, __0, __1, @@ -53089,8 +57595,9 @@ fn __action1061< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1062< +fn __action1093< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -53100,13 +57607,15 @@ fn __action1062< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action294( + let __temp0 = __action314( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action644( + __action667( + source_code, mode, __0, __1, @@ -53118,8 +57627,9 @@ fn __action1062< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1063< +fn __action1094< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -53130,12 +57640,14 @@ fn __action1063< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action295( + let __temp0 = __action315( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action644( + __action667( + source_code, mode, __0, __1, @@ -53147,8 +57659,9 @@ fn __action1063< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1064< +fn __action1095< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -53156,13 +57669,15 @@ fn __action1064< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action283( + let __temp0 = __action303( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action281( + __action301( + source_code, mode, __temp0, ) @@ -53170,8 +57685,9 @@ fn __action1064< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1065< +fn __action1096< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -53187,13 +57703,15 @@ fn __action1065< { let __start0 = __6.0; let __end0 = __7.2; - let __temp0 = __action1064( + let __temp0 = __action1095( + source_code, mode, __6, __7, ); let __temp0 = (__start0, __temp0, __end0); - __action786( + __action816( + source_code, mode, __0, __1, @@ -53209,8 +57727,9 @@ fn __action1065< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1066< +fn __action1097< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -53224,13 +57743,15 @@ fn __action1066< { let __start0 = __5.2; let __end0 = __6.0; - let __temp0 = __action282( + let __temp0 = __action302( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action786( + __action816( + source_code, mode, __0, __1, @@ -53246,8 +57767,9 @@ fn __action1066< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1067< +fn __action1098< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -53262,13 +57784,15 @@ fn __action1067< { let __start0 = __5.0; let __end0 = __6.2; - let __temp0 = __action1064( + let __temp0 = __action1095( + source_code, mode, __5, __6, ); let __temp0 = (__start0, __temp0, __end0); - __action787( + __action817( + source_code, mode, __0, __1, @@ -53283,8 +57807,9 @@ fn __action1067< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1068< +fn __action1099< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -53297,13 +57822,15 @@ fn __action1068< { let __start0 = __4.2; let __end0 = __5.0; - let __temp0 = __action282( + let __temp0 = __action302( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action787( + __action817( + source_code, mode, __0, __1, @@ -53318,8 +57845,9 @@ fn __action1068< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1069< +fn __action1100< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -53327,13 +57855,15 @@ fn __action1069< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action359( + let __temp0 = __action380( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action357( + __action378( + source_code, mode, __temp0, ) @@ -53341,8 +57871,9 @@ fn __action1069< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1070< +fn __action1101< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec<(token::Tok, ast::Identifier)>, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -53351,13 +57882,15 @@ fn __action1070< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action359( + let __temp0 = __action380( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action358( + __action379( + source_code, mode, __0, __temp0, @@ -53366,8 +57899,9 @@ fn __action1070< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1071< +fn __action1102< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -53375,13 +57909,15 @@ fn __action1071< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action273( + let __temp0 = __action293( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action271( + __action291( + source_code, mode, __temp0, ) @@ -53389,8 +57925,9 @@ fn __action1071< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1072< +fn __action1103< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -53400,13 +57937,15 @@ fn __action1072< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1071( + let __temp0 = __action1102( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action768( + __action792( + source_code, mode, __0, __temp0, @@ -53416,8 +57955,9 @@ fn __action1072< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1073< +fn __action1104< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, TextSize, TextSize), @@ -53425,13 +57965,15 @@ fn __action1073< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action272( + let __temp0 = __action292( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action768( + __action792( + source_code, mode, __0, __temp0, @@ -53441,8 +57983,9 @@ fn __action1073< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1074< +fn __action1105< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -53452,13 +57995,15 @@ fn __action1074< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1071( + let __temp0 = __action1102( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action919( + __action950( + source_code, mode, __0, __temp0, @@ -53468,8 +58013,9 @@ fn __action1074< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1075< +fn __action1106< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, TextSize, TextSize), @@ -53477,13 +58023,15 @@ fn __action1075< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action272( + let __temp0 = __action292( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action919( + __action950( + source_code, mode, __0, __temp0, @@ -53493,8 +58041,9 @@ fn __action1075< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1076< +fn __action1107< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -53504,13 +58053,15 @@ fn __action1076< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1071( + let __temp0 = __action1102( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action924( + __action955( + source_code, mode, __0, __temp0, @@ -53520,8 +58071,9 @@ fn __action1076< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1077< +fn __action1108< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, TextSize, TextSize), @@ -53529,13 +58081,15 @@ fn __action1077< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action272( + let __temp0 = __action292( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action924( + __action955( + source_code, mode, __0, __temp0, @@ -53545,8 +58099,9 @@ fn __action1077< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1078< +fn __action1109< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -53554,13 +58109,15 @@ fn __action1078< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action270( + let __temp0 = __action290( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action268( + __action288( + source_code, mode, __temp0, ) @@ -53568,8 +58125,9 @@ fn __action1078< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1079< +fn __action1110< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -53579,13 +58137,15 @@ fn __action1079< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1078( + let __temp0 = __action1109( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action902( + __action932( + source_code, mode, __0, __temp0, @@ -53595,8 +58155,9 @@ fn __action1079< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1080< +fn __action1111< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, TextSize, TextSize), @@ -53604,13 +58165,15 @@ fn __action1080< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action269( + let __temp0 = __action289( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action902( + __action932( + source_code, mode, __0, __temp0, @@ -53620,20 +58183,23 @@ fn __action1080< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1081< +fn __action1112< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> alloc::vec::Vec { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action349( + let __temp0 = __action370( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action347( + __action368( + source_code, mode, __temp0, ) @@ -53641,8 +58207,9 @@ fn __action1081< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1082< +fn __action1113< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -53650,12 +58217,14 @@ fn __action1082< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action349( + let __temp0 = __action370( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action348( + __action369( + source_code, mode, __0, __temp0, @@ -53664,20 +58233,23 @@ fn __action1082< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1083< +fn __action1114< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> alloc::vec::Vec { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action391( + let __temp0 = __action412( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action394( + __action415( + source_code, mode, __temp0, ) @@ -53685,8 +58257,9 @@ fn __action1083< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1084< +fn __action1115< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -53694,12 +58267,14 @@ fn __action1084< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action391( + let __temp0 = __action412( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action395( + __action416( + source_code, mode, __0, __temp0, @@ -53708,8 +58283,9 @@ fn __action1084< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1085< +fn __action1116< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -53718,13 +58294,15 @@ fn __action1085< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action389( + let __temp0 = __action410( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action913( + __action944( + source_code, mode, __0, __1, @@ -53735,8 +58313,9 @@ fn __action1085< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1086< +fn __action1117< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -53746,12 +58325,14 @@ fn __action1086< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action390( + let __temp0 = __action411( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action913( + __action944( + source_code, mode, __0, __1, @@ -53762,8 +58343,9 @@ fn __action1086< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1087< +fn __action1118< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -53771,13 +58353,15 @@ fn __action1087< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action402( + let __temp0 = __action423( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action400( + __action421( + source_code, mode, __temp0, ) @@ -53785,8 +58369,9 @@ fn __action1087< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1088< +fn __action1119< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -53796,13 +58381,15 @@ fn __action1088< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1087( + let __temp0 = __action1118( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action799( + __action829( + source_code, mode, __0, __temp0, @@ -53812,8 +58399,9 @@ fn __action1088< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1089< +fn __action1120< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, TextSize, TextSize), @@ -53821,13 +58409,15 @@ fn __action1089< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action401( + let __temp0 = __action422( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action799( + __action829( + source_code, mode, __0, __temp0, @@ -53837,8 +58427,9 @@ fn __action1089< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1090< +fn __action1121< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -53848,13 +58439,15 @@ fn __action1090< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1087( + let __temp0 = __action1118( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action800( + __action830( + source_code, mode, __0, __temp0, @@ -53864,8 +58457,9 @@ fn __action1090< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1091< +fn __action1122< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, TextSize, TextSize), @@ -53873,13 +58467,15 @@ fn __action1091< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action401( + let __temp0 = __action422( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action800( + __action830( + source_code, mode, __0, __temp0, @@ -53889,8 +58485,9 @@ fn __action1091< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1092< +fn __action1123< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -53899,14 +58496,16 @@ fn __action1092< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action316( + let __temp0 = __action336( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action314( + __action334( + source_code, mode, __temp0, ) @@ -53914,8 +58513,9 @@ fn __action1092< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1093< +fn __action1124< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -53931,14 +58531,16 @@ fn __action1093< { let __start0 = __7.0; let __end0 = __9.2; - let __temp0 = __action1092( + let __temp0 = __action1123( + source_code, mode, __7, __8, __9, ); let __temp0 = (__start0, __temp0, __end0); - __action784( + __action814( + source_code, mode, __0, __1, @@ -53953,8 +58555,9 @@ fn __action1093< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1094< +fn __action1125< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -53967,13 +58570,15 @@ fn __action1094< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action315( + let __temp0 = __action335( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action784( + __action814( + source_code, mode, __0, __1, @@ -53988,8 +58593,9 @@ fn __action1094< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1095< +fn __action1126< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -54004,14 +58610,16 @@ fn __action1095< { let __start0 = __6.0; let __end0 = __8.2; - let __temp0 = __action1092( + let __temp0 = __action1123( + source_code, mode, __6, __7, __8, ); let __temp0 = (__start0, __temp0, __end0); - __action785( + __action815( + source_code, mode, __0, __1, @@ -54025,8 +58633,9 @@ fn __action1095< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1096< +fn __action1127< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -54038,13 +58647,15 @@ fn __action1096< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action315( + let __temp0 = __action335( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action785( + __action815( + source_code, mode, __0, __1, @@ -54058,8 +58669,9 @@ fn __action1096< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1097< +fn __action1128< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -54074,14 +58686,16 @@ fn __action1097< { let __start0 = __4.0; let __end0 = __6.2; - let __temp0 = __action1092( + let __temp0 = __action1123( + source_code, mode, __4, __5, __6, ); let __temp0 = (__start0, __temp0, __end0); - __action914( + __action945( + source_code, mode, __0, __1, @@ -54095,8 +58709,9 @@ fn __action1097< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1098< +fn __action1129< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -54108,13 +58723,15 @@ fn __action1098< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action315( + let __temp0 = __action335( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action914( + __action945( + source_code, mode, __0, __1, @@ -54128,8 +58745,9 @@ fn __action1098< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1099< +fn __action1130< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -54144,14 +58762,16 @@ fn __action1099< { let __start0 = __4.0; let __end0 = __6.2; - let __temp0 = __action1092( + let __temp0 = __action1123( + source_code, mode, __4, __5, __6, ); let __temp0 = (__start0, __temp0, __end0); - __action915( + __action946( + source_code, mode, __0, __1, @@ -54165,8 +58785,9 @@ fn __action1099< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1100< +fn __action1131< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -54178,13 +58799,15 @@ fn __action1100< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action315( + let __temp0 = __action335( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action915( + __action946( + source_code, mode, __0, __1, @@ -54198,8 +58821,9 @@ fn __action1100< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1101< +fn __action1132< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -54212,14 +58836,16 @@ fn __action1101< { let __start0 = __4.0; let __end0 = __6.2; - let __temp0 = __action1092( + let __temp0 = __action1123( + source_code, mode, __4, __5, __6, ); let __temp0 = (__start0, __temp0, __end0); - __action927( + __action958( + source_code, mode, __0, __1, @@ -54231,8 +58857,9 @@ fn __action1101< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1102< +fn __action1133< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -54242,13 +58869,15 @@ fn __action1102< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action315( + let __temp0 = __action335( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action927( + __action958( + source_code, mode, __0, __1, @@ -54260,8 +58889,9 @@ fn __action1102< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1103< +fn __action1134< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -54270,14 +58900,16 @@ fn __action1103< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action309( + let __temp0 = __action329( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action307( + __action327( + source_code, mode, __temp0, ) @@ -54285,8 +58917,9 @@ fn __action1103< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1104< +fn __action1135< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -54298,14 +58931,16 @@ fn __action1104< { let __start0 = __3.0; let __end0 = __5.2; - let __temp0 = __action309( + let __temp0 = __action329( + source_code, mode, __3, __4, __5, ); let __temp0 = (__start0, __temp0, __end0); - __action916( + __action947( + source_code, mode, __0, __1, @@ -54316,8 +58951,9 @@ fn __action1104< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1105< +fn __action1136< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -54334,14 +58970,16 @@ fn __action1105< { let __start0 = __7.0; let __end0 = __9.2; - let __temp0 = __action1103( + let __temp0 = __action1134( + source_code, mode, __7, __8, __9, ); let __temp0 = (__start0, __temp0, __end0); - __action1097( + __action1128( + source_code, mode, __0, __1, @@ -54357,8 +58995,9 @@ fn __action1105< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1106< +fn __action1137< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -54372,13 +59011,15 @@ fn __action1106< { let __start0 = __6.2; let __end0 = __7.0; - let __temp0 = __action308( + let __temp0 = __action328( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1097( + __action1128( + source_code, mode, __0, __1, @@ -54394,8 +59035,9 @@ fn __action1106< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1107< +fn __action1138< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -54409,14 +59051,16 @@ fn __action1107< { let __start0 = __4.0; let __end0 = __6.2; - let __temp0 = __action1103( + let __temp0 = __action1134( + source_code, mode, __4, __5, __6, ); let __temp0 = (__start0, __temp0, __end0); - __action1098( + __action1129( + source_code, mode, __0, __1, @@ -54429,8 +59073,9 @@ fn __action1107< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1108< +fn __action1139< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -54441,13 +59086,15 @@ fn __action1108< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action308( + let __temp0 = __action328( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1098( + __action1129( + source_code, mode, __0, __1, @@ -54460,8 +59107,9 @@ fn __action1108< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1109< +fn __action1140< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -54478,14 +59126,16 @@ fn __action1109< { let __start0 = __7.0; let __end0 = __9.2; - let __temp0 = __action1103( + let __temp0 = __action1134( + source_code, mode, __7, __8, __9, ); let __temp0 = (__start0, __temp0, __end0); - __action1099( + __action1130( + source_code, mode, __0, __1, @@ -54501,8 +59151,9 @@ fn __action1109< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1110< +fn __action1141< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -54516,13 +59167,15 @@ fn __action1110< { let __start0 = __6.2; let __end0 = __7.0; - let __temp0 = __action308( + let __temp0 = __action328( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1099( + __action1130( + source_code, mode, __0, __1, @@ -54538,8 +59191,9 @@ fn __action1110< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1111< +fn __action1142< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -54553,14 +59207,16 @@ fn __action1111< { let __start0 = __4.0; let __end0 = __6.2; - let __temp0 = __action1103( + let __temp0 = __action1134( + source_code, mode, __4, __5, __6, ); let __temp0 = (__start0, __temp0, __end0); - __action1100( + __action1131( + source_code, mode, __0, __1, @@ -54573,8 +59229,9 @@ fn __action1111< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1112< +fn __action1143< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -54585,13 +59242,15 @@ fn __action1112< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action308( + let __temp0 = __action328( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1100( + __action1131( + source_code, mode, __0, __1, @@ -54604,8 +59263,9 @@ fn __action1112< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1113< +fn __action1144< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -54613,13 +59273,15 @@ fn __action1113< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action374( + let __temp0 = __action395( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action372( + __action393( + source_code, mode, __temp0, ) @@ -54627,8 +59289,9 @@ fn __action1113< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1114< +fn __action1145< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -54639,13 +59302,15 @@ fn __action1114< { let __start0 = __2.0; let __end0 = __3.2; - let __temp0 = __action1113( + let __temp0 = __action1144( + source_code, mode, __2, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action888( + __action918( + source_code, mode, __0, __1, @@ -54656,8 +59321,9 @@ fn __action1114< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1115< +fn __action1146< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -54666,13 +59332,15 @@ fn __action1115< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action373( + let __temp0 = __action394( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action888( + __action918( + source_code, mode, __0, __1, @@ -54683,8 +59351,9 @@ fn __action1115< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1116< +fn __action1147< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -54694,7 +59363,8 @@ fn __action1116< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action695( + let __temp0 = __action720( + source_code, mode, __0, __1, @@ -54702,7 +59372,8 @@ fn __action1116< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action409( + __action430( + source_code, mode, __temp0, ) @@ -54710,8 +59381,9 @@ fn __action1116< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1117< +fn __action1148< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec<(TextSize, ast::ParenthesizedExpr, ast::Suite)>, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -54722,7 +59394,8 @@ fn __action1117< { let __start0 = __1.0; let __end0 = __4.2; - let __temp0 = __action695( + let __temp0 = __action720( + source_code, mode, __1, __2, @@ -54730,7 +59403,8 @@ fn __action1117< __4, ); let __temp0 = (__start0, __temp0, __end0); - __action410( + __action431( + source_code, mode, __0, __temp0, @@ -54739,8 +59413,9 @@ fn __action1117< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1118< +fn __action1149< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -54751,13 +59426,15 @@ fn __action1118< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action320( + let __temp0 = __action340( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action798( + __action828( + source_code, mode, __0, __1, @@ -54770,8 +59447,9 @@ fn __action1118< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1119< +fn __action1150< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -54783,12 +59461,14 @@ fn __action1119< { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action321( + let __temp0 = __action341( + source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action798( + __action828( + source_code, mode, __0, __1, @@ -54801,8 +59481,9 @@ fn __action1119< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1120< +fn __action1151< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -54811,14 +59492,16 @@ fn __action1120< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action696( + let __temp0 = __action721( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action317( + __action337( + source_code, mode, __temp0, ) @@ -54826,8 +59509,9 @@ fn __action1120< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1121< +fn __action1152< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -54840,14 +59524,16 @@ fn __action1121< { let __start0 = __4.0; let __end0 = __6.2; - let __temp0 = __action1120( + let __temp0 = __action1151( + source_code, mode, __4, __5, __6, ); let __temp0 = (__start0, __temp0, __end0); - __action1118( + __action1149( + source_code, mode, __0, __1, @@ -54859,8 +59545,9 @@ fn __action1121< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1122< +fn __action1153< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -54870,13 +59557,15 @@ fn __action1122< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action318( + let __temp0 = __action338( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1118( + __action1149( + source_code, mode, __0, __1, @@ -54888,8 +59577,9 @@ fn __action1122< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1123< +fn __action1154< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -54903,14 +59593,16 @@ fn __action1123< { let __start0 = __5.0; let __end0 = __7.2; - let __temp0 = __action1120( + let __temp0 = __action1151( + source_code, mode, __5, __6, __7, ); let __temp0 = (__start0, __temp0, __end0); - __action1119( + __action1150( + source_code, mode, __0, __1, @@ -54923,8 +59615,9 @@ fn __action1123< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1124< +fn __action1155< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -54935,13 +59628,15 @@ fn __action1124< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action318( + let __temp0 = __action338( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1119( + __action1150( + source_code, mode, __0, __1, @@ -54954,8 +59649,9 @@ fn __action1124< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1125< +fn __action1156< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -54963,13 +59659,15 @@ fn __action1125< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action436( + let __temp0 = __action459( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action434( + __action457( + source_code, mode, __temp0, ) @@ -54977,8 +59675,9 @@ fn __action1125< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1126< +fn __action1157< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -54987,13 +59686,15 @@ fn __action1126< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action436( + let __temp0 = __action459( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action435( + __action458( + source_code, mode, __0, __temp0, @@ -55002,8 +59703,9 @@ fn __action1126< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1127< +fn __action1158< >( + source_code: &str, mode: Mode, __0: (TextSize, (Option<(TextSize, TextSize, Option)>, ast::Expr), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -55011,13 +59713,15 @@ fn __action1127< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action445( + let __temp0 = __action468( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action446( + __action469( + source_code, mode, __temp0, ) @@ -55025,8 +59729,9 @@ fn __action1127< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1128< +fn __action1159< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize), __1: (TextSize, (Option<(TextSize, TextSize, Option)>, ast::Expr), TextSize), @@ -55035,13 +59740,15 @@ fn __action1128< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action445( + let __temp0 = __action468( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action447( + __action470( + source_code, mode, __0, __temp0, @@ -55050,21 +59757,24 @@ fn __action1128< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1129< +fn __action1160< >( + source_code: &str, mode: Mode, __0: (TextSize, core::option::Option<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize), ) -> Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)> { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action443( + let __temp0 = __action466( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action239( + __action249( + source_code, mode, __temp0, __0, @@ -55073,8 +59783,9 @@ fn __action1129< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1130< +fn __action1161< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize), __1: (TextSize, core::option::Option<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize), @@ -55082,12 +59793,14 @@ fn __action1130< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action444( + let __temp0 = __action467( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action239( + __action249( + source_code, mode, __temp0, __1, @@ -55096,8 +59809,9 @@ fn __action1130< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1131< +fn __action1162< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -55105,13 +59819,15 @@ fn __action1131< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action450( + let __temp0 = __action473( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action448( + __action471( + source_code, mode, __temp0, ) @@ -55119,8 +59835,9 @@ fn __action1131< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1132< +fn __action1163< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -55129,13 +59846,15 @@ fn __action1132< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action450( + let __temp0 = __action473( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action449( + __action472( + source_code, mode, __0, __temp0, @@ -55144,8 +59863,9 @@ fn __action1132< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1133< +fn __action1164< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -55153,13 +59873,15 @@ fn __action1133< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action548( + let __temp0 = __action571( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action546( + __action569( + source_code, mode, __temp0, ) @@ -55167,8 +59889,9 @@ fn __action1133< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1134< +fn __action1165< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -55181,13 +59904,15 @@ fn __action1134< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1133( + let __temp0 = __action1164( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1050( + __action1081( + source_code, mode, __0, __temp0, @@ -55200,8 +59925,9 @@ fn __action1134< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1135< +fn __action1166< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -55212,13 +59938,15 @@ fn __action1135< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action547( + let __temp0 = __action570( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1050( + __action1081( + source_code, mode, __0, __temp0, @@ -55231,8 +59959,9 @@ fn __action1135< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1136< +fn __action1167< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -55246,13 +59975,15 @@ fn __action1136< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1133( + let __temp0 = __action1164( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1051( + __action1082( + source_code, mode, __0, __temp0, @@ -55266,8 +59997,9 @@ fn __action1136< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1137< +fn __action1168< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -55279,13 +60011,15 @@ fn __action1137< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action547( + let __temp0 = __action570( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1051( + __action1082( + source_code, mode, __0, __temp0, @@ -55299,8 +60033,9 @@ fn __action1137< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1138< +fn __action1169< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -55312,13 +60047,15 @@ fn __action1138< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1133( + let __temp0 = __action1164( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1052( + __action1083( + source_code, mode, __0, __temp0, @@ -55330,8 +60067,9 @@ fn __action1138< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1139< +fn __action1170< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -55341,13 +60079,15 @@ fn __action1139< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action547( + let __temp0 = __action570( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1052( + __action1083( + source_code, mode, __0, __temp0, @@ -55359,8 +60099,9 @@ fn __action1139< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1140< +fn __action1171< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -55373,13 +60114,15 @@ fn __action1140< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1133( + let __temp0 = __action1164( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1053( + __action1084( + source_code, mode, __0, __temp0, @@ -55392,8 +60135,9 @@ fn __action1140< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1141< +fn __action1172< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -55404,13 +60148,15 @@ fn __action1141< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action547( + let __temp0 = __action570( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1053( + __action1084( + source_code, mode, __0, __temp0, @@ -55423,8 +60169,9 @@ fn __action1141< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1142< +fn __action1173< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -55437,13 +60184,15 @@ fn __action1142< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1133( + let __temp0 = __action1164( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1054( + __action1085( + source_code, mode, __0, __temp0, @@ -55456,8 +60205,9 @@ fn __action1142< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1143< +fn __action1174< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -55468,13 +60218,15 @@ fn __action1143< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action547( + let __temp0 = __action570( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1054( + __action1085( + source_code, mode, __0, __temp0, @@ -55487,8 +60239,9 @@ fn __action1143< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1144< +fn __action1175< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -55502,13 +60255,15 @@ fn __action1144< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1133( + let __temp0 = __action1164( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1055( + __action1086( + source_code, mode, __0, __temp0, @@ -55522,8 +60277,9 @@ fn __action1144< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1145< +fn __action1176< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -55535,13 +60291,15 @@ fn __action1145< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action547( + let __temp0 = __action570( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1055( + __action1086( + source_code, mode, __0, __temp0, @@ -55555,8 +60313,9 @@ fn __action1145< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1146< +fn __action1177< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -55568,13 +60327,15 @@ fn __action1146< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1133( + let __temp0 = __action1164( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1056( + __action1087( + source_code, mode, __0, __temp0, @@ -55586,8 +60347,9 @@ fn __action1146< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1147< +fn __action1178< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -55597,13 +60359,15 @@ fn __action1147< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action547( + let __temp0 = __action570( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1056( + __action1087( + source_code, mode, __0, __temp0, @@ -55615,8 +60379,9 @@ fn __action1147< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1148< +fn __action1179< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -55629,13 +60394,15 @@ fn __action1148< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1133( + let __temp0 = __action1164( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1057( + __action1088( + source_code, mode, __0, __temp0, @@ -55648,8 +60415,9 @@ fn __action1148< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1149< +fn __action1180< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -55660,13 +60428,15 @@ fn __action1149< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action547( + let __temp0 = __action570( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1057( + __action1088( + source_code, mode, __0, __temp0, @@ -55679,8 +60449,9 @@ fn __action1149< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1150< +fn __action1181< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Pattern, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -55688,13 +60459,15 @@ fn __action1150< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action335( + let __temp0 = __action356( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action333( + __action354( + source_code, mode, __temp0, ) @@ -55702,8 +60475,9 @@ fn __action1150< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1151< +fn __action1182< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::Pattern, TextSize), @@ -55712,13 +60486,15 @@ fn __action1151< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action335( + let __temp0 = __action356( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action334( + __action355( + source_code, mode, __0, __temp0, @@ -55727,21 +60503,24 @@ fn __action1151< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1152< +fn __action1183< >( + source_code: &str, mode: Mode, __0: (TextSize, core::option::Option, TextSize), ) -> Vec { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action407( + let __temp0 = __action428( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action332( + __action353( + source_code, mode, __temp0, __0, @@ -55750,8 +60529,9 @@ fn __action1152< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1153< +fn __action1184< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -55759,12 +60539,14 @@ fn __action1153< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action408( + let __temp0 = __action429( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action332( + __action353( + source_code, mode, __temp0, __1, @@ -55773,8 +60555,9 @@ fn __action1153< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1154< +fn __action1185< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Stmt, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -55782,13 +60565,15 @@ fn __action1154< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action388( + let __temp0 = __action409( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action396( + __action417( + source_code, mode, __temp0, ) @@ -55796,8 +60581,9 @@ fn __action1154< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1155< +fn __action1186< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::Stmt, TextSize), @@ -55806,13 +60592,15 @@ fn __action1155< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action388( + let __temp0 = __action409( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action397( + __action418( + source_code, mode, __0, __temp0, @@ -55821,8 +60609,9 @@ fn __action1155< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1156< +fn __action1187< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Suite, TextSize), __1: (TextSize, ast::Stmt, TextSize), @@ -55832,13 +60621,15 @@ fn __action1156< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action386( + let __temp0 = __action407( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action645( + __action668( + source_code, mode, __0, __temp0, @@ -55850,8 +60641,9 @@ fn __action1156< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1157< +fn __action1188< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Suite, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -55862,12 +60654,14 @@ fn __action1157< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action387( + let __temp0 = __action408( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action645( + __action668( + source_code, mode, __0, __temp0, @@ -55879,8 +60673,9 @@ fn __action1157< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1158< +fn __action1189< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Suite, TextSize), __1: (TextSize, ast::Stmt, TextSize), @@ -55889,13 +60684,15 @@ fn __action1158< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action386( + let __temp0 = __action407( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action646( + __action669( + source_code, mode, __0, __temp0, @@ -55906,8 +60703,9 @@ fn __action1158< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1159< +fn __action1190< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Suite, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -55917,12 +60715,14 @@ fn __action1159< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action387( + let __temp0 = __action408( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action646( + __action669( + source_code, mode, __0, __temp0, @@ -55933,8 +60733,9 @@ fn __action1159< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1160< +fn __action1191< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Stmt, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -55943,13 +60744,15 @@ fn __action1160< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action386( + let __temp0 = __action407( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action647( + __action670( + source_code, mode, __temp0, __0, @@ -55960,8 +60763,9 @@ fn __action1160< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1161< +fn __action1192< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::Stmt, TextSize), @@ -55971,12 +60775,14 @@ fn __action1161< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action387( + let __temp0 = __action408( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action647( + __action670( + source_code, mode, __temp0, __1, @@ -55987,8 +60793,9 @@ fn __action1161< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1162< +fn __action1193< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Stmt, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -55996,13 +60803,15 @@ fn __action1162< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action386( + let __temp0 = __action407( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action648( + __action671( + source_code, mode, __temp0, __0, @@ -56012,8 +60821,9 @@ fn __action1162< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1163< +fn __action1194< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::Stmt, TextSize), @@ -56022,12 +60832,14 @@ fn __action1163< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action387( + let __temp0 = __action408( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action648( + __action671( + source_code, mode, __temp0, __1, @@ -56037,8 +60849,9 @@ fn __action1163< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1164< +fn __action1195< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, ast::Stmt, TextSize), @@ -56048,13 +60861,15 @@ fn __action1164< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action386( + let __temp0 = __action407( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action649( + __action672( + source_code, mode, __0, __temp0, @@ -56066,8 +60881,9 @@ fn __action1164< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1165< +fn __action1196< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -56078,12 +60894,14 @@ fn __action1165< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action387( + let __temp0 = __action408( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action649( + __action672( + source_code, mode, __0, __temp0, @@ -56095,8 +60913,9 @@ fn __action1165< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1166< +fn __action1197< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, ast::Stmt, TextSize), @@ -56105,13 +60924,15 @@ fn __action1166< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action386( + let __temp0 = __action407( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action650( + __action673( + source_code, mode, __0, __temp0, @@ -56122,8 +60943,9 @@ fn __action1166< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1167< +fn __action1198< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -56133,12 +60955,14 @@ fn __action1167< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action387( + let __temp0 = __action408( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action650( + __action673( + source_code, mode, __0, __temp0, @@ -56149,8 +60973,9 @@ fn __action1167< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1168< +fn __action1199< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Stmt, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -56159,13 +60984,15 @@ fn __action1168< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action386( + let __temp0 = __action407( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action651( + __action674( + source_code, mode, __temp0, __0, @@ -56176,8 +61003,9 @@ fn __action1168< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1169< +fn __action1200< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::Stmt, TextSize), @@ -56187,12 +61015,14 @@ fn __action1169< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action387( + let __temp0 = __action408( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action651( + __action674( + source_code, mode, __temp0, __1, @@ -56203,8 +61033,9 @@ fn __action1169< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1170< +fn __action1201< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Stmt, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -56212,13 +61043,15 @@ fn __action1170< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action386( + let __temp0 = __action407( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action652( + __action675( + source_code, mode, __temp0, __0, @@ -56228,8 +61061,9 @@ fn __action1170< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1171< +fn __action1202< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::Stmt, TextSize), @@ -56238,12 +61072,14 @@ fn __action1171< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action387( + let __temp0 = __action408( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action652( + __action675( + source_code, mode, __temp0, __1, @@ -56253,8 +61089,9 @@ fn __action1171< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1172< +fn __action1203< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -56266,14 +61103,16 @@ fn __action1172< { let __start0 = __1.0; let __end0 = __3.2; - let __temp0 = __action304( + let __temp0 = __action324( + source_code, mode, __1, __2, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action770( + __action794( + source_code, mode, __0, __temp0, @@ -56284,8 +61123,9 @@ fn __action1172< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1173< +fn __action1204< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -56298,14 +61138,16 @@ fn __action1173< { let __start0 = __2.0; let __end0 = __4.2; - let __temp0 = __action304( + let __temp0 = __action324( + source_code, mode, __2, __3, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action772( + __action796( + source_code, mode, __0, __1, @@ -56317,8 +61159,9 @@ fn __action1173< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1174< +fn __action1205< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -56327,11 +61170,13 @@ fn __action1174< let __start0 = __0.0; let __end0 = __0.2; let __temp0 = __action160( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action301( + __action321( + source_code, mode, __temp0, __1, @@ -56340,8 +61185,9 @@ fn __action1174< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1175< +fn __action1206< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -56352,11 +61198,13 @@ fn __action1175< let __start0 = __1.0; let __end0 = __1.2; let __temp0 = __action160( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action641( + __action664( + source_code, mode, __0, __temp0, @@ -56367,8 +61215,9 @@ fn __action1175< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1176< +fn __action1207< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -56378,11 +61227,13 @@ fn __action1176< let __start0 = __1.0; let __end0 = __1.2; let __temp0 = __action160( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action642( + __action665( + source_code, mode, __0, __temp0, @@ -56392,8 +61243,9 @@ fn __action1176< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1177< +fn __action1208< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -56401,13 +61253,15 @@ fn __action1177< { let __start0 = __0.0; let __end0 = __1.2; - let __temp0 = __action1174( + let __temp0 = __action1205( + source_code, mode, __0, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action299( + __action319( + source_code, mode, __temp0, ) @@ -56415,8 +61269,9 @@ fn __action1177< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1178< +fn __action1209< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -56428,13 +61283,15 @@ fn __action1178< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1177( + let __temp0 = __action1208( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1060( + __action1091( + source_code, mode, __0, __temp0, @@ -56446,8 +61303,9 @@ fn __action1178< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1179< +fn __action1210< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::WithItem, TextSize), @@ -56457,13 +61315,15 @@ fn __action1179< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action300( + let __temp0 = __action320( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1060( + __action1091( + source_code, mode, __0, __temp0, @@ -56475,8 +61335,9 @@ fn __action1179< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1180< +fn __action1211< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -56489,13 +61350,15 @@ fn __action1180< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1177( + let __temp0 = __action1208( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1061( + __action1092( + source_code, mode, __0, __temp0, @@ -56508,8 +61371,9 @@ fn __action1180< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1181< +fn __action1212< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::WithItem, TextSize), @@ -56520,13 +61384,15 @@ fn __action1181< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action300( + let __temp0 = __action320( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1061( + __action1092( + source_code, mode, __0, __temp0, @@ -56539,8 +61405,9 @@ fn __action1181< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1182< +fn __action1213< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -56551,13 +61418,15 @@ fn __action1182< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1177( + let __temp0 = __action1208( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1062( + __action1093( + source_code, mode, __0, __temp0, @@ -56568,8 +61437,9 @@ fn __action1182< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1183< +fn __action1214< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::WithItem, TextSize), @@ -56578,13 +61448,15 @@ fn __action1183< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action300( + let __temp0 = __action320( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1062( + __action1093( + source_code, mode, __0, __temp0, @@ -56595,8 +61467,9 @@ fn __action1183< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1184< +fn __action1215< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -56608,13 +61481,15 @@ fn __action1184< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1177( + let __temp0 = __action1208( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1063( + __action1094( + source_code, mode, __0, __temp0, @@ -56626,8 +61501,9 @@ fn __action1184< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1185< +fn __action1216< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::WithItem, TextSize), @@ -56637,13 +61513,15 @@ fn __action1185< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action300( + let __temp0 = __action320( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1063( + __action1094( + source_code, mode, __0, __temp0, @@ -56655,31 +61533,235 @@ fn __action1185< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1186< +fn __action1217< >( + source_code: &str, mode: Mode, - __0: (TextSize, (String, StringKind, bool), TextSize), -) -> (TextSize, (String, StringKind, bool), TextSize) + __0: (TextSize, ast::CmpOp, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), +) -> alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)> { - let __start0 = __0.2; + let __start0 = __0.0; + let __end0 = __1.2; + let __temp0 = __action516( + source_code, + mode, + __0, + __1, + ); + let __temp0 = (__start0, __temp0, __end0); + __action514( + source_code, + mode, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1218< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize), + __1: (TextSize, ast::CmpOp, TextSize), + __2: (TextSize, ast::ParenthesizedExpr, TextSize), +) -> alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)> +{ + let __start0 = __1.0; + let __end0 = __2.2; + let __temp0 = __action516( + source_code, + mode, + __1, + __2, + ); + let __temp0 = (__start0, __temp0, __end0); + __action515( + source_code, + mode, + __0, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1219< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, ast::Expr, TextSize), +) -> core::option::Option +{ + let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action363( + source_code, + mode, + __0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action361( + source_code, + mode, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1220< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::Pattern, TextSize), + __2: (TextSize, ast::Expr, TextSize), + __3: (TextSize, token::Tok, TextSize), + __4: (TextSize, ast::Suite, TextSize), +) -> ast::MatchCase +{ + let __start0 = __2.0; + let __end0 = __2.2; + let __temp0 = __action1219( + source_code, + mode, + __2, + ); + let __temp0 = (__start0, __temp0, __end0); + __action858( + source_code, + mode, + __0, + __1, + __temp0, + __3, + __4, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1221< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::Pattern, TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, ast::Suite, TextSize), +) -> ast::MatchCase +{ + let __start0 = __1.2; + let __end0 = __2.0; + let __temp0 = __action362( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action697( + __action858( + source_code, mode, __0, + __1, __temp0, + __2, + __3, ) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1187< +fn __action1222< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, ast::Parameters, TextSize), +) -> core::option::Option +{ + let __start0 = __0.0; + let __end0 = __0.2; + let __temp0 = __action296( + source_code, + mode, + __0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action294( + source_code, + mode, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1223< >( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::Parameters, TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, TextSize, TextSize), +) -> Result> +{ + let __start0 = __1.0; + let __end0 = __1.2; + let __temp0 = __action1222( + source_code, + mode, + __1, + ); + let __temp0 = (__start0, __temp0, __end0); + __action903( + source_code, + mode, + __0, + __temp0, + __2, + __3, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1224< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, token::Tok, TextSize), + __2: (TextSize, TextSize, TextSize), +) -> Result> +{ + let __start0 = __0.2; + let __end0 = __1.0; + let __temp0 = __action295( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action903( + source_code, + mode, + __0, + __temp0, + __1, + __2, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1225< +>( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), @@ -56688,13 +61770,15 @@ fn __action1187< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action698( + __action722( + source_code, mode, __0, __1, @@ -56705,8 +61789,9 @@ fn __action1187< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1188< +fn __action1226< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -56715,13 +61800,15 @@ fn __action1188< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action699( + __action723( + source_code, mode, __0, __1, @@ -56732,8 +61819,9 @@ fn __action1188< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1189< +fn __action1227< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -56742,13 +61830,15 @@ fn __action1189< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action700( + __action724( + source_code, mode, __0, __1, @@ -56759,8 +61849,9 @@ fn __action1189< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1190< +fn __action1228< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -56768,13 +61859,15 @@ fn __action1190< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action701( + __action725( + source_code, mode, __0, __1, @@ -56784,8 +61877,9 @@ fn __action1190< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1191< +fn __action1229< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -56793,13 +61887,15 @@ fn __action1191< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action702( + __action726( + source_code, mode, __0, __1, @@ -56809,8 +61905,9 @@ fn __action1191< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1192< +fn __action1230< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize), @@ -56819,13 +61916,15 @@ fn __action1192< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action703( + __action727( + source_code, mode, __0, __1, @@ -56836,8 +61935,9 @@ fn __action1192< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1193< +fn __action1231< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), @@ -56846,13 +61946,15 @@ fn __action1193< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action704( + __action728( + source_code, mode, __0, __1, @@ -56863,8 +61965,9 @@ fn __action1193< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1194< +fn __action1232< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), @@ -56873,13 +61976,15 @@ fn __action1194< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action705( + __action729( + source_code, mode, __0, __1, @@ -56890,8 +61995,9 @@ fn __action1194< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1195< +fn __action1233< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Pattern, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -56900,13 +62006,15 @@ fn __action1195< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action706( + __action730( + source_code, mode, __0, __1, @@ -56917,8 +62025,9 @@ fn __action1195< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1196< +fn __action1234< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -56928,13 +62037,15 @@ fn __action1196< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1046( + __action1077( + source_code, mode, __0, __1, @@ -56946,8 +62057,9 @@ fn __action1196< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1197< +fn __action1235< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -56955,13 +62067,15 @@ fn __action1197< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1047( + __action1078( + source_code, mode, __0, __1, @@ -56971,21 +62085,50 @@ fn __action1197< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1198< +fn __action1236< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, alloc::vec::Vec, TextSize), +) -> Result> +{ + let __start0 = __0.2; + let __end0 = __0.2; + let __temp0 = __action413( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action732( + source_code, + mode, + __0, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1237< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Constant, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action709( + __action733( + source_code, mode, __0, __temp0, @@ -56994,21 +62137,24 @@ fn __action1198< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1199< +fn __action1238< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action710( + __action734( + source_code, mode, __0, __temp0, @@ -57017,8 +62163,9 @@ fn __action1199< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1200< +fn __action1239< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -57027,13 +62174,15 @@ fn __action1200< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action711( + __action735( + source_code, mode, __0, __1, @@ -57044,8 +62193,9 @@ fn __action1200< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1201< +fn __action1240< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -57055,13 +62205,15 @@ fn __action1201< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action712( + __action736( + source_code, mode, __0, __1, @@ -57073,8 +62225,9 @@ fn __action1201< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1202< +fn __action1241< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -57084,13 +62237,15 @@ fn __action1202< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action713( + __action737( + source_code, mode, __0, __1, @@ -57102,8 +62257,9 @@ fn __action1202< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1203< +fn __action1242< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -57112,13 +62268,15 @@ fn __action1203< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action714( + __action738( + source_code, mode, __0, __1, @@ -57129,8 +62287,9 @@ fn __action1203< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1204< +fn __action1243< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -57142,13 +62301,15 @@ fn __action1204< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1134( + __action1165( + source_code, mode, __0, __1, @@ -57162,8 +62323,9 @@ fn __action1204< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1205< +fn __action1244< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -57173,13 +62335,15 @@ fn __action1205< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1135( + __action1166( + source_code, mode, __0, __1, @@ -57191,8 +62355,9 @@ fn __action1205< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1206< +fn __action1245< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -57205,13 +62370,15 @@ fn __action1206< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1136( + __action1167( + source_code, mode, __0, __1, @@ -57226,8 +62393,9 @@ fn __action1206< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1207< +fn __action1246< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -57238,13 +62406,15 @@ fn __action1207< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1137( + __action1168( + source_code, mode, __0, __1, @@ -57257,8 +62427,9 @@ fn __action1207< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1208< +fn __action1247< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -57269,13 +62440,15 @@ fn __action1208< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1138( + __action1169( + source_code, mode, __0, __1, @@ -57288,8 +62461,9 @@ fn __action1208< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1209< +fn __action1248< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -57298,13 +62472,15 @@ fn __action1209< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1139( + __action1170( + source_code, mode, __0, __1, @@ -57315,8 +62491,9 @@ fn __action1209< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1210< +fn __action1249< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -57328,13 +62505,15 @@ fn __action1210< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1140( + __action1171( + source_code, mode, __0, __1, @@ -57348,8 +62527,9 @@ fn __action1210< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1211< +fn __action1250< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -57359,13 +62539,15 @@ fn __action1211< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1141( + __action1172( + source_code, mode, __0, __1, @@ -57377,8 +62559,9 @@ fn __action1211< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1212< +fn __action1251< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -57386,13 +62569,15 @@ fn __action1212< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action717( + __action741( + source_code, mode, __0, __1, @@ -57402,8 +62587,9 @@ fn __action1212< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1213< +fn __action1252< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -57412,13 +62598,15 @@ fn __action1213< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action718( + __action742( + source_code, mode, __0, __1, @@ -57429,8 +62617,9 @@ fn __action1213< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1214< +fn __action1253< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -57440,13 +62629,15 @@ fn __action1214< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action719( + __action743( + source_code, mode, __0, __1, @@ -57458,8 +62649,9 @@ fn __action1214< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1215< +fn __action1254< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -57469,13 +62661,15 @@ fn __action1215< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action720( + __action744( + source_code, mode, __0, __1, @@ -57487,8 +62681,9 @@ fn __action1215< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1216< +fn __action1255< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, ast::ParenthesizedExpr)>>, TextSize), @@ -57497,13 +62692,15 @@ fn __action1216< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action721( + __action745( + source_code, mode, __0, __1, @@ -57514,8 +62711,9 @@ fn __action1216< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1217< +fn __action1256< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, (ast::ParenthesizedExpr, ast::ParenthesizedExpr), TextSize), @@ -57525,13 +62723,15 @@ fn __action1217< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action722( + __action746( + source_code, mode, __0, __1, @@ -57543,8 +62743,9 @@ fn __action1217< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1218< +fn __action1257< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -57553,13 +62754,15 @@ fn __action1218< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action723( + __action747( + source_code, mode, __0, __1, @@ -57570,8 +62773,9 @@ fn __action1218< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1219< +fn __action1258< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -57581,13 +62785,15 @@ fn __action1219< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action724( + __action748( + source_code, mode, __0, __1, @@ -57599,21 +62805,24 @@ fn __action1219< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1220< +fn __action1259< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action725( + __action749( + source_code, mode, __0, __temp0, @@ -57622,21 +62831,24 @@ fn __action1220< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1221< +fn __action1260< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action726( + __action750( + source_code, mode, __0, __temp0, @@ -57645,21 +62857,24 @@ fn __action1221< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1222< +fn __action1261< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action727( + __action751( + source_code, mode, __0, __temp0, @@ -57668,21 +62883,24 @@ fn __action1222< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1223< +fn __action1262< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action728( + __action752( + source_code, mode, __0, __temp0, @@ -57691,21 +62909,50 @@ fn __action1223< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1224< +fn __action1263< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, alloc::vec::Vec, TextSize), +) -> Result> +{ + let __start0 = __0.2; + let __end0 = __0.2; + let __temp0 = __action413( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action753( + source_code, + mode, + __0, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1264< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Constant, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action730( + __action754( + source_code, mode, __0, __temp0, @@ -57714,21 +62961,24 @@ fn __action1224< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1225< +fn __action1265< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action731( + __action755( + source_code, mode, __0, __temp0, @@ -57737,8 +62987,9 @@ fn __action1225< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1226< +fn __action1266< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -57747,13 +62998,15 @@ fn __action1226< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action732( + __action756( + source_code, mode, __0, __1, @@ -57764,8 +63017,9 @@ fn __action1226< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1227< +fn __action1267< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -57775,13 +63029,15 @@ fn __action1227< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action733( + __action757( + source_code, mode, __0, __1, @@ -57793,8 +63049,9 @@ fn __action1227< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1228< +fn __action1268< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -57806,13 +63063,15 @@ fn __action1228< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1142( + __action1173( + source_code, mode, __0, __1, @@ -57826,8 +63085,9 @@ fn __action1228< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1229< +fn __action1269< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -57837,13 +63097,15 @@ fn __action1229< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1143( + __action1174( + source_code, mode, __0, __1, @@ -57855,8 +63117,9 @@ fn __action1229< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1230< +fn __action1270< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -57869,13 +63132,15 @@ fn __action1230< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1144( + __action1175( + source_code, mode, __0, __1, @@ -57890,8 +63155,9 @@ fn __action1230< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1231< +fn __action1271< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -57902,13 +63168,15 @@ fn __action1231< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1145( + __action1176( + source_code, mode, __0, __1, @@ -57921,8 +63189,9 @@ fn __action1231< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1232< +fn __action1272< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -57933,13 +63202,15 @@ fn __action1232< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1146( + __action1177( + source_code, mode, __0, __1, @@ -57952,8 +63223,9 @@ fn __action1232< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1233< +fn __action1273< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -57962,13 +63234,15 @@ fn __action1233< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1147( + __action1178( + source_code, mode, __0, __1, @@ -57979,8 +63253,9 @@ fn __action1233< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1234< +fn __action1274< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -57992,13 +63267,15 @@ fn __action1234< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1148( + __action1179( + source_code, mode, __0, __1, @@ -58012,8 +63289,9 @@ fn __action1234< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1235< +fn __action1275< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -58023,13 +63301,15 @@ fn __action1235< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1149( + __action1180( + source_code, mode, __0, __1, @@ -58041,8 +63321,9 @@ fn __action1235< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1236< +fn __action1276< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -58050,13 +63331,15 @@ fn __action1236< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action736( + __action760( + source_code, mode, __0, __1, @@ -58066,8 +63349,9 @@ fn __action1236< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1237< +fn __action1277< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -58076,13 +63360,15 @@ fn __action1237< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action737( + __action761( + source_code, mode, __0, __1, @@ -58093,8 +63379,9 @@ fn __action1237< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1238< +fn __action1278< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -58104,13 +63391,15 @@ fn __action1238< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action738( + __action762( + source_code, mode, __0, __1, @@ -58122,8 +63411,9 @@ fn __action1238< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1239< +fn __action1279< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -58133,13 +63423,15 @@ fn __action1239< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action739( + __action763( + source_code, mode, __0, __1, @@ -58151,8 +63443,9 @@ fn __action1239< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1240< +fn __action1280< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option>, ast::ParenthesizedExpr)>>, TextSize), @@ -58161,13 +63454,15 @@ fn __action1240< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action740( + __action764( + source_code, mode, __0, __1, @@ -58178,8 +63473,9 @@ fn __action1240< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1241< +fn __action1281< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, (ast::ParenthesizedExpr, ast::ParenthesizedExpr), TextSize), @@ -58189,13 +63485,15 @@ fn __action1241< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action741( + __action765( + source_code, mode, __0, __1, @@ -58207,8 +63505,9 @@ fn __action1241< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1242< +fn __action1282< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -58217,13 +63516,15 @@ fn __action1242< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action742( + __action766( + source_code, mode, __0, __1, @@ -58234,8 +63535,9 @@ fn __action1242< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1243< +fn __action1283< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -58245,13 +63547,15 @@ fn __action1243< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action743( + __action767( + source_code, mode, __0, __1, @@ -58263,21 +63567,24 @@ fn __action1243< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1244< +fn __action1284< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action744( + __action768( + source_code, mode, __0, __temp0, @@ -58286,21 +63593,24 @@ fn __action1244< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1245< +fn __action1285< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action745( + __action769( + source_code, mode, __0, __temp0, @@ -58309,21 +63619,24 @@ fn __action1245< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1246< +fn __action1286< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action746( + __action770( + source_code, mode, __0, __temp0, @@ -58332,21 +63645,24 @@ fn __action1246< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1247< +fn __action1287< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action747( + __action771( + source_code, mode, __0, __temp0, @@ -58355,8 +63671,9 @@ fn __action1247< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1248< +fn __action1288< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Arguments, TextSize), @@ -58364,13 +63681,15 @@ fn __action1248< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action748( + __action772( + source_code, mode, __0, __1, @@ -58380,8 +63699,9 @@ fn __action1248< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1249< +fn __action1289< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -58391,13 +63711,15 @@ fn __action1249< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action749( + __action773( + source_code, mode, __0, __1, @@ -58409,8 +63731,9 @@ fn __action1249< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1250< +fn __action1290< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -58419,13 +63742,15 @@ fn __action1250< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action750( + __action774( + source_code, mode, __0, __1, @@ -58436,8 +63761,9 @@ fn __action1250< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1251< +fn __action1291< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Arguments, TextSize), @@ -58445,13 +63771,15 @@ fn __action1251< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action751( + __action775( + source_code, mode, __0, __1, @@ -58461,8 +63789,9 @@ fn __action1251< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1252< +fn __action1292< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -58472,13 +63801,15 @@ fn __action1252< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action752( + __action776( + source_code, mode, __0, __1, @@ -58490,8 +63821,9 @@ fn __action1252< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1253< +fn __action1293< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -58500,13 +63832,15 @@ fn __action1253< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action753( + __action777( + source_code, mode, __0, __1, @@ -58517,8 +63851,9 @@ fn __action1253< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1254< +fn __action1294< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -58526,13 +63861,15 @@ fn __action1254< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action754( + __action778( + source_code, mode, __0, __1, @@ -58542,8 +63879,9 @@ fn __action1254< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1255< +fn __action1295< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -58551,13 +63889,15 @@ fn __action1255< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action755( + __action779( + source_code, mode, __0, __1, @@ -58567,21 +63907,24 @@ fn __action1255< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1256< +fn __action1296< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), ) -> ast::Pattern { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action756( + __action780( + source_code, mode, __0, __temp0, @@ -58590,8 +63933,9 @@ fn __action1256< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1257< +fn __action1297< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Expr, TextSize), __1: (TextSize, ast::PatternArguments, TextSize), @@ -58599,13 +63943,15 @@ fn __action1257< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action758( + __action782( + source_code, mode, __0, __1, @@ -58615,8 +63961,9 @@ fn __action1257< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1258< +fn __action1298< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Expr, TextSize), __1: (TextSize, ast::PatternArguments, TextSize), @@ -58624,13 +63971,15 @@ fn __action1258< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action759( + __action783( + source_code, mode, __0, __1, @@ -58640,8 +63989,9 @@ fn __action1258< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1259< +fn __action1299< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize), @@ -58649,13 +63999,15 @@ fn __action1259< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action760( + __action784( + source_code, mode, __0, __1, @@ -58665,8 +64017,9 @@ fn __action1259< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1260< +fn __action1300< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize), @@ -58674,13 +64027,15 @@ fn __action1260< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action761( + __action785( + source_code, mode, __0, __1, @@ -58690,21 +64045,24 @@ fn __action1260< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1261< +fn __action1301< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Constant, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action762( + __action786( + source_code, mode, __0, __temp0, @@ -58713,8 +64071,9 @@ fn __action1261< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1262< +fn __action1302< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -58722,13 +64081,15 @@ fn __action1262< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action763( + __action787( + source_code, mode, __0, __1, @@ -58738,8 +64099,9 @@ fn __action1262< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1263< +fn __action1303< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -58748,13 +64110,15 @@ fn __action1263< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action764( + __action788( + source_code, mode, __0, __1, @@ -58765,8 +64129,9 @@ fn __action1263< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1264< +fn __action1304< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -58774,13 +64139,15 @@ fn __action1264< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action765( + __action789( + source_code, mode, __0, __1, @@ -58790,21 +64157,24 @@ fn __action1264< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1265< +fn __action1305< >( + source_code: &str, mode: Mode, __0: (TextSize, String, TextSize), ) -> ast::Identifier { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action766( + __action790( + source_code, mode, __0, __temp0, @@ -58813,8 +64183,9 @@ fn __action1265< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1266< +fn __action1306< >( + source_code: &str, mode: Mode, __0: (TextSize, String, TextSize), __1: (TextSize, alloc::vec::Vec<(token::Tok, ast::Identifier)>, TextSize), @@ -58822,13 +64193,15 @@ fn __action1266< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action767( + __action791( + source_code, mode, __0, __1, @@ -58838,8 +64211,9 @@ fn __action1266< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1267< +fn __action1307< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -58848,13 +64222,15 @@ fn __action1267< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1072( + __action1103( + source_code, mode, __0, __1, @@ -58865,21 +64241,24 @@ fn __action1267< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1268< +fn __action1308< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), ) -> ast::Parameter { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1073( + __action1104( + source_code, mode, __0, __temp0, @@ -58888,8 +64267,9 @@ fn __action1268< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1269< +fn __action1309< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -58898,13 +64278,15 @@ fn __action1269< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action773( + __action797( + source_code, mode, __0, __1, @@ -58915,8 +64297,9 @@ fn __action1269< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1270< +fn __action1310< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -58925,13 +64308,15 @@ fn __action1270< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action774( + __action798( + source_code, mode, __0, __1, @@ -58942,8 +64327,9 @@ fn __action1270< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1271< +fn __action1311< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -58951,13 +64337,15 @@ fn __action1271< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action775( + __action799( + source_code, mode, __0, __1, @@ -58967,8 +64355,9 @@ fn __action1271< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1272< +fn __action1312< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), @@ -58977,13 +64366,15 @@ fn __action1272< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action776( + __action800( + source_code, mode, __0, __1, @@ -58994,8 +64385,9 @@ fn __action1272< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1273< +fn __action1313< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -59005,13 +64397,15 @@ fn __action1273< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action777( + __action801( + source_code, mode, __0, __1, @@ -59023,8 +64417,135 @@ fn __action1273< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1274< +fn __action1314< >( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, alloc::vec::Vec, TextSize), + __2: (TextSize, token::Tok, TextSize), +) -> StringType +{ + let __start0 = __2.2; + let __end0 = __2.2; + let __temp0 = __action413( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action803( + source_code, + mode, + __0, + __1, + __2, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1315< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, alloc::vec::Vec, TextSize), +) -> ast::Expr +{ + let __start0 = __0.2; + let __end0 = __0.2; + let __temp0 = __action413( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action804( + source_code, + mode, + __0, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1316< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, core::option::Option<(TextSize, ast::ConversionFlag)>, TextSize), + __4: (TextSize, core::option::Option, TextSize), + __5: (TextSize, token::Tok, TextSize), +) -> Result> +{ + let __start0 = __5.2; + let __end0 = __5.2; + let __temp0 = __action413( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action806( + source_code, + mode, + __0, + __1, + __2, + __3, + __4, + __5, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1317< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, core::option::Option<(TextSize, ast::ConversionFlag)>, TextSize), + __3: (TextSize, core::option::Option, TextSize), + __4: (TextSize, token::Tok, TextSize), +) -> Result> +{ + let __start0 = __4.2; + let __end0 = __4.2; + let __temp0 = __action413( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action807( + source_code, + mode, + __0, + __1, + __2, + __3, + __4, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1318< +>( + source_code: &str, mode: Mode, __0: (TextSize, ast::UnaryOp, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -59032,13 +64553,15 @@ fn __action1274< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action778( + __action808( + source_code, mode, __0, __1, @@ -59048,8 +64571,9 @@ fn __action1274< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1275< +fn __action1319< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::UnaryOp, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -59057,13 +64581,15 @@ fn __action1275< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action779( + __action809( + source_code, mode, __0, __1, @@ -59073,21 +64599,24 @@ fn __action1275< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1276< +fn __action1320< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::Stmt { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action780( + __action810( + source_code, mode, __0, __temp0, @@ -59096,21 +64625,24 @@ fn __action1276< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1277< +fn __action1321< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::Stmt { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action781( + __action811( + source_code, mode, __0, __temp0, @@ -59119,8 +64651,9 @@ fn __action1277< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1278< +fn __action1322< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -59128,13 +64661,15 @@ fn __action1278< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action782( + __action812( + source_code, mode, __0, __1, @@ -59144,21 +64679,24 @@ fn __action1278< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1279< +fn __action1323< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::Stmt { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action783( + __action813( + source_code, mode, __0, __temp0, @@ -59167,8 +64705,9 @@ fn __action1279< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1280< +fn __action1324< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, core::option::Option>, TextSize), @@ -59176,13 +64715,15 @@ fn __action1280< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action788( + __action818( + source_code, mode, __0, __1, @@ -59192,8 +64733,9 @@ fn __action1280< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1281< +fn __action1325< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -59202,13 +64744,15 @@ fn __action1281< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action789( + __action819( + source_code, mode, __0, __1, @@ -59219,8 +64763,9 @@ fn __action1281< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1282< +fn __action1326< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -59228,13 +64773,15 @@ fn __action1282< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action790( + __action820( + source_code, mode, __0, __1, @@ -59244,8 +64791,9 @@ fn __action1282< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1283< +fn __action1327< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -59253,13 +64801,15 @@ fn __action1283< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action791( + __action821( + source_code, mode, __0, __1, @@ -59269,8 +64819,9 @@ fn __action1283< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1284< +fn __action1328< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -59278,13 +64829,15 @@ fn __action1284< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action792( + __action822( + source_code, mode, __0, __1, @@ -59294,21 +64847,24 @@ fn __action1284< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1285< +fn __action1329< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action793( + __action823( + source_code, mode, __0, __temp0, @@ -59317,8 +64873,9 @@ fn __action1285< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1286< +fn __action1330< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -59326,13 +64883,15 @@ fn __action1286< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action794( + __action824( + source_code, mode, __0, __1, @@ -59342,21 +64901,24 @@ fn __action1286< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1287< +fn __action1331< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action795( + __action825( + source_code, mode, __0, __temp0, @@ -59365,8 +64927,9 @@ fn __action1287< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1288< +fn __action1332< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -59374,13 +64937,15 @@ fn __action1288< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action796( + __action826( + source_code, mode, __0, __1, @@ -59390,21 +64955,24 @@ fn __action1288< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1289< +fn __action1333< >( + source_code: &str, mode: Mode, __0: (TextSize, String, TextSize), ) -> ast::Identifier { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action797( + __action827( + source_code, mode, __0, __temp0, @@ -59413,8 +64981,9 @@ fn __action1289< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1290< +fn __action1334< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -59423,13 +64992,15 @@ fn __action1290< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1088( + __action1119( + source_code, mode, __0, __1, @@ -59440,21 +65011,24 @@ fn __action1290< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1291< +fn __action1335< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), ) -> ast::Alias { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1089( + __action1120( + source_code, mode, __0, __temp0, @@ -59463,8 +65037,9 @@ fn __action1291< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1292< +fn __action1336< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -59473,13 +65048,15 @@ fn __action1292< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1090( + __action1121( + source_code, mode, __0, __1, @@ -59490,21 +65067,24 @@ fn __action1292< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1293< +fn __action1337< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), ) -> ast::Alias { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1091( + __action1122( + source_code, mode, __0, __temp0, @@ -59513,21 +65093,24 @@ fn __action1293< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1294< +fn __action1338< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), ) -> Vec { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action801( + __action831( + source_code, mode, __0, __temp0, @@ -59536,8 +65119,9 @@ fn __action1294< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1295< +fn __action1339< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -59547,13 +65131,15 @@ fn __action1295< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action802( + __action832( + source_code, mode, __0, __1, @@ -59565,8 +65151,9 @@ fn __action1295< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1296< +fn __action1340< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -59575,13 +65162,15 @@ fn __action1296< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action803( + __action833( + source_code, mode, __0, __1, @@ -59592,21 +65181,24 @@ fn __action1296< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1297< +fn __action1341< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> Vec { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action804( + __action834( + source_code, mode, __0, __temp0, @@ -59615,8 +65207,9 @@ fn __action1297< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1298< +fn __action1342< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -59624,13 +65217,15 @@ fn __action1298< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action805( + __action835( + source_code, mode, __0, __1, @@ -59640,8 +65235,9 @@ fn __action1298< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1299< +fn __action1343< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, (Option, Option), TextSize), @@ -59651,13 +65247,15 @@ fn __action1299< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action806( + __action836( + source_code, mode, __0, __1, @@ -59669,21 +65267,24 @@ fn __action1299< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1300< +fn __action1344< >( + source_code: &str, mode: Mode, __0: (TextSize, (IpyEscapeKind, String), TextSize), ) -> Result> { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action807( + __action837( + source_code, mode, __0, __temp0, @@ -59692,21 +65293,24 @@ fn __action1300< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1301< +fn __action1345< >( + source_code: &str, mode: Mode, __0: (TextSize, (IpyEscapeKind, String), TextSize), ) -> Result> { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action808( + __action838( + source_code, mode, __0, __temp0, @@ -59715,8 +65319,9 @@ fn __action1301< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1302< +fn __action1346< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -59724,13 +65329,15 @@ fn __action1302< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action809( + __action839( + source_code, mode, __0, __1, @@ -59740,59 +65347,68 @@ fn __action1302< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1303< +fn __action1347< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, core::option::Option<(String, bool)>, TextSize), + __4: (TextSize, ast::ParenthesizedExpr, TextSize), ) -> Result> { let __start0 = __1.2; let __end0 = __2.0; - let __start1 = __3.2; - let __end1 = __3.2; - let __temp0 = __action392( + let __start1 = __4.2; + let __end1 = __4.2; + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action392( + let __temp1 = __action413( + source_code, mode, &__start1, &__end1, ); let __temp1 = (__start1, __temp1, __end1); - __action810( + __action840( + source_code, mode, __0, __1, __temp0, __2, __3, + __4, __temp1, ) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1304< +fn __action1348< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::Pattern { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action811( + __action841( + source_code, mode, __0, __temp0, @@ -59801,21 +65417,24 @@ fn __action1304< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1305< +fn __action1349< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::Pattern { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action812( + __action842( + source_code, mode, __0, __temp0, @@ -59824,21 +65443,24 @@ fn __action1305< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1306< +fn __action1350< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::Pattern { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action813( + __action843( + source_code, mode, __0, __temp0, @@ -59847,21 +65469,24 @@ fn __action1306< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1307< +fn __action1351< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::Pattern { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action814( + __action844( + source_code, mode, __0, __temp0, @@ -59870,21 +65495,24 @@ fn __action1307< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1308< +fn __action1352< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::Pattern { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action815( + __action845( + source_code, mode, __0, __temp0, @@ -59893,21 +65521,24 @@ fn __action1308< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1309< +fn __action1353< >( + source_code: &str, mode: Mode, - __0: (TextSize, alloc::vec::Vec<(TextSize, (String, StringKind, bool), TextSize)>, TextSize), + __0: (TextSize, alloc::vec::Vec, TextSize), ) -> Result> { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action816( + __action846( + source_code, mode, __0, __temp0, @@ -59916,21 +65547,24 @@ fn __action1309< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1310< +fn __action1354< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::Expr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action817( + __action847( + source_code, mode, __0, __temp0, @@ -59939,21 +65573,24 @@ fn __action1310< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1311< +fn __action1355< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::Expr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action818( + __action848( + source_code, mode, __0, __temp0, @@ -59962,21 +65599,24 @@ fn __action1311< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1312< +fn __action1356< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::Expr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action819( + __action849( + source_code, mode, __0, __temp0, @@ -59985,8 +65625,35 @@ fn __action1312< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1313< +fn __action1357< >( + source_code: &str, + mode: Mode, + __0: (TextSize, alloc::vec::Vec, TextSize), +) -> Result> +{ + let __start0 = __0.2; + let __end0 = __0.2; + let __temp0 = __action413( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action850( + source_code, + mode, + __0, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1358< +>( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -59994,13 +65661,15 @@ fn __action1313< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action821( + __action851( + source_code, mode, __0, __1, @@ -60010,8 +65679,9 @@ fn __action1313< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1314< +fn __action1359< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec<(ast::Expr, ast::Pattern)>, TextSize), @@ -60021,13 +65691,15 @@ fn __action1314< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action822( + __action852( + source_code, mode, __0, __1, @@ -60039,8 +65711,9 @@ fn __action1314< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1315< +fn __action1360< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec<(ast::Expr, ast::Pattern)>, TextSize), @@ -60049,13 +65722,15 @@ fn __action1315< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action823( + __action853( + source_code, mode, __0, __1, @@ -60066,8 +65741,9 @@ fn __action1315< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1316< +fn __action1361< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60078,13 +65754,15 @@ fn __action1316< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action824( + __action854( + source_code, mode, __0, __1, @@ -60097,8 +65775,9 @@ fn __action1316< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1317< +fn __action1362< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60108,13 +65787,15 @@ fn __action1317< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action825( + __action855( + source_code, mode, __0, __1, @@ -60126,8 +65807,9 @@ fn __action1317< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1318< +fn __action1363< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec<(ast::Expr, ast::Pattern)>, TextSize), @@ -60140,13 +65822,15 @@ fn __action1318< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action826( + __action856( + source_code, mode, __0, __1, @@ -60161,8 +65845,9 @@ fn __action1318< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1319< +fn __action1364< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec<(ast::Expr, ast::Pattern)>, TextSize), @@ -60174,13 +65859,15 @@ fn __action1319< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action827( + __action857( + source_code, mode, __0, __1, @@ -60194,8 +65881,9 @@ fn __action1319< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1320< +fn __action1365< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60204,13 +65892,15 @@ fn __action1320< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action829( + __action859( + source_code, mode, __0, __1, @@ -60221,21 +65911,24 @@ fn __action1320< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1321< +fn __action1366< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), ) -> ast::Expr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action830( + __action860( + source_code, mode, __0, __temp0, @@ -60244,8 +65937,9 @@ fn __action1321< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1322< +fn __action1367< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Expr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60254,13 +65948,15 @@ fn __action1322< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action831( + __action861( + source_code, mode, __0, __1, @@ -60271,8 +65967,9 @@ fn __action1322< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1323< +fn __action1368< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Expr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60281,13 +65978,15 @@ fn __action1323< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action832( + __action862( + source_code, mode, __0, __1, @@ -60298,8 +65997,127 @@ fn __action1323< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1324< +fn __action1369< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, token::Tok, TextSize), + __4: (TextSize, token::Tok, TextSize), + __5: (TextSize, token::Tok, TextSize), + __6: (TextSize, alloc::vec::Vec, TextSize), + __7: (TextSize, token::Tok, TextSize), +) -> ast::Stmt +{ + let __start0 = __2.2; + let __end0 = __3.0; + let __temp0 = __action413( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action864( + source_code, + mode, + __0, + __1, + __2, + __temp0, + __3, + __4, + __5, + __6, + __7, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1370< >( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, Vec, TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, token::Tok, TextSize), + __4: (TextSize, token::Tok, TextSize), + __5: (TextSize, token::Tok, TextSize), + __6: (TextSize, alloc::vec::Vec, TextSize), + __7: (TextSize, token::Tok, TextSize), +) -> ast::Stmt +{ + let __start0 = __2.2; + let __end0 = __3.0; + let __temp0 = __action413( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action865( + source_code, + mode, + __0, + __1, + __2, + __temp0, + __3, + __4, + __5, + __6, + __7, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1371< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, Vec, TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, token::Tok, TextSize), + __4: (TextSize, token::Tok, TextSize), + __5: (TextSize, alloc::vec::Vec, TextSize), + __6: (TextSize, token::Tok, TextSize), +) -> ast::Stmt +{ + let __start0 = __1.2; + let __end0 = __2.0; + let __temp0 = __action413( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action866( + source_code, + mode, + __0, + __1, + __temp0, + __2, + __3, + __4, + __5, + __6, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1372< +>( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60308,13 +66126,15 @@ fn __action1324< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action837( + __action867( + source_code, mode, __0, __1, @@ -60325,21 +66145,24 @@ fn __action1324< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1325< +fn __action1373< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action838( + __action868( + source_code, mode, __0, __temp0, @@ -60348,8 +66171,9 @@ fn __action1325< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1326< +fn __action1374< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -60357,13 +66181,15 @@ fn __action1326< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action839( + __action869( + source_code, mode, __0, __1, @@ -60373,8 +66199,9 @@ fn __action1326< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1327< +fn __action1375< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -60382,13 +66209,15 @@ fn __action1327< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action840( + __action870( + source_code, mode, __0, __1, @@ -60398,8 +66227,9 @@ fn __action1327< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1328< +fn __action1376< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -60407,13 +66237,15 @@ fn __action1328< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action841( + __action871( + source_code, mode, __0, __1, @@ -60423,21 +66255,24 @@ fn __action1328< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1329< +fn __action1377< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), ) -> ast::Pattern { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action842( + __action872( + source_code, mode, __0, __temp0, @@ -60446,8 +66281,9 @@ fn __action1329< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1330< +fn __action1378< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -60455,13 +66291,15 @@ fn __action1330< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action843( + __action873( + source_code, mode, __0, __1, @@ -60471,8 +66309,9 @@ fn __action1330< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1331< +fn __action1379< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -60480,13 +66319,15 @@ fn __action1331< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action844( + __action874( + source_code, mode, __0, __1, @@ -60496,8 +66337,9 @@ fn __action1331< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1332< +fn __action1380< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParameterWithDefault, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60506,13 +66348,15 @@ fn __action1332< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action472( + __action495( + source_code, mode, __0, __1, @@ -60523,8 +66367,9 @@ fn __action1332< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1333< +fn __action1381< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParameterWithDefault, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60533,13 +66378,15 @@ fn __action1333< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action461( + __action484( + source_code, mode, __0, __1, @@ -60550,8 +66397,9 @@ fn __action1333< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1334< +fn __action1382< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60564,13 +66412,15 @@ fn __action1334< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action967( + __action998( + source_code, mode, __0, __1, @@ -60585,8 +66435,9 @@ fn __action1334< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1335< +fn __action1383< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60598,13 +66449,15 @@ fn __action1335< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action968( + __action999( + source_code, mode, __0, __1, @@ -60618,8 +66471,9 @@ fn __action1335< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1336< +fn __action1384< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60633,13 +66487,15 @@ fn __action1336< { let __start0 = __7.2; let __end0 = __7.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action969( + __action1000( + source_code, mode, __0, __1, @@ -60655,8 +66511,9 @@ fn __action1336< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1337< +fn __action1385< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60669,13 +66526,15 @@ fn __action1337< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action970( + __action1001( + source_code, mode, __0, __1, @@ -60690,8 +66549,9 @@ fn __action1337< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1338< +fn __action1386< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60702,13 +66562,15 @@ fn __action1338< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action971( + __action1002( + source_code, mode, __0, __1, @@ -60721,8 +66583,9 @@ fn __action1338< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1339< +fn __action1387< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60732,13 +66595,15 @@ fn __action1339< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action972( + __action1003( + source_code, mode, __0, __1, @@ -60750,8 +66615,9 @@ fn __action1339< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1340< +fn __action1388< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60763,13 +66629,15 @@ fn __action1340< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action973( + __action1004( + source_code, mode, __0, __1, @@ -60783,8 +66651,9 @@ fn __action1340< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1341< +fn __action1389< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60795,13 +66664,15 @@ fn __action1341< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action974( + __action1005( + source_code, mode, __0, __1, @@ -60814,8 +66685,9 @@ fn __action1341< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1342< +fn __action1390< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60823,13 +66695,15 @@ fn __action1342< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action975( + __action1006( + source_code, mode, __0, __1, @@ -60839,8 +66713,9 @@ fn __action1342< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1343< +fn __action1391< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60852,13 +66727,15 @@ fn __action1343< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action976( + __action1007( + source_code, mode, __0, __1, @@ -60872,8 +66749,9 @@ fn __action1343< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1344< +fn __action1392< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60884,13 +66762,15 @@ fn __action1344< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action977( + __action1008( + source_code, mode, __0, __1, @@ -60903,8 +66783,9 @@ fn __action1344< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1345< +fn __action1393< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60917,13 +66798,15 @@ fn __action1345< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action978( + __action1009( + source_code, mode, __0, __1, @@ -60938,8 +66821,9 @@ fn __action1345< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1346< +fn __action1394< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60951,13 +66835,15 @@ fn __action1346< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action979( + __action1010( + source_code, mode, __0, __1, @@ -60971,8 +66857,9 @@ fn __action1346< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1347< +fn __action1395< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -60982,13 +66869,15 @@ fn __action1347< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action980( + __action1011( + source_code, mode, __0, __1, @@ -61000,8 +66889,9 @@ fn __action1347< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1348< +fn __action1396< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61010,13 +66900,15 @@ fn __action1348< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action981( + __action1012( + source_code, mode, __0, __1, @@ -61027,8 +66919,9 @@ fn __action1348< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1349< +fn __action1397< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61039,13 +66932,15 @@ fn __action1349< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action982( + __action1013( + source_code, mode, __0, __1, @@ -61058,8 +66953,9 @@ fn __action1349< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1350< +fn __action1398< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61069,13 +66965,15 @@ fn __action1350< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action983( + __action1014( + source_code, mode, __0, __1, @@ -61087,21 +66985,24 @@ fn __action1350< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1351< +fn __action1399< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), ) -> Result> { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action984( + __action1015( + source_code, mode, __0, __temp0, @@ -61110,8 +67011,9 @@ fn __action1351< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1352< +fn __action1400< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61121,13 +67023,15 @@ fn __action1352< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action847( + __action877( + source_code, mode, __0, __1, @@ -61139,8 +67043,9 @@ fn __action1352< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1353< +fn __action1401< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61149,13 +67054,15 @@ fn __action1353< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action848( + __action878( + source_code, mode, __0, __1, @@ -61166,8 +67073,9 @@ fn __action1353< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1354< +fn __action1402< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -61178,13 +67086,15 @@ fn __action1354< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action943( + __action974( + source_code, mode, __0, __1, @@ -61197,8 +67107,9 @@ fn __action1354< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1355< +fn __action1403< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61208,13 +67119,15 @@ fn __action1355< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action944( + __action975( + source_code, mode, __0, __1, @@ -61226,8 +67139,9 @@ fn __action1355< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1356< +fn __action1404< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -61239,13 +67153,15 @@ fn __action1356< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action945( + __action976( + source_code, mode, __0, __1, @@ -61259,8 +67175,9 @@ fn __action1356< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1357< +fn __action1405< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -61271,13 +67188,15 @@ fn __action1357< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action946( + __action977( + source_code, mode, __0, __1, @@ -61290,8 +67209,9 @@ fn __action1357< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1358< +fn __action1406< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -61300,13 +67220,15 @@ fn __action1358< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action947( + __action978( + source_code, mode, __0, __1, @@ -61317,8 +67239,9 @@ fn __action1358< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1359< +fn __action1407< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61326,13 +67249,15 @@ fn __action1359< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action948( + __action979( + source_code, mode, __0, __1, @@ -61342,8 +67267,9 @@ fn __action1359< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1360< +fn __action1408< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -61353,13 +67279,15 @@ fn __action1360< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action949( + __action980( + source_code, mode, __0, __1, @@ -61371,8 +67299,9 @@ fn __action1360< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1361< +fn __action1409< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -61381,13 +67310,15 @@ fn __action1361< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action950( + __action981( + source_code, mode, __0, __1, @@ -61398,8 +67329,9 @@ fn __action1361< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1362< +fn __action1410< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -61409,13 +67341,15 @@ fn __action1362< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action951( + __action982( + source_code, mode, __0, __1, @@ -61427,8 +67361,9 @@ fn __action1362< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1363< +fn __action1411< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61437,13 +67372,15 @@ fn __action1363< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action952( + __action983( + source_code, mode, __0, __1, @@ -61454,8 +67391,9 @@ fn __action1363< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1364< +fn __action1412< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -61466,13 +67404,15 @@ fn __action1364< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action953( + __action984( + source_code, mode, __0, __1, @@ -61485,8 +67425,9 @@ fn __action1364< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1365< +fn __action1413< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -61496,13 +67437,15 @@ fn __action1365< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action954( + __action985( + source_code, mode, __0, __1, @@ -61514,8 +67457,9 @@ fn __action1365< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1366< +fn __action1414< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -61523,13 +67467,15 @@ fn __action1366< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action955( + __action986( + source_code, mode, __0, __1, @@ -61539,21 +67485,24 @@ fn __action1366< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1367< +fn __action1415< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> Result> { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action956( + __action987( + source_code, mode, __0, __temp0, @@ -61562,8 +67511,9 @@ fn __action1367< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1368< +fn __action1416< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -61572,13 +67522,15 @@ fn __action1368< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action957( + __action988( + source_code, mode, __0, __1, @@ -61589,8 +67541,9 @@ fn __action1368< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1369< +fn __action1417< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -61598,13 +67551,15 @@ fn __action1369< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action958( + __action989( + source_code, mode, __0, __1, @@ -61614,8 +67569,9 @@ fn __action1369< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1370< +fn __action1418< >( + source_code: &str, mode: Mode, __0: (TextSize, Option>, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61623,13 +67579,15 @@ fn __action1370< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action851( + __action881( + source_code, mode, __0, __1, @@ -61639,21 +67597,24 @@ fn __action1370< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1371< +fn __action1419< >( + source_code: &str, mode: Mode, __0: (TextSize, Option>, TextSize), ) -> ast::Parameters { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action852( + __action882( + source_code, mode, __0, __temp0, @@ -61662,8 +67623,9 @@ fn __action1371< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1372< +fn __action1420< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61676,13 +67638,15 @@ fn __action1372< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1027( + __action1058( + source_code, mode, __0, __1, @@ -61697,8 +67661,9 @@ fn __action1372< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1373< +fn __action1421< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61710,13 +67675,15 @@ fn __action1373< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1028( + __action1059( + source_code, mode, __0, __1, @@ -61730,8 +67697,9 @@ fn __action1373< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1374< +fn __action1422< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61745,13 +67713,15 @@ fn __action1374< { let __start0 = __7.2; let __end0 = __7.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1029( + __action1060( + source_code, mode, __0, __1, @@ -61767,8 +67737,9 @@ fn __action1374< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1375< +fn __action1423< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61781,13 +67752,15 @@ fn __action1375< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1030( + __action1061( + source_code, mode, __0, __1, @@ -61802,8 +67775,9 @@ fn __action1375< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1376< +fn __action1424< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61814,13 +67788,15 @@ fn __action1376< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1031( + __action1062( + source_code, mode, __0, __1, @@ -61833,8 +67809,9 @@ fn __action1376< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1377< +fn __action1425< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61844,13 +67821,15 @@ fn __action1377< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1032( + __action1063( + source_code, mode, __0, __1, @@ -61862,8 +67841,9 @@ fn __action1377< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1378< +fn __action1426< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61875,13 +67855,15 @@ fn __action1378< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1033( + __action1064( + source_code, mode, __0, __1, @@ -61895,8 +67877,9 @@ fn __action1378< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1379< +fn __action1427< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61907,13 +67890,15 @@ fn __action1379< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1034( + __action1065( + source_code, mode, __0, __1, @@ -61926,8 +67911,9 @@ fn __action1379< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1380< +fn __action1428< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61935,13 +67921,15 @@ fn __action1380< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1035( + __action1066( + source_code, mode, __0, __1, @@ -61951,8 +67939,9 @@ fn __action1380< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1381< +fn __action1429< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61964,13 +67953,15 @@ fn __action1381< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1036( + __action1067( + source_code, mode, __0, __1, @@ -61984,8 +67975,9 @@ fn __action1381< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1382< +fn __action1430< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -61996,13 +67988,15 @@ fn __action1382< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1037( + __action1068( + source_code, mode, __0, __1, @@ -62015,8 +68009,9 @@ fn __action1382< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1383< +fn __action1431< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -62029,13 +68024,15 @@ fn __action1383< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1038( + __action1069( + source_code, mode, __0, __1, @@ -62050,8 +68047,9 @@ fn __action1383< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1384< +fn __action1432< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -62063,13 +68061,15 @@ fn __action1384< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1039( + __action1070( + source_code, mode, __0, __1, @@ -62083,8 +68083,9 @@ fn __action1384< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1385< +fn __action1433< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -62094,13 +68095,15 @@ fn __action1385< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1040( + __action1071( + source_code, mode, __0, __1, @@ -62112,8 +68115,9 @@ fn __action1385< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1386< +fn __action1434< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -62122,13 +68126,15 @@ fn __action1386< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1041( + __action1072( + source_code, mode, __0, __1, @@ -62139,8 +68145,9 @@ fn __action1386< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1387< +fn __action1435< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -62151,13 +68158,15 @@ fn __action1387< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1042( + __action1073( + source_code, mode, __0, __1, @@ -62170,8 +68179,9 @@ fn __action1387< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1388< +fn __action1436< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -62181,13 +68191,15 @@ fn __action1388< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1043( + __action1074( + source_code, mode, __0, __1, @@ -62199,21 +68211,24 @@ fn __action1388< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1389< +fn __action1437< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), ) -> Result> { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1044( + __action1075( + source_code, mode, __0, __temp0, @@ -62222,8 +68237,9 @@ fn __action1389< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1390< +fn __action1438< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -62233,13 +68249,15 @@ fn __action1390< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action855( + __action885( + source_code, mode, __0, __1, @@ -62251,8 +68269,9 @@ fn __action1390< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1391< +fn __action1439< >( + source_code: &str, mode: Mode, __0: (TextSize, (Vec, Vec), TextSize), __1: (TextSize, token::Tok, TextSize), @@ -62261,13 +68280,15 @@ fn __action1391< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action856( + __action886( + source_code, mode, __0, __1, @@ -62278,8 +68299,9 @@ fn __action1391< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1392< +fn __action1440< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -62290,13 +68312,15 @@ fn __action1392< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1003( + __action1034( + source_code, mode, __0, __1, @@ -62309,8 +68333,9 @@ fn __action1392< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1393< +fn __action1441< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -62320,13 +68345,15 @@ fn __action1393< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1004( + __action1035( + source_code, mode, __0, __1, @@ -62338,8 +68365,9 @@ fn __action1393< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1394< +fn __action1442< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -62351,13 +68379,15 @@ fn __action1394< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1005( + __action1036( + source_code, mode, __0, __1, @@ -62371,8 +68401,9 @@ fn __action1394< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1395< +fn __action1443< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -62383,13 +68414,15 @@ fn __action1395< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1006( + __action1037( + source_code, mode, __0, __1, @@ -62402,8 +68435,9 @@ fn __action1395< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1396< +fn __action1444< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -62412,13 +68446,15 @@ fn __action1396< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1007( + __action1038( + source_code, mode, __0, __1, @@ -62429,8 +68465,9 @@ fn __action1396< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1397< +fn __action1445< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -62438,13 +68475,15 @@ fn __action1397< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1008( + __action1039( + source_code, mode, __0, __1, @@ -62454,8 +68493,9 @@ fn __action1397< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1398< +fn __action1446< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -62465,13 +68505,15 @@ fn __action1398< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1009( + __action1040( + source_code, mode, __0, __1, @@ -62483,8 +68525,9 @@ fn __action1398< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1399< +fn __action1447< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -62493,13 +68536,15 @@ fn __action1399< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1010( + __action1041( + source_code, mode, __0, __1, @@ -62510,8 +68555,9 @@ fn __action1399< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1400< +fn __action1448< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -62521,13 +68567,15 @@ fn __action1400< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1011( + __action1042( + source_code, mode, __0, __1, @@ -62539,8 +68587,9 @@ fn __action1400< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1401< +fn __action1449< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -62549,13 +68598,15 @@ fn __action1401< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1012( + __action1043( + source_code, mode, __0, __1, @@ -62566,8 +68617,9 @@ fn __action1401< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1402< +fn __action1450< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -62578,13 +68630,15 @@ fn __action1402< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1013( + __action1044( + source_code, mode, __0, __1, @@ -62597,8 +68651,9 @@ fn __action1402< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1403< +fn __action1451< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -62608,13 +68663,15 @@ fn __action1403< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1014( + __action1045( + source_code, mode, __0, __1, @@ -62626,8 +68683,9 @@ fn __action1403< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1404< +fn __action1452< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -62635,13 +68693,15 @@ fn __action1404< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1015( + __action1046( + source_code, mode, __0, __1, @@ -62651,21 +68711,24 @@ fn __action1404< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1405< +fn __action1453< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> Result> { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1016( + __action1047( + source_code, mode, __0, __temp0, @@ -62674,8 +68737,9 @@ fn __action1405< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1406< +fn __action1454< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -62684,13 +68748,15 @@ fn __action1406< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1017( + __action1048( + source_code, mode, __0, __1, @@ -62701,8 +68767,9 @@ fn __action1406< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1407< +fn __action1455< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -62710,13 +68777,15 @@ fn __action1407< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1018( + __action1049( + source_code, mode, __0, __1, @@ -62726,8 +68795,9 @@ fn __action1407< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1408< +fn __action1456< >( + source_code: &str, mode: Mode, __0: (TextSize, Option>, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -62735,13 +68805,15 @@ fn __action1408< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action859( + __action889( + source_code, mode, __0, __1, @@ -62751,21 +68823,24 @@ fn __action1408< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1409< +fn __action1457< >( + source_code: &str, mode: Mode, __0: (TextSize, Option>, TextSize), ) -> ast::Parameters { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action860( + __action890( + source_code, mode, __0, __temp0, @@ -62774,23 +68849,26 @@ fn __action1409< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1410< +fn __action1458< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, core::option::Option, TextSize), + __1: (TextSize, ast::Parameters, TextSize), __2: (TextSize, token::Tok, TextSize), ) -> Result> { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action873( + __action1223( + source_code, mode, __0, __1, @@ -62801,21 +68879,52 @@ fn __action1410< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1411< +fn __action1459< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, token::Tok, TextSize), +) -> Result> +{ + let __start0 = __1.2; + let __end0 = __1.2; + let __temp0 = __action413( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1224( + source_code, + mode, + __0, + __1, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1460< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::Stmt { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action874( + __action904( + source_code, mode, __0, __temp0, @@ -62824,8 +68933,9 @@ fn __action1411< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1412< +fn __action1461< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -62837,13 +68947,15 @@ fn __action1412< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action875( + __action905( + source_code, mode, __0, __1, @@ -62857,8 +68969,9 @@ fn __action1412< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1413< +fn __action1462< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -62869,13 +68982,15 @@ fn __action1413< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action876( + __action906( + source_code, mode, __0, __1, @@ -62888,8 +69003,9 @@ fn __action1413< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1414< +fn __action1463< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -62899,13 +69015,15 @@ fn __action1414< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action877( + __action907( + source_code, mode, __0, __1, @@ -62917,8 +69035,9 @@ fn __action1414< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1415< +fn __action1464< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -62927,13 +69046,15 @@ fn __action1415< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action878( + __action908( + source_code, mode, __0, __1, @@ -62944,8 +69065,9 @@ fn __action1415< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1416< +fn __action1465< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -62955,13 +69077,15 @@ fn __action1416< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action879( + __action909( + source_code, mode, __0, __1, @@ -62973,8 +69097,9 @@ fn __action1416< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1417< +fn __action1466< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -62983,13 +69108,15 @@ fn __action1417< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action880( + __action910( + source_code, mode, __0, __1, @@ -63000,8 +69127,9 @@ fn __action1417< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1418< +fn __action1467< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -63009,13 +69137,15 @@ fn __action1418< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action881( + __action911( + source_code, mode, __0, __1, @@ -63025,8 +69155,9 @@ fn __action1418< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1419< +fn __action1468< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Pattern, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -63034,13 +69165,15 @@ fn __action1419< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action882( + __action912( + source_code, mode, __0, __1, @@ -63050,8 +69183,9 @@ fn __action1419< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1420< +fn __action1469< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -63059,13 +69193,15 @@ fn __action1420< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action883( + __action913( + source_code, mode, __0, __1, @@ -63075,21 +69211,24 @@ fn __action1420< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1421< +fn __action1470< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), ) -> ast::Pattern { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action884( + __action914( + source_code, mode, __0, __temp0, @@ -63098,8 +69237,9 @@ fn __action1421< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1422< +fn __action1471< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -63108,13 +69248,15 @@ fn __action1422< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action885( + __action915( + source_code, mode, __0, __1, @@ -63125,8 +69267,9 @@ fn __action1422< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1423< +fn __action1472< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -63135,13 +69278,15 @@ fn __action1423< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action886( + __action916( + source_code, mode, __0, __1, @@ -63152,21 +69297,24 @@ fn __action1423< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1424< +fn __action1473< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::Stmt { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action887( + __action917( + source_code, mode, __0, __temp0, @@ -63175,8 +69323,9 @@ fn __action1424< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1425< +fn __action1474< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -63186,13 +69335,15 @@ fn __action1425< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1114( + __action1145( + source_code, mode, __0, __1, @@ -63204,8 +69355,9 @@ fn __action1425< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1426< +fn __action1475< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -63213,13 +69365,15 @@ fn __action1426< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1115( + __action1146( + source_code, mode, __0, __1, @@ -63229,8 +69383,9 @@ fn __action1426< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1427< +fn __action1476< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Pattern, TextSize), @@ -63239,13 +69394,15 @@ fn __action1427< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action889( + __action919( + source_code, mode, __0, __1, @@ -63256,8 +69413,9 @@ fn __action1427< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1428< +fn __action1477< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -63265,13 +69423,15 @@ fn __action1428< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action890( + __action920( + source_code, mode, __0, __1, @@ -63281,8 +69441,9 @@ fn __action1428< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1429< +fn __action1478< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Pattern, TextSize), @@ -63292,13 +69453,15 @@ fn __action1429< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action891( + __action921( + source_code, mode, __0, __1, @@ -63310,8 +69473,9 @@ fn __action1429< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1430< +fn __action1479< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -63322,13 +69486,15 @@ fn __action1430< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action892( + __action922( + source_code, mode, __0, __1, @@ -63341,8 +69507,9 @@ fn __action1430< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1431< +fn __action1480< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -63352,13 +69519,15 @@ fn __action1431< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action893( + __action923( + source_code, mode, __0, __1, @@ -63370,8 +69539,9 @@ fn __action1431< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1432< +fn __action1481< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -63380,13 +69550,15 @@ fn __action1432< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action894( + __action924( + source_code, mode, __0, __1, @@ -63397,8 +69569,9 @@ fn __action1432< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1433< +fn __action1482< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), @@ -63407,13 +69580,15 @@ fn __action1433< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action895( + __action925( + source_code, mode, __0, __1, @@ -63424,8 +69599,9 @@ fn __action1433< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1434< +fn __action1483< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), @@ -63434,13 +69610,15 @@ fn __action1434< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action896( + __action926( + source_code, mode, __0, __1, @@ -63451,8 +69629,9 @@ fn __action1434< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1435< +fn __action1484< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -63464,13 +69643,15 @@ fn __action1435< { let __start0 = __5.2; let __end0 = __5.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action897( + __action927( + source_code, mode, __0, __1, @@ -63484,8 +69665,9 @@ fn __action1435< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1436< +fn __action1485< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -63496,13 +69678,15 @@ fn __action1436< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action898( + __action928( + source_code, mode, __0, __1, @@ -63515,8 +69699,9 @@ fn __action1436< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1437< +fn __action1486< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -63524,13 +69709,15 @@ fn __action1437< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action900( + __action930( + source_code, mode, __0, __1, @@ -63540,8 +69727,9 @@ fn __action1437< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1438< +fn __action1487< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -63549,13 +69737,15 @@ fn __action1438< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action901( + __action931( + source_code, mode, __0, __1, @@ -63565,8 +69755,9 @@ fn __action1438< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1439< +fn __action1488< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -63575,13 +69766,15 @@ fn __action1439< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1079( + __action1110( + source_code, mode, __0, __1, @@ -63592,21 +69785,24 @@ fn __action1439< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1440< +fn __action1489< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), ) -> ast::Parameter { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1080( + __action1111( + source_code, mode, __0, __temp0, @@ -63615,21 +69811,24 @@ fn __action1440< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1441< +fn __action1490< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), ) -> ast::Parameter { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action903( + __action933( + source_code, mode, __0, __temp0, @@ -63638,8 +69837,9 @@ fn __action1441< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1442< +fn __action1491< >( + source_code: &str, mode: Mode, __0: (TextSize, core::option::Option, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -63649,13 +69849,15 @@ fn __action1442< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action904( + __action935( + source_code, mode, __0, __1, @@ -63667,8 +69869,9 @@ fn __action1442< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1443< +fn __action1492< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -63676,13 +69879,15 @@ fn __action1443< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action905( + __action936( + source_code, mode, __0, __1, @@ -63692,8 +69897,9 @@ fn __action1443< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1444< +fn __action1493< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -63701,13 +69907,15 @@ fn __action1444< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action906( + __action937( + source_code, mode, __0, __1, @@ -63717,21 +69925,24 @@ fn __action1444< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1445< +fn __action1494< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action907( + __action938( + source_code, mode, __0, __temp0, @@ -63740,8 +69951,9 @@ fn __action1445< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1446< +fn __action1495< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), @@ -63750,13 +69962,15 @@ fn __action1446< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action908( + __action939( + source_code, mode, __0, __1, @@ -63767,8 +69981,9 @@ fn __action1446< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1447< +fn __action1496< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), @@ -63777,13 +69992,15 @@ fn __action1447< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action909( + __action940( + source_code, mode, __0, __1, @@ -63794,8 +70011,9 @@ fn __action1447< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1448< +fn __action1497< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -63806,13 +70024,15 @@ fn __action1448< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action910( + __action941( + source_code, mode, __0, __1, @@ -63825,8 +70045,9 @@ fn __action1448< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1449< +fn __action1498< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -63837,13 +70058,15 @@ fn __action1449< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action911( + __action942( + source_code, mode, __0, __1, @@ -63856,8 +70079,9 @@ fn __action1449< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1450< +fn __action1499< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Suite, TextSize), @@ -63865,13 +70089,15 @@ fn __action1450< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action912( + __action943( + source_code, mode, __0, __1, @@ -63881,8 +70107,9 @@ fn __action1450< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1451< +fn __action1500< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -63890,13 +70117,15 @@ fn __action1451< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1085( + __action1116( + source_code, mode, __0, __1, @@ -63906,8 +70135,9 @@ fn __action1451< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1452< +fn __action1501< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -63916,13 +70146,15 @@ fn __action1452< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1086( + __action1117( + source_code, mode, __0, __1, @@ -63933,8 +70165,9 @@ fn __action1452< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1453< +fn __action1502< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -63950,13 +70183,15 @@ fn __action1453< { let __start0 = __9.2; let __end0 = __9.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1105( + __action1136( + source_code, mode, __0, __1, @@ -63974,8 +70209,9 @@ fn __action1453< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1454< +fn __action1503< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -63988,13 +70224,15 @@ fn __action1454< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1106( + __action1137( + source_code, mode, __0, __1, @@ -64009,8 +70247,9 @@ fn __action1454< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1455< +fn __action1504< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -64023,13 +70262,15 @@ fn __action1455< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1107( + __action1138( + source_code, mode, __0, __1, @@ -64044,8 +70285,9 @@ fn __action1455< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1456< +fn __action1505< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -64055,13 +70297,15 @@ fn __action1456< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1108( + __action1139( + source_code, mode, __0, __1, @@ -64073,8 +70317,9 @@ fn __action1456< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1457< +fn __action1506< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -64090,13 +70335,15 @@ fn __action1457< { let __start0 = __9.2; let __end0 = __9.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1109( + __action1140( + source_code, mode, __0, __1, @@ -64114,8 +70361,9 @@ fn __action1457< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1458< +fn __action1507< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -64128,13 +70376,15 @@ fn __action1458< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1110( + __action1141( + source_code, mode, __0, __1, @@ -64149,8 +70399,9 @@ fn __action1458< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1459< +fn __action1508< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -64163,13 +70414,15 @@ fn __action1459< { let __start0 = __6.2; let __end0 = __6.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1111( + __action1142( + source_code, mode, __0, __1, @@ -64184,8 +70437,9 @@ fn __action1459< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1460< +fn __action1509< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -64195,13 +70449,15 @@ fn __action1460< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1112( + __action1143( + source_code, mode, __0, __1, @@ -64213,21 +70469,24 @@ fn __action1460< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1461< +fn __action1510< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), ) -> ast::Expr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action917( + __action948( + source_code, mode, __0, __temp0, @@ -64236,8 +70495,9 @@ fn __action1461< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1462< +fn __action1511< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Expr, TextSize), @@ -64248,13 +70508,15 @@ fn __action1462< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action918( + __action949( + source_code, mode, __0, __1, @@ -64267,8 +70529,9 @@ fn __action1462< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1463< +fn __action1512< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -64277,13 +70540,15 @@ fn __action1463< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1074( + __action1105( + source_code, mode, __0, __1, @@ -64294,21 +70559,24 @@ fn __action1463< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1464< +fn __action1513< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), ) -> ast::TypeParam { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1075( + __action1106( + source_code, mode, __0, __temp0, @@ -64317,8 +70585,9 @@ fn __action1464< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1465< +fn __action1514< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -64326,13 +70595,15 @@ fn __action1465< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action920( + __action951( + source_code, mode, __0, __1, @@ -64342,8 +70613,9 @@ fn __action1465< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1466< +fn __action1515< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -64351,13 +70623,15 @@ fn __action1466< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action921( + __action952( + source_code, mode, __0, __1, @@ -64367,8 +70641,9 @@ fn __action1466< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1467< +fn __action1516< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -64378,13 +70653,15 @@ fn __action1467< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action922( + __action953( + source_code, mode, __0, __1, @@ -64396,8 +70673,9 @@ fn __action1467< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1468< +fn __action1517< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -64406,13 +70684,15 @@ fn __action1468< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action923( + __action954( + source_code, mode, __0, __1, @@ -64423,8 +70703,9 @@ fn __action1468< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1469< +fn __action1518< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -64433,13 +70714,15 @@ fn __action1469< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1076( + __action1107( + source_code, mode, __0, __1, @@ -64450,21 +70733,24 @@ fn __action1469< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1470< +fn __action1519< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), ) -> ast::ParameterWithDefault { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1077( + __action1108( + source_code, mode, __0, __temp0, @@ -64473,21 +70759,24 @@ fn __action1470< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1471< +fn __action1520< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), ) -> ast::ParameterWithDefault { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action925( + __action956( + source_code, mode, __0, __temp0, @@ -64496,21 +70785,24 @@ fn __action1471< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1472< +fn __action1521< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Expr, TextSize), ) -> ast::Pattern { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action926( + __action957( + source_code, mode, __0, __temp0, @@ -64519,8 +70811,9 @@ fn __action1472< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1473< +fn __action1522< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -64529,13 +70822,15 @@ fn __action1473< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action928( + __action959( + source_code, mode, __0, __1, @@ -64546,8 +70841,9 @@ fn __action1473< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1474< +fn __action1523< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -64556,13 +70852,15 @@ fn __action1474< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action931( + __action962( + source_code, mode, __0, __1, @@ -64573,8 +70871,9 @@ fn __action1474< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1475< +fn __action1524< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -64583,13 +70882,15 @@ fn __action1475< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action932( + __action963( + source_code, mode, __0, __1, @@ -64600,8 +70901,9 @@ fn __action1475< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1476< +fn __action1525< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, core::option::Option, TextSize), @@ -64609,13 +70911,15 @@ fn __action1476< { let __start0 = __1.2; let __end0 = __1.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action933( + __action964( + source_code, mode, __0, __1, @@ -64625,8 +70929,9 @@ fn __action1476< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1477< +fn __action1526< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -64635,13 +70940,15 @@ fn __action1477< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action392( + let __temp0 = __action413( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action934( + __action965( + source_code, mode, __0, __1, @@ -64652,250 +70959,9 @@ fn __action1477< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1478< ->( - mode: Mode, - __0: (TextSize, (String, StringKind, bool), TextSize), -) -> alloc::vec::Vec<(TextSize, (String, StringKind, bool), TextSize)> -{ - let __start0 = __0.0; - let __end0 = __0.2; - let __temp0 = __action1186( - mode, - __0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action329( - mode, - __temp0, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1479< ->( - mode: Mode, - __0: (TextSize, alloc::vec::Vec<(TextSize, (String, StringKind, bool), TextSize)>, TextSize), - __1: (TextSize, (String, StringKind, bool), TextSize), -) -> alloc::vec::Vec<(TextSize, (String, StringKind, bool), TextSize)> -{ - let __start0 = __1.0; - let __end0 = __1.2; - let __temp0 = __action1186( - mode, - __1, - ); - let __temp0 = (__start0, __temp0, __end0); - __action330( - mode, - __0, - __temp0, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1480< ->( - mode: Mode, - __0: (TextSize, ast::CmpOp, TextSize), - __1: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)> -{ - let __start0 = __0.0; - let __end0 = __1.2; - let __temp0 = __action493( - mode, - __0, - __1, - ); - let __temp0 = (__start0, __temp0, __end0); - __action491( - mode, - __temp0, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1481< ->( - mode: Mode, - __0: (TextSize, alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)>, TextSize), - __1: (TextSize, ast::CmpOp, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), -) -> alloc::vec::Vec<(ast::CmpOp, ast::ParenthesizedExpr)> -{ - let __start0 = __1.0; - let __end0 = __2.2; - let __temp0 = __action493( - mode, - __1, - __2, - ); - let __temp0 = (__start0, __temp0, __end0); - __action492( - mode, - __0, - __temp0, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1482< ->( - mode: Mode, - __0: (TextSize, ast::Expr, TextSize), -) -> core::option::Option -{ - let __start0 = __0.0; - let __end0 = __0.2; - let __temp0 = __action342( - mode, - __0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action340( - mode, - __temp0, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1483< ->( - mode: Mode, - __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::Pattern, TextSize), - __2: (TextSize, ast::Expr, TextSize), - __3: (TextSize, token::Tok, TextSize), - __4: (TextSize, ast::Suite, TextSize), -) -> ast::MatchCase -{ - let __start0 = __2.0; - let __end0 = __2.2; - let __temp0 = __action1482( - mode, - __2, - ); - let __temp0 = (__start0, __temp0, __end0); - __action828( - mode, - __0, - __1, - __temp0, - __3, - __4, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1484< ->( - mode: Mode, - __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::Pattern, TextSize), - __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::Suite, TextSize), -) -> ast::MatchCase -{ - let __start0 = __1.2; - let __end0 = __2.0; - let __temp0 = __action341( - mode, - &__start0, - &__end0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action828( - mode, - __0, - __1, - __temp0, - __2, - __3, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1485< ->( - mode: Mode, - __0: (TextSize, ast::Parameters, TextSize), -) -> core::option::Option -{ - let __start0 = __0.0; - let __end0 = __0.2; - let __temp0 = __action276( - mode, - __0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action274( - mode, - __temp0, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1486< ->( - mode: Mode, - __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, ast::Parameters, TextSize), - __2: (TextSize, token::Tok, TextSize), -) -> Result> -{ - let __start0 = __1.0; - let __end0 = __1.2; - let __temp0 = __action1485( - mode, - __1, - ); - let __temp0 = (__start0, __temp0, __end0); - __action1410( - mode, - __0, - __temp0, - __2, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1487< ->( - mode: Mode, - __0: (TextSize, token::Tok, TextSize), - __1: (TextSize, token::Tok, TextSize), -) -> Result> -{ - let __start0 = __0.2; - let __end0 = __1.0; - let __temp0 = __action275( - mode, - &__start0, - &__end0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action1410( - mode, - __0, - __temp0, - __1, - ) -} - -#[allow(unused_variables)] -#[allow(clippy::too_many_arguments)] -fn __action1488< +fn __action1527< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -64908,12 +70974,14 @@ fn __action1488< { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action266( + let __temp0 = __action286( + source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action757( + __action781( + source_code, mode, __0, __1, @@ -64927,8 +70995,9 @@ fn __action1488< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1489< +fn __action1528< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -64940,13 +71009,15 @@ fn __action1489< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action267( + let __temp0 = __action287( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action757( + __action781( + source_code, mode, __0, __1, @@ -64960,21 +71031,24 @@ fn __action1489< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1490< +fn __action1529< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::Stmt { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action382( + let __temp0 = __action403( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1271( + __action1311( + source_code, mode, __0, __temp0, @@ -64983,8 +71057,9 @@ fn __action1490< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1491< +fn __action1530< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -64992,12 +71067,14 @@ fn __action1491< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action383( + let __temp0 = __action404( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1271( + __action1311( + source_code, mode, __0, __temp0, @@ -65006,8 +71083,9 @@ fn __action1491< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1492< +fn __action1531< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -65017,12 +71095,14 @@ fn __action1492< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action377( + let __temp0 = __action398( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1273( + __action1313( + source_code, mode, __0, __1, @@ -65033,8 +71113,9 @@ fn __action1492< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1493< +fn __action1532< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -65043,13 +71124,15 @@ fn __action1493< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action378( + let __temp0 = __action399( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1273( + __action1313( + source_code, mode, __0, __1, @@ -65060,20 +71143,23 @@ fn __action1493< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1494< +fn __action1533< >( + source_code: &str, mode: Mode, __0: (TextSize, (Option<(TextSize, TextSize, Option)>, ast::Expr), TextSize), ) -> Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)> { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action441( + let __temp0 = __action464( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1129( + __action1160( + source_code, mode, __temp0, ) @@ -65081,8 +71167,9 @@ fn __action1494< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1495< +fn __action1534< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -65090,13 +71177,15 @@ fn __action1495< { let __start0 = *__lookbehind; let __end0 = *__lookahead; - let __temp0 = __action442( + let __temp0 = __action465( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1129( + __action1160( + source_code, mode, __temp0, ) @@ -65104,8 +71193,9 @@ fn __action1495< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1496< +fn __action1535< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize), __1: (TextSize, (Option<(TextSize, TextSize, Option)>, ast::Expr), TextSize), @@ -65113,12 +71203,14 @@ fn __action1496< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action441( + let __temp0 = __action464( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1130( + __action1161( + source_code, mode, __0, __temp0, @@ -65127,21 +71219,24 @@ fn __action1496< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1497< +fn __action1536< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize), ) -> Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)> { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action442( + let __temp0 = __action465( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1130( + __action1161( + source_code, mode, __0, __temp0, @@ -65150,8 +71245,9 @@ fn __action1497< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1498< +fn __action1537< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, (Option<(TextSize, TextSize, Option)>, ast::Expr), TextSize), @@ -65160,12 +71256,14 @@ fn __action1498< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action1494( + let __temp0 = __action1533( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1192( + __action1230( + source_code, mode, __0, __temp0, @@ -65175,8 +71273,9 @@ fn __action1498< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1499< +fn __action1538< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -65184,13 +71283,15 @@ fn __action1499< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action1495( + let __temp0 = __action1534( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1192( + __action1230( + source_code, mode, __0, __temp0, @@ -65200,8 +71301,9 @@ fn __action1499< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1500< +fn __action1539< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize), @@ -65211,13 +71313,15 @@ fn __action1500< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1496( + let __temp0 = __action1535( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1192( + __action1230( + source_code, mode, __0, __temp0, @@ -65227,8 +71331,9 @@ fn __action1500< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1501< +fn __action1540< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec<(Option<(TextSize, TextSize, Option)>, ast::Expr)>, TextSize), @@ -65237,12 +71342,14 @@ fn __action1501< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action1497( + let __temp0 = __action1536( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1192( + __action1230( + source_code, mode, __0, __temp0, @@ -65252,20 +71359,23 @@ fn __action1501< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1502< +fn __action1541< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Pattern, TextSize), ) -> Vec { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action405( + let __temp0 = __action426( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1152( + __action1183( + source_code, mode, __temp0, ) @@ -65273,8 +71383,9 @@ fn __action1502< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1503< +fn __action1542< >( + source_code: &str, mode: Mode, __lookbehind: &TextSize, __lookahead: &TextSize, @@ -65282,13 +71393,15 @@ fn __action1503< { let __start0 = *__lookbehind; let __end0 = *__lookahead; - let __temp0 = __action406( + let __temp0 = __action427( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1152( + __action1183( + source_code, mode, __temp0, ) @@ -65296,8 +71409,9 @@ fn __action1503< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1504< +fn __action1543< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::Pattern, TextSize), @@ -65305,12 +71419,14 @@ fn __action1504< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action405( + let __temp0 = __action426( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1153( + __action1184( + source_code, mode, __0, __temp0, @@ -65319,21 +71435,24 @@ fn __action1504< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1505< +fn __action1544< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), ) -> Vec { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action406( + let __temp0 = __action427( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1153( + __action1184( + source_code, mode, __0, __temp0, @@ -65342,8 +71461,9 @@ fn __action1505< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1506< +fn __action1545< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Pattern, TextSize), @@ -65352,12 +71472,14 @@ fn __action1506< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action1502( + let __temp0 = __action1541( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1432( + __action1481( + source_code, mode, __0, __temp0, @@ -65367,8 +71489,9 @@ fn __action1506< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1507< +fn __action1546< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -65376,13 +71499,15 @@ fn __action1507< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action1503( + let __temp0 = __action1542( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1432( + __action1481( + source_code, mode, __0, __temp0, @@ -65392,8 +71517,9 @@ fn __action1507< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1508< +fn __action1547< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -65403,13 +71529,15 @@ fn __action1508< { let __start0 = __1.0; let __end0 = __2.2; - let __temp0 = __action1504( + let __temp0 = __action1543( + source_code, mode, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1432( + __action1481( + source_code, mode, __0, __temp0, @@ -65419,8 +71547,9 @@ fn __action1508< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1509< +fn __action1548< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -65429,12 +71558,14 @@ fn __action1509< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action1505( + let __temp0 = __action1544( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1432( + __action1481( + source_code, mode, __0, __temp0, @@ -65444,8 +71575,9 @@ fn __action1509< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1510< +fn __action1549< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, Vec, TextSize), @@ -65453,12 +71585,14 @@ fn __action1510< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action237( + let __temp0 = __action247( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1280( + __action1324( + source_code, mode, __0, __temp0, @@ -65467,21 +71601,24 @@ fn __action1510< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1511< +fn __action1550< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), ) -> (Option<(TextSize, TextSize, Option)>, ast::Expr) { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action238( + let __temp0 = __action248( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1280( + __action1324( + source_code, mode, __0, __temp0, @@ -65490,8 +71627,9 @@ fn __action1511< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1512< +fn __action1551< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -65502,13 +71640,15 @@ fn __action1512< { let __start0 = __4.2; let __end0 = __4.2; - let __temp0 = __action240( + let __temp0 = __action250( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1435( + __action1484( + source_code, mode, __0, __1, @@ -65521,8 +71661,9 @@ fn __action1512< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1513< +fn __action1552< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -65534,12 +71675,14 @@ fn __action1513< { let __start0 = __5.0; let __end0 = __5.2; - let __temp0 = __action241( + let __temp0 = __action251( + source_code, mode, __5, ); let __temp0 = (__start0, __temp0, __end0); - __action1435( + __action1484( + source_code, mode, __0, __1, @@ -65552,8 +71695,9 @@ fn __action1513< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1514< +fn __action1553< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -65563,13 +71707,15 @@ fn __action1514< { let __start0 = __3.2; let __end0 = __3.2; - let __temp0 = __action240( + let __temp0 = __action250( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1436( + __action1485( + source_code, mode, __0, __1, @@ -65581,8 +71727,9 @@ fn __action1514< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1515< +fn __action1554< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -65593,12 +71740,14 @@ fn __action1515< { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action241( + let __temp0 = __action251( + source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action1436( + __action1485( + source_code, mode, __0, __1, @@ -65610,8 +71759,9 @@ fn __action1515< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1516< +fn __action1555< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -65623,13 +71773,15 @@ fn __action1516< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action286( + let __temp0 = __action306( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1488( + __action1527( + source_code, mode, __temp0, __0, @@ -65643,8 +71795,9 @@ fn __action1516< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1517< +fn __action1556< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -65657,12 +71810,14 @@ fn __action1517< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action287( + let __temp0 = __action307( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1488( + __action1527( + source_code, mode, __temp0, __1, @@ -65676,8 +71831,9 @@ fn __action1517< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1518< +fn __action1557< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -65688,13 +71844,15 @@ fn __action1518< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action286( + let __temp0 = __action306( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1489( + __action1528( + source_code, mode, __temp0, __0, @@ -65707,8 +71865,9 @@ fn __action1518< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1519< +fn __action1558< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -65720,12 +71879,14 @@ fn __action1519< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action287( + let __temp0 = __action307( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1489( + __action1528( + source_code, mode, __temp0, __1, @@ -65738,8 +71899,9 @@ fn __action1519< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1520< +fn __action1559< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -65754,13 +71916,15 @@ fn __action1520< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action286( + let __temp0 = __action306( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1065( + __action1096( + source_code, mode, __temp0, __0, @@ -65777,8 +71941,9 @@ fn __action1520< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1521< +fn __action1560< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -65794,12 +71959,14 @@ fn __action1521< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action287( + let __temp0 = __action307( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1065( + __action1096( + source_code, mode, __temp0, __1, @@ -65816,8 +71983,9 @@ fn __action1521< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1522< +fn __action1561< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -65830,13 +71998,15 @@ fn __action1522< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action286( + let __temp0 = __action306( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1066( + __action1097( + source_code, mode, __temp0, __0, @@ -65851,8 +72021,9 @@ fn __action1522< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1523< +fn __action1562< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -65866,12 +72037,14 @@ fn __action1523< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action287( + let __temp0 = __action307( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1066( + __action1097( + source_code, mode, __temp0, __1, @@ -65886,8 +72059,9 @@ fn __action1523< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1524< +fn __action1563< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -65901,13 +72075,15 @@ fn __action1524< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action286( + let __temp0 = __action306( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1067( + __action1098( + source_code, mode, __temp0, __0, @@ -65923,8 +72099,9 @@ fn __action1524< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1525< +fn __action1564< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -65939,12 +72116,14 @@ fn __action1525< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action287( + let __temp0 = __action307( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1067( + __action1098( + source_code, mode, __temp0, __1, @@ -65960,8 +72139,9 @@ fn __action1525< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1526< +fn __action1565< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -65973,13 +72153,15 @@ fn __action1526< { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action286( + let __temp0 = __action306( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1068( + __action1099( + source_code, mode, __temp0, __0, @@ -65993,8 +72175,9 @@ fn __action1526< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1527< +fn __action1566< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66007,12 +72190,14 @@ fn __action1527< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action287( + let __temp0 = __action307( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1068( + __action1099( + source_code, mode, __temp0, __1, @@ -66026,8 +72211,9 @@ fn __action1527< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1528< +fn __action1567< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec<(Option>, ast::ParenthesizedExpr)>, TextSize), @@ -66036,12 +72222,14 @@ fn __action1528< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action541( + let __temp0 = __action564( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1216( + __action1255( + source_code, mode, __0, __temp0, @@ -66051,8 +72239,9 @@ fn __action1528< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1529< +fn __action1568< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66060,13 +72249,15 @@ fn __action1529< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action542( + let __temp0 = __action565( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1216( + __action1255( + source_code, mode, __0, __temp0, @@ -66076,8 +72267,9 @@ fn __action1529< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1530< +fn __action1569< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec<(Option>, ast::ParenthesizedExpr)>, TextSize), @@ -66086,12 +72278,14 @@ fn __action1530< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action541( + let __temp0 = __action564( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1240( + __action1280( + source_code, mode, __0, __temp0, @@ -66101,8 +72295,9 @@ fn __action1530< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1531< +fn __action1570< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66110,13 +72305,15 @@ fn __action1531< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action542( + let __temp0 = __action565( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1240( + __action1280( + source_code, mode, __0, __temp0, @@ -66126,8 +72323,9 @@ fn __action1531< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1532< +fn __action1571< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameter, TextSize), @@ -66135,12 +72333,14 @@ fn __action1532< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action475( + let __temp0 = __action498( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action417( + __action438( + source_code, mode, __0, __temp0, @@ -66149,21 +72349,24 @@ fn __action1532< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1533< +fn __action1572< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> Option> { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action476( + let __temp0 = __action499( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action417( + __action438( + source_code, mode, __0, __temp0, @@ -66172,8 +72375,503 @@ fn __action1533< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1534< +fn __action1573< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, (TextSize, ast::ConversionFlag), TextSize), + __4: (TextSize, core::option::Option, TextSize), + __5: (TextSize, token::Tok, TextSize), +) -> Result> +{ + let __start0 = __3.0; + let __end0 = __3.2; + let __temp0 = __action266( + source_code, + mode, + __3, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1316( + source_code, + mode, + __0, + __1, + __2, + __temp0, + __4, + __5, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1574< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, core::option::Option, TextSize), + __4: (TextSize, token::Tok, TextSize), +) -> Result> +{ + let __start0 = __2.2; + let __end0 = __3.0; + let __temp0 = __action267( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1316( + source_code, + mode, + __0, + __1, + __2, + __temp0, + __3, + __4, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1575< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, (TextSize, ast::ConversionFlag), TextSize), + __3: (TextSize, core::option::Option, TextSize), + __4: (TextSize, token::Tok, TextSize), +) -> Result> +{ + let __start0 = __2.0; + let __end0 = __2.2; + let __temp0 = __action266( + source_code, + mode, + __2, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1317( + source_code, + mode, + __0, + __1, + __temp0, + __3, + __4, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1576< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, core::option::Option, TextSize), + __3: (TextSize, token::Tok, TextSize), +) -> Result> +{ + let __start0 = __1.2; + let __end0 = __2.0; + let __temp0 = __action267( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1317( + source_code, + mode, + __0, + __1, + __temp0, + __2, + __3, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1577< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, (TextSize, ast::ConversionFlag), TextSize), + __4: (TextSize, ast::Expr, TextSize), + __5: (TextSize, token::Tok, TextSize), +) -> Result> +{ + let __start0 = __4.0; + let __end0 = __4.2; + let __temp0 = __action264( + source_code, + mode, + __4, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1573( + source_code, + mode, + __0, + __1, + __2, + __3, + __temp0, + __5, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1578< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, (TextSize, ast::ConversionFlag), TextSize), + __4: (TextSize, token::Tok, TextSize), +) -> Result> +{ + let __start0 = __3.2; + let __end0 = __4.0; + let __temp0 = __action265( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1573( + source_code, + mode, + __0, + __1, + __2, + __3, + __temp0, + __4, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1579< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, ast::Expr, TextSize), + __4: (TextSize, token::Tok, TextSize), +) -> Result> +{ + let __start0 = __3.0; + let __end0 = __3.2; + let __temp0 = __action264( + source_code, + mode, + __3, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1574( + source_code, + mode, + __0, + __1, + __2, + __temp0, + __4, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1580< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, token::Tok, TextSize), +) -> Result> +{ + let __start0 = __2.2; + let __end0 = __3.0; + let __temp0 = __action265( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1574( + source_code, + mode, + __0, + __1, + __2, + __temp0, + __3, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1581< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, (TextSize, ast::ConversionFlag), TextSize), + __3: (TextSize, ast::Expr, TextSize), + __4: (TextSize, token::Tok, TextSize), +) -> Result> +{ + let __start0 = __3.0; + let __end0 = __3.2; + let __temp0 = __action264( + source_code, + mode, + __3, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1575( + source_code, + mode, + __0, + __1, + __2, + __temp0, + __4, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1582< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, (TextSize, ast::ConversionFlag), TextSize), + __3: (TextSize, token::Tok, TextSize), +) -> Result> +{ + let __start0 = __2.2; + let __end0 = __3.0; + let __temp0 = __action265( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1575( + source_code, + mode, + __0, + __1, + __2, + __temp0, + __3, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1583< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, ast::Expr, TextSize), + __3: (TextSize, token::Tok, TextSize), +) -> Result> +{ + let __start0 = __2.0; + let __end0 = __2.2; + let __temp0 = __action264( + source_code, + mode, + __2, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1576( + source_code, + mode, + __0, + __1, + __temp0, + __3, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1584< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, token::Tok, TextSize), +) -> Result> +{ + let __start0 = __1.2; + let __end0 = __2.0; + let __temp0 = __action265( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1576( + source_code, + mode, + __0, + __1, + __temp0, + __2, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1585< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, token::Tok, TextSize), +) -> StringType +{ + let __start0 = __0.2; + let __end0 = __1.0; + let __temp0 = __action270( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1314( + source_code, + mode, + __0, + __temp0, + __1, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1586< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, alloc::vec::Vec, TextSize), + __2: (TextSize, token::Tok, TextSize), +) -> StringType +{ + let __start0 = __1.0; + let __end0 = __1.2; + let __temp0 = __action271( + source_code, + mode, + __1, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1314( + source_code, + mode, + __0, + __temp0, + __2, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1587< +>( + source_code: &str, + mode: Mode, + __lookbehind: &TextSize, + __lookahead: &TextSize, +) -> ast::Expr +{ + let __start0 = *__lookbehind; + let __end0 = *__lookahead; + let __temp0 = __action270( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1315( + source_code, + mode, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1588< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, alloc::vec::Vec, TextSize), +) -> ast::Expr +{ + let __start0 = __0.0; + let __end0 = __0.2; + let __temp0 = __action271( + source_code, + mode, + __0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1315( + source_code, + mode, + __temp0, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1589< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66182,14 +72880,16 @@ fn __action1534< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action1290( + let __temp0 = __action1334( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action369( + __action390( + source_code, mode, __temp0, ) @@ -66197,20 +72897,23 @@ fn __action1534< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1535< +fn __action1590< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), ) -> Vec { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action1291( + let __temp0 = __action1335( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action369( + __action390( + source_code, mode, __temp0, ) @@ -66218,8 +72921,9 @@ fn __action1535< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1536< +fn __action1591< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66230,14 +72934,16 @@ fn __action1536< { let __start0 = __2.0; let __end0 = __4.2; - let __temp0 = __action1290( + let __temp0 = __action1334( + source_code, mode, __2, __3, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action370( + __action391( + source_code, mode, __0, __1, @@ -66247,8 +72953,9 @@ fn __action1536< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1537< +fn __action1592< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66257,12 +72964,14 @@ fn __action1537< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action1291( + let __temp0 = __action1335( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action370( + __action391( + source_code, mode, __0, __1, @@ -66272,8 +72981,9 @@ fn __action1537< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1538< +fn __action1593< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66282,14 +72992,16 @@ fn __action1538< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action1292( + let __temp0 = __action1336( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action362( + __action383( + source_code, mode, __temp0, ) @@ -66297,20 +73009,23 @@ fn __action1538< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1539< +fn __action1594< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), ) -> Vec { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action1293( + let __temp0 = __action1337( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action362( + __action383( + source_code, mode, __temp0, ) @@ -66318,8 +73033,9 @@ fn __action1539< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1540< +fn __action1595< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66330,14 +73046,16 @@ fn __action1540< { let __start0 = __2.0; let __end0 = __4.2; - let __temp0 = __action1292( + let __temp0 = __action1336( + source_code, mode, __2, __3, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action363( + __action384( + source_code, mode, __0, __1, @@ -66347,8 +73065,9 @@ fn __action1540< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1541< +fn __action1596< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66357,12 +73076,14 @@ fn __action1541< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action1293( + let __temp0 = __action1337( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action363( + __action384( + source_code, mode, __0, __1, @@ -66372,21 +73093,24 @@ fn __action1541< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1542< +fn __action1597< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::Identifier, TextSize), ) -> (Option, Option) { let __start0 = __0.0; let __end0 = __0.0; - let __temp0 = __action367( + let __temp0 = __action388( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); __action62( + source_code, mode, __temp0, __0, @@ -66395,8 +73119,9 @@ fn __action1542< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1543< +fn __action1598< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -66404,12 +73129,14 @@ fn __action1543< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action368( + let __temp0 = __action389( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); __action62( + source_code, mode, __temp0, __1, @@ -66418,8 +73145,9 @@ fn __action1543< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1544< +fn __action1599< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -66428,12 +73156,14 @@ fn __action1544< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action549( + let __temp0 = __action572( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1200( + __action1239( + source_code, mode, __0, __temp0, @@ -66443,8 +73173,9 @@ fn __action1544< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1545< +fn __action1600< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66452,13 +73183,15 @@ fn __action1545< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action550( + let __temp0 = __action573( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1200( + __action1239( + source_code, mode, __0, __temp0, @@ -66468,8 +73201,9 @@ fn __action1545< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1546< +fn __action1601< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Vec, TextSize), @@ -66478,12 +73212,14 @@ fn __action1546< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action549( + let __temp0 = __action572( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1226( + __action1266( + source_code, mode, __0, __temp0, @@ -66493,8 +73229,9 @@ fn __action1546< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1547< +fn __action1602< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66502,13 +73239,15 @@ fn __action1547< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action550( + let __temp0 = __action573( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1226( + __action1266( + source_code, mode, __0, __temp0, @@ -66518,8 +73257,9 @@ fn __action1547< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1548< +fn __action1603< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66532,12 +73272,14 @@ fn __action1548< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1334( + __action1382( + source_code, mode, __temp0, __1, @@ -66551,8 +73293,9 @@ fn __action1548< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1549< +fn __action1604< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66567,14 +73310,16 @@ fn __action1549< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1334( + __action1382( + source_code, mode, __temp0, __3, @@ -66588,8 +73333,9 @@ fn __action1549< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1550< +fn __action1605< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66605,7 +73351,8 @@ fn __action1550< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -66613,7 +73360,8 @@ fn __action1550< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1334( + __action1382( + source_code, mode, __temp0, __4, @@ -66627,8 +73375,9 @@ fn __action1550< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1551< +fn __action1606< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66640,12 +73389,14 @@ fn __action1551< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1335( + __action1383( + source_code, mode, __temp0, __1, @@ -66658,8 +73409,9 @@ fn __action1551< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1552< +fn __action1607< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66673,14 +73425,16 @@ fn __action1552< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1335( + __action1383( + source_code, mode, __temp0, __3, @@ -66693,8 +73447,9 @@ fn __action1552< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1553< +fn __action1608< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66709,7 +73464,8 @@ fn __action1553< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -66717,7 +73473,8 @@ fn __action1553< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1335( + __action1383( + source_code, mode, __temp0, __4, @@ -66730,8 +73487,9 @@ fn __action1553< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1554< +fn __action1609< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66745,12 +73503,14 @@ fn __action1554< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1336( + __action1384( + source_code, mode, __temp0, __1, @@ -66765,8 +73525,9 @@ fn __action1554< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1555< +fn __action1610< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66782,14 +73543,16 @@ fn __action1555< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1336( + __action1384( + source_code, mode, __temp0, __3, @@ -66804,8 +73567,9 @@ fn __action1555< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1556< +fn __action1611< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66822,7 +73586,8 @@ fn __action1556< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -66830,7 +73595,8 @@ fn __action1556< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1336( + __action1384( + source_code, mode, __temp0, __4, @@ -66845,8 +73611,9 @@ fn __action1556< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1557< +fn __action1612< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66859,12 +73626,14 @@ fn __action1557< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1337( + __action1385( + source_code, mode, __temp0, __1, @@ -66878,8 +73647,9 @@ fn __action1557< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1558< +fn __action1613< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66894,14 +73664,16 @@ fn __action1558< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1337( + __action1385( + source_code, mode, __temp0, __3, @@ -66915,8 +73687,9 @@ fn __action1558< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1559< +fn __action1614< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66932,7 +73705,8 @@ fn __action1559< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -66940,7 +73714,8 @@ fn __action1559< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1337( + __action1385( + source_code, mode, __temp0, __4, @@ -66954,8 +73729,9 @@ fn __action1559< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1560< +fn __action1615< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66966,12 +73742,14 @@ fn __action1560< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1338( + __action1386( + source_code, mode, __temp0, __1, @@ -66983,8 +73761,9 @@ fn __action1560< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1561< +fn __action1616< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -66997,14 +73776,16 @@ fn __action1561< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1338( + __action1386( + source_code, mode, __temp0, __3, @@ -67016,8 +73797,9 @@ fn __action1561< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1562< +fn __action1617< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67031,7 +73813,8 @@ fn __action1562< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -67039,7 +73822,8 @@ fn __action1562< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1338( + __action1386( + source_code, mode, __temp0, __4, @@ -67051,8 +73835,9 @@ fn __action1562< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1563< +fn __action1618< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67062,12 +73847,14 @@ fn __action1563< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1339( + __action1387( + source_code, mode, __temp0, __1, @@ -67078,8 +73865,9 @@ fn __action1563< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1564< +fn __action1619< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67091,14 +73879,16 @@ fn __action1564< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1339( + __action1387( + source_code, mode, __temp0, __3, @@ -67109,8 +73899,9 @@ fn __action1564< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1565< +fn __action1620< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67123,7 +73914,8 @@ fn __action1565< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -67131,7 +73923,8 @@ fn __action1565< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1339( + __action1387( + source_code, mode, __temp0, __4, @@ -67142,8 +73935,9 @@ fn __action1565< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1566< +fn __action1621< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67155,12 +73949,14 @@ fn __action1566< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1340( + __action1388( + source_code, mode, __temp0, __1, @@ -67173,8 +73969,9 @@ fn __action1566< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1567< +fn __action1622< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67188,14 +73985,16 @@ fn __action1567< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1340( + __action1388( + source_code, mode, __temp0, __3, @@ -67208,8 +74007,9 @@ fn __action1567< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1568< +fn __action1623< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67224,7 +74024,8 @@ fn __action1568< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -67232,7 +74033,8 @@ fn __action1568< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1340( + __action1388( + source_code, mode, __temp0, __4, @@ -67245,8 +74047,9 @@ fn __action1568< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1569< +fn __action1624< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67257,12 +74060,14 @@ fn __action1569< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1341( + __action1389( + source_code, mode, __temp0, __1, @@ -67274,8 +74079,9 @@ fn __action1569< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1570< +fn __action1625< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67288,14 +74094,16 @@ fn __action1570< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1341( + __action1389( + source_code, mode, __temp0, __3, @@ -67307,8 +74115,9 @@ fn __action1570< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1571< +fn __action1626< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67322,7 +74131,8 @@ fn __action1571< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -67330,7 +74140,8 @@ fn __action1571< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1341( + __action1389( + source_code, mode, __temp0, __4, @@ -67342,8 +74153,9 @@ fn __action1571< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1572< +fn __action1627< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67351,12 +74163,14 @@ fn __action1572< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1342( + __action1390( + source_code, mode, __temp0, __1, @@ -67365,8 +74179,9 @@ fn __action1572< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1573< +fn __action1628< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67376,14 +74191,16 @@ fn __action1573< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1342( + __action1390( + source_code, mode, __temp0, __3, @@ -67392,8 +74209,9 @@ fn __action1573< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1574< +fn __action1629< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67404,7 +74222,8 @@ fn __action1574< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -67412,7 +74231,8 @@ fn __action1574< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1342( + __action1390( + source_code, mode, __temp0, __4, @@ -67421,8 +74241,9 @@ fn __action1574< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1575< +fn __action1630< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67434,12 +74255,14 @@ fn __action1575< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1343( + __action1391( + source_code, mode, __temp0, __1, @@ -67452,8 +74275,9 @@ fn __action1575< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1576< +fn __action1631< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67467,14 +74291,16 @@ fn __action1576< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1343( + __action1391( + source_code, mode, __temp0, __3, @@ -67487,8 +74313,9 @@ fn __action1576< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1577< +fn __action1632< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67503,7 +74330,8 @@ fn __action1577< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -67511,7 +74339,8 @@ fn __action1577< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1343( + __action1391( + source_code, mode, __temp0, __4, @@ -67524,8 +74353,9 @@ fn __action1577< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1578< +fn __action1633< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67536,12 +74366,14 @@ fn __action1578< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1344( + __action1392( + source_code, mode, __temp0, __1, @@ -67553,8 +74385,9 @@ fn __action1578< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1579< +fn __action1634< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67567,14 +74400,16 @@ fn __action1579< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1344( + __action1392( + source_code, mode, __temp0, __3, @@ -67586,8 +74421,9 @@ fn __action1579< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1580< +fn __action1635< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67601,7 +74437,8 @@ fn __action1580< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -67609,7 +74446,8 @@ fn __action1580< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1344( + __action1392( + source_code, mode, __temp0, __4, @@ -67621,8 +74459,9 @@ fn __action1580< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1581< +fn __action1636< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67635,12 +74474,14 @@ fn __action1581< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1345( + __action1393( + source_code, mode, __temp0, __1, @@ -67654,8 +74495,9 @@ fn __action1581< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1582< +fn __action1637< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67670,14 +74512,16 @@ fn __action1582< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1345( + __action1393( + source_code, mode, __temp0, __3, @@ -67691,8 +74535,9 @@ fn __action1582< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1583< +fn __action1638< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67708,7 +74553,8 @@ fn __action1583< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -67716,7 +74562,8 @@ fn __action1583< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1345( + __action1393( + source_code, mode, __temp0, __4, @@ -67730,8 +74577,9 @@ fn __action1583< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1584< +fn __action1639< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67743,12 +74591,14 @@ fn __action1584< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1346( + __action1394( + source_code, mode, __temp0, __1, @@ -67761,8 +74611,9 @@ fn __action1584< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1585< +fn __action1640< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67776,14 +74627,16 @@ fn __action1585< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1346( + __action1394( + source_code, mode, __temp0, __3, @@ -67796,8 +74649,9 @@ fn __action1585< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1586< +fn __action1641< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67812,7 +74666,8 @@ fn __action1586< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -67820,7 +74675,8 @@ fn __action1586< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1346( + __action1394( + source_code, mode, __temp0, __4, @@ -67833,8 +74689,9 @@ fn __action1586< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1587< +fn __action1642< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67844,12 +74701,14 @@ fn __action1587< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1347( + __action1395( + source_code, mode, __temp0, __1, @@ -67860,8 +74719,9 @@ fn __action1587< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1588< +fn __action1643< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67873,14 +74733,16 @@ fn __action1588< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1347( + __action1395( + source_code, mode, __temp0, __3, @@ -67891,8 +74753,9 @@ fn __action1588< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1589< +fn __action1644< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67905,7 +74768,8 @@ fn __action1589< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -67913,7 +74777,8 @@ fn __action1589< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1347( + __action1395( + source_code, mode, __temp0, __4, @@ -67924,8 +74789,9 @@ fn __action1589< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1590< +fn __action1645< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67934,12 +74800,14 @@ fn __action1590< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1348( + __action1396( + source_code, mode, __temp0, __1, @@ -67949,8 +74817,9 @@ fn __action1590< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1591< +fn __action1646< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67961,14 +74830,16 @@ fn __action1591< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1348( + __action1396( + source_code, mode, __temp0, __3, @@ -67978,8 +74849,9 @@ fn __action1591< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1592< +fn __action1647< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -67991,7 +74863,8 @@ fn __action1592< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -67999,7 +74872,8 @@ fn __action1592< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1348( + __action1396( + source_code, mode, __temp0, __4, @@ -68009,8 +74883,9 @@ fn __action1592< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1593< +fn __action1648< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68021,12 +74896,14 @@ fn __action1593< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1349( + __action1397( + source_code, mode, __temp0, __1, @@ -68038,8 +74915,9 @@ fn __action1593< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1594< +fn __action1649< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68052,14 +74930,16 @@ fn __action1594< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1349( + __action1397( + source_code, mode, __temp0, __3, @@ -68071,8 +74951,9 @@ fn __action1594< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1595< +fn __action1650< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68086,7 +74967,8 @@ fn __action1595< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -68094,7 +74976,8 @@ fn __action1595< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1349( + __action1397( + source_code, mode, __temp0, __4, @@ -68106,8 +74989,9 @@ fn __action1595< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1596< +fn __action1651< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68117,12 +75001,14 @@ fn __action1596< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1350( + __action1398( + source_code, mode, __temp0, __1, @@ -68133,8 +75019,9 @@ fn __action1596< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1597< +fn __action1652< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68146,14 +75033,16 @@ fn __action1597< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1350( + __action1398( + source_code, mode, __temp0, __3, @@ -68164,8 +75053,9 @@ fn __action1597< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1598< +fn __action1653< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68178,7 +75068,8 @@ fn __action1598< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -68186,7 +75077,8 @@ fn __action1598< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1350( + __action1398( + source_code, mode, __temp0, __4, @@ -68197,20 +75089,23 @@ fn __action1598< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1599< +fn __action1654< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), ) -> Result> { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1351( + __action1399( + source_code, mode, __temp0, ) @@ -68218,8 +75113,9 @@ fn __action1599< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1600< +fn __action1655< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68228,14 +75124,16 @@ fn __action1600< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1351( + __action1399( + source_code, mode, __temp0, ) @@ -68243,8 +75141,9 @@ fn __action1600< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1601< +fn __action1656< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68254,7 +75153,8 @@ fn __action1601< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -68262,7 +75162,8 @@ fn __action1601< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1351( + __action1399( + source_code, mode, __temp0, ) @@ -68270,8 +75171,9 @@ fn __action1601< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1602< +fn __action1657< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68281,12 +75183,14 @@ fn __action1602< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1352( + __action1400( + source_code, mode, __temp0, __1, @@ -68297,8 +75201,9 @@ fn __action1602< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1603< +fn __action1658< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68310,14 +75215,16 @@ fn __action1603< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1352( + __action1400( + source_code, mode, __temp0, __3, @@ -68328,8 +75235,9 @@ fn __action1603< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1604< +fn __action1659< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68342,7 +75250,8 @@ fn __action1604< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -68350,7 +75259,8 @@ fn __action1604< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1352( + __action1400( + source_code, mode, __temp0, __4, @@ -68361,8 +75271,9 @@ fn __action1604< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1605< +fn __action1660< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68371,12 +75282,14 @@ fn __action1605< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action422( + let __temp0 = __action443( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1353( + __action1401( + source_code, mode, __temp0, __1, @@ -68386,8 +75299,9 @@ fn __action1605< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1606< +fn __action1661< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68398,14 +75312,16 @@ fn __action1606< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action673( + let __temp0 = __action698( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1353( + __action1401( + source_code, mode, __temp0, __3, @@ -68415,8 +75331,9 @@ fn __action1606< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1607< +fn __action1662< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68428,7 +75345,8 @@ fn __action1607< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action674( + let __temp0 = __action699( + source_code, mode, __0, __1, @@ -68436,7 +75354,8 @@ fn __action1607< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1353( + __action1401( + source_code, mode, __temp0, __4, @@ -68446,8 +75365,9 @@ fn __action1607< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1608< +fn __action1663< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68460,12 +75380,14 @@ fn __action1608< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1372( + __action1420( + source_code, mode, __temp0, __1, @@ -68479,8 +75401,9 @@ fn __action1608< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1609< +fn __action1664< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68495,14 +75418,16 @@ fn __action1609< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1372( + __action1420( + source_code, mode, __temp0, __3, @@ -68516,8 +75441,9 @@ fn __action1609< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1610< +fn __action1665< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68533,7 +75459,8 @@ fn __action1610< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -68541,7 +75468,8 @@ fn __action1610< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1372( + __action1420( + source_code, mode, __temp0, __4, @@ -68555,8 +75483,9 @@ fn __action1610< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1611< +fn __action1666< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68568,12 +75497,14 @@ fn __action1611< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1373( + __action1421( + source_code, mode, __temp0, __1, @@ -68586,8 +75517,9 @@ fn __action1611< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1612< +fn __action1667< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68601,14 +75533,16 @@ fn __action1612< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1373( + __action1421( + source_code, mode, __temp0, __3, @@ -68621,8 +75555,9 @@ fn __action1612< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1613< +fn __action1668< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68637,7 +75572,8 @@ fn __action1613< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -68645,7 +75581,8 @@ fn __action1613< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1373( + __action1421( + source_code, mode, __temp0, __4, @@ -68658,8 +75595,9 @@ fn __action1613< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1614< +fn __action1669< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68673,12 +75611,14 @@ fn __action1614< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1374( + __action1422( + source_code, mode, __temp0, __1, @@ -68693,8 +75633,9 @@ fn __action1614< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1615< +fn __action1670< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68710,14 +75651,16 @@ fn __action1615< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1374( + __action1422( + source_code, mode, __temp0, __3, @@ -68732,8 +75675,9 @@ fn __action1615< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1616< +fn __action1671< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68750,7 +75694,8 @@ fn __action1616< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -68758,7 +75703,8 @@ fn __action1616< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1374( + __action1422( + source_code, mode, __temp0, __4, @@ -68773,8 +75719,9 @@ fn __action1616< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1617< +fn __action1672< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68787,12 +75734,14 @@ fn __action1617< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1375( + __action1423( + source_code, mode, __temp0, __1, @@ -68806,8 +75755,9 @@ fn __action1617< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1618< +fn __action1673< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68822,14 +75772,16 @@ fn __action1618< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1375( + __action1423( + source_code, mode, __temp0, __3, @@ -68843,8 +75795,9 @@ fn __action1618< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1619< +fn __action1674< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68860,7 +75813,8 @@ fn __action1619< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -68868,7 +75822,8 @@ fn __action1619< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1375( + __action1423( + source_code, mode, __temp0, __4, @@ -68882,8 +75837,9 @@ fn __action1619< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1620< +fn __action1675< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68894,12 +75850,14 @@ fn __action1620< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1376( + __action1424( + source_code, mode, __temp0, __1, @@ -68911,8 +75869,9 @@ fn __action1620< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1621< +fn __action1676< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68925,14 +75884,16 @@ fn __action1621< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1376( + __action1424( + source_code, mode, __temp0, __3, @@ -68944,8 +75905,9 @@ fn __action1621< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1622< +fn __action1677< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68959,7 +75921,8 @@ fn __action1622< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -68967,7 +75930,8 @@ fn __action1622< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1376( + __action1424( + source_code, mode, __temp0, __4, @@ -68979,8 +75943,9 @@ fn __action1622< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1623< +fn __action1678< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -68990,12 +75955,14 @@ fn __action1623< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1377( + __action1425( + source_code, mode, __temp0, __1, @@ -69006,8 +75973,9 @@ fn __action1623< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1624< +fn __action1679< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69019,14 +75987,16 @@ fn __action1624< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1377( + __action1425( + source_code, mode, __temp0, __3, @@ -69037,8 +76007,9 @@ fn __action1624< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1625< +fn __action1680< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69051,7 +76022,8 @@ fn __action1625< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -69059,7 +76031,8 @@ fn __action1625< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1377( + __action1425( + source_code, mode, __temp0, __4, @@ -69070,8 +76043,9 @@ fn __action1625< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1626< +fn __action1681< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69083,12 +76057,14 @@ fn __action1626< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1378( + __action1426( + source_code, mode, __temp0, __1, @@ -69101,8 +76077,9 @@ fn __action1626< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1627< +fn __action1682< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69116,14 +76093,16 @@ fn __action1627< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1378( + __action1426( + source_code, mode, __temp0, __3, @@ -69136,8 +76115,9 @@ fn __action1627< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1628< +fn __action1683< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69152,7 +76132,8 @@ fn __action1628< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -69160,7 +76141,8 @@ fn __action1628< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1378( + __action1426( + source_code, mode, __temp0, __4, @@ -69173,8 +76155,9 @@ fn __action1628< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1629< +fn __action1684< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69185,12 +76168,14 @@ fn __action1629< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1379( + __action1427( + source_code, mode, __temp0, __1, @@ -69202,8 +76187,9 @@ fn __action1629< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1630< +fn __action1685< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69216,14 +76202,16 @@ fn __action1630< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1379( + __action1427( + source_code, mode, __temp0, __3, @@ -69235,8 +76223,9 @@ fn __action1630< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1631< +fn __action1686< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69250,7 +76239,8 @@ fn __action1631< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -69258,7 +76248,8 @@ fn __action1631< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1379( + __action1427( + source_code, mode, __temp0, __4, @@ -69270,8 +76261,9 @@ fn __action1631< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1632< +fn __action1687< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69279,12 +76271,14 @@ fn __action1632< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1380( + __action1428( + source_code, mode, __temp0, __1, @@ -69293,8 +76287,9 @@ fn __action1632< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1633< +fn __action1688< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69304,14 +76299,16 @@ fn __action1633< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1380( + __action1428( + source_code, mode, __temp0, __3, @@ -69320,8 +76317,9 @@ fn __action1633< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1634< +fn __action1689< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69332,7 +76330,8 @@ fn __action1634< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -69340,7 +76339,8 @@ fn __action1634< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1380( + __action1428( + source_code, mode, __temp0, __4, @@ -69349,8 +76349,9 @@ fn __action1634< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1635< +fn __action1690< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69362,12 +76363,14 @@ fn __action1635< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1381( + __action1429( + source_code, mode, __temp0, __1, @@ -69380,8 +76383,9 @@ fn __action1635< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1636< +fn __action1691< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69395,14 +76399,16 @@ fn __action1636< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1381( + __action1429( + source_code, mode, __temp0, __3, @@ -69415,8 +76421,9 @@ fn __action1636< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1637< +fn __action1692< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69431,7 +76438,8 @@ fn __action1637< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -69439,7 +76447,8 @@ fn __action1637< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1381( + __action1429( + source_code, mode, __temp0, __4, @@ -69452,8 +76461,9 @@ fn __action1637< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1638< +fn __action1693< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69464,12 +76474,14 @@ fn __action1638< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1382( + __action1430( + source_code, mode, __temp0, __1, @@ -69481,8 +76493,9 @@ fn __action1638< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1639< +fn __action1694< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69495,14 +76508,16 @@ fn __action1639< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1382( + __action1430( + source_code, mode, __temp0, __3, @@ -69514,8 +76529,9 @@ fn __action1639< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1640< +fn __action1695< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69529,7 +76545,8 @@ fn __action1640< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -69537,7 +76554,8 @@ fn __action1640< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1382( + __action1430( + source_code, mode, __temp0, __4, @@ -69549,8 +76567,9 @@ fn __action1640< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1641< +fn __action1696< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69563,12 +76582,14 @@ fn __action1641< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1383( + __action1431( + source_code, mode, __temp0, __1, @@ -69582,8 +76603,9 @@ fn __action1641< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1642< +fn __action1697< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69598,14 +76620,16 @@ fn __action1642< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1383( + __action1431( + source_code, mode, __temp0, __3, @@ -69619,8 +76643,9 @@ fn __action1642< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1643< +fn __action1698< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69636,7 +76661,8 @@ fn __action1643< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -69644,7 +76670,8 @@ fn __action1643< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1383( + __action1431( + source_code, mode, __temp0, __4, @@ -69658,8 +76685,9 @@ fn __action1643< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1644< +fn __action1699< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69671,12 +76699,14 @@ fn __action1644< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1384( + __action1432( + source_code, mode, __temp0, __1, @@ -69689,8 +76719,9 @@ fn __action1644< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1645< +fn __action1700< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69704,14 +76735,16 @@ fn __action1645< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1384( + __action1432( + source_code, mode, __temp0, __3, @@ -69724,8 +76757,9 @@ fn __action1645< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1646< +fn __action1701< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69740,7 +76774,8 @@ fn __action1646< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -69748,7 +76783,8 @@ fn __action1646< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1384( + __action1432( + source_code, mode, __temp0, __4, @@ -69761,8 +76797,9 @@ fn __action1646< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1647< +fn __action1702< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69772,12 +76809,14 @@ fn __action1647< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1385( + __action1433( + source_code, mode, __temp0, __1, @@ -69788,8 +76827,9 @@ fn __action1647< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1648< +fn __action1703< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69801,14 +76841,16 @@ fn __action1648< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1385( + __action1433( + source_code, mode, __temp0, __3, @@ -69819,8 +76861,9 @@ fn __action1648< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1649< +fn __action1704< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69833,7 +76876,8 @@ fn __action1649< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -69841,7 +76885,8 @@ fn __action1649< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1385( + __action1433( + source_code, mode, __temp0, __4, @@ -69852,8 +76897,9 @@ fn __action1649< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1650< +fn __action1705< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69862,12 +76908,14 @@ fn __action1650< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1386( + __action1434( + source_code, mode, __temp0, __1, @@ -69877,8 +76925,9 @@ fn __action1650< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1651< +fn __action1706< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69889,14 +76938,16 @@ fn __action1651< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1386( + __action1434( + source_code, mode, __temp0, __3, @@ -69906,8 +76957,9 @@ fn __action1651< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1652< +fn __action1707< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69919,7 +76971,8 @@ fn __action1652< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -69927,7 +76980,8 @@ fn __action1652< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1386( + __action1434( + source_code, mode, __temp0, __4, @@ -69937,8 +76991,9 @@ fn __action1652< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1653< +fn __action1708< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69949,12 +77004,14 @@ fn __action1653< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1387( + __action1435( + source_code, mode, __temp0, __1, @@ -69966,8 +77023,9 @@ fn __action1653< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1654< +fn __action1709< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -69980,14 +77038,16 @@ fn __action1654< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1387( + __action1435( + source_code, mode, __temp0, __3, @@ -69999,8 +77059,9 @@ fn __action1654< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1655< +fn __action1710< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70014,7 +77075,8 @@ fn __action1655< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -70022,7 +77084,8 @@ fn __action1655< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1387( + __action1435( + source_code, mode, __temp0, __4, @@ -70034,8 +77097,9 @@ fn __action1655< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1656< +fn __action1711< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70045,12 +77109,14 @@ fn __action1656< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1388( + __action1436( + source_code, mode, __temp0, __1, @@ -70061,8 +77127,9 @@ fn __action1656< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1657< +fn __action1712< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70074,14 +77141,16 @@ fn __action1657< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1388( + __action1436( + source_code, mode, __temp0, __3, @@ -70092,8 +77161,9 @@ fn __action1657< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1658< +fn __action1713< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70106,7 +77176,8 @@ fn __action1658< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -70114,7 +77185,8 @@ fn __action1658< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1388( + __action1436( + source_code, mode, __temp0, __4, @@ -70125,20 +77197,23 @@ fn __action1658< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1659< +fn __action1714< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), ) -> Result> { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1389( + __action1437( + source_code, mode, __temp0, ) @@ -70146,8 +77221,9 @@ fn __action1659< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1660< +fn __action1715< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70156,14 +77232,16 @@ fn __action1660< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1389( + __action1437( + source_code, mode, __temp0, ) @@ -70171,8 +77249,9 @@ fn __action1660< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1661< +fn __action1716< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70182,7 +77261,8 @@ fn __action1661< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -70190,7 +77270,8 @@ fn __action1661< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1389( + __action1437( + source_code, mode, __temp0, ) @@ -70198,8 +77279,9 @@ fn __action1661< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1662< +fn __action1717< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70209,12 +77291,14 @@ fn __action1662< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1390( + __action1438( + source_code, mode, __temp0, __1, @@ -70225,8 +77309,9 @@ fn __action1662< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1663< +fn __action1718< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70238,14 +77323,16 @@ fn __action1663< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1390( + __action1438( + source_code, mode, __temp0, __3, @@ -70256,8 +77343,9 @@ fn __action1663< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1664< +fn __action1719< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70270,7 +77358,8 @@ fn __action1664< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -70278,7 +77367,8 @@ fn __action1664< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1390( + __action1438( + source_code, mode, __temp0, __4, @@ -70289,8 +77379,9 @@ fn __action1664< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1665< +fn __action1720< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70299,12 +77390,14 @@ fn __action1665< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action430( + let __temp0 = __action451( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1391( + __action1439( + source_code, mode, __temp0, __1, @@ -70314,8 +77407,9 @@ fn __action1665< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1666< +fn __action1721< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70326,14 +77420,16 @@ fn __action1666< { let __start0 = __0.0; let __end0 = __2.2; - let __temp0 = __action681( + let __temp0 = __action706( + source_code, mode, __0, __1, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1391( + __action1439( + source_code, mode, __temp0, __3, @@ -70343,8 +77439,9 @@ fn __action1666< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1667< +fn __action1722< >( + source_code: &str, mode: Mode, __0: (TextSize, Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70356,7 +77453,8 @@ fn __action1667< { let __start0 = __0.0; let __end0 = __3.2; - let __temp0 = __action682( + let __temp0 = __action707( + source_code, mode, __0, __1, @@ -70364,7 +77462,8 @@ fn __action1667< __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1391( + __action1439( + source_code, mode, __temp0, __4, @@ -70374,62 +77473,73 @@ fn __action1667< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1668< +fn __action1723< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Parameters, TextSize), __2: (TextSize, token::Tok, TextSize), - __3: (TextSize, ast::ParenthesizedExpr, TextSize), + __3: (TextSize, core::option::Option<(String, bool)>, TextSize), + __4: (TextSize, ast::ParenthesizedExpr, TextSize), ) -> Result> { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action258( + let __temp0 = __action278( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1303( + __action1347( + source_code, mode, __0, __temp0, __2, __3, + __4, ) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1669< +fn __action1724< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), - __2: (TextSize, ast::ParenthesizedExpr, TextSize), + __2: (TextSize, core::option::Option<(String, bool)>, TextSize), + __3: (TextSize, ast::ParenthesizedExpr, TextSize), ) -> Result> { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action259( + let __temp0 = __action279( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1303( + __action1347( + source_code, mode, __0, __temp0, __1, __2, + __3, ) } #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1670< +fn __action1725< >( + source_code: &str, mode: Mode, __0: (TextSize, core::option::Option, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70439,12 +77549,14 @@ fn __action1670< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action254( + let __temp0 = __action272( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1442( + __action1491( + source_code, mode, __0, __1, @@ -70455,8 +77567,9 @@ fn __action1670< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1671< +fn __action1726< >( + source_code: &str, mode: Mode, __0: (TextSize, core::option::Option, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70465,13 +77578,15 @@ fn __action1671< { let __start0 = __2.2; let __end0 = __2.2; - let __temp0 = __action255( + let __temp0 = __action273( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1442( + __action1491( + source_code, mode, __0, __1, @@ -70482,8 +77597,9 @@ fn __action1671< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1672< +fn __action1727< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -70493,12 +77609,14 @@ fn __action1672< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action302( + let __temp0 = __action322( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action769( + __action793( + source_code, mode, __0, __temp0, @@ -70509,8 +77627,9 @@ fn __action1672< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1673< +fn __action1728< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70519,13 +77638,15 @@ fn __action1673< { let __start0 = __0.2; let __end0 = __1.0; - let __temp0 = __action303( + let __temp0 = __action323( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action769( + __action793( + source_code, mode, __0, __temp0, @@ -70536,8 +77657,9 @@ fn __action1673< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1674< +fn __action1729< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -70545,12 +77667,14 @@ fn __action1674< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action302( + let __temp0 = __action322( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action899( + __action929( + source_code, mode, __0, __temp0, @@ -70559,21 +77683,24 @@ fn __action1674< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1675< +fn __action1730< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> Option { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action303( + let __temp0 = __action323( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action899( + __action929( + source_code, mode, __0, __temp0, @@ -70582,8 +77709,9 @@ fn __action1675< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1676< +fn __action1731< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70595,17 +77723,20 @@ fn __action1676< let __end0 = __0.2; let __start1 = __2.0; let __end1 = __2.2; - let __temp0 = __action302( + let __temp0 = __action322( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action302( + let __temp1 = __action322( + source_code, mode, __2, ); let __temp1 = (__start1, __temp1, __end1); - __action1670( + __action1725( + source_code, mode, __temp0, __1, @@ -70616,8 +77747,9 @@ fn __action1676< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1677< +fn __action1732< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70628,18 +77760,21 @@ fn __action1677< let __end0 = __0.2; let __start1 = __1.2; let __end1 = __2.0; - let __temp0 = __action302( + let __temp0 = __action322( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action303( + let __temp1 = __action323( + source_code, mode, &__start1, &__end1, ); let __temp1 = (__start1, __temp1, __end1); - __action1670( + __action1725( + source_code, mode, __temp0, __1, @@ -70650,8 +77785,9 @@ fn __action1677< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1678< +fn __action1733< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -70662,18 +77798,21 @@ fn __action1678< let __end0 = __0.0; let __start1 = __1.0; let __end1 = __1.2; - let __temp0 = __action303( + let __temp0 = __action323( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action302( + let __temp1 = __action322( + source_code, mode, __1, ); let __temp1 = (__start1, __temp1, __end1); - __action1670( + __action1725( + source_code, mode, __temp0, __0, @@ -70684,8 +77823,9 @@ fn __action1678< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1679< +fn __action1734< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, Option, TextSize), @@ -70695,19 +77835,22 @@ fn __action1679< let __end0 = __0.0; let __start1 = __0.2; let __end1 = __1.0; - let __temp0 = __action303( + let __temp0 = __action323( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action303( + let __temp1 = __action323( + source_code, mode, &__start1, &__end1, ); let __temp1 = (__start1, __temp1, __end1); - __action1670( + __action1725( + source_code, mode, __temp0, __0, @@ -70718,8 +77861,9 @@ fn __action1679< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1680< +fn __action1735< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70730,17 +77874,20 @@ fn __action1680< let __end0 = __0.2; let __start1 = __2.0; let __end1 = __2.2; - let __temp0 = __action302( + let __temp0 = __action322( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action302( + let __temp1 = __action322( + source_code, mode, __2, ); let __temp1 = (__start1, __temp1, __end1); - __action1671( + __action1726( + source_code, mode, __temp0, __1, @@ -70750,8 +77897,9 @@ fn __action1680< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1681< +fn __action1736< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70761,18 +77909,21 @@ fn __action1681< let __end0 = __0.2; let __start1 = __1.2; let __end1 = __1.2; - let __temp0 = __action302( + let __temp0 = __action322( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action303( + let __temp1 = __action323( + source_code, mode, &__start1, &__end1, ); let __temp1 = (__start1, __temp1, __end1); - __action1671( + __action1726( + source_code, mode, __temp0, __1, @@ -70782,8 +77933,9 @@ fn __action1681< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1682< +fn __action1737< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -70793,18 +77945,21 @@ fn __action1682< let __end0 = __0.0; let __start1 = __1.0; let __end1 = __1.2; - let __temp0 = __action303( + let __temp0 = __action323( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action302( + let __temp1 = __action322( + source_code, mode, __1, ); let __temp1 = (__start1, __temp1, __end1); - __action1671( + __action1726( + source_code, mode, __temp0, __0, @@ -70814,8 +77969,9 @@ fn __action1682< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1683< +fn __action1738< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::ParenthesizedExpr @@ -70824,19 +77980,22 @@ fn __action1683< let __end0 = __0.0; let __start1 = __0.2; let __end1 = __0.2; - let __temp0 = __action303( + let __temp0 = __action323( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - let __temp1 = __action303( + let __temp1 = __action323( + source_code, mode, &__start1, &__end1, ); let __temp1 = (__start1, __temp1, __end1); - __action1671( + __action1726( + source_code, mode, __temp0, __0, @@ -70846,8 +78005,9 @@ fn __action1683< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1684< +fn __action1739< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70863,12 +78023,14 @@ fn __action1684< { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action222( + let __temp0 = __action232( + source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action1093( + __action1124( + source_code, mode, __0, __1, @@ -70885,8 +78047,9 @@ fn __action1684< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1685< +fn __action1740< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -70899,12 +78062,14 @@ fn __action1685< { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action222( + let __temp0 = __action232( + source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action1094( + __action1125( + source_code, mode, __0, __1, @@ -70918,8 +78083,9 @@ fn __action1685< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1686< +fn __action1741< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -70934,12 +78100,14 @@ fn __action1686< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action222( + let __temp0 = __action232( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1095( + __action1126( + source_code, mode, __0, __1, @@ -70955,8 +78123,9 @@ fn __action1686< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1687< +fn __action1742< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -70968,12 +78137,14 @@ fn __action1687< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action222( + let __temp0 = __action232( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1096( + __action1127( + source_code, mode, __0, __1, @@ -70986,20 +78157,23 @@ fn __action1687< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1688< +fn __action1743< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), ) -> core::option::Option { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action222( + let __temp0 = __action232( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action375( + __action396( + source_code, mode, __temp0, ) @@ -71007,20 +78181,23 @@ fn __action1688< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1689< +fn __action1744< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action222( + let __temp0 = __action232( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); __action31( + source_code, mode, __temp0, ) @@ -71028,20 +78205,23 @@ fn __action1689< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1690< +fn __action1745< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action222( + let __temp0 = __action232( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); __action33( + source_code, mode, __temp0, ) @@ -71049,8 +78229,9 @@ fn __action1690< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1691< +fn __action1746< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -71058,12 +78239,14 @@ fn __action1691< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action222( + let __temp0 = __action232( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1451( + __action1500( + source_code, mode, __0, __temp0, @@ -71072,8 +78255,9 @@ fn __action1691< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1692< +fn __action1747< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -71082,12 +78266,14 @@ fn __action1692< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action222( + let __temp0 = __action232( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1452( + __action1501( + source_code, mode, __0, __temp0, @@ -71097,8 +78283,9 @@ fn __action1692< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1693< +fn __action1748< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -71106,12 +78293,14 @@ fn __action1693< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action1688( + let __temp0 = __action1743( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1278( + __action1322( + source_code, mode, __0, __temp0, @@ -71120,21 +78309,24 @@ fn __action1693< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1694< +fn __action1749< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::Stmt { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action376( + let __temp0 = __action397( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1278( + __action1322( + source_code, mode, __0, __temp0, @@ -71143,8 +78335,9 @@ fn __action1694< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1695< +fn __action1750< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::ParenthesizedExpr, TextSize), @@ -71152,12 +78345,14 @@ fn __action1695< { let __start0 = __1.0; let __end0 = __1.2; - let __temp0 = __action1688( + let __temp0 = __action1743( + source_code, mode, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action1476( + __action1525( + source_code, mode, __0, __temp0, @@ -71166,21 +78361,24 @@ fn __action1695< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1696< +fn __action1751< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), ) -> ast::ParenthesizedExpr { let __start0 = __0.2; let __end0 = __0.2; - let __temp0 = __action376( + let __temp0 = __action397( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1476( + __action1525( + source_code, mode, __0, __temp0, @@ -71189,20 +78387,23 @@ fn __action1696< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1697< +fn __action1752< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), ) -> ast::Stmt { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action1690( + let __temp0 = __action1745( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1490( + __action1529( + source_code, mode, __temp0, ) @@ -71210,8 +78411,9 @@ fn __action1697< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1698< +fn __action1753< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, alloc::vec::Vec, TextSize), @@ -71219,12 +78421,14 @@ fn __action1698< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action1690( + let __temp0 = __action1745( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1491( + __action1530( + source_code, mode, __temp0, __1, @@ -71233,8 +78437,9 @@ fn __action1698< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1699< +fn __action1754< >( + source_code: &str, mode: Mode, __0: (TextSize, ast::ParenthesizedExpr, TextSize), __1: (TextSize, ast::Operator, TextSize), @@ -71243,12 +78448,14 @@ fn __action1699< { let __start0 = __0.0; let __end0 = __0.2; - let __temp0 = __action1690( + let __temp0 = __action1745( + source_code, mode, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action1272( + __action1312( + source_code, mode, __temp0, __1, @@ -71258,8 +78465,9 @@ fn __action1699< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1700< +fn __action1755< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -71271,12 +78479,14 @@ fn __action1700< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action284( + let __temp0 = __action304( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1516( + __action1555( + source_code, mode, __0, __1, @@ -71289,8 +78499,9 @@ fn __action1700< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1701< +fn __action1756< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -71301,13 +78512,15 @@ fn __action1701< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action285( + let __temp0 = __action305( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1516( + __action1555( + source_code, mode, __0, __1, @@ -71320,8 +78533,9 @@ fn __action1701< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1702< +fn __action1757< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -71334,12 +78548,14 @@ fn __action1702< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action284( + let __temp0 = __action304( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1517( + __action1556( + source_code, mode, __0, __1, @@ -71353,8 +78569,9 @@ fn __action1702< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1703< +fn __action1758< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -71366,13 +78583,15 @@ fn __action1703< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action285( + let __temp0 = __action305( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1517( + __action1556( + source_code, mode, __0, __1, @@ -71386,8 +78605,9 @@ fn __action1703< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1704< +fn __action1759< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -71398,12 +78618,14 @@ fn __action1704< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action284( + let __temp0 = __action304( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1518( + __action1557( + source_code, mode, __0, __1, @@ -71415,8 +78637,9 @@ fn __action1704< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1705< +fn __action1760< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -71426,13 +78649,15 @@ fn __action1705< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action285( + let __temp0 = __action305( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1518( + __action1557( + source_code, mode, __0, __1, @@ -71444,8 +78669,9 @@ fn __action1705< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1706< +fn __action1761< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -71457,12 +78683,14 @@ fn __action1706< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action284( + let __temp0 = __action304( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1519( + __action1558( + source_code, mode, __0, __1, @@ -71475,8 +78703,9 @@ fn __action1706< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1707< +fn __action1762< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -71487,13 +78716,15 @@ fn __action1707< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action285( + let __temp0 = __action305( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1519( + __action1558( + source_code, mode, __0, __1, @@ -71506,8 +78737,9 @@ fn __action1707< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1708< +fn __action1763< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -71522,12 +78754,14 @@ fn __action1708< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action284( + let __temp0 = __action304( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1520( + __action1559( + source_code, mode, __0, __1, @@ -71543,8 +78777,9 @@ fn __action1708< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1709< +fn __action1764< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -71558,13 +78793,15 @@ fn __action1709< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action285( + let __temp0 = __action305( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1520( + __action1559( + source_code, mode, __0, __1, @@ -71580,8 +78817,9 @@ fn __action1709< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1710< +fn __action1765< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -71597,12 +78835,14 @@ fn __action1710< { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action284( + let __temp0 = __action304( + source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action1521( + __action1560( + source_code, mode, __0, __1, @@ -71619,8 +78859,9 @@ fn __action1710< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1711< +fn __action1766< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -71635,13 +78876,15 @@ fn __action1711< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action285( + let __temp0 = __action305( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1521( + __action1560( + source_code, mode, __0, __1, @@ -71658,8 +78901,9 @@ fn __action1711< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1712< +fn __action1767< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -71672,12 +78916,14 @@ fn __action1712< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action284( + let __temp0 = __action304( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1522( + __action1561( + source_code, mode, __0, __1, @@ -71691,8 +78937,9 @@ fn __action1712< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1713< +fn __action1768< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -71704,13 +78951,15 @@ fn __action1713< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action285( + let __temp0 = __action305( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1522( + __action1561( + source_code, mode, __0, __1, @@ -71724,8 +78973,9 @@ fn __action1713< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1714< +fn __action1769< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -71739,12 +78989,14 @@ fn __action1714< { let __start0 = __4.0; let __end0 = __4.2; - let __temp0 = __action284( + let __temp0 = __action304( + source_code, mode, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action1523( + __action1562( + source_code, mode, __0, __1, @@ -71759,8 +79011,9 @@ fn __action1714< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1715< +fn __action1770< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -71773,13 +79026,15 @@ fn __action1715< { let __start0 = __3.2; let __end0 = __4.0; - let __temp0 = __action285( + let __temp0 = __action305( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1523( + __action1562( + source_code, mode, __0, __1, @@ -71794,8 +79049,9 @@ fn __action1715< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1716< +fn __action1771< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -71809,12 +79065,14 @@ fn __action1716< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action284( + let __temp0 = __action304( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1524( + __action1563( + source_code, mode, __0, __1, @@ -71829,8 +79087,9 @@ fn __action1716< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1717< +fn __action1772< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -71843,13 +79102,15 @@ fn __action1717< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action285( + let __temp0 = __action305( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1524( + __action1563( + source_code, mode, __0, __1, @@ -71864,8 +79125,9 @@ fn __action1717< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1718< +fn __action1773< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -71880,12 +79142,14 @@ fn __action1718< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action284( + let __temp0 = __action304( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1525( + __action1564( + source_code, mode, __0, __1, @@ -71901,8 +79165,9 @@ fn __action1718< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1719< +fn __action1774< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -71916,13 +79181,15 @@ fn __action1719< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action285( + let __temp0 = __action305( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1525( + __action1564( + source_code, mode, __0, __1, @@ -71938,8 +79205,9 @@ fn __action1719< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1720< +fn __action1775< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -71951,12 +79219,14 @@ fn __action1720< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action284( + let __temp0 = __action304( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1526( + __action1565( + source_code, mode, __0, __1, @@ -71969,8 +79239,9 @@ fn __action1720< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1721< +fn __action1776< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Identifier, TextSize), @@ -71981,13 +79252,15 @@ fn __action1721< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action285( + let __temp0 = __action305( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1526( + __action1565( + source_code, mode, __0, __1, @@ -72000,8 +79273,9 @@ fn __action1721< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1722< +fn __action1777< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -72014,12 +79288,14 @@ fn __action1722< { let __start0 = __3.0; let __end0 = __3.2; - let __temp0 = __action284( + let __temp0 = __action304( + source_code, mode, __3, ); let __temp0 = (__start0, __temp0, __end0); - __action1527( + __action1566( + source_code, mode, __0, __1, @@ -72033,8 +79309,9 @@ fn __action1722< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1723< +fn __action1778< >( + source_code: &str, mode: Mode, __0: (TextSize, alloc::vec::Vec, TextSize), __1: (TextSize, token::Tok, TextSize), @@ -72046,13 +79323,15 @@ fn __action1723< { let __start0 = __2.2; let __end0 = __3.0; - let __temp0 = __action285( + let __temp0 = __action305( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1527( + __action1566( + source_code, mode, __0, __1, @@ -72066,8 +79345,9 @@ fn __action1723< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1724< +fn __action1779< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Expr, TextSize), @@ -72078,12 +79358,14 @@ fn __action1724< { let __start0 = __2.0; let __end0 = __2.2; - let __temp0 = __action284( + let __temp0 = __action304( + source_code, mode, __2, ); let __temp0 = (__start0, __temp0, __end0); - __action1462( + __action1511( + source_code, mode, __0, __1, @@ -72095,8 +79377,9 @@ fn __action1724< #[allow(unused_variables)] #[allow(clippy::too_many_arguments)] -fn __action1725< +fn __action1780< >( + source_code: &str, mode: Mode, __0: (TextSize, token::Tok, TextSize), __1: (TextSize, ast::Expr, TextSize), @@ -72106,13 +79389,15 @@ fn __action1725< { let __start0 = __1.2; let __end0 = __2.0; - let __temp0 = __action285( + let __temp0 = __action305( + source_code, mode, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action1462( + __action1511( + source_code, mode, __0, __1, @@ -72121,6 +79406,130 @@ fn __action1725< __3, ) } + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1781< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::Parameters, TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, (String, bool), TextSize), + __4: (TextSize, ast::ParenthesizedExpr, TextSize), +) -> Result> +{ + let __start0 = __3.0; + let __end0 = __3.2; + let __temp0 = __action276( + source_code, + mode, + __3, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1723( + source_code, + mode, + __0, + __1, + __2, + __temp0, + __4, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1782< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, ast::Parameters, TextSize), + __2: (TextSize, token::Tok, TextSize), + __3: (TextSize, ast::ParenthesizedExpr, TextSize), +) -> Result> +{ + let __start0 = __2.2; + let __end0 = __3.0; + let __temp0 = __action277( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1723( + source_code, + mode, + __0, + __1, + __2, + __temp0, + __3, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1783< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, token::Tok, TextSize), + __2: (TextSize, (String, bool), TextSize), + __3: (TextSize, ast::ParenthesizedExpr, TextSize), +) -> Result> +{ + let __start0 = __2.0; + let __end0 = __2.2; + let __temp0 = __action276( + source_code, + mode, + __2, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1724( + source_code, + mode, + __0, + __1, + __temp0, + __3, + ) +} + +#[allow(unused_variables)] +#[allow(clippy::too_many_arguments)] +fn __action1784< +>( + source_code: &str, + mode: Mode, + __0: (TextSize, token::Tok, TextSize), + __1: (TextSize, token::Tok, TextSize), + __2: (TextSize, ast::ParenthesizedExpr, TextSize), +) -> Result> +{ + let __start0 = __1.2; + let __end0 = __2.0; + let __temp0 = __action277( + source_code, + mode, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action1724( + source_code, + mode, + __0, + __1, + __temp0, + __2, + ) +} #[allow(clippy::type_complexity)] pub trait __ToTriple<> diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__empty_fstrings.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__empty_fstrings.snap new file mode 100644 index 0000000000000..6f56991ade231 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__empty_fstrings.snap @@ -0,0 +1,66 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + FStringEnd, + 2..3, + ), + ( + String { + value: "", + kind: String, + triple_quoted: false, + }, + 4..6, + ), + ( + FStringStart, + 7..9, + ), + ( + FStringEnd, + 9..10, + ), + ( + FStringStart, + 11..13, + ), + ( + FStringEnd, + 13..14, + ), + ( + String { + value: "", + kind: String, + triple_quoted: false, + }, + 15..17, + ), + ( + FStringStart, + 18..22, + ), + ( + FStringEnd, + 22..25, + ), + ( + FStringStart, + 26..30, + ), + ( + FStringEnd, + 30..33, + ), + ( + Newline, + 33..33, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring.snap new file mode 100644 index 0000000000000..cc415cb5ccd61 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring.snap @@ -0,0 +1,88 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + FStringMiddle { + value: "normal ", + is_raw: false, + }, + 2..9, + ), + ( + Lbrace, + 9..10, + ), + ( + Name { + name: "foo", + }, + 10..13, + ), + ( + Rbrace, + 13..14, + ), + ( + FStringMiddle { + value: " {another} ", + is_raw: false, + }, + 14..27, + ), + ( + Lbrace, + 27..28, + ), + ( + Name { + name: "bar", + }, + 28..31, + ), + ( + Rbrace, + 31..32, + ), + ( + FStringMiddle { + value: " {", + is_raw: false, + }, + 32..35, + ), + ( + Lbrace, + 35..36, + ), + ( + Name { + name: "three", + }, + 36..41, + ), + ( + Rbrace, + 41..42, + ), + ( + FStringMiddle { + value: "}", + is_raw: false, + }, + 42..44, + ), + ( + FStringEnd, + 44..45, + ), + ( + Newline, + 45..45, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_comments.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_comments.snap new file mode 100644 index 0000000000000..b0427ad58fe64 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_comments.snap @@ -0,0 +1,60 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..4, + ), + ( + FStringMiddle { + value: "\n# not a comment ", + is_raw: false, + }, + 4..21, + ), + ( + Lbrace, + 21..22, + ), + ( + Comment( + "# comment {", + ), + 23..34, + ), + ( + NonLogicalNewline, + 34..35, + ), + ( + Name { + name: "x", + }, + 39..40, + ), + ( + NonLogicalNewline, + 40..41, + ), + ( + Rbrace, + 41..42, + ), + ( + FStringMiddle { + value: " # not a comment\n", + is_raw: false, + }, + 42..59, + ), + ( + FStringEnd, + 59..62, + ), + ( + Newline, + 62..62, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_conversion.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_conversion.snap new file mode 100644 index 0000000000000..d52a1772889d1 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_conversion.snap @@ -0,0 +1,116 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + Lbrace, + 2..3, + ), + ( + Name { + name: "x", + }, + 3..4, + ), + ( + Exclamation, + 4..5, + ), + ( + Name { + name: "s", + }, + 5..6, + ), + ( + Rbrace, + 6..7, + ), + ( + FStringMiddle { + value: " ", + is_raw: false, + }, + 7..8, + ), + ( + Lbrace, + 8..9, + ), + ( + Name { + name: "x", + }, + 9..10, + ), + ( + Equal, + 10..11, + ), + ( + Exclamation, + 11..12, + ), + ( + Name { + name: "r", + }, + 12..13, + ), + ( + Rbrace, + 13..14, + ), + ( + FStringMiddle { + value: " ", + is_raw: false, + }, + 14..15, + ), + ( + Lbrace, + 15..16, + ), + ( + Name { + name: "x", + }, + 16..17, + ), + ( + Colon, + 17..18, + ), + ( + FStringMiddle { + value: ".3f!r", + is_raw: false, + }, + 18..23, + ), + ( + Rbrace, + 23..24, + ), + ( + FStringMiddle { + value: " {x!r}", + is_raw: false, + }, + 24..32, + ), + ( + FStringEnd, + 32..33, + ), + ( + Newline, + 33..33, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_escape.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_escape.snap new file mode 100644 index 0000000000000..886c384db2fa8 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_escape.snap @@ -0,0 +1,71 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + FStringMiddle { + value: "\\", + is_raw: false, + }, + 2..3, + ), + ( + Lbrace, + 3..4, + ), + ( + Name { + name: "x", + }, + 4..5, + ), + ( + Colon, + 5..6, + ), + ( + FStringMiddle { + value: "\\\"\\", + is_raw: false, + }, + 6..9, + ), + ( + Lbrace, + 9..10, + ), + ( + Name { + name: "x", + }, + 10..11, + ), + ( + Rbrace, + 11..12, + ), + ( + Rbrace, + 12..13, + ), + ( + FStringMiddle { + value: " \\\"\\\"\\\n end", + is_raw: false, + }, + 13..24, + ), + ( + FStringEnd, + 24..25, + ), + ( + Newline, + 25..25, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_escape_braces.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_escape_braces.snap new file mode 100644 index 0000000000000..d0d44618e02d6 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_escape_braces.snap @@ -0,0 +1,98 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + FStringMiddle { + value: "\\", + is_raw: false, + }, + 2..3, + ), + ( + Lbrace, + 3..4, + ), + ( + Name { + name: "foo", + }, + 4..7, + ), + ( + Rbrace, + 7..8, + ), + ( + FStringEnd, + 8..9, + ), + ( + FStringStart, + 10..12, + ), + ( + FStringMiddle { + value: "\\\\", + is_raw: false, + }, + 12..14, + ), + ( + Lbrace, + 14..15, + ), + ( + Name { + name: "foo", + }, + 15..18, + ), + ( + Rbrace, + 18..19, + ), + ( + FStringEnd, + 19..20, + ), + ( + FStringStart, + 21..23, + ), + ( + FStringMiddle { + value: "\\{foo}", + is_raw: false, + }, + 23..31, + ), + ( + FStringEnd, + 31..32, + ), + ( + FStringStart, + 33..35, + ), + ( + FStringMiddle { + value: "\\\\{foo}", + is_raw: false, + }, + 35..44, + ), + ( + FStringEnd, + 44..45, + ), + ( + Newline, + 45..45, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_escape_raw.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_escape_raw.snap new file mode 100644 index 0000000000000..b5ee34faa81df --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_escape_raw.snap @@ -0,0 +1,71 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..3, + ), + ( + FStringMiddle { + value: "\\", + is_raw: true, + }, + 3..4, + ), + ( + Lbrace, + 4..5, + ), + ( + Name { + name: "x", + }, + 5..6, + ), + ( + Colon, + 6..7, + ), + ( + FStringMiddle { + value: "\\\"\\", + is_raw: true, + }, + 7..10, + ), + ( + Lbrace, + 10..11, + ), + ( + Name { + name: "x", + }, + 11..12, + ), + ( + Rbrace, + 12..13, + ), + ( + Rbrace, + 13..14, + ), + ( + FStringMiddle { + value: " \\\"\\\"\\\n end", + is_raw: true, + }, + 14..25, + ), + ( + FStringEnd, + 25..26, + ), + ( + Newline, + 26..26, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_expression_multiline.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_expression_multiline.snap new file mode 100644 index 0000000000000..e6f6703a3ca76 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_expression_multiline.snap @@ -0,0 +1,72 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + FStringMiddle { + value: "first ", + is_raw: false, + }, + 2..8, + ), + ( + Lbrace, + 8..9, + ), + ( + NonLogicalNewline, + 9..10, + ), + ( + Name { + name: "x", + }, + 14..15, + ), + ( + NonLogicalNewline, + 15..16, + ), + ( + Star, + 24..25, + ), + ( + NonLogicalNewline, + 25..26, + ), + ( + Name { + name: "y", + }, + 38..39, + ), + ( + NonLogicalNewline, + 39..40, + ), + ( + Rbrace, + 40..41, + ), + ( + FStringMiddle { + value: " second", + is_raw: false, + }, + 41..48, + ), + ( + FStringEnd, + 48..49, + ), + ( + Newline, + 49..49, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_multiline.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_multiline.snap new file mode 100644 index 0000000000000..0b89f0e51d83e --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_multiline.snap @@ -0,0 +1,99 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..4, + ), + ( + FStringMiddle { + value: "\nhello\n world\n", + is_raw: false, + }, + 4..21, + ), + ( + FStringEnd, + 21..24, + ), + ( + FStringStart, + 25..29, + ), + ( + FStringMiddle { + value: "\n world\nhello\n", + is_raw: false, + }, + 29..46, + ), + ( + FStringEnd, + 46..49, + ), + ( + FStringStart, + 50..52, + ), + ( + FStringMiddle { + value: "some ", + is_raw: false, + }, + 52..57, + ), + ( + Lbrace, + 57..58, + ), + ( + FStringStart, + 58..62, + ), + ( + FStringMiddle { + value: "multiline\nallowed ", + is_raw: false, + }, + 62..80, + ), + ( + Lbrace, + 80..81, + ), + ( + Name { + name: "x", + }, + 81..82, + ), + ( + Rbrace, + 82..83, + ), + ( + FStringEnd, + 83..86, + ), + ( + Rbrace, + 86..87, + ), + ( + FStringMiddle { + value: " string", + is_raw: false, + }, + 87..94, + ), + ( + FStringEnd, + 94..95, + ), + ( + Newline, + 95..95, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_named_unicode.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_named_unicode.snap new file mode 100644 index 0000000000000..0a9392ee7d415 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_named_unicode.snap @@ -0,0 +1,25 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + FStringMiddle { + value: "\\N{BULLET} normal \\Nope \\N", + is_raw: false, + }, + 2..28, + ), + ( + FStringEnd, + 28..29, + ), + ( + Newline, + 29..29, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_named_unicode_raw.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_named_unicode_raw.snap new file mode 100644 index 0000000000000..f80b8761c683e --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_named_unicode_raw.snap @@ -0,0 +1,46 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..3, + ), + ( + FStringMiddle { + value: "\\N", + is_raw: true, + }, + 3..5, + ), + ( + Lbrace, + 5..6, + ), + ( + Name { + name: "BULLET", + }, + 6..12, + ), + ( + Rbrace, + 12..13, + ), + ( + FStringMiddle { + value: " normal", + is_raw: true, + }, + 13..20, + ), + ( + FStringEnd, + 20..21, + ), + ( + Newline, + 21..21, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_nested.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_nested.snap new file mode 100644 index 0000000000000..7a4191cd63172 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_nested.snap @@ -0,0 +1,163 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + FStringMiddle { + value: "foo ", + is_raw: false, + }, + 2..6, + ), + ( + Lbrace, + 6..7, + ), + ( + FStringStart, + 7..9, + ), + ( + FStringMiddle { + value: "bar ", + is_raw: false, + }, + 9..13, + ), + ( + Lbrace, + 13..14, + ), + ( + Name { + name: "x", + }, + 14..15, + ), + ( + Plus, + 16..17, + ), + ( + FStringStart, + 18..20, + ), + ( + Lbrace, + 20..21, + ), + ( + Name { + name: "wow", + }, + 21..24, + ), + ( + Rbrace, + 24..25, + ), + ( + FStringEnd, + 25..26, + ), + ( + Rbrace, + 26..27, + ), + ( + FStringEnd, + 27..28, + ), + ( + Rbrace, + 28..29, + ), + ( + FStringMiddle { + value: " baz", + is_raw: false, + }, + 29..33, + ), + ( + FStringEnd, + 33..34, + ), + ( + FStringStart, + 35..37, + ), + ( + FStringMiddle { + value: "foo ", + is_raw: false, + }, + 37..41, + ), + ( + Lbrace, + 41..42, + ), + ( + FStringStart, + 42..44, + ), + ( + FStringMiddle { + value: "bar", + is_raw: false, + }, + 44..47, + ), + ( + FStringEnd, + 47..48, + ), + ( + Rbrace, + 48..49, + ), + ( + FStringMiddle { + value: " some ", + is_raw: false, + }, + 49..55, + ), + ( + Lbrace, + 55..56, + ), + ( + FStringStart, + 56..58, + ), + ( + FStringMiddle { + value: "another", + is_raw: false, + }, + 58..65, + ), + ( + FStringEnd, + 65..66, + ), + ( + Rbrace, + 66..67, + ), + ( + FStringEnd, + 67..68, + ), + ( + Newline, + 68..68, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_parentheses.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_parentheses.snap new file mode 100644 index 0000000000000..1e4b829ac9db5 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_parentheses.snap @@ -0,0 +1,154 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + Lbrace, + 2..3, + ), + ( + Rbrace, + 3..4, + ), + ( + FStringEnd, + 4..5, + ), + ( + FStringStart, + 6..8, + ), + ( + FStringMiddle { + value: "{}", + is_raw: false, + }, + 8..12, + ), + ( + FStringEnd, + 12..13, + ), + ( + FStringStart, + 14..16, + ), + ( + FStringMiddle { + value: " ", + is_raw: false, + }, + 16..17, + ), + ( + Lbrace, + 17..18, + ), + ( + Rbrace, + 18..19, + ), + ( + FStringEnd, + 19..20, + ), + ( + FStringStart, + 21..23, + ), + ( + FStringMiddle { + value: "{", + is_raw: false, + }, + 23..25, + ), + ( + Lbrace, + 25..26, + ), + ( + Rbrace, + 26..27, + ), + ( + FStringMiddle { + value: "}", + is_raw: false, + }, + 27..29, + ), + ( + FStringEnd, + 29..30, + ), + ( + FStringStart, + 31..33, + ), + ( + FStringMiddle { + value: "{{}}", + is_raw: false, + }, + 33..41, + ), + ( + FStringEnd, + 41..42, + ), + ( + FStringStart, + 43..45, + ), + ( + FStringMiddle { + value: " ", + is_raw: false, + }, + 45..46, + ), + ( + Lbrace, + 46..47, + ), + ( + Rbrace, + 47..48, + ), + ( + FStringMiddle { + value: " {} {", + is_raw: false, + }, + 48..56, + ), + ( + Lbrace, + 56..57, + ), + ( + Rbrace, + 57..58, + ), + ( + FStringMiddle { + value: "} {{}} ", + is_raw: false, + }, + 58..71, + ), + ( + FStringEnd, + 71..72, + ), + ( + Newline, + 72..72, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_prefix.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_prefix.snap new file mode 100644 index 0000000000000..36e048ca40cfc --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_prefix.snap @@ -0,0 +1,90 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + FStringEnd, + 2..3, + ), + ( + FStringStart, + 4..6, + ), + ( + FStringEnd, + 6..7, + ), + ( + FStringStart, + 8..11, + ), + ( + FStringEnd, + 11..12, + ), + ( + FStringStart, + 13..16, + ), + ( + FStringEnd, + 16..17, + ), + ( + FStringStart, + 18..21, + ), + ( + FStringEnd, + 21..22, + ), + ( + FStringStart, + 23..26, + ), + ( + FStringEnd, + 26..27, + ), + ( + FStringStart, + 28..31, + ), + ( + FStringEnd, + 31..32, + ), + ( + FStringStart, + 33..36, + ), + ( + FStringEnd, + 36..37, + ), + ( + FStringStart, + 38..41, + ), + ( + FStringEnd, + 41..42, + ), + ( + FStringStart, + 43..46, + ), + ( + FStringEnd, + 46..47, + ), + ( + Newline, + 47..47, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_single_quote_escape_mac_eol.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_single_quote_escape_mac_eol.snap new file mode 100644 index 0000000000000..c955bded5f680 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_single_quote_escape_mac_eol.snap @@ -0,0 +1,25 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: fstring_single_quote_escape_eol(MAC_EOL) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + FStringMiddle { + value: "text \\\r more text", + is_raw: false, + }, + 2..19, + ), + ( + FStringEnd, + 19..20, + ), + ( + Newline, + 20..20, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_single_quote_escape_unix_eol.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_single_quote_escape_unix_eol.snap new file mode 100644 index 0000000000000..0b30f70577f83 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_single_quote_escape_unix_eol.snap @@ -0,0 +1,25 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: fstring_single_quote_escape_eol(UNIX_EOL) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + FStringMiddle { + value: "text \\\n more text", + is_raw: false, + }, + 2..19, + ), + ( + FStringEnd, + 19..20, + ), + ( + Newline, + 20..20, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_single_quote_escape_windows_eol.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_single_quote_escape_windows_eol.snap new file mode 100644 index 0000000000000..e7b88d9f94b7f --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_single_quote_escape_windows_eol.snap @@ -0,0 +1,25 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: fstring_single_quote_escape_eol(WINDOWS_EOL) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + FStringMiddle { + value: "text \\\r\n more text", + is_raw: false, + }, + 2..20, + ), + ( + FStringEnd, + 20..21, + ), + ( + Newline, + 21..21, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_format_spec.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_format_spec.snap new file mode 100644 index 0000000000000..db324bdef0c2d --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_format_spec.snap @@ -0,0 +1,266 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + Lbrace, + 2..3, + ), + ( + Name { + name: "foo", + }, + 3..6, + ), + ( + Colon, + 6..7, + ), + ( + Rbrace, + 7..8, + ), + ( + FStringMiddle { + value: " ", + is_raw: false, + }, + 8..9, + ), + ( + Lbrace, + 9..10, + ), + ( + Name { + name: "x", + }, + 10..11, + ), + ( + Equal, + 11..12, + ), + ( + Exclamation, + 12..13, + ), + ( + Name { + name: "s", + }, + 13..14, + ), + ( + Colon, + 14..15, + ), + ( + FStringMiddle { + value: ".3f", + is_raw: false, + }, + 15..18, + ), + ( + Rbrace, + 18..19, + ), + ( + FStringMiddle { + value: " ", + is_raw: false, + }, + 19..20, + ), + ( + Lbrace, + 20..21, + ), + ( + Name { + name: "x", + }, + 21..22, + ), + ( + Colon, + 22..23, + ), + ( + FStringMiddle { + value: ".", + is_raw: false, + }, + 23..24, + ), + ( + Lbrace, + 24..25, + ), + ( + Name { + name: "y", + }, + 25..26, + ), + ( + Rbrace, + 26..27, + ), + ( + FStringMiddle { + value: "f", + is_raw: false, + }, + 27..28, + ), + ( + Rbrace, + 28..29, + ), + ( + FStringMiddle { + value: " ", + is_raw: false, + }, + 29..30, + ), + ( + Lbrace, + 30..31, + ), + ( + String { + value: "", + kind: String, + triple_quoted: false, + }, + 31..33, + ), + ( + Colon, + 33..34, + ), + ( + FStringMiddle { + value: "*^", + is_raw: false, + }, + 34..36, + ), + ( + Lbrace, + 36..37, + ), + ( + Int { + value: 1, + }, + 37..38, + ), + ( + Colon, + 38..39, + ), + ( + Lbrace, + 39..40, + ), + ( + Int { + value: 1, + }, + 40..41, + ), + ( + Rbrace, + 41..42, + ), + ( + Rbrace, + 42..43, + ), + ( + Rbrace, + 43..44, + ), + ( + FStringMiddle { + value: " ", + is_raw: false, + }, + 44..45, + ), + ( + Lbrace, + 45..46, + ), + ( + Name { + name: "x", + }, + 46..47, + ), + ( + Colon, + 47..48, + ), + ( + Lbrace, + 48..49, + ), + ( + Lbrace, + 49..50, + ), + ( + Int { + value: 1, + }, + 50..51, + ), + ( + Rbrace, + 51..52, + ), + ( + Dot, + 52..53, + ), + ( + Name { + name: "pop", + }, + 53..56, + ), + ( + Lpar, + 56..57, + ), + ( + Rpar, + 57..58, + ), + ( + Rbrace, + 58..59, + ), + ( + Rbrace, + 59..60, + ), + ( + FStringEnd, + 60..61, + ), + ( + Newline, + 61..61, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_ipy_escape_command.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_ipy_escape_command.snap new file mode 100644 index 0000000000000..89911851aa022 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_ipy_escape_command.snap @@ -0,0 +1,50 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + FStringMiddle { + value: "foo ", + is_raw: false, + }, + 2..6, + ), + ( + Lbrace, + 6..7, + ), + ( + Exclamation, + 7..8, + ), + ( + Name { + name: "pwd", + }, + 8..11, + ), + ( + Rbrace, + 11..12, + ), + ( + FStringMiddle { + value: " bar", + is_raw: false, + }, + 12..16, + ), + ( + FStringEnd, + 16..17, + ), + ( + Newline, + 17..17, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_lambda_expression.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_lambda_expression.snap new file mode 100644 index 0000000000000..efb14aceb649d --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_lambda_expression.snap @@ -0,0 +1,110 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + Lbrace, + 2..3, + ), + ( + Lambda, + 3..9, + ), + ( + Name { + name: "x", + }, + 10..11, + ), + ( + Colon, + 11..12, + ), + ( + Lbrace, + 12..13, + ), + ( + Name { + name: "x", + }, + 13..14, + ), + ( + Rbrace, + 14..15, + ), + ( + Rbrace, + 15..16, + ), + ( + FStringEnd, + 16..17, + ), + ( + Newline, + 17..18, + ), + ( + FStringStart, + 18..20, + ), + ( + Lbrace, + 20..21, + ), + ( + Lpar, + 21..22, + ), + ( + Lambda, + 22..28, + ), + ( + Name { + name: "x", + }, + 29..30, + ), + ( + Colon, + 30..31, + ), + ( + Lbrace, + 31..32, + ), + ( + Name { + name: "x", + }, + 32..33, + ), + ( + Rbrace, + 33..34, + ), + ( + Rpar, + 34..35, + ), + ( + Rbrace, + 35..36, + ), + ( + FStringEnd, + 36..37, + ), + ( + Newline, + 37..37, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_multiline_format_spec.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_multiline_format_spec.snap new file mode 100644 index 0000000000000..6cab3fb5a5bda --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_multiline_format_spec.snap @@ -0,0 +1,244 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..4, + ), + ( + FStringMiddle { + value: "__", + is_raw: false, + }, + 4..6, + ), + ( + Lbrace, + 6..7, + ), + ( + NonLogicalNewline, + 7..8, + ), + ( + Name { + name: "x", + }, + 12..13, + ), + ( + Colon, + 13..14, + ), + ( + FStringMiddle { + value: "d\n", + is_raw: false, + }, + 14..16, + ), + ( + Rbrace, + 16..17, + ), + ( + FStringMiddle { + value: "__", + is_raw: false, + }, + 17..19, + ), + ( + FStringEnd, + 19..22, + ), + ( + Newline, + 22..23, + ), + ( + FStringStart, + 23..27, + ), + ( + FStringMiddle { + value: "__", + is_raw: false, + }, + 27..29, + ), + ( + Lbrace, + 29..30, + ), + ( + NonLogicalNewline, + 30..31, + ), + ( + Name { + name: "x", + }, + 35..36, + ), + ( + Colon, + 36..37, + ), + ( + FStringMiddle { + value: "a\n b\n c\n", + is_raw: false, + }, + 37..61, + ), + ( + Rbrace, + 61..62, + ), + ( + FStringMiddle { + value: "__", + is_raw: false, + }, + 62..64, + ), + ( + FStringEnd, + 64..67, + ), + ( + Newline, + 67..68, + ), + ( + FStringStart, + 68..70, + ), + ( + FStringMiddle { + value: "__", + is_raw: false, + }, + 70..72, + ), + ( + Lbrace, + 72..73, + ), + ( + NonLogicalNewline, + 73..74, + ), + ( + Name { + name: "x", + }, + 78..79, + ), + ( + Colon, + 79..80, + ), + ( + FStringMiddle { + value: "d", + is_raw: false, + }, + 80..81, + ), + ( + NonLogicalNewline, + 81..82, + ), + ( + Rbrace, + 82..83, + ), + ( + FStringMiddle { + value: "__", + is_raw: false, + }, + 83..85, + ), + ( + FStringEnd, + 85..86, + ), + ( + Newline, + 86..87, + ), + ( + FStringStart, + 87..89, + ), + ( + FStringMiddle { + value: "__", + is_raw: false, + }, + 89..91, + ), + ( + Lbrace, + 91..92, + ), + ( + NonLogicalNewline, + 92..93, + ), + ( + Name { + name: "x", + }, + 97..98, + ), + ( + Colon, + 98..99, + ), + ( + FStringMiddle { + value: "a", + is_raw: false, + }, + 99..100, + ), + ( + NonLogicalNewline, + 100..101, + ), + ( + Name { + name: "b", + }, + 109..110, + ), + ( + NonLogicalNewline, + 110..111, + ), + ( + Rbrace, + 111..112, + ), + ( + FStringMiddle { + value: "__", + is_raw: false, + }, + 112..114, + ), + ( + FStringEnd, + 114..115, + ), + ( + Newline, + 115..116, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_named_expression.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_named_expression.snap new file mode 100644 index 0000000000000..aa551e4d73f3a --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_named_expression.snap @@ -0,0 +1,170 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + Lbrace, + 2..3, + ), + ( + Name { + name: "x", + }, + 3..4, + ), + ( + Colon, + 4..5, + ), + ( + FStringMiddle { + value: "=10", + is_raw: false, + }, + 5..8, + ), + ( + Rbrace, + 8..9, + ), + ( + FStringMiddle { + value: " ", + is_raw: false, + }, + 9..10, + ), + ( + Lbrace, + 10..11, + ), + ( + Lpar, + 11..12, + ), + ( + Name { + name: "x", + }, + 12..13, + ), + ( + ColonEqual, + 13..15, + ), + ( + Int { + value: 10, + }, + 15..17, + ), + ( + Rpar, + 17..18, + ), + ( + Rbrace, + 18..19, + ), + ( + FStringMiddle { + value: " ", + is_raw: false, + }, + 19..20, + ), + ( + Lbrace, + 20..21, + ), + ( + Name { + name: "x", + }, + 21..22, + ), + ( + Comma, + 22..23, + ), + ( + Lbrace, + 23..24, + ), + ( + Name { + name: "y", + }, + 24..25, + ), + ( + ColonEqual, + 25..27, + ), + ( + Int { + value: 10, + }, + 27..29, + ), + ( + Rbrace, + 29..30, + ), + ( + Rbrace, + 30..31, + ), + ( + FStringMiddle { + value: " ", + is_raw: false, + }, + 31..32, + ), + ( + Lbrace, + 32..33, + ), + ( + Lsqb, + 33..34, + ), + ( + Name { + name: "x", + }, + 34..35, + ), + ( + ColonEqual, + 35..37, + ), + ( + Int { + value: 10, + }, + 37..39, + ), + ( + Rsqb, + 39..40, + ), + ( + Rbrace, + 40..41, + ), + ( + FStringEnd, + 41..42, + ), + ( + Newline, + 42..42, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_nul_char.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_nul_char.snap new file mode 100644 index 0000000000000..667d1897ecbcd --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_nul_char.snap @@ -0,0 +1,25 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_source(source) +--- +[ + ( + FStringStart, + 0..2, + ), + ( + FStringMiddle { + value: "\\0", + is_raw: false, + }, + 2..4, + ), + ( + FStringEnd, + 4..5, + ), + ( + Newline, + 5..5, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__invalid_leading_zero_big.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__invalid_leading_zero_big.snap new file mode 100644 index 0000000000000..c2906398a5141 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__invalid_leading_zero_big.snap @@ -0,0 +1,12 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: tokens +--- +Err( + LexicalError { + error: OtherError( + "Invalid Token", + ), + location: 0, + }, +) diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__invalid_leading_zero_small.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__invalid_leading_zero_small.snap new file mode 100644 index 0000000000000..c2906398a5141 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__invalid_leading_zero_small.snap @@ -0,0 +1,12 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: tokens +--- +Err( + LexicalError { + error: OtherError( + "Invalid Token", + ), + location: 0, + }, +) diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__numbers.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__numbers.snap index 91493ac6b02d0..f9a7a988b1e7f 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__numbers.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__numbers.snap @@ -71,8 +71,20 @@ expression: lex_source(source) }, 55..59, ), + ( + Int { + value: 0, + }, + 60..63, + ), + ( + Int { + value: 0x995DC9BBDF1939FA, + }, + 64..82, + ), ( Newline, - 59..59, + 82..82, ), ] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__fstrings.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__fstrings.snap new file mode 100644 index 0000000000000..f1e664a40990c --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__fstrings.snap @@ -0,0 +1,877 @@ +--- +source: crates/ruff_python_parser/src/parser.rs +expression: parse_ast +--- +[ + Expr( + StmtExpr { + range: 0..9, + value: FString( + ExprFString { + range: 0..9, + values: [ + FormattedValue( + ExprFormattedValue { + range: 2..8, + value: Constant( + ExprConstant { + range: 3..7, + value: Str( + StringConstant { + value: " f", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + implicit_concatenated: false, + }, + ), + }, + ), + Expr( + StmtExpr { + range: 10..20, + value: FString( + ExprFString { + range: 10..20, + values: [ + FormattedValue( + ExprFormattedValue { + range: 12..19, + value: Name( + ExprName { + range: 13..16, + id: "foo", + ctx: Load, + }, + ), + debug_text: None, + conversion: Str, + format_spec: None, + }, + ), + ], + implicit_concatenated: false, + }, + ), + }, + ), + Expr( + StmtExpr { + range: 21..28, + value: FString( + ExprFString { + range: 21..28, + values: [ + FormattedValue( + ExprFormattedValue { + range: 23..27, + value: Tuple( + ExprTuple { + range: 24..26, + elts: [ + Constant( + ExprConstant { + range: 24..25, + value: Int( + 3, + ), + }, + ), + ], + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + implicit_concatenated: false, + }, + ), + }, + ), + Expr( + StmtExpr { + range: 29..39, + value: FString( + ExprFString { + range: 29..39, + values: [ + FormattedValue( + ExprFormattedValue { + range: 31..38, + value: Compare( + ExprCompare { + range: 32..36, + left: Constant( + ExprConstant { + range: 32..33, + value: Int( + 3, + ), + }, + ), + ops: [ + NotEq, + ], + comparators: [ + Constant( + ExprConstant { + range: 35..36, + value: Int( + 4, + ), + }, + ), + ], + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FString( + ExprFString { + range: 37..37, + values: [], + implicit_concatenated: false, + }, + ), + ), + }, + ), + ], + implicit_concatenated: false, + }, + ), + }, + ), + Expr( + StmtExpr { + range: 40..55, + value: FString( + ExprFString { + range: 40..55, + values: [ + FormattedValue( + ExprFormattedValue { + range: 42..54, + value: Constant( + ExprConstant { + range: 43..44, + value: Int( + 3, + ), + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FString( + ExprFString { + range: 45..53, + values: [ + FormattedValue( + ExprFormattedValue { + range: 45..50, + value: Constant( + ExprConstant { + range: 46..49, + value: Str( + StringConstant { + value: "}", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Constant( + ExprConstant { + range: 50..53, + value: Str( + StringConstant { + value: ">10", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + ], + implicit_concatenated: false, + }, + ), + ), + }, + ), + ], + implicit_concatenated: false, + }, + ), + }, + ), + Expr( + StmtExpr { + range: 56..71, + value: FString( + ExprFString { + range: 56..71, + values: [ + FormattedValue( + ExprFormattedValue { + range: 58..70, + value: Constant( + ExprConstant { + range: 59..60, + value: Int( + 3, + ), + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FString( + ExprFString { + range: 61..69, + values: [ + FormattedValue( + ExprFormattedValue { + range: 61..66, + value: Constant( + ExprConstant { + range: 62..65, + value: Str( + StringConstant { + value: "{", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Constant( + ExprConstant { + range: 66..69, + value: Str( + StringConstant { + value: ">10", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + ], + implicit_concatenated: false, + }, + ), + ), + }, + ), + ], + implicit_concatenated: false, + }, + ), + }, + ), + Expr( + StmtExpr { + range: 72..86, + value: FString( + ExprFString { + range: 72..86, + values: [ + FormattedValue( + ExprFormattedValue { + range: 74..85, + value: Name( + ExprName { + range: 77..80, + id: "foo", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: " ", + trailing: " = ", + }, + ), + conversion: None, + format_spec: None, + }, + ), + ], + implicit_concatenated: false, + }, + ), + }, + ), + Expr( + StmtExpr { + range: 87..107, + value: FString( + ExprFString { + range: 87..107, + values: [ + FormattedValue( + ExprFormattedValue { + range: 89..106, + value: Name( + ExprName { + range: 92..95, + id: "foo", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: " ", + trailing: " = ", + }, + ), + conversion: None, + format_spec: Some( + FString( + ExprFString { + range: 100..105, + values: [ + Constant( + ExprConstant { + range: 100..105, + value: Str( + StringConstant { + value: ".3f ", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + ], + implicit_concatenated: false, + }, + ), + ), + }, + ), + ], + implicit_concatenated: false, + }, + ), + }, + ), + Expr( + StmtExpr { + range: 108..126, + value: FString( + ExprFString { + range: 108..126, + values: [ + FormattedValue( + ExprFormattedValue { + range: 110..125, + value: Name( + ExprName { + range: 113..116, + id: "foo", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: " ", + trailing: " = ", + }, + ), + conversion: Str, + format_spec: None, + }, + ), + ], + implicit_concatenated: false, + }, + ), + }, + ), + Expr( + StmtExpr { + range: 127..143, + value: FString( + ExprFString { + range: 127..143, + values: [ + FormattedValue( + ExprFormattedValue { + range: 129..142, + value: Tuple( + ExprTuple { + range: 132..136, + elts: [ + Constant( + ExprConstant { + range: 132..133, + value: Int( + 1, + ), + }, + ), + Constant( + ExprConstant { + range: 135..136, + value: Int( + 2, + ), + }, + ), + ], + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: " ", + trailing: " = ", + }, + ), + conversion: None, + format_spec: None, + }, + ), + ], + implicit_concatenated: false, + }, + ), + }, + ), + Expr( + StmtExpr { + range: 144..170, + value: FString( + ExprFString { + range: 144..170, + values: [ + FormattedValue( + ExprFormattedValue { + range: 146..169, + value: FString( + ExprFString { + range: 147..163, + values: [ + FormattedValue( + ExprFormattedValue { + range: 149..162, + value: Constant( + ExprConstant { + range: 150..156, + value: Float( + 3.1415, + ), + }, + ), + debug_text: Some( + DebugText { + leading: "", + trailing: "=", + }, + ), + conversion: None, + format_spec: Some( + FString( + ExprFString { + range: 158..161, + values: [ + Constant( + ExprConstant { + range: 158..161, + value: Str( + StringConstant { + value: ".1f", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + ], + implicit_concatenated: false, + }, + ), + ), + }, + ), + ], + implicit_concatenated: false, + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FString( + ExprFString { + range: 164..168, + values: [ + Constant( + ExprConstant { + range: 164..168, + value: Str( + StringConstant { + value: "*^20", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + ], + implicit_concatenated: false, + }, + ), + ), + }, + ), + ], + implicit_concatenated: false, + }, + ), + }, + ), + Expr( + StmtExpr { + range: 172..206, + value: Dict( + ExprDict { + range: 172..206, + keys: [ + Some( + FString( + ExprFString { + range: 173..201, + values: [ + Constant( + ExprConstant { + range: 174..186, + value: Str( + StringConstant { + value: "foo bar ", + unicode: false, + implicit_concatenated: true, + }, + ), + }, + ), + FormattedValue( + ExprFormattedValue { + range: 186..193, + value: BinOp( + ExprBinOp { + range: 187..192, + left: Name( + ExprName { + range: 187..188, + id: "x", + ctx: Load, + }, + ), + op: Add, + right: Name( + ExprName { + range: 191..192, + id: "y", + ctx: Load, + }, + ), + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Constant( + ExprConstant { + range: 193..200, + value: Str( + StringConstant { + value: " baz", + unicode: false, + implicit_concatenated: true, + }, + ), + }, + ), + ], + implicit_concatenated: true, + }, + ), + ), + ], + values: [ + Constant( + ExprConstant { + range: 203..205, + value: Int( + 10, + ), + }, + ), + ], + }, + ), + }, + ), + Match( + StmtMatch { + range: 207..298, + subject: Name( + ExprName { + range: 213..216, + id: "foo", + ctx: Load, + }, + ), + cases: [ + MatchCase { + range: 222..246, + pattern: MatchValue( + PatternMatchValue { + range: 227..232, + value: Constant( + ExprConstant { + range: 227..232, + value: Str( + StringConstant { + value: "one", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + }, + ), + guard: None, + body: [ + Pass( + StmtPass { + range: 242..246, + }, + ), + ], + }, + MatchCase { + range: 251..298, + pattern: MatchValue( + PatternMatchValue { + range: 256..284, + value: Constant( + ExprConstant { + range: 256..284, + value: Str( + StringConstant { + value: "implicitly concatenated", + unicode: false, + implicit_concatenated: true, + }, + ), + }, + ), + }, + ), + guard: None, + body: [ + Pass( + StmtPass { + range: 294..298, + }, + ), + ], + }, + ], + }, + ), + Expr( + StmtExpr { + range: 300..317, + value: FString( + ExprFString { + range: 300..317, + values: [ + Constant( + ExprConstant { + range: 302..303, + value: Str( + StringConstant { + value: "\\", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + FormattedValue( + ExprFormattedValue { + range: 303..308, + value: Name( + ExprName { + range: 304..307, + id: "foo", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Constant( + ExprConstant { + range: 308..309, + value: Str( + StringConstant { + value: "\\", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + FormattedValue( + ExprFormattedValue { + range: 309..316, + value: Name( + ExprName { + range: 310..313, + id: "bar", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FString( + ExprFString { + range: 314..315, + values: [ + Constant( + ExprConstant { + range: 314..315, + value: Str( + StringConstant { + value: "\\", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + ], + implicit_concatenated: false, + }, + ), + ), + }, + ), + ], + implicit_concatenated: false, + }, + ), + }, + ), + Expr( + StmtExpr { + range: 318..332, + value: FString( + ExprFString { + range: 318..332, + values: [ + Constant( + ExprConstant { + range: 320..331, + value: Str( + StringConstant { + value: "\\{foo\\}", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + ], + implicit_concatenated: false, + }, + ), + }, + ), + Expr( + StmtExpr { + range: 333..373, + value: FString( + ExprFString { + range: 333..373, + values: [ + FormattedValue( + ExprFormattedValue { + range: 337..370, + value: Name( + ExprName { + range: 343..346, + id: "foo", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FString( + ExprFString { + range: 347..369, + values: [ + Constant( + ExprConstant { + range: 347..369, + value: Str( + StringConstant { + value: "x\n y\n z\n", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + ], + implicit_concatenated: false, + }, + ), + ), + }, + ), + ], + implicit_concatenated: false, + }, + ), + }, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__fstrings_with_unicode.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__fstrings_with_unicode.snap new file mode 100644 index 0000000000000..b10d76f60f49f --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__fstrings_with_unicode.snap @@ -0,0 +1,214 @@ +--- +source: crates/ruff_python_parser/src/parser.rs +expression: parse_ast +--- +[ + Expr( + StmtExpr { + range: 0..29, + value: FString( + ExprFString { + range: 0..29, + values: [ + Constant( + ExprConstant { + range: 2..5, + value: Str( + StringConstant { + value: "foo", + unicode: true, + implicit_concatenated: true, + }, + ), + }, + ), + FormattedValue( + ExprFormattedValue { + range: 9..14, + value: Name( + ExprName { + range: 10..13, + id: "bar", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Constant( + ExprConstant { + range: 17..28, + value: Str( + StringConstant { + value: "baz some", + unicode: false, + implicit_concatenated: true, + }, + ), + }, + ), + ], + implicit_concatenated: true, + }, + ), + }, + ), + Expr( + StmtExpr { + range: 30..59, + value: FString( + ExprFString { + range: 30..59, + values: [ + Constant( + ExprConstant { + range: 31..34, + value: Str( + StringConstant { + value: "foo", + unicode: false, + implicit_concatenated: true, + }, + ), + }, + ), + FormattedValue( + ExprFormattedValue { + range: 38..43, + value: Name( + ExprName { + range: 39..42, + id: "bar", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Constant( + ExprConstant { + range: 47..58, + value: Str( + StringConstant { + value: "baz some", + unicode: true, + implicit_concatenated: true, + }, + ), + }, + ), + ], + implicit_concatenated: true, + }, + ), + }, + ), + Expr( + StmtExpr { + range: 60..89, + value: FString( + ExprFString { + range: 60..89, + values: [ + Constant( + ExprConstant { + range: 61..64, + value: Str( + StringConstant { + value: "foo", + unicode: false, + implicit_concatenated: true, + }, + ), + }, + ), + FormattedValue( + ExprFormattedValue { + range: 68..73, + value: Name( + ExprName { + range: 69..72, + id: "bar", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Constant( + ExprConstant { + range: 76..88, + value: Str( + StringConstant { + value: "baz some", + unicode: false, + implicit_concatenated: true, + }, + ), + }, + ), + ], + implicit_concatenated: true, + }, + ), + }, + ), + Expr( + StmtExpr { + range: 90..128, + value: FString( + ExprFString { + range: 90..128, + values: [ + Constant( + ExprConstant { + range: 92..103, + value: Str( + StringConstant { + value: "foobar ", + unicode: true, + implicit_concatenated: true, + }, + ), + }, + ), + FormattedValue( + ExprFormattedValue { + range: 103..108, + value: Name( + ExprName { + range: 104..107, + id: "baz", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Constant( + ExprConstant { + range: 108..127, + value: Str( + StringConstant { + value: " reallybarno", + unicode: false, + implicit_concatenated: true, + }, + ), + }, + ), + ], + implicit_concatenated: true, + }, + ), + }, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__match.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__match.snap index dc723a1468a29..cc9c5dd5e913d 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__match.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__match.snap @@ -445,4 +445,153 @@ expression: parse_ast ], }, ), + Match( + StmtMatch { + range: 298..332, + subject: Tuple( + ExprTuple { + range: 304..306, + elts: [ + Name( + ExprName { + range: 304..305, + id: "x", + ctx: Load, + }, + ), + ], + ctx: Load, + }, + ), + cases: [ + MatchCase { + range: 312..332, + pattern: MatchAs( + PatternMatchAs { + range: 317..318, + pattern: None, + name: Some( + Identifier { + id: "z", + range: 317..318, + }, + ), + }, + ), + guard: None, + body: [ + Pass( + StmtPass { + range: 328..332, + }, + ), + ], + }, + ], + }, + ), + Match( + StmtMatch { + range: 333..369, + subject: Tuple( + ExprTuple { + range: 339..343, + elts: [ + Name( + ExprName { + range: 339..340, + id: "x", + ctx: Load, + }, + ), + Name( + ExprName { + range: 342..343, + id: "y", + ctx: Load, + }, + ), + ], + ctx: Load, + }, + ), + cases: [ + MatchCase { + range: 349..369, + pattern: MatchAs( + PatternMatchAs { + range: 354..355, + pattern: None, + name: Some( + Identifier { + id: "z", + range: 354..355, + }, + ), + }, + ), + guard: None, + body: [ + Pass( + StmtPass { + range: 365..369, + }, + ), + ], + }, + ], + }, + ), + Match( + StmtMatch { + range: 370..407, + subject: Tuple( + ExprTuple { + range: 376..381, + elts: [ + Name( + ExprName { + range: 376..377, + id: "x", + ctx: Load, + }, + ), + Name( + ExprName { + range: 379..380, + id: "y", + ctx: Load, + }, + ), + ], + ctx: Load, + }, + ), + cases: [ + MatchCase { + range: 387..407, + pattern: MatchAs( + PatternMatchAs { + range: 392..393, + pattern: None, + name: Some( + Identifier { + id: "z", + range: 392..393, + }, + ), + }, + ), + guard: None, + body: [ + Pass( + StmtPass { + range: 403..407, + }, + ), + ], + }, + ], + }, + ), ] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__patma.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__patma.snap index 622287a6becde..1ea20048fa507 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__patma.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__patma.snap @@ -3449,10 +3449,18 @@ expression: parse_ast Match( StmtMatch { range: 2661..2697, - subject: Name( - ExprName { - range: 2667..2668, - id: "x", + subject: Tuple( + ExprTuple { + range: 2667..2669, + elts: [ + Name( + ExprName { + range: 2667..2668, + id: "x", + ctx: Load, + }, + ), + ], ctx: Load, }, ), @@ -3512,7 +3520,7 @@ expression: parse_ast range: 2720..2760, subject: Tuple( ExprTuple { - range: 2720..2760, + range: 2726..2730, elts: [ Name( ExprName { @@ -3598,23 +3606,31 @@ expression: parse_ast Match( StmtMatch { range: 2783..2829, - subject: NamedExpr( - ExprNamedExpr { - range: 2789..2795, - target: Name( - ExprName { - range: 2789..2790, - id: "w", - ctx: Store, - }, - ), - value: Name( - ExprName { - range: 2794..2795, - id: "x", - ctx: Load, - }, - ), + subject: Tuple( + ExprTuple { + range: 2789..2796, + elts: [ + NamedExpr( + ExprNamedExpr { + range: 2789..2795, + target: Name( + ExprName { + range: 2789..2790, + id: "w", + ctx: Store, + }, + ), + value: Name( + ExprName { + range: 2794..2795, + id: "x", + ctx: Load, + }, + ), + }, + ), + ], + ctx: Load, }, ), cases: [ diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__unicode_aliases.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__unicode_aliases.snap new file mode 100644 index 0000000000000..b7e2c7c1899e3 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__parser__tests__unicode_aliases.snap @@ -0,0 +1,32 @@ +--- +source: crates/ruff_python_parser/src/parser.rs +expression: parse_ast +--- +[ + Assign( + StmtAssign { + range: 0..37, + targets: [ + Name( + ExprName { + range: 0..1, + id: "x", + ctx: Store, + }, + ), + ], + value: Constant( + ExprConstant { + range: 4..37, + value: Str( + StringConstant { + value: "\u{8}another cool trick", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + }, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_base.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_base.snap index 2ea0c26e91d2d..7927d57d4f621 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_base.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_base.snap @@ -3,24 +3,37 @@ source: crates/ruff_python_parser/src/string.rs expression: parse_ast --- [ - FormattedValue( - ExprFormattedValue { - range: 2..9, - value: Name( - ExprName { - range: 3..7, - id: "user", - ctx: Load, + Expr( + StmtExpr { + range: 0..10, + value: FString( + ExprFString { + range: 0..10, + values: [ + FormattedValue( + ExprFormattedValue { + range: 2..9, + value: Name( + ExprName { + range: 3..7, + id: "user", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: "", + trailing: "=", + }, + ), + conversion: None, + format_spec: None, + }, + ), + ], + implicit_concatenated: false, }, ), - debug_text: Some( - DebugText { - leading: "", - trailing: "=", - }, - ), - conversion: None, - format_spec: None, }, ), ] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_base_more.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_base_more.snap index 346124137fa71..c3f98691021dd 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_base_more.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_base_more.snap @@ -3,68 +3,81 @@ source: crates/ruff_python_parser/src/string.rs expression: parse_ast --- [ - Constant( - ExprConstant { - range: 2..6, - value: Str( - StringConstant { - value: "mix ", - unicode: false, + Expr( + StmtExpr { + range: 0..38, + value: FString( + ExprFString { + range: 0..38, + values: [ + Constant( + ExprConstant { + range: 2..6, + value: Str( + StringConstant { + value: "mix ", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + FormattedValue( + ExprFormattedValue { + range: 6..13, + value: Name( + ExprName { + range: 7..11, + id: "user", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: "", + trailing: "=", + }, + ), + conversion: None, + format_spec: None, + }, + ), + Constant( + ExprConstant { + range: 13..28, + value: Str( + StringConstant { + value: " with text and ", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + FormattedValue( + ExprFormattedValue { + range: 28..37, + value: Name( + ExprName { + range: 29..35, + id: "second", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: "", + trailing: "=", + }, + ), + conversion: None, + format_spec: None, + }, + ), + ], implicit_concatenated: false, }, ), }, ), - FormattedValue( - ExprFormattedValue { - range: 6..13, - value: Name( - ExprName { - range: 7..11, - id: "user", - ctx: Load, - }, - ), - debug_text: Some( - DebugText { - leading: "", - trailing: "=", - }, - ), - conversion: None, - format_spec: None, - }, - ), - Constant( - ExprConstant { - range: 13..28, - value: Str( - StringConstant { - value: " with text and ", - unicode: false, - implicit_concatenated: false, - }, - ), - }, - ), - FormattedValue( - ExprFormattedValue { - range: 28..37, - value: Name( - ExprName { - range: 29..35, - id: "second", - ctx: Load, - }, - ), - debug_text: Some( - DebugText { - leading: "", - trailing: "=", - }, - ), - conversion: None, - format_spec: None, - }, - ), ] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_format.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_format.snap index e22f1f70ae5f6..21fca06ff64b2 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_format.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__fstring_parse_self_documenting_format.snap @@ -3,44 +3,57 @@ source: crates/ruff_python_parser/src/string.rs expression: parse_ast --- [ - FormattedValue( - ExprFormattedValue { - range: 2..13, - value: Name( - ExprName { - range: 3..7, - id: "user", - ctx: Load, - }, - ), - debug_text: Some( - DebugText { - leading: "", - trailing: "=", - }, - ), - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 9..12, - values: [ - Constant( - ExprConstant { - range: 9..12, - value: Str( - StringConstant { - value: ">10", - unicode: false, + Expr( + StmtExpr { + range: 0..14, + value: FString( + ExprFString { + range: 0..14, + values: [ + FormattedValue( + ExprFormattedValue { + range: 2..13, + value: Name( + ExprName { + range: 3..7, + id: "user", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: "", + trailing: "=", + }, + ), + conversion: None, + format_spec: Some( + FString( + ExprFString { + range: 9..12, + values: [ + Constant( + ExprConstant { + range: 9..12, + value: Str( + StringConstant { + value: ">10", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + ], implicit_concatenated: false, }, ), - }, - ), - ], - implicit_concatenated: false, - }, - ), + ), + }, + ), + ], + implicit_concatenated: false, + }, ), }, ), diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_empty_fstring.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_empty_fstring.snap index a1435da1835d3..08b71212046b2 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_empty_fstring.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_empty_fstring.snap @@ -1,5 +1,18 @@ --- source: crates/ruff_python_parser/src/string.rs -expression: "parse_fstring(\"\").unwrap()" +expression: "parse_suite(r#\"f\"\"\"#, \"\").unwrap()" --- -[] +[ + Expr( + StmtExpr { + range: 0..3, + value: FString( + ExprFString { + range: 0..3, + values: [], + implicit_concatenated: false, + }, + ), + }, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring.snap index ea76fa6ad48eb..ec007012e25db 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring.snap @@ -3,43 +3,56 @@ source: crates/ruff_python_parser/src/string.rs expression: parse_ast --- [ - FormattedValue( - ExprFormattedValue { - range: 2..5, - value: Name( - ExprName { - range: 3..4, - id: "a", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - FormattedValue( - ExprFormattedValue { - range: 5..10, - value: Name( - ExprName { - range: 7..8, - id: "b", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - Constant( - ExprConstant { - range: 10..17, - value: Str( - StringConstant { - value: "{foo}", - unicode: false, + Expr( + StmtExpr { + range: 0..18, + value: FString( + ExprFString { + range: 0..18, + values: [ + FormattedValue( + ExprFormattedValue { + range: 2..5, + value: Name( + ExprName { + range: 3..4, + id: "a", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + FormattedValue( + ExprFormattedValue { + range: 5..10, + value: Name( + ExprName { + range: 7..8, + id: "b", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + Constant( + ExprConstant { + range: 10..17, + value: Str( + StringConstant { + value: "{foo}", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + ], implicit_concatenated: false, }, ), diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_equals.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_equals.snap index 8a4ae20ea4575..99e94a06b52cb 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_equals.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_equals.snap @@ -3,38 +3,51 @@ source: crates/ruff_python_parser/src/string.rs expression: parse_ast --- [ - FormattedValue( - ExprFormattedValue { - range: 2..12, - value: Compare( - ExprCompare { - range: 3..11, - left: Constant( - ExprConstant { - range: 3..5, - value: Int( - 42, - ), - }, - ), - ops: [ - Eq, - ], - comparators: [ - Constant( - ExprConstant { - range: 9..11, - value: Int( - 42, + Expr( + StmtExpr { + range: 0..13, + value: FString( + ExprFString { + range: 0..13, + values: [ + FormattedValue( + ExprFormattedValue { + range: 2..12, + value: Compare( + ExprCompare { + range: 3..11, + left: Constant( + ExprConstant { + range: 3..5, + value: Int( + 42, + ), + }, + ), + ops: [ + Eq, + ], + comparators: [ + Constant( + ExprConstant { + range: 9..11, + value: Int( + 42, + ), + }, + ), + ], + }, ), + debug_text: None, + conversion: None, + format_spec: None, }, ), ], + implicit_concatenated: false, }, ), - debug_text: None, - conversion: None, - format_spec: None, }, ), ] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_concatenation_string_spec.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_concatenation_string_spec.snap index 752f06e9b23b0..105460ecbcd24 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_concatenation_string_spec.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_concatenation_string_spec.snap @@ -3,47 +3,60 @@ source: crates/ruff_python_parser/src/string.rs expression: parse_ast --- [ - FormattedValue( - ExprFormattedValue { - range: 2..15, - value: Name( - ExprName { - range: 3..6, - id: "foo", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 7..14, - values: [ - FormattedValue( - ExprFormattedValue { - range: 7..14, - value: Constant( - ExprConstant { - range: 8..13, - value: Str( - StringConstant { - value: "", - unicode: false, - implicit_concatenated: true, - }, - ), + Expr( + StmtExpr { + range: 0..16, + value: FString( + ExprFString { + range: 0..16, + values: [ + FormattedValue( + ExprFormattedValue { + range: 2..15, + value: Name( + ExprName { + range: 3..6, + id: "foo", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FString( + ExprFString { + range: 7..14, + values: [ + FormattedValue( + ExprFormattedValue { + range: 7..14, + value: Constant( + ExprConstant { + range: 8..13, + value: Str( + StringConstant { + value: "", + unicode: false, + implicit_concatenated: true, + }, + ), + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + implicit_concatenated: false, }, ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - ], - implicit_concatenated: false, - }, - ), + ), + }, + ), + ], + implicit_concatenated: false, + }, ), }, ), diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_spec.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_spec.snap index d93be4602f04e..39f80bde5c65c 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_spec.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_spec.snap @@ -3,42 +3,55 @@ source: crates/ruff_python_parser/src/string.rs expression: parse_ast --- [ - FormattedValue( - ExprFormattedValue { - range: 2..14, - value: Name( - ExprName { - range: 3..6, - id: "foo", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 7..13, - values: [ - FormattedValue( - ExprFormattedValue { - range: 7..13, - value: Name( - ExprName { - range: 8..12, - id: "spec", - ctx: Load, + Expr( + StmtExpr { + range: 0..15, + value: FString( + ExprFString { + range: 0..15, + values: [ + FormattedValue( + ExprFormattedValue { + range: 2..14, + value: Name( + ExprName { + range: 3..6, + id: "foo", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FString( + ExprFString { + range: 7..13, + values: [ + FormattedValue( + ExprFormattedValue { + range: 7..13, + value: Name( + ExprName { + range: 8..12, + id: "spec", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + implicit_concatenated: false, }, ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - ], - implicit_concatenated: false, - }, - ), + ), + }, + ), + ], + implicit_concatenated: false, + }, ), }, ), diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_string_spec.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_string_spec.snap index 8a1149aa5c66f..b1abddec3d7d0 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_string_spec.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_nested_string_spec.snap @@ -3,47 +3,60 @@ source: crates/ruff_python_parser/src/string.rs expression: parse_ast --- [ - FormattedValue( - ExprFormattedValue { - range: 2..12, - value: Name( - ExprName { - range: 3..6, - id: "foo", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 7..11, - values: [ - FormattedValue( - ExprFormattedValue { - range: 7..11, - value: Constant( - ExprConstant { - range: 8..10, - value: Str( - StringConstant { - value: "", - unicode: false, - implicit_concatenated: false, - }, - ), + Expr( + StmtExpr { + range: 0..13, + value: FString( + ExprFString { + range: 0..13, + values: [ + FormattedValue( + ExprFormattedValue { + range: 2..12, + value: Name( + ExprName { + range: 3..6, + id: "foo", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FString( + ExprFString { + range: 7..11, + values: [ + FormattedValue( + ExprFormattedValue { + range: 7..11, + value: Constant( + ExprConstant { + range: 8..10, + value: Str( + StringConstant { + value: "", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + implicit_concatenated: false, }, ), - debug_text: None, - conversion: None, - format_spec: None, - }, - ), - ], - implicit_concatenated: false, - }, - ), + ), + }, + ), + ], + implicit_concatenated: false, + }, ), }, ), diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_not_equals.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_not_equals.snap index 759c8bc9ad50f..c0035a45b9405 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_not_equals.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_not_equals.snap @@ -3,38 +3,51 @@ source: crates/ruff_python_parser/src/string.rs expression: parse_ast --- [ - FormattedValue( - ExprFormattedValue { - range: 2..10, - value: Compare( - ExprCompare { - range: 3..9, - left: Constant( - ExprConstant { - range: 3..4, - value: Int( - 1, - ), - }, - ), - ops: [ - NotEq, - ], - comparators: [ - Constant( - ExprConstant { - range: 8..9, - value: Int( - 2, + Expr( + StmtExpr { + range: 0..11, + value: FString( + ExprFString { + range: 0..11, + values: [ + FormattedValue( + ExprFormattedValue { + range: 2..10, + value: Compare( + ExprCompare { + range: 3..9, + left: Constant( + ExprConstant { + range: 3..4, + value: Int( + 1, + ), + }, + ), + ops: [ + NotEq, + ], + comparators: [ + Constant( + ExprConstant { + range: 8..9, + value: Int( + 2, + ), + }, + ), + ], + }, ), + debug_text: None, + conversion: None, + format_spec: None, }, ), ], + implicit_concatenated: false, }, ), - debug_text: None, - conversion: None, - format_spec: None, }, ), ] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_not_nested_spec.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_not_nested_spec.snap index f4294c5bb328b..e5cc2fade40ae 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_not_nested_spec.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_not_nested_spec.snap @@ -3,39 +3,52 @@ source: crates/ruff_python_parser/src/string.rs expression: parse_ast --- [ - FormattedValue( - ExprFormattedValue { - range: 2..12, - value: Name( - ExprName { - range: 3..6, - id: "foo", - ctx: Load, - }, - ), - debug_text: None, - conversion: None, - format_spec: Some( - FString( - ExprFString { - range: 7..11, - values: [ - Constant( - ExprConstant { - range: 7..11, - value: Str( - StringConstant { - value: "spec", - unicode: false, + Expr( + StmtExpr { + range: 0..13, + value: FString( + ExprFString { + range: 0..13, + values: [ + FormattedValue( + ExprFormattedValue { + range: 2..12, + value: Name( + ExprName { + range: 3..6, + id: "foo", + ctx: Load, + }, + ), + debug_text: None, + conversion: None, + format_spec: Some( + FString( + ExprFString { + range: 7..11, + values: [ + Constant( + ExprConstant { + range: 7..11, + value: Str( + StringConstant { + value: "spec", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + ], implicit_concatenated: false, }, ), - }, - ), - ], - implicit_concatenated: false, - }, - ), + ), + }, + ), + ], + implicit_concatenated: false, + }, ), }, ), diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_self_doc_prec_space.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_self_doc_prec_space.snap index 1891d37330dd0..134e8043877e3 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_self_doc_prec_space.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_self_doc_prec_space.snap @@ -3,24 +3,37 @@ source: crates/ruff_python_parser/src/string.rs expression: parse_ast --- [ - FormattedValue( - ExprFormattedValue { - range: 2..9, - value: Name( - ExprName { - range: 3..4, - id: "x", - ctx: Load, + Expr( + StmtExpr { + range: 0..10, + value: FString( + ExprFString { + range: 0..10, + values: [ + FormattedValue( + ExprFormattedValue { + range: 2..9, + value: Name( + ExprName { + range: 3..4, + id: "x", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: "", + trailing: " =", + }, + ), + conversion: None, + format_spec: None, + }, + ), + ], + implicit_concatenated: false, }, ), - debug_text: Some( - DebugText { - leading: "", - trailing: " =", - }, - ), - conversion: None, - format_spec: None, }, ), ] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_self_doc_trailing_space.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_self_doc_trailing_space.snap index aa84db5f3f4fa..b7c6e8505810c 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_self_doc_trailing_space.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_self_doc_trailing_space.snap @@ -3,24 +3,37 @@ source: crates/ruff_python_parser/src/string.rs expression: parse_ast --- [ - FormattedValue( - ExprFormattedValue { - range: 2..9, - value: Name( - ExprName { - range: 3..4, - id: "x", - ctx: Load, + Expr( + StmtExpr { + range: 0..10, + value: FString( + ExprFString { + range: 0..10, + values: [ + FormattedValue( + ExprFormattedValue { + range: 2..9, + value: Name( + ExprName { + range: 3..4, + id: "x", + ctx: Load, + }, + ), + debug_text: Some( + DebugText { + leading: "", + trailing: "= ", + }, + ), + conversion: None, + format_spec: None, + }, + ), + ], + implicit_concatenated: false, }, ), - debug_text: Some( - DebugText { - leading: "", - trailing: "= ", - }, - ), - conversion: None, - format_spec: None, }, ), ] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_yield_expr.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_yield_expr.snap index d52ab525d43db..32693e49d7ac4 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_yield_expr.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__parse_fstring_yield_expr.snap @@ -3,18 +3,31 @@ source: crates/ruff_python_parser/src/string.rs expression: parse_ast --- [ - FormattedValue( - ExprFormattedValue { - range: 2..9, - value: Yield( - ExprYield { - range: 3..8, - value: None, + Expr( + StmtExpr { + range: 0..10, + value: FString( + ExprFString { + range: 0..10, + values: [ + FormattedValue( + ExprFormattedValue { + range: 2..9, + value: Yield( + ExprYield { + range: 3..8, + value: None, + }, + ), + debug_text: None, + conversion: None, + format_spec: None, + }, + ), + ], + implicit_concatenated: false, }, ), - debug_text: None, - conversion: None, - format_spec: None, }, ), ] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_mac_eol.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_mac_eol.snap new file mode 100644 index 0000000000000..451aae8765f97 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_mac_eol.snap @@ -0,0 +1,23 @@ +--- +source: crates/ruff_python_parser/src/string.rs +expression: parse_ast +--- +[ + Expr( + StmtExpr { + range: 0..18, + value: Constant( + ExprConstant { + range: 0..18, + value: Str( + StringConstant { + value: "text more text", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + }, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_unix_eol.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_unix_eol.snap new file mode 100644 index 0000000000000..451aae8765f97 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_unix_eol.snap @@ -0,0 +1,23 @@ +--- +source: crates/ruff_python_parser/src/string.rs +expression: parse_ast +--- +[ + Expr( + StmtExpr { + range: 0..18, + value: Constant( + ExprConstant { + range: 0..18, + value: Str( + StringConstant { + value: "text more text", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + }, + ), +] diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_windows_eol.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_windows_eol.snap new file mode 100644 index 0000000000000..9b839986a3f55 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__string__tests__string_parser_escaped_windows_eol.snap @@ -0,0 +1,23 @@ +--- +source: crates/ruff_python_parser/src/string.rs +expression: parse_ast +--- +[ + Expr( + StmtExpr { + range: 0..19, + value: Constant( + ExprConstant { + range: 0..19, + value: Str( + StringConstant { + value: "text more text", + unicode: false, + implicit_concatenated: false, + }, + ), + }, + ), + }, + ), +] diff --git a/crates/ruff_python_parser/src/string.rs b/crates/ruff_python_parser/src/string.rs index 0524473f1252e..81cbe2f9a1ce3 100644 --- a/crates/ruff_python_parser/src/string.rs +++ b/crates/ruff_python_parser/src/string.rs @@ -1,22 +1,61 @@ -use ruff_python_ast::ConversionFlag; +//! Parsing of string literals, bytes literals, and implicit string concatenation. + use ruff_python_ast::{self as ast, BytesConstant, Constant, Expr, StringConstant}; use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; -// Contains the logic for parsing string literals (mostly concerned with f-strings.) -// -// The lexer doesn't do any special handling of f-strings, it just treats them as -// regular strings. Since the ruff_python_parser has no definition of f-string formats (Pending PEP 701) -// we have to do the parsing here, manually. -use crate::{ - lexer::{LexicalError, LexicalErrorType}, - parse_expression_starts_at, - parser::{ParseError, ParseErrorType}, - token::{StringKind, Tok}, -}; +use crate::lexer::{LexicalError, LexicalErrorType}; +use crate::token::{StringKind, Tok}; // unicode_name2 does not expose `MAX_NAME_LENGTH`, so we replicate that constant here, fix #3798 const MAX_UNICODE_NAME: usize = 88; +pub(crate) struct StringConstantWithRange { + value: StringConstant, + range: TextRange, +} + +impl Ranged for StringConstantWithRange { + fn range(&self) -> TextRange { + self.range + } +} + +pub(crate) struct BytesConstantWithRange { + value: BytesConstant, + range: TextRange, +} + +impl Ranged for BytesConstantWithRange { + fn range(&self) -> TextRange { + self.range + } +} + +pub(crate) enum StringType { + Str(StringConstantWithRange), + Bytes(BytesConstantWithRange), + FString(ast::ExprFString), +} + +impl Ranged for StringType { + fn range(&self) -> TextRange { + match self { + Self::Str(node) => node.range(), + Self::Bytes(node) => node.range(), + Self::FString(node) => node.range(), + } + } +} + +impl StringType { + fn is_unicode(&self) -> bool { + match self { + Self::Str(StringConstantWithRange { value, .. }) => value.unicode, + _ => false, + } + } +} + struct StringParser<'a> { chars: std::str::Chars<'a>, kind: StringKind, @@ -24,17 +63,11 @@ struct StringParser<'a> { } impl<'a> StringParser<'a> { - fn new(source: &'a str, kind: StringKind, triple_quoted: bool, start: TextSize) -> Self { - let offset = kind.prefix_len() - + if triple_quoted { - TextSize::from(3) - } else { - TextSize::from(1) - }; + fn new(source: &'a str, kind: StringKind, start: TextSize) -> Self { Self { chars: source.chars(), kind, - location: start + offset, + location: start, } } @@ -50,13 +83,6 @@ impl<'a> StringParser<'a> { self.chars.clone().next() } - #[inline] - fn peek2(&mut self) -> Option { - let mut chars = self.chars.clone(); - chars.next(); - chars.next() - } - #[inline] fn get_pos(&self) -> TextSize { self.location @@ -152,6 +178,12 @@ impl<'a> StringParser<'a> { 'N' if !self.kind.is_any_bytes() => self.parse_unicode_name()?, // Special cases where the escape sequence is not a single character '\n' => return Ok(String::new()), + '\r' => { + if self.peek() == Some('\n') { + self.next_char(); + } + return Ok(String::new()); + } c => { if self.kind.is_any_bytes() && !c.is_ascii() { return Err(LexicalError { @@ -173,318 +205,51 @@ impl<'a> StringParser<'a> { } } - fn parse_formatted_value(&mut self, nested: u8) -> Result, LexicalError> { - use FStringErrorType::{ - EmptyExpression, InvalidConversionFlag, InvalidExpression, MismatchedDelimiter, - UnclosedLbrace, Unmatched, UnterminatedString, - }; - - let mut expression = String::new(); - // for self-documenting strings we also store the `=` and any trailing space inside - // expression (because we want to combine it with any trailing spaces before the equal - // sign). the expression_length is the length of the actual expression part that we pass to - // `parse_fstring_expr` - let mut expression_length = 0; - let mut spec = None; - let mut delimiters = Vec::new(); - let mut conversion = ConversionFlag::None; - let mut self_documenting = false; + fn parse_fstring_middle(&mut self) -> Result { + let mut value = String::new(); let start_location = self.get_pos(); - - assert_eq!(self.next_char(), Some('{')); - while let Some(ch) = self.next_char() { match ch { - // can be integrated better with the remaining code, but as a starting point ok - // in general I would do here a tokenizing of the fstrings to omit this peeking. - '!' | '=' | '>' | '<' if self.peek() == Some('=') => { - expression.push(ch); - expression.push('='); - self.next_char(); - } - '!' if delimiters.is_empty() && self.peek() != Some('=') => { - if expression.trim().is_empty() { - return Err(FStringError::new(EmptyExpression, self.get_pos()).into()); - } - - conversion = match self.next_char() { - Some('s') => ConversionFlag::Str, - Some('a') => ConversionFlag::Ascii, - Some('r') => ConversionFlag::Repr, - Some(_) => { - return Err( - FStringError::new(InvalidConversionFlag, self.get_pos()).into() - ); - } - None => { - return Err(FStringError::new(UnclosedLbrace, self.get_pos()).into()); - } - }; - - match self.peek() { - Some('}' | ':') => {} - Some(_) | None => { - return Err(FStringError::new(UnclosedLbrace, self.get_pos()).into()); - } - } - } - - // match a python 3.8 self documenting expression - // format '{' PYTHON_EXPRESSION '=' FORMAT_SPECIFIER? '}' - '=' if self.peek() != Some('=') && delimiters.is_empty() => { - expression_length = expression.len(); - expression.push(ch); - self_documenting = true; - } - - ':' if delimiters.is_empty() => { - let start_location = self.get_pos(); - let parsed_spec = self.parse_spec(nested)?; - - spec = Some(Box::new(Expr::from(ast::ExprFString { - values: parsed_spec, - implicit_concatenated: false, - range: self.range(start_location), - }))); - } - '(' | '{' | '[' => { - expression.push(ch); - delimiters.push(ch); - } - ')' => { - let last_delim = delimiters.pop(); - match last_delim { - Some('(') => { - expression.push(ch); - } - Some(c) => { - return Err(FStringError::new( - MismatchedDelimiter(c, ')'), - self.get_pos(), - ) - .into()); - } - None => { - return Err(FStringError::new(Unmatched(')'), self.get_pos()).into()); - } - } - } - ']' => { - let last_delim = delimiters.pop(); - match last_delim { - Some('[') => { - expression.push(ch); - } - Some(c) => { - return Err(FStringError::new( - MismatchedDelimiter(c, ']'), - self.get_pos(), - ) - .into()); - } - None => { - return Err(FStringError::new(Unmatched(']'), self.get_pos()).into()); - } - } - } - '}' if !delimiters.is_empty() => { - let last_delim = delimiters.pop(); - match last_delim { - Some('{') => { - expression.push(ch); - } - Some(c) => { - return Err(FStringError::new( - MismatchedDelimiter(c, '}'), - self.get_pos(), - ) - .into()); - } - None => {} - } - } - '}' => { - if expression.trim().is_empty() { - return Err(FStringError::new(EmptyExpression, self.get_pos()).into()); - } - - let ret = if self_documenting { - let value = - parse_fstring_expr(&expression[..expression_length], start_location) - .map_err(|e| { - FStringError::new( - InvalidExpression(Box::new(e.error)), - start_location, - ) - })?; - let leading = - &expression[..usize::from(value.start() - start_location) - 1]; - let trailing = &expression[usize::from(value.end() - start_location) - 1..]; - vec![Expr::from(ast::ExprFormattedValue { - value: Box::new(value), - debug_text: Some(ast::DebugText { - leading: leading.to_string(), - trailing: trailing.to_string(), - }), - conversion, - format_spec: spec, - range: self.range(start_location), - })] - } else { - vec![Expr::from(ast::ExprFormattedValue { - value: Box::new( - parse_fstring_expr(&expression, start_location).map_err(|e| { - FStringError::new( - InvalidExpression(Box::new(e.error)), - start_location, - ) - })?, - ), - debug_text: None, - conversion, - format_spec: spec, - range: self.range(start_location), - })] - }; - return Ok(ret); - } - '"' | '\'' => { - expression.push(ch); - loop { - let Some(c) = self.next_char() else { - return Err( - FStringError::new(UnterminatedString, self.get_pos()).into() - ); - }; - expression.push(c); - if c == ch { - break; - } - } - } - ' ' if self_documenting => expression.push(ch), - '\\' => return Err(FStringError::new(UnterminatedString, self.get_pos()).into()), - _ => { - if self_documenting { - return Err(FStringError::new(UnclosedLbrace, self.get_pos()).into()); - } - - expression.push(ch); - } - } - } - Err(FStringError::new(UnclosedLbrace, self.get_pos()).into()) - } - - fn parse_spec(&mut self, nested: u8) -> Result, LexicalError> { - let mut spec_constructor = Vec::new(); - let mut constant_piece = String::new(); - let mut start_location = self.get_pos(); - while let Some(next) = self.peek() { - match next { - '{' => { - if !constant_piece.is_empty() { - spec_constructor.push(Expr::from(ast::ExprConstant { - value: std::mem::take(&mut constant_piece).into(), - range: self.range(start_location), - })); - } - let parsed_expr = self.parse_fstring(nested + 1)?; - spec_constructor.extend(parsed_expr); - start_location = self.get_pos(); - continue; - } - '}' => { - break; - } - _ => { - constant_piece.push(next); - } - } - self.next_char(); - } - if !constant_piece.is_empty() { - spec_constructor.push(Expr::from(ast::ExprConstant { - value: std::mem::take(&mut constant_piece).into(), - range: self.range(start_location), - })); - } - Ok(spec_constructor) - } - - fn parse_fstring(&mut self, nested: u8) -> Result, LexicalError> { - use FStringErrorType::{ExpressionNestedTooDeeply, SingleRbrace, UnclosedLbrace}; - - if nested >= 2 { - return Err(FStringError::new(ExpressionNestedTooDeeply, self.get_pos()).into()); - } - - let mut content = String::new(); - let mut start_location = self.get_pos(); - let mut values = vec![]; - - while let Some(ch) = self.peek() { - match ch { - '{' => { - if nested == 0 { - match self.peek2() { - Some('{') => { - self.next_char(); - self.next_char(); - content.push('{'); - continue; - } - None => { - return Err(FStringError::new(UnclosedLbrace, self.get_pos()).into()) - } - _ => {} - } - } - if !content.is_empty() { - values.push(Expr::from(ast::ExprConstant { - value: std::mem::take(&mut content).into(), - range: self.range(start_location), - })); - } - - let parsed_values = self.parse_formatted_value(nested)?; - values.extend(parsed_values); - start_location = self.get_pos(); - } - '}' => { - if nested > 0 { - break; - } - self.next_char(); - if let Some('}') = self.peek() { - self.next_char(); - content.push('}'); - } else { - return Err(FStringError::new(SingleRbrace, self.get_pos()).into()); - } - } - '\\' if !self.kind.is_raw() => { - self.next_char(); - content.push_str(&self.parse_escaped_char()?); + // We can encounter a `\` as the last character in a `FStringMiddle` + // token which is valid in this context. For example, + // + // ```python + // f"\{foo} \{bar:\}" + // # ^ ^^ ^ + // ``` + // + // Here, the `FStringMiddle` token content will be "\" and " \" + // which is invalid if we look at the content in isolation: + // + // ```python + // "\" + // ``` + // + // However, the content is syntactically valid in the context of + // the f-string because it's a substring of the entire f-string. + // This is still an invalid escape sequence, but we don't want to + // raise a syntax error as is done by the CPython parser. It might + // be supported in the future, refer to point 3: https://peps.python.org/pep-0701/#rejected-ideas + '\\' if !self.kind.is_raw() && self.peek().is_some() => { + value.push_str(&self.parse_escaped_char()?); } - _ => { - content.push(ch); - self.next_char(); + // If there are any curly braces inside a `FStringMiddle` token, + // then they were escaped (i.e. `{{` or `}}`). This means that + // we need increase the location by 2 instead of 1. + ch @ ('{' | '}') => { + self.location += ch.text_len(); + value.push(ch); } + ch => value.push(ch), } } - - if !content.is_empty() { - values.push(Expr::from(ast::ExprConstant { - value: content.into(), - range: self.range(start_location), - })); - } - - Ok(values) + Ok(Expr::from(ast::ExprConstant { + value: value.into(), + range: self.range(start_location), + })) } - fn parse_bytes(&mut self) -> Result { + fn parse_bytes(&mut self) -> Result { let mut content = String::new(); let start_location = self.get_pos(); while let Some(ch) = self.next_char() { @@ -506,13 +271,13 @@ impl<'a> StringParser<'a> { } } - Ok(Expr::from(ast::ExprConstant { + Ok(StringType::Bytes(BytesConstantWithRange { value: content.chars().map(|c| c as u8).collect::>().into(), range: self.range(start_location), })) } - fn parse_string(&mut self) -> Result { + fn parse_string(&mut self) -> Result { let mut value = String::new(); let start_location = self.get_pos(); while let Some(ch) = self.next_char() { @@ -523,78 +288,92 @@ impl<'a> StringParser<'a> { ch => value.push(ch), } } - Ok(Expr::from(ast::ExprConstant { - value: ast::Constant::Str(ast::StringConstant { + Ok(StringType::Str(StringConstantWithRange { + value: StringConstant { value, unicode: self.kind.is_unicode(), implicit_concatenated: false, - }), + }, range: self.range(start_location), })) } - fn parse(&mut self) -> Result, LexicalError> { - if self.kind.is_any_fstring() { - self.parse_fstring(0) - } else if self.kind.is_any_bytes() { - self.parse_bytes().map(|expr| vec![expr]) + fn parse(&mut self) -> Result { + if self.kind.is_any_bytes() { + self.parse_bytes() } else { - self.parse_string().map(|expr| vec![expr]) + self.parse_string() } } } -fn parse_fstring_expr(source: &str, location: TextSize) -> Result { - let fstring_body = format!("({source})"); - parse_expression_starts_at(&fstring_body, "", location) -} - -fn parse_string( +pub(crate) fn parse_string_literal( source: &str, kind: StringKind, triple_quoted: bool, - start: TextSize, -) -> Result, LexicalError> { - StringParser::new(source, kind, triple_quoted, start).parse() + start_location: TextSize, +) -> Result { + let start_location = start_location + + kind.prefix_len() + + if triple_quoted { + TextSize::from(3) + } else { + TextSize::from(1) + }; + StringParser::new(source, kind, start_location).parse() +} + +pub(crate) fn parse_fstring_middle( + source: &str, + is_raw: bool, + start_location: TextSize, +) -> Result { + let kind = if is_raw { + StringKind::RawString + } else { + StringKind::String + }; + StringParser::new(source, kind, start_location).parse_fstring_middle() } -pub(crate) fn parse_strings( - values: Vec<(TextSize, (String, StringKind, bool), TextSize)>, +/// Concatenate a list of string literals into a single string expression. +pub(crate) fn concatenate_strings( + strings: Vec, + range: TextRange, ) -> Result { - // Preserve the initial location and kind. - let initial_start = values[0].0; - let last_end = values.last().unwrap().2; - let is_initial_kind_unicode = values[0].1 .1 == StringKind::Unicode; - let has_fstring = values - .iter() - .any(|(_, (_, kind, ..), _)| kind.is_any_fstring()); - let num_bytes = values - .iter() - .filter(|(_, (_, kind, ..), _)| kind.is_any_bytes()) - .count(); - let has_bytes = num_bytes > 0; - let implicit_concatenated = values.len() > 1; - - if has_bytes && num_bytes < values.len() { + #[cfg(debug_assertions)] + debug_assert!(!strings.is_empty()); + + let mut has_fstring = false; + let mut byte_literal_count = 0; + for string in &strings { + match string { + StringType::FString(_) => has_fstring = true, + StringType::Bytes(_) => byte_literal_count += 1, + StringType::Str(_) => {} + } + } + let has_bytes = byte_literal_count > 0; + let implicit_concatenated = strings.len() > 1; + + if has_bytes && byte_literal_count < strings.len() { return Err(LexicalError { error: LexicalErrorType::OtherError( "cannot mix bytes and nonbytes literals".to_owned(), ), - location: initial_start, + location: range.start(), }); } if has_bytes { let mut content: Vec = vec![]; - for (start, (source, kind, triple_quoted), _) in values { - for value in parse_string(&source, kind, triple_quoted, start)? { - match value { - Expr::Constant(ast::ExprConstant { - value: Constant::Bytes(BytesConstant { value, .. }), - .. - }) => content.extend(value), - _ => unreachable!("Unexpected non-bytes expression."), - } + for string in strings { + match string { + StringType::Bytes(BytesConstantWithRange { + value: BytesConstant { value, .. }, + .. + }) => content.extend(value), + _ => unreachable!("Unexpected non-bytes literal."), } } return Ok(ast::ExprConstant { @@ -602,85 +381,115 @@ pub(crate) fn parse_strings( value: content, implicit_concatenated, }), - range: TextRange::new(initial_start, last_end), + range, } .into()); } if !has_fstring { - let mut content: Vec = vec![]; - for (start, (source, kind, triple_quoted), _) in values { - for value in parse_string(&source, kind, triple_quoted, start)? { - match value { - Expr::Constant(ast::ExprConstant { - value: Constant::Str(StringConstant { value, .. }), - .. - }) => content.push(value), - _ => unreachable!("Unexpected non-string expression."), - } + let mut content = String::new(); + let is_unicode = strings.first().map_or(false, StringType::is_unicode); + for string in strings { + match string { + StringType::Str(StringConstantWithRange { + value: StringConstant { value, .. }, + .. + }) => content.push_str(&value), + _ => unreachable!("Unexpected non-string literal."), } } return Ok(ast::ExprConstant { value: Constant::Str(StringConstant { - value: content.join(""), - unicode: is_initial_kind_unicode, + value: content, + unicode: is_unicode, implicit_concatenated, }), - range: TextRange::new(initial_start, last_end), + range, } .into()); } // De-duplicate adjacent constants. let mut deduped: Vec = vec![]; - let mut current: Vec = vec![]; - let mut current_start = initial_start; - let mut current_end = last_end; + let mut current = String::new(); + let mut current_start = range.start(); + let mut current_end = range.end(); + let mut is_unicode = false; - let take_current = |current: &mut Vec, start, end| -> Expr { + let take_current = |current: &mut String, start, end, unicode| -> Expr { Expr::Constant(ast::ExprConstant { value: Constant::Str(StringConstant { - value: current.drain(..).collect::(), - unicode: is_initial_kind_unicode, + value: std::mem::take(current), + unicode, implicit_concatenated, }), range: TextRange::new(start, end), }) }; - for (start, (source, kind, triple_quoted), _) in values { - for value in parse_string(&source, kind, triple_quoted, start)? { - let value_range = value.range(); - match value { - Expr::FormattedValue { .. } => { - if !current.is_empty() { - deduped.push(take_current(&mut current, current_start, current_end)); + for string in strings { + let string_range = string.range(); + match string { + StringType::FString(ast::ExprFString { values, .. }) => { + for value in values { + let value_range = value.range(); + match value { + Expr::FormattedValue { .. } => { + if !current.is_empty() { + deduped.push(take_current( + &mut current, + current_start, + current_end, + is_unicode, + )); + } + deduped.push(value); + is_unicode = false; + } + Expr::Constant(ast::ExprConstant { + value: Constant::Str(StringConstant { value, unicode, .. }), + .. + }) => { + if current.is_empty() { + is_unicode |= unicode; + current_start = value_range.start(); + } + current_end = value_range.end(); + current.push_str(&value); + } + _ => unreachable!("Expected `Expr::FormattedValue` or `Expr::Constant`"), } - deduped.push(value); } - Expr::Constant(ast::ExprConstant { - value: Constant::Str(StringConstant { value, .. }), - .. - }) => { - if current.is_empty() { - current_start = value_range.start(); - } - current_end = value_range.end(); - current.push(value); + } + StringType::Str(StringConstantWithRange { + value: StringConstant { value, unicode, .. }, + .. + }) => { + if current.is_empty() { + is_unicode |= unicode; + current_start = string_range.start(); } - _ => unreachable!("Unexpected non-string expression."), + current_end = string_range.end(); + current.push_str(&value); } + StringType::Bytes(_) => unreachable!("Unexpected bytes literal."), } } if !current.is_empty() { - deduped.push(take_current(&mut current, current_start, current_end)); + deduped.push(take_current( + &mut current, + current_start, + current_end, + is_unicode, + )); } - Ok(Expr::FString(ast::ExprFString { + Ok(ast::ExprFString { values: deduped, implicit_concatenated, - range: TextRange::new(initial_start, last_end), - })) + range, + } + .into()) } // TODO: consolidate these with ParseError @@ -693,13 +502,6 @@ struct FStringError { pub(crate) location: TextSize, } -impl FStringError { - /// Creates a new `FStringError` with the given error type and location. - pub(crate) fn new(error: FStringErrorType, location: TextSize) -> Self { - Self { error, location } - } -} - impl From for LexicalError { fn from(err: FStringError) -> Self { LexicalError { @@ -714,59 +516,34 @@ impl From for LexicalError { pub enum FStringErrorType { /// Expected a right brace after an opened left brace. UnclosedLbrace, - /// An error occurred while parsing an f-string expression. - InvalidExpression(Box), /// An invalid conversion flag was encountered. InvalidConversionFlag, - /// An empty expression was encountered. - EmptyExpression, - /// An opening delimiter was not closed properly. - MismatchedDelimiter(char, char), - /// Too many nested expressions in an f-string. - ExpressionNestedTooDeeply, - /// The f-string expression cannot include the given character. - ExpressionCannotInclude(char), /// A single right brace was encountered. SingleRbrace, - /// A closing delimiter was not opened properly. - Unmatched(char), - // TODO: Test this case. /// Unterminated string. UnterminatedString, + /// Unterminated triple-quoted string. + UnterminatedTripleQuotedString, + // TODO(dhruvmanila): The parser can't catch all cases of this error, but + // wherever it can, we'll display the correct error message. + /// A lambda expression without parentheses was encountered. + LambdaWithoutParentheses, } impl std::fmt::Display for FStringErrorType { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { use FStringErrorType::{ - EmptyExpression, ExpressionCannotInclude, ExpressionNestedTooDeeply, - InvalidConversionFlag, InvalidExpression, MismatchedDelimiter, SingleRbrace, - UnclosedLbrace, Unmatched, UnterminatedString, + InvalidConversionFlag, LambdaWithoutParentheses, SingleRbrace, UnclosedLbrace, + UnterminatedString, UnterminatedTripleQuotedString, }; match self { UnclosedLbrace => write!(f, "expecting '}}'"), - InvalidExpression(error) => { - write!(f, "{error}") - } InvalidConversionFlag => write!(f, "invalid conversion character"), - EmptyExpression => write!(f, "empty expression not allowed"), - MismatchedDelimiter(first, second) => write!( - f, - "closing parenthesis '{second}' does not match opening parenthesis '{first}'" - ), SingleRbrace => write!(f, "single '}}' is not allowed"), - Unmatched(delim) => write!(f, "unmatched '{delim}'"), - ExpressionNestedTooDeeply => { - write!(f, "expressions nested too deeply") - } - UnterminatedString => { - write!(f, "unterminated string") - } - ExpressionCannotInclude(c) => { - if *c == '\\' { - write!(f, "f-string expression part cannot include a backslash") - } else { - write!(f, "f-string expression part cannot include '{c}'s") - } + UnterminatedString => write!(f, "unterminated string"), + UnterminatedTripleQuotedString => write!(f, "unterminated triple-quoted string"), + LambdaWithoutParentheses => { + write!(f, "lambda expressions are not allowed without parentheses") } } } @@ -785,70 +562,96 @@ impl From for crate::parser::LalrpopError Suite { + let source = format!(r"'text \{eol}more text'"); + parse_suite(&source, "").unwrap() + } + + #[test] + fn test_string_parser_escaped_unix_eol() { + let parse_ast = string_parser_escaped_eol(UNIX_EOL); + insta::assert_debug_snapshot!(parse_ast); + } + + #[test] + fn test_string_parser_escaped_mac_eol() { + let parse_ast = string_parser_escaped_eol(MAC_EOL); + insta::assert_debug_snapshot!(parse_ast); + } - fn parse_fstring(source: &str) -> Result, LexicalError> { - StringParser::new(source, StringKind::FString, false, TextSize::default()).parse() + #[test] + fn test_string_parser_escaped_windows_eol() { + let parse_ast = string_parser_escaped_eol(WINDOWS_EOL); + insta::assert_debug_snapshot!(parse_ast); } #[test] fn test_parse_fstring() { - let source = "{a}{ b }{{foo}}"; - let parse_ast = parse_fstring(source).unwrap(); + let source = r#"f"{a}{ b }{{foo}}""#; + let parse_ast = parse_suite(source, "").unwrap(); insta::assert_debug_snapshot!(parse_ast); } #[test] fn test_parse_fstring_nested_spec() { - let source = "{foo:{spec}}"; - let parse_ast = parse_fstring(source).unwrap(); + let source = r#"f"{foo:{spec}}""#; + let parse_ast = parse_suite(source, "").unwrap(); insta::assert_debug_snapshot!(parse_ast); } #[test] fn test_parse_fstring_not_nested_spec() { - let source = "{foo:spec}"; - let parse_ast = parse_fstring(source).unwrap(); + let source = r#"f"{foo:spec}""#; + let parse_ast = parse_suite(source, "").unwrap(); insta::assert_debug_snapshot!(parse_ast); } #[test] fn test_parse_empty_fstring() { - insta::assert_debug_snapshot!(parse_fstring("").unwrap()); + insta::assert_debug_snapshot!(parse_suite(r#"f"""#, "").unwrap()); } #[test] fn test_fstring_parse_self_documenting_base() { - let src = "{user=}"; - let parse_ast = parse_fstring(src).unwrap(); + let source = r#"f"{user=}""#; + let parse_ast = parse_suite(source, "").unwrap(); insta::assert_debug_snapshot!(parse_ast); } #[test] fn test_fstring_parse_self_documenting_base_more() { - let src = "mix {user=} with text and {second=}"; - let parse_ast = parse_fstring(src).unwrap(); + let source = r#"f"mix {user=} with text and {second=}""#; + let parse_ast = parse_suite(source, "").unwrap(); insta::assert_debug_snapshot!(parse_ast); } #[test] fn test_fstring_parse_self_documenting_format() { - let src = "{user=:>10}"; - let parse_ast = parse_fstring(src).unwrap(); + let source = r#"f"{user=:>10}""#; + let parse_ast = parse_suite(source, "").unwrap(); insta::assert_debug_snapshot!(parse_ast); } fn parse_fstring_error(source: &str) -> FStringErrorType { - parse_fstring(source) + parse_suite(source, "") .map_err(|e| match e.error { - LexicalErrorType::FStringError(e) => e, + ParseErrorType::Lexical(LexicalErrorType::FStringError(e)) => e, e => unreachable!("Expected FStringError: {:?}", e), }) .expect_err("Expected error") @@ -856,68 +659,52 @@ mod tests { #[test] fn test_parse_invalid_fstring() { - use FStringErrorType::{ - EmptyExpression, ExpressionNestedTooDeeply, InvalidConversionFlag, SingleRbrace, - UnclosedLbrace, - }; - assert_eq!(parse_fstring_error("{5!a"), UnclosedLbrace); - assert_eq!(parse_fstring_error("{5!a1}"), UnclosedLbrace); - assert_eq!(parse_fstring_error("{5!"), UnclosedLbrace); - assert_eq!(parse_fstring_error("abc{!a 'cat'}"), EmptyExpression); - assert_eq!(parse_fstring_error("{!a"), EmptyExpression); - assert_eq!(parse_fstring_error("{ !a}"), EmptyExpression); - - assert_eq!(parse_fstring_error("{5!}"), InvalidConversionFlag); - assert_eq!(parse_fstring_error("{5!x}"), InvalidConversionFlag); + use FStringErrorType::{InvalidConversionFlag, LambdaWithoutParentheses}; + assert_eq!(parse_fstring_error(r#"f"{5!x}""#), InvalidConversionFlag); assert_eq!( - parse_fstring_error("{a:{a:{b}}}"), - ExpressionNestedTooDeeply + parse_fstring_error("f'{lambda x:{x}}'"), + LambdaWithoutParentheses ); - - assert_eq!(parse_fstring_error("{a:b}}"), SingleRbrace); - assert_eq!(parse_fstring_error("}"), SingleRbrace); - assert_eq!(parse_fstring_error("{a:{b}"), UnclosedLbrace); - assert_eq!(parse_fstring_error("{"), UnclosedLbrace); - - assert_eq!(parse_fstring_error("{}"), EmptyExpression); - - // TODO: check for InvalidExpression enum? - assert!(parse_fstring("{class}").is_err()); + assert_eq!( + parse_fstring_error("f'{lambda x: {x}}'"), + LambdaWithoutParentheses + ); + assert!(parse_suite(r#"f"{class}""#, "").is_err()); } #[test] fn test_parse_fstring_not_equals() { - let source = "{1 != 2}"; - let parse_ast = parse_fstring(source).unwrap(); + let source = r#"f"{1 != 2}""#; + let parse_ast = parse_suite(source, "").unwrap(); insta::assert_debug_snapshot!(parse_ast); } #[test] fn test_parse_fstring_equals() { - let source = "{42 == 42}"; - let parse_ast = parse_fstring(source).unwrap(); + let source = r#"f"{42 == 42}""#; + let parse_ast = parse_suite(source, "").unwrap(); insta::assert_debug_snapshot!(parse_ast); } #[test] fn test_parse_fstring_self_doc_prec_space() { - let source = "{x =}"; - let parse_ast = parse_fstring(source).unwrap(); + let source = r#"f"{x =}""#; + let parse_ast = parse_suite(source, "").unwrap(); insta::assert_debug_snapshot!(parse_ast); } #[test] fn test_parse_fstring_self_doc_trailing_space() { - let source = "{x= }"; - let parse_ast = parse_fstring(source).unwrap(); + let source = r#"f"{x= }""#; + let parse_ast = parse_suite(source, "").unwrap(); insta::assert_debug_snapshot!(parse_ast); } #[test] fn test_parse_fstring_yield_expr() { - let source = "{yield}"; - let parse_ast = parse_fstring(source).unwrap(); + let source = r#"f"{yield}""#; + let parse_ast = parse_suite(source, "").unwrap(); insta::assert_debug_snapshot!(parse_ast); } @@ -1089,16 +876,16 @@ mod tests { #[test] fn test_parse_fstring_nested_string_spec() { - let source = "{foo:{''}}"; - let parse_ast = parse_fstring(source).unwrap(); + let source = r#"f"{foo:{''}}""#; + let parse_ast = parse_suite(source, "").unwrap(); insta::assert_debug_snapshot!(parse_ast); } #[test] fn test_parse_fstring_nested_concatenation_string_spec() { - let source = "{foo:{'' ''}}"; - let parse_ast = parse_fstring(source).unwrap(); + let source = r#"f"{foo:{'' ''}}""#; + let parse_ast = parse_suite(source, "").unwrap(); insta::assert_debug_snapshot!(parse_ast); } diff --git a/crates/ruff_python_parser/src/token.rs b/crates/ruff_python_parser/src/token.rs index 9bec604b8d495..ac441395fffc2 100644 --- a/crates/ruff_python_parser/src/token.rs +++ b/crates/ruff_python_parser/src/token.rs @@ -5,8 +5,8 @@ //! //! [CPython source]: https://github.com/python/cpython/blob/dfc2e065a2e71011017077e549cd2f9bf4944c54/Include/internal/pycore_token.h; use crate::Mode; -use num_bigint::BigInt; -use ruff_python_ast::IpyEscapeKind; + +use ruff_python_ast::{Int, IpyEscapeKind}; use ruff_text_size::TextSize; use std::fmt; @@ -21,7 +21,7 @@ pub enum Tok { /// Token value for an integer. Int { /// The integer value. - value: BigInt, + value: Int, }, /// Token value for a floating point number. Float { @@ -44,6 +44,19 @@ pub enum Tok { /// Whether the string is triple quoted. triple_quoted: bool, }, + /// Token value for the start of an f-string. This includes the `f`/`F`/`fr` prefix + /// and the opening quote(s). + FStringStart, + /// Token value that includes the portion of text inside the f-string that's not + /// part of the expression part and isn't an opening or closing brace. + FStringMiddle { + /// The string value. + value: String, + /// Whether the string is raw or not. + is_raw: bool, + }, + /// Token value for the end of an f-string. This includes the closing quote. + FStringEnd, /// Token value for IPython escape commands. These are recognized by the lexer /// only when the mode is [`Mode::Ipython`]. IpyEscapeCommand { @@ -66,6 +79,8 @@ pub enum Tok { EndOfFile, /// Token value for a question mark `?`. This is only used in [`Mode::Ipython`]. Question, + /// Token value for a exclamation mark `!`. + Exclamation, /// Token value for a left parenthesis `(`. Lpar, /// Token value for a right parenthesis `)`. @@ -234,6 +249,9 @@ impl fmt::Display for Tok { let quotes = "\"".repeat(if *triple_quoted { 3 } else { 1 }); write!(f, "{kind}{quotes}{value}{quotes}") } + FStringStart => f.write_str("FStringStart"), + FStringMiddle { value, .. } => f.write_str(value), + FStringEnd => f.write_str("FStringEnd"), IpyEscapeCommand { kind, value } => write!(f, "{kind}{value}"), Newline => f.write_str("Newline"), NonLogicalNewline => f.write_str("NonLogicalNewline"), @@ -243,6 +261,7 @@ impl fmt::Display for Tok { StartExpression => f.write_str("StartExpression"), EndOfFile => f.write_str("EOF"), Question => f.write_str("'?'"), + Exclamation => f.write_str("'!'"), Lpar => f.write_str("'('"), Rpar => f.write_str("')'"), Lsqb => f.write_str("'['"), @@ -336,19 +355,19 @@ impl fmt::Display for Tok { /// The kind of string literal as described in the [String and Bytes literals] /// section of the Python reference. /// +/// Note that f-strings are not included here, because as of [PEP 701] they +/// emit different tokens than other string literals. +/// /// [String and Bytes literals]: https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals +/// [PEP 701]: https://peps.python.org/pep-0701/ #[derive(PartialEq, Eq, Debug, Clone, Hash, Copy)] // TODO: is_macro::Is pub enum StringKind { /// A normal string literal with no prefix. String, - /// A f-string literal, with a `f` or `F` prefix. - FString, /// A byte string literal, with a `b` or `B` prefix. Bytes, /// A raw string literal, with a `r` or `R` prefix. RawString, - /// A raw f-string literal, with a `rf`/`fr` or `rF`/`Fr` or `Rf`/`fR` or `RF`/`FR` prefix. - RawFString, /// A raw byte string literal, with a `rb`/`br` or `rB`/`Br` or `Rb`/`bR` or `RB`/`BR` prefix. RawBytes, /// A unicode string literal, with a `u` or `U` prefix. @@ -361,7 +380,6 @@ impl TryFrom for StringKind { fn try_from(ch: char) -> Result { match ch { 'r' | 'R' => Ok(StringKind::RawString), - 'f' | 'F' => Ok(StringKind::FString), 'u' | 'U' => Ok(StringKind::Unicode), 'b' | 'B' => Ok(StringKind::Bytes), c => Err(format!("Unexpected string prefix: {c}")), @@ -374,8 +392,6 @@ impl TryFrom<[char; 2]> for StringKind { fn try_from(chars: [char; 2]) -> Result { match chars { - ['r' | 'R', 'f' | 'F'] => Ok(StringKind::RawFString), - ['f' | 'F', 'r' | 'R'] => Ok(StringKind::RawFString), ['r' | 'R', 'b' | 'B'] => Ok(StringKind::RawBytes), ['b' | 'B', 'r' | 'R'] => Ok(StringKind::RawBytes), [c1, c2] => Err(format!("Unexpected string prefix: {c1}{c2}")), @@ -385,32 +401,16 @@ impl TryFrom<[char; 2]> for StringKind { impl fmt::Display for StringKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use StringKind::{Bytes, FString, RawBytes, RawFString, RawString, String, Unicode}; - match self { - String => f.write_str(""), - FString => f.write_str("f"), - Bytes => f.write_str("b"), - RawString => f.write_str("r"), - RawFString => f.write_str("rf"), - RawBytes => f.write_str("rb"), - Unicode => f.write_str("u"), - } + f.write_str(self.as_str()) } } impl StringKind { /// Returns true if the string is a raw string, i,e one of - /// [`StringKind::RawString`] or [`StringKind::RawFString`] or [`StringKind::RawBytes`]. + /// [`StringKind::RawString`] or [`StringKind::RawBytes`]. pub fn is_raw(&self) -> bool { - use StringKind::{RawBytes, RawFString, RawString}; - matches!(self, RawString | RawFString | RawBytes) - } - - /// Returns true if the string is an f-string, i,e one of - /// [`StringKind::FString`] or [`StringKind::RawFString`]. - pub fn is_any_fstring(&self) -> bool { - use StringKind::{FString, RawFString}; - matches!(self, FString | RawFString) + use StringKind::{RawBytes, RawString}; + matches!(self, RawString | RawBytes) } /// Returns true if the string is a byte string, i,e one of @@ -427,14 +427,25 @@ impl StringKind { /// Returns the number of characters in the prefix. pub fn prefix_len(&self) -> TextSize { - use StringKind::{Bytes, FString, RawBytes, RawFString, RawString, String, Unicode}; + use StringKind::{Bytes, RawBytes, RawString, String, Unicode}; let len = match self { String => 0, - RawString | FString | Unicode | Bytes => 1, - RawFString | RawBytes => 2, + RawString | Unicode | Bytes => 1, + RawBytes => 2, }; len.into() } + + pub fn as_str(&self) -> &'static str { + use StringKind::{Bytes, RawBytes, RawString, String, Unicode}; + match self { + String => "", + Bytes => "b", + RawString => "r", + RawBytes => "rb", + Unicode => "u", + } + } } // TODO move to ruff_python_parser? @@ -450,6 +461,14 @@ pub enum TokenKind { Complex, /// Token value for a string. String, + /// Token value for the start of an f-string. This includes the `f`/`F`/`fr` prefix + /// and the opening quote(s). + FStringStart, + /// Token value that includes the portion of text inside the f-string that's not + /// part of the expression part and isn't an opening or closing brace. + FStringMiddle, + /// Token value for the end of an f-string. This includes the closing quote. + FStringEnd, /// Token value for a IPython escape command. EscapeCommand, /// Token value for a comment. These are filtered out of the token stream prior to parsing. @@ -466,6 +485,8 @@ pub enum TokenKind { EndOfFile, /// Token value for a question mark `?`. Question, + /// Token value for an exclamation mark `!`. + Exclamation, /// Token value for a left parenthesis `(`. Lpar, /// Token value for a right parenthesis `)`. @@ -781,6 +802,9 @@ impl TokenKind { Tok::Float { .. } => TokenKind::Float, Tok::Complex { .. } => TokenKind::Complex, Tok::String { .. } => TokenKind::String, + Tok::FStringStart => TokenKind::FStringStart, + Tok::FStringMiddle { .. } => TokenKind::FStringMiddle, + Tok::FStringEnd => TokenKind::FStringEnd, Tok::IpyEscapeCommand { .. } => TokenKind::EscapeCommand, Tok::Comment(_) => TokenKind::Comment, Tok::Newline => TokenKind::Newline, @@ -789,6 +813,7 @@ impl TokenKind { Tok::Dedent => TokenKind::Dedent, Tok::EndOfFile => TokenKind::EndOfFile, Tok::Question => TokenKind::Question, + Tok::Exclamation => TokenKind::Exclamation, Tok::Lpar => TokenKind::Lpar, Tok::Rpar => TokenKind::Rpar, Tok::Lsqb => TokenKind::Lsqb, diff --git a/crates/ruff_python_semantic/Cargo.toml b/crates/ruff_python_semantic/Cargo.toml index 58484d140d24b..602a0e27c1b31 100644 --- a/crates/ruff_python_semantic/Cargo.toml +++ b/crates/ruff_python_semantic/Cargo.toml @@ -21,7 +21,6 @@ ruff_text_size = { path = "../ruff_text_size" } bitflags = { workspace = true } is-macro = { workspace = true } -num-traits = { workspace = true } rustc-hash = { workspace = true } smallvec = { workspace = true } diff --git a/crates/ruff_python_semantic/src/analyze/typing.rs b/crates/ruff_python_semantic/src/analyze/typing.rs index 707d55553c30a..c1fcab65a82f4 100644 --- a/crates/ruff_python_semantic/src/analyze/typing.rs +++ b/crates/ruff_python_semantic/src/analyze/typing.rs @@ -1,14 +1,10 @@ //! Analysis rules for the `typing` module. -use num_traits::identities::Zero; +use ruff_python_ast::call_path::{from_qualified_name, from_unqualified_name, CallPath}; +use ruff_python_ast::helpers::{any_over_expr, is_const_false, map_subscript}; use ruff_python_ast::{ - self as ast, Constant, Expr, Operator, ParameterWithDefault, Parameters, Stmt, + self as ast, Constant, Expr, Int, Operator, ParameterWithDefault, Parameters, Stmt, }; - -use crate::analyze::type_inference::{PythonType, ResolvedPythonType}; -use crate::{Binding, BindingKind}; -use ruff_python_ast::call_path::{from_qualified_name, from_unqualified_name, CallPath}; -use ruff_python_ast::helpers::{is_const_false, map_subscript}; use ruff_python_stdlib::typing::{ as_pep_585_generic, has_pep_585_generic, is_immutable_generic_type, is_immutable_non_generic_type, is_immutable_return_type, is_literal_member, @@ -17,7 +13,9 @@ use ruff_python_stdlib::typing::{ }; use ruff_text_size::Ranged; +use crate::analyze::type_inference::{PythonType, ResolvedPythonType}; use crate::model::SemanticModel; +use crate::{Binding, BindingKind}; #[derive(Copy, Clone)] pub enum Callable { @@ -304,7 +302,7 @@ pub fn is_mutable_expr(expr: &Expr, semantic: &SemanticModel) -> bool { } } -/// Return `true` if [`Expr`] is a guard for a type-checking block. +/// Return `true` if [`ast::StmtIf`] is a guard for a type-checking block. pub fn is_type_checking_block(stmt: &ast::StmtIf, semantic: &SemanticModel) -> bool { let ast::StmtIf { test, .. } = stmt; @@ -314,14 +312,14 @@ pub fn is_type_checking_block(stmt: &ast::StmtIf, semantic: &SemanticModel) -> b } // Ex) `if 0:` - if let Expr::Constant(ast::ExprConstant { - value: Constant::Int(value), - .. - }) = test.as_ref() - { - if value.is_zero() { - return true; - } + if matches!( + test.as_ref(), + Expr::Constant(ast::ExprConstant { + value: Constant::Int(Int::ZERO), + .. + }) + ) { + return true; } // Ex) `if typing.TYPE_CHECKING:` @@ -335,6 +333,17 @@ pub fn is_type_checking_block(stmt: &ast::StmtIf, semantic: &SemanticModel) -> b false } +/// Returns `true` if the [`ast::StmtIf`] is a version-checking block (e.g., `if sys.version_info >= ...:`). +pub fn is_sys_version_block(stmt: &ast::StmtIf, semantic: &SemanticModel) -> bool { + let ast::StmtIf { test, .. } = stmt; + + any_over_expr(test, &|expr| { + semantic.resolve_call_path(expr).is_some_and(|call_path| { + matches!(call_path.as_slice(), ["sys", "version_info" | "platform"]) + }) + }) +} + /// Abstraction for a type checker, conservatively checks for the intended type(s). trait TypeChecker { /// Check annotation expression to match the intended type(s). @@ -487,6 +496,14 @@ impl BuiltinTypeChecker for SetChecker { const EXPR_TYPE: PythonType = PythonType::Set; } +struct TupleChecker; + +impl BuiltinTypeChecker for TupleChecker { + const BUILTIN_TYPE_NAME: &'static str = "tuple"; + const TYPING_NAME: &'static str = "Tuple"; + const EXPR_TYPE: PythonType = PythonType::Tuple; +} + /// Test whether the given binding (and the given name) can be considered a list. /// For this, we check what value might be associated with it through it's initialization and /// what annotation it has (we consider `list` and `typing.List`). @@ -508,6 +525,14 @@ pub fn is_set(binding: &Binding, semantic: &SemanticModel) -> bool { check_type::(binding, semantic) } +/// Test whether the given binding (and the given name) can be considered a +/// tuple. For this, we check what value might be associated with it through +/// it's initialization and what annotation it has (we consider `tuple` and +/// `typing.Tuple`). +pub fn is_tuple(binding: &Binding, semantic: &SemanticModel) -> bool { + check_type::(binding, semantic) +} + /// Find the [`ParameterWithDefault`] corresponding to the given [`Binding`]. #[inline] fn find_parameter<'a>( diff --git a/crates/ruff_python_semantic/src/model.rs b/crates/ruff_python_semantic/src/model.rs index f8e3f8438661c..c9187aa39fba9 100644 --- a/crates/ruff_python_semantic/src/model.rs +++ b/crates/ruff_python_semantic/src/model.rs @@ -887,11 +887,9 @@ impl<'a> SemanticModel<'a> { .filter(|id| self.nodes[*id].is_statement()) } - /// Return the [`NodeId`] of the current [`Stmt`]. - pub fn current_statement_id(&self) -> NodeId { - self.current_statement_ids() - .next() - .expect("No current statement") + /// Return the [`NodeId`] of the current [`Stmt`], if any. + pub fn current_statement_id(&self) -> Option { + self.current_statement_ids().next() } /// Return the [`NodeId`] of the current [`Stmt`] parent, if any. @@ -1161,7 +1159,7 @@ impl<'a> SemanticModel<'a> { pub fn add_delayed_annotation(&mut self, binding_id: BindingId, annotation_id: BindingId) { self.delayed_annotations .entry(binding_id) - .or_insert_with(Vec::new) + .or_default() .push(annotation_id); } @@ -1175,7 +1173,7 @@ impl<'a> SemanticModel<'a> { pub fn add_rebinding_scope(&mut self, binding_id: BindingId, scope_id: ScopeId) { self.rebinding_scopes .entry(binding_id) - .or_insert_with(Vec::new) + .or_default() .push(scope_id); } @@ -1602,6 +1600,16 @@ bitflags! { /// ``` const FUTURE_ANNOTATIONS = 1 << 14; + /// The model is in a type parameter definition. + /// + /// For example, the model could be visiting `Record` in: + /// ```python + /// from typing import TypeVar + /// + /// Record = TypeVar("Record") + /// + const TYPE_PARAM_DEFINITION = 1 << 15; + /// The context is in any type annotation. const ANNOTATION = Self::TYPING_ONLY_ANNOTATION.bits() | Self::RUNTIME_ANNOTATION.bits(); @@ -1612,11 +1620,12 @@ bitflags! { /// The context is in any deferred type definition. const DEFERRED_TYPE_DEFINITION = Self::SIMPLE_STRING_TYPE_DEFINITION.bits() | Self::COMPLEX_STRING_TYPE_DEFINITION.bits() - | Self::FUTURE_TYPE_DEFINITION.bits(); + | Self::FUTURE_TYPE_DEFINITION.bits() + | Self::TYPE_PARAM_DEFINITION.bits(); /// The context is in a typing-only context. const TYPING_CONTEXT = Self::TYPE_CHECKING_BLOCK.bits() | Self::TYPING_ONLY_ANNOTATION.bits() | - Self::STRING_TYPE_DEFINITION.bits(); + Self::STRING_TYPE_DEFINITION.bits() | Self::TYPE_PARAM_DEFINITION.bits(); } } diff --git a/crates/ruff_python_semantic/src/nodes.rs b/crates/ruff_python_semantic/src/nodes.rs index 3a95b2e8e2c3c..37bd797442eb0 100644 --- a/crates/ruff_python_semantic/src/nodes.rs +++ b/crates/ruff_python_semantic/src/nodes.rs @@ -74,11 +74,11 @@ impl<'a> Index for Nodes<'a> { } } -/// A reference to an AST node. Like [`ruff_python_ast::node::AnyNodeRef`], but wraps the node +/// A reference to an AST node. Like [`ruff_python_ast::AnyNodeRef`], but wraps the node /// itself (like [`Stmt`]) rather than the narrowed type (like [`ruff_python_ast::StmtAssign`]). /// -/// TODO(charlie): Replace with [`ruff_python_ast::node::AnyNodeRef`]. This requires migrating -/// the rest of the codebase to use [`ruff_python_ast::node::AnyNodeRef`] and related abstractions, +/// TODO(charlie): Replace with [`ruff_python_ast::AnyNodeRef`]. This requires migrating +/// the rest of the codebase to use [`ruff_python_ast::AnyNodeRef`] and related abstractions, /// like [`ruff_python_ast::ExpressionRef`] instead of [`Expr`]. #[derive(Copy, Clone, Debug, PartialEq)] pub enum NodeRef<'a> { diff --git a/crates/ruff_python_stdlib/src/builtins.rs b/crates/ruff_python_stdlib/src/builtins.rs index c39ce21cdfc39..56412a19f6f87 100644 --- a/crates/ruff_python_stdlib/src/builtins.rs +++ b/crates/ruff_python_stdlib/src/builtins.rs @@ -337,3 +337,11 @@ pub fn is_builtin(name: &str) -> bool { | "zip" ) } + +/// Returns `true` if the given name is that of a Python builtin iterator. +pub fn is_iterator(name: &str) -> bool { + matches!( + name, + "enumerate" | "filter" | "map" | "reversed" | "zip" | "iter" + ) +} diff --git a/crates/ruff_python_trivia/src/lib.rs b/crates/ruff_python_trivia/src/lib.rs index 9c9bb8158c74c..9fed887c17ff4 100644 --- a/crates/ruff_python_trivia/src/lib.rs +++ b/crates/ruff_python_trivia/src/lib.rs @@ -1,10 +1,12 @@ mod comment_ranges; mod cursor; +mod pragmas; pub mod textwrap; mod tokenizer; mod whitespace; pub use comment_ranges::CommentRanges; pub use cursor::*; +pub use pragmas::*; pub use tokenizer::*; pub use whitespace::*; diff --git a/crates/ruff_python_trivia/src/pragmas.rs b/crates/ruff_python_trivia/src/pragmas.rs new file mode 100644 index 0000000000000..7fe50d71a0eb8 --- /dev/null +++ b/crates/ruff_python_trivia/src/pragmas.rs @@ -0,0 +1,30 @@ +/// Returns `true` if a comment appears to be a pragma comment. +/// +/// ``` +/// assert!(ruff_python_trivia::is_pragma_comment("# type: ignore")); +/// assert!(ruff_python_trivia::is_pragma_comment("# noqa: F401")); +/// assert!(ruff_python_trivia::is_pragma_comment("# noqa")); +/// assert!(ruff_python_trivia::is_pragma_comment("# NoQA")); +/// assert!(ruff_python_trivia::is_pragma_comment("# nosec")); +/// assert!(ruff_python_trivia::is_pragma_comment("# nosec B602, B607")); +/// assert!(ruff_python_trivia::is_pragma_comment("# isort: off")); +/// assert!(ruff_python_trivia::is_pragma_comment("# isort: skip")); +/// ``` +pub fn is_pragma_comment(comment: &str) -> bool { + let Some(content) = comment.strip_prefix('#') else { + return false; + }; + let trimmed = content.trim_start(); + + // Case-insensitive match against `noqa` (which doesn't require a trailing colon). + matches!( + trimmed.as_bytes(), + [b'n' | b'N', b'o' | b'O', b'q' | b'Q', b'a' | b'A', ..] + ) || + // Case-insensitive match against pragmas that don't require a trailing colon. + trimmed.starts_with("nosec") || + // Case-sensitive match against a variety of pragmas that _do_ require a trailing colon. + trimmed + .split_once(':') + .is_some_and(|(maybe_pragma, _)| matches!(maybe_pragma, "isort" | "type" | "pyright" | "pylint" | "flake8" | "ruff")) +} diff --git a/crates/ruff_python_trivia/src/tokenizer.rs b/crates/ruff_python_trivia/src/tokenizer.rs index 060c673fc0e1e..7f6835edfe0c6 100644 --- a/crates/ruff_python_trivia/src/tokenizer.rs +++ b/crates/ruff_python_trivia/src/tokenizer.rs @@ -88,10 +88,33 @@ pub fn lines_after(offset: TextSize, code: &str) -> u32 { newlines } +/// Counts the empty lines after `offset`, ignoring any trailing trivia: end-of-line comments, +/// own-line comments, and any intermediary newlines. +pub fn lines_after_ignoring_trivia(offset: TextSize, code: &str) -> u32 { + let mut newlines = 0u32; + for token in SimpleTokenizer::starts_at(offset, code) { + match token.kind() { + SimpleTokenKind::Newline => { + newlines += 1; + } + SimpleTokenKind::Whitespace => {} + // If we see a comment, reset the newlines counter. + SimpleTokenKind::Comment => { + newlines = 0; + } + // As soon as we see a non-trivia token, we're done. + _ => { + break; + } + } + } + newlines +} + /// Counts the empty lines after `offset`, ignoring any trailing trivia on the same line as /// `offset`. #[allow(clippy::cast_possible_truncation)] -pub fn lines_after_ignoring_trivia(offset: TextSize, code: &str) -> u32 { +pub fn lines_after_ignoring_end_of_line_trivia(offset: TextSize, code: &str) -> u32 { // SAFETY: We don't support files greater than 4GB, so casting to u32 is safe. SimpleTokenizer::starts_at(offset, code) .skip_while(|token| token.kind != SimpleTokenKind::Newline && token.kind.is_trivia()) @@ -543,8 +566,10 @@ impl<'a> SimpleTokenizer<'a> { kind } - ' ' | '\t' => { - self.cursor.eat_while(|c| matches!(c, ' ' | '\t')); + // Space, tab, or form feed. We ignore the true semantics of form feed, and treat it as + // whitespace. + ' ' | '\t' | '\x0C' => { + self.cursor.eat_while(|c| matches!(c, ' ' | '\t' | '\x0C')); SimpleTokenKind::Whitespace } @@ -814,10 +839,13 @@ impl<'a> BackwardsTokenizer<'a> { } let kind = match last { - // This may not be 100% correct because it will lex-out trailing whitespace from a comment - // as whitespace rather than being part of the token. This shouldn't matter for what we use the lexer for. - ' ' | '\t' => { - self.cursor.eat_back_while(|c| matches!(c, ' ' | '\t')); + // Space, tab, or form feed. We ignore the true semantics of form feed, and treat it as + // whitespace. Note that this will lex-out trailing whitespace from a comment as + // whitespace rather than as part of the comment token, but this shouldn't matter for + // our use case. + ' ' | '\t' | '\x0C' => { + self.cursor + .eat_back_while(|c| matches!(c, ' ' | '\t' | '\x0C')); SimpleTokenKind::Whitespace } diff --git a/crates/ruff_shrinking/Cargo.toml b/crates/ruff_shrinking/Cargo.toml index efa1ff30c9afa..8c6276e182f9b 100644 --- a/crates/ruff_shrinking/Cargo.toml +++ b/crates/ruff_shrinking/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ruff_shrinking" -version = "0.1.0" +version = "0.1.3" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/ruff_shrinking/src/main.rs b/crates/ruff_shrinking/src/main.rs index 2ffee84e7bc7e..9f4fb043f7b74 100644 --- a/crates/ruff_shrinking/src/main.rs +++ b/crates/ruff_shrinking/src/main.rs @@ -320,7 +320,7 @@ fn minimization_step( last_strategy_and_idx: Option<(&'static dyn Strategy, usize)>, ) -> Result> { let tokens = ruff_python_parser::tokenize(input, Mode::Module); - let ast = ruff_python_parser::parse_program_tokens(tokens, "input.py", false) + let ast = ruff_python_parser::parse_program_tokens(tokens, input, "input.py", false) .context("not valid python")?; // Try the last succeeding strategy first, skipping all that failed last time diff --git a/crates/ruff_source_file/src/lib.rs b/crates/ruff_source_file/src/lib.rs index dd375f7e242dc..fc2a10108de69 100644 --- a/crates/ruff_source_file/src/lib.rs +++ b/crates/ruff_source_file/src/lib.rs @@ -68,6 +68,10 @@ impl<'src, 'index> SourceCode<'src, 'index> { self.index.line_end(line, self.text) } + pub fn line_end_exclusive(&self, line: OneIndexed) -> TextSize { + self.index.line_end_exclusive(line, self.text) + } + pub fn line_range(&self, line: OneIndexed) -> TextRange { self.index.line_range(line, self.text) } diff --git a/crates/ruff_source_file/src/line_index.rs b/crates/ruff_source_file/src/line_index.rs index 9bf7b20985558..279e68dfb84d0 100644 --- a/crates/ruff_source_file/src/line_index.rs +++ b/crates/ruff_source_file/src/line_index.rs @@ -184,6 +184,20 @@ impl LineIndex { } } + /// Returns the [byte offset](TextSize) of the `line`'s end. + /// The offset is the end of the line, excluding the newline character ending the line (if any). + pub fn line_end_exclusive(&self, line: OneIndexed, contents: &str) -> TextSize { + let row_index = line.to_zero_indexed(); + let starts = self.line_starts(); + + // If start-of-line position after last line + if row_index.saturating_add(1) >= starts.len() { + contents.text_len() + } else { + starts[row_index + 1] - TextSize::new(1) + } + } + /// Returns the [`TextRange`] of the `line` with the given index. /// The start points to the first character's [byte offset](TextSize), the end up to, and including /// the newline character ending the line (if any). diff --git a/crates/ruff_wasm/src/lib.rs b/crates/ruff_wasm/src/lib.rs index e3a6974e6b28c..a067cde03e168 100644 --- a/crates/ruff_wasm/src/lib.rs +++ b/crates/ruff_wasm/src/lib.rs @@ -4,17 +4,17 @@ use js_sys::Error; use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; -use ruff_formatter::{FormatResult, Formatted}; +use ruff_formatter::{FormatResult, Formatted, IndentStyle}; use ruff_linter::directives; -use ruff_linter::line_width::{LineLength, TabSize}; +use ruff_linter::line_width::{IndentWidth, LineLength}; use ruff_linter::linter::{check_path, LinterResult}; use ruff_linter::registry::AsRule; use ruff_linter::settings::types::PythonVersion; -use ruff_linter::settings::{flags, DUMMY_VARIABLE_RGX, PREFIXES}; +use ruff_linter::settings::{flags, DEFAULT_SELECTORS, DUMMY_VARIABLE_RGX}; use ruff_linter::source_kind::SourceKind; use ruff_python_ast::{Mod, PySourceType}; use ruff_python_codegen::Stylist; -use ruff_python_formatter::{format_node, pretty_comments, PyFormatContext}; +use ruff_python_formatter::{format_module_ast, pretty_comments, PyFormatContext, QuoteStyle}; use ruff_python_index::{CommentRangesBuilder, Indexer}; use ruff_python_parser::lexer::LexResult; use ruff_python_parser::{parse_tokens, AsMode, Mode}; @@ -22,7 +22,7 @@ use ruff_python_trivia::CommentRanges; use ruff_source_file::{Locator, SourceLocation}; use ruff_text_size::Ranged; use ruff_workspace::configuration::Configuration; -use ruff_workspace::options::Options; +use ruff_workspace::options::{FormatOptions, LintCommonOptions, LintOptions, Options}; use ruff_workspace::Settings; #[wasm_bindgen(typescript_custom_section)] @@ -119,46 +119,35 @@ impl Workspace { #[wasm_bindgen(js_name = defaultSettings)] pub fn default_settings() -> Result { serde_wasm_bindgen::to_value(&Options { + preview: Some(false), + // Propagate defaults. - allowed_confusables: Some(Vec::default()), builtins: Some(Vec::default()), - dummy_variable_rgx: Some(DUMMY_VARIABLE_RGX.as_str().to_string()), - extend_fixable: Some(Vec::default()), - extend_ignore: Some(Vec::default()), - extend_select: Some(Vec::default()), - extend_unfixable: Some(Vec::default()), - external: Some(Vec::default()), - ignore: Some(Vec::default()), + line_length: Some(LineLength::default()), - preview: Some(false), - select: Some(PREFIXES.to_vec()), - tab_size: Some(TabSize::default()), + + indent_width: Some(IndentWidth::default()), target_version: Some(PythonVersion::default()), - // Ignore a bunch of options that don't make sense in a single-file editor. - cache_dir: None, - exclude: None, - extend: None, - extend_exclude: None, - extend_include: None, - extend_per_file_ignores: None, - fix: None, - fix_only: None, - fixable: None, - force_exclude: None, - output_format: None, - ignore_init_module_imports: None, - include: None, - logger_objects: None, - namespace_packages: None, - per_file_ignores: None, - required_version: None, - respect_gitignore: None, - show_fixes: None, - show_source: None, - src: None, - task_tags: None, - typing_modules: None, - unfixable: None, + + lint: Some(LintOptions { + common: LintCommonOptions { + allowed_confusables: Some(Vec::default()), + dummy_variable_rgx: Some(DUMMY_VARIABLE_RGX.as_str().to_string()), + ignore: Some(Vec::default()), + select: Some(DEFAULT_SELECTORS.to_vec()), + extend_fixable: Some(Vec::default()), + extend_select: Some(Vec::default()), + external: Some(Vec::default()), + ..LintCommonOptions::default() + }, + + ..LintOptions::default() + }), + format: Some(FormatOptions { + indent_style: Some(IndentStyle::Space), + quote_style: Some(QuoteStyle::Double), + ..FormatOptions::default() + }), ..Options::default() }) .map_err(into_error) @@ -290,7 +279,7 @@ impl<'a> ParsedModule<'a> { comment_ranges.visit_token(token, *range); } let comment_ranges = comment_ranges.finish(); - let module = parse_tokens(tokens, Mode::Module, ".").map_err(into_error)?; + let module = parse_tokens(tokens, source, Mode::Module, ".").map_err(into_error)?; Ok(Self { source_code: source, @@ -305,7 +294,7 @@ impl<'a> ParsedModule<'a> { .formatter .to_format_options(PySourceType::default(), self.source_code); - format_node( + format_module_ast( &self.module, &self.comment_ranges, self.source_code, diff --git a/crates/ruff_workspace/Cargo.toml b/crates/ruff_workspace/Cargo.toml index 7cde787831b84..154fb55d1b086 100644 --- a/crates/ruff_workspace/Cargo.toml +++ b/crates/ruff_workspace/Cargo.toml @@ -25,13 +25,14 @@ anyhow = { workspace = true } colored = { workspace = true } dirs = { version = "5.0.0" } ignore = { workspace = true } +is-macro = { workspace = true } itertools = { workspace = true } log = { workspace = true } glob = { workspace = true } globset = { workspace = true } once_cell = { workspace = true } path-absolutize = { workspace = true } -pep440_rs = { version = "0.3.1", features = ["serde"] } +pep440_rs = { version = "0.3.12", features = ["serde"] } regex = { workspace = true } rustc-hash = { workspace = true } schemars = { workspace = true, optional = true } diff --git a/crates/ruff_workspace/src/configuration.rs b/crates/ruff_workspace/src/configuration.rs index afc47401c84db..0f7924531a388 100644 --- a/crates/ruff_workspace/src/configuration.rs +++ b/crates/ruff_workspace/src/configuration.rs @@ -4,7 +4,7 @@ use std::borrow::Cow; use std::env::VarError; -use std::num::NonZeroU16; +use std::num::{NonZeroU16, NonZeroU8}; use std::path::{Path, PathBuf}; use anyhow::{anyhow, Result}; @@ -16,18 +16,19 @@ use shellexpand::LookupError; use strum::IntoEnumIterator; use ruff_cache::cache_dir; -use ruff_formatter::{IndentStyle, LineWidth}; -use ruff_linter::line_width::{LineLength, TabSize}; +use ruff_formatter::IndentStyle; +use ruff_linter::line_width::{IndentWidth, LineLength}; use ruff_linter::registry::RuleNamespace; use ruff_linter::registry::{Rule, RuleSet, INCOMPATIBLE_CODES}; -use ruff_linter::rule_selector::Specificity; +use ruff_linter::rule_selector::{PreviewOptions, Specificity}; +use ruff_linter::rules::pycodestyle; use ruff_linter::settings::rule_table::RuleTable; use ruff_linter::settings::types::{ FilePattern, FilePatternSet, PerFileIgnore, PreviewMode, PythonVersion, SerializationFormat, - Version, + UnsafeFixes, Version, }; use ruff_linter::settings::{ - resolve_per_file_ignores, LinterSettings, DUMMY_VARIABLE_RGX, PREFIXES, TASK_TAGS, + resolve_per_file_ignores, LinterSettings, DEFAULT_SELECTORS, DUMMY_VARIABLE_RGX, TASK_TAGS, }; use ruff_linter::{ fs, warn_user, warn_user_once, warn_user_once_by_id, RuleSelector, RUFF_PKG_VERSION, @@ -39,9 +40,9 @@ use crate::options::{ Flake8ComprehensionsOptions, Flake8CopyrightOptions, Flake8ErrMsgOptions, Flake8GetTextOptions, Flake8ImplicitStrConcatOptions, Flake8ImportConventionsOptions, Flake8PytestStyleOptions, Flake8QuotesOptions, Flake8SelfOptions, Flake8TidyImportsOptions, Flake8TypeCheckingOptions, - Flake8UnusedArgumentsOptions, FormatOptions, FormatOrOutputFormat, IsortOptions, McCabeOptions, - Options, Pep8NamingOptions, PyUpgradeOptions, PycodestyleOptions, PydocstyleOptions, - PyflakesOptions, PylintOptions, + Flake8UnusedArgumentsOptions, FormatOptions, IsortOptions, LintOptions, McCabeOptions, Options, + Pep8NamingOptions, PyUpgradeOptions, PycodestyleOptions, PydocstyleOptions, PyflakesOptions, + PylintOptions, }; use crate::settings::{ FileResolverSettings, FormatterSettings, LineEnding, Settings, EXCLUDE, INCLUDE, @@ -57,66 +58,84 @@ pub struct RuleSelection { pub extend_fixable: Vec, } +#[derive(Debug, Eq, PartialEq, is_macro::Is)] +pub enum RuleSelectorKind { + /// Enables the selected rules + Enable, + /// Disables the selected rules + Disable, + /// Modifies the behavior of selected rules + Modify, +} + +impl RuleSelection { + pub fn selectors_by_kind(&self) -> impl Iterator { + self.select + .iter() + .flatten() + .map(|selector| (RuleSelectorKind::Enable, selector)) + .chain( + self.fixable + .iter() + .flatten() + .map(|selector| (RuleSelectorKind::Modify, selector)), + ) + .chain( + self.ignore + .iter() + .map(|selector| (RuleSelectorKind::Disable, selector)), + ) + .chain( + self.extend_select + .iter() + .map(|selector| (RuleSelectorKind::Enable, selector)), + ) + .chain( + self.unfixable + .iter() + .map(|selector| (RuleSelectorKind::Modify, selector)), + ) + .chain( + self.extend_fixable + .iter() + .map(|selector| (RuleSelectorKind::Modify, selector)), + ) + } +} + #[derive(Debug, Default)] pub struct Configuration { - pub rule_selections: Vec, - pub per_file_ignores: Option>, - - pub allowed_confusables: Option>, - pub builtins: Option>, + // Global options pub cache_dir: Option, - pub dummy_variable_rgx: Option, - pub exclude: Option>, pub extend: Option, - pub extend_exclude: Vec, - pub extend_include: Vec, - pub extend_per_file_ignores: Vec, - pub external: Option>, pub fix: Option, pub fix_only: Option, - pub force_exclude: Option, + pub unsafe_fixes: Option, pub output_format: Option, - pub ignore_init_module_imports: Option, - pub include: Option>, - pub line_length: Option, - pub logger_objects: Option>, - pub namespace_packages: Option>, pub preview: Option, pub required_version: Option, - pub respect_gitignore: Option, pub show_fixes: Option, pub show_source: Option, + + // File resolver options + pub exclude: Option>, + pub extend_exclude: Vec, + pub extend_include: Vec, + pub force_exclude: Option, + pub include: Option>, + pub respect_gitignore: Option, + + // Generic python options settings + pub builtins: Option>, + pub namespace_packages: Option>, pub src: Option>, - pub tab_size: Option, pub target_version: Option, - pub task_tags: Option>, - pub typing_modules: Option>, - // Plugins - pub flake8_annotations: Option, - pub flake8_bandit: Option, - pub flake8_bugbear: Option, - pub flake8_builtins: Option, - pub flake8_comprehensions: Option, - pub flake8_copyright: Option, - pub flake8_errmsg: Option, - pub flake8_gettext: Option, - pub flake8_implicit_str_concat: Option, - pub flake8_import_conventions: Option, - pub flake8_pytest_style: Option, - pub flake8_quotes: Option, - pub flake8_self: Option, - pub flake8_tidy_imports: Option, - pub flake8_type_checking: Option, - pub flake8_unused_arguments: Option, - pub isort: Option, - pub mccabe: Option, - pub pep8_naming: Option, - pub pycodestyle: Option, - pub pydocstyle: Option, - pub pyflakes: Option, - pub pylint: Option, - pub pyupgrade: Option, + // Global formatting options + pub line_length: Option, + pub indent_width: Option, + + pub lint: LintConfiguration, pub format: FormatConfiguration, } @@ -133,30 +152,40 @@ impl Configuration { } let target_version = self.target_version.unwrap_or_default(); - let rules = self.as_rule_table(); - let preview = self.preview.unwrap_or_default(); + let global_preview = self.preview.unwrap_or_default(); let format = self.format; let format_defaults = FormatterSettings::default(); - // TODO(micha): Support changing the tab-width but disallow changing the number of spaces + let formatter = FormatterSettings { - preview: match format.preview.unwrap_or(preview) { + exclude: FilePatternSet::try_from_iter(format.exclude.unwrap_or_default())?, + preview: match format.preview.unwrap_or(global_preview) { PreviewMode::Disabled => ruff_python_formatter::PreviewMode::Disabled, PreviewMode::Enabled => ruff_python_formatter::PreviewMode::Enabled, }, line_width: self .line_length .map_or(format_defaults.line_width, |length| { - LineWidth::from(NonZeroU16::from(length)) + ruff_formatter::LineWidth::from(NonZeroU16::from(length)) }), line_ending: format.line_ending.unwrap_or(format_defaults.line_ending), indent_style: format.indent_style.unwrap_or(format_defaults.indent_style), + indent_width: self + .indent_width + .map_or(format_defaults.indent_width, |tab_size| { + ruff_formatter::IndentWidth::from(NonZeroU8::from(tab_size)) + }), quote_style: format.quote_style.unwrap_or(format_defaults.quote_style), magic_trailing_comma: format .magic_trailing_comma .unwrap_or(format_defaults.magic_trailing_comma), }; + let lint = self.lint; + let lint_preview = lint.preview.unwrap_or(global_preview); + + let line_length = self.line_length.unwrap_or_default(); + Ok(Settings { cache_dir: self .cache_dir @@ -164,6 +193,7 @@ impl Configuration { .unwrap_or_else(|| cache_dir(project_root)), fix: self.fix.unwrap_or(false), fix_only: self.fix_only.unwrap_or(false), + unsafe_fixes: self.unsafe_fixes.unwrap_or_default(), output_format: self.output_format.unwrap_or_default(), show_fixes: self.show_fixes.unwrap_or(false), show_source: self.show_source.unwrap_or(false), @@ -183,135 +213,163 @@ impl Configuration { }, linter: LinterSettings { + rules: lint.as_rule_table(lint_preview), + exclude: FilePatternSet::try_from_iter(lint.exclude.unwrap_or_default())?, + preview: lint_preview, target_version, project_root: project_root.to_path_buf(), - rules, - allowed_confusables: self + allowed_confusables: lint .allowed_confusables .map(FxHashSet::from_iter) .unwrap_or_default(), builtins: self.builtins.unwrap_or_default(), - dummy_variable_rgx: self + dummy_variable_rgx: lint .dummy_variable_rgx .unwrap_or_else(|| DUMMY_VARIABLE_RGX.clone()), - external: FxHashSet::from_iter(self.external.unwrap_or_default()), - ignore_init_module_imports: self.ignore_init_module_imports.unwrap_or_default(), - line_length: self.line_length.unwrap_or_default(), - tab_size: self.tab_size.unwrap_or_default(), + external: lint.external.unwrap_or_default(), + ignore_init_module_imports: lint.ignore_init_module_imports.unwrap_or_default(), + line_length, + tab_size: self.indent_width.unwrap_or_default(), namespace_packages: self.namespace_packages.unwrap_or_default(), per_file_ignores: resolve_per_file_ignores( - self.per_file_ignores + lint.per_file_ignores .unwrap_or_default() .into_iter() - .chain(self.extend_per_file_ignores) + .chain(lint.extend_per_file_ignores) .collect(), )?, + + extend_safe_fixes: lint + .extend_safe_fixes + .iter() + .flat_map(|selector| { + selector.rules(&PreviewOptions { + mode: lint_preview, + require_explicit: false, + }) + }) + .collect(), + extend_unsafe_fixes: lint + .extend_unsafe_fixes + .iter() + .flat_map(|selector| { + selector.rules(&PreviewOptions { + mode: lint_preview, + require_explicit: false, + }) + }) + .collect(), + src: self.src.unwrap_or_else(|| vec![project_root.to_path_buf()]), + explicit_preview_rules: lint.explicit_preview_rules.unwrap_or_default(), - task_tags: self + task_tags: lint .task_tags .unwrap_or_else(|| TASK_TAGS.iter().map(ToString::to_string).collect()), - logger_objects: self.logger_objects.unwrap_or_default(), - preview, - typing_modules: self.typing_modules.unwrap_or_default(), + logger_objects: lint.logger_objects.unwrap_or_default(), + typing_modules: lint.typing_modules.unwrap_or_default(), // Plugins - flake8_annotations: self + flake8_annotations: lint .flake8_annotations .map(Flake8AnnotationsOptions::into_settings) .unwrap_or_default(), - flake8_bandit: self + flake8_bandit: lint .flake8_bandit .map(Flake8BanditOptions::into_settings) .unwrap_or_default(), - flake8_bugbear: self + flake8_bugbear: lint .flake8_bugbear .map(Flake8BugbearOptions::into_settings) .unwrap_or_default(), - flake8_builtins: self + flake8_builtins: lint .flake8_builtins .map(Flake8BuiltinsOptions::into_settings) .unwrap_or_default(), - flake8_comprehensions: self + flake8_comprehensions: lint .flake8_comprehensions .map(Flake8ComprehensionsOptions::into_settings) .unwrap_or_default(), - flake8_copyright: self + flake8_copyright: lint .flake8_copyright .map(Flake8CopyrightOptions::try_into_settings) .transpose()? .unwrap_or_default(), - flake8_errmsg: self + flake8_errmsg: lint .flake8_errmsg .map(Flake8ErrMsgOptions::into_settings) .unwrap_or_default(), - flake8_implicit_str_concat: self + flake8_implicit_str_concat: lint .flake8_implicit_str_concat .map(Flake8ImplicitStrConcatOptions::into_settings) .unwrap_or_default(), - flake8_import_conventions: self + flake8_import_conventions: lint .flake8_import_conventions .map(Flake8ImportConventionsOptions::into_settings) .unwrap_or_default(), - flake8_pytest_style: self + flake8_pytest_style: lint .flake8_pytest_style .map(Flake8PytestStyleOptions::try_into_settings) .transpose()? .unwrap_or_default(), - flake8_quotes: self + flake8_quotes: lint .flake8_quotes .map(Flake8QuotesOptions::into_settings) .unwrap_or_default(), - flake8_self: self + flake8_self: lint .flake8_self .map(Flake8SelfOptions::into_settings) .unwrap_or_default(), - flake8_tidy_imports: self + flake8_tidy_imports: lint .flake8_tidy_imports .map(Flake8TidyImportsOptions::into_settings) .unwrap_or_default(), - flake8_type_checking: self + flake8_type_checking: lint .flake8_type_checking .map(Flake8TypeCheckingOptions::into_settings) .unwrap_or_default(), - flake8_unused_arguments: self + flake8_unused_arguments: lint .flake8_unused_arguments .map(Flake8UnusedArgumentsOptions::into_settings) .unwrap_or_default(), - flake8_gettext: self + flake8_gettext: lint .flake8_gettext .map(Flake8GetTextOptions::into_settings) .unwrap_or_default(), - isort: self + isort: lint .isort .map(IsortOptions::try_into_settings) .transpose()? .unwrap_or_default(), - mccabe: self + mccabe: lint .mccabe .map(McCabeOptions::into_settings) .unwrap_or_default(), - pep8_naming: self + pep8_naming: lint .pep8_naming .map(Pep8NamingOptions::try_into_settings) .transpose()? .unwrap_or_default(), - pycodestyle: self - .pycodestyle - .map(PycodestyleOptions::into_settings) - .unwrap_or_default(), - pydocstyle: self + pycodestyle: if let Some(pycodestyle) = lint.pycodestyle { + pycodestyle.into_settings(line_length) + } else { + pycodestyle::settings::Settings { + max_line_length: line_length, + ..pycodestyle::settings::Settings::default() + } + }, + pydocstyle: lint .pydocstyle .map(PydocstyleOptions::into_settings) .unwrap_or_default(), - pyflakes: self + pyflakes: lint .pyflakes .map(PyflakesOptions::into_settings) .unwrap_or_default(), - pylint: self + pylint: lint .pylint .map(PylintOptions::into_settings) .unwrap_or_default(), - pyupgrade: self + pyupgrade: lint .pyupgrade .map(PyUpgradeOptions::into_settings) .unwrap_or_default(), @@ -322,40 +380,36 @@ impl Configuration { } pub fn from_options(options: Options, project_root: &Path) -> Result { + let lint = if let Some(mut lint) = options.lint { + lint.common = lint.common.combine(options.lint_top_level); + lint + } else { + LintOptions { + common: options.lint_top_level, + ..LintOptions::default() + } + }; + + #[allow(deprecated)] + let indent_width = { + if options.tab_size.is_some() { + warn_user_once!("The `tab-size` option has been renamed to `indent-width` to emphasize that it configures the indentation used by the formatter as well as the tab width. Please update your configuration to use `indent-width = ` instead."); + } + + options.indent_width.or(options.tab_size) + }; + Ok(Self { - rule_selections: vec![RuleSelection { - select: options.select, - ignore: options - .ignore - .into_iter() - .flatten() - .chain(options.extend_ignore.into_iter().flatten()) - .collect(), - extend_select: options.extend_select.unwrap_or_default(), - fixable: options.fixable, - unfixable: options - .unfixable - .into_iter() - .flatten() - .chain(options.extend_unfixable.into_iter().flatten()) - .collect(), - extend_fixable: options.extend_fixable.unwrap_or_default(), - }], - allowed_confusables: options.allowed_confusables, builtins: options.builtins, cache_dir: options .cache_dir .map(|dir| { let dir = shellexpand::full(&dir); - dir.map(|dir| PathBuf::from(dir.as_ref())) + dir.map(|dir| fs::normalize_path_to(dir.as_ref(), project_root)) }) .transpose() .map_err(|e| anyhow!("Invalid `cache-dir` value: {e}"))?, - dummy_variable_rgx: options - .dummy_variable_rgx - .map(|pattern| Regex::new(&pattern)) - .transpose() - .map_err(|e| anyhow!("Invalid `dummy-variable-rgx` value: {e}"))?, + exclude: options.exclude.map(|paths| { paths .into_iter() @@ -397,28 +451,6 @@ impl Configuration { .collect() }) .unwrap_or_default(), - extend_per_file_ignores: options - .extend_per_file_ignores - .map(|per_file_ignores| { - per_file_ignores - .into_iter() - .map(|(pattern, prefixes)| { - PerFileIgnore::new(pattern, &prefixes, Some(project_root)) - }) - .collect() - }) - .unwrap_or_default(), - external: options.external, - fix: options.fix, - fix_only: options.fix_only, - output_format: options.output_format.or_else(|| { - options - .format - .as_ref() - .and_then(FormatOrOutputFormat::as_output_format) - }), - force_exclude: options.force_exclude, - ignore_init_module_imports: options.ignore_init_module_imports, include: options.include.map(|paths| { paths .into_iter() @@ -428,21 +460,18 @@ impl Configuration { }) .collect() }), + fix: options.fix, + fix_only: options.fix_only, + unsafe_fixes: options.unsafe_fixes.map(UnsafeFixes::from), + output_format: options.output_format, + force_exclude: options.force_exclude, line_length: options.line_length, - tab_size: options.tab_size, + indent_width, namespace_packages: options .namespace_packages .map(|namespace_package| resolve_src(&namespace_package, project_root)) .transpose()?, preview: options.preview.map(PreviewMode::from), - per_file_ignores: options.per_file_ignores.map(|per_file_ignores| { - per_file_ignores - .into_iter() - .map(|(pattern, prefixes)| { - PerFileIgnore::new(pattern, &prefixes, Some(project_root)) - }) - .collect() - }), required_version: options.required_version, respect_gitignore: options.respect_gitignore, show_source: options.show_source, @@ -452,54 +481,221 @@ impl Configuration { .map(|src| resolve_src(&src, project_root)) .transpose()?, target_version: options.target_version, - task_tags: options.task_tags, - logger_objects: options.logger_objects, - typing_modules: options.typing_modules, + + lint: LintConfiguration::from_options(lint, project_root)?, + format: FormatConfiguration::from_options( + options.format.unwrap_or_default(), + project_root, + )?, + }) + } + + #[must_use] + pub fn combine(self, config: Self) -> Self { + Self { + builtins: self.builtins.or(config.builtins), + cache_dir: self.cache_dir.or(config.cache_dir), + exclude: self.exclude.or(config.exclude), + extend: self.extend.or(config.extend), + extend_exclude: config + .extend_exclude + .into_iter() + .chain(self.extend_exclude) + .collect(), + extend_include: config + .extend_include + .into_iter() + .chain(self.extend_include) + .collect(), + include: self.include.or(config.include), + fix: self.fix.or(config.fix), + fix_only: self.fix_only.or(config.fix_only), + unsafe_fixes: self.unsafe_fixes.or(config.unsafe_fixes), + output_format: self.output_format.or(config.output_format), + force_exclude: self.force_exclude.or(config.force_exclude), + line_length: self.line_length.or(config.line_length), + indent_width: self.indent_width.or(config.indent_width), + namespace_packages: self.namespace_packages.or(config.namespace_packages), + required_version: self.required_version.or(config.required_version), + respect_gitignore: self.respect_gitignore.or(config.respect_gitignore), + show_source: self.show_source.or(config.show_source), + show_fixes: self.show_fixes.or(config.show_fixes), + src: self.src.or(config.src), + target_version: self.target_version.or(config.target_version), + preview: self.preview.or(config.preview), + + lint: self.lint.combine(config.lint), + format: self.format.combine(config.format), + } + } +} + +#[derive(Debug, Default)] +pub struct LintConfiguration { + pub exclude: Option>, + pub preview: Option, + + // Rule selection + pub extend_per_file_ignores: Vec, + pub per_file_ignores: Option>, + pub rule_selections: Vec, + pub explicit_preview_rules: Option, + + // Fix configuration + pub extend_unsafe_fixes: Vec, + pub extend_safe_fixes: Vec, + + // Global lint settings + pub allowed_confusables: Option>, + pub dummy_variable_rgx: Option, + pub external: Option>, + pub ignore_init_module_imports: Option, + pub logger_objects: Option>, + pub task_tags: Option>, + pub typing_modules: Option>, + + // Plugins + pub flake8_annotations: Option, + pub flake8_bandit: Option, + pub flake8_bugbear: Option, + pub flake8_builtins: Option, + pub flake8_comprehensions: Option, + pub flake8_copyright: Option, + pub flake8_errmsg: Option, + pub flake8_gettext: Option, + pub flake8_implicit_str_concat: Option, + pub flake8_import_conventions: Option, + pub flake8_pytest_style: Option, + pub flake8_quotes: Option, + pub flake8_self: Option, + pub flake8_tidy_imports: Option, + pub flake8_type_checking: Option, + pub flake8_unused_arguments: Option, + pub isort: Option, + pub mccabe: Option, + pub pep8_naming: Option, + pub pycodestyle: Option, + pub pydocstyle: Option, + pub pyflakes: Option, + pub pylint: Option, + pub pyupgrade: Option, +} + +impl LintConfiguration { + fn from_options(options: LintOptions, project_root: &Path) -> Result { + #[allow(deprecated)] + let ignore = options + .common + .ignore + .into_iter() + .flatten() + .chain(options.common.extend_ignore.into_iter().flatten()) + .collect(); + #[allow(deprecated)] + let unfixable = options + .common + .unfixable + .into_iter() + .flatten() + .chain(options.common.extend_unfixable.into_iter().flatten()) + .collect(); + Ok(LintConfiguration { + exclude: options.exclude.map(|paths| { + paths + .into_iter() + .map(|pattern| { + let absolute = fs::normalize_path_to(&pattern, project_root); + FilePattern::User(pattern, absolute) + }) + .collect() + }), + preview: options.preview.map(PreviewMode::from), + + rule_selections: vec![RuleSelection { + select: options.common.select, + ignore, + extend_select: options.common.extend_select.unwrap_or_default(), + fixable: options.common.fixable, + unfixable, + extend_fixable: options.common.extend_fixable.unwrap_or_default(), + }], + extend_safe_fixes: options.common.extend_safe_fixes.unwrap_or_default(), + extend_unsafe_fixes: options.common.extend_unsafe_fixes.unwrap_or_default(), + allowed_confusables: options.common.allowed_confusables, + dummy_variable_rgx: options + .common + .dummy_variable_rgx + .map(|pattern| Regex::new(&pattern)) + .transpose() + .map_err(|e| anyhow!("Invalid `dummy-variable-rgx` value: {e}"))?, + extend_per_file_ignores: options + .common + .extend_per_file_ignores + .map(|per_file_ignores| { + per_file_ignores + .into_iter() + .map(|(pattern, prefixes)| { + PerFileIgnore::new(pattern, &prefixes, Some(project_root)) + }) + .collect() + }) + .unwrap_or_default(), + external: options.common.external, + ignore_init_module_imports: options.common.ignore_init_module_imports, + explicit_preview_rules: options.common.explicit_preview_rules, + per_file_ignores: options.common.per_file_ignores.map(|per_file_ignores| { + per_file_ignores + .into_iter() + .map(|(pattern, prefixes)| { + PerFileIgnore::new(pattern, &prefixes, Some(project_root)) + }) + .collect() + }), + task_tags: options.common.task_tags, + logger_objects: options.common.logger_objects, + typing_modules: options.common.typing_modules, // Plugins - flake8_annotations: options.flake8_annotations, - flake8_bandit: options.flake8_bandit, - flake8_bugbear: options.flake8_bugbear, - flake8_builtins: options.flake8_builtins, - flake8_comprehensions: options.flake8_comprehensions, - flake8_copyright: options.flake8_copyright, - flake8_errmsg: options.flake8_errmsg, - flake8_gettext: options.flake8_gettext, - flake8_implicit_str_concat: options.flake8_implicit_str_concat, - flake8_import_conventions: options.flake8_import_conventions, - flake8_pytest_style: options.flake8_pytest_style, - flake8_quotes: options.flake8_quotes, - flake8_self: options.flake8_self, - flake8_tidy_imports: options.flake8_tidy_imports, - flake8_type_checking: options.flake8_type_checking, - flake8_unused_arguments: options.flake8_unused_arguments, - isort: options.isort, - mccabe: options.mccabe, - pep8_naming: options.pep8_naming, - pycodestyle: options.pycodestyle, - pydocstyle: options.pydocstyle, - pyflakes: options.pyflakes, - pylint: options.pylint, - pyupgrade: options.pyupgrade, - - format: if let Some(FormatOrOutputFormat::Format(format)) = options.format { - FormatConfiguration::from_options(format)? - } else { - FormatConfiguration::default() - }, + flake8_annotations: options.common.flake8_annotations, + flake8_bandit: options.common.flake8_bandit, + flake8_bugbear: options.common.flake8_bugbear, + flake8_builtins: options.common.flake8_builtins, + flake8_comprehensions: options.common.flake8_comprehensions, + flake8_copyright: options.common.flake8_copyright, + flake8_errmsg: options.common.flake8_errmsg, + flake8_gettext: options.common.flake8_gettext, + flake8_implicit_str_concat: options.common.flake8_implicit_str_concat, + flake8_import_conventions: options.common.flake8_import_conventions, + flake8_pytest_style: options.common.flake8_pytest_style, + flake8_quotes: options.common.flake8_quotes, + flake8_self: options.common.flake8_self, + flake8_tidy_imports: options.common.flake8_tidy_imports, + flake8_type_checking: options.common.flake8_type_checking, + flake8_unused_arguments: options.common.flake8_unused_arguments, + isort: options.common.isort, + mccabe: options.common.mccabe, + pep8_naming: options.common.pep8_naming, + pycodestyle: options.common.pycodestyle, + pydocstyle: options.common.pydocstyle, + pyflakes: options.common.pyflakes, + pylint: options.common.pylint, + pyupgrade: options.common.pyupgrade, }) } - pub fn as_rule_table(&self) -> RuleTable { - let preview = self.preview.unwrap_or_default(); + fn as_rule_table(&self, preview: PreviewMode) -> RuleTable { + let preview = PreviewOptions { + mode: preview, + require_explicit: self.explicit_preview_rules.unwrap_or_default(), + }; // The select_set keeps track of which rules have been selected. - let mut select_set: RuleSet = PREFIXES + let mut select_set: RuleSet = DEFAULT_SELECTORS .iter() - .flat_map(|selector| selector.rules(preview)) + .flat_map(|selector| selector.rules(&preview)) .collect(); // The fixable set keeps track of which rules are fixable. - let mut fixable_set: RuleSet = RuleSelector::All.rules(preview).collect(); + let mut fixable_set: RuleSet = RuleSelector::All.rules(&preview).collect(); // Ignores normally only subtract from the current set of selected // rules. By that logic the ignore in `select = [], ignore = ["E501"]` @@ -538,7 +734,7 @@ impl Configuration { .chain(selection.extend_select.iter()) .filter(|s| s.specificity() == spec) { - for rule in selector.rules(preview) { + for rule in selector.rules(&preview) { select_map_updates.insert(rule, true); } } @@ -548,7 +744,7 @@ impl Configuration { .chain(carriedover_ignores.into_iter().flatten()) .filter(|s| s.specificity() == spec) { - for rule in selector.rules(preview) { + for rule in selector.rules(&preview) { select_map_updates.insert(rule, false); } } @@ -560,7 +756,7 @@ impl Configuration { .chain(selection.extend_fixable.iter()) .filter(|s| s.specificity() == spec) { - for rule in selector.rules(preview) { + for rule in selector.rules(&preview) { fixable_map_updates.insert(rule, true); } } @@ -570,7 +766,7 @@ impl Configuration { .chain(carriedover_unfixables.into_iter().flatten()) .filter(|s| s.specificity() == spec) { - for rule in selector.rules(preview) { + for rule in selector.rules(&preview) { fixable_map_updates.insert(rule, false); } } @@ -625,28 +821,21 @@ impl Configuration { } // Check for selections that require a warning - for selector in selection - .select - .iter() - .chain(selection.fixable.iter()) - .flatten() - .chain(selection.ignore.iter()) - .chain(selection.extend_select.iter()) - .chain(selection.unfixable.iter()) - .chain(selection.extend_fixable.iter()) - { + for (kind, selector) in selection.selectors_by_kind() { #[allow(deprecated)] if matches!(selector, RuleSelector::Nursery) { - let suggestion = if preview.is_disabled() { + let suggestion = if preview.mode.is_disabled() { " Use the `--preview` flag instead." } else { // We have no suggested alternative since there is intentionally no "PREVIEW" selector "" }; warn_user_once!("The `NURSERY` selector has been deprecated.{suggestion}"); - } + }; - if preview.is_disabled() { + // Only warn for the following selectors if used to enable rules + // e.g. use with `--ignore` or `--fixable` is okay + if preview.mode.is_disabled() && kind.is_enable() { if let RuleSelector::Rule { prefix, .. } = selector { if prefix.rules().any(|rule| rule.is_nursery()) { deprecated_nursery_selectors.insert(selector); @@ -654,7 +843,7 @@ impl Configuration { } // Check if the selector is empty because preview mode is disabled - if selector.rules(PreviewMode::Disabled).next().is_none() { + if selector.rules(&PreviewOptions::default()).next().is_none() { ignored_preview_selectors.insert(selector); } } @@ -725,53 +914,39 @@ impl Configuration { #[must_use] pub fn combine(self, config: Self) -> Self { Self { + exclude: self.exclude.or(config.exclude), + preview: self.preview.or(config.preview), rule_selections: config .rule_selections .into_iter() .chain(self.rule_selections) .collect(), - allowed_confusables: self.allowed_confusables.or(config.allowed_confusables), - builtins: self.builtins.or(config.builtins), - cache_dir: self.cache_dir.or(config.cache_dir), - dummy_variable_rgx: self.dummy_variable_rgx.or(config.dummy_variable_rgx), - exclude: self.exclude.or(config.exclude), - extend: self.extend.or(config.extend), - extend_exclude: config - .extend_exclude + extend_safe_fixes: config + .extend_safe_fixes .into_iter() - .chain(self.extend_exclude) + .chain(self.extend_safe_fixes) .collect(), - extend_include: config - .extend_include + extend_unsafe_fixes: config + .extend_unsafe_fixes .into_iter() - .chain(self.extend_include) + .chain(self.extend_unsafe_fixes) .collect(), + allowed_confusables: self.allowed_confusables.or(config.allowed_confusables), + dummy_variable_rgx: self.dummy_variable_rgx.or(config.dummy_variable_rgx), extend_per_file_ignores: config .extend_per_file_ignores .into_iter() .chain(self.extend_per_file_ignores) .collect(), external: self.external.or(config.external), - fix: self.fix.or(config.fix), - fix_only: self.fix_only.or(config.fix_only), - output_format: self.output_format.or(config.output_format), - force_exclude: self.force_exclude.or(config.force_exclude), - include: self.include.or(config.include), ignore_init_module_imports: self .ignore_init_module_imports .or(config.ignore_init_module_imports), - line_length: self.line_length.or(config.line_length), logger_objects: self.logger_objects.or(config.logger_objects), - tab_size: self.tab_size.or(config.tab_size), - namespace_packages: self.namespace_packages.or(config.namespace_packages), per_file_ignores: self.per_file_ignores.or(config.per_file_ignores), - required_version: self.required_version.or(config.required_version), - respect_gitignore: self.respect_gitignore.or(config.respect_gitignore), - show_source: self.show_source.or(config.show_source), - show_fixes: self.show_fixes.or(config.show_fixes), - src: self.src.or(config.src), - target_version: self.target_version.or(config.target_version), - preview: self.preview.or(config.preview), + explicit_preview_rules: self + .explicit_preview_rules + .or(config.explicit_preview_rules), task_tags: self.task_tags.or(config.task_tags), typing_modules: self.typing_modules.or(config.typing_modules), // Plugins @@ -809,29 +984,34 @@ impl Configuration { pyflakes: self.pyflakes.combine(config.pyflakes), pylint: self.pylint.combine(config.pylint), pyupgrade: self.pyupgrade.combine(config.pyupgrade), - - format: self.format.combine(config.format), } } } #[derive(Debug, Default)] pub struct FormatConfiguration { + pub exclude: Option>, pub preview: Option, pub indent_style: Option, - pub quote_style: Option, - pub magic_trailing_comma: Option, - pub line_ending: Option, } impl FormatConfiguration { #[allow(clippy::needless_pass_by_value)] - pub fn from_options(options: FormatOptions) -> Result { + pub fn from_options(options: FormatOptions, project_root: &Path) -> Result { Ok(Self { + exclude: options.exclude.map(|paths| { + paths + .into_iter() + .map(|pattern| { + let absolute = fs::normalize_path_to(&pattern, project_root); + FilePattern::User(pattern, absolute) + }) + .collect() + }), preview: options.preview.map(PreviewMode::from), indent_style: options.indent_style, quote_style: options.quote_style, @@ -850,6 +1030,7 @@ impl FormatConfiguration { #[allow(clippy::needless_pass_by_value)] pub fn combine(self, other: Self) -> Self { Self { + exclude: self.exclude.or(other.exclude), preview: self.preview.or(other.preview), indent_style: self.indent_style.or(other.indent_style), quote_style: self.quote_style.or(other.quote_style), @@ -858,7 +1039,6 @@ impl FormatConfiguration { } } } - pub(crate) trait CombinePluginOptions { #[must_use] fn combine(self, other: Self) -> Self; @@ -897,13 +1077,13 @@ pub fn resolve_src(src: &[String], project_root: &Path) -> Result> #[cfg(test)] mod tests { + use crate::configuration::{LintConfiguration, RuleSelection}; use ruff_linter::codes::{Flake8Copyright, Pycodestyle, Refurb}; use ruff_linter::registry::{Linter, Rule, RuleSet}; + use ruff_linter::rule_selector::PreviewOptions; use ruff_linter::settings::types::PreviewMode; use ruff_linter::RuleSelector; - use crate::configuration::{Configuration, RuleSelection}; - const NURSERY_RULES: &[Rule] = &[ Rule::MissingCopyrightNotice, Rule::IndentationWithInvalidMultiple, @@ -950,6 +1130,8 @@ mod tests { ]; const PREVIEW_RULES: &[Rule] = &[ + Rule::AndOrTernary, + Rule::AssignmentInAssert, Rule::DirectLoggerInstantiation, Rule::InvalidGetLoggerArgument, Rule::ManualDictComprehension, @@ -964,14 +1146,14 @@ mod tests { #[allow(clippy::needless_pass_by_value)] fn resolve_rules( selections: impl IntoIterator, - preview: Option, + preview: Option, ) -> RuleSet { - Configuration { + LintConfiguration { rule_selections: selections.into_iter().collect(), - preview, - ..Configuration::default() + explicit_preview_rules: preview.as_ref().map(|preview| preview.require_explicit), + ..LintConfiguration::default() } - .as_rule_table() + .as_rule_table(preview.map(|preview| preview.mode).unwrap_or_default()) .iter_enabled() // Filter out rule gated behind `#[cfg(feature = "unreachable-code")]`, which is off-by-default .filter(|rule| rule.noqa_code() != "RUF014") @@ -1207,7 +1389,10 @@ mod tests { select: Some(vec![RuleSelector::All]), ..RuleSelection::default() }], - Some(PreviewMode::Disabled), + Some(PreviewOptions { + mode: PreviewMode::Disabled, + ..PreviewOptions::default() + }), ); assert!(!actual.intersects(&RuleSet::from_rules(PREVIEW_RULES))); @@ -1216,7 +1401,10 @@ mod tests { select: Some(vec![RuleSelector::All]), ..RuleSelection::default() }], - Some(PreviewMode::Enabled), + Some(PreviewOptions { + mode: PreviewMode::Enabled, + ..PreviewOptions::default() + }), ); assert!(actual.intersects(&RuleSet::from_rules(PREVIEW_RULES))); } @@ -1228,7 +1416,10 @@ mod tests { select: Some(vec![Linter::Flake8Copyright.into()]), ..RuleSelection::default() }], - Some(PreviewMode::Disabled), + Some(PreviewOptions { + mode: PreviewMode::Disabled, + ..PreviewOptions::default() + }), ); let expected = RuleSet::empty(); assert_eq!(actual, expected); @@ -1238,7 +1429,10 @@ mod tests { select: Some(vec![Linter::Flake8Copyright.into()]), ..RuleSelection::default() }], - Some(PreviewMode::Enabled), + Some(PreviewOptions { + mode: PreviewMode::Enabled, + ..PreviewOptions::default() + }), ); let expected = RuleSet::from_rule(Rule::MissingCopyrightNotice); assert_eq!(actual, expected); @@ -1251,7 +1445,10 @@ mod tests { select: Some(vec![Flake8Copyright::_0.into()]), ..RuleSelection::default() }], - Some(PreviewMode::Disabled), + Some(PreviewOptions { + mode: PreviewMode::Disabled, + ..PreviewOptions::default() + }), ); let expected = RuleSet::empty(); assert_eq!(actual, expected); @@ -1261,7 +1458,10 @@ mod tests { select: Some(vec![Flake8Copyright::_0.into()]), ..RuleSelection::default() }], - Some(PreviewMode::Enabled), + Some(PreviewOptions { + mode: PreviewMode::Enabled, + ..PreviewOptions::default() + }), ); let expected = RuleSet::from_rule(Rule::MissingCopyrightNotice); assert_eq!(actual, expected); @@ -1269,12 +1469,16 @@ mod tests { #[test] fn select_rule_preview() { + // Test inclusion when toggling preview on and off let actual = resolve_rules( [RuleSelection { select: Some(vec![Refurb::_145.into()]), ..RuleSelection::default() }], - Some(PreviewMode::Disabled), + Some(PreviewOptions { + mode: PreviewMode::Disabled, + ..PreviewOptions::default() + }), ); let expected = RuleSet::empty(); assert_eq!(actual, expected); @@ -1284,7 +1488,24 @@ mod tests { select: Some(vec![Refurb::_145.into()]), ..RuleSelection::default() }], - Some(PreviewMode::Enabled), + Some(PreviewOptions { + mode: PreviewMode::Enabled, + ..PreviewOptions::default() + }), + ); + let expected = RuleSet::from_rule(Rule::SliceCopy); + assert_eq!(actual, expected); + + // Test inclusion when preview is on but explicit codes are required + let actual = resolve_rules( + [RuleSelection { + select: Some(vec![Refurb::_145.into()]), + ..RuleSelection::default() + }], + Some(PreviewOptions { + mode: PreviewMode::Enabled, + require_explicit: true, + }), ); let expected = RuleSet::from_rule(Rule::SliceCopy); assert_eq!(actual, expected); @@ -1299,7 +1520,10 @@ mod tests { select: Some(vec![Flake8Copyright::_001.into()]), ..RuleSelection::default() }], - Some(PreviewMode::Disabled), + Some(PreviewOptions { + mode: PreviewMode::Disabled, + ..PreviewOptions::default() + }), ); let expected = RuleSet::from_rule(Rule::MissingCopyrightNotice); assert_eq!(actual, expected); @@ -1309,7 +1533,10 @@ mod tests { select: Some(vec![Flake8Copyright::_001.into()]), ..RuleSelection::default() }], - Some(PreviewMode::Enabled), + Some(PreviewOptions { + mode: PreviewMode::Enabled, + ..PreviewOptions::default() + }), ); let expected = RuleSet::from_rule(Rule::MissingCopyrightNotice); assert_eq!(actual, expected); @@ -1325,7 +1552,10 @@ mod tests { select: Some(vec![RuleSelector::Nursery]), ..RuleSelection::default() }], - Some(PreviewMode::Disabled), + Some(PreviewOptions { + mode: PreviewMode::Disabled, + ..PreviewOptions::default() + }), ); let expected = RuleSet::from_rules(NURSERY_RULES); assert_eq!(actual, expected); @@ -1335,7 +1565,10 @@ mod tests { select: Some(vec![RuleSelector::Nursery]), ..RuleSelection::default() }], - Some(PreviewMode::Enabled), + Some(PreviewOptions { + mode: PreviewMode::Enabled, + ..PreviewOptions::default() + }), ); let expected = RuleSet::from_rules(NURSERY_RULES); assert_eq!(actual, expected); diff --git a/crates/ruff_workspace/src/options.rs b/crates/ruff_workspace/src/options.rs index 7963ef48f2346..b065f22b39e38 100644 --- a/crates/ruff_workspace/src/options.rs +++ b/crates/ruff_workspace/src/options.rs @@ -2,13 +2,12 @@ use std::collections::BTreeSet; use std::hash::BuildHasherDefault; use regex::Regex; -use ruff_formatter::IndentStyle; use rustc_hash::{FxHashMap, FxHashSet}; use serde::{Deserialize, Serialize}; use strum::IntoEnumIterator; -use crate::options_base::{OptionsMetadata, Visit}; -use ruff_linter::line_width::{LineLength, TabSize}; +use ruff_formatter::IndentStyle; +use ruff_linter::line_width::{IndentWidth, LineLength}; use ruff_linter::rules::flake8_pytest_style::settings::SettingsError; use ruff_linter::rules::flake8_pytest_style::types; use ruff_linter::rules::flake8_quotes::settings::Quote; @@ -27,39 +26,15 @@ use ruff_linter::settings::types::{ IdentifierPattern, PythonVersion, SerializationFormat, Version, }; use ruff_linter::{warn_user_once, RuleSelector}; -use ruff_macros::{CombineOptions, ConfigurationOptions}; +use ruff_macros::{CombineOptions, OptionsMetadata}; use ruff_python_formatter::QuoteStyle; use crate::settings::LineEnding; -#[derive(Debug, PartialEq, Eq, Default, ConfigurationOptions, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Default, OptionsMetadata, Serialize, Deserialize)] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Options { - /// A list of allowed "confusable" Unicode characters to ignore when - /// enforcing `RUF001`, `RUF002`, and `RUF003`. - #[option( - default = r#"[]"#, - value_type = "list[str]", - example = r#" - # Allow minus-sign (U+2212), greek-small-letter-rho (U+03C1), and the asterisk-operator (U+2217), - # which could be confused for "-", "p", and "*", respectively. - allowed-confusables = ["−", "ρ", "∗"] - "# - )] - pub allowed_confusables: Option>, - - /// A list of builtins to treat as defined references, in addition to the - /// system builtins. - #[option( - default = r#"[]"#, - value_type = "list[str]", - example = r#" - builtins = ["_"] - "# - )] - pub builtins: Option>, - /// A path to the cache directory. /// /// By default, Ruff stores cache results in a `.ruff_cache` directory in @@ -77,20 +52,108 @@ pub struct Options { )] pub cache_dir: Option, - /// A regular expression used to identify "dummy" variables, or those which - /// should be ignored when enforcing (e.g.) unused-variable rules. The - /// default expression matches `_`, `__`, and `_var`, but not `_var_`. + /// A path to a local `pyproject.toml` file to merge into this + /// configuration. User home directory and environment variables will be + /// expanded. + /// + /// To resolve the current `pyproject.toml` file, Ruff will first resolve + /// this base configuration file, then merge in any properties defined + /// in the current configuration file. #[option( - default = r#""^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$""#, - value_type = "re.Pattern", + default = r#"null"#, + value_type = "str", example = r#" - # Only ignore variables named "_". - dummy-variable-rgx = "^_$" + # Extend the `pyproject.toml` file in the parent directory. + extend = "../pyproject.toml" + # But use a different line length. + line-length = 100 "# )] - pub dummy_variable_rgx: Option, + pub extend: Option, + + /// The style in which violation messages should be formatted: `"text"` + /// (default), `"grouped"` (group messages by file), `"json"` + /// (machine-readable), `"junit"` (machine-readable XML), `"github"` (GitHub + /// Actions annotations), `"gitlab"` (GitLab CI code quality report), + /// `"pylint"` (Pylint text format) or `"azure"` (Azure Pipeline logging commands). + #[option( + default = r#""text""#, + value_type = r#""text" | "json" | "junit" | "github" | "gitlab" | "pylint" | "azure""#, + example = r#" + # Group violations by containing file. + output-format = "grouped" + "# + )] + pub output_format: Option, + + /// Enable fix behavior by-default when running `ruff` (overridden + /// by the `--fix` and `--no-fix` command-line flags). + /// Only includes automatic fixes unless `--unsafe-fixes` is provided. + #[option(default = "false", value_type = "bool", example = "fix = true")] + pub fix: Option, + + /// Enable application of unsafe fixes. + #[option( + default = "false", + value_type = "bool", + example = "unsafe-fixes = true" + )] + pub unsafe_fixes: Option, + + /// Like `fix`, but disables reporting on leftover violation. Implies `fix`. + #[option(default = "false", value_type = "bool", example = "fix-only = true")] + pub fix_only: Option, + + /// Whether to show source code snippets when reporting lint violations + /// (overridden by the `--show-source` command-line flag). + #[option( + default = "false", + value_type = "bool", + example = r#" + # By default, always show source code snippets. + show-source = true + "# + )] + pub show_source: Option, + + /// Whether to show an enumeration of all fixed lint violations + /// (overridden by the `--show-fixes` command-line flag). + #[option( + default = "false", + value_type = "bool", + example = r#" + # Enumerate all fixed violations. + show-fixes = true + "# + )] + pub show_fixes: Option, + + /// Require a specific version of Ruff to be running (useful for unifying + /// results across many environments, e.g., with a `pyproject.toml` + /// file). + #[option( + default = "null", + value_type = "str", + example = r#" + required-version = "0.0.193" + "# + )] + pub required_version: Option, + + /// Whether to enable preview mode. When preview mode is enabled, Ruff will + /// use unstable rules, fixes, and formatting. + #[option( + default = "false", + value_type = "bool", + example = r#" + # Enable preview features. + preview = true + "# + )] + pub preview: Option, - /// A list of file patterns to exclude from linting. + // File resolver options + /// A list of file patterns to exclude from formatting and linting. /// /// Exclusions are based on globs, and can be either: /// @@ -115,26 +178,7 @@ pub struct Options { )] pub exclude: Option>, - /// A path to a local `pyproject.toml` file to merge into this - /// configuration. User home directory and environment variables will be - /// expanded. - /// - /// To resolve the current `pyproject.toml` file, Ruff will first resolve - /// this base configuration file, then merge in any properties defined - /// in the current configuration file. - #[option( - default = r#"None"#, - value_type = "str", - example = r#" - # Extend the `pyproject.toml` file in the parent directory. - extend = "../pyproject.toml" - # But use a different line length. - line-length = 100 - "# - )] - pub extend: Option, - - /// A list of file patterns to omit from linting, in addition to those + /// A list of file patterns to omit from formatting and linting, in addition to those /// specified by `exclude`. /// /// Exclusions are based on globs, and can be either: @@ -175,11 +219,291 @@ pub struct Options { )] pub extend_include: Option>, + /// Whether to enforce `exclude` and `extend-exclude` patterns, even for + /// paths that are passed to Ruff explicitly. Typically, Ruff will lint + /// any paths passed in directly, even if they would typically be + /// excluded. Setting `force-exclude = true` will cause Ruff to + /// respect these exclusions unequivocally. + /// + /// This is useful for [`pre-commit`](https://pre-commit.com/), which explicitly passes all + /// changed files to the [`ruff-pre-commit`](https://github.com/astral-sh/ruff-pre-commit) + /// plugin, regardless of whether they're marked as excluded by Ruff's own + /// settings. + #[option( + default = r#"false"#, + value_type = "bool", + example = r#" + force-exclude = true + "# + )] + pub force_exclude: Option, + + /// A list of file patterns to include when linting. + /// + /// Inclusion are based on globs, and should be single-path patterns, like + /// `*.pyw`, to include any file with the `.pyw` extension. `pyproject.toml` is + /// included here not for configuration but because we lint whether e.g. the + /// `[project]` matches the schema. + /// + /// For more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax). + #[option( + default = r#"["*.py", "*.pyi", "**/pyproject.toml"]"#, + value_type = "list[str]", + example = r#" + include = ["*.py"] + "# + )] + pub include: Option>, + + /// Whether to automatically exclude files that are ignored by `.ignore`, + /// `.gitignore`, `.git/info/exclude`, and global `gitignore` files. + /// Enabled by default. + #[option( + default = "true", + value_type = "bool", + example = r#" + respect-gitignore = false + "# + )] + pub respect_gitignore: Option, + + // Generic python options + /// A list of builtins to treat as defined references, in addition to the + /// system builtins. + #[option( + default = r#"[]"#, + value_type = "list[str]", + example = r#" + builtins = ["_"] + "# + )] + pub builtins: Option>, + + /// Mark the specified directories as namespace packages. For the purpose of + /// module resolution, Ruff will treat those directories as if they + /// contained an `__init__.py` file. + #[option( + default = r#"[]"#, + value_type = "list[str]", + example = r#" + namespace-packages = ["airflow/providers"] + "# + )] + pub namespace_packages: Option>, + + /// The minimum Python version to target, e.g., when considering automatic + /// code upgrades, like rewriting type annotations. Ruff will not propose + /// changes using features that are not available in the given version. + /// + /// For example, to represent supporting Python >=3.10 or ==3.10 + /// specify `target-version = "py310"`. + /// + /// If omitted, and Ruff is configured via a `pyproject.toml` file, the + /// target version will be inferred from its `project.requires-python` + /// field (e.g., `requires-python = ">=3.8"`). If Ruff is configured via + /// `ruff.toml` or `.ruff.toml`, no such inference will be performed. + #[option( + default = r#""py38""#, + value_type = r#""py37" | "py38" | "py39" | "py310" | "py311" | "py312""#, + example = r#" + # Always generate Python 3.7-compatible code. + target-version = "py37" + "# + )] + pub target_version: Option, + + /// The directories to consider when resolving first- vs. third-party + /// imports. + /// + /// As an example: given a Python package structure like: + /// + /// ```text + /// my_project + /// ├── pyproject.toml + /// └── src + /// └── my_package + /// ├── __init__.py + /// ├── foo.py + /// └── bar.py + /// ``` + /// + /// The `./src` directory should be included in the `src` option + /// (e.g., `src = ["src"]`), such that when resolving imports, + /// `my_package.foo` is considered a first-party import. + /// + /// When omitted, the `src` directory will typically default to the + /// directory containing the nearest `pyproject.toml`, `ruff.toml`, or + /// `.ruff.toml` file (the "project root"), unless a configuration file + /// is explicitly provided (e.g., via the `--config` command-line flag). + /// + /// This field supports globs. For example, if you have a series of Python + /// packages in a `python_modules` directory, `src = ["python_modules/*"]` + /// would expand to incorporate all of the packages in that directory. User + /// home directory and environment variables will also be expanded. + #[option( + default = r#"["."]"#, + value_type = "list[str]", + example = r#" + # Allow imports relative to the "src" and "test" directories. + src = ["src", "test"] + "# + )] + pub src: Option>, + + // Global Formatting options + /// The line length to use when enforcing long-lines violations (like `E501`) + /// and at which `isort` and the formatter prefers to wrap lines. + /// + /// The length is determined by the number of characters per line, except for lines containing East Asian characters or emojis. + /// For these lines, the [unicode width](https://unicode.org/reports/tr11/) of each character is added up to determine the length. + /// + /// The value must be greater than `0` and less than or equal to `320`. + /// + /// Note: While the formatter will attempt to format lines such that they remain + /// within the `line-length`, it isn't a hard upper bound, and formatted lines may + /// exceed the `line-length`. + /// + /// See [`pycodestyle.max-line-length`](#pycodestyle-max-line-length) to configure different lengths for `E501` and the formatter. + #[option( + default = "88", + value_type = "int", + example = r#" + # Allow lines to be as long as 120. + line-length = 120 + "# + )] + pub line_length: Option, + + /// The number of spaces per indentation level (tab). + /// + /// Used by the formatter and when enforcing long-line violations (like `E501`) to determine the visual + /// width of a tab. + /// + /// This option changes the number of spaces the formatter inserts when + /// using soft-tabs (`indent-style = space`). + /// + /// PEP 8 recommends using 4 spaces per [indentation level](https://peps.python.org/pep-0008/#indentation). + #[option( + default = "4", + value_type = "int", + example = r#" + indent-width = 2 + "# + )] + pub indent_width: Option, + + /// The number of spaces a tab is equal to when enforcing long-line violations (like `E501`) + /// or formatting code with the formatter. + /// + /// This option changes the number of spaces inserted by the formatter when + /// using soft-tabs (`indent-style = space`). + #[option( + default = "4", + value_type = "int", + example = r#" + tab-size = 2 + "# + )] + #[deprecated( + since = "0.1.2", + note = "The `tab-size` option has been renamed to `indent-width` to emphasize that it configures the indentation used by the formatter as well as the tab width. Please update your configuration to use `indent-width = ` instead." + )] + pub tab_size: Option, + + pub lint: Option, + + /// The lint sections specified at the top level. + #[serde(flatten)] + pub lint_top_level: LintCommonOptions, + + /// Options to configure code formatting. + #[option_group] + pub format: Option, +} + +/// Experimental section to configure Ruff's linting. This new section will eventually +/// replace the top-level linting options. +/// +/// Options specified in the `lint` section take precedence over the top-level settings. +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] +#[derive(Debug, PartialEq, Eq, Default, OptionsMetadata, Serialize, Deserialize)] +#[serde(deny_unknown_fields, rename_all = "kebab-case")] +pub struct LintOptions { + #[serde(flatten)] + pub common: LintCommonOptions, + + /// A list of file patterns to exclude from linting in addition to the files excluded globally (see [`exclude`](#exclude), and [`extend-exclude`](#extend-exclude)). + /// + /// Exclusions are based on globs, and can be either: + /// + /// - Single-path patterns, like `.mypy_cache` (to exclude any directory + /// named `.mypy_cache` in the tree), `foo.py` (to exclude any file named + /// `foo.py`), or `foo_*.py` (to exclude any file matching `foo_*.py` ). + /// - Relative patterns, like `directory/foo.py` (to exclude that specific + /// file) or `directory/*.py` (to exclude any Python files in + /// `directory`). Note that these paths are relative to the project root + /// (e.g., the directory containing your `pyproject.toml`). + /// + /// For more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax). + #[option( + default = r#"[]"#, + value_type = "list[str]", + example = r#" + exclude = ["generated"] + "# + )] + pub exclude: Option>, + + /// Whether to enable preview mode. When preview mode is enabled, Ruff will + /// use unstable rules and fixes. + #[option( + default = "false", + value_type = "bool", + example = r#" + # Enable preview features. + preview = true + "# + )] + pub preview: Option, +} + +// Note: This struct should be inlined into [`LintOptions`] once support for the top-level lint settings +// is removed. + +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] +#[derive( + Debug, PartialEq, Eq, Default, OptionsMetadata, CombineOptions, Serialize, Deserialize, +)] +#[serde(deny_unknown_fields, rename_all = "kebab-case")] +pub struct LintCommonOptions { + /// A list of allowed "confusable" Unicode characters to ignore when + /// enforcing `RUF001`, `RUF002`, and `RUF003`. + #[option( + default = r#"[]"#, + value_type = "list[str]", + example = r#" + # Allow minus-sign (U+2212), greek-small-letter-rho (U+03C1), and the asterisk-operator (U+2217), + # which could be confused for "-", "p", and "*", respectively. + allowed-confusables = ["−", "ρ", "∗"] + "# + )] + pub allowed_confusables: Option>, + + /// A regular expression used to identify "dummy" variables, or those which + /// should be ignored when enforcing (e.g.) unused-variable rules. The + /// default expression matches `_`, `__`, and `_var`, but not `_var_`. + #[option( + default = r#""^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$""#, + value_type = "re.Pattern", + example = r#" + # Only ignore variables named "_". + dummy-variable-rgx = "^_$" + "# + )] + pub dummy_variable_rgx: Option, + /// A list of rule codes or prefixes to ignore, in addition to those /// specified by `ignore`. - /// - /// This option has been **deprecated** in favor of `ignore` - /// since its usage is now interchangeable with `ignore`. #[option( default = "[]", value_type = "list[RuleSelector]", @@ -188,7 +512,9 @@ pub struct Options { extend-ignore = ["F841"] "# )] - #[cfg_attr(feature = "schemars", schemars(skip))] + #[deprecated( + note = "The `extend-ignore` option is now interchangeable with `ignore`. Please update your configuration to use the `ignore` option instead." + )] pub extend_ignore: Option>, /// A list of rule codes or prefixes to enable, in addition to those @@ -203,13 +529,13 @@ pub struct Options { )] pub extend_select: Option>, - /// A list of rule codes or prefixes to consider autofixable, in addition to those + /// A list of rule codes or prefixes to consider fixable, in addition to those /// specified by `fixable`. #[option( default = r#"[]"#, value_type = "list[RuleSelector]", example = r#" - # Enable autofix for flake8-bugbear (`B`), on top of any rules specified by `fixable`. + # Enable fix for flake8-bugbear (`B`), on top of any rules specified by `fixable`. extend-fixable = ["B"] "# )] @@ -217,13 +543,12 @@ pub struct Options { /// A list of rule codes or prefixes to consider non-auto-fixable, in addition to those /// specified by `unfixable`. - /// - /// This option has been **deprecated** in favor of `unfixable` since its usage is now - /// interchangeable with `unfixable`. - #[cfg_attr(feature = "schemars", schemars(skip))] + #[deprecated( + note = "The `extend-unfixable` option is now interchangeable with `unfixable`. Please update your configuration to use the `unfixable` option instead." + )] pub extend_unfixable: Option>, - /// A list of rule codes that are unsupported by Ruff, but should be + /// A list of rule codes or prefixes that are unsupported by Ruff, but should be /// preserved when (e.g.) validating `# noqa` directives. Useful for /// retaining `# noqa` directives that cover plugins not yet implemented /// by Ruff. @@ -231,74 +556,24 @@ pub struct Options { default = "[]", value_type = "list[str]", example = r#" - # Avoiding flagging (and removing) `V101` from any `# noqa` - # directives, despite Ruff's lack of support for `vulture`. - external = ["V101"] + # Avoiding flagging (and removing) any codes starting with `V` from any + # `# noqa` directives, despite Ruff's lack of support for `vulture`. + external = ["V"] "# )] pub external: Option>, - /// Enable autofix behavior by-default when running `ruff` (overridden - /// by the `--fix` and `--no-fix` command-line flags). - #[option(default = "false", value_type = "bool", example = "fix = true")] - pub fix: Option, - - /// Like `fix`, but disables reporting on leftover violation. Implies `fix`. - #[option(default = "false", value_type = "bool", example = "fix-only = true")] - pub fix_only: Option, - - /// A list of rule codes or prefixes to consider autofixable. By default, - /// all rules are considered autofixable. - #[option( - default = r#"["ALL"]"#, - value_type = "list[RuleSelector]", - example = r#" - # Only allow autofix behavior for `E` and `F` rules. - fixable = ["E", "F"] - "# - )] - pub fixable: Option>, - - /// The style in which violation messages should be formatted: `"text"` - /// (default), `"grouped"` (group messages by file), `"json"` - /// (machine-readable), `"junit"` (machine-readable XML), `"github"` (GitHub - /// Actions annotations), `"gitlab"` (GitLab CI code quality report), - /// `"pylint"` (Pylint text format) or `"azure"` (Azure Pipeline logging commands). - #[option( - default = r#""text""#, - value_type = r#""text" | "json" | "junit" | "github" | "gitlab" | "pylint" | "azure""#, - example = r#" - # Group violations by containing file. - output-format = "grouped" - "# - )] - pub output_format: Option, - - #[option( - default = r#"false"#, - value_type = "bool", - example = r#" - force-exclude = true - "# - )] - /// Whether to enforce `exclude` and `extend-exclude` patterns, even for - /// paths that are passed to Ruff explicitly. Typically, Ruff will lint - /// any paths passed in directly, even if they would typically be - /// excluded. Setting `force-exclude = true` will cause Ruff to - /// respect these exclusions unequivocally. - /// - /// This is useful for [`pre-commit`](https://pre-commit.com/), which explicitly passes all - /// changed files to the [`ruff-pre-commit`](https://github.com/astral-sh/ruff-pre-commit) - /// plugin, regardless of whether they're marked as excluded by Ruff's own - /// settings. + /// A list of rule codes or prefixes to consider fixable. By default, + /// all rules are considered fixable. #[option( - default = r#"false"#, - value_type = "bool", + default = r#"["ALL"]"#, + value_type = "list[RuleSelector]", example = r#" - force-exclude = true + # Only allow fix behavior for `E` and `F` rules. + fixable = ["E", "F"] "# )] - pub force_exclude: Option, + pub fixable: Option>, /// A list of rule codes or prefixes to ignore. Prefixes can specify exact /// rules (like `F841`), entire categories (like `F`), or anything in @@ -317,58 +592,42 @@ pub struct Options { )] pub ignore: Option>, - /// Avoid automatically removing unused imports in `__init__.py` files. Such - /// imports will still be flagged, but with a dedicated message suggesting - /// that the import is either added to the module's `__all__` symbol, or - /// re-exported with a redundant alias (e.g., `import os as os`). - #[option( - default = "false", - value_type = "bool", - example = r#" - ignore-init-module-imports = true - "# - )] - pub ignore_init_module_imports: Option, - - /// A list of file patterns to include when linting. - /// - /// Inclusion are based on globs, and should be single-path patterns, like - /// `*.pyw`, to include any file with the `.pyw` extension. `pyproject.toml` is - /// included here not for configuration but because we lint whether e.g. the - /// `[project]` matches the schema. - /// - /// For more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax). + /// A list of rule codes or prefixes for which unsafe fixes should be considered + /// safe. #[option( - default = r#"["*.py", "*.pyi", "**/pyproject.toml"]"#, - value_type = "list[str]", + default = "[]", + value_type = "list[RuleSelector]", example = r#" - include = ["*.py"] + # Allow applying all unsafe fixes in the `E` rules and `F401` without the `--unsafe-fixes` flag + extend-safe-fixes = ["E", "F401"] "# )] - pub include: Option>, + pub extend_safe_fixes: Option>, - /// The line length to use when enforcing long-lines violations (like - /// `E501`). Must be greater than `0` and less than or equal to `320`. + /// A list of rule codes or prefixes for which safe fixes should be considered + /// unsafe. #[option( - default = "88", - value_type = "int", + default = "[]", + value_type = "list[RuleSelector]", example = r#" - # Allow lines to be as long as 120 characters. - line-length = 120 + # Require the `--unsafe-fixes` flag when fixing the `E` rules and `F401` + extend-unsafe-fixes = ["E", "F401"] "# )] - #[cfg_attr(feature = "schemars", schemars(range(min = 1, max = 320)))] - pub line_length: Option, + pub extend_unsafe_fixes: Option>, - /// The tabulation size to calculate line length. + /// Avoid automatically removing unused imports in `__init__.py` files. Such + /// imports will still be flagged, but with a dedicated message suggesting + /// that the import is either added to the module's `__all__` symbol, or + /// re-exported with a redundant alias (e.g., `import os as os`). #[option( - default = "4", - value_type = "int", + default = "false", + value_type = "bool", example = r#" - tab-size = 8 + ignore-init-module-imports = true "# )] - pub tab_size: Option, + pub ignore_init_module_imports: Option, /// A list of objects that should be treated equivalently to a /// `logging.Logger` object. @@ -395,30 +654,6 @@ pub struct Options { )] pub logger_objects: Option>, - /// Require a specific version of Ruff to be running (useful for unifying - /// results across many environments, e.g., with a `pyproject.toml` - /// file). - #[option( - default = "None", - value_type = "str", - example = r#" - required-version = "0.0.193" - "# - )] - pub required_version: Option, - - /// Whether to automatically exclude files that are ignored by `.ignore`, - /// `.gitignore`, `.git/info/exclude`, and global `gitignore` files. - /// Enabled by default. - #[option( - default = "true", - value_type = "bool", - example = r#" - respect-gitignore = false - "# - )] - pub respect_gitignore: Option, - /// A list of rule codes or prefixes to enable. Prefixes can specify exact /// rules (like `F841`), entire categories (like `F`), or anything in /// between. @@ -427,121 +662,27 @@ pub struct Options { /// `ignore`, respectively), more specific prefixes override less /// specific prefixes. #[option( - default = r#"["E", "F"]"#, + default = r#"["E4", "E7", "E9", "F"]"#, value_type = "list[RuleSelector]", example = r#" - # On top of the defaults (`E`, `F`), enable flake8-bugbear (`B`) and flake8-quotes (`Q`). - select = ["E", "F", "B", "Q"] + # On top of the defaults (`E4`, E7`, `E9`, and `F`), enable flake8-bugbear (`B`) and flake8-quotes (`Q`). + select = ["E4", "E7", "E9", "F", "B", "Q"] "# )] pub select: Option>, - /// Whether to show source code snippets when reporting lint violations - /// (overridden by the `--show-source` command-line flag). - #[option( - default = "false", - value_type = "bool", - example = r#" - # By default, always show source code snippets. - show-source = true - "# - )] - pub show_source: Option, - - /// Whether to show an enumeration of all autofixed lint violations - /// (overridden by the `--show-fixes` command-line flag). - #[option( - default = "false", - value_type = "bool", - example = r#" - # Enumerate all fixed violations. - show-fixes = true - "# - )] - pub show_fixes: Option, - - /// The directories to consider when resolving first- vs. third-party - /// imports. - /// - /// As an example: given a Python package structure like: - /// - /// ```text - /// my_project - /// ├── pyproject.toml - /// └── src - /// └── my_package - /// ├── __init__.py - /// ├── foo.py - /// └── bar.py - /// ``` - /// - /// The `./src` directory should be included in the `src` option - /// (e.g., `src = ["src"]`), such that when resolving imports, - /// `my_package.foo` is considered a first-party import. - /// - /// When omitted, the `src` directory will typically default to the - /// directory containing the nearest `pyproject.toml`, `ruff.toml`, or - /// `.ruff.toml` file (the "project root"), unless a configuration file - /// is explicitly provided (e.g., via the `--config` command-line flag). - /// - /// This field supports globs. For example, if you have a series of Python - /// packages in a `python_modules` directory, `src = ["python_modules/*"]` - /// would expand to incorporate all of the packages in that directory. User - /// home directory and environment variables will also be expanded. - #[option( - default = r#"["."]"#, - value_type = "list[str]", - example = r#" - # Allow imports relative to the "src" and "test" directories. - src = ["src", "test"] - "# - )] - pub src: Option>, - - /// Mark the specified directories as namespace packages. For the purpose of - /// module resolution, Ruff will treat those directories as if they - /// contained an `__init__.py` file. - #[option( - default = r#"[]"#, - value_type = "list[str]", - example = r#" - namespace-packages = ["airflow/providers"] - "# - )] - pub namespace_packages: Option>, - - /// The minimum Python version to target, e.g., when considering automatic - /// code upgrades, like rewriting type annotations. Ruff will not propose - /// changes using features that are not available in the given version. - /// - /// For example, to represent supporting Python >=3.10 or ==3.10 - /// specify `target-version = "py310"`. - /// - /// If omitted, and Ruff is configured via a `pyproject.toml` file, the - /// target version will be inferred from its `project.requires-python` - /// field (e.g., `requires-python = ">=3.8"`). If Ruff is configured via - /// `ruff.toml` or `.ruff.toml`, no such inference will be performed. - #[option( - default = r#""py38""#, - value_type = r#""py37" | "py38" | "py39" | "py310" | "py311" | "py312""#, - example = r#" - # Always generate Python 3.7-compatible code. - target-version = "py37" - "# - )] - pub target_version: Option, - - /// Whether to enable preview mode. When preview mode is enabled, Ruff will - /// use unstable rules and fixes. + /// Whether to require exact codes to select preview rules. When enabled, + /// preview rules will not be selected by prefixes — the full code of each + /// preview rule will be required to enable the rule. #[option( default = "false", value_type = "bool", example = r#" - # Enable preview features - preview = true + # Require explicit selection of preview rules. + explicit-preview-rules = true "# )] - pub preview: Option, + pub explicit_preview_rules: Option, /// A list of task tags to recognize (e.g., "TODO", "FIXME", "XXX"). /// @@ -551,7 +692,9 @@ pub struct Options { #[option( default = r#"["TODO", "FIXME", "XXX"]"#, value_type = "list[str]", - example = r#"task-tags = ["HACK"]"# + example = r#" + task-tags = ["HACK"] + "# )] pub task_tags: Option>, @@ -570,12 +713,12 @@ pub struct Options { )] pub typing_modules: Option>, - /// A list of rule codes or prefixes to consider non-autofix-able. + /// A list of rule codes or prefixes to consider non-fixable. #[option( default = "[]", value_type = "list[RuleSelector]", example = r#" - # Disable autofix for unused imports (`F401`). + # Disable fix for unused imports (`F401`). unfixable = ["F401"] "# )] @@ -677,20 +820,6 @@ pub struct Options { #[option_group] pub pyupgrade: Option, - /// Options to configure the code formatting. - /// - /// Previously: - /// The style in which violation messages should be formatted: `"text"` - /// (default), `"grouped"` (group messages by file), `"json"` - /// (machine-readable), `"junit"` (machine-readable XML), `"github"` (GitHub - /// Actions annotations), `"gitlab"` (GitLab CI code quality report), - /// `"pylint"` (Pylint text format) or `"azure"` (Azure Pipeline logging commands). - /// - /// This option has been **deprecated** in favor of `output-format` - /// to avoid ambiguity with Ruff's upcoming formatter. - #[option_group] - pub format: Option, - // Tables are required to go last. /// A list of mappings from file pattern to rule codes or prefixes to /// exclude, when considering any matching files. @@ -722,7 +851,7 @@ pub struct Options { #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive( - Debug, PartialEq, Eq, Default, ConfigurationOptions, CombineOptions, Serialize, Deserialize, + Debug, PartialEq, Eq, Default, OptionsMetadata, CombineOptions, Serialize, Deserialize, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] pub struct Flake8AnnotationsOptions { @@ -790,7 +919,7 @@ impl Flake8AnnotationsOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -838,7 +967,7 @@ impl Flake8BanditOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -868,7 +997,7 @@ impl Flake8BugbearOptions { } } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -890,7 +1019,7 @@ impl Flake8BuiltinsOptions { } } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -915,7 +1044,7 @@ impl Flake8ComprehensionsOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -938,7 +1067,7 @@ pub struct Flake8CopyrightOptions { /// Author to enforce within the copyright notice. If provided, the /// author must be present immediately following the copyright notice. - #[option(default = "None", value_type = "str", example = r#"author = "Ruff""#)] + #[option(default = "null", value_type = "str", example = r#"author = "Ruff""#)] pub author: Option, /// A minimum file size (in bytes) required for a copyright notice to @@ -969,7 +1098,7 @@ impl Flake8CopyrightOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -988,7 +1117,7 @@ impl Flake8ErrMsgOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -1025,7 +1154,7 @@ impl Flake8GetTextOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -1058,7 +1187,7 @@ impl Flake8ImplicitStrConcatOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -1140,7 +1269,7 @@ impl Flake8ImportConventionsOptions { } } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -1276,13 +1405,16 @@ impl Flake8PytestStyleOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Flake8QuotesOptions { /// Quote style to prefer for inline strings (either "single" or /// "double"). + /// + /// When using the formatter, ensure that `format.quote-style` is set to + /// the same preferred quote style. #[option( default = r#""double""#, value_type = r#""single" | "double""#, @@ -1294,6 +1426,9 @@ pub struct Flake8QuotesOptions { /// Quote style to prefer for multiline strings (either "single" or /// "double"). + /// + /// When using the formatter, only "double" is compatible, as the formatter + /// enforces double quotes for multiline strings. #[option( default = r#""double""#, value_type = r#""single" | "double""#, @@ -1304,6 +1439,9 @@ pub struct Flake8QuotesOptions { pub multiline_quotes: Option, /// Quote style to prefer for docstrings (either "single" or "double"). + /// + /// When using the formatter, only "double" is compatible, as the formatter + /// enforces double quotes for docstrings strings. #[option( default = r#""double""#, value_type = r#""single" | "double""#, @@ -1339,7 +1477,7 @@ impl Flake8QuotesOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -1379,7 +1517,7 @@ impl Flake8SelfOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -1436,7 +1574,7 @@ impl Flake8TidyImportsOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -1510,7 +1648,7 @@ impl Flake8TypeCheckingOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -1533,7 +1671,7 @@ impl Flake8UnusedArgumentsOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -1554,6 +1692,9 @@ pub struct IsortOptions { /// `combine-as-imports = true`. When `combine-as-imports` isn't /// enabled, every aliased `import from` will be given its own line, in /// which case, wrapping is not necessary. + /// + /// When using the formatter, ensure that `format.skip-magic-trailing-comma` is set to `false` (default) + /// when enabling `force-wrap-aliases` to avoid that the formatter collapses members if they all fit on a single line. #[option( default = r#"false"#, value_type = "bool", @@ -1597,6 +1738,9 @@ pub struct IsortOptions { /// the imports will never be folded into one line. /// /// See isort's [`split-on-trailing-comma`](https://pycqa.github.io/isort/docs/configuration/options.html#split-on-trailing-comma) option. + /// + /// When using the formatter, ensure that `format.skip-magic-trailing-comma` is set to `false` (default) when enabling `split-on-trailing-comma` + /// to avoid that the formatter removes the trailing commas. #[option( default = r#"true"#, value_type = "bool", @@ -1778,6 +1922,9 @@ pub struct IsortOptions { /// The number of blank lines to place after imports. /// Use `-1` for automatic determination. + /// + /// When using the formatter, only the values `-1`, `1`, and `2` are compatible because + /// it enforces at least one empty and at most two empty lines after imports. #[option( default = r#"-1"#, value_type = "int", @@ -1789,11 +1936,14 @@ pub struct IsortOptions { pub lines_after_imports: Option, /// The number of lines to place between "direct" and `import from` imports. + /// + /// When using the formatter, only the values `0` and `1` are compatible because + /// it preserves up to one empty line after imports in nested blocks. #[option( default = r#"0"#, value_type = "int", example = r#" - # Use a single line between direct and from import + # Use a single line between direct and from import. lines-between-types = 1 "# )] @@ -2016,7 +2166,7 @@ impl IsortOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -2044,12 +2194,16 @@ impl McCabeOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Pep8NamingOptions { /// A list of names (or patterns) to ignore when considering `pep8-naming` violations. + /// + /// Supports glob patterns. For example, to ignore all names starting with + /// or ending with `_test`, you could use `ignore-names = ["test_*", "*_test"]`. + /// For more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax). #[option( default = r#"["setUp", "tearDown", "setUpClass", "tearDownClass", "setUpModule", "tearDownModule", "asyncSetUp", "asyncTearDown", "setUpTestData", "failureException", "longMessage", "maxDiff"]"#, value_type = "list[str]", @@ -2060,7 +2214,11 @@ pub struct Pep8NamingOptions { pub ignore_names: Option>, /// Additional names (or patterns) to ignore when considering `pep8-naming` violations, - /// in addition to those included in `ignore-names`. + /// in addition to those included in `ignore-names` + /// + /// Supports glob patterns. For example, to ignore all names starting with + /// or ending with `_test`, you could use `ignore-names = ["test_*", "*_test"]`. + /// For more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax). #[option( default = r#"[]"#, value_type = "list[str]", @@ -2074,6 +2232,9 @@ pub struct Pep8NamingOptions { /// /// For example, Ruff will expect that any method decorated by a decorator /// in this list takes a `cls` argument as its first argument. + /// + /// Expects to receive a list of fully-qualified names (e.g., `pydantic.validator`, + /// rather than `validator`). #[option( default = r#"[]"#, value_type = "list[str]", @@ -2090,12 +2251,15 @@ pub struct Pep8NamingOptions { /// /// For example, Ruff will expect that any method decorated by a decorator /// in this list has no `self` or `cls` argument. + /// + /// Expects to receive a list of fully-qualified names (e.g., `belay.Device.teardown`, + /// rather than `teardown`). #[option( default = r#"[]"#, value_type = "list[str]", example = r#" - # Allow a shorthand alias, `@stcmthd`, to trigger static method treatment. - staticmethod-decorators = ["stcmthd"] + # Allow Belay's `@Device.teardown` decorator to trigger static method treatment. + staticmethod-decorators = ["belay.Device.teardown"] "# )] pub staticmethod_decorators: Option>, @@ -2123,18 +2287,47 @@ impl Pep8NamingOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct PycodestyleOptions { - /// The maximum line length to allow for line-length violations within + /// The maximum line length to allow for [`line-too-long`](https://docs.astral.sh/ruff/rules/line-too-long/) violations. By default, + /// this is set to the value of the [`line-length`](#line-length) option. + /// + /// Use this option when you want to detect extra-long lines that the formatter can't automatically split by setting + /// `pycodestyle.line-length` to a value larger than [`line-length`](#line-length). + /// + /// ```toml + /// line-length = 88 # The formatter wraps lines at a length of 88 + /// + /// [pycodestyle] + /// max-line-length = 100 # E501 reports lines that exceed the length of 100. + /// ``` + /// + /// The length is determined by the number of characters per line, except for lines containing East Asian characters or emojis. + /// For these lines, the [unicode width](https://unicode.org/reports/tr11/) of each character is added up to determine the length. + /// + /// See the [`line-too-long`](https://docs.astral.sh/ruff/rules/line-too-long/) rule for more information. + #[option( + default = "null", + value_type = "int", + example = r#" + max-line-length = 100 + "# + )] + pub max_line_length: Option, + + /// The maximum line length to allow for [`doc-line-too-long`](https://docs.astral.sh/ruff/rules/doc-line-too-long/) violations within /// documentation (`W505`), including standalone comments. By default, /// this is set to null which disables reporting violations. /// + /// The length is determined by the number of characters per line, except for lines containing Asian characters or emojis. + /// For these lines, the [unicode width](https://unicode.org/reports/tr11/) of each character is added up to determine the length. + /// /// See the [`doc-line-too-long`](https://docs.astral.sh/ruff/rules/doc-line-too-long/) rule for more information. #[option( - default = "None", + default = "null", value_type = "int", example = r#" max-doc-length = 88 @@ -2156,21 +2349,22 @@ pub struct PycodestyleOptions { } impl PycodestyleOptions { - pub fn into_settings(self) -> pycodestyle::settings::Settings { + pub fn into_settings(self, global_line_length: LineLength) -> pycodestyle::settings::Settings { pycodestyle::settings::Settings { max_doc_length: self.max_doc_length, + max_line_length: self.max_line_length.unwrap_or(global_line_length), ignore_overlong_task_comments: self.ignore_overlong_task_comments.unwrap_or_default(), } } } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct PydocstyleOptions { - /// Whether to use Google-style or NumPy-style conventions or the PEP257 + /// Whether to use Google-style or NumPy-style conventions or the [PEP 257](https://peps.python.org/pep-0257/) /// defaults when analyzing docstring sections. /// /// Enabling a convention will force-disable any rules that are not @@ -2199,7 +2393,7 @@ pub struct PydocstyleOptions { /// enabling _additional_ rules on top of a convention is currently /// unsupported. #[option( - default = r#"None"#, + default = r#"null"#, value_type = r#""google" | "numpy" | "pep257""#, example = r#" # Use Google-style docstrings. @@ -2246,7 +2440,7 @@ impl PydocstyleOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -2274,7 +2468,7 @@ impl PyflakesOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -2282,7 +2476,7 @@ pub struct PylintOptions { /// Constant types to ignore when used as "magic values" (see: `PLR2004`). #[option( default = r#"["str", "bytes"]"#, - value_type = r#"list["str" | "bytes" | "complex" | "float" | "int" | "tuple"]"#, + value_type = r#"list["str" | "bytes" | "complex" | "float" | "int"]"#, example = r#" allow-magic-value-types = ["int"] "# @@ -2316,6 +2510,11 @@ pub struct PylintOptions { example = r"max-public-methods = 20" )] pub max_public_methods: Option, + + /// Maximum number of Boolean expressions allowed within a single `if` statement + /// (see: `PLR0916`). + #[option(default = r"5", value_type = "int", example = r"max-bool-expr = 5")] + pub max_bool_expr: Option, } impl PylintOptions { @@ -2326,6 +2525,7 @@ impl PylintOptions { .allow_magic_value_types .unwrap_or(defaults.allow_magic_value_types), max_args: self.max_args.unwrap_or(defaults.max_args), + max_bool_expr: self.max_bool_expr.unwrap_or(defaults.max_bool_expr), max_returns: self.max_returns.unwrap_or(defaults.max_returns), max_branches: self.max_branches.unwrap_or(defaults.max_branches), max_statements: self.max_statements.unwrap_or(defaults.max_statements), @@ -2337,7 +2537,7 @@ impl PylintOptions { } #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -2391,83 +2591,100 @@ impl PyUpgradeOptions { } } -#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(untagged)] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub enum FormatOrOutputFormat { - Format(FormatOptions), - OutputFormat(SerializationFormat), -} - -impl FormatOrOutputFormat { - pub const fn as_output_format(&self) -> Option { - match self { - FormatOrOutputFormat::Format(_) => None, - FormatOrOutputFormat::OutputFormat(format) => Some(*format), - } - } -} - -impl OptionsMetadata for FormatOrOutputFormat { - fn record(visit: &mut dyn Visit) { - FormatOptions::record(visit); - } - - fn documentation() -> Option<&'static str> { - FormatOptions::documentation() - } -} - /// Experimental: Configures how `ruff format` formats your code. /// /// Please provide feedback in [this discussion](https://github.com/astral-sh/ruff/discussions/7310). #[derive( - Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions, + Debug, PartialEq, Eq, Default, Deserialize, Serialize, OptionsMetadata, CombineOptions, )] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct FormatOptions { + /// A list of file patterns to exclude from formatting in addition to the files excluded globally (see [`exclude`](#exclude), and [`extend-exclude`](#extend-exclude)). + /// + /// Exclusions are based on globs, and can be either: + /// + /// - Single-path patterns, like `.mypy_cache` (to exclude any directory + /// named `.mypy_cache` in the tree), `foo.py` (to exclude any file named + /// `foo.py`), or `foo_*.py` (to exclude any file matching `foo_*.py` ). + /// - Relative patterns, like `directory/foo.py` (to exclude that specific + /// file) or `directory/*.py` (to exclude any Python files in + /// `directory`). Note that these paths are relative to the project root + /// (e.g., the directory containing your `pyproject.toml`). + /// + /// For more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax). + #[option( + default = r#"[]"#, + value_type = "list[str]", + example = r#" + exclude = ["generated"] + "# + )] + pub exclude: Option>, + /// Whether to enable the unstable preview style formatting. #[option( default = "false", value_type = "bool", example = r#" - # Enable preview style formatting + # Enable preview style formatting. preview = true "# )] pub preview: Option, - /// Whether to use 4 spaces or hard tabs for indenting code. + /// Whether to use spaces or tabs for indentation. + /// + /// `indent-style = "space"` (default): + /// + /// ```python + /// def f(): + /// print("Hello") # Spaces indent the `print` statement. + /// ``` /// - /// Defaults to 4 spaces. We care about accessibility; if you do not need tabs for accessibility, we do not recommend you use them. + /// `indent-style = "tab""`: + /// + /// ```python + /// def f(): + /// print("Hello") # A tab `\t` indents the `print` statement. + /// ``` + /// + /// PEP 8 recommends using spaces for [indentation](https://peps.python.org/pep-0008/#indentation). + /// We care about accessibility; if you do not need tabs for accessibility, we do not recommend you use them. + /// + /// See [`indent-width`](#indent-width) to configure the number of spaces per indentation and the tab width. #[option( default = "space", value_type = r#""space" | "tab""#, example = r#" - # Use tabs instead of 4 space indentation + # Use tabs instead of 4 space indentation. indent-style = "tab" "# )] pub indent_style: Option, - /// Whether to prefer single `'` or double `"` quotes for strings and docstrings. + /// Whether to prefer single `'` or double `"` quotes for strings. Defaults to double quotes. + /// + /// In compliance with [PEP 8](https://peps.python.org/pep-0008/) and [PEP 257](https://peps.python.org/pep-0257/), + /// Ruff prefers double quotes for multiline strings and docstrings, regardless of the + /// configured quote style. /// - /// Ruff may deviate from this option if using the configured quotes would require more escaped quotes: + /// Ruff may also deviate from this option if using the configured quotes would require + /// escaping quote characters within the string. For example, given: /// /// ```python - /// a = "It's monday morning" - /// b = "a string without any quotes" + /// a = "a string without any quotes" + /// b = "It's monday morning" /// ``` /// - /// Ruff leaves `a` unchanged when using `quote-style = "single"` because it is otherwise - /// necessary to escape the `'` which leads to less readable code: `'It\'s monday morning'`. - /// Ruff changes the quotes of `b` to use single quotes. + /// Ruff will change `a` to use single quotes when using `quote-style = "single"`. However, + /// `b` will be unchanged, as converting to single quotes would require the inner `'` to be + /// escaped, which leads to less readable code: `'It\'s monday morning'`. #[option( default = r#"double"#, value_type = r#""double" | "single""#, example = r#" - # Prefer single quotes over double quotes + # Prefer single quotes over double quotes. quote-style = "single" "# )] @@ -2477,7 +2694,7 @@ pub struct FormatOptions { /// If this option is set to `true`, the magic trailing comma is ignored. /// /// For example, Ruff leaves the arguments separate even though - /// collapsing the arguments to a single line doesn't exceed the line width if `skip-magic-trailing-comma = false`: + /// collapsing the arguments to a single line doesn't exceed the line length if `skip-magic-trailing-comma = false`: /// /// ```python /// # The arguments remain on separate lines because of the trailing comma after `b` @@ -2503,16 +2720,16 @@ pub struct FormatOptions { /// The character Ruff uses at the end of a line. /// + /// * `auto`: The newline style is detected automatically on a file per file basis. Files with mixed line endings will be converted to the first detected line ending. Defaults to `\n` for files that contain no line endings. /// * `lf`: Line endings will be converted to `\n`. The default line ending on Unix. /// * `cr-lf`: Line endings will be converted to `\r\n`. The default line ending on Windows. - /// * `auto`: The newline style is detected automatically on a file per file basis. Files with mixed line endings will be converted to the first detected line ending. Defaults to `\n` for files that contain no line endings. /// * `native`: Line endings will be converted to `\n` on Unix and `\r\n` on Windows. #[option( - default = r#"lf"#, - value_type = r#""lf" | "crlf" | "auto" | "native""#, + default = r#"auto"#, + value_type = r#""auto" | "lf" | "cr-lf" | "native""#, example = r#" - # Automatically detect the line ending on a file per file basis. - line-ending = "auto" + # Use `\n` line endings for all files + line-ending = "lf" "# )] pub line_ending: Option, diff --git a/crates/ruff_workspace/src/options_base.rs b/crates/ruff_workspace/src/options_base.rs index 8bf095598976e..60cbbe6facf24 100644 --- a/crates/ruff_workspace/src/options_base.rs +++ b/crates/ruff_workspace/src/options_base.rs @@ -100,6 +100,7 @@ impl OptionSet { /// default: "false", /// value_type: "bool", /// example: "", + /// deprecated: None, /// }); /// } /// } @@ -121,6 +122,7 @@ impl OptionSet { /// default: "false", /// value_type: "bool", /// example: "", + /// deprecated: None /// }); /// /// visit.record_set("format", Nested::metadata()); @@ -136,6 +138,7 @@ impl OptionSet { /// default: "false", /// value_type: "bool", /// example: "", + /// deprecated: None /// }); /// } /// } @@ -166,6 +169,7 @@ impl OptionSet { /// default: "false", /// value_type: "bool", /// example: "", + /// deprecated: None /// }; /// /// impl OptionsMetadata for WithOptions { @@ -187,6 +191,7 @@ impl OptionSet { /// default: "false", /// value_type: "bool", /// example: "", + /// deprecated: None /// }; /// /// struct Root; @@ -198,6 +203,7 @@ impl OptionSet { /// default: "false", /// value_type: "bool", /// example: "", + /// deprecated: None /// }); /// /// visit.record_set("format", Nested::metadata()); @@ -280,11 +286,19 @@ impl<'fmt, 'buf> DisplayVisitor<'fmt, 'buf> { impl Visit for DisplayVisitor<'_, '_> { fn record_set(&mut self, name: &str, _: OptionSet) { - self.result = self.result.and_then(|_| writeln!(self.f, "{name}")); + self.result = self.result.and_then(|()| writeln!(self.f, "{name}")); } - fn record_field(&mut self, name: &str, _: OptionField) { - self.result = self.result.and_then(|_| writeln!(self.f, "{name}")); + fn record_field(&mut self, name: &str, field: OptionField) { + self.result = self.result.and_then(|()| { + write!(self.f, "{name}")?; + + if field.deprecated.is_some() { + write!(self.f, " (deprecated)")?; + } + + writeln!(self.f) + }); } } @@ -308,6 +322,13 @@ pub struct OptionField { pub default: &'static str, pub value_type: &'static str, pub example: &'static str, + pub deprecated: Option, +} + +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct Deprecated { + pub since: Option<&'static str>, + pub message: Option<&'static str>, } impl Display for OptionField { @@ -316,6 +337,21 @@ impl Display for OptionField { writeln!(f)?; writeln!(f, "Default value: {}", self.default)?; writeln!(f, "Type: {}", self.value_type)?; + + if let Some(deprecated) = &self.deprecated { + write!(f, "Deprecated")?; + + if let Some(since) = deprecated.since { + write!(f, " (since {since})")?; + } + + if let Some(message) = deprecated.message { + write!(f, ": {message}")?; + } + + writeln!(f)?; + } + writeln!(f, "Example usage:\n```toml\n{}\n```", self.example) } } diff --git a/crates/ruff_workspace/src/pyproject.rs b/crates/ruff_workspace/src/pyproject.rs index cf6fb30893b2e..38b7811dd634f 100644 --- a/crates/ruff_workspace/src/pyproject.rs +++ b/crates/ruff_workspace/src/pyproject.rs @@ -161,7 +161,7 @@ mod tests { use ruff_linter::line_width::LineLength; use ruff_linter::settings::types::PatternPrefixPair; - use crate::options::Options; + use crate::options::{LintCommonOptions, Options}; use crate::pyproject::{find_settings_toml, parse_pyproject_toml, Pyproject, Tools}; use crate::tests::test_resource_path; @@ -236,7 +236,10 @@ select = ["E501"] pyproject.tool, Some(Tools { ruff: Some(Options { - select: Some(vec![codes::Pycodestyle::E501.into()]), + lint_top_level: LintCommonOptions { + select: Some(vec![codes::Pycodestyle::E501.into()]), + ..LintCommonOptions::default() + }, ..Options::default() }) }) @@ -254,8 +257,11 @@ ignore = ["E501"] pyproject.tool, Some(Tools { ruff: Some(Options { - extend_select: Some(vec![codes::Ruff::_100.into()]), - ignore: Some(vec![codes::Pycodestyle::E501.into()]), + lint_top_level: LintCommonOptions { + extend_select: Some(vec![codes::Ruff::_100.into()]), + ignore: Some(vec![codes::Pycodestyle::E501.into()]), + ..LintCommonOptions::default() + }, ..Options::default() }) }) @@ -308,10 +314,14 @@ other-attribute = 1 "migrations".to_string(), "with_excluded_file/other_excluded_file.py".to_string(), ]), - per_file_ignores: Some(FxHashMap::from_iter([( - "__init__.py".to_string(), - vec![codes::Pyflakes::_401.into()] - )])), + + lint_top_level: LintCommonOptions { + per_file_ignores: Some(FxHashMap::from_iter([( + "__init__.py".to_string(), + vec![codes::Pyflakes::_401.into()] + )])), + ..LintCommonOptions::default() + }, ..Options::default() } ); diff --git a/crates/ruff_workspace/src/resolver.rs b/crates/ruff_workspace/src/resolver.rs index a7d3002bd253b..6bf5671a3ca59 100644 --- a/crates/ruff_workspace/src/resolver.rs +++ b/crates/ruff_workspace/src/resolver.rs @@ -1,23 +1,25 @@ //! Discover Python files, and their corresponding [`Settings`], from the //! filesystem. +use std::cmp::Ordering; use std::collections::BTreeMap; +use std::ffi::OsStr; use std::path::{Path, PathBuf}; use std::sync::RwLock; use anyhow::Result; use anyhow::{anyhow, bail}; -use ignore::{DirEntry, WalkBuilder, WalkState}; +use globset::{Candidate, GlobSet}; +use ignore::{WalkBuilder, WalkState}; use itertools::Itertools; use log::debug; use path_absolutize::path_dedot; use rustc_hash::{FxHashMap, FxHashSet}; +use ruff_linter::fs; use ruff_linter::packaging::is_package; -use ruff_linter::{fs, warn_user_once}; use crate::configuration::Configuration; -use crate::options::FormatOrOutputFormat; use crate::pyproject; use crate::pyproject::settings_toml; use crate::settings::Settings; @@ -221,10 +223,6 @@ fn resolve_configuration( let options = pyproject::load_options(&path) .map_err(|err| anyhow!("Failed to parse `{}`: {}", path.display(), err))?; - if matches!(options.format, Some(FormatOrOutputFormat::OutputFormat(_))) { - warn_user_once!("The option `format` has been deprecated to avoid ambiguity with Ruff's upcoming formatter. Use `output-format` instead."); - } - let project_root = relativity.resolve(&path); let configuration = Configuration::from_options(options, &project_root)?; @@ -281,7 +279,7 @@ pub fn python_files_in_path( paths: &[PathBuf], pyproject_config: &PyprojectConfig, transformer: &dyn ConfigurationTransformer, -) -> Result<(Vec>, Resolver)> { +) -> Result<(Vec>, Resolver)> { // Normalize every path (e.g., convert from relative to absolute). let mut paths: Vec = paths.iter().map(fs::normalize_path).unique().collect(); @@ -310,13 +308,12 @@ pub fn python_files_in_path( } } + let (first_path, rest_paths) = paths + .split_first() + .ok_or_else(|| anyhow!("Expected at least one path to search for Python files"))?; // Create the `WalkBuilder`. - let mut builder = WalkBuilder::new( - paths - .get(0) - .ok_or_else(|| anyhow!("Expected at least one path to search for Python files"))?, - ); - for path in &paths[1..] { + let mut builder = WalkBuilder::new(first_path); + for path in rest_paths { builder.add(path); } builder.standard_filters(pyproject_config.settings.file_resolver.respect_gitignore); @@ -326,7 +323,7 @@ pub fn python_files_in_path( // Run the `WalkParallel` to collect all Python files. let error: std::sync::Mutex> = std::sync::Mutex::new(Ok(())); let resolver: RwLock = RwLock::new(resolver); - let files: std::sync::Mutex>> = + let files: std::sync::Mutex>> = std::sync::Mutex::new(vec![]); walker.run(|| { Box::new(|result| { @@ -337,18 +334,20 @@ pub fn python_files_in_path( let resolver = resolver.read().unwrap(); let settings = resolver.resolve(path, pyproject_config); if let Some(file_name) = path.file_name() { - if !settings.file_resolver.exclude.is_empty() - && match_exclusion(path, file_name, &settings.file_resolver.exclude) - { + let file_path = Candidate::new(path); + let file_basename = Candidate::new(file_name); + if match_candidate_exclusion( + &file_path, + &file_basename, + &settings.file_resolver.exclude, + ) { debug!("Ignored path via `exclude`: {:?}", path); return WalkState::Skip; - } else if !settings.file_resolver.extend_exclude.is_empty() - && match_exclusion( - path, - file_name, - &settings.file_resolver.extend_exclude, - ) - { + } else if match_candidate_exclusion( + &file_path, + &file_basename, + &settings.file_resolver.extend_exclude, + ) { debug!("Ignored path via `extend-exclude`: {:?}", path); return WalkState::Skip; } @@ -391,30 +390,37 @@ pub fn python_files_in_path( } } - if result.as_ref().map_or(true, |entry| { - // Ignore directories - if entry.file_type().map_or(true, |ft| ft.is_dir()) { - false - } else if entry.depth() == 0 { - // Accept all files that are passed-in directly. - true - } else { - // Otherwise, check if the file is included. - let path = entry.path(); - let resolver = resolver.read().unwrap(); - let settings = resolver.resolve(path, pyproject_config); - if settings.file_resolver.include.is_match(path) { - debug!("Included path via `include`: {:?}", path); - true - } else if settings.file_resolver.extend_include.is_match(path) { - debug!("Included path via `extend-include`: {:?}", path); - true + match result { + Ok(entry) => { + // Ignore directories + let resolved = if entry.file_type().map_or(true, |ft| ft.is_dir()) { + None + } else if entry.depth() == 0 { + // Accept all files that are passed-in directly. + Some(ResolvedFile::Root(entry.into_path())) } else { - false + // Otherwise, check if the file is included. + let path = entry.path(); + let resolver = resolver.read().unwrap(); + let settings = resolver.resolve(path, pyproject_config); + if settings.file_resolver.include.is_match(path) { + debug!("Included path via `include`: {:?}", path); + Some(ResolvedFile::Nested(entry.into_path())) + } else if settings.file_resolver.extend_include.is_match(path) { + debug!("Included path via `extend-include`: {:?}", path); + Some(ResolvedFile::Nested(entry.into_path())) + } else { + None + } + }; + + if let Some(resolved) = resolved { + files.lock().unwrap().push(Ok(resolved)); } } - }) { - files.lock().unwrap().push(result); + Err(err) => { + files.lock().unwrap().push(Err(err)); + } } WalkState::Continue @@ -426,6 +432,51 @@ pub fn python_files_in_path( Ok((files.into_inner().unwrap(), resolver.into_inner().unwrap())) } +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum ResolvedFile { + /// File explicitly passed to the CLI + Root(PathBuf), + /// File in a sub-directory + Nested(PathBuf), +} + +impl ResolvedFile { + pub fn into_path(self) -> PathBuf { + match self { + ResolvedFile::Root(path) => path, + ResolvedFile::Nested(path) => path, + } + } + + pub fn path(&self) -> &Path { + match self { + ResolvedFile::Root(root) => root.as_path(), + ResolvedFile::Nested(root) => root.as_path(), + } + } + + pub fn file_name(&self) -> &OsStr { + let path = self.path(); + path.file_name().unwrap_or(path.as_os_str()) + } + + pub fn is_root(&self) -> bool { + matches!(self, ResolvedFile::Root(_)) + } +} + +impl PartialOrd for ResolvedFile { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for ResolvedFile { + fn cmp(&self, other: &Self) -> Ordering { + self.path().cmp(other.path()) + } +} + /// Return `true` if the Python file at [`Path`] is _not_ excluded. pub fn python_file_at_path( path: &Path, @@ -463,25 +514,27 @@ fn is_file_excluded( ) -> bool { // TODO(charlie): Respect gitignore. for path in path.ancestors() { - if path.file_name().is_none() { - break; - } let settings = resolver.resolve(path, pyproject_strategy); if let Some(file_name) = path.file_name() { - if !settings.file_resolver.exclude.is_empty() - && match_exclusion(path, file_name, &settings.file_resolver.exclude) - { + let file_path = Candidate::new(path); + let file_basename = Candidate::new(file_name); + if match_candidate_exclusion( + &file_path, + &file_basename, + &settings.file_resolver.exclude, + ) { debug!("Ignored path via `exclude`: {:?}", path); return true; - } else if !settings.file_resolver.extend_exclude.is_empty() - && match_exclusion(path, file_name, &settings.file_resolver.extend_exclude) - { + } else if match_candidate_exclusion( + &file_path, + &file_basename, + &settings.file_resolver.extend_exclude, + ) { debug!("Ignored path via `extend-exclude`: {:?}", path); return true; } } else { - debug!("Ignored path due to error in parsing: {:?}", path); - return true; + break; } if path == settings.file_resolver.project_root { // Bail out; we'd end up past the project root on the next iteration @@ -494,14 +547,30 @@ fn is_file_excluded( /// Return `true` if the given file should be ignored based on the exclusion /// criteria. -fn match_exclusion, R: AsRef>( +pub fn match_exclusion, R: AsRef>( file_path: P, file_basename: R, - exclusion: &globset::GlobSet, + exclusion: &GlobSet, ) -> bool { + if exclusion.is_empty() { + return false; + } exclusion.is_match(file_path) || exclusion.is_match(file_basename) } +/// Return `true` if the given candidates should be ignored based on the exclusion +/// criteria. +pub fn match_candidate_exclusion( + file_path: &Candidate, + file_basename: &Candidate, + exclusion: &GlobSet, +) -> bool { + if exclusion.is_empty() { + return false; + } + exclusion.is_match_candidate(file_path) || exclusion.is_match_candidate(file_basename) +} + #[cfg(test)] mod tests { use std::fs::{create_dir, File}; @@ -520,7 +589,7 @@ mod tests { use crate::resolver::{ is_file_excluded, match_exclusion, python_files_in_path, resolve_root_settings, ConfigurationTransformer, PyprojectConfig, PyprojectDiscoveryStrategy, Relativity, - Resolver, + ResolvedFile, Resolver, }; use crate::settings::Settings; use crate::tests::test_resource_path; @@ -589,12 +658,12 @@ mod tests { &NoOpTransformer, )?; let paths = paths - .iter() + .into_iter() .flatten() - .map(ignore::DirEntry::path) + .map(ResolvedFile::into_path) .sorted() .collect::>(); - assert_eq!(paths, &[file2, file1]); + assert_eq!(paths, [file2, file1]); Ok(()) } diff --git a/crates/ruff_workspace/src/settings.rs b/crates/ruff_workspace/src/settings.rs index 0e069a58c01dd..982732e487317 100644 --- a/crates/ruff_workspace/src/settings.rs +++ b/crates/ruff_workspace/src/settings.rs @@ -1,7 +1,7 @@ use path_absolutize::path_dedot; use ruff_cache::cache_dir; -use ruff_formatter::{FormatOptions, IndentStyle, LineWidth}; -use ruff_linter::settings::types::{FilePattern, FilePatternSet, SerializationFormat}; +use ruff_formatter::{FormatOptions, IndentStyle, IndentWidth, LineWidth}; +use ruff_linter::settings::types::{FilePattern, FilePatternSet, SerializationFormat, UnsafeFixes}; use ruff_linter::settings::LinterSettings; use ruff_macros::CacheKey; use ruff_python_ast::PySourceType; @@ -19,6 +19,8 @@ pub struct Settings { #[cache_key(ignore)] pub fix_only: bool, #[cache_key(ignore)] + pub unsafe_fixes: UnsafeFixes, + #[cache_key(ignore)] pub output_format: SerializationFormat, #[cache_key(ignore)] pub show_fixes: bool, @@ -40,6 +42,7 @@ impl Default for Settings { output_format: SerializationFormat::default(), show_fixes: false, show_source: false, + unsafe_fixes: UnsafeFixes::default(), linter: LinterSettings::new(project_root), file_resolver: FileResolverSettings::new(project_root), formatter: FormatterSettings::default(), @@ -108,11 +111,13 @@ impl FileResolverSettings { #[derive(CacheKey, Clone, Debug)] pub struct FormatterSettings { + pub exclude: FilePatternSet, pub preview: PreviewMode, pub line_width: LineWidth, pub indent_style: IndentStyle, + pub indent_width: IndentWidth, pub quote_style: QuoteStyle, @@ -146,6 +151,7 @@ impl FormatterSettings { PyFormatOptions::from_source_type(source_type) .with_indent_style(self.indent_style) + .with_indent_width(self.indent_width) .with_quote_style(self.quote_style) .with_magic_trailing_comma(self.magic_trailing_comma) .with_preview(self.preview) @@ -159,10 +165,12 @@ impl Default for FormatterSettings { let default_options = PyFormatOptions::default(); Self { - preview: ruff_python_formatter::PreviewMode::Disabled, + exclude: FilePatternSet::default(), + preview: PreviewMode::Disabled, line_width: default_options.line_width(), - line_ending: LineEnding::Lf, + line_ending: LineEnding::Auto, indent_style: default_options.indent_style(), + indent_width: default_options.indent_width(), quote_style: default_options.quote_style(), magic_trailing_comma: default_options.magic_trailing_comma(), } @@ -175,18 +183,18 @@ impl Default for FormatterSettings { #[serde(rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub enum LineEnding { - /// Line endings will be converted to `\n` as is common on Unix. + /// The newline style is detected automatically on a file per file basis. + /// Files with mixed line endings will be converted to the first detected line ending. + /// Defaults to [`LineEnding::Lf`] for a files that contain no line endings. #[default] + Auto, + + /// Line endings will be converted to `\n` as is common on Unix. Lf, /// Line endings will be converted to `\r\n` as is common on Windows. CrLf, - /// The newline style is detected automatically on a file per file basis. - /// Files with mixed line endings will be converted to the first detected line ending. - /// Defaults to [`LineEnding::Lf`] for a files that contain no line endings. - Auto, - /// Line endings will be converted to `\n` on Unix and `\r\n` on Windows. Native, } diff --git a/docs/configuration.md b/docs/configuration.md index 8cce70bcc6c11..ee991f0100a1a 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -2,8 +2,10 @@ Ruff can be configured through a `pyproject.toml`, `ruff.toml`, or `.ruff.toml` file. -For a complete enumeration of the available configuration options, see -[_Settings_](settings.md). +Whether you're using Ruff as a linter, formatter, or both, the underlying configuration strategy and +semantics are the same. + +For a complete enumeration of the available configuration options, see [_Settings_](settings.md). ## Using `pyproject.toml` @@ -11,16 +13,6 @@ If left unspecified, Ruff's default configuration is equivalent to: ```toml [tool.ruff] -# Enable the pycodestyle (`E`) and Pyflakes (`F`) rules by default. -# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or -# McCabe complexity (`C901`) by default. -select = ["E", "F"] -ignore = [] - -# Allow autofix for all enabled rules (when `--fix`) is provided. -fixable = ["ALL"] -unfixable = [] - # Exclude a variety of commonly ignored directories. exclude = [ ".bzr", @@ -45,24 +37,48 @@ exclude = [ "node_modules", "venv", ] -per-file-ignores = {} # Same as Black. line-length = 88 +indent-width = 4 + +# Assume Python 3.8 +target-version = "py38" + +[tool.ruff.lint] +# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. +# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or +# McCabe complexity (`C901`) by default. +select = ["E4", "E7", "E9", "F"] +ignore = [] + +# Allow fix for all enabled rules (when `--fix`) is provided. +fixable = ["ALL"] +unfixable = [] # Allow unused variables when underscore-prefixed. dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" -# Assume Python 3.8 -target-version = "py38" +[tool.ruff.format] +# Like Black, use double quotes for strings. +quote-style = "double" + +# Like Black, indent with spaces, rather than tabs. +indent-style = "space" + +# Like Black, respect magic trailing commas. +skip-magic-trailing-comma = false + +# Like Black, automatically detect the appropriate line ending. +line-ending = "auto" ``` As an example, the following would configure Ruff to: ```toml -[tool.ruff] +[tool.ruff.lint] # 1. Enable flake8-bugbear (`B`) rules, in addition to the defaults. -select = ["E", "F", "B"] +select = ["E4", "E7", "E9", "F", "B"] # 2. Avoid enforcing line-length violations (`E501`) ignore = ["E501"] @@ -70,47 +86,28 @@ ignore = ["E501"] # 3. Avoid trying to fix flake8-bugbear (`B`) violations. unfixable = ["B"] -# 4. Ignore `E402` (import violations) in all `__init__.py` files, and in `path/to/file.py`. -[tool.ruff.per-file-ignores] +# 4. Ignore `E402` (import violations) in all `__init__.py` files, and in select subdirectories. +[tool.ruff.lint.per-file-ignores] "__init__.py" = ["E402"] -"path/to/file.py" = ["E402"] "**/{tests,docs,tools}/*" = ["E402"] + +[tool.ruff.format] +# 5. Use single quotes for non-triple-quoted strings. +quote-style = "single" ``` -Plugin configurations should be expressed as subsections, e.g.: +Linter plugin configurations are expressed as subsections, e.g.: ```toml -[tool.ruff] +[tool.ruff.lint] # Add "Q" to the list of enabled codes. -select = ["E", "F", "Q"] +select = ["E4", "E7", "E9", "F", "Q"] -[tool.ruff.flake8-quotes] +[tool.ruff.lint.flake8-quotes] docstring-quotes = "double" ``` -For a complete enumeration of the available configuration options, see -[_Settings_](settings.md). - -Ruff mirrors Flake8's rule code system, in which each rule code consists of a one-to-three letter -prefix, followed by three digits (e.g., `F401`). The prefix indicates that "source" of the rule -(e.g., `F` for Pyflakes, `E` for pycodestyle, `ANN` for flake8-annotations). The set of enabled -rules is determined by the `select` and `ignore` options, which accept either the full code (e.g., -`F401`) or the prefix (e.g., `F`). - -As a special-case, Ruff also supports the `ALL` code, which enables all rules. Note that some -pydocstyle rules conflict (e.g., `D203` and `D211`) as they represent alternative docstring -formats. Ruff will automatically disable any conflicting rules when `ALL` is enabled. - -If you're wondering how to configure Ruff, here are some **recommended guidelines**: - -- Prefer `select` and `ignore` over `extend-select` and `extend-ignore`, to make your rule set - explicit. -- Use `ALL` with discretion. Enabling `ALL` will implicitly enable new rules whenever you upgrade. -- Start with a small set of rules (`select = ["E", "F"]`) and add a category at-a-time. For example, - you might consider expanding to `select = ["E", "F", "B"]` to enable the popular flake8-bugbear - extension. -- By default, Ruff's autofix is aggressive. If you find that it's too aggressive for your liking, - consider turning off autofix for specific rules or categories (see [_FAQ_](faq.md#ruff-tried-to-fix-something--but-it-broke-my-code)). +For a complete enumeration of the available configuration options, see [_Settings_](settings.md). ## Using `ruff.toml` @@ -122,8 +119,9 @@ For example, the `pyproject.toml` described above would be represented via the f `ruff.toml` (or `.ruff.toml`): ```toml +[lint] # Enable flake8-bugbear (`B`) rules. -select = ["E", "F", "B"] +select = ["E4", "E7", "E9", "F", "B"] # Never enforce `E501` (line length violations). ignore = ["E501"] @@ -131,14 +129,104 @@ ignore = ["E501"] # Avoid trying to fix flake8-bugbear (`B`) violations. unfixable = ["B"] -# Ignore `E402` (import violations) in all `__init__.py` files, and in `path/to/file.py`. -[per-file-ignores] +# Ignore `E402` (import violations) in all `__init__.py` files, and in select subdirectories. +[lint.per-file-ignores] "__init__.py" = ["E402"] -"path/to/file.py" = ["E402"] +"**/{tests,docs,tools}/*" = ["E402"] + +[format] +# Use single quotes for non-triple-quoted strings. +quote-style = "single" ``` For a complete enumeration of the available configuration options, see [_Settings_](settings.md). +## `pyproject.toml` discovery + +Similar to [ESLint](https://eslint.org/docs/latest/user-guide/configuring/configuration-files#cascading-and-hierarchy), +Ruff supports hierarchical configuration, such that the "closest" `pyproject.toml` file in the +directory hierarchy is used for every individual file, with all paths in the `pyproject.toml` file +(e.g., `exclude` globs, `src` paths) being resolved relative to the directory containing that +`pyproject.toml` file. + +There are a few exceptions to these rules: + +1. In locating the "closest" `pyproject.toml` file for a given path, Ruff ignores any + `pyproject.toml` files that lack a `[tool.ruff]` section. +1. If a configuration file is passed directly via `--config`, those settings are used for _all_ + analyzed files, and any relative paths in that configuration file (like `exclude` globs or + `src` paths) are resolved relative to the _current_ working directory. +1. If no `pyproject.toml` file is found in the filesystem hierarchy, Ruff will fall back to using + a default configuration. If a user-specific configuration file exists + at `${config_dir}/ruff/pyproject.toml`, that file will be used instead of the default + configuration, with `${config_dir}` being determined via the [`dirs`](https://docs.rs/dirs/4.0.0/dirs/fn.config_dir.html) + crate, and all relative paths being again resolved relative to the _current working directory_. +1. Any `pyproject.toml`-supported settings that are provided on the command-line (e.g., via + `--select`) will override the settings in _every_ resolved configuration file. + +Unlike [ESLint](https://eslint.org/docs/latest/user-guide/configuring/configuration-files#cascading-and-hierarchy), +Ruff does not merge settings across configuration files; instead, the "closest" configuration file +is used, and any parent configuration files are ignored. In lieu of this implicit cascade, Ruff +supports an [`extend`](settings.md#extend) field, which allows you to inherit the settings from another +`pyproject.toml` file, like so: + +```toml +[tool.ruff] +# Extend the `pyproject.toml` file in the parent directory... +extend = "../pyproject.toml" + +# ...but use a different line length. +line-length = 100 +``` + +All of the above rules apply equivalently to `ruff.toml` and `.ruff.toml` files. If Ruff detects +multiple configuration files in the same directory, the `.ruff.toml` file will take precedence over +the `ruff.toml` file, and the `ruff.toml` file will take precedence over the `pyproject.toml` file. + +## Python file discovery + +When passed a path on the command-line, Ruff will automatically discover all Python files in that +path, taking into account the [`exclude`](settings.md#exclude) and [`extend-exclude`](settings.md#extend-exclude) +settings in each directory's `pyproject.toml` file. + +Files can also be selectively excluded from linting or formatting by scoping the `exclude` and +`extend-exclude` settings to the tool-specific configuration tables. For example, the following +would prevent `ruff` from formatting `.pyi` files, but would continue to include them in linting: + +```toml +[tool.ruff.format] +extend-exclude = ["*.pyi"] +``` + +By default, Ruff will also skip any files that are omitted via `.ignore`, `.gitignore`, +`.git/info/exclude`, and global `gitignore` files (see: [`respect-gitignore`](settings.md#respect-gitignore)). + +Files that are passed to `ruff` directly are always analyzed, regardless of the above criteria. +For example, `ruff check /path/to/excluded/file.py` will always lint `file.py`. + +## Jupyter Notebook discovery + +Ruff has built-in support for [Jupyter Notebooks](https://jupyter.org/). + +To opt in to linting and formatting Jupyter Notebook (`.ipynb`) files, add the `*.ipynb` pattern to +your [`extend-include`](settings.md#extend-include) setting, like so: + +```toml +[tool.ruff] +extend-include = ["*.ipynb"] +``` + +This will prompt Ruff to discover Jupyter Notebook (`.ipynb`) files in any specified +directories, then lint and format them accordingly. + +Alternatively, pass the notebook file(s) to `ruff` on the command-line directly. For example, +`ruff check /path/to/notebook.ipynb` will always lint `notebook.ipynb`. Similarly, +`ruff format /path/to/notebook.ipynb` will always format `notebook.ipynb`. + +All of the above rules apply equivalently to `ruff.toml` and `.ruff.toml` files. If Ruff detects +multiple configuration files in the same directory, the `.ruff.toml` file will take precedence over +the `ruff.toml` file, and the `ruff.toml` file will take precedence over the `pyproject.toml` file. + ## Command-line interface Some configuration options can be provided via the command-line, such as those related to rule @@ -158,12 +246,14 @@ Ruff: An extremely fast Python linter. Usage: ruff [OPTIONS] Commands: - check Run Ruff on the given files or directories (default) - rule Explain a rule (or all rules) - config List or describe the available configuration options - linter List all supported upstream linters - clean Clear any caches in the current directory and any subdirectories - help Print this message or the help of the given subcommand(s) + check Run Ruff on the given files or directories (default) + rule Explain a rule (or all rules) + config List or describe the available configuration options + linter List all supported upstream linters + clean Clear any caches in the current directory and any subdirectories + format Run the Ruff formatter on the given files or directories + version Display Ruff's version + help Print this message or the help of the given subcommand(s) Options: -h, --help Print help @@ -181,7 +271,7 @@ For help with a specific command, see: `ruff help `. Or `ruff help check` for more on the linting command: - + ```text Run Ruff on the given files or directories (default) @@ -193,17 +283,19 @@ Arguments: Options: --fix - Attempt to automatically fix lint violations. Use `--no-fix` to disable + Apply fixes to resolve lint violations. Use `--no-fix` to disable or `--unsafe-fixes` to include unsafe fixes + --unsafe-fixes + Include fixes that may not retain the original intent of the code. Use `--no-unsafe-fixes` to disable --show-source Show violations with source code. Use `--no-show-source` to disable --show-fixes - Show an enumeration of all autofixed lint violations. Use `--no-show-fixes` to disable + Show an enumeration of all fixed lint violations. Use `--no-show-fixes` to disable --diff Avoid writing any fixed files back; instead, output a diff for each changed file to stdout. Implies `--fix-only` -w, --watch Run in watch mode by re-running whenever files change --fix-only - Fix any fixable lint violations, but don't report on leftover violations. Implies `--fix`. Use `--no-fix-only` to disable + Apply fixes to resolve lint violations, but don't report on leftover violations. Implies `--fix`. Use `--no-fix-only` to disable or `--unsafe-fixes` to include unsafe fixes --ignore-noqa Ignore any `# noqa` comments --output-format @@ -239,9 +331,9 @@ Rule selection: --extend-per-file-ignores Like `--per-file-ignores`, but adds additional ignores on top of those already specified --fixable - List of rule codes to treat as eligible for autofix. Only applicable when autofix itself is enabled (e.g., via `--fix`) + List of rule codes to treat as eligible for fix. Only applicable when fix itself is enabled (e.g., via `--fix`) --unfixable - List of rule codes to treat as ineligible for autofix. Only applicable when autofix itself is enabled (e.g., via `--fix`) + List of rule codes to treat as ineligible for fix. Only applicable when fix itself is enabled (e.g., via `--fix`) --extend-fixable Like --fixable, but adds additional rule codes on top of those already specified @@ -263,7 +355,7 @@ Miscellaneous: -e, --exit-zero Exit with status code "0", even upon detecting lint violations --exit-non-zero-on-fix - Exit with a non-zero status code if any files were modified via autofix, even if no lint violations remain + Exit with a non-zero status code if any files were modified via fix, even if no lint violations remain Log levels: -v, --verbose Enable verbose logging @@ -271,210 +363,52 @@ Log levels: -s, --silent Disable all logging (but still exit with status code "1" upon detecting diagnostics) ``` - - -## `pyproject.toml` discovery - -Similar to [ESLint](https://eslint.org/docs/latest/user-guide/configuring/configuration-files#cascading-and-hierarchy), -Ruff supports hierarchical configuration, such that the "closest" `pyproject.toml` file in the -directory hierarchy is used for every individual file, with all paths in the `pyproject.toml` file -(e.g., `exclude` globs, `src` paths) being resolved relative to the directory containing that -`pyproject.toml` file. - -There are a few exceptions to these rules: - -1. In locating the "closest" `pyproject.toml` file for a given path, Ruff ignores any - `pyproject.toml` files that lack a `[tool.ruff]` section. -1. If a configuration file is passed directly via `--config`, those settings are used for across - files. Any relative paths in that configuration file (like `exclude` globs or `src` paths) are - resolved relative to the _current working directory_. -1. If no `pyproject.toml` file is found in the filesystem hierarchy, Ruff will fall back to using - a default configuration. If a user-specific configuration file exists - at `${config_dir}/ruff/pyproject.toml`, that file will be used instead of the default - configuration, with `${config_dir}` being determined via the [`dirs`](https://docs.rs/dirs/4.0.0/dirs/fn.config_dir.html) - crate, and all relative paths being again resolved relative to the _current working directory_. -1. Any `pyproject.toml`-supported settings that are provided on the command-line (e.g., via - `--select`) will override the settings in _every_ resolved configuration file. - -Unlike [ESLint](https://eslint.org/docs/latest/user-guide/configuring/configuration-files#cascading-and-hierarchy), -Ruff does not merge settings across configuration files; instead, the "closest" configuration file -is used, and any parent configuration files are ignored. In lieu of this implicit cascade, Ruff -supports an [`extend`](settings.md#extend) field, which allows you to inherit the settings from another -`pyproject.toml` file, like so: - -```toml -# Extend the `pyproject.toml` file in the parent directory. -extend = "../pyproject.toml" -# But use a different line length. -line-length = 100 -``` - -All of the above rules apply equivalently to `ruff.toml` and `.ruff.toml` files. If Ruff detects -multiple configuration files in the same directory, the `.ruff.toml` file will take precedence over -the `ruff.toml` file, and the `ruff.toml` file will take precedence over the `pyproject.toml` file. - -## Python file discovery - -When passed a path on the command-line, Ruff will automatically discover all Python files in that -path, taking into account the [`exclude`](settings.md#exclude) and -[`extend-exclude`](settings.md#extend-exclude) settings in each directory's -`pyproject.toml` file. - -By default, Ruff will also skip any files that are omitted via `.ignore`, `.gitignore`, -`.git/info/exclude`, and global `gitignore` files (see: [`respect-gitignore`](settings.md#respect-gitignore)). - -Files that are passed to `ruff` directly are always linted, regardless of the above criteria. -For example, `ruff check /path/to/excluded/file.py` will always lint `file.py`. - -## Jupyter Notebook discovery - -Ruff has built-in support for linting [Jupyter Notebooks](https://jupyter.org/). - -To opt in to linting Jupyter Notebook (`.ipynb`) files, add the `*.ipynb` pattern to your -[`include`](settings.md#include) setting, like so: - -```toml -[tool.ruff] -include = ["*.py", "*.pyi", "**/pyproject.toml", "*.ipynb"] -``` - -This will prompt Ruff to discover Jupyter Notebook (`.ipynb`) files in any specified -directories, and lint them accordingly. - -Alternatively, pass the notebook file(s) to `ruff` on the command-line directly. For example, -`ruff check /path/to/notebook.ipynb` will always lint `notebook.ipynb`. - -## Rule selection - -The set of enabled rules is controlled via the [`select`](settings.md#select) and -[`ignore`](settings.md#ignore) settings, along with the -[`extend-select`](settings.md#extend-select) and -[`extend-ignore`](settings.md#extend-ignore) modifiers. - -To resolve the enabled rule set, Ruff may need to reconcile `select` and `ignore` from a variety -of sources, including the current `pyproject.toml`, any inherited `pyproject.toml` files, and the -CLI (e.g., `--select`). - -In those scenarios, Ruff uses the "highest-priority" `select` as the basis for the rule set, and -then applies any `extend-select`, `ignore`, and `extend-ignore` adjustments. CLI options are given -higher priority than `pyproject.toml` options, and the current `pyproject.toml` file is given higher -priority than any inherited `pyproject.toml` files. - -For example, given the following `pyproject.toml` file: - -```toml -[tool.ruff] -select = ["E", "F"] -ignore = ["F401"] -``` - -Running `ruff check --select F401` would result in Ruff enforcing `F401`, and no other rules. - -Running `ruff check --extend-select B` would result in Ruff enforcing the `E`, `F`, and `B` rules, -with the exception of `F401`. - -## Error suppression + -To omit a lint rule entirely, add it to the "ignore" list via [`ignore`](settings.md#ignore) -or [`extend-ignore`](settings.md#extend-ignore), either on the command-line -or in your `pyproject.toml` file. +Or `ruff help format` for more on the formatting command: -To ignore a violation inline, Ruff uses a `noqa` system similar to -[Flake8](https://flake8.pycqa.org/en/3.1.1/user/ignoring-errors.html). To ignore an individual -violation, add `# noqa: {code}` to the end of the line, like so: + -```python -# Ignore F841. -x = 1 # noqa: F841 - -# Ignore E741 and F841. -i = 1 # noqa: E741, F841 - -# Ignore _all_ violations. -x = 1 # noqa -``` - -For multi-line strings (like docstrings), -the `noqa` directive should come at the end of the string (after the closing triple quote), -and will apply to the entire string, like so: +```text +Run the Ruff formatter on the given files or directories -```python -"""Lorem ipsum dolor sit amet. +Usage: ruff format [OPTIONS] [FILES]... -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor. -""" # noqa: E501 -``` +Arguments: + [FILES]... List of files or directories to format -To ignore all violations across an entire file, add `# ruff: noqa` to any line in the file, like so: +Options: + --check + Avoid writing any formatted files back; instead, exit with a non-zero status code if any files would have been modified, and zero otherwise + --diff + Avoid writing any formatted files back; instead, exit with a non-zero status code and the difference between the current file and how the formatted file would look like + --config + Path to the `pyproject.toml` or `ruff.toml` file to use for configuration + --target-version + The minimum Python version that should be supported [possible values: py37, py38, py39, py310, py311, py312] + --preview + Enable preview mode; enables unstable formatting. Use `--no-preview` to disable + -h, --help + Print help -```python -# ruff: noqa -``` +Miscellaneous: + -n, --no-cache Disable cache reads + --cache-dir Path to the cache directory [env: RUFF_CACHE_DIR=] + --isolated Ignore all configuration files + --stdin-filename The name of the file when passing it through stdin -To ignore a specific rule across an entire file, add `# ruff: noqa: {code}` to any line in the file, -like so: +File selection: + --respect-gitignore Respect file exclusions via `.gitignore` and other standard ignore files. Use `--no-respect-gitignore` to disable + --exclude List of paths, used to omit files and/or directories from analysis + --force-exclude Enforce exclusions, even for paths passed to Ruff directly on the command-line. Use `--no-force-exclude` to disable -```python -# ruff: noqa: F841 +Log levels: + -v, --verbose Enable verbose logging + -q, --quiet Print diagnostics, but nothing else + -s, --silent Disable all logging (but still exit with status code "1" upon detecting diagnostics) ``` -Or see the [`per-file-ignores`](settings.md#per-file-ignores) configuration -setting, which enables the same functionality via a `pyproject.toml` file. - -Note that Ruff will also respect Flake8's `# flake8: noqa` directive, and will treat it as -equivalent to `# ruff: noqa`. - -### Automatic `noqa` management - -Ruff supports several workflows to aid in `noqa` management. - -First, Ruff provides a special rule code, `RUF100`, to enforce that your `noqa` directives are -"valid", in that the violations they _say_ they ignore are actually being triggered on that line -(and thus suppressed). You can run `ruff check /path/to/file.py --extend-select RUF100` to flag -unused `noqa` directives. - -Second, Ruff can _automatically remove_ unused `noqa` directives via its autofix functionality. -You can run `ruff check /path/to/file.py --extend-select RUF100 --fix` to automatically remove -unused `noqa` directives. - -Third, Ruff can _automatically add_ `noqa` directives to all failing lines. This is useful when -migrating a new codebase to Ruff. You can run `ruff check /path/to/file.py --add-noqa` to -automatically add `noqa` directives to all failing lines, with the appropriate rule codes. - -### Action comments - -Ruff respects isort's [action comments](https://pycqa.github.io/isort/docs/configuration/action_comments.html) -(`# isort: skip_file`, `# isort: on`, `# isort: off`, `# isort: skip`, and `# isort: split`), which -enable selectively enabling and disabling import sorting for blocks of code and other inline -configuration. - -Ruff will also respect variants of these action comments with a `# ruff:` prefix -(e.g., `# ruff: isort: skip_file`, `# ruff: isort: on`, and so on). These variants more clearly -convey that the action comment is intended for Ruff, but are functionally equivalent to the -isort variants. - -See the [isort documentation](https://pycqa.github.io/isort/docs/configuration/action_comments.html) -for more. - -## Exit codes - -By default, Ruff exits with the following status codes: - -- `0` if no violations were found, or if all present violations were fixed automatically. -- `1` if violations were found. -- `2` if Ruff terminates abnormally due to invalid configuration, invalid CLI options, or an - internal error. - -This convention mirrors that of tools like ESLint, Prettier, and RuboCop. - -Ruff supports two command-line flags that alter its exit code behavior: - -- `--exit-zero` will cause Ruff to exit with a status code of `0` even if violations were found. - Note that Ruff will still exit with a status code of `2` if it terminates abnormally. -- `--exit-non-zero-on-fix` will cause Ruff to exit with a status code of `1` if violations were - found, _even if_ all such violations were fixed automatically. Note that the use of - `--exit-non-zero-on-fix` can result in a non-zero exit code even if no violations remain after - autofixing. + ## Shell autocompletion diff --git a/docs/faq.md b/docs/faq.md index fa82b1abeb885..0eb4a5aa1d20b 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -1,12 +1,12 @@ # FAQ -## Is Ruff compatible with Black? +## Is the Ruff linter compatible with Black? -Yes. Ruff is compatible with [Black](https://github.com/psf/black) out-of-the-box, as long as -the `line-length` setting is consistent between the two. +Yes. The Ruff linter is compatible with [Black](https://github.com/psf/black) out-of-the-box, as +long as the `line-length` setting is consistent between the two. -As a project, Ruff is designed to be used alongside Black and, as such, will defer implementing -stylistic lint rules that are obviated by autoformatting. +Ruff is designed to be used alongside a formatter (like Ruff's own formatter, or Black) and, as +such, will defer implementing stylistic rules that are obviated by automated formatting. Note that Ruff and Black treat line-length enforcement a little differently. Black makes a best-effort attempt to adhere to the `line-length`, but avoids automatic line-wrapping in some cases @@ -14,10 +14,21 @@ best-effort attempt to adhere to the `line-length`, but avoids automatic line-wr the `line-length` setting. As such, if `E501` is enabled, Ruff can still trigger line-length violations even when Black is enabled. -## How does Ruff compare to Flake8? +## How does Ruff's formatter compare to Black? -(Coming from Flake8? Try [`flake8-to-ruff`](https://pypi.org/project/flake8-to-ruff/) to -automatically convert your existing configuration.) +The Ruff formatter is designed to be a drop-in replacement for [Black](https://github.com/psf/black). + +Specifically, the formatter is intended to emit near-identical output when run over Black-formatted +code. When run over extensive Black-formatted projects like Django and Zulip, > 99.9% of lines +are formatted identically. When migrating an existing project from Black to Ruff, you should expect +to see a few differences on the margins, but the vast majority of your code should be unchanged. + +When run over _non_-Black-formatted code, the formatter makes some different decisions than Black, +and so more deviations should be expected, especially around the treatment of end-of-line comments. + +See [_Black compatibility_](formatter.md#black-compatibility) for more. + +## How does Ruff's linter compare to Flake8? Ruff can be used as a drop-in replacement for Flake8 when used (1) without or with a small number of plugins, (2) alongside Black, and (3) on Python 3 code. @@ -98,10 +109,10 @@ There are a few other minor incompatibilities between Ruff and the originating F code. (This is often solved by modifying the `src` property, e.g., to `src = ["src"]`, if your code is nested in a `src` directory.) -## How does Ruff compare to Pylint? +## How does Ruff's linter compare to Pylint? -At time of writing, Pylint implements ~409 total rules, while Ruff implements 440, of which at least -89 overlap with the Pylint rule set (you can find the mapping in [#970](https://github.com/astral-sh/ruff/issues/970)). +At time of writing, Pylint implements ~409 total rules, while Ruff implements over 700, of which at +least 172 overlap with the Pylint rule set (see: [#970](https://github.com/astral-sh/ruff/issues/970)). Pylint implements many rules that Ruff does not, and vice versa. For example, Pylint does more type inference than Ruff (e.g., Pylint can validate the number of arguments in a function call). As such, @@ -182,16 +193,21 @@ Today, Ruff can be used to replace Flake8 when used with any of the following pl - [pydocstyle](https://pypi.org/project/pydocstyle/) - [tryceratops](https://pypi.org/project/tryceratops/) -Ruff can also replace [isort](https://pypi.org/project/isort/), +Ruff can also replace [Black](https://pypi.org/project/black/), [isort](https://pypi.org/project/isort/), [yesqa](https://github.com/asottile/yesqa), [eradicate](https://pypi.org/project/eradicate/), and most of the rules implemented in [pyupgrade](https://pypi.org/project/pyupgrade/). If you're looking to use Ruff, but rely on an unsupported Flake8 plugin, feel free to file an [issue](https://github.com/astral-sh/ruff/issues/new). +## Do I have to use Ruff's linter and formatter together? + +Nope! Ruff's linter and formatter can be used independently of one another -- you can use +Ruff as a formatter, but not a linter, or vice versa. + ## What versions of Python does Ruff support? -Ruff can lint code for any Python version from 3.7 onwards, including Python 3.10 and 3.11. +Ruff can lint code for any Python version from 3.7 onwards, including Python 3.12. Ruff does not support Python 2. Ruff _may_ run on pre-Python 3.7 code, although such versions are not officially supported (e.g., Ruff does _not_ respect type comments). @@ -209,7 +225,7 @@ pip install ruff Ruff ships with wheels for all major platforms, which enables `pip` to install Ruff without relying on Rust at all. -## Can I write my own plugins for Ruff? +## Can I write my own linter plugins for Ruff? Ruff does not yet support third-party plugins, though a plugin system is within-scope for the project. See [#283](https://github.com/astral-sh/ruff/issues/283) for more. @@ -326,18 +342,19 @@ For a detailed explanation, see the [contributing guide](contributing.md). Ruff has built-in support for linting [Jupyter Notebooks](https://jupyter.org/). To opt in to linting Jupyter Notebook (`.ipynb`) files, add the `*.ipynb` pattern to your -[`include`](settings.md#include) setting, like so: +[`extend-include`](settings.md#extend-include) setting, like so: ```toml [tool.ruff] -include = ["*.py", "*.pyi", "**/pyproject.toml", "*.ipynb"] +extend-include = ["*.ipynb"] ``` This will prompt Ruff to discover Jupyter Notebook (`.ipynb`) files in any specified -directories, and lint them accordingly. +directories, then lint and format them accordingly. Alternatively, pass the notebook file(s) to `ruff` on the command-line directly. For example, -`ruff check /path/to/notebook.ipynb` will always lint `notebook.ipynb`. +`ruff check /path/to/notebook.ipynb` will always lint `notebook.ipynb`. Similarly, +`ruff format /path/to/notebook.ipynb` will always format `notebook.ipynb`. Ruff also integrates with [nbQA](https://github.com/nbQA-dev/nbQA), a tool for running linters and code formatters over Jupyter Notebooks. @@ -384,7 +401,7 @@ matter how they're provided, which avoids accidental incompatibilities and simpl By default, no `convention` is set, and so the enabled rules are determined by the `select` setting alone. -## What is preview? +## What is "preview"? Preview enables a collection of newer rules and fixes that are considered experimental or unstable. See the [preview documentation](preview.md) for more details; or, to see which rules are currently @@ -394,7 +411,7 @@ in preview, visit the [rules reference](rules.md). Run `ruff check /path/to/code.py --show-settings` to view the resolved settings for a given file. -## I want to use Ruff, but I don't want to use `pyproject.toml`. Is that possible? +## I want to use Ruff, but I don't want to use `pyproject.toml`. What are my options? Yes! In lieu of a `pyproject.toml` file, you can use a `ruff.toml` file for configuration. The two files are functionally equivalent and have an identical schema, with the exception that a `ruff.toml` @@ -434,24 +451,15 @@ On Windows, Ruff expects that file to be located at `C:\Users\Alice\AppData\Roam For more, see the [`dirs`](https://docs.rs/dirs/4.0.0/dirs/fn.config_dir.html) crate. -## Ruff tried to fix something — but it broke my code? +## Ruff tried to fix something — but it broke my code. What's going on? -Ruff's autofix is a best-effort mechanism. Given the dynamic nature of Python, it's difficult to -have _complete_ certainty when making changes to code, even for the seemingly trivial fixes. - -In the future, Ruff will support enabling autofix behavior based on the safety of the patch. - -In the meantime, if you find that the autofix is too aggressive, you can disable it on a per-rule or -per-category basis using the [`unfixable`](settings.md#unfixable) mechanic. -For example, to disable autofix for some possibly-unsafe rules, you could add the following to your -`pyproject.toml`: - -```toml -[tool.ruff] -unfixable = ["B", "SIM", "TRY", "RUF"] -``` +Ruff labels fixes as "safe" and "unsafe". By default, Ruff will fix all violations for which safe +fixes are available, while unsafe fixes can be enabled via the [`unsafe-fixes`](settings.md#unsafe-fixes) +setting, or passing the `--unsafe-fixes` flag to `ruff check`. For more, see [the fix documentation](configuration.md#fixes). -If you find a case where Ruff's autofix breaks your code, please file an Issue! +Even still, given the dynamic nature of Python, it's difficult to have _complete_ certainty when +making changes to code, even for seemingly trivial fixes. If a "safe" fix breaks your code, please +[file an Issue](https://github.com/astral-sh/ruff/issues/new). ## How can I disable Ruff's color output? diff --git a/docs/formatter.md b/docs/formatter.md new file mode 100644 index 0000000000000..c6b84524eef2a --- /dev/null +++ b/docs/formatter.md @@ -0,0 +1,274 @@ +# The Ruff Formatter + +The Ruff formatter is an extremely fast Python code formatter designed as a drop-in replacement for +[Black](https://pypi.org/project/black/), available as part of the `ruff` CLI (as of Ruff v0.0.289). + +## `ruff format` + +`ruff format` is the primary entrypoint to the formatter. It accepts a list of files or +directories, and formats all discovered Python files: + +```shell +ruff format . # Format all files in the current directory. +ruff format /path/to/file.py # Format a single file. +``` + +Similar to Black, running `ruff format /path/to/file.py` will format the given file or directory +in-place, while `ruff format --check /path/to/file.py` will avoid writing any formatted files back, +and instead exit with a non-zero status code upon detecting any unformatted files. + +For the full list of supported options, run `ruff format --help`. + +## Philosophy + +The initial goal of the Ruff formatter is _not_ to innovate on code style, but rather, to innovate +on performance, and provide a unified toolchain across Ruff's linter, formatter, and any and all +future tools. + +As such, the formatter is designed as a drop-in replacement for [Black](https://github.com/psf/black), +but with an excessive focus on performance and direct integration with Ruff. Given Black's +popularity within the Python ecosystem, targeting Black compatibility ensures that formatter +adoption is minimally disruptive for the vast majority of projects. + +Specifically, the formatter is intended to emit near-identical output when run over existing +Black-formatted code. When run over extensive Black-formatted projects like Django and Zulip, > 99.9% +of lines are formatted identically. (See: [_Black compatibility_](#black-compatibility).) + +Given this focus on Black compatibility, the formatter thus adheres to [Black's (stable) code style](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html), +which aims for "consistency, generality, readability and reducing git diffs". To give you a sense +for the enforced code style, here's an example: + +```python +# Input +def _make_ssl_transport( + rawsock, protocol, sslcontext, waiter=None, + *, server_side=False, server_hostname=None, + extra=None, server=None, + ssl_handshake_timeout=None, + call_connection_made=True): + '''Make an SSL transport.''' + if waiter is None: + waiter = Future(loop=loop) + + if extra is None: + extra = {} + + ... + +# Ruff +def _make_ssl_transport( + rawsock, + protocol, + sslcontext, + waiter=None, + *, + server_side=False, + server_hostname=None, + extra=None, + server=None, + ssl_handshake_timeout=None, + call_connection_made=True, +): + """Make an SSL transport.""" + if waiter is None: + waiter = Future(loop=loop) + + if extra is None: + extra = {} + + ... +``` + +Like Black, the Ruff formatter does _not_ support extensive code style configuration; however, +unlike Black, it _does_ support configuring the desired quote style, indent style, line endings, +and more. (See: [_Configuration_](#configuration).) + +While the formatter is designed to be a drop-in replacement for Black, it is not intended to be +used interchangeably with Black on an ongoing basis, as the formatter _does_ differ from +Black in a few conscious ways (see: [_Known deviations_](formatter/black.md)). In general, +deviations are limited to cases in which Ruff's behavior was deemed more consistent, or +significantly simpler to support (with negligible end-user impact) given the differences in the +underlying implementations between Black and Ruff. + +Going forward, the Ruff Formatter will support Black's preview style under Ruff's own +[preview](preview.md) mode. + +## Configuration + +The Ruff Formatter exposes a small set of configuration options, some of which are also supported +by Black (like line width), some of which are unique to Ruff (like quote and indentation style). + +For example, to configure the formatter to use single quotes, a line width of 100, and +tab indentation, add the following to your `pyproject.toml`: + +```toml +[tool.ruff] +line-length = 100 + +[tool.ruff.format] +quote-style = "single" +indent-style = "tab" +``` + +For the full list of supported settings, see [_Settings_](settings.md#format). For more on +configuring Ruff via `pyproject.toml`, see [_Configuring Ruff_](configuration.md). + +Given the focus on Black compatibility (and unlike formatters like [YAPF](https://github.com/google/yapf)), +Ruff does not currently expose any configuration options to modify core formatting behavior outside +of these trivia-related settings. + +## Format suppression + +Like Black, Ruff supports `# fmt: on`, `# fmt: off`, and `# fmt: skip` pragma comments, which can +be used to temporarily disable formatting for a given code block. + +`# fmt: on` and `# fmt: off` comments are enforced at the statement level: + +```python +# fmt: off +not_formatted=3 +also_not_formatted=4 +# fmt: on +``` + +As such, adding `# fmt: on` and `# fmt: off` comments within expressions will have no effect. In +the following example, both list entries will be formatted, despite the `# fmt: off`: + +```python +[ + # fmt: off + '1', + # fmt: on + '2', +] +``` + +Instead, apply the `# fmt: off` comment to the entire statement: + +```python +# fmt: off +[ + '1', + '2', +] +# fmt: on +``` + +`# fmt: skip` comments suppress formatting for a preceding statement, case header, decorator, +function definition, or class definition: + +```python +if True: + pass +elif False: # fmt: skip + pass + +@Test +@Test2 # fmt: skip +def test(): ... + +a = [1, 2, 3, 4, 5] # fmt: skip + +def test(a, b, c, d, e, f) -> int: # fmt: skip + pass +``` + +Like Black, Ruff will _also_ recognize [YAPF](https://github.com/google/yapf)'s `# yapf: disable` and `# yapf: enable` pragma +comments, which are treated equivalently to `# fmt: off` and `# fmt: on`, respectively. + +## Conflicting lint rules + +Ruff's formatter is designed to be used alongside the linter. However, the linter includes +some rules that, when enabled, can cause conflicts with the formatter, leading to unexpected +behavior. When configured appropriately, the goal of Ruff's formatter-linter compatibility is +such that running the formatter should never introduce new lint errors. + +As such, when using Ruff as a formatter, we recommend avoiding the following lint rules: + +- [`tab-indentation`](rules/tab-indentation.md) (`W191`) +- [`indentation-with-invalid-multiple`](rules/indentation-with-invalid-multiple.md) (`E111`) +- [`indentation-with-invalid-multiple-comment`](rules/indentation-with-invalid-multiple-comment.md) (`E114`) +- [`over-indented`](rules/over-indented.md) (`E117`) +- [`indent-with-spaces`](rules/indent-with-spaces.md) (`D206`) +- [`triple-single-quotes`](rules/triple-single-quotes.md) (`D300`) +- [`bad-quotes-inline-string`](rules/bad-quotes-inline-string.md) (`Q000`) +- [`bad-quotes-multiline-string`](rules/bad-quotes-multiline-string.md) (`Q001`) +- [`bad-quotes-docstring`](rules/bad-quotes-docstring.md) (`Q002`) +- [`avoidable-escaped-quote`](rules/avoidable-escaped-quote.md) (`Q003`) +- [`missing-trailing-comma`](rules/missing-trailing-comma.md) (`COM812`) +- [`prohibited-trailing-comma`](rules/prohibited-trailing-comma.md) (`COM819`) +- [`single-line-implicit-string-concatenation`](rules/single-line-implicit-string-concatenation.md) (`ISC001`) +- [`multi-line-implicit-string-concatenation`](rules/multi-line-implicit-string-concatenation.md) (`ISC002`) + +None of the above are included in Ruff's default configuration. However, if you've enabled +any of these rules or their parent categories (like `Q`), we recommend disabling them via the +linter's [`ignore`](settings.md#ignore) setting. + +Similarly, we recommend avoiding the following isort settings, which are incompatible with the +formatter's treatment of import statements when set to non-default values: + +- [`force-single-line`](settings.md#isort-force-single-line) +- [`force-wrap-aliases`](settings.md#isort-force-wrap-aliases) +- [`lines-after-imports`](settings.md#isort-lines-after-imports) +- [`lines-between-types`](settings.md#isort-lines-between-types) +- [`split-on-trailing-comma`](settings.md#isort-split-on-trailing-comma) + +If you've configured any of these settings to take on non-default values, we recommend removing +them from your Ruff configuration. + +When an incompatible lint rule or setting is enabled, `ruff format` will emit a warning. If your +`ruff format` is free of warnings, you're good to go! + +## Exit codes + +`ruff format` exits with the following status codes: + +- `0` if Ruff terminates successfully, regardless of whether any files were formatted. +- `2` if Ruff terminates abnormally due to invalid configuration, invalid CLI options, or an + internal error. + +Meanwhile, `ruff format --check` exits with the following status codes: + +- `0` if Ruff terminates successfully, and no files would be formatted if `--check` were not + specified. +- `1` if Ruff terminates successfully, and one or more files would be formatted if `--check` were + not specified. +- `2` if Ruff terminates abnormally due to invalid configuration, invalid CLI options, or an + internal error. + +## Black compatibility + +The formatter is designed to be a drop-in replacement for [Black](https://github.com/psf/black). + +Specifically, the formatter is intended to emit near-identical output when run over Black-formatted +code. When run over extensive Black-formatted projects like Django and Zulip, > 99.9% of lines +are formatted identically. When migrating an existing project from Black to Ruff, you should expect +to see a few differences on the margins, but the vast majority of your code should be unchanged. + +When run over _non_-Black-formatted code, the formatter makes some different decisions than Black, +and so more deviations should be expected, especially around the treatment of end-of-line comments. + +If you identify deviations in your project, spot-check them against the [known deviations](formatter/black.md), +as well as the [unintentional deviations](https://github.com/astral-sh/ruff/issues?q=is%3Aopen+is%3Aissue+label%3Aformatter) +filed in the issue tracker. If you've identified a new deviation, please [file an issue](https://github.com/astral-sh/ruff/issues/new). + +### Intentional deviations + +While the Ruff formatter aims to be a drop-in replacement for Black, it does differ from Black +in a few known ways. Some of these differences emerge from conscious attempts to improve upon +Black's code style, while others fall out of differences in the underlying implementations. + +For a complete enumeration of these intentional deviations, see [_Known deviations_](formatter/black.md). + +Unintentional deviations from Black are tracked in the [issue tracker](https://github.com/astral-sh/ruff/issues?q=is%3Aopen+is%3Aissue+label%3Aformatter). + +### Preview style + +Black gates formatting changes behind a [`preview`](https://black.readthedocs.io/en/stable/the_black_code_style/future_style.html#preview-style) +flag. The formatter does not yet support Black's preview style, though the intention is to support +it within the coming months behind Ruff's own [`preview`](https://docs.astral.sh/ruff/settings/#preview) +flag. + +Black promotes some of its preview styling to stable at the end of each year. Ruff will similarly +implement formatting changes under the [`preview`](https://docs.astral.sh/ruff/settings/#preview) +flag, promoting them to stable through minor releases, in accordance with our [versioning policy](https://github.com/astral-sh/ruff/discussions/6998#discussioncomment-7016766). diff --git a/docs/formatter/black.md b/docs/formatter/black.md new file mode 100644 index 0000000000000..d9683c89b02bc --- /dev/null +++ b/docs/formatter/black.md @@ -0,0 +1,510 @@ +--- +title: "Known Deviations from Black" +hide: + - navigation +--- + +This document enumerates the known, intentional differences in code style between Black and Ruff's +formatter. + +For a list of unintentional deviations, see [issue tracker](https://github.com/astral-sh/ruff/issues?q=is%3Aopen+is%3Aissue+label%3Aformatter). + +### Trailing end-of-line comments + +Black's priority is to fit an entire statement on a line, even if it contains end-of-line comments. +In such cases, Black collapses the statement, and moves the comment to the end of the collapsed +statement: + +```python +# Input +while ( + cond1 # almost always true + and cond2 # almost never true +): + print("Do something") + +# Black +while cond1 and cond2: # almost always true # almost never true + print("Do something") +``` + +Ruff, like [Prettier](https://prettier.io/), expands any statement that contains trailing +end-of-line comments. For example, Ruff would avoid collapsing the `while` test in the snippet +above. This ensures that the comments remain close to their original position and retain their +original intent, at the cost of retaining additional vertical space. + +This deviation only impacts unformatted code, in that Ruff's output should not deviate for code that +has already been formatted by Black. + +### Pragma comments are ignored when computing line width + +Pragma comments (`# type`, `# noqa`, `# pyright`, `# pylint`, etc.) are ignored when computing the width of a line. +This prevents Ruff from moving pragma comments around, thereby modifying their meaning and behavior: + +See Ruff's [pragma comment handling proposal](https://github.com/astral-sh/ruff/discussions/6670) +for details. + +This is similar to [Pyink](https://github.com/google/pyink) but a deviation from Black. Black avoids +splitting any lines that contain a `# type` comment ([#997](https://github.com/psf/black/issues/997)), +but otherwise avoids special-casing pragma comments. + +As Ruff expands trailing end-of-line comments, Ruff will also avoid moving pragma comments in cases +like the following, where moving the `# noqa` to the end of the line causes it to suppress errors +on both `first()` and `second()`: + +```python +# Input +[ + first(), # noqa + second() +] + +# Black +[first(), second()] # noqa + +# Ruff +[ + first(), # noqa + second(), +] +``` + +### Line width vs. line length + +Ruff uses the Unicode width of a line to determine if a line fits. Black's stable style uses +character width, while Black's preview style uses Unicode width for strings ([#3445](https://github.com/psf/black/pull/3445)), +and character width for all other tokens. Ruff's behavior is closer to Black's preview style than +Black's stable style, although Ruff _also_ uses Unicode width for identifiers and comments. + +### Walruses in slice expressions + +Black avoids inserting space around `:=` operators within slices. For example, the following adheres +to Black stable style: + +```python +# Input +x[y:=1] + +# Black +x[y:=1] +``` + +Ruff will instead add space around the `:=` operator: + +```python +# Input +x[y:=1] + +# Ruff +x[y := 1] +``` + +This will likely be incorporated into Black's preview style ([#3823](https://github.com/psf/black/pull/3823)). + +### `global` and `nonlocal` names are broken across multiple lines by continuations + +If a `global` or `nonlocal` statement includes multiple names, and exceeds the configured line +width, Ruff will break them across multiple lines using continuations: + +```python +# Input +global analyze_featuremap_layer, analyze_featuremapcompression_layer, analyze_latencies_post, analyze_motions_layer, analyze_size_model + +# Ruff +global \ + analyze_featuremap_layer, \ + analyze_featuremapcompression_layer, \ + analyze_latencies_post, \ + analyze_motions_layer, \ + analyze_size_model +``` + +### Newlines are inserted after all class docstrings + +Black typically enforces a single newline after a class docstring. However, it does not apply such +formatting if the docstring is single-quoted rather than triple-quoted, while Ruff enforces a +single newline in both cases: + +```python +# Input +class IntFromGeom(GEOSFuncFactory): + "Argument is a geometry, return type is an integer." + argtypes = [GEOM_PTR] + restype = c_int + errcheck = staticmethod(check_minus_one) + +# Black +class IntFromGeom(GEOSFuncFactory): + "Argument is a geometry, return type is an integer." + argtypes = [GEOM_PTR] + restype = c_int + errcheck = staticmethod(check_minus_one) + +# Ruff +class IntFromGeom(GEOSFuncFactory): + "Argument is a geometry, return type is an integer." + + argtypes = [GEOM_PTR] + restype = c_int + errcheck = staticmethod(check_minus_one) +``` + +### Trailing own-line comments on imports are not moved to the next line + +Black enforces a single empty line between an import and a trailing own-line comment. Ruff leaves +such comments in-place: + +```python +# Input +import os +# comment + +import sys + +# Black +import os + +# comment + +import sys + +# Ruff +import os +# comment + +import sys +``` + +### Parentheses around awaited collections are not preserved + +Black preserves parentheses around awaited collections: + +```python +await ([1, 2, 3]) +``` + +Ruff will instead remove them: + +```python +await [1, 2, 3] +``` + +This is more consistent to the formatting of other awaited expressions: Ruff and Black both +remove parentheses around, e.g., `await (1)`, only retaining them when syntactically required, +as in, e.g., `await (x := 1)`. + +### Implicit string concatenations in attribute accesses + +Given the following unformatted code: + +```python +print("aaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaa".format(bbbbbbbbbbbbbbbbbb + bbbbbbbbbbbbbbbbbb)) +``` + +Internally, Black's logic will first expand the outermost `print` call: + +```python +print( + "aaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaa".format(bbbbbbbbbbbbbbbbbb + bbbbbbbbbbbbbbbbbb) +) +``` + +Since the argument is _still_ too long, Black will then split on the operator with the highest split +precedence. In this case, Black splits on the implicit string concatenation, to produce the +following Black-formatted code: + +```python +print( + "aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa".format(bbbbbbbbbbbbbbbbbb + bbbbbbbbbbbbbbbbbb) +) +``` + +Ruff gives implicit concatenations a "lower" priority when breaking lines. As a result, Ruff +would instead format the above as: + +```python +print( + "aaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaa".format( + bbbbbbbbbbbbbbbbbb + bbbbbbbbbbbbbbbbbb + ) +) +``` + +In general, Black splits implicit string concatenations over multiple lines more often than Ruff, +even if those concatenations _can_ fit on a single line. Ruff instead avoids splitting such +concatenations unless doing so is necessary to fit within the configured line width. + +### Own-line comments on expressions don't cause the expression to expand + +Given an expression like: + +```python +( + # A comment in the middle + some_example_var and some_example_var not in some_example_var +) +``` + +Black associates the comment with `some_example_var`, thus splitting it over two lines: + +```python +( + # A comment in the middle + some_example_var + and some_example_var not in some_example_var +) +``` + +Ruff will instead associate the comment with the entire boolean expression, thus preserving the +initial formatting: + +```python +( + # A comment in the middle + some_example_var and some_example_var not in some_example_var +) +``` + +### Tuples are parenthesized when expanded + +Ruff tends towards parenthesizing tuples (with a few exceptions), while Black tends to remove tuple +parentheses more often. + +In particular, Ruff will always insert parentheses around tuples that expand over multiple lines: + +```python +# Input +(a, b), (c, d,) + +# Black +(a, b), ( + c, + d, +) + +# Ruff +( + (a, b), + ( + c, + d, + ), +) +``` + +There's one exception here. In `for` loops, both Ruff and Black will avoid inserting unnecessary +parentheses: + +```python +# Input +for a, f(b,) in c: + pass + +# Black +for a, f( + b, +) in c: + pass + +# Ruff +for a, f( + b, +) in c: + pass +``` + +### Single-element tuples are always parenthesized + +Ruff always inserts parentheses around single-element tuples, while Black will omit them in some +cases: + +```python +# Input +(a, b), + +# Black +(a, b), + +# Ruff +((a, b),) +``` + +Adding parentheses around single-element tuples adds visual distinction and helps avoid "accidental" +tuples created by extraneous trailing commas (see, e.g., [#17181](https://github.com/django/django/pull/17181)). + +### Trailing commas are inserted when expanding a function definition with a single argument + +When a function definition with a single argument is expanded over multiple lines, Black +will add a trailing comma in some cases, depending on whether the argument includes a type +annotation and/or a default value. + +For example, Black will add a trailing comma to the first and second function definitions below, +but not the third: + +```python +def func( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, +) -> None: + ... + + +def func( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=1, +) -> None: + ... + + +def func( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: Argument( + "network_messages.pickle", + help="The path of the pickle file that will contain the network messages", + ) = 1 +) -> None: + ... +``` + +Ruff will instead insert a trailing comma in all such cases for consistency. + +### Parentheses around call-chain assignment values are not preserved + +Given: + +```python +def update_emission_strength(): + ( + get_rgbw_emission_node_tree(self) + .nodes["Emission"] + .inputs["Strength"] + .default_value + ) = (self.emission_strength * 2) +``` + +Black will preserve the parentheses in `(self.emission_strength * 2)`, whereas Ruff will remove +them. + +Both Black and Ruff remove such parentheses in simpler assignments, like: + +```python +# Input +def update_emission_strength(): + value = (self.emission_strength * 2) + +# Black +def update_emission_strength(): + value = self.emission_strength * 2 + +# Ruff +def update_emission_strength(): + value = self.emission_strength * 2 +``` + +### Call chain calls break differently + +Black occasionally breaks call chains differently than Ruff; in particular, Black occasionally +expands the arguments for the last call in the chain, as in: + +```python +# Input +df.drop( + columns=["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"] +).drop_duplicates().rename( + columns={ + "a": "a", + } +).to_csv(path / "aaaaaa.csv", index=False) + +# Black +df.drop( + columns=["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"] +).drop_duplicates().rename( + columns={ + "a": "a", + } +).to_csv( + path / "aaaaaa.csv", index=False +) + +# Ruff +df.drop( + columns=["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"] +).drop_duplicates().rename( + columns={ + "a": "a", + } +).to_csv(path / "aaaaaa.csv", index=False) +``` + +Ruff will only expand the arguments if doing so is necessary to fit within the configured line +width. + +Note that Black does not apply this last-call argument breaking universally. For example, both +Black and Ruff will format the following identically: + +```python +# Input +df.drop( + columns=["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"] +).drop_duplicates(a).rename( + columns={ + "a": "a", + } +).to_csv( + path / "aaaaaa.csv", index=False +).other(a) + +# Black +df.drop(columns=["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]).drop_duplicates(a).rename( + columns={ + "a": "a", + } +).to_csv(path / "aaaaaa.csv", index=False).other(a) + +# Ruff +df.drop(columns=["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]).drop_duplicates(a).rename( + columns={ + "a": "a", + } +).to_csv(path / "aaaaaa.csv", index=False).other(a) +``` + +### Expressions with (non-pragma) trailing comments are split more often + +Both Ruff and Black will break the following expression over multiple lines, since it then allows +the expression to fit within the configured line width: + +```python +# Input +some_long_variable_name = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + +# Black +some_long_variable_name = ( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +) + +# Ruff +some_long_variable_name = ( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +) +``` + +However, if the expression ends in a trailing comment, Black will avoid wrapping the expression +in some cases, while Ruff will wrap as long as it allows the expanded lines to fit within the line +length limit: + +```python +# Input +some_long_variable_name = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # a trailing comment + +# Black +some_long_variable_name = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # a trailing comment + +# Ruff +some_long_variable_name = ( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +) # a trailing comment +``` + +Doing so leads to fewer overlong lines while retaining the comment's intent. As pragma comments +(like `# noqa` and `# type: ignore`) are ignored when computing line width, this behavior only +applies to non-pragma comments. diff --git a/docs/installation.md b/docs/installation.md index 259946f85180e..6456ade624ff9 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -6,6 +6,13 @@ Ruff is available as [`ruff`](https://pypi.org/project/ruff/) on PyPI: pip install ruff ``` +Once installed, you can run Ruff from the command line: + +```shell +ruff check . # Lint all files in the current directory. +ruff format . # Format all files in the current directory. +``` + For **macOS Homebrew** and **Linuxbrew** users, Ruff is also available as [`ruff`](https://formulae.brew.sh/formula/ruff) on Homebrew: diff --git a/docs/editor-integrations.md b/docs/integrations.md similarity index 76% rename from docs/editor-integrations.md rename to docs/integrations.md index 45b1e2da4928f..94f095dbd5956 100644 --- a/docs/editor-integrations.md +++ b/docs/integrations.md @@ -1,12 +1,64 @@ -# Editor Integrations +# Integrations ## VS Code (Official) Download the [Ruff VS Code extension](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff), -which supports autofix actions, import sorting, and more. +which supports fix actions, import sorting, and more. ![Ruff VS Code extension](https://user-images.githubusercontent.com/1309177/205175763-cf34871d-5c05-4abf-9916-440afc82dbf8.gif) +## pre-commit + +Ruff can be used as a [pre-commit](https://pre-commit.com) hook via [`ruff-pre-commit`](https://github.com/astral-sh/ruff-pre-commit): + +```yaml +# Run the Ruff formatter. +- repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.0.291 + hooks: + - id: ruff-format +# Run the Ruff linter. +- repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.0.291 + hooks: + - id: ruff +``` + +To enable fixes, add the `--fix` argument to the linter: + +```yaml +# Run the Ruff linter. +- repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.0.291 + hooks: + - id: ruff + args: [ --fix, --exit-non-zero-on-fix ] +``` + +To run the hooks over Jupyter Notebooks too, add `jupyter` to the list of allowed filetypes: + +```yaml +# Run the Ruff linter. +- repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.0.291 + hooks: + - id: ruff + types_or: [python, pyi, jupyter] +``` + +Ruff's lint hook should be placed after other formatting tools, such as Ruff's format hook, Black, +or isort, _unless_ you enable autofix, in which case, Ruff's pre-commit hook should run _before_ +Black, isort, and other formatting tools, as Ruff's autofix behavior can output code changes that +require reformatting. + +As long as your Ruff configuration avoids any [linter-formatter incompatibilities](formatter.md#conflicting-lint-rules), +`ruff format` should never introduce new lint errors, so it's safe to run Ruff's format hook _after_ +`ruff check --fix`. + ## Language Server Protocol (Official) Ruff supports the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) @@ -292,7 +344,53 @@ jobs: run: | python -m pip install --upgrade pip pip install ruff - # Include `--format=github` to enable automatic inline annotations. + # Update output format to enable automatic inline annotations. - name: Run Ruff - run: ruff check --format=github . + run: ruff check --output-format=github . +``` + +Ruff can also be used as a GitHub Action via [`ruff-action`](https://github.com/chartboost/ruff-action). + +By default, `ruff-action` runs as a pass-fail test to ensure that a given repository doesn't contain +any lint rule violations as per its [configuration](https://github.com/astral-sh/ruff/blob/main/docs/configuration.md). +However, under-the-hood, `ruff-action` installs and runs `ruff` directly, so it can be used to +execute any supported `ruff` command (e.g., `ruff check --fix`). + +`ruff-action` supports all GitHub-hosted runners, and can be used with any published Ruff version +(i.e., any version available on [PyPI](https://pypi.org/project/ruff/)). + +To use `ruff-action`, create a file (e.g., `.github/workflows/ruff.yml`) inside your repository +with: + +```yaml +name: Ruff +on: [ push, pull_request ] +jobs: + ruff: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: chartboost/ruff-action@v1 +``` + +Alternatively, you can include `ruff-action` as a step in any other workflow file: + +```yaml + - uses: chartboost/ruff-action@v1 +``` + +`ruff-action` accepts optional configuration parameters via `with:`, including: + +- `version`: The Ruff version to install (default: latest). +- `options`: The command-line arguments to pass to Ruff (default: `"check"`). +- `src`: The source paths to pass to Ruff (default: `"."`). + +For example, to run `ruff check --select B ./src` using Ruff version `0.0.259`: + +```yaml +- uses: chartboost/ruff-action@v1 + with: + src: "./src" + version: 0.0.259 + args: --select B ``` diff --git a/docs/linter.md b/docs/linter.md new file mode 100644 index 0000000000000..891d133cfb0c2 --- /dev/null +++ b/docs/linter.md @@ -0,0 +1,295 @@ +# The Ruff Linter + +The Ruff Linter is an extremely fast Python linter designed as a drop-in replacement for [Flake8](https://pypi.org/project/flake8/) +(plus dozens of plugins), [isort](https://pypi.org/project/isort/), [pydocstyle](https://pypi.org/project/pydocstyle/), +[pyupgrade](https://pypi.org/project/pyupgrade/), [autoflake](https://pypi.org/project/autoflake/), +and more. + +## `ruff check` + +`ruff check` is the primary entrypoint to the Ruff linter. It accepts a list of files or +directories, and lints all discovered Python files, optionally fixing any fixable errors: + +```shell +ruff check . # Lint all files in the current directory. +ruff check . --fix # Lint all files in the current directory, and fix any fixable errors. +ruff check . --watch # Lint all files in the current directory, and re-lint on change. +``` + +For the full list of supported options, run `ruff check --help`. + +## Rule selection + +The set of enabled rules is controlled via the [`select`](settings.md#select) and [`ignore`](settings.md#ignore) +settings, along with the [`extend-select`](settings.md#extend-select) and [`extend-ignore`](settings.md#extend-ignore) +modifiers. + +Ruff's linter mirrors Flake8's rule code system, in which each rule code consists of a one-to-three +letter prefix, followed by three digits (e.g., `F401`). The prefix indicates that "source" of the rule +(e.g., `F` for Pyflakes, `E` for pycodestyle, `ANN` for flake8-annotations). + +Rule selectors like [`select`](settings.md#select) and [`ignore`](settings.md#ignore) accept either +a full rule code (e.g., `F401`) or any valid prefix (e.g., `F`). For example, given the following +`pyproject.toml` file: + +```toml +[tool.ruff.lint] +select = ["E", "F"] +ignore = ["F401"] +``` + +Ruff would enable all rules with the `E` (pycodestyle) or `F` (Pyflakes) prefix, with the exception +of `F401`. For more on configuring Ruff via `pyproject.toml`, see [_Configuring Ruff_](configuration.md). + +As a special-case, Ruff also supports the `ALL` code, which enables all rules. Note that some +pydocstyle rules conflict (e.g., `D203` and `D211`) as they represent alternative docstring +formats. Ruff will automatically disable any conflicting rules when `ALL` is enabled. + +If you're wondering how to configure Ruff, here are some **recommended guidelines**: + +- Prefer `select` and `ignore` over `extend-select` and `extend-ignore`, to make your rule set + explicit. +- Use `ALL` with discretion. Enabling `ALL` will implicitly enable new rules whenever you upgrade. +- Start with a small set of rules (`select = ["E", "F"]`) and add a category at-a-time. For example, + you might consider expanding to `select = ["E", "F", "B"]` to enable the popular flake8-bugbear + extension. + +For example, a configuration that enables some of the most popular rules (without being too +pedantic) might look like the following: + +```toml +[tool.ruff.lint] +select = [ + # pycodestyle + "E", + # Pyflakes + "F", + # pyupgrade + "UP", + # flake8-bugbear + "B", + # flake8-simplify + "SIM", + # isort + "I", +] +``` + +To resolve the enabled rule set, Ruff may need to reconcile `select` and `ignore` from a variety +of sources, including the current `pyproject.toml`, any inherited `pyproject.toml` files, and the +CLI (e.g., `--select`). + +In those scenarios, Ruff uses the "highest-priority" `select` as the basis for the rule set, and +then applies any `extend-select`, `ignore`, and `extend-ignore` adjustments. CLI options are given +higher priority than `pyproject.toml` options, and the current `pyproject.toml` file is given higher +priority than any inherited `pyproject.toml` files. + +For example, given the following `pyproject.toml` file: + +```toml +[tool.ruff.lint] +select = ["E", "F"] +ignore = ["F401"] +``` + +Running `ruff check --select F401` would result in Ruff enforcing `F401`, and no other rules. + +Running `ruff check --extend-select B` would result in Ruff enforcing the `E`, `F`, and `B` rules, +with the exception of `F401`. + +## Fixes + +Ruff supports automatic fixes for a variety of lint errors. For example, Ruff can remove unused +imports, reformat docstrings, rewrite type annotations to use newer Python syntax, and more. + +To enable fixes, pass the `--fix` flag to `ruff check`: + +```shell +ruff check . --fix +``` + +By default, Ruff will fix all violations for which safe fixes are available; to determine +whether a rule supports fixing, see [_Rules_](rules.md). + +### Fix safety + +Ruff labels fixes as "safe" and "unsafe". The meaning and intent of your code will be retained when applying safe fixes, but the meaning could be changed when applying unsafe fixes. + +For example, [`unnecessary-iterable-allocation-for-first-element`](rules/unnecessary-iterable-allocation-for-first-element.md) (`RUF015`) is a rule which checks for potentially unperformant use of `list(...)[0]`. The fix replaces this pattern with `next(iter(...))` which can result in a drastic speedup: + +```shell +$ python -m timeit "head = list(range(99999999))[0]" +1 loop, best of 5: 1.69 sec per loop +``` + +```shell +$ python -m timeit "head = next(iter(range(99999999)))" +5000000 loops, best of 5: 70.8 nsec per loop +``` + +However, when the collection is empty, this changes the raised exception from an `IndexError` to `StopIteration`: + +```shell +$ python -c 'list(range(0))[0]' +Traceback (most recent call last): + File "", line 1, in +IndexError: list index out of range +``` + +```shell +$ python -c 'next(iter(range(0)))[0]' +Traceback (most recent call last): + File "", line 1, in +StopIteration +``` + +Since this could break error handling, this fix is categorized as unsafe. + +Ruff only enables safe fixes by default. Unsafe fixes can be enabled by settings [`unsafe-fixes`](settings.md#unsafe-fixes) in your configuration file or passing the `--unsafe-fixes` flag to `ruff check`: + +```shell +# Show unsafe fixes +ruff check . --unsafe-fixes + +# Apply unsafe fixes +ruff check . --fix --unsafe-fixes +``` + +The safety of fixes can be adjusted per rule using the [`extend-safe-fixes`](settings.md#extend-safe-fixes) and [`extend-unsafe-fixes`](settings.md#extend-unsafe-fixes) settings. + +For example, the following configuration would promote unsafe fixes for `F601` to safe fixes and demote safe fixes for `UP034` to unsafe fixes: + +```toml +[tool.ruff.lint] +extend-safe-fixes = ["F601"] +extend-unsafe-fixes = ["UP034"] +``` + +You may use prefixes to select rules as well, e.g., `F` can be used to promote fixes for all rules in Pyflakes to safe. + +!!! note + All fixes will always be displayed by Ruff when using the `json` output format. The safety of each fix is available under the `applicability` field. + +### Disabling fixes + +To limit the set of rules that Ruff should fix, use the [`fixable`](settings.md#fixable) and [`unfixable`](settings.md#unfixable) settings, along with their [`extend-fixable`](settings.md#extend-fixable) and [`extend-unfixable`](settings.md#extend-unfixable) +variants. + +For example, the following configuration would enable fixes for all rules except +[`unused-imports`](rules/unused-import.md) (`F401`): + +```toml +[tool.ruff.lint] +fixable = ["ALL"] +unfixable = ["F401"] +``` + +Conversely, the following configuration would only enable fixes for `F401`: + +```toml +[tool.ruff.lint] +fixable = ["F401"] +``` + +## Error suppression + +Ruff supports several mechanisms for suppressing lint errors, be they false positives or +permissible violations. + +To omit a lint rule entirely, add it to the "ignore" list via the [`ignore`](settings.md#ignore) +or [`extend-ignore`](settings.md#extend-ignore) settings, either on the command-line +or in your `pyproject.toml` or `ruff.toml` file. + +To suppress a violation inline, Ruff uses a `noqa` system similar to [Flake8](https://flake8.pycqa.org/en/3.1.1/user/ignoring-errors.html). +To ignore an individual violation, add `# noqa: {code}` to the end of the line, like so: + +```python +# Ignore F841. +x = 1 # noqa: F841 + +# Ignore E741 and F841. +i = 1 # noqa: E741, F841 + +# Ignore _all_ violations. +x = 1 # noqa +``` + +For multi-line strings (like docstrings), the `noqa` directive should come at the end of the string +(after the closing triple quote), and will apply to the entire string, like so: + +```python +"""Lorem ipsum dolor sit amet. + +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor. +""" # noqa: E501 +``` + +To ignore all violations across an entire file, add `# ruff: noqa` to any line in the file, like so: + +```python +# ruff: noqa +``` + +To ignore a specific rule across an entire file, add `# ruff: noqa: {code}` to any line in the file, +like so: + +```python +# ruff: noqa: F841 +``` + +Or see the [`per-file-ignores`](settings.md#per-file-ignores) setting, which enables the same +functionality from within your `pyproject.toml` or `ruff.toml` file. + +Note that Ruff will also respect Flake8's `# flake8: noqa` directive, and will treat it as +equivalent to `# ruff: noqa`. + +### Detecting unused suppression comments + +Ruff implements a special rule, [`unused-noqa`](https://docs.astral.sh/ruff/rules/unused-noqa/), +under the `RUF100` code, to enforce that your `noqa` directives are "valid", in that the violations +they _say_ they ignore are actually being triggered on that line (and thus suppressed). To flag +unused `noqa` directives, run: `ruff check /path/to/file.py --extend-select RUF100`. + +Ruff can also _remove_ any unused `noqa` directives via its fix functionality. To remove any +unused `noqa` directives, run: `ruff check /path/to/file.py --extend-select RUF100 --fix`. + +### Inserting necessary suppression comments + +Ruff can _automatically add_ `noqa` directives to all lines that contain violations, which is +useful when migrating a new codebase to Ruff. To automatically add `noqa` directives to all +relevant lines (with the appropriate rule codes), run: `ruff check /path/to/file.py --add-noqa`. + +### Action comments + +Ruff respects isort's [action comments](https://pycqa.github.io/isort/docs/configuration/action_comments.html) +(`# isort: skip_file`, `# isort: on`, `# isort: off`, `# isort: skip`, and `# isort: split`), which +enable selectively enabling and disabling import sorting for blocks of code and other inline +configuration. + +Ruff will also respect variants of these action comments with a `# ruff:` prefix +(e.g., `# ruff: isort: skip_file`, `# ruff: isort: on`, and so on). These variants more clearly +convey that the action comment is intended for Ruff, but are functionally equivalent to the +isort variants. + +See the [isort documentation](https://pycqa.github.io/isort/docs/configuration/action_comments.html) +for more. + +## Exit codes + +By default, `ruff check` exits with the following status codes: + +- `0` if no violations were found, or if all present violations were fixed automatically. +- `1` if violations were found. +- `2` if Ruff terminates abnormally due to invalid configuration, invalid CLI options, or an + internal error. + +This convention mirrors that of tools like ESLint, Prettier, and RuboCop. + +`ruff check` supports two command-line flags that alter its exit code behavior: + +- `--exit-zero` will cause Ruff to exit with a status code of `0` even if violations were found. + Note that Ruff will still exit with a status code of `2` if it terminates abnormally. +- `--exit-non-zero-on-fix` will cause Ruff to exit with a status code of `1` if violations were + found, _even if_ all such violations were fixed automatically. Note that the use of + `--exit-non-zero-on-fix` can result in a non-zero exit code even if no violations remain after + fixing. diff --git a/docs/preview.md b/docs/preview.md index b1abd25a1a56b..0c369d4245218 100644 --- a/docs/preview.md +++ b/docs/preview.md @@ -3,13 +3,28 @@ Ruff includes an opt-in preview mode to provide an opportunity for community feedback and increase confidence that changes are a net-benefit before enabling them for everyone. -Preview mode enables a collection of newer rules and fixes that are considered experimental or unstable. +Preview mode enables a collection of newer lint rules, fixes, and formatter style changes that are +considered experimental or unstable,. ## Enabling preview mode Preview mode can be enabled with the `--preview` flag on the CLI or by setting `preview = true` in your Ruff configuration file (e.g. `pyproject.toml`). +Preview mode can be configured separately for linting and formatting (requires Ruff v0.1.1+). To enable preview lint rules without preview style formatting: + +```toml +[lint] +preview = true +``` + +To enable preview style formatting without enabling any preview lint rules: + +```toml +[format] +preview = true +``` + ## Using rules that are in preview If a rule is marked as preview, it can only be selected if preview mode is enabled. For example, consider a @@ -46,3 +61,29 @@ preview = true Or, if you provided the `--preview` CLI flag. To see which rules are currently in preview, visit the [rules reference](rules.md). + +## Selecting single preview rules + +When preview mode is enabled, selecting rule categories or prefixes will include all preview rules that match. +If you'd prefer to opt-in to each preview rule individually, you can toggle the `explicit-preview-rules` +setting in your `pyproject.toml`: + +```toml +[tool.ruff] +preview = true +explicit-preview-rules = true +``` + +In our previous example, `--select` with `ALL` `HYP`, `HYP0`, or `HYP00` would not enable `HYP001`. Each preview +rule will need to be selected with its exact code, e.g. `--select ALL,HYP001`. + +If preview mode is not enabled, this setting has no effect. + +## Legacy behavior + +Before the preview mode was introduced, new rules were added in a "nursery" category that required selection of +rules with their exact codes — similar to if `explicit-preview-rules` is enabled. + +The nursery category has been deprecated and all rules in the nursery are now considered to be in preview. +For backwards compatibility, nursery rules are selectable with their exact codes without enabling preview mode. +However, this behavior will display a warning and support will be removed in a future release. diff --git a/docs/requirements-insiders.txt b/docs/requirements-insiders.txt index f9a72033886d4..4b0124b6c1a7e 100644 --- a/docs/requirements-insiders.txt +++ b/docs/requirements-insiders.txt @@ -1,4 +1,4 @@ PyYAML==6.0 -black==23.3.0 +black==23.10.0 mkdocs==1.5.0 git+ssh://git@github.com/astral-sh/mkdocs-material-insiders.git@38c0b8187325c3bab386b666daf3518ac036f2f4 diff --git a/docs/requirements.txt b/docs/requirements.txt index b5cb285e069c7..f852e10f92686 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,4 @@ PyYAML==6.0 -black==23.3.0 +black==23.10.0 mkdocs==1.5.0 mkdocs-material==9.1.18 diff --git a/docs/tutorial.md b/docs/tutorial.md index 89dec0c3e1d6c..25b2a7023eb57 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -1,11 +1,17 @@ # Tutorial -This tutorial will walk you through the process of integrating Ruff into your project. For a more -detailed overview, see [_Configuration_](configuration.md). +This tutorial will walk you through the process of integrating Ruff's linter and formatter into +your project. For a more detailed overview, see [_Configuring Ruff_](configuration.md). ## Getting Started -Let's assume that our project structure looks like: +To start, we'll install Ruff through PyPI (or with your [preferred package manager](installation.md)): + +```shell +pip install ruff +``` + +Let's then assume that our project structure looks like: ```text numbers @@ -13,36 +19,33 @@ numbers └── numbers.py ``` -Where `numbers.py` contains the following code: +...where `numbers.py` contains the following code: ```py -from typing import List +from typing import Iterable import os -def sum_even_numbers(numbers: List[int]) -> int: - """Given a list of integers, return the sum of all even numbers in the list.""" - return sum(num for num in numbers if num % 2 == 0) -``` - -To start, we'll install Ruff through PyPI (or with your [preferred package manager](installation.md)): - -```shell -> pip install ruff +def sum_even_numbers(numbers: Iterable[int]) -> int: + """Given an iterable of integers, return the sum of all even numbers in the iterable.""" + return sum( + num for num in numbers + if num % 2 == 0 + ) ``` -We can then run Ruff over our project via: +We can run the Ruff linter over our project via `ruff check`: ```shell ❯ ruff check . numbers/numbers.py:3:8: F401 [*] `os` imported but unused Found 1 error. -[*] 1 potentially fixable with the --fix option. +[*] 1 fixable with the `--fix` option. ``` Ruff identified an unused import, which is a common error in Python code. Ruff considers this a -"fixable" error, so we can resolve the issue automatically by running: +"fixable" error, so we can resolve the issue automatically by running `ruff check --fix`: ```shell ❯ ruff check --fix . @@ -55,14 +58,41 @@ Running `git diff` shows the following: --- a/numbers/numbers.py +++ b/numbers/numbers.py @@ -1,7 +1,5 @@ - from typing import List + from typing import Iterable -import os - -def sum_even_numbers(numbers: List[int]) -> int: - """Given a list of integers, return the sum of all even numbers in the list.""" - return sum(num for num in numbers if num % 2 == 0) +def sum_even_numbers(numbers: Iterable[int]) -> int: + """Given an iterable of integers, return the sum of all even numbers in the iterable.""" + return sum( + num for num in numbers + if num % 2 == 0 + ) +``` + +Now that our project is passing `ruff check`, we can run the Ruff formatter via `ruff format`: + +```shell +❯ ruff format . +1 file reformatted +``` + +Running `git diff` shows that the `sum` call was reformatted to fit within the default 88-character +line length limit: + +```diff +--- a/numbers.py ++++ b/numbers.py +@@ -3,7 +3,4 @@ from typing import Iterable + + def sum_even_numbers(numbers: Iterable[int]) -> int: + """Given an iterable of integers, return the sum of all even numbers in the iterable.""" +- return sum( +- num for num in numbers +- if num % 2 == 0 +- ) ++ return sum(num for num in numbers if num % 2 == 0) ``` Thus far, we've been using Ruff's default configuration. Let's take a look at how we can customize @@ -73,19 +103,25 @@ Ruff's behavior. To determine the appropriate settings for each Python file, Ruff looks for the first `pyproject.toml`, `ruff.toml`, or `.ruff.toml` file in the file's directory or any parent directory. -Let's create a `pyproject.toml` file in our project's root directory: +To configure Ruff, let's create a `pyproject.toml` file in our project's root directory: ```toml [tool.ruff] -# Decrease the maximum line length to 79 characters. +# Set the maximum line length to 79. line-length = 79 + +[tool.ruff.lint] +# Add the `line-too-long` rule to the enforced rule set. By default, Ruff omits rules that +# overlap with the use of a formatter, like Black, but we can override this behavior by +# explicitly adding the rule. +extend-select = ["E501"] ``` -Running Ruff again, we can see that it now enforces a line length of 79 characters: +Running Ruff again, we see that it now enforces a maximum line width, with a limit of 79: ```shell ❯ ruff check . -numbers/numbers.py:6:80: E501 Line too long (83 > 79 characters) +numbers/numbers.py:5:80: E501 Line too long (90 > 79) Found 1 error. ``` @@ -98,9 +134,12 @@ specifically, we'll want to make note of the minimum supported Python version: requires-python = ">=3.10" [tool.ruff] -# Decrease the maximum line length to 79 characters. +# Set the maximum line length to 79. line-length = 79 -src = ["src"] + +[tool.ruff.lint] +# Add the `line-too-long` rule to the enforced rule set. +extend-select = ["E501"] ``` ### Rule Selection @@ -109,8 +148,9 @@ Ruff supports [over 700 lint rules](rules.md) split across over 50 built-in plug determining the right set of rules will depend on your project's needs: some rules may be too strict, some are framework-specific, and so on. -By default, Ruff enforces the `E`- and `F`-prefixed rules, which correspond to those derived from -pycodestyle and Pyflakes, respectively. +By default, Ruff enables Flake8's `F` rules, along with a subset of the `E` rules, omitting any +stylistic rules that overlap with the use of a formatter, like `ruff format` or +[Black](https://github.com/psf/black). If you're introducing a linter for the first time, **the default rule set is a great place to start**: it's narrow and focused while catching a wide variety of common errors (like unused @@ -118,41 +158,42 @@ imports) with zero configuration. If you're migrating to Ruff from another linter, you can enable rules that are equivalent to those enforced in your previous configuration. For example, if we want to enforce the pyupgrade -rules, we can add the following to our `pyproject.toml`: +rules, we can set our `pyproject.toml` to the following: ```toml -[tool.ruff] -select = [ - "E", # pycodestyle - "F", # pyflakes +[project] +requires-python = ">=3.10" + +[tool.ruff.lint] +extend-select = [ "UP", # pyupgrade ] ``` If we run Ruff again, we'll see that it now enforces the pyupgrade rules. In particular, Ruff flags -the use of `List` instead of its standard-library variant: +the use of the deprecated `typing.Iterable` instead of `collections.abc.Iterable`: ```shell ❯ ruff check . -numbers/numbers.py:5:31: UP006 [*] Use `list` instead of `List` for type annotations -numbers/numbers.py:6:80: E501 Line too long (83 > 79 characters) -Found 2 errors. -[*] 1 potentially fixable with the --fix option. +numbers/numbers.py:1:1: UP035 [*] Import from `collections.abc` instead: `Iterable` +Found 1 error. +[*] 1 fixable with the `--fix` option. ``` Over time, we may choose to enforce additional rules. For example, we may want to enforce that all functions have docstrings: ```toml -[tool.ruff] -select = [ - "E", # pycodestyle - "F", # pyflakes +[project] +requires-python = ">=3.10" + +[tool.ruff.lint] +extend-select = [ "UP", # pyupgrade "D", # pydocstyle ] -[tool.ruff.pydocstyle] +[tool.ruff.lint.pydocstyle] convention = "google" ``` @@ -161,34 +202,32 @@ If we run Ruff again, we'll see that it now enforces the pydocstyle rules: ```shell ❯ ruff check . numbers/__init__.py:1:1: D104 Missing docstring in public package +numbers/numbers.py:1:1: UP035 [*] Import from `collections.abc` instead: `Iterable` numbers/numbers.py:1:1: D100 Missing docstring in public module -numbers/numbers.py:5:31: UP006 [*] Use `list` instead of `List` for type annotations -numbers/numbers.py:5:80: E501 Line too long (83 > 79 characters) Found 3 errors. -[*] 1 potentially fixable with the --fix option. +[*] 1 fixable with the `--fix` option. ``` ### Ignoring Errors Any lint rule can be ignored by adding a `# noqa` comment to the line in question. For example, -let's ignore the `UP006` rule for the `List` import: +let's ignore the `UP035` rule for the `Iterable` import: ```py -from typing import List +from typing import Iterable # noqa: UP035 -def sum_even_numbers(numbers: List[int]) -> int: # noqa: UP006 - """Given a list of integers, return the sum of all even numbers in the list.""" +def sum_even_numbers(numbers: Iterable[int]) -> int: + """Given an iterable of integers, return the sum of all even numbers in the iterable.""" return sum(num for num in numbers if num % 2 == 0) ``` -Running Ruff again, we'll see that it no longer flags the `List` import: +Running `ruff check` again, we'll see that it no longer flags the `Iterable` import: ```shell ❯ ruff check . numbers/__init__.py:1:1: D104 Missing docstring in public package numbers/numbers.py:1:1: D100 Missing docstring in public module -numbers/numbers.py:5:80: E501 Line too long (83 > 79 characters) Found 3 errors. ``` @@ -196,17 +235,16 @@ If we want to ignore a rule for an entire file, we can add a `# ruff: noqa` comm the file: ```py -# ruff: noqa: UP006 -from typing import List +# ruff: noqa: UP035 +from typing import Iterable -def sum_even_numbers(numbers: List[int]) -> int: - """Given a list of integers, return the sum of all even numbers in the list.""" +def sum_even_numbers(numbers: Iterable[int]) -> int: + """Given an iterable of integers, return the sum of all even numbers in the iterable.""" return sum(num for num in numbers if num % 2 == 0) ``` -For more in-depth instructions on ignoring errors, -please see [_Configuration_](configuration.md#error-suppression). +For more in-depth instructions on ignoring errors, please see [_Error suppression_](linter.md#error-suppression). ### Adding Rules @@ -215,10 +253,10 @@ violations of that rule and instead focus on enforcing it going forward. Ruff enables this workflow via the `--add-noqa` flag, which will adds a `# noqa` directive to each line based on its existing violations. We can combine `--add-noqa` with the `--select` command-line -flag to add `# noqa` directives to all existing `UP006` violations: +flag to add `# noqa` directives to all existing `UP035` violations: ```shell -❯ ruff check --select UP006 --add-noqa . +❯ ruff check --select UP035 --add-noqa . Added 1 noqa directive. ``` @@ -229,34 +267,35 @@ diff --git a/tutorial/src/main.py b/tutorial/src/main.py index b9291c5ca..b9f15b8c1 100644 --- a/numbers/numbers.py +++ b/numbers/numbers.py -@@ -1,6 +1,6 @@ - from typing import List +@@ -1,4 +1,4 @@ +-from typing import Iterable ++from typing import Iterable # noqa: UP035 --def sum_even_numbers(numbers: List[int]) -> int: -+def sum_even_numbers(numbers: List[int]) -> int: # noqa: UP006 - """Given a list of integers, return the sum of all even numbers in the list.""" - return sum(num for num in numbers if num % 2 == 0) + def sum_even_numbers(numbers: Iterable[int]) -> int: ``` -## Continuous Integration +## Integrations This tutorial has focused on Ruff's command-line interface, but Ruff can also be used as a -[pre-commit](https://pre-commit.com) hook: +[pre-commit](https://pre-commit.com) hook via [`ruff-pre-commit`](https://github.com/astral-sh/ruff-pre-commit): ```yaml +# Run the Ruff linter. - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.0.291 + rev: v0.1.3 hooks: - id: ruff +# Run the Ruff formatter. +- repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.1.3 + hooks: + - id: ruff-format ``` -See [_Usage_](usage.md) for more. - -## Editor Integrations - Ruff can also be used as a [VS Code extension](https://github.com/astral-sh/ruff-vscode) or alongside any other editor through the [Ruff LSP](https://github.com/astral-sh/ruff-lsp). -See [_Editor Integrations_](editor-integrations.md). +For more, see [_Integrations_](integrations.md). diff --git a/docs/usage.md b/docs/usage.md deleted file mode 100644 index fd15f4da0dfc1..0000000000000 --- a/docs/usage.md +++ /dev/null @@ -1,109 +0,0 @@ -# Using Ruff - -To run Ruff, try any of the following: - -```shell -ruff check . # Lint all files in the current directory (and any subdirectories) -ruff check path/to/code/ # Lint all files in `/path/to/code` (and any subdirectories) -ruff check path/to/code/*.py # Lint all `.py` files in `/path/to/code` -ruff check path/to/code/to/file.py # Lint `file.py` -ruff check @file_paths.txt # Lint using an input file and treat its contents as command-line arguments (newline delimiter) -``` - -You can run Ruff in `--watch` mode to automatically re-run on-change: - -```shell -ruff check path/to/code/ --watch -``` - -## pre-commit - -Ruff can also be used as a [pre-commit](https://pre-commit.com) hook: - -```yaml -- repo: https://github.com/astral-sh/ruff-pre-commit - # Ruff version. - rev: v0.0.291 - hooks: - - id: ruff -``` - -Or, to enable autofix: - -```yaml -- repo: https://github.com/astral-sh/ruff-pre-commit - # Ruff version. - rev: v0.0.291 - hooks: - - id: ruff - args: [ --fix, --exit-non-zero-on-fix ] -``` - -Or, to run the hook on Jupyter Notebooks too: - -```yaml -- repo: https://github.com/astral-sh/ruff-pre-commit - # Ruff version. - rev: v0.0.291 - hooks: - - id: ruff - types_or: [python, pyi, jupyter] -``` - -Ruff's pre-commit hook should be placed after other formatting tools, such as Black and isort, -_unless_ you enable autofix, in which case, Ruff's pre-commit hook should run _before_ Black, isort, -and other formatting tools, as Ruff's autofix behavior can output code changes that require -reformatting. - -## VS Code - -Ruff can also be used as a [VS Code extension](https://github.com/astral-sh/ruff-vscode) or -alongside any other editor through the [Ruff LSP](https://github.com/astral-sh/ruff-lsp). - -## GitHub Action - -Ruff can also be used as a GitHub Action via [`ruff-action`](https://github.com/chartboost/ruff-action). - -By default, `ruff-action` runs as a pass-fail test to ensure that a given repository doesn't contain -any lint rule violations as per its [configuration](https://github.com/astral-sh/ruff/blob/main/docs/configuration.md). -However, under-the-hood, `ruff-action` installs and runs `ruff` directly, so it can be used to -execute any supported `ruff` command (e.g., `ruff check --fix`). - -`ruff-action` supports all GitHub-hosted runners, and can be used with any published Ruff version -(i.e., any version available on [PyPI](https://pypi.org/project/ruff/)). - -To use `ruff-action`, create a file (e.g., `.github/workflows/ruff.yml`) inside your repository -with: - -```yaml -name: Ruff -on: [ push, pull_request ] -jobs: - ruff: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: chartboost/ruff-action@v1 -``` - -Alternatively, you can include `ruff-action` as a step in any other workflow file: - -```yaml - - uses: chartboost/ruff-action@v1 -``` - -`ruff-action` accepts optional configuration parameters via `with:`, including: - -- `version`: The Ruff version to install (default: latest). -- `options`: The command-line arguments to pass to Ruff (default: `"check"`). -- `src`: The source paths to pass to Ruff (default: `"."`). - -For example, to run `ruff check --select B ./src` using Ruff version `0.0.259`: - -```yaml -- uses: chartboost/ruff-action@v1 - with: - src: "./src" - version: 0.0.259 - args: --select B -``` diff --git a/docs/versioning.md b/docs/versioning.md new file mode 100644 index 0000000000000..afd76c947c259 --- /dev/null +++ b/docs/versioning.md @@ -0,0 +1,64 @@ +# Versioning + +Ruff uses a custom versioning scheme that uses the **minor** version number for breaking changes and the **patch** version number for bug fixes. Ruff does not yet have a stable API; once Ruff's API is stable, the **major** version number and semantic versioning will be used. + +## Version changes + +**Minor** version increases will occur when: + +- A deprecated option or feature is removed +- Configuration changes in a backwards incompatible way + - This _may_ occur in minor version changes until `1.0.0`, however it should generally be avoided. +- A rule is promoted to stable +- Support for a new file type is promoted to stable +- Support for an end-of-life Python version is dropped +- The behavior of a stable rule is changed + - The scope of a stable rule is significantly increased + - The intent of the rule changes + - Does not include bug fixes that follow the original intent of the rule +- Stable rules are added to the default set +- Stable rules are removed from the default set +- A safe fix for a rule is promoted to stable + +**Patch** version increases will occur when: + +- Bugs are fixed, _including behavior changes that fix bugs_ +- An unsafe fix for a rule is added +- A safe fix for a rule is added in preview +- The scope of a rule is increased in preview +- A fix’s applicability is demoted +- A new configuration option is added +- A rule is added in preview +- The behavior of a preview rule is changed +- Support for a new Python version is added +- Support for a new file type is added in preview +- An option or feature is deprecated + +## Preview mode + +A preview mode is available to enable new, unstable rules and features e.g. support for a new file type. + +The preview mode is intended to help us collect community feedback and gain confidence that changes are a net-benefit. + +The preview mode is _not_ intended to gate access to work that is incomplete or features that we are _likely to remove._ However, **we reserve the right to make changes to _any_ behavior gated by the mode** including the removal of preview features or rules. + +## Rule stabilization + +When modifying or adding rules, we use the following guidelines: + +- New rules are always be added in a preview mode +- New rules remain in preview mode for at least one minor release before being promoted to stable + - If added in a patch release i.e. `0.6.1` then a rule are not be eligible for stability until `0.8.0` +- Stable rule behavior are not changed significantly in patch versions +- Promotion of rules to stable may be delayed in order to “batch” them into a single minor release +- Not all rules in preview need to be promoted in a given minor release + +## Fix stabilization + +Fixes have three applicability levels: + +- **Display**: Never applied, just displayed. +- **Unsafe**: Can be applied with explicit opt-in. +- **Safe**: Can be applied automatically. + +Fixes for rules may be introduced at a lower applicability then promoted to a higher applicability. Reducing the applicability of a fix is not a breaking change. The applicability of a given fix may change when the preview mode is enabled. diff --git a/mkdocs.template.yml b/mkdocs.template.yml index a917a25dad8ec..23d417404a00c 100644 --- a/mkdocs.template.yml +++ b/mkdocs.template.yml @@ -14,16 +14,22 @@ theme: - navigation.top - content.code.copy palette: + # Note: Using the system theme works with the insiders version + # https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#automatic-light-dark-mode + - media: "(prefers-color-scheme)" + toggle: + icon: material/brightness-auto + name: Switch to light mode - media: "(prefers-color-scheme: light)" scheme: astral-light toggle: - icon: material/weather-sunny + icon: material/brightness-7 name: Switch to dark mode - media: "(prefers-color-scheme: dark)" scheme: astral-dark toggle: - icon: material/weather-night - name: Switch to light mode + icon: material/brightness-4 + name: Switch to system preference custom_dir: docs/.overrides repo_url: https://github.com/astral-sh/ruff repo_name: ruff @@ -31,6 +37,8 @@ site_author: charliermarsh site_url: https://docs.astral.sh/ruff/ site_dir: site/ruff markdown_extensions: + - admonition + - pymdownx.details - toc: permalink: "#" - pymdownx.snippets: @@ -53,6 +61,7 @@ extra_css: - stylesheets/extra.css not_in_nav: | /rules/* + /formatter/* extra: analytics: provider: fathom diff --git a/playground/src/Editor/SourceEditor.tsx b/playground/src/Editor/SourceEditor.tsx index 33b9b48473d40..e5da55d91e23a 100644 --- a/playground/src/Editor/SourceEditor.tsx +++ b/playground/src/Editor/SourceEditor.tsx @@ -51,7 +51,6 @@ export default function SourceEditor({ const codeActionProvider = monaco?.languages.registerCodeActionProvider( "python", { - // @ts-expect-error: The type definition is wrong. provideCodeActions: function (model, position) { const actions = diagnostics .filter((check) => position.startLineNumber === check.location.row) @@ -61,7 +60,7 @@ export default function SourceEditor({ ? check.fix.message ? `${check.code}: ${check.fix.message}` : `Fix ${check.code}` - : "Autofix", + : "Fix", id: `fix-${check.code}`, kind: "quickfix", edit: check.fix @@ -69,7 +68,7 @@ export default function SourceEditor({ edits: check.fix.edits.map((edit) => ({ resource: model.uri, versionId: model.getVersionId(), - edit: { + textEdit: { range: { startLineNumber: edit.location.row, startColumn: edit.location.column, diff --git a/pyproject.toml b/pyproject.toml index 37c64f34ae4ff..e194ff3497030 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,14 +1,12 @@ [build-system] requires = ["maturin>=1.0,<2.0"] - build-backend = "maturin" [project] name = "ruff" -version = "0.0.291" +version = "0.1.3" description = "An extremely fast Python linter, written in Rust." -authors = [{ name = "Charlie Marsh", email = "charlie.r.marsh@gmail.com" }] -maintainers = [{ name = "Charlie Marsh", email = "charlie.r.marsh@gmail.com" }] +authors = [{ name = "Astral Software Inc.", email = "hey@astral.sh" }] readme = "README.md" requires-python = ">=3.7" license = { file = "LICENSE" } @@ -32,6 +30,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Rust", "Topic :: Software Development :: Libraries :: Python Modules", diff --git a/python/ruff-ecosystem/README.md b/python/ruff-ecosystem/README.md new file mode 100644 index 0000000000000..abc6be7e57ca1 --- /dev/null +++ b/python/ruff-ecosystem/README.md @@ -0,0 +1,46 @@ +# ruff-ecosystem + +Compare lint and format results for two different ruff versions (e.g. main and a PR) on real world projects. + +## Installation + +From the Ruff project root, install with `pip`: + +```shell +pip install -e ./python/ruff-ecosystem +``` + +## Usage + +```shell +ruff-ecosystem +``` + +Note executable paths may be absolute, relative to the current working directory, or will be looked up in the +current Python environment and PATH. + +Run `ruff check` ecosystem checks comparing your debug build to your system Ruff: + +```shell +ruff-ecosystem check ruff "./target/debug/ruff" +``` + +Run `ruff format` ecosystem checks comparing your debug build to your system Ruff: + +```shell +ruff-ecosystem format ruff "./target/debug/ruff" +``` + +## Development + +When developing, it can be useful to set the `--pdb` flag to drop into a debugger on failure: + +```shell +ruff-ecosystem check ruff "./target/debug/ruff" --pdb +``` + +You can also provide a path to cache checkouts to speed up repeated runs: + +```shell +ruff-ecosystem check ruff "./target/debug/ruff" --cache ./repos +``` diff --git a/python/ruff-ecosystem/pyproject.toml b/python/ruff-ecosystem/pyproject.toml new file mode 100644 index 0000000000000..8bff7a17060b8 --- /dev/null +++ b/python/ruff-ecosystem/pyproject.toml @@ -0,0 +1,15 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "ruff-ecosystem" +version = "0.0.0" +dependencies = ["unidiff==0.7.5"] + +[project.scripts] +ruff-ecosystem = "ruff_ecosystem.cli:entrypoint" + +[tool.ruff] +extend-select = ["I"] +preview = true diff --git a/python/ruff-ecosystem/ruff_ecosystem/__init__.py b/python/ruff-ecosystem/ruff_ecosystem/__init__.py new file mode 100644 index 0000000000000..883ecb9c74b23 --- /dev/null +++ b/python/ruff-ecosystem/ruff_ecosystem/__init__.py @@ -0,0 +1,3 @@ +import logging + +logger = logging.getLogger("ruff-ecosystem") diff --git a/python/ruff-ecosystem/ruff_ecosystem/__main__.py b/python/ruff-ecosystem/ruff_ecosystem/__main__.py new file mode 100644 index 0000000000000..bc1e7d2c79373 --- /dev/null +++ b/python/ruff-ecosystem/ruff_ecosystem/__main__.py @@ -0,0 +1,8 @@ +""" +Enables usage with `python -m ruff_ecosystem` +""" + +import ruff_ecosystem.cli + +if __name__ == "__main__": + ruff_ecosystem.cli.entrypoint() diff --git a/python/ruff-ecosystem/ruff_ecosystem/check.py b/python/ruff-ecosystem/ruff_ecosystem/check.py new file mode 100644 index 0000000000000..3e2462ffeb9bb --- /dev/null +++ b/python/ruff-ecosystem/ruff_ecosystem/check.py @@ -0,0 +1,563 @@ +""" +Execution, comparison, and summary of `ruff check` ecosystem checks. +""" +from __future__ import annotations + +import asyncio +import dataclasses +import re +import time +from asyncio import create_subprocess_exec +from collections import Counter +from dataclasses import dataclass, field +from pathlib import Path +from subprocess import PIPE +from typing import TYPE_CHECKING, Iterable, Iterator, Self, Sequence + +from ruff_ecosystem import logger +from ruff_ecosystem.markdown import ( + markdown_details, + markdown_plus_minus, + markdown_project_section, +) +from ruff_ecosystem.types import ( + Comparison, + Diff, + Result, + RuffError, + Serializable, +) + +if TYPE_CHECKING: + from ruff_ecosystem.projects import ClonedRepository, Project + + +# Matches lines that are summaries rather than diagnostics +CHECK_SUMMARY_LINE_RE = re.compile(r"^(Found \d+ error.*)|(.* fixable with .*)$") + +# Parses a diagnostic line (in a diff) to retrieve path and line number +CHECK_DIFF_LINE_RE = re.compile( + r"^(?P

[+-]) (?P(?P[^:]+):(?P\d+):\d+:) (?P.*)$",
+)
+
+CHECK_DIAGNOSTIC_LINE_RE = re.compile(
+    r"^(?P[+-])? ?(?P.*): (?P[A-Z]{1,4}[0-9]{3,4})(?P \[\*\])? (?P.*)"
+)
+
+CHECK_VIOLATION_FIX_INDICATOR = " [*]"
+
+GITHUB_MAX_COMMENT_LENGTH = 65536  # characters
+
+
+def markdown_check_result(result: Result) -> str:
+    """
+    Render a `ruff check` ecosystem check result as markdown.
+    """
+    # Calculate the total number of rule changes
+    all_rule_changes = RuleChanges()
+    project_diffs = {
+        project: CheckDiff.from_simple_diff(comparison.diff)
+        for project, comparison in result.completed
+    }
+    project_rule_changes: dict[Project, RuleChanges] = {}
+    for project, diff in project_diffs.items():
+        project_rule_changes[project] = changes = RuleChanges.from_diff(diff)
+        all_rule_changes.update(changes)
+
+    lines = []
+    total_removed = all_rule_changes.total_removed_violations()
+    total_added = all_rule_changes.total_added_violations()
+    total_added_fixes = all_rule_changes.total_added_fixes()
+    total_removed_fixes = all_rule_changes.total_removed_fixes()
+    total_changes = (
+        total_added + total_removed + total_added_fixes + total_removed_fixes
+    )
+    error_count = len(result.errored)
+    total_affected_rules = len(all_rule_changes.rule_codes())
+
+    if total_affected_rules == 0 and error_count == 0:
+        return "\u2705 ecosystem check detected no linter changes."
+
+    # Summarize the total changes
+    if total_affected_rules == 0:
+        # Only errors
+        s = "s" if error_count != 1 else ""
+        lines.append(
+            f"\u2139\ufe0f ecosystem check **encountered linter errors**. (no lint changes; {error_count} project error{s})"
+        )
+    else:
+        change_summary = (
+            f"{markdown_plus_minus(total_added, total_removed)} violations, "
+            f"{markdown_plus_minus(total_added_fixes, total_removed_fixes)} fixes "
+            f"in {len(result.completed)} projects"
+        )
+        if error_count:
+            s = "s" if error_count != 1 else ""
+            change_summary += f"; {error_count} project error{s}"
+        lines.append(
+            f"\u2139\ufe0f ecosystem check **detected linter changes**. ({change_summary})"
+        )
+    lines.append("")
+
+    # Display per project changes
+    for project, comparison in result.completed:
+        # TODO: This is not a performant way to check the length but the whole
+        #       GitHub comment length issue needs to be addressed anyway
+        if len(" ".join(lines)) > GITHUB_MAX_COMMENT_LENGTH // 3:
+            lines.append("")
+            lines.append(
+                "_... Truncated remaining completed projected reports due to GitHub comment length restrictions_"
+            )
+            lines.append("")
+            break
+
+        if not comparison.diff:
+            continue  # Skip empty diffs
+
+        diff = project_diffs[project]
+        rule_changes = project_rule_changes[project]
+        project_removed_violations = rule_changes.total_removed_violations()
+        project_added_violations = rule_changes.total_added_violations()
+        project_added_fixes = rule_changes.total_added_fixes()
+        project_removed_fixes = rule_changes.total_removed_fixes()
+        project_changes = (
+            project_added_violations
+            + project_removed_violations
+            + project_added_fixes
+            + project_removed_fixes
+        )
+
+        # Limit the number of items displayed per project to between 10 and 50
+        # based on the proportion of total changes present in this project
+        max_display_per_project = max(10, int((project_changes / total_changes) * 50))
+
+        # Limit the number of items displayed per rule to between 5 and the max for
+        # the project based on the number of rules affected (less rules, more per rule)
+        max_display_per_rule = max(
+            5, max_display_per_project // len(rule_changes.rule_codes())
+        )
+
+        # Display the diff
+        displayed_changes_per_rule = Counter()
+        displayed_changes = 0
+
+        # Wrap with `
` for code-styling with support for links
+        diff_lines = ["
"]
+        for line in diff.parsed_lines:
+            rule_code = line.rule_code
+
+            # Limit the number of changes we'll show per rule code
+            if displayed_changes_per_rule[rule_code] > max_display_per_rule:
+                continue
+
+            diff_lines.append(
+                add_permalink_to_diagnostic_line(comparison.repo, line.to_string())
+            )
+
+            displayed_changes_per_rule[rule_code] += 1
+            displayed_changes += 1
+
+            # If we just reached the maximum... display an omission line
+            if displayed_changes_per_rule[rule_code] > max_display_per_rule:
+                hidden_count = (
+                    rule_changes.added_violations[rule_code]
+                    + rule_changes.removed_violations[rule_code]
+                    + rule_changes.added_fixes[rule_code]
+                    + rule_changes.removed_fixes[rule_code]
+                    - max_display_per_rule
+                )
+                diff_lines.append(
+                    f"... {hidden_count} additional changes omitted for rule {rule_code}"
+                )
+
+            if displayed_changes >= max_display_per_project:
+                break
+
+        if project_changes > max_display_per_project:
+            hidden_count = project_changes - displayed_changes
+            diff_lines.append(
+                f"... {hidden_count} additional changes omitted for project"
+            )
+
+        diff_lines.append("
") + + title = ( + f"+{project_added_violations} " + f"-{project_removed_violations} violations, " + f"+{project_added_fixes} " + f"-{project_removed_fixes} fixes" + ) + + lines.extend( + markdown_project_section( + title=title, + content=diff_lines, + options=project.check_options, + project=project, + ) + ) + + for project, error in result.errored: + lines.extend( + markdown_project_section( + title="error", + content=f"```\n{error}```", + options=project.check_options, + project=project, + ) + ) + + # Display a summary table of changed rules + if all_rule_changes: + table_lines = [] + table_lines.append( + "| code | total | + violation | - violation | + fix | - fix |" + ) + table_lines.append("| ---- | ------- | --------- | -------- | ----- | ---- |") + for rule, total in sorted( + all_rule_changes.total_changes_by_rule(), + key=lambda item: item[1], # Sort by the total changes + reverse=True, + ): + added_violations, removed_violations, added_fixes, removed_fixes = ( + all_rule_changes.added_violations[rule], + all_rule_changes.removed_violations[rule], + all_rule_changes.added_fixes[rule], + all_rule_changes.removed_fixes[rule], + ) + table_lines.append( + f"| {rule} | {total} | {added_violations} | {removed_violations} " + f"| {added_fixes} | {removed_fixes} |" + ) + + lines.extend( + markdown_details( + summary=f"Changes by rule ({total_affected_rules} rules affected)", + preface="", + content=table_lines, + ) + ) + + return "\n".join(lines) + + +@dataclass(frozen=True) +class RuleChanges: + """ + The number of additions and removals by rule code. + + While the attributes are frozen to avoid accidentally changing the value of an attribute, + the counters themselves are mutable and this class can be mutated with `+` and `update`. + """ + + added_violations: Counter = field(default_factory=Counter) + removed_violations: Counter = field(default_factory=Counter) + added_fixes: Counter = field(default_factory=Counter) + removed_fixes: Counter = field(default_factory=Counter) + + def rule_codes(self) -> set[str]: + return ( + set(self.added_violations.keys()) + .union(self.removed_violations.keys()) + .union(self.added_fixes.keys()) + .union(self.removed_fixes.keys()) + ) + + def __add__(self, other: Self) -> Self: + if not isinstance(other, type(self)): + return NotImplemented + + new = type(self)() + new.update(self) + new.update(other) + return new + + def update(self, other: Self) -> Self: + self.added_violations.update(other.added_violations) + self.removed_violations.update(other.removed_violations) + self.added_fixes.update(other.added_fixes) + self.removed_fixes.update(other.removed_fixes) + return self + + def total_added_violations(self) -> int: + return sum(self.added_violations.values()) + + def total_removed_violations(self) -> int: + return sum(self.removed_violations.values()) + + def total_added_fixes(self) -> int: + return sum(self.added_fixes.values()) + + def total_removed_fixes(self) -> int: + return sum(self.removed_fixes.values()) + + def total_changes_by_rule(self) -> Iterator[tuple[str, int]]: + """ + Yields the sum of changes for each rule + """ + totals = Counter() + totals.update(self.added_violations) + totals.update(self.removed_violations) + totals.update(self.added_fixes) + totals.update(self.removed_fixes) + yield from totals.items() + + @classmethod + def from_diff(cls: type[Self], diff: CheckDiff) -> Self: + """ + Parse a diff from `ruff check` to determine the additions and removals for each rule + """ + rule_changes = cls() + + for line in diff.parsed_lines: + if line.is_added: + if line in diff.fix_only_lines: + if line.fix_available: + rule_changes.added_fixes[line.rule_code] += 1 + else: + rule_changes.removed_fixes[line.rule_code] += 1 + else: + rule_changes.added_violations[line.rule_code] += 1 + elif line.is_removed: + if line in diff.fix_only_lines: + if line.fix_available: + rule_changes.removed_fixes[line.rule_code] += 1 + else: + rule_changes.added_fixes[line.rule_code] += 1 + else: + rule_changes.removed_violations[line.rule_code] += 1 + + return rule_changes + + def __bool__(self): + return bool( + self.added_violations + or self.removed_violations + or self.added_fixes + or self.removed_fixes + ) + + +@dataclass(frozen=True) +class DiagnosticLine: + is_added: bool | None + is_removed: bool | None + fix_available: bool + rule_code: str + location: str + message: str + + def to_string(self) -> str: + """ + Construct the line from the components + """ + line = "" + if self.is_added: + line += "+ " + elif self.is_removed: + line += "- " + line += f"{self.location}: {self.rule_code} " + if self.fix_available: + line += "[*] " + line += self.message + return line + + def with_fix_available(self) -> DiagnosticLine: + return DiagnosticLine(**{**dataclasses.asdict(self), "fix_available": True}) + + def without_fix_available(self) -> DiagnosticLine: + return DiagnosticLine(**{**dataclasses.asdict(self), "fix_available": False}) + + def without_diff(self) -> DiagnosticLine: + return DiagnosticLine( + **{**dataclasses.asdict(self), "is_added": None, "is_removed": None} + ) + + @classmethod + def try_from_string(cls: type[Self], line: str) -> Self | None: + """ + Parse the rule code from a diagnostic line string + """ + match = CHECK_DIAGNOSTIC_LINE_RE.match(line) + + if match is None: + # Handle case where there are no regex match e.g. + # + "?application=AIRFLOW&authenticator=TEST_AUTH&role=TEST_ROLE&warehouse=TEST_WAREHOUSE" # noqa: E501, ERA001 + # Which was found in local testing + return None + + match_items = match.groupdict() + + return cls( + location=match_items["location"], + is_removed=match_items.get("diff") == "-", + is_added=match_items.get("diff") == "+", + fix_available=match_items.get("fixable") is not None, + rule_code=match_items["code"], + message=match_items["message"], + ) + + +class CheckDiff(Diff): + """ + Extends the normal diff with diagnostic parsing + """ + + def __init__( + self, + lines: Iterable[str], + parsed_lines: list[DiagnosticLine], + fix_only_lines: set[DiagnosticLine], + ) -> None: + self.parsed_lines = parsed_lines + self.fix_only_lines = fix_only_lines + super().__init__(lines) + + @classmethod + def from_simple_diff(cls, diff: Diff) -> CheckDiff: + """ + Parse a simple diff to include check-specific analyses. + """ + # Drop unchanged lines + diff = diff.without_unchanged_lines() + + # Sort without account for the leading + / - + sorted_lines = list(sorted(diff, key=lambda line: line[2:])) + + # Parse the lines, drop lines that cannot be parsed + parsed_lines: list[DiagnosticLine] = list( + filter( + None, + (DiagnosticLine.try_from_string(line) for line in sorted_lines), + ) + ) + + # Calculate which lines only changed fix availability + fix_only: set[DiagnosticLine] = set() + + # TODO(zanieb): There has to be a cleaner way to express this logic + # We check if each added line is available in the removed set with fix + # availability toggled and vice-versa + for line in parsed_lines: + other_set = diff.removed if line.is_added else diff.added + toggled = ( + line.without_fix_available() + if line.fix_available + else line.with_fix_available() + ) + if toggled.without_diff().to_string() in other_set: + fix_only.add(line) + + return CheckDiff( + lines=sorted_lines, parsed_lines=parsed_lines, fix_only_lines=fix_only + ) + + +def add_permalink_to_diagnostic_line(repo: ClonedRepository, line: str) -> str: + match = CHECK_DIFF_LINE_RE.match(line) + if match is None: + return line + + pre, inner, path, lnum, post = match.groups() + url = repo.url_for(path, int(lnum)) + return f"{pre} {inner} {post}" + + +async def compare_check( + ruff_baseline_executable: Path, + ruff_comparison_executable: Path, + options: CheckOptions, + cloned_repo: ClonedRepository, +) -> Comparison: + async with asyncio.TaskGroup() as tg: + baseline_task = tg.create_task( + ruff_check( + executable=ruff_baseline_executable.resolve(), + path=cloned_repo.path, + name=cloned_repo.fullname, + options=options, + ), + ) + comparison_task = tg.create_task( + ruff_check( + executable=ruff_comparison_executable.resolve(), + path=cloned_repo.path, + name=cloned_repo.fullname, + options=options, + ), + ) + + baseline_output, comparison_output = ( + baseline_task.result(), + comparison_task.result(), + ) + + diff = Diff.from_pair(baseline_output, comparison_output) + + return Comparison(diff=diff, repo=cloned_repo) + + +async def ruff_check( + *, executable: Path, path: Path, name: str, options: CheckOptions +) -> Sequence[str]: + """Run the given ruff binary against the specified path.""" + logger.debug(f"Checking {name} with {executable}") + ruff_args = options.to_cli_args() + + start = time.time() + proc = await create_subprocess_exec( + executable.absolute(), + *ruff_args, + ".", + stdout=PIPE, + stderr=PIPE, + cwd=path, + ) + result, err = await proc.communicate() + end = time.time() + + logger.debug(f"Finished checking {name} with {executable} in {end - start:.2f}s") + + if proc.returncode != 0: + raise RuffError(err.decode("utf8")) + + # Strip summary lines so the diff is only diagnostic lines + lines = [ + line + for line in result.decode("utf8").splitlines() + if not CHECK_SUMMARY_LINE_RE.match(line) + ] + + return lines + + +@dataclass(frozen=True) +class CheckOptions(Serializable): + """ + Ruff check options + """ + + select: str = "" + ignore: str = "" + exclude: str = "" + + # Generating fixes is slow and verbose + show_fixes: bool = False + + # Limit the number of reported lines per rule + max_lines_per_rule: int | None = 50 + + def markdown(self) -> str: + return f"select {self.select} ignore {self.ignore} exclude {self.exclude}" + + def to_cli_args(self) -> list[str]: + args = ["check", "--no-cache", "--exit-zero"] + if self.select: + args.extend(["--select", self.select]) + if self.ignore: + args.extend(["--ignore", self.ignore]) + if self.exclude: + args.extend(["--exclude", self.exclude]) + if self.show_fixes: + args.extend(["--show-fixes", "--ecosystem-ci"]) + return args diff --git a/python/ruff-ecosystem/ruff_ecosystem/cli.py b/python/ruff-ecosystem/ruff_ecosystem/cli.py new file mode 100644 index 0000000000000..348bab300d603 --- /dev/null +++ b/python/ruff-ecosystem/ruff_ecosystem/cli.py @@ -0,0 +1,166 @@ +import argparse +import asyncio +import logging +import os +import shutil +import sys +import sysconfig +import tempfile +from contextlib import nullcontext +from pathlib import Path +from signal import SIGINT, SIGTERM + +from ruff_ecosystem import logger +from ruff_ecosystem.defaults import DEFAULT_TARGETS +from ruff_ecosystem.main import OutputFormat, main +from ruff_ecosystem.projects import RuffCommand + + +def excepthook(type, value, tb): + if hasattr(sys, "ps1") or not sys.stderr.isatty(): + # we are in interactive mode or we don't have a tty so call the default + sys.__excepthook__(type, value, tb) + else: + import pdb + import traceback + + traceback.print_exception(type, value, tb) + print() + pdb.post_mortem(tb) + + +def entrypoint(): + args = parse_args() + + if args.pdb: + sys.excepthook = excepthook + + if args.verbose: + logging.basicConfig(level=logging.DEBUG) + else: + logging.basicConfig(level=logging.INFO) + + # Use a temporary directory for caching if no cache is specified + cache_context = ( + tempfile.TemporaryDirectory() if not args.cache else nullcontext(args.cache) + ) + + ruff_baseline = args.ruff_baseline + if not args.ruff_baseline.exists(): + ruff_baseline = get_executable_path(str(args.ruff_baseline)) + if not ruff_baseline: + print( + f"Could not find ruff baseline executable: {args.ruff_baseline}", + sys.stderr, + ) + exit(1) + logger.info( + "Resolved baseline executable %s to %s", args.ruff_baseline, ruff_baseline + ) + + ruff_comparison = args.ruff_comparison + if not args.ruff_comparison.exists(): + ruff_comparison = get_executable_path(str(args.ruff_comparison)) + if not ruff_comparison: + print( + f"Could not find ruff comparison executable: {args.ruff_comparison}", + sys.stderr, + ) + exit(1) + logger.info( + "Resolved comparison executable %s to %s", + args.ruff_comparison, + ruff_comparison, + ) + + with cache_context as cache: + loop = asyncio.get_event_loop() + main_task = asyncio.ensure_future( + main( + command=RuffCommand(args.ruff_command), + ruff_baseline_executable=ruff_baseline, + ruff_comparison_executable=ruff_comparison, + targets=DEFAULT_TARGETS, + format=OutputFormat(args.output_format), + project_dir=Path(cache), + raise_on_failure=args.pdb, + ) + ) + # https://stackoverflow.com/a/58840987/3549270 + for signal in [SIGINT, SIGTERM]: + loop.add_signal_handler(signal, main_task.cancel) + try: + loop.run_until_complete(main_task) + finally: + loop.close() + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description="Check two versions of ruff against a corpus of open-source code.", + ) + + # TODO: Support non-default `--targets` + # parser.add_argument( + # "--targets", + # type=Path, + # help=( + # "Optional JSON files to use over the default repositories. " + # "Supports both github_search_*.jsonl and known-github-tomls.jsonl." + # ), + # ) + parser.add_argument( + "--cache", + type=Path, + help="Location for caching cloned repositories", + ) + parser.add_argument( + "--output-format", + choices=[option.name for option in OutputFormat], + default="json", + help="Location for caching cloned repositories", + ) + parser.add_argument( + "-v", + "--verbose", + action="store_true", + help="Enable debug logging", + ) + parser.add_argument( + "--pdb", + action="store_true", + help="Enable debugging on failure", + ) + parser.add_argument( + "ruff_command", + choices=[option.name for option in RuffCommand], + help="The Ruff command to test", + ) + parser.add_argument( + "ruff_baseline", + type=Path, + ) + parser.add_argument( + "ruff_comparison", + type=Path, + ) + + return parser.parse_args() + + +def get_executable_path(name: str) -> Path | None: + # Add suffix for Windows executables + name += ".exe" if sys.platform == "win32" and not name.endswith(".exe") else "" + + path = os.path.join(sysconfig.get_path("scripts"), name) + + # The executable in the current interpreter's scripts directory. + if os.path.exists(path): + return Path(path) + + # The executable in the global environment. + environment_path = shutil.which(name) + if environment_path: + return Path(environment_path) + + return None diff --git a/python/ruff-ecosystem/ruff_ecosystem/defaults.py b/python/ruff-ecosystem/ruff_ecosystem/defaults.py new file mode 100644 index 0000000000000..16db062715356 --- /dev/null +++ b/python/ruff-ecosystem/ruff_ecosystem/defaults.py @@ -0,0 +1,73 @@ +""" +Default projects for ecosystem checks +""" +from ruff_ecosystem.projects import CheckOptions, FormatOptions, Project, Repository + +# TODO(zanieb): Consider exporting this as JSON and loading from there instead +DEFAULT_TARGETS = [ + Project(repo=Repository(owner="DisnakeDev", name="disnake", ref="master")), + Project(repo=Repository(owner="PostHog", name="HouseWatch", ref="main")), + Project(repo=Repository(owner="RasaHQ", name="rasa", ref="main")), + Project(repo=Repository(owner="Snowflake-Labs", name="snowcli", ref="main")), + Project(repo=Repository(owner="aiven", name="aiven-client", ref="main")), + Project(repo=Repository(owner="alteryx", name="featuretools", ref="main")), + Project( + repo=Repository(owner="apache", name="airflow", ref="main"), + check_options=CheckOptions(select="ALL"), + ), + Project(repo=Repository(owner="aws", name="aws-sam-cli", ref="develop")), + Project(repo=Repository(owner="bloomberg", name="pytest-memray", ref="main")), + Project( + repo=Repository(owner="bokeh", name="bokeh", ref="branch-3.3"), + check_options=CheckOptions(select="ALL"), + ), + Project(repo=Repository(owner="commaai", name="openpilot", ref="master")), + Project( + repo=Repository(owner="demisto", name="content", ref="master"), + format_options=FormatOptions( + # Syntax errors in this file + exclude="Packs/ThreatQ/Integrations/ThreatQ/ThreatQ.py" + ), + ), + Project(repo=Repository(owner="docker", name="docker-py", ref="main")), + Project(repo=Repository(owner="freedomofpress", name="securedrop", ref="develop")), + Project(repo=Repository(owner="fronzbot", name="blinkpy", ref="dev")), + Project(repo=Repository(owner="ibis-project", name="ibis", ref="master")), + Project(repo=Repository(owner="ing-bank", name="probatus", ref="main")), + Project(repo=Repository(owner="jrnl-org", name="jrnl", ref="develop")), + Project(repo=Repository(owner="latchbio", name="latch", ref="main")), + Project(repo=Repository(owner="lnbits", name="lnbits", ref="main")), + Project(repo=Repository(owner="milvus-io", name="pymilvus", ref="master")), + Project(repo=Repository(owner="mlflow", name="mlflow", ref="master")), + Project(repo=Repository(owner="model-bakers", name="model_bakery", ref="main")), + Project(repo=Repository(owner="pandas-dev", name="pandas", ref="main")), + Project(repo=Repository(owner="prefecthq", name="prefect", ref="main")), + Project(repo=Repository(owner="pypa", name="build", ref="main")), + Project(repo=Repository(owner="pypa", name="cibuildwheel", ref="main")), + Project(repo=Repository(owner="pypa", name="pip", ref="main")), + Project(repo=Repository(owner="pypa", name="setuptools", ref="main")), + Project(repo=Repository(owner="python", name="mypy", ref="master")), + Project( + repo=Repository( + owner="python", + name="typeshed", + ref="main", + ), + check_options=CheckOptions(select="PYI"), + ), + Project(repo=Repository(owner="python-poetry", name="poetry", ref="master")), + Project(repo=Repository(owner="reflex-dev", name="reflex", ref="main")), + Project(repo=Repository(owner="rotki", name="rotki", ref="develop")), + Project(repo=Repository(owner="scikit-build", name="scikit-build", ref="main")), + Project( + repo=Repository(owner="scikit-build", name="scikit-build-core", ref="main") + ), + Project(repo=Repository(owner="sphinx-doc", name="sphinx", ref="master")), + Project(repo=Repository(owner="spruceid", name="siwe-py", ref="main")), + Project(repo=Repository(owner="tiangolo", name="fastapi", ref="master")), + Project(repo=Repository(owner="yandex", name="ch-backup", ref="main")), + Project( + repo=Repository(owner="zulip", name="zulip", ref="main"), + check_options=CheckOptions(select="ALL"), + ), +] diff --git a/python/ruff-ecosystem/ruff_ecosystem/format.py b/python/ruff-ecosystem/ruff_ecosystem/format.py new file mode 100644 index 0000000000000..686515521e544 --- /dev/null +++ b/python/ruff-ecosystem/ruff_ecosystem/format.py @@ -0,0 +1,195 @@ +""" +Execution, comparison, and summary of `ruff format` ecosystem checks. +""" + +from __future__ import annotations + +import time +from asyncio import create_subprocess_exec +from dataclasses import dataclass +from pathlib import Path +from subprocess import PIPE +from typing import TYPE_CHECKING, Sequence + +from unidiff import PatchSet + +from ruff_ecosystem import logger +from ruff_ecosystem.markdown import markdown_project_section +from ruff_ecosystem.types import Comparison, Diff, Result, RuffError + +if TYPE_CHECKING: + from ruff_ecosystem.projects import ClonedRepository + + +def markdown_format_result(result: Result) -> str: + """ + Render a `ruff format` ecosystem check result as markdown. + """ + lines = [] + total_lines_removed = total_lines_added = 0 + total_files_modified = 0 + error_count = len(result.errored) + patch_sets = [] + + for project, comparison in result.completed: + total_lines_added += comparison.diff.lines_added + total_lines_removed += comparison.diff.lines_removed + + patch_set = PatchSet("\n".join(comparison.diff.lines)) + patch_sets.append(patch_set) + total_files_modified += len(patch_set.modified_files) + + if total_lines_removed == 0 and total_lines_added == 0 and error_count == 0: + return "\u2705 ecosystem check detected no format changes." + + # Summarize the total changes + if total_lines_added == 0 and total_lines_added == 0: + # Only errors + s = "s" if error_count != 1 else "" + lines.append( + f"\u2139\ufe0f ecosystem check **encountered format errors**. (no format changes; {error_count} project error{s})" + ) + else: + s = "s" if total_files_modified != 1 else "" + changes = f"+{total_lines_added} -{total_lines_removed} lines in {total_files_modified} file{s} in {len(result.completed)} projects" + if error_count: + s = "s" if error_count != 1 else "" + changes += f"; {error_count} project error{s}" + + lines.append( + f"\u2139\ufe0f ecosystem check **detected format changes**. ({changes})" + ) + + lines.append("") + + # Then per-project changes + for (project, comparison), patch_set in zip(result.completed, patch_sets): + if not comparison.diff: + continue # Skip empty diffs + + files = len(patch_set.modified_files) + s = "s" if files != 1 else "" + title = f"+{comparison.diff.lines_added} -{comparison.diff.lines_removed} lines across {files} file{s}" + + lines.extend( + markdown_project_section( + title=title, + content=format_patchset(patch_set, comparison.repo), + options=project.format_options, + project=project, + ) + ) + + for project, error in result.errored: + lines.extend( + markdown_project_section( + title="error", + content=f"```\n{error}```", + options=project.format_options, + project=project, + ) + ) + + return "\n".join(lines) + + +def format_patchset(patch_set: PatchSet, repo: ClonedRepository) -> str: + """ + Convert a patchset to markdown, adding permalinks to the start of each hunk. + """ + lines = [] + for file_patch in patch_set: + for hunk in file_patch: + # Note: When used for `format` checks, the line number is not exact because + # we formatted the repository for a baseline; we can't know the exact + # line number in the original + # source file. + hunk_link = repo.url_for(file_patch.path, hunk.source_start) + hunk_lines = str(hunk).splitlines() + + # Add a link before the hunk + link_title = file_patch.path + "~L" + str(hunk.source_start) + lines.append(f"{link_title}") + + # Wrap the contents of the hunk in a diff code block + lines.append("```diff") + lines.extend(hunk_lines[1:]) + lines.append("```") + + return "\n".join(lines) + + +async def compare_format( + ruff_baseline_executable: Path, + ruff_comparison_executable: Path, + options: FormatOptions, + cloned_repo: ClonedRepository, +): + # Run format without diff to get the baseline + await ruff_format( + executable=ruff_baseline_executable.resolve(), + path=cloned_repo.path, + name=cloned_repo.fullname, + options=options, + ) + # Then get the diff from stdout + diff = await ruff_format( + executable=ruff_comparison_executable.resolve(), + path=cloned_repo.path, + name=cloned_repo.fullname, + options=options, + diff=True, + ) + + return Comparison(diff=Diff(diff), repo=cloned_repo) + + +async def ruff_format( + *, + executable: Path, + path: Path, + name: str, + options: FormatOptions, + diff: bool = False, +) -> Sequence[str]: + """Run the given ruff binary against the specified path.""" + logger.debug(f"Formatting {name} with {executable}") + ruff_args = options.to_cli_args() + + if diff: + ruff_args.append("--diff") + + start = time.time() + proc = await create_subprocess_exec( + executable.absolute(), + *ruff_args, + ".", + stdout=PIPE, + stderr=PIPE, + cwd=path, + ) + result, err = await proc.communicate() + end = time.time() + + logger.debug(f"Finished formatting {name} with {executable} in {end - start:.2f}s") + + if proc.returncode not in [0, 1]: + raise RuffError(err.decode("utf8")) + + lines = result.decode("utf8").splitlines() + return lines + + +@dataclass(frozen=True) +class FormatOptions: + """ + Ruff format options. + """ + + exclude: str = "" + + def to_cli_args(self) -> list[str]: + args = ["format"] + if self.exclude: + args.extend(["--exclude", self.exclude]) + return args diff --git a/python/ruff-ecosystem/ruff_ecosystem/main.py b/python/ruff-ecosystem/ruff_ecosystem/main.py new file mode 100644 index 0000000000000..b44a5caf34d4b --- /dev/null +++ b/python/ruff-ecosystem/ruff_ecosystem/main.py @@ -0,0 +1,144 @@ +import asyncio +import dataclasses +import json +from enum import Enum +from pathlib import Path +from typing import Awaitable, TypeVar + +from ruff_ecosystem import logger +from ruff_ecosystem.check import compare_check, markdown_check_result +from ruff_ecosystem.format import compare_format, markdown_format_result +from ruff_ecosystem.projects import ( + Project, + RuffCommand, +) +from ruff_ecosystem.types import Comparison, Result, Serializable + +T = TypeVar("T") +GITHUB_MAX_COMMENT_LENGTH = 65536 + + +class OutputFormat(Enum): + markdown = "markdown" + json = "json" + + +async def main( + command: RuffCommand, + ruff_baseline_executable: Path, + ruff_comparison_executable: Path, + targets: list[Project], + project_dir: Path, + format: OutputFormat, + max_parallelism: int = 50, + raise_on_failure: bool = False, +) -> None: + logger.debug("Using command %s", command.value) + logger.debug("Using baseline executable at %s", ruff_baseline_executable) + logger.debug("Using comparison executable at %s", ruff_comparison_executable) + logger.debug("Using checkout_dir directory %s", project_dir) + logger.debug("Checking %s targets", len(targets)) + + # Limit parallelism to avoid high memory consumption + semaphore = asyncio.Semaphore(max_parallelism) + + async def limited_parallelism(coroutine: Awaitable[T]) -> T: + async with semaphore: + return await coroutine + + comparisons: list[Exception | Comparison] = await asyncio.gather( + *[ + limited_parallelism( + clone_and_compare( + command, + ruff_baseline_executable, + ruff_comparison_executable, + target, + project_dir, + ) + ) + for target in targets + ], + return_exceptions=not raise_on_failure, + ) + comparisons_by_target = dict(zip(targets, comparisons, strict=True)) + + # Split comparisons into errored / completed + errored, completed = [], [] + for target, comparison in comparisons_by_target.items(): + if isinstance(comparison, Exception): + errored.append((target, comparison)) + else: + completed.append((target, comparison)) + + result = Result(completed=completed, errored=errored) + + match format: + case OutputFormat.json: + print(json.dumps(result, indent=4, cls=JSONEncoder)) + case OutputFormat.markdown: + match command: + case RuffCommand.check: + print(markdown_check_result(result)) + case RuffCommand.format: + print(markdown_format_result(result)) + case _: + raise ValueError(f"Unknown target Ruff command {command}") + case _: + raise ValueError(f"Unknown output format {format}") + + return None + + +async def clone_and_compare( + command: RuffCommand, + ruff_baseline_executable: Path, + ruff_comparison_executable: Path, + target: Project, + project_dir: Path, +) -> Comparison: + """Check a specific repository against two versions of ruff.""" + assert ":" not in target.repo.owner + assert ":" not in target.repo.name + + match command: + case RuffCommand.check: + compare, options = ( + compare_check, + target.check_options, + ) + case RuffCommand.format: + compare, options = ( + compare_format, + target.format_options, + ) + case _: + raise ValueError(f"Unknown target Ruff command {command}") + + checkout_dir = project_dir.joinpath(f"{target.repo.owner}:{target.repo.name}") + cloned_repo = await target.repo.clone(checkout_dir) + + try: + return await compare( + ruff_baseline_executable, + ruff_comparison_executable, + options, + cloned_repo, + ) + except ExceptionGroup as e: + raise e.exceptions[0] from e + + +class JSONEncoder(json.JSONEncoder): + def default(self, o): + if isinstance(o, Serializable): + return o.jsonable() + if dataclasses.is_dataclass(o): + return dataclasses.asdict(o) + if isinstance(o, set): + return tuple(o) + if isinstance(o, Path): + return str(o) + if isinstance(o, Exception): + return str(o) + return super().default(o) diff --git a/python/ruff-ecosystem/ruff_ecosystem/markdown.py b/python/ruff-ecosystem/ruff_ecosystem/markdown.py new file mode 100644 index 0000000000000..80f11f0cb2950 --- /dev/null +++ b/python/ruff-ecosystem/ruff_ecosystem/markdown.py @@ -0,0 +1,44 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from ruff_ecosystem.projects import Project + + +def markdown_project_section( + title: str, content: str | list[str], options: object, project: Project +) -> list[str]: + return markdown_details( + summary=f'{project.repo.fullname} ({title})', + # Show the command used for the check + preface="
ruff " + " ".join(options.to_cli_args()) + "
", + content=content, + ) + + +def markdown_plus_minus(added: int, removed: int) -> str: + # TODO(zanieb): GitHub does not support coloring with it seems like the only + # way is to use LateX `${\text{\color{green}+10 \color{red}-10}}$` but + # it renders so ugly it's not worth doing yet + return f"+{added} -{removed}" + + +def markdown_details(summary: str, preface: str, content: str | list[str]): + lines = [] + lines.append(f"
{summary}") + lines.append("

") + lines.append(preface) + lines.append("

") + lines.append("

") + lines.append("") + + if isinstance(content, str): + lines.append(content) + else: + lines.extend(content) + + lines.append("") + lines.append("

") + lines.append("
") + return lines diff --git a/python/ruff-ecosystem/ruff_ecosystem/projects.py b/python/ruff-ecosystem/ruff_ecosystem/projects.py new file mode 100644 index 0000000000000..deb140856c108 --- /dev/null +++ b/python/ruff-ecosystem/ruff_ecosystem/projects.py @@ -0,0 +1,168 @@ +""" +Abstractions and utilities for working with projects to run ecosystem checks on. +""" + +from __future__ import annotations + +from asyncio import create_subprocess_exec +from dataclasses import dataclass, field +from enum import Enum +from pathlib import Path +from subprocess import PIPE +from typing import Self + +from ruff_ecosystem import logger +from ruff_ecosystem.check import CheckOptions +from ruff_ecosystem.format import FormatOptions +from ruff_ecosystem.types import Serializable + + +@dataclass(frozen=True) +class Project(Serializable): + """ + An ecosystem target + """ + + repo: Repository + check_options: CheckOptions = field(default_factory=lambda: CheckOptions()) + format_options: FormatOptions = field(default_factory=lambda: FormatOptions()) + + +class RuffCommand(Enum): + check = "check" + format = "format" + + +class ProjectSetupError(Exception): + """An error setting up a project.""" + + +@dataclass(frozen=True) +class Repository(Serializable): + """ + A remote GitHub repository. + """ + + owner: str + name: str + ref: str | None + + @property + def fullname(self) -> str: + return f"{self.owner}/{self.name}" + + @property + def url(self: Self) -> str: + return f"https://github.com/{self.owner}/{self.name}" + + async def clone(self: Self, checkout_dir: Path) -> ClonedRepository: + """ + Shallow clone this repository + """ + if checkout_dir.exists(): + logger.debug(f"Reusing {self.owner}:{self.name}") + + if self.ref: + logger.debug(f"Checking out ref {self.ref}") + process = await create_subprocess_exec( + *["git", "checkout", "-f", self.ref], + cwd=checkout_dir, + env={"GIT_TERMINAL_PROMPT": "0"}, + stdout=PIPE, + stderr=PIPE, + ) + if await process.wait() != 0: + _, stderr = await process.communicate() + raise ProjectSetupError( + f"Failed to checkout {self.ref}: {stderr.decode()}" + ) + + return await ClonedRepository.from_path(checkout_dir, self) + + logger.debug(f"Cloning {self.owner}:{self.name} to {checkout_dir}") + command = [ + "git", + "clone", + "--config", + "advice.detachedHead=false", + "--quiet", + "--depth", + "1", + "--no-tags", + ] + if self.ref: + command.extend(["--branch", self.ref]) + + command.extend( + [ + f"https://github.com/{self.owner}/{self.name}", + str(checkout_dir), + ], + ) + + process = await create_subprocess_exec( + *command, env={"GIT_TERMINAL_PROMPT": "0"} + ) + + status_code = await process.wait() + + logger.debug( + f"Finished cloning {self.fullname} with status {status_code}", + ) + return await ClonedRepository.from_path(checkout_dir, self) + + +@dataclass(frozen=True) +class ClonedRepository(Repository, Serializable): + """ + A cloned GitHub repository, which includes the hash of the current commit. + """ + + commit_hash: str + path: Path + + def url_for( + self: Self, + path: str, + line_number: int | None = None, + end_line_number: int | None = None, + ) -> str: + """ + Return the remote GitHub URL for the given path in this repository. + """ + url = f"https://github.com/{self.owner}/{self.name}/blob/{self.commit_hash}/{path}" + if line_number: + url += f"#L{line_number}" + if end_line_number: + url += f"-L{end_line_number}" + return url + + @property + def url(self: Self) -> str: + return f"https://github.com/{self.owner}/{self.name}@{self.commit_hash}" + + @classmethod + async def from_path(cls, path: Path, repo: Repository): + return cls( + name=repo.name, + owner=repo.owner, + ref=repo.ref, + path=path, + commit_hash=await cls._get_head_commit(path), + ) + + @staticmethod + async def _get_head_commit(checkout_dir: Path) -> str: + """ + Return the commit sha for the repository in the checkout directory. + """ + process = await create_subprocess_exec( + *["git", "rev-parse", "HEAD"], + cwd=checkout_dir, + stdout=PIPE, + ) + stdout, _ = await process.communicate() + if await process.wait() != 0: + raise ProjectSetupError(f"Failed to retrieve commit sha at {checkout_dir}") + + return stdout.decode().strip() diff --git a/python/ruff-ecosystem/ruff_ecosystem/types.py b/python/ruff-ecosystem/ruff_ecosystem/types.py new file mode 100644 index 0000000000000..e2a36d8f86176 --- /dev/null +++ b/python/ruff-ecosystem/ruff_ecosystem/types.py @@ -0,0 +1,93 @@ +from __future__ import annotations + +import abc +import dataclasses +import difflib +from dataclasses import dataclass, is_dataclass +from typing import TYPE_CHECKING, Any, Generator, Iterable, Sequence + +if TYPE_CHECKING: + from ruff_ecosystem.projects import ClonedRepository, Project + + +class Serializable(abc.ABC): + """ + Allows serialization of content by casting to a JSON-compatible type. + """ + + def jsonable(self) -> Any: + # Default implementation for dataclasses + if is_dataclass(self) and not isinstance(self, type): + return dataclasses.asdict(self) + + raise NotImplementedError() + + +class Diff(Serializable): + def __init__(self, lines: Iterable[str], leading_spaces: int = 0) -> None: + self.lines = list(lines) + + # Compute added and removed lines once + self.added = list( + line[2:] + for line in self.lines + if line.startswith("+" + " " * leading_spaces) + ) + self.removed = list( + line[2:] + for line in self.lines + if line.startswith("-" + " " * leading_spaces) + ) + + def __bool__(self) -> bool: + return bool(self.added or self.removed) + + def __iter__(self) -> Generator[str, None, None]: + yield from self.lines + + @property + def lines_added(self): + return len(self.added) + + @property + def lines_removed(self): + return len(self.removed) + + @classmethod + def from_pair(cls, baseline: Sequence[str], comparison: Sequence[str]): + """ + Construct a diff from before and after. + """ + return cls(difflib.ndiff(baseline, comparison), leading_spaces=1) + + def without_unchanged_lines(self) -> Diff: + return Diff( + line for line in self.lines if line.startswith("+") or line.startswith("-") + ) + + def jsonable(self) -> Any: + return self.lines + + +@dataclass(frozen=True) +class Result(Serializable): + """ + The result of an ecosystem check for a collection of projects. + """ + + errored: list[tuple[Project, Exception]] + completed: list[tuple[Project, Comparison]] + + +@dataclass(frozen=True) +class Comparison(Serializable): + """ + The result of a completed ecosystem comparison for a single project. + """ + + diff: Diff + repo: ClonedRepository + + +class RuffError(Exception): + """An error reported by Ruff.""" diff --git a/ruff.schema.json b/ruff.schema.json index 07d35210b27b5..121211d0e3583 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -40,7 +40,7 @@ ] }, "exclude": { - "description": "A list of file patterns to exclude from linting.\n\nExclusions are based on globs, and can be either:\n\n- Single-path patterns, like `.mypy_cache` (to exclude any directory named `.mypy_cache` in the tree), `foo.py` (to exclude any file named `foo.py`), or `foo_*.py` (to exclude any file matching `foo_*.py` ). - Relative patterns, like `directory/foo.py` (to exclude that specific file) or `directory/*.py` (to exclude any Python files in `directory`). Note that these paths are relative to the project root (e.g., the directory containing your `pyproject.toml`).\n\nFor more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax).\n\nNote that you'll typically want to use [`extend-exclude`](#extend-exclude) to modify the excluded paths.", + "description": "A list of file patterns to exclude from formatting and linting.\n\nExclusions are based on globs, and can be either:\n\n- Single-path patterns, like `.mypy_cache` (to exclude any directory named `.mypy_cache` in the tree), `foo.py` (to exclude any file named `foo.py`), or `foo_*.py` (to exclude any file matching `foo_*.py` ). - Relative patterns, like `directory/foo.py` (to exclude that specific file) or `directory/*.py` (to exclude any Python files in `directory`). Note that these paths are relative to the project root (e.g., the directory containing your `pyproject.toml`).\n\nFor more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax).\n\nNote that you'll typically want to use [`extend-exclude`](#extend-exclude) to modify the excluded paths.", "type": [ "array", "null" @@ -49,6 +49,13 @@ "type": "string" } }, + "explicit-preview-rules": { + "description": "Whether to require exact codes to select preview rules. When enabled, preview rules will not be selected by prefixes — the full code of each preview rule will be required to enable the rule.", + "type": [ + "boolean", + "null" + ] + }, "extend": { "description": "A path to a local `pyproject.toml` file to merge into this configuration. User home directory and environment variables will be expanded.\n\nTo resolve the current `pyproject.toml` file, Ruff will first resolve this base configuration file, then merge in any properties defined in the current configuration file.", "type": [ @@ -57,7 +64,7 @@ ] }, "extend-exclude": { - "description": "A list of file patterns to omit from linting, in addition to those specified by `exclude`.\n\nExclusions are based on globs, and can be either:\n\n- Single-path patterns, like `.mypy_cache` (to exclude any directory named `.mypy_cache` in the tree), `foo.py` (to exclude any file named `foo.py`), or `foo_*.py` (to exclude any file matching `foo_*.py` ). - Relative patterns, like `directory/foo.py` (to exclude that specific file) or `directory/*.py` (to exclude any Python files in `directory`). Note that these paths are relative to the project root (e.g., the directory containing your `pyproject.toml`).\n\nFor more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax).", + "description": "A list of file patterns to omit from formatting and linting, in addition to those specified by `exclude`.\n\nExclusions are based on globs, and can be either:\n\n- Single-path patterns, like `.mypy_cache` (to exclude any directory named `.mypy_cache` in the tree), `foo.py` (to exclude any file named `foo.py`), or `foo_*.py` (to exclude any file matching `foo_*.py` ). - Relative patterns, like `directory/foo.py` (to exclude that specific file) or `directory/*.py` (to exclude any Python files in `directory`). Note that these paths are relative to the project root (e.g., the directory containing your `pyproject.toml`).\n\nFor more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax).", "type": [ "array", "null" @@ -67,7 +74,18 @@ } }, "extend-fixable": { - "description": "A list of rule codes or prefixes to consider autofixable, in addition to those specified by `fixable`.", + "description": "A list of rule codes or prefixes to consider fixable, in addition to those specified by `fixable`.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/RuleSelector" + } + }, + "extend-ignore": { + "description": "A list of rule codes or prefixes to ignore, in addition to those specified by `ignore`.", + "deprecated": true, "type": [ "array", "null" @@ -99,6 +117,16 @@ } } }, + "extend-safe-fixes": { + "description": "A list of rule codes or prefixes for which unsafe fixes should be considered safe.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/RuleSelector" + } + }, "extend-select": { "description": "A list of rule codes or prefixes to enable, in addition to those specified by `select`.", "type": [ @@ -109,8 +137,29 @@ "$ref": "#/definitions/RuleSelector" } }, + "extend-unfixable": { + "description": "A list of rule codes or prefixes to consider non-auto-fixable, in addition to those specified by `unfixable`.", + "deprecated": true, + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/RuleSelector" + } + }, + "extend-unsafe-fixes": { + "description": "A list of rule codes or prefixes for which safe fixes should be considered unsafe.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/RuleSelector" + } + }, "external": { - "description": "A list of rule codes that are unsupported by Ruff, but should be preserved when (e.g.) validating `# noqa` directives. Useful for retaining `# noqa` directives that cover plugins not yet implemented by Ruff.", + "description": "A list of rule codes or prefixes that are unsupported by Ruff, but should be preserved when (e.g.) validating `# noqa` directives. Useful for retaining `# noqa` directives that cover plugins not yet implemented by Ruff.", "type": [ "array", "null" @@ -120,7 +169,7 @@ } }, "fix": { - "description": "Enable autofix behavior by-default when running `ruff` (overridden by the `--fix` and `--no-fix` command-line flags).", + "description": "Enable fix behavior by-default when running `ruff` (overridden by the `--fix` and `--no-fix` command-line flags). Only includes automatic fixes unless `--unsafe-fixes` is provided.", "type": [ "boolean", "null" @@ -134,7 +183,7 @@ ] }, "fixable": { - "description": "A list of rule codes or prefixes to consider autofixable. By default, all rules are considered autofixable.", + "description": "A list of rule codes or prefixes to consider fixable. By default, all rules are considered fixable.", "type": [ "array", "null" @@ -327,10 +376,10 @@ ] }, "format": { - "description": "Options to configure the code formatting.\n\nPreviously: The style in which violation messages should be formatted: `\"text\"` (default), `\"grouped\"` (group messages by file), `\"json\"` (machine-readable), `\"junit\"` (machine-readable XML), `\"github\"` (GitHub Actions annotations), `\"gitlab\"` (GitLab CI code quality report), `\"pylint\"` (Pylint text format) or `\"azure\"` (Azure Pipeline logging commands).\n\nThis option has been **deprecated** in favor of `output-format` to avoid ambiguity with Ruff's upcoming formatter.", + "description": "Options to configure code formatting.", "anyOf": [ { - "$ref": "#/definitions/FormatOrOutputFormat" + "$ref": "#/definitions/FormatOptions" }, { "type": "null" @@ -364,6 +413,17 @@ "type": "string" } }, + "indent-width": { + "description": "The number of spaces per indentation level (tab).\n\nUsed by the formatter and when enforcing long-line violations (like `E501`) to determine the visual width of a tab.\n\nThis option changes the number of spaces the formatter inserts when using soft-tabs (`indent-style = space`).\n\nPEP 8 recommends using 4 spaces per [indentation level](https://peps.python.org/pep-0008/#indentation).", + "anyOf": [ + { + "$ref": "#/definitions/IndentWidth" + }, + { + "type": "null" + } + ] + }, "isort": { "description": "Options for the `isort` plugin.", "anyOf": [ @@ -376,7 +436,7 @@ ] }, "line-length": { - "description": "The line length to use when enforcing long-lines violations (like `E501`). Must be greater than `0` and less than or equal to `320`.", + "description": "The line length to use when enforcing long-lines violations (like `E501`) and at which `isort` and the formatter prefers to wrap lines.\n\nThe length is determined by the number of characters per line, except for lines containing East Asian characters or emojis. For these lines, the [unicode width](https://unicode.org/reports/tr11/) of each character is added up to determine the length.\n\nThe value must be greater than `0` and less than or equal to `320`.\n\nNote: While the formatter will attempt to format lines such that they remain within the `line-length`, it isn't a hard upper bound, and formatted lines may exceed the `line-length`.\n\nSee [`pycodestyle.max-line-length`](#pycodestyle-max-line-length) to configure different lengths for `E501` and the formatter.", "anyOf": [ { "$ref": "#/definitions/LineLength" @@ -384,9 +444,17 @@ { "type": "null" } - ], - "maximum": 320.0, - "minimum": 1.0 + ] + }, + "lint": { + "anyOf": [ + { + "$ref": "#/definitions/LintOptions" + }, + { + "type": "null" + } + ] }, "logger-objects": { "description": "A list of objects that should be treated equivalently to a `logging.Logger` object.\n\nThis is useful for ensuring proper diagnostics (e.g., to identify `logging` deprecations and other best-practices) for projects that re-export a `logging.Logger` object from a common module.\n\nFor example, if you have a module `logging_setup.py` with the following contents: ```python import logging\n\nlogger = logging.getLogger(__name__) ```\n\nAdding `\"logging_setup.logger\"` to `logger-objects` will ensure that `logging_setup.logger` is treated as a `logging.Logger` object when imported from other modules (e.g., `from logging_setup import logger`).", @@ -455,7 +523,7 @@ } }, "preview": { - "description": "Whether to enable preview mode. When preview mode is enabled, Ruff will use unstable rules and fixes.", + "description": "Whether to enable preview mode. When preview mode is enabled, Ruff will use unstable rules, fixes, and formatting.", "type": [ "boolean", "null" @@ -545,7 +613,7 @@ } }, "show-fixes": { - "description": "Whether to show an enumeration of all autofixed lint violations (overridden by the `--show-fixes` command-line flag).", + "description": "Whether to show an enumeration of all fixed lint violations (overridden by the `--show-fixes` command-line flag).", "type": [ "boolean", "null" @@ -569,10 +637,11 @@ } }, "tab-size": { - "description": "The tabulation size to calculate line length.", + "description": "The number of spaces a tab is equal to when enforcing long-line violations (like `E501`) or formatting code with the formatter.\n\nThis option changes the number of spaces inserted by the formatter when using soft-tabs (`indent-style = space`).", + "deprecated": true, "anyOf": [ { - "$ref": "#/definitions/TabSize" + "$ref": "#/definitions/IndentWidth" }, { "type": "null" @@ -611,7 +680,7 @@ } }, "unfixable": { - "description": "A list of rule codes or prefixes to consider non-autofix-able.", + "description": "A list of rule codes or prefixes to consider non-fixable.", "type": [ "array", "null" @@ -619,6 +688,13 @@ "items": { "$ref": "#/definitions/RuleSelector" } + }, + "unsafe-fixes": { + "description": "Enable application of unsafe fixes.", + "type": [ + "boolean", + "null" + ] } }, "additionalProperties": false, @@ -643,8 +719,7 @@ "complex", "float", "int", - "str", - "tuple" + "str" ] }, "Convention": { @@ -1008,7 +1083,7 @@ ] }, "docstring-quotes": { - "description": "Quote style to prefer for docstrings (either \"single\" or \"double\").", + "description": "Quote style to prefer for docstrings (either \"single\" or \"double\").\n\nWhen using the formatter, only \"double\" is compatible, as the formatter enforces double quotes for docstrings strings.", "anyOf": [ { "$ref": "#/definitions/Quote" @@ -1019,7 +1094,7 @@ ] }, "inline-quotes": { - "description": "Quote style to prefer for inline strings (either \"single\" or \"double\").", + "description": "Quote style to prefer for inline strings (either \"single\" or \"double\").\n\nWhen using the formatter, ensure that `format.quote-style` is set to the same preferred quote style.", "anyOf": [ { "$ref": "#/definitions/Quote" @@ -1030,7 +1105,7 @@ ] }, "multiline-quotes": { - "description": "Quote style to prefer for multiline strings (either \"single\" or \"double\").", + "description": "Quote style to prefer for multiline strings (either \"single\" or \"double\").\n\nWhen using the formatter, only \"double\" is compatible, as the formatter enforces double quotes for multiline strings.", "anyOf": [ { "$ref": "#/definitions/Quote" @@ -1166,8 +1241,18 @@ "description": "Experimental: Configures how `ruff format` formats your code.\n\nPlease provide feedback in [this discussion](https://github.com/astral-sh/ruff/discussions/7310).", "type": "object", "properties": { + "exclude": { + "description": "A list of file patterns to exclude from formatting in addition to the files excluded globally (see [`exclude`](#exclude), and [`extend-exclude`](#extend-exclude)).\n\nExclusions are based on globs, and can be either:\n\n- Single-path patterns, like `.mypy_cache` (to exclude any directory named `.mypy_cache` in the tree), `foo.py` (to exclude any file named `foo.py`), or `foo_*.py` (to exclude any file matching `foo_*.py` ). - Relative patterns, like `directory/foo.py` (to exclude that specific file) or `directory/*.py` (to exclude any Python files in `directory`). Note that these paths are relative to the project root (e.g., the directory containing your `pyproject.toml`).\n\nFor more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, "indent-style": { - "description": "Whether to use 4 spaces or hard tabs for indenting code.\n\nDefaults to 4 spaces. We care about accessibility; if you do not need tabs for accessibility, we do not recommend you use them.", + "description": "Whether to use spaces or tabs for indentation.\n\n`indent-style = \"space\"` (default):\n\n```python def f(): print(\"Hello\") # Spaces indent the `print` statement. ```\n\n`indent-style = \"tab\"\"`:\n\n```python def f(): print(\"Hello\") # A tab `\\t` indents the `print` statement. ```\n\nPEP 8 recommends using spaces for [indentation](https://peps.python.org/pep-0008/#indentation). We care about accessibility; if you do not need tabs for accessibility, we do not recommend you use them.\n\nSee [`indent-width`](#indent-width) to configure the number of spaces per indentation and the tab width.", "anyOf": [ { "$ref": "#/definitions/IndentStyle" @@ -1178,7 +1263,7 @@ ] }, "line-ending": { - "description": "The character Ruff uses at the end of a line.\n\n* `lf`: Line endings will be converted to `\\n`. The default line ending on Unix. * `cr-lf`: Line endings will be converted to `\\r\\n`. The default line ending on Windows. * `auto`: The newline style is detected automatically on a file per file basis. Files with mixed line endings will be converted to the first detected line ending. Defaults to `\\n` for files that contain no line endings. * `native`: Line endings will be converted to `\\n` on Unix and `\\r\\n` on Windows.", + "description": "The character Ruff uses at the end of a line.\n\n* `auto`: The newline style is detected automatically on a file per file basis. Files with mixed line endings will be converted to the first detected line ending. Defaults to `\\n` for files that contain no line endings. * `lf`: Line endings will be converted to `\\n`. The default line ending on Unix. * `cr-lf`: Line endings will be converted to `\\r\\n`. The default line ending on Windows. * `native`: Line endings will be converted to `\\n` on Unix and `\\r\\n` on Windows.", "anyOf": [ { "$ref": "#/definitions/LineEnding" @@ -1196,7 +1281,7 @@ ] }, "quote-style": { - "description": "Whether to prefer single `'` or double `\"` quotes for strings and docstrings.\n\nRuff may deviate from this option if using the configured quotes would require more escaped quotes:\n\n```python a = \"It's monday morning\" b = \"a string without any quotes\" ```\n\nRuff leaves `a` unchanged when using `quote-style = \"single\"` because it is otherwise necessary to escape the `'` which leads to less readable code: `'It\\'s monday morning'`. Ruff changes the quotes of `b` to use single quotes.", + "description": "Whether to prefer single `'` or double `\"` quotes for strings. Defaults to double quotes.\n\nIn compliance with [PEP 8](https://peps.python.org/pep-0008/) and [PEP 257](https://peps.python.org/pep-0257/), Ruff prefers double quotes for multiline strings and docstrings, regardless of the configured quote style.\n\nRuff may also deviate from this option if using the configured quotes would require escaping quote characters within the string. For example, given:\n\n```python a = \"a string without any quotes\" b = \"It's monday morning\" ```\n\nRuff will change `a` to use single quotes when using `quote-style = \"single\"`. However, `b` will be unchanged, as converting to single quotes would require the inner `'` to be escaped, which leads to less readable code: `'It\\'s monday morning'`.", "anyOf": [ { "$ref": "#/definitions/QuoteStyle" @@ -1207,7 +1292,7 @@ ] }, "skip-magic-trailing-comma": { - "description": "Ruff uses existing trailing commas as an indication that short lines should be left separate. If this option is set to `true`, the magic trailing comma is ignored.\n\nFor example, Ruff leaves the arguments separate even though collapsing the arguments to a single line doesn't exceed the line width if `skip-magic-trailing-comma = false`:\n\n```python # The arguments remain on separate lines because of the trailing comma after `b` def test( a, b, ): pass ```\n\nSetting `skip-magic-trailing-comma = true` changes the formatting to:\n\n```python # The arguments remain on separate lines because of the trailing comma after `b` def test(a, b): pass ```", + "description": "Ruff uses existing trailing commas as an indication that short lines should be left separate. If this option is set to `true`, the magic trailing comma is ignored.\n\nFor example, Ruff leaves the arguments separate even though collapsing the arguments to a single line doesn't exceed the line length if `skip-magic-trailing-comma = false`:\n\n```python # The arguments remain on separate lines because of the trailing comma after `b` def test( a, b, ): pass ```\n\nSetting `skip-magic-trailing-comma = true` changes the formatting to:\n\n```python # The arguments remain on separate lines because of the trailing comma after `b` def test(a, b): pass ```", "type": [ "boolean", "null" @@ -1216,16 +1301,6 @@ }, "additionalProperties": false }, - "FormatOrOutputFormat": { - "anyOf": [ - { - "$ref": "#/definitions/FormatOptions" - }, - { - "$ref": "#/definitions/SerializationFormat" - } - ] - }, "ImportSection": { "anyOf": [ { @@ -1264,6 +1339,12 @@ } ] }, + "IndentWidth": { + "description": "The size of a tab.", + "type": "integer", + "format": "uint8", + "minimum": 1.0 + }, "IsortOptions": { "type": "object", "properties": { @@ -1343,7 +1424,7 @@ } }, "force-wrap-aliases": { - "description": "Force `import from` statements with multiple members and at least one alias (e.g., `import A as B`) to wrap such that every line contains exactly one member. For example, this formatting would be retained, rather than condensing to a single line:\n\n```python from .utils import ( test_directory as test_directory, test_id as test_id ) ```\n\nNote that this setting is only effective when combined with `combine-as-imports = true`. When `combine-as-imports` isn't enabled, every aliased `import from` will be given its own line, in which case, wrapping is not necessary.", + "description": "Force `import from` statements with multiple members and at least one alias (e.g., `import A as B`) to wrap such that every line contains exactly one member. For example, this formatting would be retained, rather than condensing to a single line:\n\n```python from .utils import ( test_directory as test_directory, test_id as test_id ) ```\n\nNote that this setting is only effective when combined with `combine-as-imports = true`. When `combine-as-imports` isn't enabled, every aliased `import from` will be given its own line, in which case, wrapping is not necessary.\n\nWhen using the formatter, ensure that `format.skip-magic-trailing-comma` is set to `false` (default) when enabling `force-wrap-aliases` to avoid that the formatter collapses members if they all fit on a single line.", "type": [ "boolean", "null" @@ -1390,7 +1471,7 @@ } }, "lines-after-imports": { - "description": "The number of blank lines to place after imports. Use `-1` for automatic determination.", + "description": "The number of blank lines to place after imports. Use `-1` for automatic determination.\n\nWhen using the formatter, only the values `-1`, `1`, and `2` are compatible because it enforces at least one empty and at most two empty lines after imports.", "type": [ "integer", "null" @@ -1398,7 +1479,7 @@ "format": "int" }, "lines-between-types": { - "description": "The number of lines to place between \"direct\" and `import from` imports.", + "description": "The number of lines to place between \"direct\" and `import from` imports.\n\nWhen using the formatter, only the values `0` and `1` are compatible because it preserves up to one empty line after imports in nested blocks.", "type": [ "integer", "null" @@ -1478,7 +1559,7 @@ } }, "split-on-trailing-comma": { - "description": "If a comma is placed after the last member in a multi-line import, then the imports will never be folded into one line.\n\nSee isort's [`split-on-trailing-comma`](https://pycqa.github.io/isort/docs/configuration/options.html#split-on-trailing-comma) option.", + "description": "If a comma is placed after the last member in a multi-line import, then the imports will never be folded into one line.\n\nSee isort's [`split-on-trailing-comma`](https://pycqa.github.io/isort/docs/configuration/options.html#split-on-trailing-comma) option.\n\nWhen using the formatter, ensure that `format.skip-magic-trailing-comma` is set to `false` (default) when enabling `split-on-trailing-comma` to avoid that the formatter removes the trailing commas.", "type": [ "boolean", "null" @@ -1500,24 +1581,24 @@ "LineEnding": { "oneOf": [ { - "description": "Line endings will be converted to `\\n` as is common on Unix.", + "description": "The newline style is detected automatically on a file per file basis. Files with mixed line endings will be converted to the first detected line ending. Defaults to [`LineEnding::Lf`] for a files that contain no line endings.", "type": "string", "enum": [ - "lf" + "auto" ] }, { - "description": "Line endings will be converted to `\\r\\n` as is common on Windows.", + "description": "Line endings will be converted to `\\n` as is common on Unix.", "type": "string", "enum": [ - "cr-lf" + "lf" ] }, { - "description": "The newline style is detected automatically on a file per file basis. Files with mixed line endings will be converted to the first detected line ending. Defaults to [`LineEnding::Lf`] for a files that contain no line endings.", + "description": "Line endings will be converted to `\\r\\n` as is common on Windows.", "type": "string", "enum": [ - "auto" + "cr-lf" ] }, { @@ -1533,8 +1614,498 @@ "description": "The length of a line of text that is considered too long.\n\nThe allowed range of values is 1..=320", "type": "integer", "format": "uint16", + "maximum": 320.0, "minimum": 1.0 }, + "LintOptions": { + "description": "Experimental section to configure Ruff's linting. This new section will eventually replace the top-level linting options.\n\nOptions specified in the `lint` section take precedence over the top-level settings.", + "type": "object", + "properties": { + "allowed-confusables": { + "description": "A list of allowed \"confusable\" Unicode characters to ignore when enforcing `RUF001`, `RUF002`, and `RUF003`.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string", + "maxLength": 1, + "minLength": 1 + } + }, + "dummy-variable-rgx": { + "description": "A regular expression used to identify \"dummy\" variables, or those which should be ignored when enforcing (e.g.) unused-variable rules. The default expression matches `_`, `__`, and `_var`, but not `_var_`.", + "type": [ + "string", + "null" + ] + }, + "exclude": { + "description": "A list of file patterns to exclude from linting in addition to the files excluded globally (see [`exclude`](#exclude), and [`extend-exclude`](#extend-exclude)).\n\nExclusions are based on globs, and can be either:\n\n- Single-path patterns, like `.mypy_cache` (to exclude any directory named `.mypy_cache` in the tree), `foo.py` (to exclude any file named `foo.py`), or `foo_*.py` (to exclude any file matching `foo_*.py` ). - Relative patterns, like `directory/foo.py` (to exclude that specific file) or `directory/*.py` (to exclude any Python files in `directory`). Note that these paths are relative to the project root (e.g., the directory containing your `pyproject.toml`).\n\nFor more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "explicit-preview-rules": { + "description": "Whether to require exact codes to select preview rules. When enabled, preview rules will not be selected by prefixes — the full code of each preview rule will be required to enable the rule.", + "type": [ + "boolean", + "null" + ] + }, + "extend-fixable": { + "description": "A list of rule codes or prefixes to consider fixable, in addition to those specified by `fixable`.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/RuleSelector" + } + }, + "extend-ignore": { + "description": "A list of rule codes or prefixes to ignore, in addition to those specified by `ignore`.", + "deprecated": true, + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/RuleSelector" + } + }, + "extend-per-file-ignores": { + "description": "A list of mappings from file pattern to rule codes or prefixes to exclude, in addition to any rules excluded by `per-file-ignores`.", + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/definitions/RuleSelector" + } + } + }, + "extend-safe-fixes": { + "description": "A list of rule codes or prefixes for which unsafe fixes should be considered safe.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/RuleSelector" + } + }, + "extend-select": { + "description": "A list of rule codes or prefixes to enable, in addition to those specified by `select`.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/RuleSelector" + } + }, + "extend-unfixable": { + "description": "A list of rule codes or prefixes to consider non-auto-fixable, in addition to those specified by `unfixable`.", + "deprecated": true, + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/RuleSelector" + } + }, + "extend-unsafe-fixes": { + "description": "A list of rule codes or prefixes for which safe fixes should be considered unsafe.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/RuleSelector" + } + }, + "external": { + "description": "A list of rule codes or prefixes that are unsupported by Ruff, but should be preserved when (e.g.) validating `# noqa` directives. Useful for retaining `# noqa` directives that cover plugins not yet implemented by Ruff.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "fixable": { + "description": "A list of rule codes or prefixes to consider fixable. By default, all rules are considered fixable.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/RuleSelector" + } + }, + "flake8-annotations": { + "description": "Options for the `flake8-annotations` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Flake8AnnotationsOptions" + }, + { + "type": "null" + } + ] + }, + "flake8-bandit": { + "description": "Options for the `flake8-bandit` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Flake8BanditOptions" + }, + { + "type": "null" + } + ] + }, + "flake8-bugbear": { + "description": "Options for the `flake8-bugbear` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Flake8BugbearOptions" + }, + { + "type": "null" + } + ] + }, + "flake8-builtins": { + "description": "Options for the `flake8-builtins` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Flake8BuiltinsOptions" + }, + { + "type": "null" + } + ] + }, + "flake8-comprehensions": { + "description": "Options for the `flake8-comprehensions` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Flake8ComprehensionsOptions" + }, + { + "type": "null" + } + ] + }, + "flake8-copyright": { + "description": "Options for the `flake8-copyright` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Flake8CopyrightOptions" + }, + { + "type": "null" + } + ] + }, + "flake8-errmsg": { + "description": "Options for the `flake8-errmsg` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Flake8ErrMsgOptions" + }, + { + "type": "null" + } + ] + }, + "flake8-gettext": { + "description": "Options for the `flake8-gettext` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Flake8GetTextOptions" + }, + { + "type": "null" + } + ] + }, + "flake8-implicit-str-concat": { + "description": "Options for the `flake8-implicit-str-concat` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Flake8ImplicitStrConcatOptions" + }, + { + "type": "null" + } + ] + }, + "flake8-import-conventions": { + "description": "Options for the `flake8-import-conventions` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Flake8ImportConventionsOptions" + }, + { + "type": "null" + } + ] + }, + "flake8-pytest-style": { + "description": "Options for the `flake8-pytest-style` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Flake8PytestStyleOptions" + }, + { + "type": "null" + } + ] + }, + "flake8-quotes": { + "description": "Options for the `flake8-quotes` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Flake8QuotesOptions" + }, + { + "type": "null" + } + ] + }, + "flake8-self": { + "description": "Options for the `flake8_self` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Flake8SelfOptions" + }, + { + "type": "null" + } + ] + }, + "flake8-tidy-imports": { + "description": "Options for the `flake8-tidy-imports` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Flake8TidyImportsOptions" + }, + { + "type": "null" + } + ] + }, + "flake8-type-checking": { + "description": "Options for the `flake8-type-checking` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Flake8TypeCheckingOptions" + }, + { + "type": "null" + } + ] + }, + "flake8-unused-arguments": { + "description": "Options for the `flake8-unused-arguments` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Flake8UnusedArgumentsOptions" + }, + { + "type": "null" + } + ] + }, + "ignore": { + "description": "A list of rule codes or prefixes to ignore. Prefixes can specify exact rules (like `F841`), entire categories (like `F`), or anything in between.\n\nWhen breaking ties between enabled and disabled rules (via `select` and `ignore`, respectively), more specific prefixes override less specific prefixes.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/RuleSelector" + } + }, + "ignore-init-module-imports": { + "description": "Avoid automatically removing unused imports in `__init__.py` files. Such imports will still be flagged, but with a dedicated message suggesting that the import is either added to the module's `__all__` symbol, or re-exported with a redundant alias (e.g., `import os as os`).", + "type": [ + "boolean", + "null" + ] + }, + "isort": { + "description": "Options for the `isort` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/IsortOptions" + }, + { + "type": "null" + } + ] + }, + "logger-objects": { + "description": "A list of objects that should be treated equivalently to a `logging.Logger` object.\n\nThis is useful for ensuring proper diagnostics (e.g., to identify `logging` deprecations and other best-practices) for projects that re-export a `logging.Logger` object from a common module.\n\nFor example, if you have a module `logging_setup.py` with the following contents: ```python import logging\n\nlogger = logging.getLogger(__name__) ```\n\nAdding `\"logging_setup.logger\"` to `logger-objects` will ensure that `logging_setup.logger` is treated as a `logging.Logger` object when imported from other modules (e.g., `from logging_setup import logger`).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "mccabe": { + "description": "Options for the `mccabe` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/McCabeOptions" + }, + { + "type": "null" + } + ] + }, + "pep8-naming": { + "description": "Options for the `pep8-naming` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/Pep8NamingOptions" + }, + { + "type": "null" + } + ] + }, + "per-file-ignores": { + "description": "A list of mappings from file pattern to rule codes or prefixes to exclude, when considering any matching files.", + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/definitions/RuleSelector" + } + } + }, + "preview": { + "description": "Whether to enable preview mode. When preview mode is enabled, Ruff will use unstable rules and fixes.", + "type": [ + "boolean", + "null" + ] + }, + "pycodestyle": { + "description": "Options for the `pycodestyle` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/PycodestyleOptions" + }, + { + "type": "null" + } + ] + }, + "pydocstyle": { + "description": "Options for the `pydocstyle` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/PydocstyleOptions" + }, + { + "type": "null" + } + ] + }, + "pyflakes": { + "description": "Options for the `pyflakes` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/PyflakesOptions" + }, + { + "type": "null" + } + ] + }, + "pylint": { + "description": "Options for the `pylint` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/PylintOptions" + }, + { + "type": "null" + } + ] + }, + "pyupgrade": { + "description": "Options for the `pyupgrade` plugin.", + "anyOf": [ + { + "$ref": "#/definitions/PyUpgradeOptions" + }, + { + "type": "null" + } + ] + }, + "select": { + "description": "A list of rule codes or prefixes to enable. Prefixes can specify exact rules (like `F841`), entire categories (like `F`), or anything in between.\n\nWhen breaking ties between enabled and disabled rules (via `select` and `ignore`, respectively), more specific prefixes override less specific prefixes.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/RuleSelector" + } + }, + "task-tags": { + "description": "A list of task tags to recognize (e.g., \"TODO\", \"FIXME\", \"XXX\").\n\nComments starting with these tags will be ignored by commented-out code detection (`ERA`), and skipped by line-length rules (`E501`) if `ignore-overlong-task-comments` is set to `true`.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "typing-modules": { + "description": "A list of modules whose exports should be treated equivalently to members of the `typing` module.\n\nThis is useful for ensuring proper type annotation inference for projects that re-export `typing` and `typing_extensions` members from a compatibility module. If omitted, any members imported from modules apart from `typing` and `typing_extensions` will be treated as ordinary Python objects.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "unfixable": { + "description": "A list of rule codes or prefixes to consider non-fixable.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/RuleSelector" + } + } + }, + "additionalProperties": false + }, "McCabeOptions": { "type": "object", "properties": { @@ -1576,7 +2147,7 @@ "type": "object", "properties": { "classmethod-decorators": { - "description": "A list of decorators that, when applied to a method, indicate that the method should be treated as a class method (in addition to the builtin `@classmethod`).\n\nFor example, Ruff will expect that any method decorated by a decorator in this list takes a `cls` argument as its first argument.", + "description": "A list of decorators that, when applied to a method, indicate that the method should be treated as a class method (in addition to the builtin `@classmethod`).\n\nFor example, Ruff will expect that any method decorated by a decorator in this list takes a `cls` argument as its first argument.\n\nExpects to receive a list of fully-qualified names (e.g., `pydantic.validator`, rather than `validator`).", "type": [ "array", "null" @@ -1586,7 +2157,7 @@ } }, "extend-ignore-names": { - "description": "Additional names (or patterns) to ignore when considering `pep8-naming` violations, in addition to those included in `ignore-names`.", + "description": "Additional names (or patterns) to ignore when considering `pep8-naming` violations, in addition to those included in `ignore-names`\n\nSupports glob patterns. For example, to ignore all names starting with or ending with `_test`, you could use `ignore-names = [\"test_*\", \"*_test\"]`. For more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax).", "type": [ "array", "null" @@ -1596,7 +2167,7 @@ } }, "ignore-names": { - "description": "A list of names (or patterns) to ignore when considering `pep8-naming` violations.", + "description": "A list of names (or patterns) to ignore when considering `pep8-naming` violations.\n\nSupports glob patterns. For example, to ignore all names starting with or ending with `_test`, you could use `ignore-names = [\"test_*\", \"*_test\"]`. For more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax).", "type": [ "array", "null" @@ -1606,7 +2177,7 @@ } }, "staticmethod-decorators": { - "description": "A list of decorators that, when applied to a method, indicate that the method should be treated as a static method (in addition to the builtin `@staticmethod`).\n\nFor example, Ruff will expect that any method decorated by a decorator in this list has no `self` or `cls` argument.", + "description": "A list of decorators that, when applied to a method, indicate that the method should be treated as a static method (in addition to the builtin `@staticmethod`).\n\nFor example, Ruff will expect that any method decorated by a decorator in this list has no `self` or `cls` argument.\n\nExpects to receive a list of fully-qualified names (e.g., `belay.Device.teardown`, rather than `teardown`).", "type": [ "array", "null" @@ -1642,7 +2213,18 @@ ] }, "max-doc-length": { - "description": "The maximum line length to allow for line-length violations within documentation (`W505`), including standalone comments. By default, this is set to null which disables reporting violations.\n\nSee the [`doc-line-too-long`](https://docs.astral.sh/ruff/rules/doc-line-too-long/) rule for more information.", + "description": "The maximum line length to allow for [`doc-line-too-long`](https://docs.astral.sh/ruff/rules/doc-line-too-long/) violations within documentation (`W505`), including standalone comments. By default, this is set to null which disables reporting violations.\n\nThe length is determined by the number of characters per line, except for lines containing Asian characters or emojis. For these lines, the [unicode width](https://unicode.org/reports/tr11/) of each character is added up to determine the length.\n\nSee the [`doc-line-too-long`](https://docs.astral.sh/ruff/rules/doc-line-too-long/) rule for more information.", + "anyOf": [ + { + "$ref": "#/definitions/LineLength" + }, + { + "type": "null" + } + ] + }, + "max-line-length": { + "description": "The maximum line length to allow for [`line-too-long`](https://docs.astral.sh/ruff/rules/line-too-long/) violations. By default, this is set to the value of the [`line-length`](#line-length) option.\n\nUse this option when you want to detect extra-long lines that the formatter can't automatically split by setting `pycodestyle.line-length` to a value larger than [`line-length`](#line-length).\n\n```toml line-length = 88 # The formatter wraps lines at a length of 88\n\n[pycodestyle] max-line-length = 100 # E501 reports lines that exceed the length of 100. ```\n\nThe length is determined by the number of characters per line, except for lines containing East Asian characters or emojis. For these lines, the [unicode width](https://unicode.org/reports/tr11/) of each character is added up to determine the length.\n\nSee the [`line-too-long`](https://docs.astral.sh/ruff/rules/line-too-long/) rule for more information.", "anyOf": [ { "$ref": "#/definitions/LineLength" @@ -1659,7 +2241,7 @@ "type": "object", "properties": { "convention": { - "description": "Whether to use Google-style or NumPy-style conventions or the PEP257 defaults when analyzing docstring sections.\n\nEnabling a convention will force-disable any rules that are not included in the specified convention. As such, the intended use is to enable a convention and then selectively disable any additional rules on top of it.\n\nFor example, to use Google-style conventions but avoid requiring documentation for every function parameter:\n\n```toml [tool.ruff] # Enable all `pydocstyle` rules, limiting to those that adhere to the # Google convention via `convention = \"google\"`, below. select = [\"D\"]\n\n# On top of the Google convention, disable `D417`, which requires # documentation for every function parameter. ignore = [\"D417\"]\n\n[tool.ruff.pydocstyle] convention = \"google\" ```\n\nAs conventions force-disable all rules not included in the convention, enabling _additional_ rules on top of a convention is currently unsupported.", + "description": "Whether to use Google-style or NumPy-style conventions or the [PEP 257](https://peps.python.org/pep-0257/) defaults when analyzing docstring sections.\n\nEnabling a convention will force-disable any rules that are not included in the specified convention. As such, the intended use is to enable a convention and then selectively disable any additional rules on top of it.\n\nFor example, to use Google-style conventions but avoid requiring documentation for every function parameter:\n\n```toml [tool.ruff] # Enable all `pydocstyle` rules, limiting to those that adhere to the # Google convention via `convention = \"google\"`, below. select = [\"D\"]\n\n# On top of the Google convention, disable `D417`, which requires # documentation for every function parameter. ignore = [\"D417\"]\n\n[tool.ruff.pydocstyle] convention = \"google\" ```\n\nAs conventions force-disable all rules not included in the convention, enabling _additional_ rules on top of a convention is currently unsupported.", "anyOf": [ { "$ref": "#/definitions/Convention" @@ -1730,6 +2312,15 @@ "format": "uint", "minimum": 0.0 }, + "max-bool-expr": { + "description": "Maximum number of Boolean expressions allowed within a single `if` statement (see: `PLR0916`).", + "type": [ + "integer", + "null" + ], + "format": "uint", + "minimum": 0.0 + }, "max-branches": { "description": "Maximum number of branches allowed for a function or method body (see: `PLR0912`).", "type": [ @@ -2046,6 +2637,8 @@ "E115", "E116", "E117", + "E12", + "E122", "E2", "E20", "E201", @@ -2218,6 +2811,7 @@ "FURB", "FURB1", "FURB10", + "FURB101", "FURB105", "FURB11", "FURB113", @@ -2228,6 +2822,9 @@ "FURB140", "FURB145", "FURB148", + "FURB17", + "FURB171", + "FURB177", "G", "G0", "G00", @@ -2383,6 +2980,11 @@ "PLC19", "PLC190", "PLC1901", + "PLC2", + "PLC24", + "PLC240", + "PLC2401", + "PLC2403", "PLC3", "PLC30", "PLC300", @@ -2408,6 +3010,9 @@ "PLE060", "PLE0604", "PLE0605", + "PLE07", + "PLE070", + "PLE0704", "PLE1", "PLE11", "PLE114", @@ -2459,10 +3064,12 @@ "PLR0912", "PLR0913", "PLR0915", + "PLR0916", "PLR1", "PLR17", "PLR170", "PLR1701", + "PLR1706", "PLR171", "PLR1711", "PLR1714", @@ -2477,12 +3084,17 @@ "PLR550", "PLR5501", "PLR6", + "PLR62", + "PLR620", + "PLR6201", "PLR63", "PLR630", "PLR6301", "PLW", "PLW0", "PLW01", + "PLW010", + "PLW0108", "PLW012", "PLW0120", "PLW0127", @@ -2496,6 +3108,7 @@ "PLW060", "PLW0602", "PLW0603", + "PLW0604", "PLW07", "PLW071", "PLW0711", @@ -2506,6 +3119,7 @@ "PLW1509", "PLW151", "PLW1510", + "PLW1514", "PLW16", "PLW164", "PLW1641", @@ -2687,6 +3301,8 @@ "RUF015", "RUF016", "RUF017", + "RUF018", + "RUF019", "RUF1", "RUF10", "RUF100", @@ -2740,6 +3356,7 @@ "S5", "S50", "S501", + "S505", "S506", "S507", "S508", @@ -2973,12 +3590,6 @@ } ] }, - "TabSize": { - "description": "The size of a tab.", - "type": "integer", - "format": "uint8", - "minimum": 1.0 - }, "Version": { "type": "string" } diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 7e8f0a9aabf5e..50fa4928b96fe 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "1.72" +channel = "1.73" diff --git a/scripts/add_rule.py b/scripts/add_rule.py index 841088b9b5ed8..bfc61b733e8ae 100755 --- a/scripts/add_rule.py +++ b/scripts/add_rule.py @@ -140,8 +140,7 @@ def main(*, name: str, prefix: str, code: str, linter: str) -> None: variant = pascal_case(linter) rule = f"""rules::{linter.split(" ")[0]}::rules::{name}""" lines.append( - " " * 8 - + f"""({variant}, "{code}") => (RuleGroup::Unspecified, {rule}),\n""", + " " * 8 + f"""({variant}, "{code}") => (RuleGroup::Stable, {rule}),\n""", ) lines.sort() text += "".join(lines) diff --git a/scripts/benchmarks/pyproject.toml b/scripts/benchmarks/pyproject.toml index 0018532fc473e..744a1f4b3a642 100644 --- a/scripts/benchmarks/pyproject.toml +++ b/scripts/benchmarks/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "scripts" -version = "0.1.0" +version = "0.1.3" description = "" authors = ["Charles Marsh "] diff --git a/scripts/benchmarks/run_formatter.sh b/scripts/benchmarks/run_formatter.sh index f4acd73fcd42f..645075674794e 100755 --- a/scripts/benchmarks/run_formatter.sh +++ b/scripts/benchmarks/run_formatter.sh @@ -5,7 +5,9 @@ # # Expects to be run from the repo root after invoking `cargo build --release`, # in an environment with access to `black`, `autopep8`, and `yapf` (most recently: -# `black` v23.9.1, `autopep8` v2.0.4, and `yapf` v0.40.1). +# `black` v23.9.1, `autopep8` v2.0.4, and `yapf` v0.40.2, on Python 3.11.6, the +# most recent combination of versions for which Black provides compiled wheels at +# time of writing). # # Example usage: # diff --git a/scripts/check_docs_formatted.py b/scripts/check_docs_formatted.py index bc6f93010cafa..78334cc3b5f9a 100755 --- a/scripts/check_docs_formatted.py +++ b/scripts/check_docs_formatted.py @@ -55,6 +55,7 @@ "multiple-statements-on-one-line-semicolon", "no-blank-line-before-function", "no-indented-block-comment", + "no-return-argument-annotation-in-stub", "no-space-after-block-comment", "no-space-after-inline-comment", "non-empty-stub-body", @@ -67,6 +68,7 @@ "surrounding-whitespace", "tab-indentation", "too-few-spaces-before-inline-comment", + "too-many-boolean-expressions", "trailing-comma-on-bare-tuple", "triple-single-quotes", "under-indentation", diff --git a/scripts/check_ecosystem.py b/scripts/check_ecosystem.py index 1b173076c1d54..f45fae776c3e8 100755 --- a/scripts/check_ecosystem.py +++ b/scripts/check_ecosystem.py @@ -1,5 +1,9 @@ #!/usr/bin/env python3 -"""Check two versions of ruff against a corpus of open-source code. +""" +**DEPRECATED** This script is being replaced by the ruff-ecosystem package. + + +Check two versions of ruff against a corpus of open-source code. Example usage: diff --git a/scripts/ecosystem_all_check.py b/scripts/ecosystem_all_check.py index 8111821d9a991..8882142e85f14 100644 --- a/scripts/ecosystem_all_check.py +++ b/scripts/ecosystem_all_check.py @@ -1,5 +1,5 @@ """This is @konstin's scripts for checking an entire checkout of ~2.1k packages for -panics, autofix errors and similar problems. +panics, fix errors and similar problems. It's a less elaborate, more hacky version of check_ecosystem.py """ diff --git a/scripts/ecosystem_all_check.sh b/scripts/ecosystem_all_check.sh index 7c3233cc33b9a..20181082802f3 100755 --- a/scripts/ecosystem_all_check.sh +++ b/scripts/ecosystem_all_check.sh @@ -1,6 +1,6 @@ #!/bin/bash # This is @konstin's setup for checking an entire checkout of ~3k packages for -# panics, autofix errors and similar problems. +# panics, fix errors and similar problems. # # We put this in a docker container because processing random scraped code from GitHub is # [kinda dangerous](https://moyix.blogspot.com/2022/09/someones-been-messing-with-my-subnormals.html) @@ -28,7 +28,7 @@ time docker run --rm -it \ -v "${SCRIPT_DIR}/ecosystem_all_check.py:/app/ecosystem_all_check.py" \ python:3.11 ./ecosystem_all_check_entrypoint.sh "$@" -# grep the autofix errors -grep -R "the rule codes" "${SCRIPT_DIR}/../target/ecosystem_all_results" | sort > "${SCRIPT_DIR}/../target/autofix-errors.txt" +# grep the fix errors +grep -R "the rule codes" "${SCRIPT_DIR}/../target/ecosystem_all_results" | sort > "${SCRIPT_DIR}/../target/fix-errors.txt" # Make sure we didn't have an early exit echo "Done" diff --git a/scripts/formatter_ecosystem_checks.sh b/scripts/formatter_ecosystem_checks.sh index 46966c91cc224..ec8d41dcbdf81 100755 --- a/scripts/formatter_ecosystem_checks.sh +++ b/scripts/formatter_ecosystem_checks.sh @@ -10,7 +10,7 @@ # # The pinned revisions are the latest of this writing, update freely. -set -ex +set -e target=$(git rev-parse --show-toplevel)/target dir="$target/progress_projects" @@ -20,43 +20,61 @@ mkdir -p "$dir" if [ ! -d "$dir/twine/.git" ]; then git clone --filter=tree:0 https://github.com/pypa/twine "$dir/twine" fi -git -C "$dir/twine" checkout 0bb428c410b8df64c04dc881ac1db37d932f3066 +git -C "$dir/twine" checkout -q afc37f8b26ed06ccd104f6724f293f657b9b7f15 # web framework that implements a lot of magic if [ ! -d "$dir/django/.git" ]; then git clone --filter=tree:0 https://github.com/django/django "$dir/django" fi -git -C "$dir/django" checkout 48a1929ca050f1333927860ff561f6371706968a +git -C "$dir/django" checkout -q 20b7aac7ca60b0352d926340622e618bcbee54a8 # an ML project if [ ! -d "$dir/transformers/.git" ]; then git clone --filter=tree:0 https://github.com/huggingface/transformers "$dir/transformers" fi -git -C "$dir/transformers" checkout 62396cff46854dc53023236cfeb785993fa70067 +git -C "$dir/transformers" checkout -q 5c081e29930466ecf9a478727039d980131076d9 # type annotations if [ ! -d "$dir/typeshed/.git" ]; then git clone --filter=tree:0 https://github.com/python/typeshed "$dir/typeshed" fi -git -C "$dir/typeshed" checkout 2c15a8e7906e19f49bb765e2807dd0079fe9c04b +git -C "$dir/typeshed" checkout -q cb688d2577520d98c09853acc20de099300b4e48 # python 3.11, typing and 100% test coverage if [ ! -d "$dir/warehouse/.git" ]; then git clone --filter=tree:0 https://github.com/pypi/warehouse "$dir/warehouse" fi -git -C "$dir/warehouse" checkout 6be6bccf07dace18784ea8aeac7906903fdbcf3a +git -C "$dir/warehouse" checkout -q c6d9dd32b7c85d3a5f4240c95267874417e5b965 # zulip, a django user if [ ! -d "$dir/zulip/.git" ]; then git clone --filter=tree:0 https://github.com/zulip/zulip "$dir/zulip" fi -git -C "$dir/zulip" checkout 328cdde24331b82baa4c9b1bf1cb7b2015799826 +git -C "$dir/zulip" checkout -q b605042312c763c9a1e458f0ca6a003799682546 + +# home-assistant, home automation with 1ok files +if [ ! -d "$dir/home-assistant/.git" ]; then + git clone --filter=tree:0 https://github.com/home-assistant/core "$dir/home-assistant" +fi +git -C "$dir/home-assistant" checkout -q 88296c1998fd1943576e0167ab190d25af175257 + +# poetry, a package manager that uses black preview style +if [ ! -d "$dir/poetry/.git" ]; then + git clone --filter=tree:0 https://github.com/python-poetry/poetry "$dir/poetry" +fi +git -C "$dir/poetry" checkout -q f5cb9f0fb19063cf280faf5e39c82d5691da9939 # cpython itself if [ ! -d "$dir/cpython/.git" ]; then git clone --filter=tree:0 https://github.com/python/cpython "$dir/cpython" fi -git -C "$dir/cpython" checkout 1a1bfc28912a39b500c578e9f10a8a222638d411 +git -C "$dir/cpython" checkout -q b75186f69edcf54615910a5cd707996144163ef7 + +# poetry itself +if [ ! -d "$dir/poetry/.git" ]; then + git clone --filter=tree:0 https://github.com/python-poetry/poetry "$dir/poetry" +fi +git -C "$dir/poetry" checkout -q 611033a7335f3c8e2b74dd58688fb9021cf84a5b # Uncomment if you want to update the hashes #for i in "$dir"/*/; do git -C "$i" switch main && git -C "$i" pull; done @@ -64,7 +82,7 @@ git -C "$dir/cpython" checkout 1a1bfc28912a39b500c578e9f10a8a222638d411 time cargo run --bin ruff_dev -- format-dev --stability-check \ --error-file "$target/progress_projects_errors.txt" --log-file "$target/progress_projects_log.txt" --stats-file "$target/progress_projects_stats.txt" \ - --files-with-errors 16 --multi-project "$dir" || ( + --files-with-errors 14 --multi-project "$dir" || ( echo "Ecosystem check failed" cat "$target/progress_projects_log.txt" exit 1 diff --git a/scripts/generate_mkdocs.py b/scripts/generate_mkdocs.py index fca685680907a..165debb768765 100644 --- a/scripts/generate_mkdocs.py +++ b/scripts/generate_mkdocs.py @@ -22,13 +22,15 @@ class Section(NamedTuple): SECTIONS: list[Section] = [ Section("Overview", "index.md", generated=True), Section("Tutorial", "tutorial.md", generated=False), - Section("Installation", "installation.md", generated=False), - Section("Usage", "usage.md", generated=False), - Section("Configuration", "configuration.md", generated=False), + Section("Installing Ruff", "installation.md", generated=False), + Section("The Ruff Linter", "linter.md", generated=False), + Section("The Ruff Formatter", "formatter.md", generated=False), + Section("Configuring Ruff", "configuration.md", generated=False), Section("Preview", "preview.md", generated=False), Section("Rules", "rules.md", generated=True), Section("Settings", "settings.md", generated=True), - Section("Editor Integrations", "editor-integrations.md", generated=False), + Section("Versioning", "versioning.md", generated=False), + Section("Integrations", "integrations.md", generated=False), Section("FAQ", "faq.md", generated=False), Section("Contributing", "contributing.md", generated=True), ] @@ -41,13 +43,12 @@ class Section(NamedTuple): "configuration.md#pyprojecttoml-discovery" ), "https://docs.astral.sh/ruff/contributing/": "contributing.md", - "https://docs.astral.sh/ruff/editor-integrations/": "editor-integrations.md", + "https://docs.astral.sh/ruff/editor-integrations/": "integrations.md", "https://docs.astral.sh/ruff/faq/#how-does-ruff-compare-to-flake8": ( "faq.md#how-does-ruff-compare-to-flake8" ), "https://docs.astral.sh/ruff/installation/": "installation.md", "https://docs.astral.sh/ruff/rules/": "rules.md", - "https://docs.astral.sh/ruff/rules/#error-e": "rules.md#error-e", "https://docs.astral.sh/ruff/settings/": "settings.md", } From 8f5d6fc84ae965ed22ad16d03470d67cc9ea2cf8 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Sun, 29 Oct 2023 04:56:40 +0900 Subject: [PATCH 03/21] Fix some clippy issues. --- ...n_line_missing_indentation_or_outdented.rs | 45 +++++++++---------- crates/ruff_workspace/src/configuration.rs | 1 + 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs index 0273e8eeb6bd6..861f5564fb10a 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs @@ -12,7 +12,7 @@ use ruff_text_size::{Ranged, TextRange, TextSize}; /// Checks for continuation lines not indented as far as they should be or indented too far. /// /// ## Why is this bad? -/// This makes reading code harder. +/// This makes distinguishing continuation line harder. /// /// ## Example /// ```python @@ -25,6 +25,8 @@ use ruff_text_size::{Ranged, TextRange, TextSize}; /// print("Python", ( /// "Rules")) /// ``` +/// +/// [PEP 8]: https://www.python.org/dev/peps/pep-0008/#indentation #[violation] pub struct MissingOrOutdentedIndentation; @@ -44,7 +46,7 @@ struct TokenInfo<'a> { line: &'a str, } -/// Compute the TokenInfo of each token. +/// Compute the `TokenInfo` of each token. fn get_token_infos<'a>(logical_line: &LogicalLine, locator: &'a Locator) -> Vec> { let mut token_infos = Vec::new(); let mut current_line_idx: usize = 0; @@ -63,7 +65,7 @@ fn get_token_infos<'a>(logical_line: &LogicalLine, locator: &'a Locator) -> Vec< // Check for escaped ('\') continuation lines between the previous and current tokens. if let Some(prev_token) = prev_token { let trivia = locator.slice(TextRange::new(prev_token.range.end(), token.range.start())); - for (index, _text) in trivia.match_indices("\n") { + for (index, _text) in trivia.match_indices('\n') { start_physical_line_idx += 1; current_line_idx = start_physical_line_idx; first_physical_line_start = @@ -77,8 +79,8 @@ fn get_token_infos<'a>(logical_line: &LogicalLine, locator: &'a Locator) -> Vec< TokenKind::NonLogicalNewline | TokenKind::Newline ) { // Look for newlines within strings. - let trivia = locator.slice(TextRange::new(token.range.start(), token.range.end())); - for (index, _text) in trivia.match_indices("\n") { + let trivia = locator.slice(token.range); + for (index, _text) in trivia.match_indices('\n') { current_line_idx += 1; current_physical_line_start = token.range.start() + TextSize::try_from(index + 1).unwrap(); @@ -92,7 +94,7 @@ fn get_token_infos<'a>(logical_line: &LogicalLine, locator: &'a Locator) -> Vec< .into(), token_end_within_physical_line: (token.range.end() - current_physical_line_start) .into(), - line: locator.slice(locator.full_lines_range(token.range)), + line: locator.full_lines(token.range), }); if matches!( @@ -104,7 +106,7 @@ fn get_token_infos<'a>(logical_line: &LogicalLine, locator: &'a Locator) -> Vec< } else { first_physical_line_start = current_physical_line_start; } - prev_token = Some(&token); + prev_token = Some(token); } token_infos @@ -169,10 +171,10 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( // Here "row" is the physical line index (within the logical line). let mut row = 0; let mut depth = 0; - let valid_hangs = if indent_char != '\t' { - vec![indent_size as i64] - } else { + let valid_hangs = if indent_char == '\t' { vec![indent_size as i64, indent_size as i64 * 2] + } else { + vec![indent_size as i64] }; // Remember how many brackets were opened on each line. let mut parens = vec![0; nb_physical_lines]; @@ -233,18 +235,16 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( // Is there any chance of visual indent ? visual_indent = !is_closing_bracket && hang > 0 - && indent_chances.contains(&token_info.token_start_within_physical_line.into()); + && indent_chances.contains(&token_info.token_start_within_physical_line); if is_closing_bracket && indent[depth] != 0 { // Closing bracket for visual indent. if token_info.token_start_within_physical_line != indent[depth] { - dbg!("E124"); // TODO: Raise E124. } } else if is_closing_bracket && hang == 0 { // Closing bracket matches indentation of opening bracket's line if hang_closing { - dbg!("E133"); // TODO: Raise E133. } } else if indent[depth] != 0 @@ -252,14 +252,12 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( { // visual indent is broken if !visual_indent { - dbg!("E128"); // TODO: Raise E128. } } else if hanging_indent || (indent_next && rel_indent[row] == (2 * indent_size) as i64) { // hanging indent is verified if is_closing_bracket && !hang_closing { - dbg!("E123"); // TODO: Raise E123. } hangs[depth] = Some(hang); @@ -317,7 +315,7 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( indent_chances.push(token_info.token_end_within_physical_line + 1); } // Special case for the "if" statement because "if (".len() == 4 - else if indent_chances.len() == 0 + else if indent_chances.is_empty() && row == 0 && depth == 0 && matches!(token.kind, TokenKind::If) @@ -359,21 +357,18 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( last_indent }; hangs.pop(); - for d in 0..depth { - if indent[d] > prev_indent { - indent[d] = 0 + for ind in indent.iter_mut().take(depth) { + if *ind > prev_indent { + *ind = 0; } } - indent_chances = indent_chances - .into_iter() - .filter(|&ind| ind < prev_indent) - .collect(); + indent_chances.retain(|&ind| ind < prev_indent); open_rows.truncate(depth); depth -= 1; if depth > 0 { indent_chances.push(indent[depth]); } - for idx in (0..row + 1).rev() { + for idx in (0..=row).rev() { if parens[idx] != 0 { parens[idx] -= 1; break; @@ -389,7 +384,7 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( last_token_multiline = token_info.start_physical_line_idx != token_info.end_physical_line_idx; if last_token_multiline { - rel_indent[token_info.end_physical_line_idx] = rel_indent[row] + rel_indent[token_info.end_physical_line_idx] = rel_indent[row]; } if indent_next && expand_indent(token_info.line) == start_indent_level + indent_size { diff --git a/crates/ruff_workspace/src/configuration.rs b/crates/ruff_workspace/src/configuration.rs index 0f7924531a388..fc052a1d2c1d0 100644 --- a/crates/ruff_workspace/src/configuration.rs +++ b/crates/ruff_workspace/src/configuration.rs @@ -1106,6 +1106,7 @@ mod tests { Rule::MissingWhitespaceAroundBitwiseOrShiftOperator, Rule::MissingWhitespaceAroundModuloOperator, Rule::MissingWhitespace, + Rule::MissingOrOutdentedIndentation, Rule::MultipleSpacesAfterComma, Rule::TabAfterComma, Rule::UnexpectedSpacesAroundKeywordParameterEquals, From a72b89a6bd1749e23aeda4ab1f921d316e407dc3 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Thu, 2 Nov 2023 22:01:00 +0900 Subject: [PATCH 04/21] Use i64 for most variables to avoid conversions. --- ...n_line_missing_indentation_or_outdented.rs | 57 +++++++++++-------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs index 861f5564fb10a..92bb68ba2547d 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs @@ -6,7 +6,7 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_parser::TokenKind; use ruff_source_file::Locator; -use ruff_text_size::{Ranged, TextRange, TextSize}; +use ruff_text_size::{Ranged, TextRange}; /// ## What it does /// Checks for continuation lines not indented as far as they should be or indented too far. @@ -41,8 +41,8 @@ impl Violation for MissingOrOutdentedIndentation { struct TokenInfo<'a> { start_physical_line_idx: usize, end_physical_line_idx: usize, - token_start_within_physical_line: usize, - token_end_within_physical_line: usize, + token_start_within_physical_line: i64, + token_end_within_physical_line: i64, line: &'a str, } @@ -51,12 +51,13 @@ fn get_token_infos<'a>(logical_line: &LogicalLine, locator: &'a Locator) -> Vec< let mut token_infos = Vec::new(); let mut current_line_idx: usize = 0; // The first physical line occupied by the token, since a token can span multiple physical lines. - let mut first_physical_line_start = if let Some(first_token) = logical_line.first_token() { - first_token.range.start() + let mut first_physical_line_start: usize = if let Some(first_token) = logical_line.first_token() + { + first_token.range.start().into() } else { return token_infos; }; - let mut current_physical_line_start: TextSize; + let mut current_physical_line_start: usize; let mut prev_token: Option<&LogicalLineToken> = None; for token in logical_line.tokens() { let mut start_physical_line_idx = current_line_idx; @@ -68,8 +69,7 @@ fn get_token_infos<'a>(logical_line: &LogicalLine, locator: &'a Locator) -> Vec< for (index, _text) in trivia.match_indices('\n') { start_physical_line_idx += 1; current_line_idx = start_physical_line_idx; - first_physical_line_start = - prev_token.range.end() + TextSize::try_from(index + 1).unwrap(); + first_physical_line_start = usize::from(prev_token.range.end()) + index + 1; current_physical_line_start = first_physical_line_start; } } @@ -82,18 +82,21 @@ fn get_token_infos<'a>(logical_line: &LogicalLine, locator: &'a Locator) -> Vec< let trivia = locator.slice(token.range); for (index, _text) in trivia.match_indices('\n') { current_line_idx += 1; - current_physical_line_start = - token.range.start() + TextSize::try_from(index + 1).unwrap(); + current_physical_line_start = usize::from(token.range.start()) + index + 1; } } token_infos.push(TokenInfo { start_physical_line_idx, end_physical_line_idx: current_line_idx, - token_start_within_physical_line: (token.range.start() - first_physical_line_start) - .into(), - token_end_within_physical_line: (token.range.end() - current_physical_line_start) - .into(), + token_start_within_physical_line: i64::try_from( + usize::from(token.range.start()) - first_physical_line_start, + ) + .expect("Lines are expected to be relatively short."), + token_end_within_physical_line: i64::try_from( + usize::from(token.range.end()) - current_physical_line_start, + ) + .expect("Lines are expected to be relatively short."), line: locator.full_lines(token.range), }); @@ -102,7 +105,7 @@ fn get_token_infos<'a>(logical_line: &LogicalLine, locator: &'a Locator) -> Vec< TokenKind::NonLogicalNewline | TokenKind::Newline ) { current_line_idx += 1; - first_physical_line_start = token.range.end(); + first_physical_line_start = token.range.end().into(); } else { first_physical_line_start = current_physical_line_start; } @@ -114,10 +117,11 @@ fn get_token_infos<'a>(logical_line: &LogicalLine, locator: &'a Locator) -> Vec< /// Return the amount of indentation of the given line. /// Tabs are expanded to the next multiple of 8. -fn expand_indent(line: &str) -> usize { +fn expand_indent(line: &str) -> i64 { if !line.contains('\t') { // If there are no tabs in the line, return the leading space count - return line.len() - line.trim_start().len(); + return i64::try_from(line.len() - line.trim_start().len()) + .expect("Line length to be relatively small."); } let mut indent = 0; @@ -142,6 +146,9 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( indent_char: char, indent_size: usize, ) { + // The pycodestyle implementation makes use of negative values, + // converting the indent_size type at the start avoids converting it multiple times later. + let indent_size = i64::try_from(indent_size).expect("Indent size to be relatively small."); let token_infos = get_token_infos(logical_line, locator); let nb_physical_lines = if let Some(last_token_info) = token_infos.last() { 1 + last_token_info.start_physical_line_idx @@ -172,9 +179,9 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( let mut row = 0; let mut depth = 0; let valid_hangs = if indent_char == '\t' { - vec![indent_size as i64, indent_size as i64 * 2] + vec![indent_size, indent_size * 2] } else { - vec![indent_size as i64] + vec![indent_size] }; // Remember how many brackets were opened on each line. let mut parens = vec![0; nb_physical_lines]; @@ -187,7 +194,7 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( let mut hang: i64 = 0; let mut hanging_indent: bool = false; // Visual indents - let mut indent_chances: Vec = Vec::new(); + let mut indent_chances: Vec = Vec::new(); let mut last_indent = start_indent_level; let mut visual_indent = false; let mut last_token_multiline = false; @@ -218,7 +225,7 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( last_indent = token_info.token_start_within_physical_line; // Record the initial indent. - rel_indent[row] = expand_indent(token_info.line) as i64 - start_indent_level as i64; + rel_indent[row] = expand_indent(token_info.line) - start_indent_level; // Is the indent relative to an opening bracket line ? for open_row in open_rows[depth].iter().rev() { @@ -254,8 +261,7 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( if !visual_indent { // TODO: Raise E128. } - } else if hanging_indent || (indent_next && rel_indent[row] == (2 * indent_size) as i64) - { + } else if hanging_indent || (indent_next && rel_indent[row] == (2 * indent_size)) { // hanging indent is verified if is_closing_bracket && !hang_closing { // TODO: Raise E123. @@ -280,7 +286,7 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( // TODO: Raise 131. } else { hangs[depth] = Some(hang); - if hang > indent_size as i64 { + if hang > indent_size { // TODO: Raise 126. } else { // TODO: Raise E121. @@ -322,7 +328,8 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( { indent_chances.push(token_info.token_end_within_physical_line + 1); } else if matches!(token.kind, TokenKind::Colon) - && token_info.line[token_info.token_end_within_physical_line..] + && token_info.line[usize::try_from(token_info.token_end_within_physical_line) + .expect("Line to be relatively short.")..] .trim() .is_empty() { From 3e74e8d1777fb5ab2837ef9dc3a08f23d36eb1b1 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Fri, 3 Nov 2023 00:14:47 +0900 Subject: [PATCH 05/21] Began adding the other E12 rules, however it seems like the pycodestyle implementation is broken. --- .../test/fixtures/pycodestyle/E12.py | 128 +++++++++- ...n_line_missing_indentation_or_outdented.rs | 230 +++++++++++++++++- ruff.schema.json | 11 +- 3 files changed, 356 insertions(+), 13 deletions(-) diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py index 1becd795329e2..bb98c9a6c7478 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py @@ -1,3 +1,13 @@ +#: E121 +print "E121", ( + "dent") + +#: E121 +result = { + 'key1': 'value', + 'key2': 'value', +} + #: E122 print("E122", ( "dent")) @@ -58,13 +68,53 @@ 'Intended Audience :: Developers', ]) -#: E701:1:8 E122:2:1 E203:4:8 E128:5:1 +#: E122:2:1 E128:5:1 if True:\ print(True) print(a , end=' ') +#: E123 +my_list = [ + 1, 2, 3, + 4, 5, 6, + ] + +#: E123 +print "E123", ( + "bad", "hanging", "close" + ) + +#: E123 +result = { + 'foo': [ + 'bar', { + 'baz': 'frop', + } + ] + } + +#: E123 +result = some_function_that_takes_arguments( + 'a', 'b', 'c', + 'd', 'e', 'f', + ) + +#: E123 +if True: + def example_issue254(): + return [node.copy( + ( + replacement + # First, look at all the node's current children. + for child in node.children + # Replace them. + for replacement in replace(child) + ), + dict(name=token.undefined) + )] + #: E124 print ("E124", ("visual", "indent_two" @@ -159,6 +209,82 @@ def qualify_by_address( """.strip().split(): print(foo) +#: E126 +print "E126", ( + "dent") + +#: E126 +print "E126", ( + "dent") + +#: E126 +my_list = [ + 1, 2, 3, + 4, 5, 6, + ] + +#: E126 +rv.update(dict.fromkeys(( + 'qualif_nr', 'reasonComment_en', 'reasonComment_fr', + 'reasonComment_de', 'reasonComment_it'), + '?'), + "foo") + +#: E126 +abricot = 3 + \ + 4 + \ + 5 + 6 +#: E126 +part = set_mimetype(( + a.get('mime_type', 'text')), + 'default') + +#: E126 +my_list = [ + 1, 2, 3, + 4, 5, 6, + ] + +#: E126 +abris = 3 + \ + 4 + \ + 5 + 6 + +#: E126 +fixed = re.sub(r'\t+', ' ', target[c::-1], 1)[::-1] + \ + target[c + 1:] + +#: E126 +rv.update(dict.fromkeys(( + 'qualif_nr', 'reasonComment_en', 'reasonComment_fr', + 'reasonComment_de', 'reasonComment_it'), + '?'), + "foo") + +#: E126 +eat_a_dict_a_day({ + "foo": "bar", +}) + +#: E126 +if ( + x == ( + 3 + ) + or y == 4): + pass + +#: E126 +if ( + x == ( + 3 + ) + or x == ( + 3) + or y == 4): + pass + + #: E127 print ("E127", ("over-", "over-indent")) diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs index 92bb68ba2547d..ca1287f4ba0ea 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs @@ -8,6 +8,39 @@ use ruff_python_parser::TokenKind; use ruff_source_file::Locator; use ruff_text_size::{Ranged, TextRange}; +/// ## What it does +/// Checks for lines less indented than they should be for hanging indents. +/// +/// ## Why is this bad? +/// This makes reading continuation line harder. +/// +/// ## Example +/// ```python +/// result = { +/// 'key1': 'value', +/// 'key2': 'value', +/// } +/// ``` +/// +/// Use instead: +/// ```python +/// result = { +/// 'key1': 'value', +/// 'key2': 'value', +/// } +/// ``` +/// +/// [PEP 8]: https://www.python.org/dev/peps/pep-0008/#indentation +#[violation] +pub struct UnderIndentedHangingIndent; + +impl Violation for UnderIndentedHangingIndent { + #[derive_message_formats] + fn message(&self) -> String { + format!("Hanging indent under-indented.") + } +} + /// ## What it does /// Checks for continuation lines not indented as far as they should be or indented too far. /// @@ -37,6 +70,162 @@ impl Violation for MissingOrOutdentedIndentation { } } +/// ## What it does +/// Checks for brackets that do not match the indentation level of the line that their opening bracket started on. +/// +/// ## Why is this bad? +/// This makes identifying brakets pair harder. +/// +/// ## Example +/// ```python +/// result = function_that_takes_arguments( +/// 'a', 'b', 'c', +/// 'd', 'e', 'f', +/// ) +/// ``` +/// +/// Use instead: +/// ```python +/// result = function_that_takes_arguments( +/// 'a', 'b', 'c', +/// 'd', 'e', 'f', +/// ) +/// ``` +/// +/// [PEP 8]: https://www.python.org/dev/peps/pep-0008/#indentation +#[violation] +pub struct ClosingBracketNotMatchingOpeningBracketIndentation; + +impl Violation for ClosingBracketNotMatchingOpeningBracketIndentation { + #[derive_message_formats] + fn message(&self) -> String { + format!("Closing bracket not matching its corresponding opening bracket's indentation.") + } +} + +/// ## What it does +/// Checks for closing brackets that do not match the indentation of the opening bracket. +/// +/// ## Why is this bad? +/// This makes identifying brakets pair harder. +/// +/// ## Example +/// ```python +/// result = function_that_takes_arguments('a', 'b', 'c', +/// 'd', 'e', 'f', +/// ) +/// ``` +/// +/// Use instead: +/// ```python +/// result = function_that_takes_arguments('a', 'b', 'c', +/// 'd', 'e', 'f', +/// ) +/// ``` +/// +/// [PEP 8]: https://www.python.org/dev/peps/pep-0008/#indentation +#[violation] +pub struct ClosingBracketNotMatchingOpeningBracketVisualIndentation; + +impl Violation for ClosingBracketNotMatchingOpeningBracketVisualIndentation { + #[derive_message_formats] + fn message(&self) -> String { + format!( + "Closing bracket not matching its corresponding opening bracket's visual indentation." + ) + } +} + +/// ## What it does +/// Checks for continuation lines with the same indent as the next logical line. +/// +/// ## Why is this bad? +/// Continuation lines should not be indented at the same level as the next logical line. +/// Instead, they should be indented to one more level so as to distinguish them from the next line. +/// +/// ## Example +/// ```python +/// if user is not None and user.is_admin or \ +/// user.name == 'Grant': +/// blah = 'yeahnah' +/// ``` +/// +/// Use instead: +/// ```python +/// if user is not None and user.is_admin or \ +/// user.name == 'Grant': +/// blah = 'yeahnah' +/// ``` +/// +/// [PEP 8]: https://www.python.org/dev/peps/pep-0008/#indentation +#[violation] +pub struct ContinuationLineIndentSameAsNextLogicalLine; + +impl Violation for ContinuationLineIndentSameAsNextLogicalLine { + #[derive_message_formats] + fn message(&self) -> String { + format!("Continuation line with same indent as next logical line.") + } +} + +/// ## What it does +/// Checks for continuation line over-indented for hanging indent. +/// +/// ## Why is this bad? +/// This makes distinguishing continuation lines harder. +/// +/// ## Example +/// ```python +/// print("Python", ( +/// "Rules")) +/// ``` +/// +/// Use instead: +/// ```python +/// print("Python", ( +/// "Rules")) +/// ``` +/// +/// [PEP 8]: https://www.python.org/dev/peps/pep-0008/#indentation +#[violation] +pub struct ContinuationLineOverIndentedForHangingIndent; + +impl Violation for ContinuationLineOverIndentedForHangingIndent { + #[derive_message_formats] + fn message(&self) -> String { + format!("Continuation line over indented for hanging indent.") + } +} + +/// ## What it does +/// Checks for continuation line over-indented for visual indent. +/// +/// ## Why is this bad? +/// This makes distinguishing continuation lines harder. +/// +/// ## Example +/// ```python +/// print("Python", ("Hello", +/// "World")) +/// ``` +/// +/// Use instead: +/// ```python +/// print("Python", ("Hello", +/// "World")) +/// ``` +/// +/// [PEP 8]: https://www.python.org/dev/peps/pep-0008/#indentation +#[violation] +pub struct ContinuationLineOverIndentedForVisualIndent; + +impl Violation for ContinuationLineOverIndentedForVisualIndent { + #[derive_message_formats] + fn message(&self) -> String { + format!("Continuation line over indented for visual indent.") + } +} + #[derive(Debug)] struct TokenInfo<'a> { start_physical_line_idx: usize, @@ -138,7 +327,7 @@ fn expand_indent(line: &str) -> i64 { indent } -/// E122 +/// E121 E122 E123 E124 E125 E126 E127 E128 E129 E133 pub(crate) fn continuation_line_missing_indentation_or_outdented( context: &mut LogicalLinesContext, logical_line: &LogicalLine, @@ -247,7 +436,12 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( if is_closing_bracket && indent[depth] != 0 { // Closing bracket for visual indent. if token_info.token_start_within_physical_line != indent[depth] { - // TODO: Raise E124. + // E124. + let diagnostic = Diagnostic::new( + ClosingBracketNotMatchingOpeningBracketVisualIndentation, + token.range, + ); + context.push_diagnostic(diagnostic); } } else if is_closing_bracket && hang == 0 { // Closing bracket matches indentation of opening bracket's line @@ -264,7 +458,12 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( } else if hanging_indent || (indent_next && rel_indent[row] == (2 * indent_size)) { // hanging indent is verified if is_closing_bracket && !hang_closing { - // TODO: Raise E123. + // E123. + let diagnostic = Diagnostic::new( + ClosingBracketNotMatchingOpeningBracketIndentation, + token.range, + ); + context.push_diagnostic(diagnostic); } hangs[depth] = Some(hang); } else if visual_indent { @@ -275,21 +474,27 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( if hang <= 0 { // E122. let diagnostic = Diagnostic::new(MissingOrOutdentedIndentation, token.range); - // if autofix_after_open_bracket { - // diagnostic - // .set_fix(Fix::automatic(Edit::range_deletion(diagnostic.range()))); - // } context.push_diagnostic(diagnostic); } else if indent[depth] != 0 { - // TODO: Raise E127. + // E127 + let diagnostic = + Diagnostic::new(ContinuationLineOverIndentedForVisualIndent, token.range); + context.push_diagnostic(diagnostic); } else if !is_closing_bracket && hangs[depth].is_some_and(|hang| hang > 0) { // TODO: Raise 131. } else { hangs[depth] = Some(hang); if hang > indent_size { - // TODO: Raise 126. + // E126 + let diagnostic = Diagnostic::new( + ContinuationLineOverIndentedForHangingIndent, + token.range, + ); + context.push_diagnostic(diagnostic); } else { - // TODO: Raise E121. + // E121. + let diagnostic = Diagnostic::new(UnderIndentedHangingIndent, token.range); + context.push_diagnostic(diagnostic); } } } @@ -398,7 +603,10 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( if visual_indent { // TODO: Raise 129. } else { - // TODO: Raise 125. + // E125. + let diagnostic = + Diagnostic::new(ContinuationLineIndentSameAsNextLogicalLine, token.range); + context.push_diagnostic(diagnostic); } } } diff --git a/ruff.schema.json b/ruff.schema.json index 121211d0e3583..4ca4f02c585a2 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -2638,7 +2638,16 @@ "E116", "E117", "E12", + "E121", "E122", + "E123", + "E124", + "E125", + "E126", + "E127", + "E128", + "E129", + "E133", "E2", "E20", "E201", @@ -3594,4 +3603,4 @@ "type": "string" } } -} \ No newline at end of file +} From 239c164c3ce39f27332ad6258e900fb5d092bc68 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Fri, 3 Nov 2023 00:32:54 +0900 Subject: [PATCH 06/21] Remove other rules' mentions. --- ...n_line_missing_indentation_or_outdented.rs | 59 ++++--------------- 1 file changed, 13 insertions(+), 46 deletions(-) diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs index 92bb68ba2547d..b81f3f401b6ce 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs @@ -196,14 +196,11 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( // Visual indents let mut indent_chances: Vec = Vec::new(); let mut last_indent = start_indent_level; - let mut visual_indent = false; + let mut visual_indent; let mut last_token_multiline = false; // For each depth, memorize the visual indent column. let mut indent = vec![start_indent_level]; - // TODO: config option: hang closing bracket instead of matching indentation of opening bracket's line. - let hang_closing = false; - for (token, token_info) in zip(logical_line.tokens(), token_infos) { let mut is_newline = row < token_info.start_physical_line_idx; if is_newline { @@ -244,28 +241,13 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( && hang > 0 && indent_chances.contains(&token_info.token_start_within_physical_line); - if is_closing_bracket && indent[depth] != 0 { - // Closing bracket for visual indent. - if token_info.token_start_within_physical_line != indent[depth] { - // TODO: Raise E124. - } - } else if is_closing_bracket && hang == 0 { - // Closing bracket matches indentation of opening bracket's line - if hang_closing { - // TODO: Raise E133. - } - } else if indent[depth] != 0 - && token_info.token_start_within_physical_line < indent[depth] + if (hang == 0 || indent[depth] != 0) && is_closing_bracket + || (indent[depth] != 0 + && token_info.token_start_within_physical_line < indent[depth]) { // visual indent is broken - if !visual_indent { - // TODO: Raise E128. - } } else if hanging_indent || (indent_next && rel_indent[row] == (2 * indent_size)) { // hanging indent is verified - if is_closing_bracket && !hang_closing { - // TODO: Raise E123. - } hangs[depth] = Some(hang); } else if visual_indent { // Visual indent is verified. @@ -280,17 +262,11 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( // .set_fix(Fix::automatic(Edit::range_deletion(diagnostic.range()))); // } context.push_diagnostic(diagnostic); - } else if indent[depth] != 0 { - // TODO: Raise E127. - } else if !is_closing_bracket && hangs[depth].is_some_and(|hang| hang > 0) { - // TODO: Raise 131. + } else if indent[depth] != 0 + || !is_closing_bracket && hangs[depth].is_some_and(|hang| hang > 0) + { } else { hangs[depth] = Some(hang); - if hang > indent_size { - // TODO: Raise 126. - } else { - // TODO: Raise E121. - } } } } @@ -317,14 +293,13 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( token.kind, TokenKind::Assert | TokenKind::Raise | TokenKind::With ) - { - indent_chances.push(token_info.token_end_within_physical_line + 1); - } // Special case for the "if" statement because "if (".len() == 4 - else if indent_chances.is_empty() - && row == 0 - && depth == 0 - && matches!(token.kind, TokenKind::If) + || ( + indent_chances.is_empty() + && row == 0 + && depth == 0 + && matches!(token.kind, TokenKind::If) + ) { indent_chances.push(token_info.token_end_within_physical_line + 1); } else if matches!(token.kind, TokenKind::Colon) @@ -393,13 +368,5 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( if last_token_multiline { rel_indent[token_info.end_physical_line_idx] = rel_indent[row]; } - - if indent_next && expand_indent(token_info.line) == start_indent_level + indent_size { - if visual_indent { - // TODO: Raise 129. - } else { - // TODO: Raise 125. - } - } } } From c925bcfd0210a7c1fbf7f6e739f352f9d4726b67 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Fri, 3 Nov 2023 11:59:03 +0900 Subject: [PATCH 07/21] Revert "Remove other rules' mentions." This reverts commit 239c164c3ce39f27332ad6258e900fb5d092bc68. --- ...n_line_missing_indentation_or_outdented.rs | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs index 8688700872629..ca1287f4ba0ea 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs @@ -385,11 +385,14 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( // Visual indents let mut indent_chances: Vec = Vec::new(); let mut last_indent = start_indent_level; - let mut visual_indent; + let mut visual_indent = false; let mut last_token_multiline = false; // For each depth, memorize the visual indent column. let mut indent = vec![start_indent_level]; + // TODO: config option: hang closing bracket instead of matching indentation of opening bracket's line. + let hang_closing = false; + for (token, token_info) in zip(logical_line.tokens(), token_infos) { let mut is_newline = row < token_info.start_physical_line_idx; if is_newline { @@ -449,6 +452,9 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( && token_info.token_start_within_physical_line < indent[depth] { // visual indent is broken + if !visual_indent { + // TODO: Raise E128. + } } else if hanging_indent || (indent_next && rel_indent[row] == (2 * indent_size)) { // hanging indent is verified if is_closing_bracket && !hang_closing { @@ -516,13 +522,14 @@ pub(crate) fn continuation_line_missing_indentation_or_outdented( token.kind, TokenKind::Assert | TokenKind::Raise | TokenKind::With ) + { + indent_chances.push(token_info.token_end_within_physical_line + 1); + } // Special case for the "if" statement because "if (".len() == 4 - || ( - indent_chances.is_empty() - && row == 0 - && depth == 0 - && matches!(token.kind, TokenKind::If) - ) + else if indent_chances.is_empty() + && row == 0 + && depth == 0 + && matches!(token.kind, TokenKind::If) { indent_chances.push(token_info.token_end_within_physical_line + 1); } else if matches!(token.kind, TokenKind::Colon) From 206b4dd4406bb1ae210ffd12a5c85ab4ad37b89b Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Fri, 3 Nov 2023 12:07:02 +0900 Subject: [PATCH 08/21] Add rule to KNOWN_FORMATTING_VIOLATIONS --- scripts/check_docs_formatted.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/check_docs_formatted.py b/scripts/check_docs_formatted.py index 78334cc3b5f9a..a99eac45dc093 100755 --- a/scripts/check_docs_formatted.py +++ b/scripts/check_docs_formatted.py @@ -36,6 +36,7 @@ "indent-with-spaces", "indentation-with-invalid-multiple", "line-too-long", + "missing-or-outdented-indentation", "missing-trailing-comma", "missing-whitespace", "missing-whitespace-after-keyword", From de4aec5402543b9e7365ee158b62caadecd3bed3 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Fri, 3 Nov 2023 12:28:55 +0900 Subject: [PATCH 09/21] Rename file to account for future E12 rules. --- .../ruff_linter/src/checkers/logical_lines.rs | 17 +++++------------ ...on_or_outdented.rs => continuation_lines.rs} | 2 +- .../pycodestyle/rules/logical_lines/mod.rs | 4 ++-- 3 files changed, 8 insertions(+), 15 deletions(-) rename crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/{continuation_line_missing_indentation_or_outdented.rs => continuation_lines.rs} (99%) diff --git a/crates/ruff_linter/src/checkers/logical_lines.rs b/crates/ruff_linter/src/checkers/logical_lines.rs index 28382971e5f24..6ce696631b02d 100644 --- a/crates/ruff_linter/src/checkers/logical_lines.rs +++ b/crates/ruff_linter/src/checkers/logical_lines.rs @@ -7,11 +7,10 @@ use ruff_text_size::{Ranged, TextRange}; use crate::registry::AsRule; use crate::rules::pycodestyle::rules::logical_lines::{ - continuation_line_missing_indentation_or_outdented, extraneous_whitespace, indentation, - missing_whitespace, missing_whitespace_after_keyword, missing_whitespace_around_operator, - space_after_comma, space_around_operator, whitespace_around_keywords, - whitespace_around_named_parameter_equals, whitespace_before_comment, - whitespace_before_parameters, LogicalLines, TokenFlags, + continuation_lines, extraneous_whitespace, indentation, missing_whitespace, + missing_whitespace_after_keyword, missing_whitespace_around_operator, space_after_comma, + space_around_operator, whitespace_around_keywords, whitespace_around_named_parameter_equals, + whitespace_before_comment, whitespace_before_parameters, LogicalLines, TokenFlags, }; use crate::settings::LinterSettings; @@ -89,13 +88,7 @@ pub(crate) fn check_logical_lines( let indent_size = 4; - continuation_line_missing_indentation_or_outdented( - &mut context, - &line, - locator, - indent_char, - indent_size, - ); + continuation_lines(&mut context, &line, locator, indent_char, indent_size); for kind in indentation( &line, diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs similarity index 99% rename from crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs rename to crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs index b81f3f401b6ce..c9bdd0b982601 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_line_missing_indentation_or_outdented.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs @@ -139,7 +139,7 @@ fn expand_indent(line: &str) -> i64 { } /// E122 -pub(crate) fn continuation_line_missing_indentation_or_outdented( +pub(crate) fn continuation_lines( context: &mut LogicalLinesContext, logical_line: &LogicalLine, locator: &Locator, diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/mod.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/mod.rs index c99589f56c953..77e9dbeaae37f 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/mod.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/mod.rs @@ -1,4 +1,4 @@ -pub(crate) use continuation_line_missing_indentation_or_outdented::*; +pub(crate) use continuation_lines::*; pub(crate) use extraneous_whitespace::*; pub(crate) use indentation::*; pub(crate) use missing_whitespace::*; @@ -21,7 +21,7 @@ use ruff_python_parser::TokenKind; use ruff_python_trivia::is_python_whitespace; use ruff_source_file::Locator; -mod continuation_line_missing_indentation_or_outdented; +mod continuation_lines; mod extraneous_whitespace; mod indentation; mod missing_whitespace; From 0bc5d296d72cb5c9769b1ff8159b8e89b407e766 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Sun, 5 Nov 2023 11:03:12 +0900 Subject: [PATCH 10/21] Remove non-E122 tests. --- .../test/fixtures/pycodestyle/E12.py | 223 ------------------ 1 file changed, 223 deletions(-) diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py index 1becd795329e2..4365025038511 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py @@ -64,226 +64,3 @@ print(a , end=' ') - -#: E124 -print ("E124", ("visual", - "indent_two" - )) - -#: E124 -print ("E124", ("visual", - "indent_five" -)) - -#: E124 -a = (123, -) - -#: E124 -my_list = [1, 2, 3, - 4, 5, 6, -] - -#: E124 -my_list = [1, 2, 3, - 4, 5, 6, - ] -#: E124 -result = some_function_that_takes_arguments('a', 'b', 'c', - 'd', 'e', 'f', -) - -#: E124 -fooff(aaaa, - cca( - vvv, - dadd - ), fff, -) - -#: E124 -fooff(aaaa, - ccaaa( - vvv, - dadd - ), - fff, -) - -#: E124 -d = dict('foo', - help="exclude files or directories which match these " - "comma separated patterns (default: %s)" % DEFAULT_EXCLUDE - ) - -#: E124 E128 E128 -if line_removed: - self.event(cr, uid, - name="Removing the option for contract", - description="contract line has been removed", - ) - -#: E124 E127 E127 -if line_removed: - self.event(cr, uid, - name="Removing the option for contract", - description="contract line has been removed", - ) - -#: E125 -if foo is None and bar is "frop" and \ - blah == 'yeah': - blah = 'yeahnah' - -#: E125 -# Further indentation required as indentation is not distinguishable -def long_function_name( - var_one, var_two, var_three, - var_four): - print(var_one) - -#: E125 -def qualify_by_address( - self, cr, uid, ids, context=None, - params_to_check=frozenset(QUALIF_BY_ADDRESS_PARAM)): - """ This gets called by the web server """ - -#: E125:2:5 E125:8:5 -if (""" - """): - pass - -for foo in """ - abc - 123 - """.strip().split(): - print(foo) - -#: E127 -print ("E127", ("over-", - "over-indent")) - -#: E127 -foo(1, 2, 3, - 4, 5, 6) -#: E127 -foo(1, 2, 3, - 4, 5, 6) -#: E127 -foo(1, 2, 3, - 4, 5, 6) -#: E127 -foo(1, 2, 3, - 4, 5, 6) -#: E127 -foo(1, 2, 3, - 4, 5, 6) -#: E127 -foo(1, 2, 3, - 4, 5, 6) -#: E127 -foo(1, 2, 3, - 4, 5, 6) -#: E127 -foo(1, 2, 3, - 4, 5, 6) -#: E127 -foo(1, 2, 3, - 4, 5, 6) - -#: E127 -rv.update(d=('a', 'b', 'c'), - e=42) -# -#: E127 W503 -rv.update(d=('a' + 'b', 'c'), - e=42, f=42 - + 42) -#: E127 W503 -input1 = {'a': {'calc': 1 + 2}, 'b': 1 - + 42} - -#: E127:4:12 -def foo(): - pass - raise 123 + \ - 123 - -#: E127:4:13 -class Eggs: - pass - assert 123456 == \ - 123456 - -#: E127:4:11 -def f1(): - print('foo') - with open('/path/to/some/file/you/want/to/read') as file_1, \ - open('/path/to/some/file/being/written', 'w') as file_2: - file_2.write(file_1.read()) - -#: E127:5:11 -def f1(): - print('foo') - with open('/path/to/some/file/you/want/to/read') as file_1, \ - open('/path/to/some/file/being/written', 'w') as file_2, \ - open('later-misindent'): - file_2.write(file_1.read()) - -#: E128 E128 -if line_removed: - self.event(cr, uid, - name="Removing the option for contract", - description="contract line has been removed", - ) - -#: E128 -print ("E128", ("visual", - "hanging")) - -#: E128 -print ("E128", ("under-", - "under-indent")) - -#: E128 -# Arguments on first line forbidden when not using vertical alignment -foo = long_function_name(var_one, var_two, - var_three, var_four) - -#: E128 -print('l.%s\t%s\t%s\t%r' % - (token[2][0], pos, tokenize.tok_name[token[0]], token[1])) - -#: E128 -def qualify_by_address(self, cr, uid, ids, context=None, - params_to_check=frozenset(QUALIF_BY_ADDRESS_PARAM)): - """ This gets called by the web server """ - -#: E128 -foo(1, 2, 3, -4, 5, 6) -#: E128 -foo(1, 2, 3, - 4, 5, 6) -#: E128 -foo(1, 2, 3, - 4, 5, 6) -#: E128 -foo(1, 2, 3, - 4, 5, 6) - -#: E128 W503 -rv.update(d=('a' + 'b', 'c'), - e=42, f=(42 - + 42)) - -#: E129 W503 -if (row < 0 or self.moduleCount <= row - or col < 0 or self.moduleCount <= col): - raise Exception("%s,%s - %s" % (row, col, self.moduleCount)) - -#: E129 -if (a == 2 - or b == "abc def ghi" - "jkl mno"): - return True From c8ce8d5f0becad30b60bbae283db4850d56d35c0 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Sun, 5 Nov 2023 11:54:28 +0900 Subject: [PATCH 11/21] Add E128, E129, E131 and E133 rules. --- .../rules/logical_lines/continuation_lines.rs | 152 +++++++++++++++++- 1 file changed, 147 insertions(+), 5 deletions(-) diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs index c8a66a8c093db..06a0c16829de6 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs @@ -226,6 +226,135 @@ impl Violation for ContinuationLineOverIndentedForVisualIndent { } } +/// ## What it does +/// Checks for continuation line under-indented for visual indent. +/// +/// ## Why is this bad? +/// This makes distinguishing continuation lines harder. +/// +/// ## Example +/// ```python +/// print("Python", ("Hello", +/// "World")) +/// ``` +/// +/// Use instead: +/// ```python +/// print("Python", ("Hello", +/// "World")) +/// ``` +/// +/// [PEP 8]: https://www.python.org/dev/peps/pep-0008/#indentation +#[violation] +pub struct ContinuationLineUnderIndentedForVisualIndent; + +impl Violation for ContinuationLineUnderIndentedForVisualIndent { + #[derive_message_formats] + fn message(&self) -> String { + format!("Continuation line under indented for visual indent.") + } +} + +/// ## What it does +/// Checks for lines visually indented with same indent as the next logical line. +/// +/// ## Why is this bad? +/// This can make reading continuation lines harder. +/// +/// ## Example +/// ```python +/// if (row < 0 or module_count <= row or +/// col < 0 or module_count <= col): +/// raise Exception("%s,%s - %s" % (row, col, self.moduleCount)) +/// ``` +/// +/// Use instead: +/// ```python +/// if (row < 0 or module_count <= row or +/// col < 0 or module_count <= col): +/// raise Exception("%s,%s - %s" % (row, col, self.moduleCount)) +/// ``` +/// +/// [PEP 8]: https://www.python.org/dev/peps/pep-0008/#indentation +#[violation] +pub struct VisuallyIndentedLineWithSameIndentAsNextLogicalLine; + +impl Violation for VisuallyIndentedLineWithSameIndentAsNextLogicalLine { + #[derive_message_formats] + fn message(&self) -> String { + format!("Visually indented line has the same indentation as the next logical line.") + } +} + +/// ## What it does +/// Checks for continuation lines unaligned for hanging indent. +/// +/// ## Why is this bad? +/// This can make reading continuation lines harder. +/// +/// ## Example +/// ```python +/// my_dict = { +/// "key": "value", +/// "long": "the quick brown fox jumps over the " +/// "lazy dog", +/// } +/// ``` +/// +/// Use instead: +/// ```python +/// my_dict = { +/// "key": "value", +/// "long": "the quick brown fox jumps over the " +/// "lazy dog", +/// } +/// ``` +/// +/// [PEP 8]: https://www.python.org/dev/peps/pep-0008/#indentation +#[violation] +pub struct ContinuationLineUnalignedForHangingIndent; + +impl Violation for ContinuationLineUnalignedForHangingIndent { + #[derive_message_formats] + fn message(&self) -> String { + format!("Continuation line unaligned for hanging indent.") + } +} + +/// ## What it does +/// Checks for closing bracket missing indentation. +/// This error only occurs if the --hang-closing flag is used, switching the default behavior of closing brackets so that they require hanging indents. +/// +/// ## Why is this bad? +/// This can make reading continuation lines harder. +/// +/// ## Example +/// ```python +/// my_list = [ +/// 1, 2, 3, +/// 4, 5, 6, +/// ] +/// ``` +/// +/// Use instead: +/// ```python +/// my_list = [ +/// 1, 2, 3, +/// 4, 5, 6, +/// ] +/// ``` +/// +/// [PEP 8]: https://www.python.org/dev/peps/pep-0008/#indentation +#[violation] +pub struct ClosingBracketMissingIndentation; + +impl Violation for ClosingBracketMissingIndentation { + #[derive_message_formats] + fn message(&self) -> String { + format!("Continuation line unaligned for hanging indent.") + } +} + #[derive(Debug)] struct TokenInfo<'a> { start_physical_line_idx: usize, @@ -327,7 +456,7 @@ fn expand_indent(line: &str) -> i64 { indent } -/// E121 E122 E123 E124 E125 E126 E127 E128 E129 E133 +/// E121 E122 E123 E124 E125 E126 E127 E128 E129 E131 E133 pub(crate) fn continuation_lines( context: &mut LogicalLinesContext, logical_line: &LogicalLine, @@ -446,14 +575,19 @@ pub(crate) fn continuation_lines( } else if is_closing_bracket && hang == 0 { // Closing bracket matches indentation of opening bracket's line if hang_closing { - // TODO: Raise E133. + // E133. + let diagnostic = Diagnostic::new(ClosingBracketMissingIndentation, token.range); + context.push_diagnostic(diagnostic); } } else if indent[depth] != 0 && token_info.token_start_within_physical_line < indent[depth] { // visual indent is broken if !visual_indent { - // TODO: Raise E128. + // E128 + let diagnostic = + Diagnostic::new(ContinuationLineUnderIndentedForVisualIndent, token.range); + context.push_diagnostic(diagnostic); } } else if hanging_indent || (indent_next && rel_indent[row] == (2 * indent_size)) { // hanging indent is verified @@ -481,7 +615,10 @@ pub(crate) fn continuation_lines( Diagnostic::new(ContinuationLineOverIndentedForVisualIndent, token.range); context.push_diagnostic(diagnostic); } else if !is_closing_bracket && hangs[depth].is_some_and(|hang| hang > 0) { - // TODO: Raise 131. + // E131 + let diagnostic = + Diagnostic::new(ContinuationLineUnalignedForHangingIndent, token.range); + context.push_diagnostic(diagnostic); } else { hangs[depth] = Some(hang); if hang > indent_size { @@ -601,7 +738,12 @@ pub(crate) fn continuation_lines( if indent_next && expand_indent(token_info.line) == start_indent_level + indent_size { if visual_indent { - // TODO: Raise 129. + // E129. + let diagnostic = Diagnostic::new( + VisuallyIndentedLineWithSameIndentAsNextLogicalLine, + token.range, + ); + context.push_diagnostic(diagnostic); } else { // E125. let diagnostic = From 9cb3af12186a86e78c0e059fc340d6c11a59127f Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Sun, 5 Nov 2023 12:14:54 +0900 Subject: [PATCH 12/21] Register E12/E13 rules. --- crates/ruff_linter/src/codes.rs | 20 +++++++++++++++ crates/ruff_linter/src/registry.rs | 10 ++++++++ .../ruff_linter/src/rules/pycodestyle/mod.rs | 25 +++++++++++++++++++ crates/ruff_workspace/src/configuration.rs | 10 ++++++++ 4 files changed, 65 insertions(+) diff --git a/crates/ruff_linter/src/codes.rs b/crates/ruff_linter/src/codes.rs index 73a63db71db5e..0cb35c845ea7b 100644 --- a/crates/ruff_linter/src/codes.rs +++ b/crates/ruff_linter/src/codes.rs @@ -81,8 +81,28 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { #[allow(deprecated)] (Pycodestyle, "E117") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::OverIndented), #[allow(deprecated)] + (Pycodestyle, "E121") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::UnderIndentedHangingIndent), + #[allow(deprecated)] (Pycodestyle, "E122") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingOrOutdentedIndentation), #[allow(deprecated)] + (Pycodestyle, "E123") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::ClosingBracketNotMatchingOpeningBracketIndentation), + #[allow(deprecated)] + (Pycodestyle, "E124") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::ClosingBracketNotMatchingOpeningBracketVisualIndentation), + #[allow(deprecated)] + (Pycodestyle, "E125") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::ContinuationLineIndentSameAsNextLogicalLine), + #[allow(deprecated)] + (Pycodestyle, "E126") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::ContinuationLineOverIndentedForHangingIndent), + #[allow(deprecated)] + (Pycodestyle, "E127") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::ContinuationLineOverIndentedForVisualIndent), + #[allow(deprecated)] + (Pycodestyle, "E128") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::ContinuationLineUnderIndentedForVisualIndent), + #[allow(deprecated)] + (Pycodestyle, "E129") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::VisuallyIndentedLineWithSameIndentAsNextLogicalLine), + #[allow(deprecated)] + (Pycodestyle, "E131") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::ContinuationLineUnalignedForHangingIndent), + #[allow(deprecated)] + (Pycodestyle, "E133") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::ClosingBracketMissingIndentation), + #[allow(deprecated)] (Pycodestyle, "E201") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::WhitespaceAfterOpenBracket), #[allow(deprecated)] (Pycodestyle, "E202") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::WhitespaceBeforeCloseBracket), diff --git a/crates/ruff_linter/src/registry.rs b/crates/ruff_linter/src/registry.rs index 26409341a9741..f74a553029fd4 100644 --- a/crates/ruff_linter/src/registry.rs +++ b/crates/ruff_linter/src/registry.rs @@ -304,7 +304,17 @@ impl Rule { Rule::ImplicitNamespacePackage | Rule::InvalidModuleName => LintSource::Filesystem, Rule::IndentationWithInvalidMultiple | Rule::IndentationWithInvalidMultipleComment + | Rule::UnderIndentedHangingIndent | Rule::MissingOrOutdentedIndentation + | Rule::ClosingBracketNotMatchingOpeningBracketIndentation + | Rule::ClosingBracketNotMatchingOpeningBracketVisualIndentation + | Rule::ContinuationLineIndentSameAsNextLogicalLine + | Rule::ContinuationLineOverIndentedForHangingIndent + | Rule::ContinuationLineOverIndentedForVisualIndent + | Rule::ContinuationLineUnderIndentedForVisualIndent + | Rule::VisuallyIndentedLineWithSameIndentAsNextLogicalLine + | Rule::ContinuationLineUnalignedForHangingIndent + | Rule::ClosingBracketMissingIndentation | Rule::MissingWhitespace | Rule::MissingWhitespaceAfterKeyword | Rule::MissingWhitespaceAroundArithmeticOperator diff --git a/crates/ruff_linter/src/rules/pycodestyle/mod.rs b/crates/ruff_linter/src/rules/pycodestyle/mod.rs index 14a69f5872c1a..144c537b1effd 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/mod.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/mod.rs @@ -122,7 +122,32 @@ mod tests { #[test_case(Rule::TooFewSpacesBeforeInlineComment, Path::new("E26.py"))] #[test_case(Rule::UnexpectedIndentation, Path::new("E11.py"))] #[test_case(Rule::UnexpectedIndentationComment, Path::new("E11.py"))] + #[test_case(Rule::UnderIndentedHangingIndent, Path::new("E12.py"))] #[test_case(Rule::MissingOrOutdentedIndentation, Path::new("E12.py"))] + #[test_case( + Rule::ClosingBracketNotMatchingOpeningBracketIndentation, + Path::new("E12.py") + )] + #[test_case( + Rule::ClosingBracketNotMatchingOpeningBracketVisualIndentation, + Path::new("E12.py") + )] + #[test_case(Rule::ContinuationLineIndentSameAsNextLogicalLine, Path::new("E12.py"))] + #[test_case( + Rule::ContinuationLineOverIndentedForHangingIndent, + Path::new("E12.py") + )] + #[test_case(Rule::ContinuationLineOverIndentedForVisualIndent, Path::new("E12.py"))] + #[test_case( + Rule::ContinuationLineUnderIndentedForVisualIndent, + Path::new("E12.py") + )] + #[test_case( + Rule::VisuallyIndentedLineWithSameIndentAsNextLogicalLine, + Path::new("E12.py") + )] + #[test_case(Rule::ContinuationLineUnalignedForHangingIndent, Path::new("E12.py"))] + #[test_case(Rule::ClosingBracketMissingIndentation, Path::new("E12.py"))] #[test_case(Rule::WhitespaceAfterOpenBracket, Path::new("E20.py"))] #[test_case(Rule::WhitespaceBeforeCloseBracket, Path::new("E20.py"))] #[test_case(Rule::WhitespaceBeforePunctuation, Path::new("E20.py"))] diff --git a/crates/ruff_workspace/src/configuration.rs b/crates/ruff_workspace/src/configuration.rs index b40c55d102311..870f8f17ee778 100644 --- a/crates/ruff_workspace/src/configuration.rs +++ b/crates/ruff_workspace/src/configuration.rs @@ -1106,7 +1106,17 @@ mod tests { Rule::MissingWhitespaceAroundBitwiseOrShiftOperator, Rule::MissingWhitespaceAroundModuloOperator, Rule::MissingWhitespace, + Rule::UnderIndentedHangingIndent, Rule::MissingOrOutdentedIndentation, + Rule::ClosingBracketNotMatchingOpeningBracketIndentation, + Rule::ClosingBracketNotMatchingOpeningBracketVisualIndentation, + Rule::ContinuationLineIndentSameAsNextLogicalLine, + Rule::ContinuationLineOverIndentedForHangingIndent, + Rule::ContinuationLineOverIndentedForVisualIndent, + Rule::ContinuationLineUnderIndentedForVisualIndent, + Rule::VisuallyIndentedLineWithSameIndentAsNextLogicalLine, + Rule::ContinuationLineUnalignedForHangingIndent, + Rule::ClosingBracketMissingIndentation, Rule::MultipleSpacesAfterComma, Rule::TabAfterComma, Rule::UnexpectedSpacesAroundKeywordParameterEquals, From e323ec065db84ce65c9ad18a638584013e19888f Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Mon, 6 Nov 2023 00:24:18 +0900 Subject: [PATCH 13/21] Fix E125. --- .../test/fixtures/pycodestyle/E12.py | 1 - .../rules/logical_lines/continuation_lines.rs | 45 ++++++++++++------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py index bb98c9a6c7478..d533ba58ebd61 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py @@ -284,7 +284,6 @@ def qualify_by_address( or y == 4): pass - #: E127 print ("E127", ("over-", "over-indent")) diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs index 06a0c16829de6..9a75ec69a536a 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs @@ -491,7 +491,7 @@ pub(crate) fn continuation_lines( // indent_next tells us whether the next block is indented. // Assuming that it is indented by 4 spaces, then we should not allow 4-space indents on the final continuation line. // In turn, some other indents are allowed to have an extra 4 spaces. - let indent_next = logical_line.text().ends_with(':'); + let indent_next = logical_line.text().trim_end().ends_with(':'); // Here "row" is the physical line index (within the logical line). let mut row = 0; @@ -522,7 +522,7 @@ pub(crate) fn continuation_lines( // TODO: config option: hang closing bracket instead of matching indentation of opening bracket's line. let hang_closing = false; - for (token, token_info) in zip(logical_line.tokens(), token_infos) { + for (token, token_info) in zip(logical_line.tokens(), &token_infos) { let mut is_newline = row < token_info.start_physical_line_idx; if is_newline { row = token_info.start_physical_line_idx; @@ -735,21 +735,34 @@ pub(crate) fn continuation_lines( if last_token_multiline { rel_indent[token_info.end_physical_line_idx] = rel_indent[row]; } + } - if indent_next && expand_indent(token_info.line) == start_indent_level + indent_size { - if visual_indent { - // E129. - let diagnostic = Diagnostic::new( - VisuallyIndentedLineWithSameIndentAsNextLogicalLine, - token.range, - ); - context.push_diagnostic(diagnostic); - } else { - // E125. - let diagnostic = - Diagnostic::new(ContinuationLineIndentSameAsNextLogicalLine, token.range); - context.push_diagnostic(diagnostic); - } + if indent_next + && expand_indent( + token_infos + .last() + .expect("Would have returned if line was empty") + .line, + ) == start_indent_level + indent_size + { + let last_token = logical_line + .tokens() + .last() + .expect("Would have returned if line was empty"); + if visual_indent { + // E129. + let diagnostic = Diagnostic::new( + VisuallyIndentedLineWithSameIndentAsNextLogicalLine, + last_token.range, + ); + context.push_diagnostic(diagnostic); + } else { + // E125. + let diagnostic = Diagnostic::new( + ContinuationLineIndentSameAsNextLogicalLine, + last_token.range, + ); + context.push_diagnostic(diagnostic); } } } From e669cc99a34ed98fba421882f341acf3aa4961a7 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Wed, 8 Nov 2023 14:44:18 +0900 Subject: [PATCH 14/21] Fix E126 edge case. Change indent_chances into a HashMap to keep track of what kind of indent was on which line. --- .../test/fixtures/pycodestyle/E12.py | 56 +++++-- .../rules/logical_lines/continuation_lines.rs | 139 ++++++++++++------ 2 files changed, 135 insertions(+), 60 deletions(-) diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py index d533ba58ebd61..1ad486f92a0a4 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py @@ -9,7 +9,7 @@ } #: E122 -print("E122", ( +print("In", ( "dent")) #: E122:6:5 E122:7:5 E122:8:1 @@ -68,13 +68,10 @@ 'Intended Audience :: Developers', ]) -#: E122:2:1 E128:5:1 +#: E122:2:1 if True:\ print(True) -print(a -, end=' ') - #: E123 my_list = [ 1, 2, 3, @@ -82,7 +79,7 @@ ] #: E123 -print "E123", ( +print "Indent", ( "bad", "hanging", "close" ) @@ -115,12 +112,12 @@ def example_issue254(): dict(name=token.undefined) )] -#: E124 +#: E124 E128 print ("E124", ("visual", "indent_two" )) -#: E124 +#: E124 E128 print ("E124", ("visual", "indent_five" )) @@ -205,16 +202,16 @@ def qualify_by_address( for foo in """ abc - 123 + def """.strip().split(): print(foo) #: E126 -print "E126", ( +print "In", ( "dent") #: E126 -print "E126", ( +print "In", ( "dent") #: E126 @@ -285,33 +282,41 @@ def qualify_by_address( pass #: E127 -print ("E127", ("over-", +print ("abcd", ("over-", "over-indent")) #: E127 foo(1, 2, 3, 4, 5, 6) + #: E127 foo(1, 2, 3, 4, 5, 6) + #: E127 foo(1, 2, 3, 4, 5, 6) + #: E127 foo(1, 2, 3, 4, 5, 6) + #: E127 foo(1, 2, 3, 4, 5, 6) + #: E127 foo(1, 2, 3, 4, 5, 6) + #: E127 foo(1, 2, 3, 4, 5, 6) + #: E127 foo(1, 2, 3, 4, 5, 6) + #: E127 foo(1, 2, 3, 4, 5, 6) @@ -324,6 +329,7 @@ def qualify_by_address( rv.update(d=('a' + 'b', 'c'), e=42, f=42 + 42) + #: E127 W503 input1 = {'a': {'calc': 1 + 2}, 'b': 1 + 42} @@ -355,6 +361,10 @@ def f1(): open('later-misindent'): file_2.write(file_1.read()) +#: E128:5:1 +print(a +, end=' ') + #: E128 E128 if line_removed: self.event(cr, uid, @@ -363,11 +373,11 @@ def f1(): ) #: E128 -print ("E128", ("visual", +print ("abcd", ("visual", "hanging")) #: E128 -print ("E128", ("under-", +print ("abcd", ("under-", "under-indent")) #: E128 @@ -385,14 +395,18 @@ def qualify_by_address(self, cr, uid, ids, context=None, """ This gets called by the web server """ #: E128 + foo(1, 2, 3, 4, 5, 6) + #: E128 foo(1, 2, 3, 4, 5, 6) + #: E128 foo(1, 2, 3, 4, 5, 6) + #: E128 foo(1, 2, 3, 4, 5, 6) @@ -412,3 +426,17 @@ def qualify_by_address(self, cr, uid, ids, context=None, or b == "abc def ghi" "jkl mno"): return True + +#: E131 +print "hello", ( + + "there", + # "john", + "dude") + +#: E131 +troublesome_hash = { + "hash": "value", + "long": "the quick brown fox jumps over the lazy dog before doing a " + "somersault", +} diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs index 9a75ec69a536a..69360d00708b7 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs @@ -7,6 +7,7 @@ use ruff_macros::{derive_message_formats, violation}; use ruff_python_parser::TokenKind; use ruff_source_file::Locator; use ruff_text_size::{Ranged, TextRange}; +use rustc_hash::FxHashMap; /// ## What it does /// Checks for lines less indented than they should be for hanging indents. @@ -364,6 +365,16 @@ struct TokenInfo<'a> { line: &'a str, } +#[derive(Debug, Clone)] +enum IndentFlag { + /// The pycodestyle's True + Standard, + /// The pycodestyle's text (str instance) + Token(TokenKind), + /// The pycodestyle's str class + StringOrComment, +} + /// Compute the `TokenInfo` of each token. fn get_token_infos<'a>(logical_line: &LogicalLine, locator: &'a Locator) -> Vec> { let mut token_infos = Vec::new(); @@ -512,9 +523,9 @@ pub(crate) fn continuation_lines( let mut hang: i64 = 0; let mut hanging_indent: bool = false; // Visual indents - let mut indent_chances: Vec = Vec::new(); + let mut indent_chances: FxHashMap = FxHashMap::default(); let mut last_indent = start_indent_level; - let mut visual_indent = false; + let mut visual_indent: Option = None; let mut last_token_multiline = false; // For each depth, memorize the visual indent column. let mut indent = vec![start_indent_level]; @@ -558,9 +569,13 @@ pub(crate) fn continuation_lines( } // Is there any chance of visual indent ? - visual_indent = !is_closing_bracket - && hang > 0 - && indent_chances.contains(&token_info.token_start_within_physical_line); + visual_indent = if !is_closing_bracket && hang > 0 { + indent_chances + .get(&token_info.token_start_within_physical_line) + .cloned() + } else { + None + }; if is_closing_bracket && indent[depth] != 0 { // Closing bracket for visual indent. @@ -583,7 +598,7 @@ pub(crate) fn continuation_lines( && token_info.token_start_within_physical_line < indent[depth] { // visual indent is broken - if !visual_indent { + if !matches!(visual_indent, Some(IndentFlag::Standard)) { // E128 let diagnostic = Diagnostic::new(ContinuationLineUnderIndentedForVisualIndent, token.range); @@ -600,38 +615,55 @@ pub(crate) fn continuation_lines( context.push_diagnostic(diagnostic); } hangs[depth] = Some(hang); - } else if visual_indent { - // Visual indent is verified. - indent[depth] = token_info.token_start_within_physical_line; } else { - // Indent is broken. - if hang <= 0 { - // E122. - let diagnostic = Diagnostic::new(MissingOrOutdentedIndentation, token.range); - context.push_diagnostic(diagnostic); - } else if indent[depth] != 0 { - // E127 - let diagnostic = - Diagnostic::new(ContinuationLineOverIndentedForVisualIndent, token.range); - context.push_diagnostic(diagnostic); - } else if !is_closing_bracket && hangs[depth].is_some_and(|hang| hang > 0) { - // E131 - let diagnostic = - Diagnostic::new(ContinuationLineUnalignedForHangingIndent, token.range); - context.push_diagnostic(diagnostic); - } else { - hangs[depth] = Some(hang); - if hang > indent_size { - // E126 - let diagnostic = Diagnostic::new( - ContinuationLineOverIndentedForHangingIndent, - token.range, - ); - context.push_diagnostic(diagnostic); - } else { - // E121. - let diagnostic = Diagnostic::new(UnderIndentedHangingIndent, token.range); - context.push_diagnostic(diagnostic); + match visual_indent { + Some(IndentFlag::Standard) => { + // Visual indent is verified. + indent[depth] = token_info.token_start_within_physical_line; + } + Some(IndentFlag::StringOrComment) => { + // Ignore token lined up with matching one from a previous line. + } + Some(IndentFlag::Token(t)) if t == token.kind => { + // Ignore token lined up with matching one from a previous line. + } + _ => { + // Indent is broken. + if hang <= 0 { + // E122. + let diagnostic = + Diagnostic::new(MissingOrOutdentedIndentation, token.range); + context.push_diagnostic(diagnostic); + } else if indent[depth] != 0 { + // E127 + let diagnostic = Diagnostic::new( + ContinuationLineOverIndentedForVisualIndent, + token.range, + ); + context.push_diagnostic(diagnostic); + } else if !is_closing_bracket && hangs[depth].is_some_and(|hang| hang > 0) { + // E131 + let diagnostic = Diagnostic::new( + ContinuationLineUnalignedForHangingIndent, + token.range, + ); + context.push_diagnostic(diagnostic); + } else { + hangs[depth] = Some(hang); + if hang > indent_size { + // E126 + let diagnostic = Diagnostic::new( + ContinuationLineOverIndentedForHangingIndent, + token.range, + ); + context.push_diagnostic(diagnostic); + } else { + // E121. + let diagnostic = + Diagnostic::new(UnderIndentedHangingIndent, token.range); + context.push_diagnostic(diagnostic); + } + } } } } @@ -646,11 +678,17 @@ pub(crate) fn continuation_lines( && indent[depth] == 0 { indent[depth] = token_info.token_start_within_physical_line; - indent_chances.push(token_info.token_start_within_physical_line); + indent_chances.insert( + token_info.token_start_within_physical_line, + IndentFlag::Standard, + ); } // Deal with implicit string concatenation. else if matches!(token.kind, TokenKind::Comment | TokenKind::String) { - indent_chances.push(token_info.token_start_within_physical_line); + indent_chances.insert( + token_info.token_start_within_physical_line, + IndentFlag::StringOrComment, + ); } // Visual indent after assert/raise/with. else if row == 0 @@ -660,7 +698,10 @@ pub(crate) fn continuation_lines( TokenKind::Assert | TokenKind::Raise | TokenKind::With ) { - indent_chances.push(token_info.token_end_within_physical_line + 1); + indent_chances.insert( + token_info.token_end_within_physical_line + 1, + IndentFlag::Standard, + ); } // Special case for the "if" statement because "if (".len() == 4 else if indent_chances.is_empty() @@ -668,7 +709,10 @@ pub(crate) fn continuation_lines( && depth == 0 && matches!(token.kind, TokenKind::If) { - indent_chances.push(token_info.token_end_within_physical_line + 1); + indent_chances.insert( + token_info.token_end_within_physical_line + 1, + IndentFlag::Standard, + ); } else if matches!(token.kind, TokenKind::Colon) && token_info.line[usize::try_from(token_info.token_end_within_physical_line) .expect("Line to be relatively short.")..] @@ -711,11 +755,11 @@ pub(crate) fn continuation_lines( *ind = 0; } } - indent_chances.retain(|&ind| ind < prev_indent); + indent_chances.retain(|&ind, _| ind < prev_indent); open_rows.truncate(depth); depth -= 1; if depth > 0 { - indent_chances.push(indent[depth]); + indent_chances.insert(indent[depth], IndentFlag::Standard); } for idx in (0..=row).rev() { if parens[idx] != 0 { @@ -724,9 +768,12 @@ pub(crate) fn continuation_lines( } } } - if !indent_chances.contains(&token_info.token_start_within_physical_line) { + if !indent_chances.contains_key(&token_info.token_start_within_physical_line) { // Allow lining up tokens - indent_chances.push(token_info.token_start_within_physical_line); + indent_chances.insert( + token_info.token_start_within_physical_line, + IndentFlag::Token(token.kind), + ); } } @@ -749,7 +796,7 @@ pub(crate) fn continuation_lines( .tokens() .last() .expect("Would have returned if line was empty"); - if visual_indent { + if visual_indent.is_some() { // E129. let diagnostic = Diagnostic::new( VisuallyIndentedLineWithSameIndentAsNextLogicalLine, From 1da9cf091dbda3bfc24507d7491ac070dce74c9e Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Wed, 8 Nov 2023 17:09:55 +0900 Subject: [PATCH 15/21] Add hang-closing as a configuration option. --- crates/ruff_linter/src/checkers/logical_lines.rs | 9 ++++++++- .../rules/logical_lines/continuation_lines.rs | 4 +--- crates/ruff_linter/src/rules/pycodestyle/settings.rs | 1 + crates/ruff_workspace/src/options.rs | 12 ++++++++++++ ruff.schema.json | 11 ++++++++++- 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/crates/ruff_linter/src/checkers/logical_lines.rs b/crates/ruff_linter/src/checkers/logical_lines.rs index 6ce696631b02d..dfdd0b482605d 100644 --- a/crates/ruff_linter/src/checkers/logical_lines.rs +++ b/crates/ruff_linter/src/checkers/logical_lines.rs @@ -88,7 +88,14 @@ pub(crate) fn check_logical_lines( let indent_size = 4; - continuation_lines(&mut context, &line, locator, indent_char, indent_size); + continuation_lines( + &mut context, + &line, + locator, + indent_char, + indent_size, + settings.pycodestyle.hang_closing, + ); for kind in indentation( &line, diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs index 69360d00708b7..a8e5a696f2100 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs @@ -474,6 +474,7 @@ pub(crate) fn continuation_lines( locator: &Locator, indent_char: char, indent_size: usize, + hang_closing: bool, ) { // The pycodestyle implementation makes use of negative values, // converting the indent_size type at the start avoids converting it multiple times later. @@ -530,9 +531,6 @@ pub(crate) fn continuation_lines( // For each depth, memorize the visual indent column. let mut indent = vec![start_indent_level]; - // TODO: config option: hang closing bracket instead of matching indentation of opening bracket's line. - let hang_closing = false; - for (token, token_info) in zip(logical_line.tokens(), &token_infos) { let mut is_newline = row < token_info.start_physical_line_idx; if is_newline { diff --git a/crates/ruff_linter/src/rules/pycodestyle/settings.rs b/crates/ruff_linter/src/rules/pycodestyle/settings.rs index 7990f6a65646d..84928f7c47722 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/settings.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/settings.rs @@ -9,4 +9,5 @@ pub struct Settings { pub max_line_length: LineLength, pub max_doc_length: Option, pub ignore_overlong_task_comments: bool, + pub hang_closing: bool, } diff --git a/crates/ruff_workspace/src/options.rs b/crates/ruff_workspace/src/options.rs index 5884bfa0a12b9..44fee970c9245 100644 --- a/crates/ruff_workspace/src/options.rs +++ b/crates/ruff_workspace/src/options.rs @@ -2346,6 +2346,17 @@ pub struct PycodestyleOptions { "# )] pub ignore_overlong_task_comments: Option, + + /// Whether missing indentation for closing brakets (E133) should be triggered. + /// If set to true, this switches the default behavior of closing brackets so that they require hanging indents. + #[option( + default = "false", + value_type = "bool", + example = r#" + hang-closing = true + "# + )] + pub hang_closing: Option, } impl PycodestyleOptions { @@ -2354,6 +2365,7 @@ impl PycodestyleOptions { max_doc_length: self.max_doc_length, max_line_length: self.max_line_length.unwrap_or(global_line_length), ignore_overlong_task_comments: self.ignore_overlong_task_comments.unwrap_or_default(), + hang_closing: self.hang_closing.unwrap_or_default(), } } } diff --git a/ruff.schema.json b/ruff.schema.json index 622655944ae8d..9f39725f26bf6 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -2205,6 +2205,13 @@ "PycodestyleOptions": { "type": "object", "properties": { + "hang-closing": { + "description": "Whether missing indentation for closing brakets (E133) should be triggered. If set to true, this switches the default behavior of closing brackets so that they require hanging indents.", + "type": [ + "boolean", + "null" + ] + }, "ignore-overlong-task-comments": { "description": "Whether line-length violations (`E501`) should be triggered for comments starting with `task-tags` (by default: \\[\"TODO\", \"FIXME\", and \"XXX\"\\]).", "type": [ @@ -2647,6 +2654,8 @@ "E127", "E128", "E129", + "E13", + "E131", "E133", "E2", "E20", @@ -3614,4 +3623,4 @@ "type": "string" } } -} +} \ No newline at end of file From fab2f50d0cfe4282025791bf247a17cd9f727821 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Wed, 8 Nov 2023 17:14:42 +0900 Subject: [PATCH 16/21] Update snapshots. --- ...ules__pycodestyle__tests__E121_E12.py.snap | 24 +++ ...ules__pycodestyle__tests__E122_E12.py.snap | 140 ++++++------ ...ules__pycodestyle__tests__E123_E12.py.snap | 73 +++++++ ...ules__pycodestyle__tests__E124_E12.py.snap | 114 ++++++++++ ...ules__pycodestyle__tests__E125_E12.py.snap | 59 +++++ ...ules__pycodestyle__tests__E126_E12.py.snap | 150 +++++++++++++ ...ules__pycodestyle__tests__E127_E12.py.snap | 201 ++++++++++++++++++ ...ules__pycodestyle__tests__E128_E12.py.snap | 168 +++++++++++++++ ...ules__pycodestyle__tests__E129_E12.py.snap | 26 +++ ...ules__pycodestyle__tests__E131_E12.py.snap | 21 ++ ...ules__pycodestyle__tests__E133_E12.py.snap | 4 + 11 files changed, 910 insertions(+), 70 deletions(-) create mode 100644 crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E121_E12.py.snap create mode 100644 crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E123_E12.py.snap create mode 100644 crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E124_E12.py.snap create mode 100644 crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E125_E12.py.snap create mode 100644 crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E126_E12.py.snap create mode 100644 crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E127_E12.py.snap create mode 100644 crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E128_E12.py.snap create mode 100644 crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E129_E12.py.snap create mode 100644 crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E131_E12.py.snap create mode 100644 crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E133_E12.py.snap diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E121_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E121_E12.py.snap new file mode 100644 index 0000000000000..3cdafc4bb355d --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E121_E12.py.snap @@ -0,0 +1,24 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +--- +E12.py:3:3: E121 Hanging indent under-indented. + | +1 | #: E121 +2 | print "E121", ( +3 | "dent") + | ^^^^^^ E121 +4 | +5 | #: E121 + | + +E12.py:7:4: E121 Hanging indent under-indented. + | +5 | #: E121 +6 | result = { +7 | 'key1': 'value', + | ^^^^^^ E121 +8 | 'key2': 'value', +9 | } + | + + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E122_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E122_E12.py.snap index d754b53b45286..cb12eb5583026 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E122_E12.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E122_E12.py.snap @@ -1,119 +1,119 @@ --- source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- -E12.py:3:1: E122 Continuation line missing indentation or outdented. - | -1 | #: E122 -2 | print("E122", ( -3 | "dent")) - | ^^^^^^ E122 -4 | -5 | #: E122:6:5 E122:7:5 E122:8:1 - | +E12.py:13:1: E122 Continuation line missing indentation or outdented. + | +11 | #: E122 +12 | print("In", ( +13 | "dent")) + | ^^^^^^ E122 +14 | +15 | #: E122:6:5 E122:7:5 E122:8:1 + | -E12.py:11:5: E122 Continuation line missing indentation or outdented. +E12.py:21:5: E122 Continuation line missing indentation or outdented. | - 9 | mv ./build/ ./{build}/%(revision)s/ -10 | '''.format( -11 | build='build', +19 | mv ./build/ ./{build}/%(revision)s/ +20 | '''.format( +21 | build='build', | ^^^^^ E122 -12 | # more stuff -13 | ) +22 | # more stuff +23 | ) | -E12.py:12:5: E122 Continuation line missing indentation or outdented. +E12.py:22:5: E122 Continuation line missing indentation or outdented. | -10 | '''.format( -11 | build='build', -12 | # more stuff +20 | '''.format( +21 | build='build', +22 | # more stuff | ^^^^^^^^^^^^ E122 -13 | ) -14 | )) +23 | ) +24 | )) | -E12.py:13:1: E122 Continuation line missing indentation or outdented. +E12.py:23:1: E122 Continuation line missing indentation or outdented. | -11 | build='build', -12 | # more stuff -13 | ) +21 | build='build', +22 | # more stuff +23 | ) | ^ E122 -14 | )) +24 | )) | -E12.py:21:1: E122 Continuation line missing indentation or outdented. +E12.py:31:1: E122 Continuation line missing indentation or outdented. | -19 | 'a', 'b', 'c', -20 | 'd', 'e', 'f', -21 | ) +29 | 'a', 'b', 'c', +30 | 'd', 'e', 'f', +31 | ) | ^ E122 -22 | -23 | #: E122 +32 | +33 | #: E122 | -E12.py:25:1: E122 Continuation line missing indentation or outdented. +E12.py:35:1: E122 Continuation line missing indentation or outdented. | -23 | #: E122 -24 | if some_very_very_very_long_variable_name or var \ -25 | or another_very_long_variable_name: +33 | #: E122 +34 | if some_very_very_very_long_variable_name or var \ +35 | or another_very_long_variable_name: | ^^ E122 -26 | raise Exception() +36 | raise Exception() | -E12.py:30:1: E122 Continuation line missing indentation or outdented. +E12.py:40:1: E122 Continuation line missing indentation or outdented. | -28 | #: E122 -29 | if some_very_very_very_long_variable_name or var[0] \ -30 | or another_very_long_variable_name: +38 | #: E122 +39 | if some_very_very_very_long_variable_name or var[0] \ +40 | or another_very_long_variable_name: | ^^ E122 -31 | raise Exception() +41 | raise Exception() | -E12.py:36:5: E122 Continuation line missing indentation or outdented. +E12.py:46:5: E122 Continuation line missing indentation or outdented. | -34 | if True: -35 | if some_very_very_very_long_variable_name or var \ -36 | or another_very_long_variable_name: +44 | if True: +45 | if some_very_very_very_long_variable_name or var \ +46 | or another_very_long_variable_name: | ^^ E122 -37 | raise Exception() +47 | raise Exception() | -E12.py:42:5: E122 Continuation line missing indentation or outdented. +E12.py:52:5: E122 Continuation line missing indentation or outdented. | -40 | if True: -41 | if some_very_very_very_long_variable_name or var[0] \ -42 | or another_very_long_variable_name: +50 | if True: +51 | if some_very_very_very_long_variable_name or var[0] \ +52 | or another_very_long_variable_name: | ^^ E122 -43 | raise Exception() +53 | raise Exception() | -E12.py:48:5: E122 Continuation line missing indentation or outdented. +E12.py:58:5: E122 Continuation line missing indentation or outdented. | -46 | dictionary = { -47 | "is": { -48 | "nested": yes(), +56 | dictionary = { +57 | "is": { +58 | "nested": yes(), | ^^^^^^^^ E122 -49 | }, -50 | } +59 | }, +60 | } | -E12.py:56:7: E122 Continuation line missing indentation or outdented. +E12.py:66:7: E122 Continuation line missing indentation or outdented. | -54 | scripts=[''], -55 | classifiers=[ -56 | 'Development Status :: 4 - Beta', +64 | scripts=[''], +65 | classifiers=[ +66 | 'Development Status :: 4 - Beta', | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E122 -57 | 'Environment :: Console', -58 | 'Intended Audience :: Developers', +67 | 'Environment :: Console', +68 | 'Intended Audience :: Developers', | -E12.py:63:1: E122 Continuation line missing indentation or outdented. +E12.py:73:1: E122 Continuation line missing indentation or outdented. | -61 | #: E701:1:8 E122:2:1 E203:4:8 E128:5:1 -62 | if True:\ -63 | print(True) +71 | #: E122:2:1 +72 | if True:\ +73 | print(True) | ^^^^^ E122 -64 | -65 | print(a +74 | +75 | #: E123 | diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E123_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E123_E12.py.snap new file mode 100644 index 0000000000000..3cfd45fca3382 --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E123_E12.py.snap @@ -0,0 +1,73 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +--- +E12.py:79:5: E123 Closing bracket not matching its corresponding opening bracket's indentation. + | +77 | 1, 2, 3, +78 | 4, 5, 6, +79 | ] + | ^ E123 +80 | +81 | #: E123 + | + +E12.py:84:5: E123 Closing bracket not matching its corresponding opening bracket's indentation. + | +82 | print "Indent", ( +83 | "bad", "hanging", "close" +84 | ) + | ^ E123 +85 | +86 | #: E123 + | + +E12.py:91:13: E123 Closing bracket not matching its corresponding opening bracket's indentation. + | +89 | 'bar', { +90 | 'baz': 'frop', +91 | } + | ^ E123 +92 | ] +93 | } + | + +E12.py:92:9: E123 Closing bracket not matching its corresponding opening bracket's indentation. + | +90 | 'baz': 'frop', +91 | } +92 | ] + | ^ E123 +93 | } + | + +E12.py:93:5: E123 Closing bracket not matching its corresponding opening bracket's indentation. + | +91 | } +92 | ] +93 | } + | ^ E123 +94 | +95 | #: E123 + | + +E12.py:99:5: E123 Closing bracket not matching its corresponding opening bracket's indentation. + | + 97 | 'a', 'b', 'c', + 98 | 'd', 'e', 'f', + 99 | ) + | ^ E123 +100 | +101 | #: E123 + | + +E12.py:111:17: E123 Closing bracket not matching its corresponding opening bracket's indentation. + | +109 | # Replace them. +110 | for replacement in replace(child) +111 | ), + | ^ E123 +112 | dict(name=token.undefined) +113 | )] + | + + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E124_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E124_E12.py.snap new file mode 100644 index 0000000000000..b9ae89e856221 --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E124_E12.py.snap @@ -0,0 +1,114 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +--- +E12.py:118:15: E124 Closing bracket not matching its corresponding opening bracket's visual indentation. + | +116 | print ("E124", ("visual", +117 | "indent_two" +118 | )) + | ^ E124 +119 | +120 | #: E124 E128 + | + +E12.py:123:1: E124 Closing bracket not matching its corresponding opening bracket's visual indentation. + | +121 | print ("E124", ("visual", +122 | "indent_five" +123 | )) + | ^ E124 +124 | +125 | #: E124 + | + +E12.py:127:1: E124 Closing bracket not matching its corresponding opening bracket's visual indentation. + | +125 | #: E124 +126 | a = (123, +127 | ) + | ^ E124 +128 | +129 | #: E124 + | + +E12.py:132:1: E124 Closing bracket not matching its corresponding opening bracket's visual indentation. + | +130 | my_list = [1, 2, 3, +131 | 4, 5, 6, +132 | ] + | ^ E124 +133 | +134 | #: E124 + | + +E12.py:137:20: E124 Closing bracket not matching its corresponding opening bracket's visual indentation. + | +135 | my_list = [1, 2, 3, +136 | 4, 5, 6, +137 | ] + | ^ E124 +138 | #: E124 +139 | result = some_function_that_takes_arguments('a', 'b', 'c', + | + +E12.py:141:1: E124 Closing bracket not matching its corresponding opening bracket's visual indentation. + | +139 | result = some_function_that_takes_arguments('a', 'b', 'c', +140 | 'd', 'e', 'f', +141 | ) + | ^ E124 +142 | +143 | #: E124 + | + +E12.py:149:1: E124 Closing bracket not matching its corresponding opening bracket's visual indentation. + | +147 | dadd +148 | ), fff, +149 | ) + | ^ E124 +150 | +151 | #: E124 + | + +E12.py:158:1: E124 Closing bracket not matching its corresponding opening bracket's visual indentation. + | +156 | ), +157 | fff, +158 | ) + | ^ E124 +159 | +160 | #: E124 + | + +E12.py:164:15: E124 Closing bracket not matching its corresponding opening bracket's visual indentation. + | +162 | help="exclude files or directories which match these " +163 | "comma separated patterns (default: %s)" % DEFAULT_EXCLUDE +164 | ) + | ^ E124 +165 | +166 | #: E124 E128 E128 + | + +E12.py:171:9: E124 Closing bracket not matching its corresponding opening bracket's visual indentation. + | +169 | name="Removing the option for contract", +170 | description="contract line has been removed", +171 | ) + | ^ E124 +172 | +173 | #: E124 E127 E127 + | + +E12.py:178:17: E124 Closing bracket not matching its corresponding opening bracket's visual indentation. + | +176 | name="Removing the option for contract", +177 | description="contract line has been removed", +178 | ) + | ^ E124 +179 | +180 | #: E125 + | + + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E125_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E125_E12.py.snap new file mode 100644 index 0000000000000..80be23ae18c61 --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E125_E12.py.snap @@ -0,0 +1,59 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +--- +E12.py:182:20: E125 Continuation line with same indent as next logical line. + | +180 | #: E125 +181 | if foo is None and bar is "frop" and \ +182 | blah == 'yeah': + | ^ E125 +183 | blah = 'yeahnah' +184 | +185 | #: E125 + | + +E12.py:189:15: E125 Continuation line with same indent as next logical line. + | +187 | def long_function_name( +188 | var_one, var_two, var_three, +189 | var_four): + | ^ E125 +190 | print(var_one) +191 | +192 | #: E125 + | + +E12.py:195:57: E125 Continuation line with same indent as next logical line. + | +193 | def qualify_by_address( +194 | self, cr, uid, ids, context=None, +195 | params_to_check=frozenset(QUALIF_BY_ADDRESS_PARAM)): + | ^ E125 +196 | """ This gets called by the web server """ +197 | +198 | #: E125:2:5 E125:8:5 + | + +E12.py:200:10: E125 Continuation line with same indent as next logical line. + | +198 | #: E125:2:5 E125:8:5 +199 | if (""" +200 | """): + | ^ E125 +201 | pass +202 | +203 | for foo in """ + | + +E12.py:206:25: E125 Continuation line with same indent as next logical line. + | +204 | abc +205 | def +206 | """.strip().split(): + | ^ E125 +207 | print(foo) +208 | +209 | #: E126 + | + + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E126_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E126_E12.py.snap new file mode 100644 index 0000000000000..234215e3d6006 --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E126_E12.py.snap @@ -0,0 +1,150 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +--- +E12.py:211:13: E126 Continuation line over indented for hanging indent. + | +209 | #: E126 +210 | print "In", ( +211 | "dent") + | ^^^^^^ E126 +212 | +213 | #: E126 + | + +E12.py:215:9: E126 Continuation line over indented for hanging indent. + | +213 | #: E126 +214 | print "In", ( +215 | "dent") + | ^^^^^^ E126 +216 | +217 | #: E126 + | + +E12.py:221:6: E126 Continuation line over indented for hanging indent. + | +219 | 1, 2, 3, +220 | 4, 5, 6, +221 | ] + | ^ E126 +222 | +223 | #: E126 + | + +E12.py:227:11: E126 Continuation line over indented for hanging indent. + | +225 | 'qualif_nr', 'reasonComment_en', 'reasonComment_fr', +226 | 'reasonComment_de', 'reasonComment_it'), +227 | '?'), + | ^^^ E126 +228 | "foo") + | + +E12.py:228:11: E126 Continuation line over indented for hanging indent. + | +226 | 'reasonComment_de', 'reasonComment_it'), +227 | '?'), +228 | "foo") + | ^^^^^ E126 +229 | +230 | #: E126 + | + +E12.py:232:11: E126 Continuation line over indented for hanging indent. + | +230 | #: E126 +231 | abricot = 3 + \ +232 | 4 + \ + | ^ E126 +233 | 5 + 6 +234 | #: E126 + | + +E12.py:237:24: E126 Continuation line over indented for hanging indent. + | +235 | part = set_mimetype(( +236 | a.get('mime_type', 'text')), +237 | 'default') + | ^^^^^^^^^ E126 +238 | +239 | #: E126 + | + +E12.py:243:9: E126 Continuation line over indented for hanging indent. + | +241 | 1, 2, 3, +242 | 4, 5, 6, +243 | ] + | ^ E126 +244 | +245 | #: E126 + | + +E12.py:247:9: E126 Continuation line over indented for hanging indent. + | +245 | #: E126 +246 | abris = 3 + \ +247 | 4 + \ + | ^ E126 +248 | 5 + 6 + | + +E12.py:252:9: E126 Continuation line over indented for hanging indent. + | +250 | #: E126 +251 | fixed = re.sub(r'\t+', ' ', target[c::-1], 1)[::-1] + \ +252 | target[c + 1:] + | ^^^^^^ E126 +253 | +254 | #: E126 + | + +E12.py:256:13: E126 Continuation line over indented for hanging indent. + | +254 | #: E126 +255 | rv.update(dict.fromkeys(( +256 | 'qualif_nr', 'reasonComment_en', 'reasonComment_fr', + | ^^^^^^^^^^^ E126 +257 | 'reasonComment_de', 'reasonComment_it'), +258 | '?'), + | + +E12.py:258:9: E126 Continuation line over indented for hanging indent. + | +256 | 'qualif_nr', 'reasonComment_en', 'reasonComment_fr', +257 | 'reasonComment_de', 'reasonComment_it'), +258 | '?'), + | ^^^ E126 +259 | "foo") + | + +E12.py:263:9: E126 Continuation line over indented for hanging indent. + | +261 | #: E126 +262 | eat_a_dict_a_day({ +263 | "foo": "bar", + | ^^^^^ E126 +264 | }) + | + +E12.py:269:13: E126 Continuation line over indented for hanging indent. + | +267 | if ( +268 | x == ( +269 | 3 + | ^ E126 +270 | ) +271 | or y == 4): + | + +E12.py:280:13: E126 Continuation line over indented for hanging indent. + | +278 | ) +279 | or x == ( +280 | 3) + | ^ E126 +281 | or y == 4): +282 | pass + | + + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E127_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E127_E12.py.snap new file mode 100644 index 0000000000000..d56ebf3111b49 --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E127_E12.py.snap @@ -0,0 +1,201 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +--- +E12.py:176:17: E127 Continuation line over indented for visual indent. + | +174 | if line_removed: +175 | self.event(cr, uid, +176 | name="Removing the option for contract", + | ^^^^ E127 +177 | description="contract line has been removed", +178 | ) + | + +E12.py:177:17: E127 Continuation line over indented for visual indent. + | +175 | self.event(cr, uid, +176 | name="Removing the option for contract", +177 | description="contract line has been removed", + | ^^^^^^^^^^^ E127 +178 | ) + | + +E12.py:286:19: E127 Continuation line over indented for visual indent. + | +284 | #: E127 +285 | print ("abcd", ("over-", +286 | "over-indent")) + | ^^^^^^^^^^^^^ E127 +287 | +288 | #: E127 + | + +E12.py:290:6: E127 Continuation line over indented for visual indent. + | +288 | #: E127 +289 | foo(1, 2, 3, +290 | 4, 5, 6) + | ^ E127 +291 | +292 | #: E127 + | + +E12.py:294:7: E127 Continuation line over indented for visual indent. + | +292 | #: E127 +293 | foo(1, 2, 3, +294 | 4, 5, 6) + | ^ E127 +295 | +296 | #: E127 + | + +E12.py:298:8: E127 Continuation line over indented for visual indent. + | +296 | #: E127 +297 | foo(1, 2, 3, +298 | 4, 5, 6) + | ^ E127 +299 | +300 | #: E127 + | + +E12.py:302:9: E127 Continuation line over indented for visual indent. + | +300 | #: E127 +301 | foo(1, 2, 3, +302 | 4, 5, 6) + | ^ E127 +303 | +304 | #: E127 + | + +E12.py:306:10: E127 Continuation line over indented for visual indent. + | +304 | #: E127 +305 | foo(1, 2, 3, +306 | 4, 5, 6) + | ^ E127 +307 | +308 | #: E127 + | + +E12.py:310:11: E127 Continuation line over indented for visual indent. + | +308 | #: E127 +309 | foo(1, 2, 3, +310 | 4, 5, 6) + | ^ E127 +311 | +312 | #: E127 + | + +E12.py:314:12: E127 Continuation line over indented for visual indent. + | +312 | #: E127 +313 | foo(1, 2, 3, +314 | 4, 5, 6) + | ^ E127 +315 | +316 | #: E127 + | + +E12.py:318:13: E127 Continuation line over indented for visual indent. + | +316 | #: E127 +317 | foo(1, 2, 3, +318 | 4, 5, 6) + | ^ E127 +319 | +320 | #: E127 + | + +E12.py:322:14: E127 Continuation line over indented for visual indent. + | +320 | #: E127 +321 | foo(1, 2, 3, +322 | 4, 5, 6) + | ^ E127 +323 | +324 | #: E127 + | + +E12.py:326:14: E127 Continuation line over indented for visual indent. + | +324 | #: E127 +325 | rv.update(d=('a', 'b', 'c'), +326 | e=42) + | ^ E127 +327 | # +328 | #: E127 W503 + | + +E12.py:331:18: E127 Continuation line over indented for visual indent. + | +329 | rv.update(d=('a' + 'b', 'c'), +330 | e=42, f=42 +331 | + 42) + | ^ E127 +332 | +333 | #: E127 W503 + | + +E12.py:335:27: E127 Continuation line over indented for visual indent. + | +333 | #: E127 W503 +334 | input1 = {'a': {'calc': 1 + 2}, 'b': 1 +335 | + 42} + | ^ E127 +336 | +337 | #: E127:4:12 + | + +E12.py:341:12: E127 Continuation line over indented for visual indent. + | +339 | pass +340 | raise 123 + \ +341 | 123 + | ^^^ E127 +342 | +343 | #: E127:4:13 + | + +E12.py:347:13: E127 Continuation line over indented for visual indent. + | +345 | pass +346 | assert 123456 == \ +347 | 123456 + | ^^^^^^ E127 +348 | +349 | #: E127:4:11 + | + +E12.py:353:11: E127 Continuation line over indented for visual indent. + | +351 | print('foo') +352 | with open('/path/to/some/file/you/want/to/read') as file_1, \ +353 | open('/path/to/some/file/being/written', 'w') as file_2: + | ^^^^ E127 +354 | file_2.write(file_1.read()) + | + +E12.py:360:10: E127 Continuation line over indented for visual indent. + | +358 | print('foo') +359 | with open('/path/to/some/file/you/want/to/read') as file_1, \ +360 | open('/path/to/some/file/being/written', 'w') as file_2, \ + | ^^^^ E127 +361 | open('later-misindent'): +362 | file_2.write(file_1.read()) + | + +E12.py:361:11: E127 Continuation line over indented for visual indent. + | +359 | with open('/path/to/some/file/you/want/to/read') as file_1, \ +360 | open('/path/to/some/file/being/written', 'w') as file_2, \ +361 | open('later-misindent'): + | ^^^^ E127 +362 | file_2.write(file_1.read()) + | + + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E128_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E128_E12.py.snap new file mode 100644 index 0000000000000..18ce940da273a --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E128_E12.py.snap @@ -0,0 +1,168 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +--- +E12.py:117:16: E128 Continuation line under indented for visual indent. + | +115 | #: E124 E128 +116 | print ("E124", ("visual", +117 | "indent_two" + | ^^^^^^^^^^^^ E128 +118 | )) + | + +E12.py:122:16: E128 Continuation line under indented for visual indent. + | +120 | #: E124 E128 +121 | print ("E124", ("visual", +122 | "indent_five" + | ^^^^^^^^^^^^^ E128 +123 | )) + | + +E12.py:169:9: E128 Continuation line under indented for visual indent. + | +167 | if line_removed: +168 | self.event(cr, uid, +169 | name="Removing the option for contract", + | ^^^^ E128 +170 | description="contract line has been removed", +171 | ) + | + +E12.py:170:9: E128 Continuation line under indented for visual indent. + | +168 | self.event(cr, uid, +169 | name="Removing the option for contract", +170 | description="contract line has been removed", + | ^^^^^^^^^^^ E128 +171 | ) + | + +E12.py:366:1: E128 Continuation line under indented for visual indent. + | +364 | #: E128:5:1 +365 | print(a +366 | , end=' ') + | ^ E128 +367 | +368 | #: E128 E128 + | + +E12.py:371:15: E128 Continuation line under indented for visual indent. + | +369 | if line_removed: +370 | self.event(cr, uid, +371 | name="Removing the option for contract", + | ^^^^ E128 +372 | description="contract line has been removed", +373 | ) + | + +E12.py:372:15: E128 Continuation line under indented for visual indent. + | +370 | self.event(cr, uid, +371 | name="Removing the option for contract", +372 | description="contract line has been removed", + | ^^^^^^^^^^^ E128 +373 | ) + | + +E12.py:377:5: E128 Continuation line under indented for visual indent. + | +375 | #: E128 +376 | print ("abcd", ("visual", +377 | "hanging")) + | ^^^^^^^^^ E128 +378 | +379 | #: E128 + | + +E12.py:381:15: E128 Continuation line under indented for visual indent. + | +379 | #: E128 +380 | print ("abcd", ("under-", +381 | "under-indent")) + | ^^^^^^^^^^^^^^ E128 +382 | +383 | #: E128 + | + +E12.py:386:5: E128 Continuation line under indented for visual indent. + | +384 | # Arguments on first line forbidden when not using vertical alignment +385 | foo = long_function_name(var_one, var_two, +386 | var_three, var_four) + | ^^^^^^^^^ E128 +387 | +388 | #: E128 + | + +E12.py:390:5: E128 Continuation line under indented for visual indent. + | +388 | #: E128 +389 | print('l.%s\t%s\t%s\t%r' % +390 | (token[2][0], pos, tokenize.tok_name[token[0]], token[1])) + | ^ E128 +391 | +392 | #: E128 + | + +E12.py:394:9: E128 Continuation line under indented for visual indent. + | +392 | #: E128 +393 | def qualify_by_address(self, cr, uid, ids, context=None, +394 | params_to_check=frozenset(QUALIF_BY_ADDRESS_PARAM)): + | ^^^^^^^^^^^^^^^ E128 +395 | """ This gets called by the web server """ + | + +E12.py:400:1: E128 Continuation line under indented for visual indent. + | +399 | foo(1, 2, 3, +400 | 4, 5, 6) + | ^ E128 +401 | +402 | #: E128 + | + +E12.py:404:2: E128 Continuation line under indented for visual indent. + | +402 | #: E128 +403 | foo(1, 2, 3, +404 | 4, 5, 6) + | ^ E128 +405 | +406 | #: E128 + | + +E12.py:408:3: E128 Continuation line under indented for visual indent. + | +406 | #: E128 +407 | foo(1, 2, 3, +408 | 4, 5, 6) + | ^ E128 +409 | +410 | #: E128 + | + +E12.py:412:4: E128 Continuation line under indented for visual indent. + | +410 | #: E128 +411 | foo(1, 2, 3, +412 | 4, 5, 6) + | ^ E128 +413 | +414 | #: E128 W503 + | + +E12.py:417:18: E128 Continuation line under indented for visual indent. + | +415 | rv.update(d=('a' + 'b', 'c'), +416 | e=42, f=(42 +417 | + 42)) + | ^ E128 +418 | +419 | #: E129 W503 + | + + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E129_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E129_E12.py.snap new file mode 100644 index 0000000000000..f93e4078db2a2 --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E129_E12.py.snap @@ -0,0 +1,26 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +--- +E12.py:421:44: E129 Visually indented line has the same indentation as the next logical line. + | +419 | #: E129 W503 +420 | if (row < 0 or self.moduleCount <= row +421 | or col < 0 or self.moduleCount <= col): + | ^ E129 +422 | raise Exception("%s,%s - %s" % (row, col, self.moduleCount)) +423 | +424 | #: E129 + | + +E12.py:427:16: E129 Visually indented line has the same indentation as the next logical line. + | +425 | if (a == 2 +426 | or b == "abc def ghi" +427 | "jkl mno"): + | ^ E129 +428 | return True +429 | +430 | #: E131 + | + + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E131_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E131_E12.py.snap new file mode 100644 index 0000000000000..d42e77e12de2a --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E131_E12.py.snap @@ -0,0 +1,21 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +--- +E12.py:434:6: E131 Continuation line unaligned for hanging indent. + | +433 | "there", +434 | # "john", + | ^^^^^^^^^ E131 +435 | "dude") + | + +E12.py:441:9: E131 Continuation line unaligned for hanging indent. + | +439 | "hash": "value", +440 | "long": "the quick brown fox jumps over the lazy dog before doing a " +441 | "somersault", + | ^^^^^^^^^^^^ E131 +442 | } + | + + diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E133_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E133_E12.py.snap new file mode 100644 index 0000000000000..6dcc4546f11f9 --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E133_E12.py.snap @@ -0,0 +1,4 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +--- + From f398c9633a0052ee0fccbc8654837aa91036fd32 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Wed, 8 Nov 2023 22:26:45 +0900 Subject: [PATCH 17/21] Fix typo, clippy lints Also add the rule examples to KNOWN_FORMATTING_VIOLATIONS. --- .../rules/logical_lines/continuation_lines.rs | 28 ++++++------------- crates/ruff_workspace/src/options.rs | 2 +- ruff.schema.json | 2 +- scripts/check_docs_formatted.py | 10 +++++++ 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs index a8e5a696f2100..2c30955c9b6cb 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/continuation_lines.rs @@ -75,7 +75,7 @@ impl Violation for MissingOrOutdentedIndentation { /// Checks for brackets that do not match the indentation level of the line that their opening bracket started on. /// /// ## Why is this bad? -/// This makes identifying brakets pair harder. +/// This makes identifying brackets pair harder. /// /// ## Example /// ```python @@ -108,7 +108,7 @@ impl Violation for ClosingBracketNotMatchingOpeningBracketIndentation { /// Checks for closing brackets that do not match the indentation of the opening bracket. /// /// ## Why is this bad? -/// This makes identifying brakets pair harder. +/// This makes identifying brackets pair harder. /// /// ## Example /// ```python @@ -689,23 +689,17 @@ pub(crate) fn continuation_lines( ); } // Visual indent after assert/raise/with. - else if row == 0 + else if (row == 0 && depth == 0 && matches!( token.kind, TokenKind::Assert | TokenKind::Raise | TokenKind::With - ) - { - indent_chances.insert( - token_info.token_end_within_physical_line + 1, - IndentFlag::Standard, - ); - } + )) // Special case for the "if" statement because "if (".len() == 4 - else if indent_chances.is_empty() + || (indent_chances.is_empty() && row == 0 && depth == 0 - && matches!(token.kind, TokenKind::If) + && matches!(token.kind, TokenKind::If)) { indent_chances.insert( token_info.token_end_within_physical_line + 1, @@ -766,13 +760,9 @@ pub(crate) fn continuation_lines( } } } - if !indent_chances.contains_key(&token_info.token_start_within_physical_line) { - // Allow lining up tokens - indent_chances.insert( - token_info.token_start_within_physical_line, - IndentFlag::Token(token.kind), - ); - } + indent_chances + .entry(token_info.token_start_within_physical_line) + .or_insert(IndentFlag::Token(token.kind)); } last_token_multiline = diff --git a/crates/ruff_workspace/src/options.rs b/crates/ruff_workspace/src/options.rs index 1a0af147b3a8d..3687cd615099d 100644 --- a/crates/ruff_workspace/src/options.rs +++ b/crates/ruff_workspace/src/options.rs @@ -2355,7 +2355,7 @@ pub struct PycodestyleOptions { )] pub ignore_overlong_task_comments: Option, - /// Whether missing indentation for closing brakets (E133) should be triggered. + /// Whether missing indentation for closing brackets (E133) should be triggered. /// If set to true, this switches the default behavior of closing brackets so that they require hanging indents. #[option( default = "false", diff --git a/ruff.schema.json b/ruff.schema.json index 5687643561710..5cb7e02c86190 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -2206,7 +2206,7 @@ "type": "object", "properties": { "hang-closing": { - "description": "Whether missing indentation for closing brakets (E133) should be triggered. If set to true, this switches the default behavior of closing brackets so that they require hanging indents.", + "description": "Whether missing indentation for closing brackets (E133) should be triggered. If set to true, this switches the default behavior of closing brackets so that they require hanging indents.", "type": [ "boolean", "null" diff --git a/scripts/check_docs_formatted.py b/scripts/check_docs_formatted.py index a99eac45dc093..ce2b537af22a5 100755 --- a/scripts/check_docs_formatted.py +++ b/scripts/check_docs_formatted.py @@ -32,6 +32,14 @@ "bad-quotes-docstring", "bad-quotes-inline-string", "bad-quotes-multiline-string", + "closing-bracket-missing-indentation", + "closing-bracket-not-matching-opening-bracket-indentation", + "closing-bracket-not-matching-opening-bracket-visual-indentation", + "continuation-line-indent-same-as-next-logical-line", + "continuation-line-over-indented-for-hanging-indent", + "continuation-line-over-indented-for-visual-indent", + "continuation-line-unaligned-for-hanging-indent", + "continuation-line-under-indented-for-visual-indent", "explicit-string-concatenation", "indent-with-spaces", "indentation-with-invalid-multiple", @@ -73,11 +81,13 @@ "trailing-comma-on-bare-tuple", "triple-single-quotes", "under-indentation", + "under-indented-hanging-indent", "unexpected-indentation-comment", "unexpected-spaces-around-keyword-parameter-equals", "unicode-kind-prefix", "unnecessary-class-parentheses", "useless-semicolon", + "visually-indented-line-with-same-indent-as-next-logical-line", "whitespace-after-open-bracket", "whitespace-before-close-bracket", "whitespace-before-parameters", From 114b50513ead977f7c04ab067c671e82629d5f3e Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Wed, 8 Nov 2023 23:31:21 +0900 Subject: [PATCH 18/21] Remove E133 test case. --- crates/ruff_linter/src/rules/pycodestyle/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/ruff_linter/src/rules/pycodestyle/mod.rs b/crates/ruff_linter/src/rules/pycodestyle/mod.rs index 144c537b1effd..ace20dd42761b 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/mod.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/mod.rs @@ -147,7 +147,6 @@ mod tests { Path::new("E12.py") )] #[test_case(Rule::ContinuationLineUnalignedForHangingIndent, Path::new("E12.py"))] - #[test_case(Rule::ClosingBracketMissingIndentation, Path::new("E12.py"))] #[test_case(Rule::WhitespaceAfterOpenBracket, Path::new("E20.py"))] #[test_case(Rule::WhitespaceBeforeCloseBracket, Path::new("E20.py"))] #[test_case(Rule::WhitespaceBeforePunctuation, Path::new("E20.py"))] From 382429c25bfa54dc37c946e3e8fe12d903bbaa47 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Wed, 8 Nov 2023 23:31:21 +0900 Subject: [PATCH 19/21] Remove E133 test case. --- .../ruff_linter__rules__pycodestyle__tests__E133_E12.py.snap | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E133_E12.py.snap diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E133_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E133_E12.py.snap deleted file mode 100644 index 6dcc4546f11f9..0000000000000 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E133_E12.py.snap +++ /dev/null @@ -1,4 +0,0 @@ ---- -source: crates/ruff_linter/src/rules/pycodestyle/mod.rs ---- - From 11deb1fda368324ead99b117ee98f263ec012062 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Tue, 27 Feb 2024 11:19:54 +0900 Subject: [PATCH 20/21] fix: update fixtures's prints to python3 --- .../test/fixtures/pycodestyle/E12.py | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py index 1ad486f92a0a4..341006da24f22 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E12.py @@ -1,6 +1,6 @@ #: E121 -print "E121", ( - "dent") +print("E121", ( + "str")) #: E121 result = { @@ -9,8 +9,8 @@ } #: E122 -print("In", ( -"dent")) +print("E122", ( +"str")) #: E122:6:5 E122:7:5 E122:8:1 print(dedent( @@ -79,9 +79,9 @@ ] #: E123 -print "Indent", ( +print("Indent", ( "bad", "hanging", "close" - ) + )) #: E123 result = { @@ -113,14 +113,14 @@ def example_issue254(): )] #: E124 E128 -print ("E124", ("visual", +print(("E124", ("visual", "indent_two" - )) + ))) #: E124 E128 -print ("E124", ("visual", +print(("E124", ("visual", "indent_five" -)) +))) #: E124 a = (123, @@ -207,12 +207,12 @@ def qualify_by_address( print(foo) #: E126 -print "In", ( - "dent") +print("In", ( + "dent")) #: E126 -print "In", ( - "dent") +print("In", ( + "dent")) #: E126 my_list = [ @@ -282,8 +282,8 @@ def qualify_by_address( pass #: E127 -print ("abcd", ("over-", - "over-indent")) +print(("abcd", ("over-", + "over-indent"))) #: E127 foo(1, 2, 3, @@ -373,12 +373,12 @@ def f1(): ) #: E128 -print ("abcd", ("visual", - "hanging")) +print(("abcd", ("visual", + "hanging"))) #: E128 -print ("abcd", ("under-", - "under-indent")) +print(("abcd", ("under-", + "under-indent"))) #: E128 # Arguments on first line forbidden when not using vertical alignment @@ -428,11 +428,11 @@ def qualify_by_address(self, cr, uid, ids, context=None, return True #: E131 -print "hello", ( +print("hello", ( "there", # "john", - "dude") + "dude")) #: E131 troublesome_hash = { From dba8819c518a0138c6d44d8f37d3e35ae6b18868 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Tue, 27 Feb 2024 11:41:23 +0900 Subject: [PATCH 21/21] update snapshots --- ...rules__pycodestyle__tests__E121_E12.py.snap | 8 +++----- ...rules__pycodestyle__tests__E122_E12.py.snap | 8 +++----- ...rules__pycodestyle__tests__E123_E12.py.snap | 6 ++---- ...rules__pycodestyle__tests__E124_E12.py.snap | 10 ++++------ ...rules__pycodestyle__tests__E126_E12.py.snap | 10 ++++------ ...rules__pycodestyle__tests__E127_E12.py.snap | 6 ++---- ...rules__pycodestyle__tests__E128_E12.py.snap | 18 ++++++++---------- ...rules__pycodestyle__tests__E131_E12.py.snap | 4 +--- 8 files changed, 27 insertions(+), 43 deletions(-) diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E121_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E121_E12.py.snap index 3cdafc4bb355d..5eb98f9874fa3 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E121_E12.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E121_E12.py.snap @@ -4,9 +4,9 @@ source: crates/ruff_linter/src/rules/pycodestyle/mod.rs E12.py:3:3: E121 Hanging indent under-indented. | 1 | #: E121 -2 | print "E121", ( -3 | "dent") - | ^^^^^^ E121 +2 | print("E121", ( +3 | "str")) + | ^^^^^ E121 4 | 5 | #: E121 | @@ -20,5 +20,3 @@ E12.py:7:4: E121 Hanging indent under-indented. 8 | 'key2': 'value', 9 | } | - - diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E122_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E122_E12.py.snap index cb12eb5583026..41858d5593408 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E122_E12.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E122_E12.py.snap @@ -4,9 +4,9 @@ source: crates/ruff_linter/src/rules/pycodestyle/mod.rs E12.py:13:1: E122 Continuation line missing indentation or outdented. | 11 | #: E122 -12 | print("In", ( -13 | "dent")) - | ^^^^^^ E122 +12 | print("E122", ( +13 | "str")) + | ^^^^^ E122 14 | 15 | #: E122:6:5 E122:7:5 E122:8:1 | @@ -115,5 +115,3 @@ E12.py:73:1: E122 Continuation line missing indentation or outdented. 74 | 75 | #: E123 | - - diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E123_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E123_E12.py.snap index 3cfd45fca3382..098d155306c8b 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E123_E12.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E123_E12.py.snap @@ -13,9 +13,9 @@ E12.py:79:5: E123 Closing bracket not matching its corresponding opening bracket E12.py:84:5: E123 Closing bracket not matching its corresponding opening bracket's indentation. | -82 | print "Indent", ( +82 | print("Indent", ( 83 | "bad", "hanging", "close" -84 | ) +84 | )) | ^ E123 85 | 86 | #: E123 @@ -69,5 +69,3 @@ E12.py:111:17: E123 Closing bracket not matching its corresponding opening brack 112 | dict(name=token.undefined) 113 | )] | - - diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E124_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E124_E12.py.snap index b9ae89e856221..d69dd1c3c93c0 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E124_E12.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E124_E12.py.snap @@ -3,9 +3,9 @@ source: crates/ruff_linter/src/rules/pycodestyle/mod.rs --- E12.py:118:15: E124 Closing bracket not matching its corresponding opening bracket's visual indentation. | -116 | print ("E124", ("visual", +116 | print(("E124", ("visual", 117 | "indent_two" -118 | )) +118 | ))) | ^ E124 119 | 120 | #: E124 E128 @@ -13,9 +13,9 @@ E12.py:118:15: E124 Closing bracket not matching its corresponding opening brack E12.py:123:1: E124 Closing bracket not matching its corresponding opening bracket's visual indentation. | -121 | print ("E124", ("visual", +121 | print(("E124", ("visual", 122 | "indent_five" -123 | )) +123 | ))) | ^ E124 124 | 125 | #: E124 @@ -110,5 +110,3 @@ E12.py:178:17: E124 Closing bracket not matching its corresponding opening brack 179 | 180 | #: E125 | - - diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E126_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E126_E12.py.snap index 234215e3d6006..3b44224fa038f 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E126_E12.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E126_E12.py.snap @@ -4,8 +4,8 @@ source: crates/ruff_linter/src/rules/pycodestyle/mod.rs E12.py:211:13: E126 Continuation line over indented for hanging indent. | 209 | #: E126 -210 | print "In", ( -211 | "dent") +210 | print("In", ( +211 | "dent")) | ^^^^^^ E126 212 | 213 | #: E126 @@ -14,8 +14,8 @@ E12.py:211:13: E126 Continuation line over indented for hanging indent. E12.py:215:9: E126 Continuation line over indented for hanging indent. | 213 | #: E126 -214 | print "In", ( -215 | "dent") +214 | print("In", ( +215 | "dent")) | ^^^^^^ E126 216 | 217 | #: E126 @@ -146,5 +146,3 @@ E12.py:280:13: E126 Continuation line over indented for hanging indent. 281 | or y == 4): 282 | pass | - - diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E127_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E127_E12.py.snap index d56ebf3111b49..4668f98971fae 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E127_E12.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E127_E12.py.snap @@ -23,8 +23,8 @@ E12.py:177:17: E127 Continuation line over indented for visual indent. E12.py:286:19: E127 Continuation line over indented for visual indent. | 284 | #: E127 -285 | print ("abcd", ("over-", -286 | "over-indent")) +285 | print(("abcd", ("over-", +286 | "over-indent"))) | ^^^^^^^^^^^^^ E127 287 | 288 | #: E127 @@ -197,5 +197,3 @@ E12.py:361:11: E127 Continuation line over indented for visual indent. | ^^^^ E127 362 | file_2.write(file_1.read()) | - - diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E128_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E128_E12.py.snap index 18ce940da273a..dbf3a354c4224 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E128_E12.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E128_E12.py.snap @@ -4,19 +4,19 @@ source: crates/ruff_linter/src/rules/pycodestyle/mod.rs E12.py:117:16: E128 Continuation line under indented for visual indent. | 115 | #: E124 E128 -116 | print ("E124", ("visual", +116 | print(("E124", ("visual", 117 | "indent_two" | ^^^^^^^^^^^^ E128 -118 | )) +118 | ))) | E12.py:122:16: E128 Continuation line under indented for visual indent. | 120 | #: E124 E128 -121 | print ("E124", ("visual", +121 | print(("E124", ("visual", 122 | "indent_five" | ^^^^^^^^^^^^^ E128 -123 | )) +123 | ))) | E12.py:169:9: E128 Continuation line under indented for visual indent. @@ -70,8 +70,8 @@ E12.py:372:15: E128 Continuation line under indented for visual indent. E12.py:377:5: E128 Continuation line under indented for visual indent. | 375 | #: E128 -376 | print ("abcd", ("visual", -377 | "hanging")) +376 | print(("abcd", ("visual", +377 | "hanging"))) | ^^^^^^^^^ E128 378 | 379 | #: E128 @@ -80,8 +80,8 @@ E12.py:377:5: E128 Continuation line under indented for visual indent. E12.py:381:15: E128 Continuation line under indented for visual indent. | 379 | #: E128 -380 | print ("abcd", ("under-", -381 | "under-indent")) +380 | print(("abcd", ("under-", +381 | "under-indent"))) | ^^^^^^^^^^^^^^ E128 382 | 383 | #: E128 @@ -164,5 +164,3 @@ E12.py:417:18: E128 Continuation line under indented for visual indent. 418 | 419 | #: E129 W503 | - - diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E131_E12.py.snap b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E131_E12.py.snap index d42e77e12de2a..cde55e21684d9 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E131_E12.py.snap +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E131_E12.py.snap @@ -6,7 +6,7 @@ E12.py:434:6: E131 Continuation line unaligned for hanging indent. 433 | "there", 434 | # "john", | ^^^^^^^^^ E131 -435 | "dude") +435 | "dude")) | E12.py:441:9: E131 Continuation line unaligned for hanging indent. @@ -17,5 +17,3 @@ E12.py:441:9: E131 Continuation line unaligned for hanging indent. | ^^^^^^^^^^^^ E131 442 | } | - -