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
|
@@ -2,8 +2,8 @@ use tree_sitter::Node;
|
|
|
2
2
|
|
|
3
3
|
use crate::diagnostic::Offense;
|
|
4
4
|
use crate::rules::RuleContext;
|
|
5
|
-
use crate::rules::send_node::named_children;
|
|
6
5
|
use crate::rules::node_ext::NodeExt;
|
|
6
|
+
use crate::rules::send_node::named_children_of;
|
|
7
7
|
|
|
8
8
|
/// `SCOPE_CHANGING_METHODS`: a block handed to one of these gives the `return` a scope of its own.
|
|
9
9
|
const SCOPE_CHANGING_METHODS: [&str; 3] = ["lambda", "define_method", "define_singleton_method"];
|
|
@@ -14,7 +14,7 @@ const COMPARISON_METHODS: [&str; 5] = ["==", "===", "!=", "<=", ">="];
|
|
|
14
14
|
pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
15
15
|
for node in context.nodes_of("return") {
|
|
16
16
|
// `return_node.descendants.any?`: a bare `return` hands back nothing to discard.
|
|
17
|
-
if
|
|
17
|
+
if named_children_of(node, context).is_empty() {
|
|
18
18
|
continue;
|
|
19
19
|
}
|
|
20
20
|
let Some(keyword) = node.child(0).filter(|child| child.kind_str() == "return") else {
|
|
@@ -5,11 +5,12 @@ use tree_sitter::Node;
|
|
|
5
5
|
use crate::diagnostic::{Edit, Offense};
|
|
6
6
|
use crate::ruby_version::RubyVersion;
|
|
7
7
|
use crate::rules::RuleContext;
|
|
8
|
-
use crate::rules::send_node::{arguments, is_plain_send
|
|
8
|
+
use crate::rules::send_node::{arguments, is_plain_send};
|
|
9
9
|
|
|
10
10
|
use super::nil_methods::nil_methods;
|
|
11
11
|
use super::node_equality;
|
|
12
12
|
use crate::rules::node_ext::NodeExt;
|
|
13
|
+
use crate::rules::send_node::named_children_of;
|
|
13
14
|
|
|
14
15
|
const MSG: &str = "Do not chain ordinary method call after safe navigation operator.";
|
|
15
16
|
|
|
@@ -129,7 +130,7 @@ fn read_chain<'tree>(node: Node<'tree>, context: &'tree RuleContext<'_>) -> Opti
|
|
|
129
130
|
(node.field("operand")?, method, None, Vec::new())
|
|
130
131
|
}
|
|
131
132
|
_ => {
|
|
132
|
-
let children =
|
|
133
|
+
let children = named_children_of(node, context);
|
|
133
134
|
(
|
|
134
135
|
*children.first()?,
|
|
135
136
|
"[]".to_owned(),
|
|
@@ -7,6 +7,7 @@ use crate::rules::send_node::{arguments, named_children, send_range};
|
|
|
7
7
|
use super::locals::LocalVariables;
|
|
8
8
|
use super::node_equality::identical;
|
|
9
9
|
use crate::rules::node_ext::NodeExt;
|
|
10
|
+
use crate::rules::send_node::named_children_of;
|
|
10
11
|
|
|
11
12
|
const MSG: &str = "Self-assignment detected.";
|
|
12
13
|
|
|
@@ -224,10 +225,10 @@ fn multiple_self_assignment(left: Node<'_>, right: Node<'_>, context: &RuleConte
|
|
|
224
225
|
// `rhs.array_type?`. `a, b = c` hands over one value rather than a list, and `a, b = *c` builds
|
|
225
226
|
// an array holding a `splat`, which is no variable read.
|
|
226
227
|
let values = match right.kind_str() {
|
|
227
|
-
"right_assignment_list" | "array" =>
|
|
228
|
+
"right_assignment_list" | "array" => named_children_of(right, context),
|
|
228
229
|
_ => return false,
|
|
229
230
|
};
|
|
230
|
-
let targets =
|
|
231
|
+
let targets = named_children_of(left, context);
|
|
231
232
|
targets.len() == values.len()
|
|
232
233
|
&& targets.iter().zip(&values).all(|(target, value)| {
|
|
233
234
|
VARIABLE_KINDS.contains(&target.kind_str())
|
|
@@ -2,10 +2,10 @@ use tree_sitter::Node;
|
|
|
2
2
|
|
|
3
3
|
use crate::diagnostic::Offense;
|
|
4
4
|
use crate::rules::RuleContext;
|
|
5
|
-
use crate::rules::send_node::named_children;
|
|
6
5
|
|
|
7
6
|
use super::variable_force::{Analysis, Assignment, Declaration, Scope, Variable};
|
|
8
7
|
use crate::rules::node_ext::NodeExt;
|
|
8
|
+
use crate::rules::send_node::named_children_of;
|
|
9
9
|
|
|
10
10
|
/// The scope kinds `method_argument?` and `block_argument?` accept: a `def`, a `defs`, and the
|
|
11
11
|
/// `block` a literal lambda is one of.
|
|
@@ -172,7 +172,7 @@ fn uses_variable(
|
|
|
172
172
|
{
|
|
173
173
|
return true;
|
|
174
174
|
}
|
|
175
|
-
|
|
175
|
+
named_children_of(node, context)
|
|
176
176
|
.into_iter()
|
|
177
177
|
.any(|child| uses_variable(child, name, analysis, context))
|
|
178
178
|
}
|
|
@@ -5,11 +5,11 @@ use tree_sitter::Node;
|
|
|
5
5
|
|
|
6
6
|
use crate::diagnostic::Offense;
|
|
7
7
|
use crate::rules::RuleContext;
|
|
8
|
-
use crate::rules::send_node::named_children;
|
|
9
8
|
|
|
10
9
|
use super::exception_hierarchy::{compare, is_exception, is_system_call_error, resolve};
|
|
11
10
|
use super::rescue_clause;
|
|
12
11
|
use crate::rules::node_ext::NodeExt;
|
|
12
|
+
use crate::rules::send_node::named_children_of;
|
|
13
13
|
|
|
14
14
|
const MSG: &str = "Do not shadow rescued Exceptions.";
|
|
15
15
|
|
|
@@ -60,7 +60,7 @@ fn evaluate_exceptions(clause: Node<'_>, context: &RuleContext<'_>) -> Group {
|
|
|
60
60
|
let Some(list) = clause.field("exceptions") else {
|
|
61
61
|
return vec![resolve("StandardError")];
|
|
62
62
|
};
|
|
63
|
-
let listed: Vec<Node<'_>> =
|
|
63
|
+
let listed: Vec<Node<'_>> = named_children_of(list, context);
|
|
64
64
|
if listed.is_empty() {
|
|
65
65
|
return vec![resolve("StandardError")];
|
|
66
66
|
}
|
|
@@ -4,9 +4,10 @@ use crate::diagnostic::{Edit, Offense};
|
|
|
4
4
|
use crate::ruby_version::RubyVersion;
|
|
5
5
|
use crate::rules::RuleContext;
|
|
6
6
|
use crate::rules::node_ext::NodeExt;
|
|
7
|
-
use crate::rules::send_node::{arguments,
|
|
7
|
+
use crate::rules::send_node::{arguments, pair_key_symbol, top_level_constant};
|
|
8
8
|
|
|
9
9
|
use super::statements::statements;
|
|
10
|
+
use crate::rules::send_node::named_children_of;
|
|
10
11
|
|
|
11
12
|
/// `EXPECTED_EXCEPTION_CLASSES`: the two the conversion itself raises.
|
|
12
13
|
const EXPECTED_EXCEPTION_CLASSES: [&str; 4] = [
|
|
@@ -32,7 +33,7 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
|
32
33
|
}
|
|
33
34
|
// `begin Integer(x) rescue [classes]; [nil] end`, which the parser keeps as a `kwbegin`.
|
|
34
35
|
for node in context.nodes_of("begin") {
|
|
35
|
-
let children =
|
|
36
|
+
let children = named_children_of(node, context);
|
|
36
37
|
let [body, clause] = children.as_slice() else {
|
|
37
38
|
continue;
|
|
38
39
|
};
|
|
@@ -135,7 +136,7 @@ fn expected_exception_classes_only(clause: Node<'_>, context: &RuleContext<'_>)
|
|
|
135
136
|
let Some(exceptions) = clause.field("exceptions") else {
|
|
136
137
|
return true;
|
|
137
138
|
};
|
|
138
|
-
|
|
139
|
+
named_children_of(exceptions, context)
|
|
139
140
|
.into_iter()
|
|
140
141
|
.filter(|child| child.kind_str() != "comment")
|
|
141
142
|
.all(|exception| EXPECTED_EXCEPTION_CLASSES.contains(&context.source.node_text(exception)))
|
|
@@ -3,7 +3,8 @@ 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::send_node::{has_interpolation,
|
|
6
|
+
use crate::rules::send_node::{has_interpolation, string_text, symbol_name};
|
|
7
|
+
use crate::rules::send_node::named_children_of;
|
|
7
8
|
|
|
8
9
|
pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
9
10
|
let consistent = context
|
|
@@ -24,7 +25,7 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
|
24
25
|
// pairs directly under the argument list. `on_hash` therefore has a second structural
|
|
25
26
|
// spelling here even though no braces were written.
|
|
26
27
|
for list in context.nodes_of("argument_list") {
|
|
27
|
-
let keys: Vec<Node<'_>> =
|
|
28
|
+
let keys: Vec<Node<'_>> = named_children_of(list, context)
|
|
28
29
|
.into_iter()
|
|
29
30
|
.filter(|child| child.kind_str() == "pair")
|
|
30
31
|
.filter_map(|pair| pair.field("key"))
|
|
@@ -76,8 +77,8 @@ fn conversion_correction(receiver: Node<'_>, context: &RuleContext<'_>) -> Optio
|
|
|
76
77
|
// was written and strips the quotes around every part.
|
|
77
78
|
"chained_string" => {
|
|
78
79
|
let mut out = String::from(":\"");
|
|
79
|
-
for part in
|
|
80
|
-
for inner in
|
|
80
|
+
for part in named_children_of(receiver, context) {
|
|
81
|
+
for inner in named_children_of(part, context) {
|
|
81
82
|
out.push_str(context.source.node_text(inner));
|
|
82
83
|
}
|
|
83
84
|
}
|
|
@@ -181,7 +182,7 @@ fn inconsistent_keys(
|
|
|
181
182
|
hash: Node<'_>,
|
|
182
183
|
ignored: &mut Vec<usize>,
|
|
183
184
|
) {
|
|
184
|
-
let keys: Vec<Node<'_>> =
|
|
185
|
+
let keys: Vec<Node<'_>> = named_children_of(hash, context)
|
|
185
186
|
.into_iter()
|
|
186
187
|
.filter(|child| child.kind_str() == "pair")
|
|
187
188
|
.filter_map(|pair| pair.field("key"))
|
data/src/rules/lint/syntax.rs
CHANGED
|
@@ -6,6 +6,7 @@ use crate::diagnostic::Offense;
|
|
|
6
6
|
use crate::ruby_version::RubyVersion;
|
|
7
7
|
use crate::rules::RuleContext;
|
|
8
8
|
use crate::rules::node_ext::NodeExt;
|
|
9
|
+
use crate::rules::send_node::named_children_of;
|
|
9
10
|
|
|
10
11
|
/// The first Ruby version whose grammar accepts each construct.
|
|
11
12
|
///
|
|
@@ -170,9 +171,9 @@ fn multiline_array_pattern(error: Node<'_>, context: &RuleContext<'_>) -> bool {
|
|
|
170
171
|
/// the body where the interpolation still is, and never finds the terminator.
|
|
171
172
|
fn opens_heredoc_in_interpolation(context: &RuleContext<'_>) -> bool {
|
|
172
173
|
context.nodes_of("interpolation").any(|interpolation| {
|
|
173
|
-
let
|
|
174
|
-
interpolation
|
|
175
|
-
.
|
|
174
|
+
let _cursor = interpolation.walk();
|
|
175
|
+
named_children_of(interpolation, context)
|
|
176
|
+
.into_iter()
|
|
176
177
|
.any(|child| child.kind_str() == "heredoc_beginning")
|
|
177
178
|
})
|
|
178
179
|
}
|
|
@@ -3,13 +3,14 @@ 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::send_node::named_children_iter;
|
|
6
7
|
|
|
7
8
|
pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
8
9
|
// `on_dstr`: the only `dstr` written as one literal per quote is the run of adjacent literals
|
|
9
10
|
// the grammar keeps as a `chained_string`.
|
|
10
11
|
for node in context.nodes_of("chained_string") {
|
|
11
|
-
let
|
|
12
|
-
let children: Vec<Node<'_>> = node
|
|
12
|
+
let _cursor = node.walk();
|
|
13
|
+
let children: Vec<Node<'_>> = named_children_iter(node, context).collect();
|
|
13
14
|
let mut empty: Vec<Node<'_>> = children
|
|
14
15
|
.iter()
|
|
15
16
|
.copied()
|
|
@@ -128,7 +128,7 @@ fn holds_interpolation(node: Node<'_>, context: &RuleContext<'_>) -> bool {
|
|
|
128
128
|
if interpolates && current.id() != node.id() {
|
|
129
129
|
return true;
|
|
130
130
|
}
|
|
131
|
-
crate::rules::
|
|
131
|
+
crate::rules::push_named_children_in(current, context, &mut stack);
|
|
132
132
|
}
|
|
133
133
|
false
|
|
134
134
|
}
|
|
@@ -8,6 +8,7 @@ use crate::rules::node_ext::NodeExt;
|
|
|
8
8
|
|
|
9
9
|
use super::blocks::BlockArgs;
|
|
10
10
|
use super::locals::LocalVariables;
|
|
11
|
+
use crate::rules::send_node::all_children_iter;
|
|
11
12
|
|
|
12
13
|
pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
13
14
|
let Some(methods) = context.setting::<BTreeMap<String, usize>>("Methods") else {
|
|
@@ -55,8 +56,8 @@ fn arg_count(
|
|
|
55
56
|
});
|
|
56
57
|
};
|
|
57
58
|
let mut count = 0;
|
|
58
|
-
let
|
|
59
|
-
for parameter in parameters
|
|
59
|
+
let _cursor = parameters.walk();
|
|
60
|
+
for parameter in all_children_iter(parameters, context) {
|
|
60
61
|
// `{ |a; b| }`: what follows the `;` is a block-local variable. Upstream's parser never
|
|
61
62
|
// puts it among the arguments; the grammar keeps it in the same node.
|
|
62
63
|
if parameter.kind_str() == ";" {
|
|
@@ -8,6 +8,7 @@ use crate::rules::send_node::{arguments, named_children};
|
|
|
8
8
|
use super::blocks::{BLOCK_KINDS, BlockArgs};
|
|
9
9
|
use super::locals::LocalVariables;
|
|
10
10
|
use super::statements::statements;
|
|
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 locals = LocalVariables::new(context);
|
|
@@ -58,7 +59,7 @@ fn argument_list(parameters: &[Node<'_>], context: &RuleContext<'_>) -> Vec<Stri
|
|
|
58
59
|
let mut names = Vec::new();
|
|
59
60
|
for parameter in parameters {
|
|
60
61
|
if parameter.kind_str() == "destructured_parameter" {
|
|
61
|
-
names.extend(argument_list(&
|
|
62
|
+
names.extend(argument_list(&named_children_of(*parameter, context), context));
|
|
62
63
|
continue;
|
|
63
64
|
}
|
|
64
65
|
let node = parameter.field("name").unwrap_or(*parameter);
|
|
@@ -128,7 +129,7 @@ fn return_values<'tree>(
|
|
|
128
129
|
{
|
|
129
130
|
values.push(argument);
|
|
130
131
|
}
|
|
131
|
-
crate::rules::
|
|
132
|
+
crate::rules::push_named_children_in(node, context, &mut stack);
|
|
132
133
|
}
|
|
133
134
|
values
|
|
134
135
|
}
|
|
@@ -230,7 +231,7 @@ fn lvar_used(node: Node<'_>, name: &str, context: &RuleContext<'_>) -> bool {
|
|
|
230
231
|
}
|
|
231
232
|
// `(dstr (begin (lvar %1)))`: a string holding nothing but the variable.
|
|
232
233
|
"string" => {
|
|
233
|
-
let parts: Vec<Node<'_>> =
|
|
234
|
+
let parts: Vec<Node<'_>> = named_children_of(node, context)
|
|
234
235
|
.into_iter()
|
|
235
236
|
.filter(|child| child.kind_str() != "comment")
|
|
236
237
|
.collect();
|
|
@@ -260,7 +261,7 @@ fn element_modified(body: Node<'_>, element: &str, context: &RuleContext<'_>) ->
|
|
|
260
261
|
if modifies_element(node, element, context) {
|
|
261
262
|
return true;
|
|
262
263
|
}
|
|
263
|
-
crate::rules::
|
|
264
|
+
crate::rules::push_named_children_in(node, context, &mut stack);
|
|
264
265
|
}
|
|
265
266
|
false
|
|
266
267
|
}
|
|
@@ -330,7 +331,7 @@ fn holds_lvar(node: Node<'_>, name: &str, context: &RuleContext<'_>) -> bool {
|
|
|
330
331
|
if is_lvar_named(current, name, context) {
|
|
331
332
|
return true;
|
|
332
333
|
}
|
|
333
|
-
crate::rules::
|
|
334
|
+
crate::rules::push_named_children_in(current, context, &mut stack);
|
|
334
335
|
}
|
|
335
336
|
false
|
|
336
337
|
}
|
|
@@ -377,7 +378,7 @@ fn expression_values(node: Node<'_>, context: &RuleContext<'_>) -> Vec<String> {
|
|
|
377
378
|
let method = (current.kind_str() == "call")
|
|
378
379
|
.then(|| current.field("method"))
|
|
379
380
|
.flatten();
|
|
380
|
-
for child in
|
|
381
|
+
for child in named_children_of(current, context) {
|
|
381
382
|
if method.is_some_and(|method| method.id() == child.id()) {
|
|
382
383
|
continue;
|
|
383
384
|
}
|
|
@@ -4,16 +4,17 @@ use crate::diagnostic::Offense;
|
|
|
4
4
|
use crate::ruby_version::RubyVersion;
|
|
5
5
|
use crate::rules::RuleContext;
|
|
6
6
|
use crate::rules::node_ext::NodeExt;
|
|
7
|
+
use crate::rules::send_node::named_children_iter;
|
|
7
8
|
|
|
8
9
|
pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
9
10
|
if context.target_ruby_version() < RubyVersion::new(2, 7) {
|
|
10
11
|
return;
|
|
11
12
|
}
|
|
12
13
|
for case in context.nodes_of("case_match") {
|
|
13
|
-
let
|
|
14
|
+
let _cursor = case.walk();
|
|
14
15
|
let mut catch_all_found = false;
|
|
15
16
|
let mut else_clause = None;
|
|
16
|
-
for branch in case
|
|
17
|
+
for branch in named_children_iter(case, context) {
|
|
17
18
|
match branch.kind_str() {
|
|
18
19
|
"else" => else_clause = Some(branch),
|
|
19
20
|
"in_clause" => {
|
|
@@ -59,8 +60,7 @@ fn is_catch_all(pattern: Node<'_>) -> bool {
|
|
|
59
60
|
"parenthesized_pattern" => pattern.named_child(0).is_some_and(is_catch_all),
|
|
60
61
|
"alternative_pattern" => {
|
|
61
62
|
let mut cursor = pattern.walk();
|
|
62
|
-
pattern
|
|
63
|
-
.named_children(&mut cursor)
|
|
63
|
+
pattern.named_children(&mut cursor)
|
|
64
64
|
.any(|alternative| is_catch_all(alternative))
|
|
65
65
|
}
|
|
66
66
|
_ => false,
|
|
@@ -68,7 +68,7 @@ fn message(
|
|
|
68
68
|
.filter(|variable| block_argument(variable, scope))
|
|
69
69
|
.collect();
|
|
70
70
|
let none_referenced = !arguments.iter().any(|argument| argument.referenced);
|
|
71
|
-
let augmentation = if is_lambda(scope.node, context.source) {
|
|
71
|
+
let augmentation = if is_lambda(scope.node, context.source, context.ast_index()) {
|
|
72
72
|
let mut message = underscore_message(name);
|
|
73
73
|
if none_referenced {
|
|
74
74
|
message.push_str(
|
|
@@ -77,7 +77,7 @@ fn message(
|
|
|
77
77
|
);
|
|
78
78
|
}
|
|
79
79
|
message
|
|
80
|
-
} else if none_referenced && block_method(scope.node, context.source) != Some("define_method") {
|
|
80
|
+
} else if none_referenced && block_method(scope.node, context.source, context.ast_index()) != Some("define_method") {
|
|
81
81
|
if arguments.len() > 1 {
|
|
82
82
|
"You can omit all the arguments if you don't care about them.".to_owned()
|
|
83
83
|
} else {
|
|
@@ -86,8 +86,7 @@ fn method_body(node: Node<'_>) -> Option<MethodBody<'_>> {
|
|
|
86
86
|
});
|
|
87
87
|
}
|
|
88
88
|
let mut cursor = body.walk();
|
|
89
|
-
let statements: Vec<Node<'_>> = body
|
|
90
|
-
.named_children(&mut cursor)
|
|
89
|
+
let statements: Vec<Node<'_>> = body.named_children(&mut cursor)
|
|
91
90
|
.filter(|child| !NOT_A_STATEMENT.contains(&child.kind_str()))
|
|
92
91
|
.collect();
|
|
93
92
|
match statements.len() {
|
|
@@ -11,6 +11,7 @@ use crate::diagnostic::{Edit, Offense};
|
|
|
11
11
|
use crate::rules::RuleContext;
|
|
12
12
|
use crate::rules::node_ext::NodeExt;
|
|
13
13
|
use crate::rules::support::spurious_assignment_list;
|
|
14
|
+
use crate::rules::send_node::named_children_of;
|
|
14
15
|
|
|
15
16
|
pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
16
17
|
let analysis = context.variable_analysis();
|
|
@@ -143,7 +144,7 @@ fn variable_like_invocation(
|
|
|
143
144
|
match node.kind_str() {
|
|
144
145
|
// A bare name standing where a value is read is a `send` upstream unless it resolved to a
|
|
145
146
|
// local, and a read of a local is an `lvar` that contributes nothing of its own here.
|
|
146
|
-
"identifier" if is_variable_read(node) && !analysis.is_variable_reference(node) => {
|
|
147
|
+
"identifier" if is_variable_read(node, context.ast_index()) && !analysis.is_variable_reference(node) => {
|
|
147
148
|
Some(context.source.node_text(node).to_owned())
|
|
148
149
|
}
|
|
149
150
|
"call" => {
|
|
@@ -354,7 +355,7 @@ fn reads_name(node: Node<'_>, name: &str, context: &RuleContext<'_>) -> bool {
|
|
|
354
355
|
.is_some_and(|method| method.id() == node.id());
|
|
355
356
|
return !target && !method;
|
|
356
357
|
}
|
|
357
|
-
|
|
358
|
+
named_children_of(node, context)
|
|
358
359
|
.into_iter()
|
|
359
360
|
.any(|child| reads_name(child, name, context))
|
|
360
361
|
}
|
|
@@ -3,9 +3,10 @@ use tree_sitter::Node;
|
|
|
3
3
|
use crate::diagnostic::Offense;
|
|
4
4
|
use crate::rules::RuleContext;
|
|
5
5
|
use crate::rules::node_ext::NodeExt;
|
|
6
|
-
use crate::rules::send_node::{arguments,
|
|
6
|
+
use crate::rules::send_node::{arguments, string_text, symbol_name};
|
|
7
7
|
|
|
8
8
|
use super::access_modifier::{bare_access_modifier, send_name};
|
|
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
|
for node in context.nodes_of("assignment") {
|
|
@@ -15,7 +16,7 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
|
15
16
|
let Some(parent) = node.parent_of(context) else {
|
|
16
17
|
continue;
|
|
17
18
|
};
|
|
18
|
-
let siblings =
|
|
19
|
+
let siblings = named_children_of(parent, context);
|
|
19
20
|
let Some(position) = siblings
|
|
20
21
|
.iter()
|
|
21
22
|
.position(|sibling| sibling.id() == node.id())
|
|
@@ -2,6 +2,7 @@ use crate::diagnostic::Offense;
|
|
|
2
2
|
use crate::ruby_version::RubyVersion;
|
|
3
3
|
use crate::rules::RuleContext;
|
|
4
4
|
use crate::rules::node_ext::NodeExt;
|
|
5
|
+
use crate::rules::send_node::named_children_of;
|
|
5
6
|
|
|
6
7
|
const MSG: &str = "`else` without `rescue` is useless.";
|
|
7
8
|
|
|
@@ -24,9 +25,9 @@ pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
|
24
25
|
if !matches!(body.kind_str(), "begin" | "body_statement" | "block_body") {
|
|
25
26
|
continue;
|
|
26
27
|
}
|
|
27
|
-
let
|
|
28
|
-
if body
|
|
29
|
-
.
|
|
28
|
+
let _cursor = body.walk();
|
|
29
|
+
if named_children_of(body, context)
|
|
30
|
+
.into_iter()
|
|
30
31
|
.any(|child| child.kind_str() == "rescue")
|
|
31
32
|
{
|
|
32
33
|
continue;
|
|
@@ -3,9 +3,10 @@ use tree_sitter::Node;
|
|
|
3
3
|
use crate::diagnostic::Offense;
|
|
4
4
|
use crate::rules::RuleContext;
|
|
5
5
|
use crate::rules::node_ext::NodeExt;
|
|
6
|
-
use crate::rules::send_node::
|
|
6
|
+
use crate::rules::send_node::arguments;
|
|
7
7
|
|
|
8
8
|
use super::statements::statements;
|
|
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
|
for node in context.nodes_of("rescue") {
|
|
@@ -23,7 +24,7 @@ fn is_last_branch(node: Node<'_>, context: &RuleContext<'_>) -> bool {
|
|
|
23
24
|
return true;
|
|
24
25
|
};
|
|
25
26
|
let mut seen = false;
|
|
26
|
-
for sibling in
|
|
27
|
+
for sibling in named_children_of(parent, context) {
|
|
27
28
|
if sibling.id() == node.id() {
|
|
28
29
|
seen = true;
|
|
29
30
|
continue;
|
|
@@ -92,7 +93,7 @@ fn uses_exception_variable_in_ensure(
|
|
|
92
93
|
let Some(parent) = node.parent_of(context) else {
|
|
93
94
|
return false;
|
|
94
95
|
};
|
|
95
|
-
let Some(ensure_clause) =
|
|
96
|
+
let Some(ensure_clause) = named_children_of(parent, context)
|
|
96
97
|
.into_iter()
|
|
97
98
|
.find(|child| child.kind_str() == "ensure")
|
|
98
99
|
else {
|
|
@@ -100,7 +101,7 @@ fn uses_exception_variable_in_ensure(
|
|
|
100
101
|
};
|
|
101
102
|
let analysis = context.variable_analysis();
|
|
102
103
|
let mut found = false;
|
|
103
|
-
crate::rules::walk_named(ensure_clause, &mut |inner| {
|
|
104
|
+
crate::rules::walk_named(ensure_clause, context, &mut |inner| {
|
|
104
105
|
if found || inner.kind_str() != "identifier" || context.source.node_text(inner) != variable
|
|
105
106
|
{
|
|
106
107
|
return;
|
|
@@ -4,6 +4,7 @@ use crate::diagnostic::Offense;
|
|
|
4
4
|
use crate::rules::RuleContext;
|
|
5
5
|
use crate::rules::node_ext::NodeExt;
|
|
6
6
|
use crate::rules::send_node::{arguments, named_children, symbol_name};
|
|
7
|
+
use crate::rules::send_node::named_children_of;
|
|
7
8
|
|
|
8
9
|
pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
9
10
|
for node in context.nodes_of("call") {
|
|
@@ -60,7 +61,7 @@ fn find_method_definition<'tree>(
|
|
|
60
61
|
) -> Option<Option<Node<'tree>>> {
|
|
61
62
|
let mut current = node.parent_of(context);
|
|
62
63
|
while let Some(ancestor) = current {
|
|
63
|
-
for child in
|
|
64
|
+
for child in named_children_of(ancestor, context) {
|
|
64
65
|
if let Some(parameters) = definition_parameters(child, name, context) {
|
|
65
66
|
return Some(parameters);
|
|
66
67
|
}
|
|
@@ -4,12 +4,13 @@ use tree_sitter::Node;
|
|
|
4
4
|
|
|
5
5
|
use crate::diagnostic::{Edit, Offense};
|
|
6
6
|
use crate::rules::RuleContext;
|
|
7
|
-
use crate::rules::send_node::named_children;
|
|
8
7
|
|
|
9
8
|
use super::literals::is_literal;
|
|
10
9
|
use super::locals::LocalVariables;
|
|
11
10
|
use super::statements::body_children;
|
|
12
11
|
use crate::rules::node_ext::NodeExt;
|
|
12
|
+
use crate::rules::send_node::named_children_of;
|
|
13
|
+
use crate::rules::send_node::named_children_iter;
|
|
13
14
|
|
|
14
15
|
/// `ASSIGNMENT_TYPES`: the variable kinds the tracker follows. A constant is deliberately missing.
|
|
15
16
|
const ASSIGNMENT_TARGETS: &[&str] = &[
|
|
@@ -106,7 +107,7 @@ impl Tracker {
|
|
|
106
107
|
if self.process_assignment_node(node, context, locals) {
|
|
107
108
|
return;
|
|
108
109
|
}
|
|
109
|
-
for child in
|
|
110
|
+
for child in named_children_of(node, context) {
|
|
110
111
|
self.scan(child, context, locals);
|
|
111
112
|
}
|
|
112
113
|
}
|
|
@@ -168,11 +169,11 @@ impl Tracker {
|
|
|
168
169
|
) {
|
|
169
170
|
let listed = matches!(right.kind_str(), "right_assignment_list" | "array");
|
|
170
171
|
let values = if listed {
|
|
171
|
-
|
|
172
|
+
named_children_of(right, context)
|
|
172
173
|
} else {
|
|
173
174
|
Vec::new()
|
|
174
175
|
};
|
|
175
|
-
for (index, target) in
|
|
176
|
+
for (index, target) in named_children_iter(targets, context).enumerate() {
|
|
176
177
|
if !ASSIGNMENT_TARGETS.contains(&target.kind_str()) {
|
|
177
178
|
continue;
|
|
178
179
|
}
|
|
@@ -9,6 +9,7 @@ use super::locals::LocalVariables;
|
|
|
9
9
|
use super::ranges::whole_lines;
|
|
10
10
|
use super::statements::statements;
|
|
11
11
|
use crate::rules::node_ext::NodeExt;
|
|
12
|
+
use crate::rules::send_node::named_children_of;
|
|
12
13
|
|
|
13
14
|
pub(super) fn check(context: &RuleContext<'_>, offenses: &mut Vec<Offense>) {
|
|
14
15
|
let locals = LocalVariables::new(context);
|
|
@@ -66,7 +67,7 @@ fn block_pass_symbol<'a>(node: Node<'_>, context: &'a RuleContext<'_>) -> Option
|
|
|
66
67
|
if node.kind_str() != "block_argument" {
|
|
67
68
|
return None;
|
|
68
69
|
}
|
|
69
|
-
symbol_name(
|
|
70
|
+
symbol_name(named_children_of(node, context).first().copied()?, context)
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
fn correction(
|
|
@@ -257,7 +258,7 @@ fn reassigns(node: Node<'_>, name: &str, context: &RuleContext<'_>) -> bool {
|
|
|
257
258
|
{
|
|
258
259
|
return true;
|
|
259
260
|
}
|
|
260
|
-
|
|
261
|
+
named_children_of(node, context)
|
|
261
262
|
.into_iter()
|
|
262
263
|
.any(|child| reassigns(child, name, context))
|
|
263
264
|
}
|
|
@@ -268,7 +269,7 @@ fn assigns_to(left: Node<'_>, name: &str, context: &RuleContext<'_>) -> bool {
|
|
|
268
269
|
"identifier" => context.source.node_text(left) == name,
|
|
269
270
|
// `i, j = 1, 2` and `(i, j), k = [1, 2], 3` nest their targets.
|
|
270
271
|
"left_assignment_list" | "destructured_left_assignment" | "rest_assignment" => {
|
|
271
|
-
|
|
272
|
+
named_children_of(left, context)
|
|
272
273
|
.into_iter()
|
|
273
274
|
.any(|target| assigns_to(target, name, context))
|
|
274
275
|
}
|