sonicop 26.8.112 → 26.8.113
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Cargo.lock +11 -11
- data/Cargo.toml +4 -4
- data/README.ja.md +36 -23
- data/README.md +38 -26
- data/lib/sonicop/version.rb +1 -1
- data/src/config/inheritance.rs +45 -3
- data/src/engine.rs +11 -7
- data/src/lib.rs +1 -0
- data/src/nul_bytes.rs +2 -6
- data/src/parser.rs +37 -0
- data/src/profile.rs +13 -1
- data/src/rules/bundler/duplicated_group.rs +3 -2
- data/src/rules/bundler/gem_comment.rs +5 -4
- data/src/rules/gemspec/attribute_assignment.rs +4 -3
- data/src/rules/gemspec/deprecated_attribute_assignment.rs +7 -6
- data/src/rules/gemspec/duplicated_assignment.rs +4 -3
- data/src/rules/gemspec/require_mfa.rs +10 -9
- data/src/rules/gemspec/required_ruby_version.rs +3 -2
- data/src/rules/gemspec/support.rs +3 -2
- data/src/rules/layout/array_alignment.rs +1 -2
- data/src/rules/layout/block_end_newline.rs +5 -5
- data/src/rules/layout/class_structure.rs +5 -3
- data/src/rules/layout/closing_heredoc_indentation.rs +4 -3
- data/src/rules/layout/closing_parenthesis_indentation.rs +1 -2
- data/src/rules/layout/condition_position.rs +3 -2
- data/src/rules/layout/def_end_alignment.rs +2 -2
- data/src/rules/layout/dot_position.rs +1 -2
- data/src/rules/layout/empty_line_after_guard_clause.rs +3 -6
- data/src/rules/layout/empty_line_after_multiline_condition.rs +5 -5
- data/src/rules/layout/empty_lines_around_access_modifier.rs +2 -3
- data/src/rules/layout/empty_lines_around_arguments.rs +4 -4
- data/src/rules/layout/empty_lines_around_exception_handling_keywords.rs +1 -2
- data/src/rules/layout/empty_lines_around_method_body.rs +3 -2
- data/src/rules/layout/end_alignment.rs +2 -2
- data/src/rules/layout/extra_spacing.rs +7 -6
- data/src/rules/layout/first_array_element_indentation.rs +1 -2
- data/src/rules/layout/first_hash_element_indentation.rs +8 -6
- data/src/rules/layout/hash_alignment.rs +4 -4
- data/src/rules/layout/heredoc_argument_closing_parenthesis.rs +6 -5
- data/src/rules/layout/heredoc_indentation.rs +4 -3
- data/src/rules/layout/indentation_style.rs +4 -3
- data/src/rules/layout/indentation_width.rs +14 -13
- data/src/rules/layout/line_continuation_leading_space.rs +4 -3
- data/src/rules/layout/line_continuation_spacing.rs +2 -2
- data/src/rules/layout/line_length.rs +101 -57
- data/src/rules/layout/multiline_assignment_layout.rs +4 -3
- data/src/rules/layout/multiline_block_layout.rs +1 -2
- data/src/rules/layout/multiline_expression.rs +60 -31
- data/src/rules/layout/multiline_hash_brace_layout.rs +4 -3
- data/src/rules/layout/multiline_method_call_indentation.rs +1 -1
- data/src/rules/layout/multiline_operation_indentation.rs +3 -3
- data/src/rules/layout/redundant_line_break.rs +3 -2
- data/src/rules/layout/single_line_block_chain.rs +4 -3
- data/src/rules/layout/space_around_block_parameters.rs +1 -2
- data/src/rules/layout/space_around_equals_in_parameter_default.rs +1 -2
- data/src/rules/layout/space_around_operators.rs +1 -2
- data/src/rules/layout/space_before_brackets.rs +6 -5
- data/src/rules/layout/space_before_comma.rs +3 -2
- data/src/rules/layout/space_inside_range_literal.rs +8 -6
- data/src/rules/layout/support.rs +9 -7
- data/src/rules/layout/tokens.rs +15 -6
- data/src/rules/lint/access_modifier.rs +19 -10
- data/src/rules/lint/ambiguity.rs +2 -2
- data/src/rules/lint/ambiguous_block_association.rs +7 -10
- data/src/rules/lint/ambiguous_regexp_literal.rs +7 -5
- data/src/rules/lint/array_literal_in_regexp.rs +4 -3
- data/src/rules/lint/assignment_in_condition.rs +3 -2
- data/src/rules/lint/blocks.rs +2 -1
- data/src/rules/lint/boolean_symbol.rs +4 -4
- data/src/rules/lint/constant_definition_in_block.rs +1 -2
- data/src/rules/lint/constant_reassignment.rs +2 -1
- data/src/rules/lint/deprecated_open_ssl_constant.rs +1 -2
- data/src/rules/lint/disjunctive_assignment_in_constructor.rs +2 -2
- data/src/rules/lint/duplicate_branch.rs +6 -5
- data/src/rules/lint/duplicate_case_condition.rs +5 -5
- data/src/rules/lint/duplicate_hash_key.rs +4 -3
- data/src/rules/lint/duplicate_match_pattern.rs +7 -5
- data/src/rules/lint/duplicate_methods.rs +4 -3
- data/src/rules/lint/duplicate_require.rs +1 -2
- data/src/rules/lint/duplicate_set_element.rs +3 -2
- data/src/rules/lint/empty_conditional_body.rs +4 -3
- data/src/rules/lint/empty_in_pattern.rs +3 -2
- data/src/rules/lint/empty_when.rs +4 -4
- data/src/rules/lint/ensure_return.rs +3 -2
- data/src/rules/lint/float_comparison.rs +8 -6
- data/src/rules/lint/format_parameter_mismatch.rs +4 -3
- data/src/rules/lint/hash_compare_by_identity.rs +5 -4
- data/src/rules/lint/heredoc_method_call_position.rs +3 -2
- data/src/rules/lint/implicit_string_concatenation.rs +7 -5
- data/src/rules/lint/ineffective_access_modifier.rs +5 -4
- data/src/rules/lint/inherit_exception.rs +4 -3
- data/src/rules/lint/literal_as_condition.rs +5 -3
- data/src/rules/lint/literal_assignment_in_condition.rs +4 -3
- data/src/rules/lint/literal_in_interpolation.rs +5 -5
- data/src/rules/lint/literals.rs +10 -8
- data/src/rules/lint/no_return_in_begin_end_blocks.rs +2 -2
- data/src/rules/lint/node_equality.rs +8 -5
- data/src/rules/lint/non_atomic_file_operation.rs +1 -1
- data/src/rules/lint/non_deterministic_require_order.rs +5 -3
- data/src/rules/lint/non_local_exit_from_iterator.rs +3 -2
- data/src/rules/lint/number_conversion.rs +1 -1
- data/src/rules/lint/out_of_range_regexp_ref.rs +6 -4
- data/src/rules/lint/redundant_dir_glob_sort.rs +1 -2
- data/src/rules/lint/redundant_safe_navigation.rs +4 -3
- data/src/rules/lint/redundant_splat_expansion.rs +4 -2
- data/src/rules/lint/redundant_string_coercion.rs +3 -2
- data/src/rules/lint/regexp_source.rs +2 -2
- data/src/rules/lint/require_range_parentheses.rs +5 -5
- data/src/rules/lint/rescue_exception.rs +4 -3
- data/src/rules/lint/rescue_type.rs +3 -2
- data/src/rules/lint/return_in_void_context.rs +2 -2
- data/src/rules/lint/safe_navigation_chain.rs +3 -2
- data/src/rules/lint/self_assignment.rs +3 -2
- data/src/rules/lint/shadowed_argument.rs +2 -2
- data/src/rules/lint/shadowed_exception.rs +2 -2
- data/src/rules/lint/suppressed_exception_in_number_conversion.rs +4 -3
- data/src/rules/lint/symbol_conversion.rs +6 -5
- data/src/rules/lint/syntax.rs +4 -3
- data/src/rules/lint/triple_quotes.rs +3 -2
- data/src/rules/lint/unescaped_bracket_in_regexp.rs +1 -1
- data/src/rules/lint/unexpected_block_arity.rs +3 -2
- data/src/rules/lint/unmodified_reduce_accumulator.rs +7 -6
- data/src/rules/lint/unreachable_pattern_branch.rs +4 -4
- data/src/rules/lint/unused_block_argument.rs +2 -2
- data/src/rules/lint/unused_method_argument.rs +1 -2
- data/src/rules/lint/useless_assignment.rs +3 -2
- data/src/rules/lint/useless_constant_scoping.rs +3 -2
- data/src/rules/lint/useless_else_without_rescue.rs +4 -3
- data/src/rules/lint/useless_rescue.rs +5 -4
- data/src/rules/lint/useless_ruby2_keywords.rs +2 -1
- data/src/rules/lint/useless_setter_call.rs +5 -4
- data/src/rules/lint/useless_times.rs +4 -3
- data/src/rules/lint/variable_force.rs +146 -100
- data/src/rules/lint/void.rs +5 -4
- data/src/rules/metrics/block_nesting.rs +1 -2
- data/src/rules/metrics/collection_literal_length.rs +2 -1
- data/src/rules/metrics/complexity.rs +18 -13
- data/src/rules/metrics/fragments.rs +10 -14
- data/src/rules/metrics/locals.rs +23 -12
- data/src/rules/metrics/parameter_lists.rs +7 -6
- data/src/rules/metrics/support.rs +1 -1
- data/src/rules/mod.rs +464 -62
- data/src/rules/naming/ascii_identifiers.rs +3 -3
- data/src/rules/naming/block_forwarding.rs +9 -8
- data/src/rules/naming/constant_name.rs +1 -1
- data/src/rules/naming/predicate_method.rs +6 -5
- data/src/rules/naming/predicate_prefix.rs +10 -8
- data/src/rules/naming/rescued_exceptions_variable_name.rs +8 -6
- data/src/rules/naming/support.rs +7 -5
- data/src/rules/naming/variable_number.rs +4 -4
- data/src/rules/node_ext.rs +1 -1
- data/src/rules/ruby_literal.rs +3 -2
- data/src/rules/security/compound_hash.rs +3 -2
- data/src/rules/security/open.rs +5 -4
- data/src/rules/send_node.rs +134 -0
- data/src/rules/single_line.rs +4 -4
- data/src/rules/style/access_modifier_declarations.rs +1 -1
- data/src/rules/style/alias.rs +1 -2
- data/src/rules/style/and_or.rs +2 -2
- data/src/rules/style/arguments_forwarding.rs +5 -5
- data/src/rules/style/array_coercion.rs +5 -5
- data/src/rules/style/array_first_last.rs +3 -3
- data/src/rules/style/array_intersect.rs +2 -2
- data/src/rules/style/array_intersect_with_single_element.rs +1 -1
- data/src/rules/style/attr.rs +1 -1
- data/src/rules/style/auto_resource_cleanup.rs +1 -1
- data/src/rules/style/bitwise_predicate.rs +2 -2
- data/src/rules/style/block_args.rs +1 -1
- data/src/rules/style/block_delimiters.rs +7 -6
- data/src/rules/style/case_equality.rs +3 -2
- data/src/rules/style/case_like_if.rs +1 -1
- data/src/rules/style/class_and_module_children.rs +7 -5
- data/src/rules/style/class_methods.rs +1 -1
- data/src/rules/style/collection_compact.rs +4 -4
- data/src/rules/style/combinable_defined.rs +2 -2
- data/src/rules/style/combinable_loops.rs +1 -1
- data/src/rules/style/comparable_clamp.rs +2 -2
- data/src/rules/style/concat_array_literals.rs +3 -3
- data/src/rules/style/conditional.rs +8 -1
- data/src/rules/style/constant_visibility.rs +3 -3
- data/src/rules/style/copyright.rs +1 -1
- data/src/rules/style/data_inheritance.rs +1 -1
- data/src/rules/style/def_with_parentheses.rs +1 -1
- data/src/rules/style/document_dynamic_eval_definition.rs +1 -1
- data/src/rules/style/documentation.rs +1 -1
- data/src/rules/style/each_for_simple_loop.rs +1 -1
- data/src/rules/style/each_with_object.rs +4 -4
- data/src/rules/style/empty_block_parameter.rs +1 -1
- data/src/rules/style/empty_case_condition.rs +6 -6
- data/src/rules/style/empty_class_definition.rs +1 -1
- data/src/rules/style/empty_else.rs +1 -1
- data/src/rules/style/empty_heredoc.rs +1 -1
- data/src/rules/style/empty_lambda_parameter.rs +1 -1
- data/src/rules/style/empty_literal.rs +2 -2
- data/src/rules/style/empty_method.rs +1 -1
- data/src/rules/style/empty_string_inside_interpolation.rs +1 -1
- data/src/rules/style/endless.rs +1 -1
- data/src/rules/style/env_home.rs +1 -1
- data/src/rules/style/even_odd.rs +1 -1
- data/src/rules/style/exact_regexp_match.rs +1 -1
- data/src/rules/style/expand_path_arguments.rs +3 -3
- data/src/rules/style/explicit_block_argument.rs +3 -3
- data/src/rules/style/file_open_call.rs +3 -3
- data/src/rules/style/file_write.rs +1 -1
- data/src/rules/style/for.rs +1 -1
- data/src/rules/style/format_string.rs +2 -2
- data/src/rules/style/format_string_token.rs +6 -6
- data/src/rules/style/guard_clause.rs +8 -7
- data/src/rules/style/hash_as_last_array_item.rs +4 -4
- data/src/rules/style/hash_each_methods.rs +1 -1
- data/src/rules/style/hash_like_case.rs +8 -8
- data/src/rules/style/hash_lookup_method.rs +3 -3
- data/src/rules/style/hash_subset.rs +16 -10
- data/src/rules/style/hash_syntax.rs +4 -4
- data/src/rules/style/hash_transform.rs +20 -18
- data/src/rules/style/identical_conditional_branches.rs +4 -5
- data/src/rules/style/if_inside_else.rs +3 -3
- data/src/rules/style/if_unless_modifier.rs +13 -14
- data/src/rules/style/if_with_boolean_literal_branches.rs +1 -1
- data/src/rules/style/if_with_semicolon.rs +1 -1
- data/src/rules/style/in_pattern_then.rs +2 -2
- data/src/rules/style/inverse_methods.rs +2 -2
- data/src/rules/style/invertible_unless_condition.rs +3 -3
- data/src/rules/style/it_block_parameter.rs +1 -1
- data/src/rules/style/keyword_arguments_merging.rs +2 -2
- data/src/rules/style/keyword_parameters_order.rs +1 -1
- data/src/rules/style/magic_comment_format.rs +3 -2
- data/src/rules/style/map_chain.rs +1 -1
- data/src/rules/style/map_compact_with_conditional_block.rs +3 -3
- data/src/rules/style/map_into_array.rs +7 -7
- data/src/rules/style/map_join.rs +3 -3
- data/src/rules/style/method_call_with_args_parentheses.rs +7 -7
- data/src/rules/style/method_call_without_args_parentheses.rs +2 -2
- data/src/rules/style/method_def_parentheses.rs +2 -3
- data/src/rules/style/min_max.rs +3 -3
- data/src/rules/style/min_max_comparison.rs +2 -2
- data/src/rules/style/missing_else.rs +1 -1
- data/src/rules/style/missing_respond_to_missing.rs +1 -1
- data/src/rules/style/mixin_grouping.rs +1 -1
- data/src/rules/style/multiline_block_chain.rs +2 -2
- data/src/rules/style/multiline_if_then.rs +1 -1
- data/src/rules/style/multiline_in_pattern_then.rs +1 -1
- data/src/rules/style/multiline_method_signature.rs +1 -1
- data/src/rules/style/multiline_when_then.rs +2 -2
- data/src/rules/style/mutable_constant.rs +3 -3
- data/src/rules/style/negated_if.rs +2 -2
- data/src/rules/style/negated_if_else_condition.rs +2 -2
- data/src/rules/style/negated_while.rs +1 -1
- data/src/rules/style/negative_array_index.rs +2 -2
- data/src/rules/style/nested_modifier.rs +1 -1
- data/src/rules/style/nested_parenthesized_calls.rs +2 -2
- data/src/rules/style/nested_ternary_operator.rs +2 -2
- data/src/rules/style/next.rs +1 -1
- data/src/rules/style/nil_lambda.rs +2 -2
- data/src/rules/style/nodes.rs +21 -0
- data/src/rules/style/non_nil_check.rs +2 -2
- data/src/rules/style/numbered_parameters_limit.rs +2 -2
- data/src/rules/style/one_line_conditional.rs +4 -4
- data/src/rules/style/optional_arguments.rs +1 -1
- data/src/rules/style/or_assignment.rs +1 -1
- data/src/rules/style/parallel_assignment.rs +9 -10
- data/src/rules/style/parens.rs +1 -1
- data/src/rules/style/parentheses_around_condition.rs +3 -3
- data/src/rules/style/partition_instead_of_double_select.rs +3 -3
- data/src/rules/style/percent.rs +9 -7
- data/src/rules/style/percent_q_literals.rs +4 -3
- data/src/rules/style/preferred_hash_methods.rs +1 -1
- data/src/rules/style/random_with_offset.rs +1 -1
- data/src/rules/style/reduce_to_hash.rs +6 -6
- data/src/rules/style/redundant_argument.rs +1 -1
- data/src/rules/style/redundant_assignment.rs +5 -5
- data/src/rules/style/redundant_begin.rs +2 -2
- data/src/rules/style/redundant_capital_w.rs +3 -2
- data/src/rules/style/redundant_condition.rs +9 -7
- data/src/rules/style/redundant_current_directory_in_path.rs +2 -2
- data/src/rules/style/redundant_double_splat_hash_braces.rs +4 -4
- data/src/rules/style/redundant_file_extension_in_require.rs +2 -2
- data/src/rules/style/redundant_format.rs +16 -14
- data/src/rules/style/redundant_freeze.rs +1 -1
- data/src/rules/style/redundant_heredoc_delimiter_quotes.rs +1 -1
- data/src/rules/style/redundant_initialize.rs +2 -2
- data/src/rules/style/redundant_interpolation.rs +2 -2
- data/src/rules/style/redundant_interpolation_unfreeze.rs +2 -2
- data/src/rules/style/redundant_line_continuation.rs +5 -4
- data/src/rules/style/redundant_parentheses.rs +16 -15
- data/src/rules/style/redundant_regexp_argument.rs +1 -1
- data/src/rules/style/redundant_regexp_character_class.rs +4 -3
- data/src/rules/style/redundant_regexp_escape.rs +3 -2
- data/src/rules/style/redundant_return.rs +1 -2
- data/src/rules/style/redundant_self.rs +11 -11
- data/src/rules/style/redundant_sort.rs +1 -1
- data/src/rules/style/redundant_sort_by.rs +1 -1
- data/src/rules/style/redundant_string_escape.rs +6 -5
- data/src/rules/style/regexp_literal.rs +3 -2
- data/src/rules/style/require_order.rs +2 -2
- data/src/rules/style/rescue_modifier.rs +1 -1
- data/src/rules/style/rescue_standard_error.rs +1 -1
- data/src/rules/style/return_nil.rs +2 -2
- data/src/rules/style/return_nil_in_predicate_method_definition.rs +2 -2
- data/src/rules/style/safe_navigation.rs +2 -2
- data/src/rules/style/sample.rs +3 -3
- data/src/rules/style/select_by.rs +2 -2
- data/src/rules/style/select_by_range.rs +1 -1
- data/src/rules/style/semicolon.rs +5 -4
- data/src/rules/style/single_argument_dig.rs +1 -1
- data/src/rules/style/single_line_block_params.rs +7 -6
- data/src/rules/style/single_line_do_end_block.rs +13 -12
- data/src/rules/style/single_line_methods.rs +2 -2
- data/src/rules/style/slicing_with_range.rs +2 -2
- data/src/rules/style/sole_nested_conditional.rs +4 -4
- data/src/rules/style/special_global_vars.rs +2 -2
- data/src/rules/style/stabby_lambda_parentheses.rs +1 -1
- data/src/rules/style/statement_modifier.rs +3 -2
- data/src/rules/style/static_class.rs +1 -1
- data/src/rules/style/string_concatenation.rs +9 -7
- data/src/rules/style/string_hash_keys.rs +3 -2
- data/src/rules/style/string_literals.rs +3 -3
- data/src/rules/style/string_literals_in_interpolation.rs +1 -1
- data/src/rules/style/struct_inheritance.rs +3 -3
- data/src/rules/style/super_arguments.rs +2 -2
- data/src/rules/style/super_with_args_parentheses.rs +1 -1
- data/src/rules/style/swap_values.rs +1 -1
- data/src/rules/style/symbol_array.rs +1 -1
- data/src/rules/style/symbol_proc.rs +3 -3
- data/src/rules/style/tally_method.rs +4 -4
- data/src/rules/style/ternary_parentheses.rs +4 -4
- data/src/rules/style/top_level_method_definition.rs +1 -1
- data/src/rules/style/trailing_body.rs +1 -1
- data/src/rules/style/trailing_comma_in_array_literal.rs +1 -1
- data/src/rules/style/trailing_comma_in_hash_literal.rs +1 -1
- data/src/rules/style/trailing_method_end_statement.rs +1 -1
- data/src/rules/style/trailing_underscore_variable.rs +4 -5
- data/src/rules/style/trivial_accessors.rs +2 -2
- data/src/rules/style/unless_logical_operators.rs +1 -1
- data/src/rules/style/unpack_first.rs +1 -1
- data/src/rules/style/when_then.rs +4 -4
- data/src/rules/style/while_until_do.rs +1 -1
- data/src/rules/style/while_until_modifier.rs +3 -3
- data/src/rules/style/word_array.rs +3 -3
- data/src/rules/style/yoda_condition.rs +2 -2
- data/src/rules/support.rs +33 -8
- metadata +2 -1
|
@@ -3,9 +3,10 @@ use tree_sitter::Node;
|
|
|
3
3
|
use crate::diagnostic::{Edit, Offense};
|
|
4
4
|
use crate::rules::RuleContext;
|
|
5
5
|
use crate::rules::node_ext::NodeExt;
|
|
6
|
-
use crate::rules::
|
|
7
|
-
use crate::rules::send_node::{arguments, is_plain_send,
|
|
6
|
+
use crate::rules::{push_named_children_in};
|
|
7
|
+
use crate::rules::send_node::{arguments, is_plain_send, top_level_constant};
|
|
8
8
|
use crate::rules::support::whole_lines;
|
|
9
|
+
use crate::rules::send_node::named_children_of;
|
|
9
10
|
|
|
10
11
|
/// The attributes RubyGems deprecated, in the order upstream tries them. The order is what the cop
|
|
11
12
|
/// reports, and it is also load-bearing for `+=`: see [`deprecated_attribute`].
|
|
@@ -87,7 +88,7 @@ fn is_specification(call: Node<'_>, context: &RuleContext<'_>) -> bool {
|
|
|
87
88
|
/// has. A destructured `|(a, b)|` yields `(a, b)`, which no receiver can be written as.
|
|
88
89
|
fn block_parameter<'a>(call: Node<'_>, context: &'a RuleContext<'_>) -> Option<&'a str> {
|
|
89
90
|
let parameters = call.field("block")?.field("parameters")?;
|
|
90
|
-
let first =
|
|
91
|
+
let first = named_children_of(parameters, context).first().copied()?;
|
|
91
92
|
Some(context.source.node_text(first))
|
|
92
93
|
}
|
|
93
94
|
|
|
@@ -100,15 +101,15 @@ fn block_parameter<'a>(call: Node<'_>, context: &'a RuleContext<'_>) -> Option<&
|
|
|
100
101
|
fn first_deprecated<'tree>(
|
|
101
102
|
call: Node<'tree>,
|
|
102
103
|
parameter: &str,
|
|
103
|
-
context: &RuleContext<'_>,
|
|
104
|
+
context: &'tree RuleContext<'_>,
|
|
104
105
|
) -> Option<(Node<'tree>, &'static str)> {
|
|
105
106
|
let mut stack = Vec::new();
|
|
106
|
-
|
|
107
|
+
push_named_children_in(call, context, &mut stack);
|
|
107
108
|
while let Some(node) = stack.pop() {
|
|
108
109
|
if let Some(attribute) = deprecated_attribute(node, parameter, context) {
|
|
109
110
|
return Some((node, attribute));
|
|
110
111
|
}
|
|
111
|
-
|
|
112
|
+
push_named_children_in(node, context, &mut stack);
|
|
112
113
|
}
|
|
113
114
|
None
|
|
114
115
|
}
|
|
@@ -2,12 +2,13 @@ use tree_sitter::Node;
|
|
|
2
2
|
|
|
3
3
|
use crate::diagnostic::Offense;
|
|
4
4
|
use crate::rules::RuleContext;
|
|
5
|
-
use crate::rules::send_node::{first_line_range, is_plain_send, literal_key
|
|
5
|
+
use crate::rules::send_node::{first_line_range, is_plain_send, literal_key};
|
|
6
6
|
|
|
7
7
|
use super::support::{
|
|
8
8
|
enclosing_specification, first_specification_variable, is_literal, is_specification_receiver,
|
|
9
9
|
};
|
|
10
10
|
use crate::rules::node_ext::NodeExt;
|
|
11
|
+
use crate::rules::send_node::named_children_of;
|
|
11
12
|
|
|
12
13
|
/// The specification block an assignment was made in, and the target it named. Two assignments
|
|
13
14
|
/// are duplicates of one another only when both agree.
|
|
@@ -30,7 +31,7 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
|
30
31
|
};
|
|
31
32
|
// `spec.a, spec.b = 1, 2` assigns through one node per target.
|
|
32
33
|
let targets = match left.kind_str() {
|
|
33
|
-
"left_assignment_list" =>
|
|
34
|
+
"left_assignment_list" => named_children_of(left, context),
|
|
34
35
|
_ => vec![left],
|
|
35
36
|
};
|
|
36
37
|
for target in targets {
|
|
@@ -92,7 +93,7 @@ fn assignment<'tree>(
|
|
|
92
93
|
return None;
|
|
93
94
|
}
|
|
94
95
|
let method = context.source.node_text(object.field("method")?);
|
|
95
|
-
let indices =
|
|
96
|
+
let indices = named_children_of(target, context);
|
|
96
97
|
let [index] = indices.get(1..)? else {
|
|
97
98
|
return None;
|
|
98
99
|
};
|
|
@@ -5,13 +5,14 @@ use tree_sitter::Node;
|
|
|
5
5
|
use crate::diagnostic::{Edit, Offense};
|
|
6
6
|
use crate::rules::RuleContext;
|
|
7
7
|
use crate::rules::node_ext::NodeExt;
|
|
8
|
-
use crate::rules::
|
|
8
|
+
use crate::rules::{push_named_children_in};
|
|
9
9
|
use crate::rules::send_node::{
|
|
10
10
|
has_interpolation, is_plain_send, is_string, named_children, pair_key_symbol, string_text,
|
|
11
11
|
symbol_name,
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
use super::support::{local_variables, specification_variable};
|
|
15
|
+
use crate::rules::send_node::named_children_of;
|
|
15
16
|
|
|
16
17
|
const KEY: &str = "rubygems_mfa_required";
|
|
17
18
|
const MSG: &str = "`metadata['rubygems_mfa_required']` must be set to `'true'`.";
|
|
@@ -41,7 +42,7 @@ fn specifications_within<'a>(block: Node<'_>, context: &'a RuleContext<'_>) -> V
|
|
|
41
42
|
if let Some(variable) = specification_variable(node, context) {
|
|
42
43
|
found.push(variable);
|
|
43
44
|
}
|
|
44
|
-
|
|
45
|
+
push_named_children_in(node, context, &mut stack);
|
|
45
46
|
}
|
|
46
47
|
found
|
|
47
48
|
}
|
|
@@ -84,7 +85,7 @@ fn report(
|
|
|
84
85
|
fn metadata_value<'tree>(
|
|
85
86
|
block: Node<'tree>,
|
|
86
87
|
locals: &HashSet<&str>,
|
|
87
|
-
context: &RuleContext<'_>,
|
|
88
|
+
context: &'tree RuleContext<'_>,
|
|
88
89
|
) -> Option<Node<'tree>> {
|
|
89
90
|
let mut stack = vec![block];
|
|
90
91
|
while let Some(node) = stack.pop() {
|
|
@@ -102,7 +103,7 @@ fn metadata_value<'tree>(
|
|
|
102
103
|
return node.field("right");
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
|
-
|
|
106
|
+
push_named_children_in(node, context, &mut stack);
|
|
106
107
|
}
|
|
107
108
|
None
|
|
108
109
|
}
|
|
@@ -111,7 +112,7 @@ fn metadata_value<'tree>(
|
|
|
111
112
|
/// hash gives the `rubygems_mfa_required` key.
|
|
112
113
|
fn mfa_value<'tree>(
|
|
113
114
|
metadata: Option<Node<'tree>>,
|
|
114
|
-
context: &RuleContext<'_>,
|
|
115
|
+
context: &'tree RuleContext<'_>,
|
|
115
116
|
) -> Option<Node<'tree>> {
|
|
116
117
|
let metadata = metadata?;
|
|
117
118
|
if is_string(metadata, context) {
|
|
@@ -122,7 +123,7 @@ fn mfa_value<'tree>(
|
|
|
122
123
|
if node.kind_str() == "pair" && is_mfa_pair(node, context) {
|
|
123
124
|
return node.field("value");
|
|
124
125
|
}
|
|
125
|
-
|
|
126
|
+
push_named_children_in(node, context, &mut stack);
|
|
126
127
|
}
|
|
127
128
|
None
|
|
128
129
|
}
|
|
@@ -139,7 +140,7 @@ fn insertion(
|
|
|
139
140
|
// `correct_metadata`: a new pair goes after the last one, or between the braces of an empty
|
|
140
141
|
// hash. Metadata assigned anything other than a hash literal cannot be corrected at all.
|
|
141
142
|
Some(hash) if hash.kind_str() == "hash" => {
|
|
142
|
-
let pairs: Vec<Node<'_>> =
|
|
143
|
+
let pairs: Vec<Node<'_>> = named_children_of(hash, context)
|
|
143
144
|
.into_iter()
|
|
144
145
|
.filter(|child| child.kind_str() == "pair")
|
|
145
146
|
.collect();
|
|
@@ -183,7 +184,7 @@ fn insertion(
|
|
|
183
184
|
fn last_metadata_assignment<'tree>(
|
|
184
185
|
block: Node<'tree>,
|
|
185
186
|
locals: &HashSet<&str>,
|
|
186
|
-
context: &RuleContext<'_>,
|
|
187
|
+
context: &'tree RuleContext<'_>,
|
|
187
188
|
) -> Option<Node<'tree>> {
|
|
188
189
|
let mut last = None;
|
|
189
190
|
let mut stack = vec![block];
|
|
@@ -196,7 +197,7 @@ fn last_metadata_assignment<'tree>(
|
|
|
196
197
|
{
|
|
197
198
|
last = Some(node);
|
|
198
199
|
}
|
|
199
|
-
|
|
200
|
+
push_named_children_in(node, context, &mut stack);
|
|
200
201
|
}
|
|
201
202
|
last
|
|
202
203
|
}
|
|
@@ -6,6 +6,7 @@ use crate::rules::send_node::{
|
|
|
6
6
|
FILE_KEYWORD, arguments, is_plain_send, is_string, named_children, string_text,
|
|
7
7
|
};
|
|
8
8
|
use crate::rules::node_ext::NodeExt;
|
|
9
|
+
use crate::rules::send_node::named_children_of;
|
|
9
10
|
|
|
10
11
|
pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
11
12
|
let assignments: Vec<Node<'_>> = context
|
|
@@ -66,7 +67,7 @@ fn dynamic_version(node: Node<'_>, context: &RuleContext<'_>) -> bool {
|
|
|
66
67
|
{
|
|
67
68
|
return true;
|
|
68
69
|
}
|
|
69
|
-
|
|
70
|
+
named_children_of(node, context)
|
|
70
71
|
.into_iter()
|
|
71
72
|
.any(|child| dynamic_descendant(child, context))
|
|
72
73
|
}
|
|
@@ -74,7 +75,7 @@ fn dynamic_version(node: Node<'_>, context: &RuleContext<'_>) -> bool {
|
|
|
74
75
|
fn dynamic_descendant(node: Node<'_>, context: &RuleContext<'_>) -> bool {
|
|
75
76
|
is_variable(node, context)
|
|
76
77
|
|| is_send(node, context)
|
|
77
|
-
||
|
|
78
|
+
|| named_children_of(node, context)
|
|
78
79
|
.into_iter()
|
|
79
80
|
.any(|child| dynamic_descendant(child, context))
|
|
80
81
|
}
|
|
@@ -8,7 +8,8 @@ use crate::rules::RuleContext;
|
|
|
8
8
|
use crate::rules::lint::blocks::BlockArgs;
|
|
9
9
|
use crate::rules::lint::locals::LocalVariables;
|
|
10
10
|
use crate::rules::node_ext::NodeExt;
|
|
11
|
-
use crate::rules::send_node::
|
|
11
|
+
use crate::rules::send_node::named_children_of;
|
|
12
|
+
use crate::rules::send_node::{arguments, top_level_constant};
|
|
12
13
|
|
|
13
14
|
/// The block parameter of `Gem::Specification.new do |spec|`, or `None` when the call is not one.
|
|
14
15
|
///
|
|
@@ -38,7 +39,7 @@ pub(super) fn specification_variable<'a>(
|
|
|
38
39
|
return None;
|
|
39
40
|
}
|
|
40
41
|
let parameters = call.field("block")?.field("parameters")?;
|
|
41
|
-
match
|
|
42
|
+
match named_children_of(parameters, context).as_slice() {
|
|
42
43
|
[only] if only.kind_str() == "identifier" => Some(context.source.node_text(*only)),
|
|
43
44
|
_ => None,
|
|
44
45
|
}
|
|
@@ -101,8 +101,7 @@ fn inspect(
|
|
|
101
101
|
/// `node.children`, where a run of `key: value` pairs is a single `hash` value upstream.
|
|
102
102
|
fn elements(node: Node<'_>) -> Vec<Range<usize>> {
|
|
103
103
|
let mut cursor = node.walk();
|
|
104
|
-
let children: Vec<Node<'_>> = node
|
|
105
|
-
.named_children(&mut cursor)
|
|
104
|
+
let children: Vec<Node<'_>> = node.named_children(&mut cursor)
|
|
106
105
|
.filter(|child| !matches!(child.kind_str(), "comment" | "heredoc_body"))
|
|
107
106
|
.collect();
|
|
108
107
|
let mut elements = Vec::new();
|
|
@@ -8,6 +8,7 @@ use super::support::{begins_its_line, heredoc_terminators};
|
|
|
8
8
|
use crate::diagnostic::{Edit, Offense};
|
|
9
9
|
use crate::rules::RuleContext;
|
|
10
10
|
use crate::rules::node_ext::NodeExt;
|
|
11
|
+
use crate::rules::send_node::named_children_of;
|
|
11
12
|
|
|
12
13
|
pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
13
14
|
let text = context.source.text();
|
|
@@ -108,9 +109,9 @@ fn last_heredoc_argument(
|
|
|
108
109
|
let terminators = heredoc_terminators(context);
|
|
109
110
|
loop {
|
|
110
111
|
if let Some(list) = argument_list(node) {
|
|
111
|
-
let
|
|
112
|
-
let found = list
|
|
113
|
-
.
|
|
112
|
+
let _cursor = list.walk();
|
|
113
|
+
let found = named_children_of(list, context)
|
|
114
|
+
.into_iter()
|
|
114
115
|
.filter(|child| child.kind_str() == "heredoc_beginning")
|
|
115
116
|
.filter_map(|child| plain_heredoc(context, &bodies, &terminators, child))
|
|
116
117
|
.last();
|
|
@@ -131,8 +132,7 @@ fn body_call<'tree>(block: Node<'tree>) -> Option<Node<'tree>> {
|
|
|
131
132
|
matches!(child.kind_str(), "body_statement" | "block_body") && child.named_child_count() > 0
|
|
132
133
|
})?;
|
|
133
134
|
let mut cursor = body.walk();
|
|
134
|
-
let statements: Vec<Node<'tree>> = body
|
|
135
|
-
.named_children(&mut cursor)
|
|
135
|
+
let statements: Vec<Node<'tree>> = body.named_children(&mut cursor)
|
|
136
136
|
.filter(|child| !matches!(child.kind_str(), "comment" | "heredoc_body"))
|
|
137
137
|
.collect();
|
|
138
138
|
match statements.as_slice() {
|
|
@@ -8,6 +8,8 @@ use crate::rules::lint::access_modifier::send_name;
|
|
|
8
8
|
use crate::rules::node_ext::NodeExt;
|
|
9
9
|
use crate::rules::send_node::{arguments, named_children, symbol_name};
|
|
10
10
|
use crate::rules::visibility::{node_visibility, siblings, statements};
|
|
11
|
+
use crate::rules::send_node::all_children_iter;
|
|
12
|
+
use crate::rules::send_node::named_children_iter;
|
|
11
13
|
|
|
12
14
|
pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
13
15
|
let expected: Vec<String> = context.setting("ExpectedOrder").unwrap_or_default();
|
|
@@ -204,7 +206,7 @@ fn is_private_constant(node: Node<'_>, context: &RuleContext<'_>) -> bool {
|
|
|
204
206
|
let Some(parent) = node.parent_of(context) else {
|
|
205
207
|
return false;
|
|
206
208
|
};
|
|
207
|
-
|
|
209
|
+
named_children_iter(parent, context).any(|sibling| {
|
|
208
210
|
sibling.kind_str() == "call"
|
|
209
211
|
&& sibling
|
|
210
212
|
.field("method")
|
|
@@ -358,8 +360,8 @@ fn is_upstream_send(node: Node<'_>, context: &RuleContext<'_>) -> bool {
|
|
|
358
360
|
}
|
|
359
361
|
|
|
360
362
|
fn operator_text<'a>(node: Node<'_>, context: &'a RuleContext<'_>) -> Option<&'a str> {
|
|
361
|
-
let
|
|
362
|
-
node
|
|
363
|
+
let _cursor = node.walk();
|
|
364
|
+
all_children_iter(node, context)
|
|
363
365
|
.find(|child| !child.is_named())
|
|
364
366
|
.map(|child| context.source.node_text(child))
|
|
365
367
|
}
|
|
@@ -7,6 +7,7 @@ use crate::rules::RuleContext;
|
|
|
7
7
|
|
|
8
8
|
use super::support::is_send_like;
|
|
9
9
|
use crate::rules::node_ext::NodeExt;
|
|
10
|
+
use crate::rules::send_node::named_children_of;
|
|
10
11
|
|
|
11
12
|
pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
12
13
|
let openers: Vec<Node<'_>> = context.nodes_of("heredoc_beginning").collect();
|
|
@@ -25,9 +26,9 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
|
25
26
|
if heredoc_type(&text[opener.byte_range()]) == Some("<<") {
|
|
26
27
|
continue;
|
|
27
28
|
}
|
|
28
|
-
let
|
|
29
|
-
let Some(delimiter) = body
|
|
30
|
-
.
|
|
29
|
+
let _cursor = body.walk();
|
|
30
|
+
let Some(delimiter) = named_children_of(body, context)
|
|
31
|
+
.into_iter()
|
|
31
32
|
.find(|child| child.kind_str() == "heredoc_end")
|
|
32
33
|
else {
|
|
33
34
|
continue;
|
|
@@ -153,8 +153,7 @@ fn delimited<'tree>(node: Node<'tree>) -> Option<Delimited<'tree>> {
|
|
|
153
153
|
"call" => grouped(node),
|
|
154
154
|
_ => {
|
|
155
155
|
let mut cursor = container.walk();
|
|
156
|
-
container
|
|
157
|
-
.named_children(&mut cursor)
|
|
156
|
+
container.named_children(&mut cursor)
|
|
158
157
|
.filter(|child| !matches!(child.kind_str(), "comment" | "heredoc_body"))
|
|
159
158
|
.map(|child| (child.start_byte(), hash_parts(child)))
|
|
160
159
|
.collect()
|
|
@@ -5,6 +5,7 @@ use tree_sitter::Node;
|
|
|
5
5
|
use crate::diagnostic::{Edit, Offense};
|
|
6
6
|
use crate::rules::RuleContext;
|
|
7
7
|
use crate::rules::node_ext::NodeExt;
|
|
8
|
+
use crate::rules::send_node::named_children_iter;
|
|
8
9
|
|
|
9
10
|
pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
10
11
|
// The modifier forms and the ternary have their own node kinds here, so reaching one of these
|
|
@@ -54,8 +55,8 @@ fn removal(context: &RuleContext<'_>, node: Node<'_>, condition: Node<'_>) -> Ed
|
|
|
54
55
|
let body = node.field("consequence").or_else(|| node.field("body"));
|
|
55
56
|
let body_start = body
|
|
56
57
|
.and_then(|body| {
|
|
57
|
-
let
|
|
58
|
-
body
|
|
58
|
+
let _cursor = body.walk();
|
|
59
|
+
named_children_iter(body, context)
|
|
59
60
|
.find(|child| !matches!(child.kind_str(), "comment" | "heredoc_body"))
|
|
60
61
|
})
|
|
61
62
|
.map(|first| first.start_byte());
|
|
@@ -6,7 +6,7 @@ use tree_sitter::Node;
|
|
|
6
6
|
|
|
7
7
|
use super::support::{effective_character_column, end_keyword, end_keyword_alignment};
|
|
8
8
|
use crate::diagnostic::Offense;
|
|
9
|
-
use crate::rules::{RuleContext,
|
|
9
|
+
use crate::rules::{RuleContext, push_named_children_in};
|
|
10
10
|
use crate::rules::node_ext::NodeExt;
|
|
11
11
|
|
|
12
12
|
pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
@@ -63,7 +63,7 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
|
63
63
|
}
|
|
64
64
|
_ => {}
|
|
65
65
|
}
|
|
66
|
-
|
|
66
|
+
push_named_children_in(node, context, &mut stack);
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -136,8 +136,7 @@ fn last_heredoc(heredocs: &[(usize, Range<usize>)], receiver: Node<'_>) -> Optio
|
|
|
136
136
|
}
|
|
137
137
|
let arguments = receiver.field("arguments")?;
|
|
138
138
|
let mut cursor = arguments.walk();
|
|
139
|
-
arguments
|
|
140
|
-
.named_children(&mut cursor)
|
|
139
|
+
arguments.named_children(&mut cursor)
|
|
141
140
|
.filter(|argument| argument.kind_str() == "heredoc_beginning")
|
|
142
141
|
.filter_map(|argument| terminator_of(argument.start_byte()))
|
|
143
142
|
.max_by_key(|terminator| terminator.end)
|
|
@@ -215,8 +215,7 @@ fn if_branch<'tree>(node: Node<'tree>) -> Option<Node<'tree>> {
|
|
|
215
215
|
// A `then` clause holding more than one statement is a `begin` upstream, which is
|
|
216
216
|
// never a guard clause.
|
|
217
217
|
let mut cursor = branch.walk();
|
|
218
|
-
let mut statements = branch
|
|
219
|
-
.named_children(&mut cursor)
|
|
218
|
+
let mut statements = branch.named_children(&mut cursor)
|
|
220
219
|
.filter(|child| !matches!(child.kind_str(), "heredoc_body" | "comment"));
|
|
221
220
|
let first = statements.next()?;
|
|
222
221
|
statements.next().is_none().then_some(first)
|
|
@@ -279,8 +278,7 @@ fn next_statement<'tree>(node: Node<'tree>) -> Option<(Node<'tree>, bool)> {
|
|
|
279
278
|
_ => return None,
|
|
280
279
|
};
|
|
281
280
|
let mut cursor = parent.walk();
|
|
282
|
-
let statements: Vec<Node<'tree>> = parent
|
|
283
|
-
.named_children(&mut cursor)
|
|
281
|
+
let statements: Vec<Node<'tree>> = parent.named_children(&mut cursor)
|
|
284
282
|
.filter(|child| {
|
|
285
283
|
!matches!(
|
|
286
284
|
child.kind_str(),
|
|
@@ -382,8 +380,7 @@ fn is_and(text: &str, node: Node<'_>) -> bool {
|
|
|
382
380
|
|
|
383
381
|
fn call_arguments<'tree>(node: Node<'tree>) -> Vec<Node<'tree>> {
|
|
384
382
|
let mut cursor = node.walk();
|
|
385
|
-
let Some(list) = node
|
|
386
|
-
.children(&mut cursor)
|
|
383
|
+
let Some(list) = node.children(&mut cursor)
|
|
387
384
|
.find(|child| child.kind_str() == "argument_list")
|
|
388
385
|
else {
|
|
389
386
|
return Vec::new();
|
|
@@ -5,8 +5,8 @@ use tree_sitter::Node;
|
|
|
5
5
|
use crate::diagnostic::{Edit, Offense};
|
|
6
6
|
use crate::rules::RuleContext;
|
|
7
7
|
use crate::rules::node_ext::NodeExt;
|
|
8
|
-
use crate::rules::send_node::named_children;
|
|
9
8
|
use crate::rules::support;
|
|
9
|
+
use crate::rules::send_node::named_children_of;
|
|
10
10
|
|
|
11
11
|
const MSG: &str = "Use empty line after multiline condition.";
|
|
12
12
|
|
|
@@ -98,11 +98,11 @@ fn block_delimiters(node: Node<'_>) -> Option<Range<usize>> {
|
|
|
98
98
|
/// `on_case`: each `when` whose own list of conditions spans more than one line.
|
|
99
99
|
fn when_branches(node: Node<'_>, context: &RuleContext<'_>) -> Vec<Offense> {
|
|
100
100
|
let mut offenses = Vec::new();
|
|
101
|
-
for branch in
|
|
101
|
+
for branch in named_children_of(node, context) {
|
|
102
102
|
if branch.kind_str() != "when" {
|
|
103
103
|
continue;
|
|
104
104
|
}
|
|
105
|
-
let conditions: Vec<Node<'_>> =
|
|
105
|
+
let conditions: Vec<Node<'_>> = named_children_of(branch, context)
|
|
106
106
|
.into_iter()
|
|
107
107
|
.filter(|child| child.kind_str() == "pattern")
|
|
108
108
|
.collect();
|
|
@@ -123,7 +123,7 @@ fn when_branches(node: Node<'_>, context: &RuleContext<'_>) -> Vec<Offense> {
|
|
|
123
123
|
|
|
124
124
|
/// `on_rescue`: each `resbody` that names more than one exception across more than one line.
|
|
125
125
|
fn rescue_branch(node: Node<'_>, context: &RuleContext<'_>) -> Option<Offense> {
|
|
126
|
-
let exceptions =
|
|
126
|
+
let exceptions = named_children_of(node.field("exceptions")?, context);
|
|
127
127
|
// `multiline_rescue_exceptions?`: one exception is never enough.
|
|
128
128
|
if exceptions.len() <= 1 {
|
|
129
129
|
return None;
|
|
@@ -170,7 +170,7 @@ fn next_statement<'tree>(
|
|
|
170
170
|
if !CONTAINERS.contains(&parent.kind_str()) {
|
|
171
171
|
return None;
|
|
172
172
|
}
|
|
173
|
-
let siblings: Vec<Node<'_>> =
|
|
173
|
+
let siblings: Vec<Node<'_>> = named_children_of(parent, context)
|
|
174
174
|
.into_iter()
|
|
175
175
|
.filter(|child| child.kind_str() != "comment")
|
|
176
176
|
.collect();
|
|
@@ -23,7 +23,7 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
|
23
23
|
// RuboCop keeps the enclosing class and block on instance variables that its callbacks fill in
|
|
24
24
|
// as the walk reaches them, so what a modifier sees is whatever was visited last -- never
|
|
25
25
|
// unwound on the way back out. A single pre-order pass reproduces that.
|
|
26
|
-
walk_named(context.root_node(), &mut |node| match node.kind_str() {
|
|
26
|
+
walk_named(context.root_node(), context, &mut |node| match node.kind_str() {
|
|
27
27
|
"class" => {
|
|
28
28
|
let header = node
|
|
29
29
|
.field("superclass")
|
|
@@ -270,8 +270,7 @@ fn enclosing_body<'tree>(node: Node<'tree>) -> Option<Body<'tree>> {
|
|
|
270
270
|
return None;
|
|
271
271
|
}
|
|
272
272
|
let mut cursor = container.walk();
|
|
273
|
-
let statements: Vec<Node<'tree>> = container
|
|
274
|
-
.named_children(&mut cursor)
|
|
273
|
+
let statements: Vec<Node<'tree>> = container.named_children(&mut cursor)
|
|
275
274
|
.filter(|child| !matches!(child.kind_str(), "rescue" | "ensure" | "else"))
|
|
276
275
|
.collect();
|
|
277
276
|
let wrapped_in_begin = statements.len() > 1;
|
|
@@ -84,7 +84,7 @@ fn send_view(context: &RuleContext<'_>, node: Node<'_>) -> Option<SendView> {
|
|
|
84
84
|
"call" => {
|
|
85
85
|
// An attribute write is one `:name=` send spanning the assignment, so the call on its
|
|
86
86
|
// own is not what upstream inspects.
|
|
87
|
-
if is_assignment_target(node) {
|
|
87
|
+
if is_assignment_target(node, context) {
|
|
88
88
|
return None;
|
|
89
89
|
}
|
|
90
90
|
let list = child_of_kind(node, "argument_list");
|
|
@@ -100,7 +100,7 @@ fn send_view(context: &RuleContext<'_>, node: Node<'_>) -> Option<SendView> {
|
|
|
100
100
|
})
|
|
101
101
|
}
|
|
102
102
|
"element_reference" => {
|
|
103
|
-
if is_assignment_target(node) {
|
|
103
|
+
if is_assignment_target(node, context) {
|
|
104
104
|
return None;
|
|
105
105
|
}
|
|
106
106
|
let bracket = child_of_kind(node, "[")?;
|
|
@@ -161,8 +161,8 @@ fn selector<'tree>(node: Node<'tree>) -> Option<Node<'tree>> {
|
|
|
161
161
|
.filter(|method| !method.byte_range().is_empty())
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
fn is_assignment_target(node: Node<'_>) -> bool {
|
|
165
|
-
|
|
164
|
+
fn is_assignment_target(node: Node<'_>, context: &RuleContext<'_>) -> bool {
|
|
165
|
+
context.parent(node).is_some_and(|parent| {
|
|
166
166
|
parent.kind_str() == "assignment" && parent.field("left") == Some(node)
|
|
167
167
|
})
|
|
168
168
|
}
|
|
@@ -98,8 +98,7 @@ fn body_clauses<'tree>(node: Node<'tree>) -> Vec<Node<'tree>> {
|
|
|
98
98
|
},
|
|
99
99
|
};
|
|
100
100
|
let mut cursor = container.walk();
|
|
101
|
-
container
|
|
102
|
-
.named_children(&mut cursor)
|
|
101
|
+
container.named_children(&mut cursor)
|
|
103
102
|
.filter(|child| matches!(child.kind_str(), "rescue" | "else" | "ensure"))
|
|
104
103
|
.collect()
|
|
105
104
|
}
|
|
@@ -6,6 +6,7 @@ use super::empty_lines_around_body::{Target, body_container, body_of, check as c
|
|
|
6
6
|
use crate::diagnostic::{Edit, Offense};
|
|
7
7
|
use crate::rules::RuleContext;
|
|
8
8
|
use crate::rules::node_ext::NodeExt;
|
|
9
|
+
use crate::rules::send_node::all_children_iter;
|
|
9
10
|
|
|
10
11
|
pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
11
12
|
let mut targets = Vec::new();
|
|
@@ -45,8 +46,8 @@ fn check_endless(context: &RuleContext<'_>, node: Node<'_>, offenses: &mut Vec<O
|
|
|
45
46
|
let Some(body) = node.field("body") else {
|
|
46
47
|
return;
|
|
47
48
|
};
|
|
48
|
-
let
|
|
49
|
-
let Some(assignment) = node
|
|
49
|
+
let _cursor = node.walk();
|
|
50
|
+
let Some(assignment) = all_children_iter(node, context).find(|child| child.kind_str() == "=") else {
|
|
50
51
|
return;
|
|
51
52
|
};
|
|
52
53
|
let assignment_line = assignment.start_position().row + 1;
|
|
@@ -11,7 +11,7 @@ use super::support::{
|
|
|
11
11
|
};
|
|
12
12
|
use crate::diagnostic::Offense;
|
|
13
13
|
use crate::rules::node_ext::NodeExt;
|
|
14
|
-
use crate::rules::{RuleContext,
|
|
14
|
+
use crate::rules::{RuleContext, push_named_children_in};
|
|
15
15
|
|
|
16
16
|
/// `EnforcedStyleAlignWith`.
|
|
17
17
|
#[derive(Clone, Copy, Eq, PartialEq)]
|
|
@@ -42,7 +42,7 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
|
42
42
|
let mut stack = vec![context.root_node()];
|
|
43
43
|
while let Some(node) = stack.pop() {
|
|
44
44
|
checker.visit(node, offenses);
|
|
45
|
-
|
|
45
|
+
push_named_children_in(node, context, &mut stack);
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
|
|
@@ -19,6 +19,7 @@ use super::tokens::{Token, tokens};
|
|
|
19
19
|
use crate::diagnostic::{Edit, Offense};
|
|
20
20
|
use crate::rules::RuleContext;
|
|
21
21
|
use crate::rules::node_ext::NodeExt;
|
|
22
|
+
use crate::rules::send_node::named_children_of;
|
|
22
23
|
|
|
23
24
|
const MSG_UNNECESSARY: &str = "Unnecessary spacing detected.";
|
|
24
25
|
const MSG_UNALIGNED_ASGN: &str = "`=` is not aligned with the preceding assignment.";
|
|
@@ -246,7 +247,7 @@ fn aligned_comment_lines(context: &RuleContext<'_>) -> HashSet<usize> {
|
|
|
246
247
|
fn ignored_ranges(context: &RuleContext<'_>) -> Vec<Range<usize>> {
|
|
247
248
|
let mut ranges = Vec::new();
|
|
248
249
|
for elements in hash_literals(context) {
|
|
249
|
-
let Some(span) = hash_span(&elements) else {
|
|
250
|
+
let Some(span) = hash_span(&elements, context) else {
|
|
250
251
|
continue;
|
|
251
252
|
};
|
|
252
253
|
if context.source.line_column(span.start).0 == context.source.line_column(span.end).0 {
|
|
@@ -265,10 +266,10 @@ fn ignored_ranges(context: &RuleContext<'_>) -> Vec<Range<usize>> {
|
|
|
265
266
|
/// Where the `hash` node upstream builds for these elements begins and ends. A braced literal is a
|
|
266
267
|
/// node of its own, whose braces count towards `single_line?`; a brace-less one is only the run of
|
|
267
268
|
/// pairs the parser folded together.
|
|
268
|
-
fn hash_span(elements: &[Node<'_>]) -> Option<Range<usize>> {
|
|
269
|
+
fn hash_span(elements: &[Node<'_>], context: &RuleContext<'_>) -> Option<Range<usize>> {
|
|
269
270
|
let first = elements.first()?;
|
|
270
271
|
let last = elements.last()?;
|
|
271
|
-
match
|
|
272
|
+
match context.parent(*first).filter(|parent| parent.kind_str() == "hash") {
|
|
272
273
|
Some(hash) => Some(hash.byte_range()),
|
|
273
274
|
None => Some(first.start_byte()..last.end_byte()),
|
|
274
275
|
}
|
|
@@ -287,8 +288,8 @@ fn previous_character(text: &str, offset: usize) -> Option<usize> {
|
|
|
287
288
|
/// nothing but comments.
|
|
288
289
|
fn is_blank(context: &RuleContext<'_>) -> bool {
|
|
289
290
|
let root = context.root_node();
|
|
290
|
-
let
|
|
291
|
-
!root
|
|
292
|
-
.
|
|
291
|
+
let _cursor = root.walk();
|
|
292
|
+
!named_children_of(root, context)
|
|
293
|
+
.into_iter()
|
|
293
294
|
.any(|child| child.kind_str() != "comment")
|
|
294
295
|
}
|
|
@@ -100,8 +100,7 @@ fn inspect(
|
|
|
100
100
|
/// first element spans the whole run rather than just its first pair.
|
|
101
101
|
fn first_element<'tree>(array: Node<'tree>) -> Option<(Range<usize>, Option<Node<'tree>>)> {
|
|
102
102
|
let mut cursor = array.walk();
|
|
103
|
-
let children: Vec<Node<'tree>> = array
|
|
104
|
-
.named_children(&mut cursor)
|
|
103
|
+
let children: Vec<Node<'tree>> = array.named_children(&mut cursor)
|
|
105
104
|
.filter(|child| !matches!(child.kind_str(), "comment" | "heredoc_body"))
|
|
106
105
|
.collect();
|
|
107
106
|
let first = *children.first()?;
|
|
@@ -11,6 +11,8 @@ use super::support::{
|
|
|
11
11
|
use crate::diagnostic::Offense;
|
|
12
12
|
use crate::rules::RuleContext;
|
|
13
13
|
use crate::rules::node_ext::NodeExt;
|
|
14
|
+
use crate::rules::send_node::named_children_of;
|
|
15
|
+
use crate::rules::send_node::all_children_of;
|
|
14
16
|
|
|
15
17
|
pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
16
18
|
let style: String = context
|
|
@@ -93,9 +95,9 @@ fn first_pair<'tree>(hash: Node<'tree>) -> Option<Node<'tree>> {
|
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
fn separator_style(context: &RuleContext<'_>, first: Node<'_>) -> bool {
|
|
96
|
-
let
|
|
97
|
-
let rocket = first
|
|
98
|
-
.
|
|
98
|
+
let _cursor = first.walk();
|
|
99
|
+
let rocket = all_children_of(first, context)
|
|
100
|
+
.into_iter()
|
|
99
101
|
.any(|child| child.kind_str() == "=>");
|
|
100
102
|
let key = if rocket {
|
|
101
103
|
"EnforcedHashRocketStyle"
|
|
@@ -109,9 +111,9 @@ fn separator_style(context: &RuleContext<'_>, first: Node<'_>) -> bool {
|
|
|
109
111
|
}
|
|
110
112
|
|
|
111
113
|
fn longest_key_overhang(context: &RuleContext<'_>, hash: Node<'_>) -> i64 {
|
|
112
|
-
let
|
|
113
|
-
let lengths: Vec<i64> = hash
|
|
114
|
-
.
|
|
114
|
+
let _cursor = hash.walk();
|
|
115
|
+
let lengths: Vec<i64> = named_children_of(hash, context)
|
|
116
|
+
.into_iter()
|
|
115
117
|
.filter(|child| child.kind_str() == "pair")
|
|
116
118
|
.filter_map(|pair| pair.field("key"))
|
|
117
119
|
.map(|key| context.source.text()[key.byte_range()].chars().count() as i64)
|
|
@@ -9,6 +9,7 @@ use super::support::{Edits, begins_its_line, hash_literals};
|
|
|
9
9
|
use crate::diagnostic::{Edit, Offense};
|
|
10
10
|
use crate::rules::RuleContext;
|
|
11
11
|
use crate::rules::node_ext::NodeExt;
|
|
12
|
+
use crate::rules::send_node::named_children_iter;
|
|
12
13
|
|
|
13
14
|
const KEY_MESSAGE: &str = "Align the keys of a hash literal if they span more than one line.";
|
|
14
15
|
const SEPARATOR_MESSAGE: &str =
|
|
@@ -648,10 +649,9 @@ fn ignored_last_argument(elements: &[Node<'_>], context: &RuleContext<'_>, style
|
|
|
648
649
|
let is_last_argument = match list.kind_str() {
|
|
649
650
|
// `on_send`, `on_csend`, `on_super` and `on_yield`: an array literal is none of them.
|
|
650
651
|
"argument_list" | "element_reference" => {
|
|
651
|
-
let
|
|
652
|
-
list
|
|
653
|
-
.
|
|
654
|
-
.last()
|
|
652
|
+
let _cursor = list.walk();
|
|
653
|
+
named_children_iter(list, context)
|
|
654
|
+
.rfind(|child| !matches!(child.kind_str(), "comment" | "heredoc_body"))
|
|
655
655
|
.is_some_and(|node| node.id() == wanted.id())
|
|
656
656
|
}
|
|
657
657
|
// `x.foo = { … }` and `x[k] = { … }` are `send :foo=` and `send :[]=` to upstream's
|