rubocop 0.82.0 → 0.86.0

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.
Files changed (280) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +27 -19
  3. data/config/default.yml +111 -23
  4. data/lib/rubocop.rb +16 -59
  5. data/lib/rubocop/ast_aliases.rb +8 -0
  6. data/lib/rubocop/cli.rb +3 -3
  7. data/lib/rubocop/cli/command/auto_genenerate_config.rb +2 -2
  8. data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
  9. data/lib/rubocop/cli/command/show_cops.rb +2 -6
  10. data/lib/rubocop/comment_config.rb +1 -1
  11. data/lib/rubocop/config.rb +6 -2
  12. data/lib/rubocop/config_loader.rb +19 -24
  13. data/lib/rubocop/config_loader_resolver.rb +45 -6
  14. data/lib/rubocop/config_store.rb +12 -2
  15. data/lib/rubocop/config_validator.rb +2 -1
  16. data/lib/rubocop/cop/autocorrect_logic.rb +1 -2
  17. data/lib/rubocop/cop/bundler/gem_comment.rb +70 -1
  18. data/lib/rubocop/cop/commissioner.rb +0 -21
  19. data/lib/rubocop/cop/cop.rb +36 -21
  20. data/lib/rubocop/cop/correctors/alignment_corrector.rb +2 -6
  21. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +1 -1
  22. data/lib/rubocop/cop/correctors/space_corrector.rb +1 -3
  23. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -3
  24. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +1 -1
  25. data/lib/rubocop/cop/generator.rb +4 -3
  26. data/lib/rubocop/cop/generator/configuration_injector.rb +1 -1
  27. data/lib/rubocop/cop/ignored_node.rb +1 -3
  28. data/lib/rubocop/cop/layout/case_indentation.rb +3 -3
  29. data/lib/rubocop/cop/layout/class_structure.rb +19 -16
  30. data/lib/rubocop/cop/layout/comment_indentation.rb +3 -3
  31. data/lib/rubocop/cop/layout/condition_position.rb +12 -2
  32. data/lib/rubocop/cop/layout/empty_comment.rb +1 -1
  33. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -6
  34. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +128 -0
  35. data/lib/rubocop/cop/layout/end_of_line.rb +3 -3
  36. data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -4
  37. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +1 -3
  38. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +1 -1
  39. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +1 -3
  40. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  41. data/lib/rubocop/cop/layout/hash_alignment.rb +7 -7
  42. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +3 -7
  43. data/lib/rubocop/cop/layout/heredoc_indentation.rb +20 -103
  44. data/lib/rubocop/cop/layout/indentation_width.rb +1 -3
  45. data/lib/rubocop/cop/layout/line_length.rb +21 -18
  46. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -1
  47. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -3
  48. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +13 -4
  49. data/lib/rubocop/cop/layout/space_after_colon.rb +1 -1
  50. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -2
  51. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -3
  52. data/lib/rubocop/cop/layout/space_around_operators.rb +19 -2
  53. data/lib/rubocop/cop/layout/space_before_block_braces.rb +14 -0
  54. data/lib/rubocop/cop/layout/space_before_comment.rb +1 -3
  55. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +2 -4
  56. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
  57. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -2
  58. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +1 -3
  59. data/lib/rubocop/cop/layout/trailing_whitespace.rb +2 -2
  60. data/lib/rubocop/cop/lint/ambiguous_operator.rb +41 -0
  61. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +14 -0
  62. data/lib/rubocop/cop/lint/constant_resolution.rb +89 -0
  63. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +137 -0
  64. data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -5
  65. data/lib/rubocop/cop/lint/empty_when.rb +29 -6
  66. data/lib/rubocop/cop/lint/ensure_return.rb +19 -2
  67. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -3
  68. data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
  69. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +38 -2
  70. data/lib/rubocop/cop/lint/literal_as_condition.rb +10 -13
  71. data/lib/rubocop/cop/lint/loop.rb +1 -1
  72. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +69 -0
  73. data/lib/rubocop/cop/lint/nested_percent_literal.rb +1 -1
  74. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +7 -7
  75. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +33 -11
  76. data/lib/rubocop/cop/lint/percent_string_array.rb +2 -4
  77. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  78. data/lib/rubocop/cop/lint/raise_exception.rb +12 -4
  79. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +5 -8
  80. data/lib/rubocop/cop/lint/redundant_require_statement.rb +3 -3
  81. data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
  82. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  83. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  84. data/lib/rubocop/cop/lint/suppressed_exception.rb +11 -4
  85. data/lib/rubocop/cop/lint/syntax.rb +1 -3
  86. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  87. data/lib/rubocop/cop/lint/useless_access_modifier.rb +13 -3
  88. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -2
  89. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +6 -1
  90. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  91. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +35 -3
  92. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  93. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +61 -0
  94. data/lib/rubocop/cop/migration/department_name.rb +7 -7
  95. data/lib/rubocop/cop/mixin/alignment.rb +1 -3
  96. data/lib/rubocop/cop/mixin/array_min_size.rb +1 -3
  97. data/lib/rubocop/cop/mixin/check_line_breakable.rb +3 -9
  98. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -3
  99. data/lib/rubocop/cop/mixin/configurable_formatting.rb +2 -4
  100. data/lib/rubocop/cop/mixin/configurable_naming.rb +1 -1
  101. data/lib/rubocop/cop/mixin/documentation_comment.rb +2 -2
  102. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  103. data/lib/rubocop/cop/mixin/first_element_line_break.rb +1 -1
  104. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +10 -1
  105. data/lib/rubocop/cop/mixin/hash_transform_method.rb +8 -1
  106. data/lib/rubocop/cop/mixin/ignored_pattern.rb +1 -1
  107. data/lib/rubocop/cop/mixin/line_length_help.rb +3 -2
  108. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
  109. data/lib/rubocop/cop/mixin/parentheses.rb +1 -2
  110. data/lib/rubocop/cop/mixin/parser_diagnostic.rb +1 -1
  111. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
  112. data/lib/rubocop/cop/mixin/range_help.rb +1 -1
  113. data/lib/rubocop/cop/mixin/regexp_literal_help.rb +43 -0
  114. data/lib/rubocop/cop/mixin/statement_modifier.rb +7 -23
  115. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  116. data/lib/rubocop/cop/mixin/surrounding_space.rb +3 -3
  117. data/lib/rubocop/cop/mixin/target_ruby_version.rb +5 -1
  118. data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -4
  119. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +3 -3
  120. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  121. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +11 -1
  122. data/lib/rubocop/cop/naming/file_name.rb +28 -17
  123. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +1 -1
  124. data/lib/rubocop/cop/naming/method_name.rb +1 -5
  125. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  126. data/lib/rubocop/cop/registry.rb +63 -10
  127. data/lib/rubocop/cop/severity.rb +1 -3
  128. data/lib/rubocop/cop/style/and_or.rb +2 -2
  129. data/lib/rubocop/cop/style/array_join.rb +1 -1
  130. data/lib/rubocop/cop/style/attr.rb +1 -3
  131. data/lib/rubocop/cop/style/bare_percent_literals.rb +2 -2
  132. data/lib/rubocop/cop/style/block_delimiters.rb +4 -12
  133. data/lib/rubocop/cop/style/case_equality.rb +1 -1
  134. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  135. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  136. data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
  137. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -4
  138. data/lib/rubocop/cop/style/copyright.rb +5 -5
  139. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1 -1
  140. data/lib/rubocop/cop/style/documentation.rb +2 -2
  141. data/lib/rubocop/cop/style/double_negation.rb +41 -4
  142. data/lib/rubocop/cop/style/empty_case_condition.rb +8 -6
  143. data/lib/rubocop/cop/style/empty_literal.rb +1 -3
  144. data/lib/rubocop/cop/style/empty_method.rb +1 -5
  145. data/lib/rubocop/cop/style/encoding.rb +1 -1
  146. data/lib/rubocop/cop/style/exponential_notation.rb +5 -5
  147. data/lib/rubocop/cop/style/format_string_token.rb +2 -3
  148. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -6
  149. data/lib/rubocop/cop/style/guard_clause.rb +25 -2
  150. data/lib/rubocop/cop/style/hash_each_methods.rb +1 -1
  151. data/lib/rubocop/cop/style/hash_syntax.rb +16 -7
  152. data/lib/rubocop/cop/style/identical_conditional_branches.rb +1 -1
  153. data/lib/rubocop/cop/style/if_inside_else.rb +1 -1
  154. data/lib/rubocop/cop/style/if_with_semicolon.rb +16 -0
  155. data/lib/rubocop/cop/style/inline_comment.rb +1 -1
  156. data/lib/rubocop/cop/style/inverse_methods.rb +1 -1
  157. data/lib/rubocop/cop/style/ip_addresses.rb +1 -1
  158. data/lib/rubocop/cop/style/lambda_call.rb +0 -20
  159. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +1 -3
  160. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +1 -3
  161. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -1
  162. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  163. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +17 -6
  164. data/lib/rubocop/cop/style/multiline_when_then.rb +16 -1
  165. data/lib/rubocop/cop/style/negated_if.rb +3 -3
  166. data/lib/rubocop/cop/style/negated_unless.rb +3 -3
  167. data/lib/rubocop/cop/style/nested_ternary_operator.rb +27 -0
  168. data/lib/rubocop/cop/style/next.rb +2 -2
  169. data/lib/rubocop/cop/style/non_nil_check.rb +1 -1
  170. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +2 -2
  171. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -6
  172. data/lib/rubocop/cop/style/optional_arguments.rb +1 -1
  173. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  174. data/lib/rubocop/cop/style/redundant_conditional.rb +4 -3
  175. data/lib/rubocop/cop/style/redundant_fetch_block.rb +103 -0
  176. data/lib/rubocop/cop/style/redundant_parentheses.rb +3 -7
  177. data/lib/rubocop/cop/style/redundant_percent_q.rb +3 -3
  178. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +89 -0
  179. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +121 -0
  180. data/lib/rubocop/cop/style/redundant_self.rb +6 -9
  181. data/lib/rubocop/cop/style/safe_navigation.rb +2 -6
  182. data/lib/rubocop/cop/style/sample.rb +1 -1
  183. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  184. data/lib/rubocop/cop/style/slicing_with_range.rb +39 -0
  185. data/lib/rubocop/cop/style/special_global_vars.rb +2 -6
  186. data/lib/rubocop/cop/style/struct_inheritance.rb +21 -0
  187. data/lib/rubocop/cop/style/symbol_array.rb +5 -5
  188. data/lib/rubocop/cop/style/ternary_parentheses.rb +2 -4
  189. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +3 -3
  190. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +3 -3
  191. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +13 -13
  192. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +3 -3
  193. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -3
  194. data/lib/rubocop/cop/style/unless_else.rb +1 -1
  195. data/lib/rubocop/cop/style/when_then.rb +1 -1
  196. data/lib/rubocop/cop/style/word_array.rb +1 -1
  197. data/lib/rubocop/cop/style/yoda_condition.rb +18 -1
  198. data/lib/rubocop/cop/team.rb +69 -25
  199. data/lib/rubocop/cop/util.rb +27 -3
  200. data/lib/rubocop/cop/utils/format_string.rb +18 -0
  201. data/lib/rubocop/cop/variable_force.rb +3 -9
  202. data/lib/rubocop/cop/variable_force/assignment.rb +1 -0
  203. data/lib/rubocop/cop/variable_force/branch.rb +1 -3
  204. data/lib/rubocop/cop/variable_force/scope.rb +1 -0
  205. data/lib/rubocop/cop/variable_force/variable.rb +3 -6
  206. data/lib/rubocop/ext/processed_source.rb +18 -0
  207. data/lib/rubocop/formatter/base_formatter.rb +0 -4
  208. data/lib/rubocop/formatter/disabled_config_formatter.rb +5 -13
  209. data/lib/rubocop/formatter/formatter_set.rb +2 -4
  210. data/lib/rubocop/formatter/junit_formatter.rb +14 -4
  211. data/lib/rubocop/magic_comment.rb +1 -1
  212. data/lib/rubocop/name_similarity.rb +18 -9
  213. data/lib/rubocop/options.rb +26 -11
  214. data/lib/rubocop/path_util.rb +2 -2
  215. data/lib/rubocop/platform.rb +1 -1
  216. data/lib/rubocop/remote_config.rb +1 -3
  217. data/lib/rubocop/result_cache.rb +5 -7
  218. data/lib/rubocop/rspec/cop_helper.rb +2 -25
  219. data/lib/rubocop/rspec/expect_offense.rb +58 -15
  220. data/lib/rubocop/rspec/shared_contexts.rb +54 -16
  221. data/lib/rubocop/runner.rb +20 -13
  222. data/lib/rubocop/target_finder.rb +8 -8
  223. data/lib/rubocop/target_ruby.rb +4 -1
  224. data/lib/rubocop/version.rb +5 -3
  225. metadata +51 -74
  226. data/lib/rubocop/ast/builder.rb +0 -85
  227. data/lib/rubocop/ast/node.rb +0 -637
  228. data/lib/rubocop/ast/node/alias_node.rb +0 -24
  229. data/lib/rubocop/ast/node/and_node.rb +0 -29
  230. data/lib/rubocop/ast/node/args_node.rb +0 -29
  231. data/lib/rubocop/ast/node/array_node.rb +0 -70
  232. data/lib/rubocop/ast/node/block_node.rb +0 -121
  233. data/lib/rubocop/ast/node/break_node.rb +0 -17
  234. data/lib/rubocop/ast/node/case_match_node.rb +0 -56
  235. data/lib/rubocop/ast/node/case_node.rb +0 -56
  236. data/lib/rubocop/ast/node/class_node.rb +0 -31
  237. data/lib/rubocop/ast/node/def_node.rb +0 -82
  238. data/lib/rubocop/ast/node/defined_node.rb +0 -17
  239. data/lib/rubocop/ast/node/ensure_node.rb +0 -17
  240. data/lib/rubocop/ast/node/float_node.rb +0 -12
  241. data/lib/rubocop/ast/node/for_node.rb +0 -53
  242. data/lib/rubocop/ast/node/forward_args_node.rb +0 -18
  243. data/lib/rubocop/ast/node/hash_node.rb +0 -109
  244. data/lib/rubocop/ast/node/if_node.rb +0 -175
  245. data/lib/rubocop/ast/node/int_node.rb +0 -12
  246. data/lib/rubocop/ast/node/keyword_splat_node.rb +0 -45
  247. data/lib/rubocop/ast/node/mixin/basic_literal_node.rb +0 -16
  248. data/lib/rubocop/ast/node/mixin/binary_operator_node.rb +0 -43
  249. data/lib/rubocop/ast/node/mixin/collection_node.rb +0 -15
  250. data/lib/rubocop/ast/node/mixin/conditional_node.rb +0 -45
  251. data/lib/rubocop/ast/node/mixin/hash_element_node.rb +0 -125
  252. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +0 -269
  253. data/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb +0 -114
  254. data/lib/rubocop/ast/node/mixin/modifier_node.rb +0 -17
  255. data/lib/rubocop/ast/node/mixin/numeric_node.rb +0 -21
  256. data/lib/rubocop/ast/node/mixin/parameterized_node.rb +0 -61
  257. data/lib/rubocop/ast/node/mixin/predicate_operator_node.rb +0 -35
  258. data/lib/rubocop/ast/node/module_node.rb +0 -24
  259. data/lib/rubocop/ast/node/or_node.rb +0 -29
  260. data/lib/rubocop/ast/node/pair_node.rb +0 -63
  261. data/lib/rubocop/ast/node/range_node.rb +0 -18
  262. data/lib/rubocop/ast/node/regexp_node.rb +0 -33
  263. data/lib/rubocop/ast/node/resbody_node.rb +0 -24
  264. data/lib/rubocop/ast/node/retry_node.rb +0 -17
  265. data/lib/rubocop/ast/node/return_node.rb +0 -24
  266. data/lib/rubocop/ast/node/self_class_node.rb +0 -24
  267. data/lib/rubocop/ast/node/send_node.rb +0 -13
  268. data/lib/rubocop/ast/node/str_node.rb +0 -16
  269. data/lib/rubocop/ast/node/super_node.rb +0 -21
  270. data/lib/rubocop/ast/node/symbol_node.rb +0 -12
  271. data/lib/rubocop/ast/node/until_node.rb +0 -35
  272. data/lib/rubocop/ast/node/when_node.rb +0 -53
  273. data/lib/rubocop/ast/node/while_node.rb +0 -35
  274. data/lib/rubocop/ast/node/yield_node.rb +0 -21
  275. data/lib/rubocop/ast/sexp.rb +0 -16
  276. data/lib/rubocop/ast/traversal.rb +0 -202
  277. data/lib/rubocop/node_pattern.rb +0 -887
  278. data/lib/rubocop/processed_source.rb +0 -213
  279. data/lib/rubocop/string_util.rb +0 -14
  280. data/lib/rubocop/token.rb +0 -114
@@ -1,85 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module AST
5
- # `RuboCop::AST::Builder` is an AST builder that is utilized to let `Parser`
6
- # generate ASTs with {RuboCop::AST::Node}.
7
- #
8
- # @example
9
- # buffer = Parser::Source::Buffer.new('(string)')
10
- # buffer.source = 'puts :foo'
11
- #
12
- # builder = RuboCop::AST::Builder.new
13
- # require 'parser/ruby25'
14
- # parser = Parser::Ruby25.new(builder)
15
- # root_node = parser.parse(buffer)
16
- class Builder < Parser::Builders::Default
17
- NODE_MAP = {
18
- and: AndNode,
19
- alias: AliasNode,
20
- args: ArgsNode,
21
- array: ArrayNode,
22
- block: BlockNode,
23
- numblock: BlockNode,
24
- break: BreakNode,
25
- case_match: CaseMatchNode,
26
- case: CaseNode,
27
- class: ClassNode,
28
- def: DefNode,
29
- defined?: DefinedNode,
30
- defs: DefNode,
31
- ensure: EnsureNode,
32
- for: ForNode,
33
- forward_args: ForwardArgsNode,
34
- float: FloatNode,
35
- hash: HashNode,
36
- if: IfNode,
37
- int: IntNode,
38
- irange: RangeNode,
39
- erange: RangeNode,
40
- kwsplat: KeywordSplatNode,
41
- module: ModuleNode,
42
- or: OrNode,
43
- pair: PairNode,
44
- regexp: RegexpNode,
45
- resbody: ResbodyNode,
46
- retry: RetryNode,
47
- return: ReturnNode,
48
- csend: SendNode,
49
- send: SendNode,
50
- str: StrNode,
51
- dstr: StrNode,
52
- xstr: StrNode,
53
- sclass: SelfClassNode,
54
- super: SuperNode,
55
- zsuper: SuperNode,
56
- sym: SymbolNode,
57
- until: UntilNode,
58
- until_post: UntilNode,
59
- when: WhenNode,
60
- while: WhileNode,
61
- while_post: WhileNode,
62
- yield: YieldNode
63
- }.freeze
64
-
65
- # Generates {Node} from the given information.
66
- #
67
- # @return [Node] the generated node
68
- def n(type, children, source_map)
69
- node_klass(type).new(type, children, location: source_map)
70
- end
71
-
72
- # TODO: Figure out what to do about literal encoding handling...
73
- # More details here https://github.com/whitequark/parser/issues/283
74
- def string_value(token)
75
- value(token)
76
- end
77
-
78
- private
79
-
80
- def node_klass(type)
81
- NODE_MAP[type] || Node
82
- end
83
- end
84
- end
85
- end
@@ -1,637 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module AST
5
- # `RuboCop::AST::Node` is a subclass of `Parser::AST::Node`. It provides
6
- # access to parent nodes and an object-oriented way to traverse an AST with
7
- # the power of `Enumerable`.
8
- #
9
- # It has predicate methods for every node type, like this:
10
- #
11
- # @example
12
- # node.send_type? # Equivalent to: `node.type == :send`
13
- # node.op_asgn_type? # Equivalent to: `node.type == :op_asgn`
14
- #
15
- # # Non-word characters (other than a-zA-Z0-9_) in type names are omitted.
16
- # node.defined_type? # Equivalent to: `node.type == :defined?`
17
- #
18
- # # Find the first lvar node under the receiver node.
19
- # lvar_node = node.each_descendant.find(&:lvar_type?)
20
- #
21
- class Node < Parser::AST::Node # rubocop:disable Metrics/ClassLength
22
- include RuboCop::AST::Sexp
23
- extend NodePattern::Macros
24
-
25
- # <=> isn't included here, because it doesn't return a boolean.
26
- COMPARISON_OPERATORS = %i[== === != <= >= > <].freeze
27
-
28
- TRUTHY_LITERALS = %i[str dstr xstr int float sym dsym array
29
- hash regexp true irange erange complex
30
- rational regopt].freeze
31
- FALSEY_LITERALS = %i[false nil].freeze
32
- LITERALS = (TRUTHY_LITERALS + FALSEY_LITERALS).freeze
33
- COMPOSITE_LITERALS = %i[dstr xstr dsym array hash irange
34
- erange regexp].freeze
35
- BASIC_LITERALS = (LITERALS - COMPOSITE_LITERALS).freeze
36
- MUTABLE_LITERALS = %i[str dstr xstr array hash
37
- regexp irange erange].freeze
38
- IMMUTABLE_LITERALS = (LITERALS - MUTABLE_LITERALS).freeze
39
-
40
- EQUALS_ASSIGNMENTS = %i[lvasgn ivasgn cvasgn gvasgn
41
- casgn masgn].freeze
42
- SHORTHAND_ASSIGNMENTS = %i[op_asgn or_asgn and_asgn].freeze
43
- ASSIGNMENTS = (EQUALS_ASSIGNMENTS + SHORTHAND_ASSIGNMENTS).freeze
44
-
45
- BASIC_CONDITIONALS = %i[if while until].freeze
46
- CONDITIONALS = [*BASIC_CONDITIONALS, :case].freeze
47
- VARIABLES = %i[ivar gvar cvar lvar].freeze
48
- REFERENCES = %i[nth_ref back_ref].freeze
49
- KEYWORDS = %i[alias and break case class def defs defined?
50
- kwbegin do else ensure for if module next
51
- not or postexe redo rescue retry return self
52
- super zsuper then undef until when while
53
- yield].freeze
54
- OPERATOR_KEYWORDS = %i[and or].freeze
55
- SPECIAL_KEYWORDS = %w[__FILE__ __LINE__ __ENCODING__].freeze
56
-
57
- # @see https://www.rubydoc.info/gems/ast/AST/Node:initialize
58
- def initialize(type, children = [], properties = {})
59
- @mutable_attributes = {}
60
-
61
- # ::AST::Node#initialize freezes itself.
62
- super
63
-
64
- # #parent= may be invoked multiple times for a node because there are
65
- # pending nodes while constructing AST and they are replaced later.
66
- # For example, `lvar` and `send` type nodes are initially created as an
67
- # `ident` type node and fixed to the appropriate type later.
68
- # So, the #parent attribute needs to be mutable.
69
- each_child_node do |child_node|
70
- child_node.parent = self unless child_node.complete?
71
- end
72
- end
73
-
74
- Parser::Meta::NODE_TYPES.each do |node_type|
75
- method_name = "#{node_type.to_s.gsub(/\W/, '')}_type?"
76
- define_method(method_name) do
77
- type == node_type
78
- end
79
- end
80
-
81
- # Returns the parent node, or `nil` if the receiver is a root node.
82
- #
83
- # @return [Node, nil] the parent node or `nil`
84
- def parent
85
- @mutable_attributes[:parent]
86
- end
87
-
88
- def parent=(node)
89
- @mutable_attributes[:parent] = node
90
- end
91
-
92
- def complete!
93
- @mutable_attributes.freeze
94
- each_child_node(&:complete!)
95
- end
96
-
97
- def complete?
98
- @mutable_attributes.frozen?
99
- end
100
-
101
- protected :parent=
102
-
103
- # Override `AST::Node#updated` so that `AST::Processor` does not try to
104
- # mutate our ASTs. Since we keep references from children to parents and
105
- # not just the other way around, we cannot update an AST and share
106
- # identical subtrees. Rather, the entire AST must be copied any time any
107
- # part of it is changed.
108
- def updated(type = nil, children = nil, properties = {})
109
- properties[:location] ||= @location
110
- klass = RuboCop::AST::Builder::NODE_MAP[type || @type] || Node
111
- klass.new(type || @type, children || @children, properties)
112
- end
113
-
114
- # Returns the index of the receiver node in its siblings. (Sibling index
115
- # uses zero based numbering.)
116
- #
117
- # @return [Integer] the index of the receiver node in its siblings
118
- def sibling_index
119
- parent&.children&.index { |sibling| sibling.equal?(self) }
120
- end
121
-
122
- # Common destructuring method. This can be used to normalize
123
- # destructuring for different variations of the node.
124
- # Some node types override this with their own custom
125
- # destructuring method.
126
- #
127
- # @return [Array<Node>] the different parts of the ndde
128
- def node_parts
129
- to_a
130
- end
131
-
132
- # Calls the given block for each ancestor node from parent to root.
133
- # If no block is given, an `Enumerator` is returned.
134
- #
135
- # @overload each_ancestor
136
- # Yield all nodes.
137
- # @overload each_ancestor(type)
138
- # Yield only nodes matching the type.
139
- # @param [Symbol] type a node type
140
- # @overload each_ancestor(type_a, type_b, ...)
141
- # Yield only nodes matching any of the types.
142
- # @param [Symbol] type_a a node type
143
- # @param [Symbol] type_b a node type
144
- # @yieldparam [Node] node each ancestor node
145
- # @return [self] if a block is given
146
- # @return [Enumerator] if no block is given
147
- def each_ancestor(*types, &block)
148
- return to_enum(__method__, *types) unless block_given?
149
-
150
- visit_ancestors(types, &block)
151
-
152
- self
153
- end
154
-
155
- # Returns an array of ancestor nodes.
156
- # This is a shorthand for `node.each_ancestor.to_a`.
157
- #
158
- # @return [Array<Node>] an array of ancestor nodes
159
- def ancestors
160
- each_ancestor.to_a
161
- end
162
-
163
- # Calls the given block for each child node.
164
- # If no block is given, an `Enumerator` is returned.
165
- #
166
- # Note that this is different from `node.children.each { |child| ... }`
167
- # which yields all children including non-node elements.
168
- #
169
- # @overload each_child_node
170
- # Yield all nodes.
171
- # @overload each_child_node(type)
172
- # Yield only nodes matching the type.
173
- # @param [Symbol] type a node type
174
- # @overload each_child_node(type_a, type_b, ...)
175
- # Yield only nodes matching any of the types.
176
- # @param [Symbol] type_a a node type
177
- # @param [Symbol] type_b a node type
178
- # @yieldparam [Node] node each child node
179
- # @return [self] if a block is given
180
- # @return [Enumerator] if no block is given
181
- def each_child_node(*types)
182
- return to_enum(__method__, *types) unless block_given?
183
-
184
- children.each do |child|
185
- next unless child.is_a?(Node)
186
-
187
- yield child if types.empty? || types.include?(child.type)
188
- end
189
-
190
- self
191
- end
192
-
193
- # Returns an array of child nodes.
194
- # This is a shorthand for `node.each_child_node.to_a`.
195
- #
196
- # @return [Array<Node>] an array of child nodes
197
- def child_nodes
198
- each_child_node.to_a
199
- end
200
-
201
- # Calls the given block for each descendant node with depth first order.
202
- # If no block is given, an `Enumerator` is returned.
203
- #
204
- # @overload each_descendant
205
- # Yield all nodes.
206
- # @overload each_descendant(type)
207
- # Yield only nodes matching the type.
208
- # @param [Symbol] type a node type
209
- # @overload each_descendant(type_a, type_b, ...)
210
- # Yield only nodes matching any of the types.
211
- # @param [Symbol] type_a a node type
212
- # @param [Symbol] type_b a node type
213
- # @yieldparam [Node] node each descendant node
214
- # @return [self] if a block is given
215
- # @return [Enumerator] if no block is given
216
- def each_descendant(*types, &block)
217
- return to_enum(__method__, *types) unless block_given?
218
-
219
- visit_descendants(types, &block)
220
-
221
- self
222
- end
223
-
224
- # Returns an array of descendant nodes.
225
- # This is a shorthand for `node.each_descendant.to_a`.
226
- #
227
- # @return [Array<Node>] an array of descendant nodes
228
- def descendants
229
- each_descendant.to_a
230
- end
231
-
232
- # Calls the given block for the receiver and each descendant node in
233
- # depth-first order.
234
- # If no block is given, an `Enumerator` is returned.
235
- #
236
- # This method would be useful when you treat the receiver node as the root
237
- # of a tree and want to iterate over all nodes in the tree.
238
- #
239
- # @overload each_node
240
- # Yield all nodes.
241
- # @overload each_node(type)
242
- # Yield only nodes matching the type.
243
- # @param [Symbol] type a node type
244
- # @overload each_node(type_a, type_b, ...)
245
- # Yield only nodes matching any of the types.
246
- # @param [Symbol] type_a a node type
247
- # @param [Symbol] type_b a node type
248
- # @yieldparam [Node] node each node
249
- # @return [self] if a block is given
250
- # @return [Enumerator] if no block is given
251
- def each_node(*types, &block)
252
- return to_enum(__method__, *types) unless block_given?
253
-
254
- yield self if types.empty? || types.include?(type)
255
-
256
- visit_descendants(types, &block)
257
-
258
- self
259
- end
260
-
261
- def source
262
- loc.expression.source
263
- end
264
-
265
- def source_range
266
- loc.expression
267
- end
268
-
269
- def first_line
270
- loc.line
271
- end
272
-
273
- def last_line
274
- loc.last_line
275
- end
276
-
277
- def line_count
278
- return 0 unless source_range
279
-
280
- source_range.last_line - source_range.first_line + 1
281
- end
282
-
283
- def nonempty_line_count
284
- source.lines.grep(/\S/).size
285
- end
286
-
287
- def source_length
288
- source_range ? source_range.size : 0
289
- end
290
-
291
- ## Destructuring
292
-
293
- def_node_matcher :receiver, <<~PATTERN
294
- {(send $_ ...) ({block numblock} (send $_ ...) ...)}
295
- PATTERN
296
-
297
- def_node_matcher :str_content, '(str $_)'
298
-
299
- def const_name
300
- return unless const_type?
301
-
302
- namespace, name = *self
303
- if namespace && !namespace.cbase_type?
304
- "#{namespace.const_name}::#{name}"
305
- else
306
- name.to_s
307
- end
308
- end
309
-
310
- def_node_matcher :defined_module0, <<~PATTERN
311
- {(class (const $_ $_) ...)
312
- (module (const $_ $_) ...)
313
- (casgn $_ $_ (send (const nil? {:Class :Module}) :new ...))
314
- (casgn $_ $_ (block (send (const nil? {:Class :Module}) :new ...) ...))}
315
- PATTERN
316
-
317
- private :defined_module0
318
-
319
- def defined_module
320
- namespace, name = *defined_module0
321
- s(:const, namespace, name) if name
322
- end
323
-
324
- def defined_module_name
325
- (const = defined_module) && const.const_name
326
- end
327
-
328
- ## Searching the AST
329
-
330
- def parent_module_name
331
- # what class or module is this method/constant/etc definition in?
332
- # returns nil if answer cannot be determined
333
- ancestors = each_ancestor(:class, :module, :sclass, :casgn, :block)
334
- result = ancestors.map do |ancestor|
335
- parent_module_name_part(ancestor) { |full_name| return full_name }
336
- end.compact.reverse.join('::')
337
- result.empty? ? 'Object' : result
338
- end
339
-
340
- ## Predicates
341
-
342
- def multiline?
343
- line_count > 1
344
- end
345
-
346
- def single_line?
347
- line_count == 1
348
- end
349
-
350
- def empty_source?
351
- source_length.zero?
352
- end
353
-
354
- # Some cops treat the shovel operator as a kind of assignment.
355
- def_node_matcher :assignment_or_similar?, <<~PATTERN
356
- {assignment? (send _recv :<< ...)}
357
- PATTERN
358
-
359
- def literal?
360
- LITERALS.include?(type)
361
- end
362
-
363
- def basic_literal?
364
- BASIC_LITERALS.include?(type)
365
- end
366
-
367
- def truthy_literal?
368
- TRUTHY_LITERALS.include?(type)
369
- end
370
-
371
- def falsey_literal?
372
- FALSEY_LITERALS.include?(type)
373
- end
374
-
375
- def mutable_literal?
376
- MUTABLE_LITERALS.include?(type)
377
- end
378
-
379
- def immutable_literal?
380
- IMMUTABLE_LITERALS.include?(type)
381
- end
382
-
383
- %i[literal basic_literal].each do |kind|
384
- recursive_kind = :"recursive_#{kind}?"
385
- kind_filter = :"#{kind}?"
386
- define_method(recursive_kind) do
387
- case type
388
- when :send
389
- [*COMPARISON_OPERATORS, :!, :<=>].include?(method_name) &&
390
- receiver.send(recursive_kind) &&
391
- arguments.all?(&recursive_kind)
392
- when :begin, :pair, *OPERATOR_KEYWORDS, *COMPOSITE_LITERALS
393
- children.compact.all?(&recursive_kind)
394
- else
395
- send(kind_filter)
396
- end
397
- end
398
- end
399
-
400
- def variable?
401
- VARIABLES.include?(type)
402
- end
403
-
404
- def reference?
405
- REFERENCES.include?(type)
406
- end
407
-
408
- def equals_asgn?
409
- EQUALS_ASSIGNMENTS.include?(type)
410
- end
411
-
412
- def shorthand_asgn?
413
- SHORTHAND_ASSIGNMENTS.include?(type)
414
- end
415
-
416
- def assignment?
417
- ASSIGNMENTS.include?(type)
418
- end
419
-
420
- def basic_conditional?
421
- BASIC_CONDITIONALS.include?(type)
422
- end
423
-
424
- def conditional?
425
- CONDITIONALS.include?(type)
426
- end
427
-
428
- def keyword?
429
- return true if special_keyword? || send_type? && prefix_not?
430
- return false unless KEYWORDS.include?(type)
431
-
432
- !OPERATOR_KEYWORDS.include?(type) || loc.operator.is?(type.to_s)
433
- end
434
-
435
- def special_keyword?
436
- SPECIAL_KEYWORDS.include?(source)
437
- end
438
-
439
- def operator_keyword?
440
- OPERATOR_KEYWORDS.include?(type)
441
- end
442
-
443
- def parenthesized_call?
444
- loc.respond_to?(:begin) && loc.begin && loc.begin.is?('(')
445
- end
446
-
447
- def call_type?
448
- send_type? || csend_type?
449
- end
450
-
451
- def chained?
452
- parent&.call_type? && eql?(parent.receiver)
453
- end
454
-
455
- def argument?
456
- parent&.send_type? && parent.arguments.include?(self)
457
- end
458
-
459
- def boolean_type?
460
- true_type? || false_type?
461
- end
462
-
463
- def numeric_type?
464
- int_type? || float_type?
465
- end
466
-
467
- def range_type?
468
- irange_type? || erange_type?
469
- end
470
-
471
- def guard_clause?
472
- node = and_type? || or_type? ? rhs : self
473
-
474
- node.match_guard_clause?
475
- end
476
-
477
- def_node_matcher :match_guard_clause?, <<~PATTERN
478
- [${(send nil? {:raise :fail} ...) return break next} single_line?]
479
- PATTERN
480
-
481
- def_node_matcher :proc?, <<~PATTERN
482
- {(block (send nil? :proc) ...)
483
- (block (send (const nil? :Proc) :new) ...)
484
- (send (const nil? :Proc) :new)}
485
- PATTERN
486
-
487
- def_node_matcher :lambda?, '({block numblock} (send nil? :lambda) ...)'
488
- def_node_matcher :lambda_or_proc?, '{lambda? proc?}'
489
-
490
- def_node_matcher :class_constructor?, <<~PATTERN
491
- { (send (const nil? {:Class :Module}) :new ...)
492
- (block (send (const nil? {:Class :Module}) :new ...) ...)}
493
- PATTERN
494
-
495
- # Some expressions are evaluated for their value, some for their side
496
- # effects, and some for both
497
- # If we know that an expression is useful only for its side effects, that
498
- # means we can transform it in ways which preserve the side effects, but
499
- # change the return value
500
- # So, does the return value of this node matter? If we changed it to
501
- # `(...; nil)`, might that affect anything?
502
- #
503
- # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
504
- def value_used?
505
- # Be conservative and return true if we're not sure.
506
- return false if parent.nil?
507
-
508
- case parent.type
509
- when :array, :defined?, :dstr, :dsym, :eflipflop, :erange, :float,
510
- :hash, :iflipflop, :irange, :not, :pair, :regexp, :str, :sym,
511
- :when, :xstr
512
- parent.value_used?
513
- when :begin, :kwbegin
514
- begin_value_used?
515
- when :for
516
- for_value_used?
517
- when :case, :if
518
- case_if_value_used?
519
- when :while, :until, :while_post, :until_post
520
- while_until_value_used?
521
- else
522
- true
523
- end
524
- end
525
- # rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity
526
-
527
- # Some expressions are evaluated for their value, some for their side
528
- # effects, and some for both.
529
- # If we know that expressions are useful only for their return values,
530
- # and have no side effects, that means we can reorder them, change the
531
- # number of times they are evaluated, or replace them with other
532
- # expressions which are equivalent in value.
533
- # So, is evaluation of this node free of side effects?
534
- #
535
- def pure?
536
- # Be conservative and return false if we're not sure
537
- case type
538
- when :__FILE__, :__LINE__, :const, :cvar, :defined?, :false, :float,
539
- :gvar, :int, :ivar, :lvar, :nil, :str, :sym, :true, :regopt
540
- true
541
- when :and, :array, :begin, :case, :dstr, :dsym, :eflipflop, :ensure,
542
- :erange, :for, :hash, :if, :iflipflop, :irange, :kwbegin, :not,
543
- :or, :pair, :regexp, :until, :until_post, :when, :while,
544
- :while_post
545
- child_nodes.all?(&:pure?)
546
- else
547
- false
548
- end
549
- end
550
-
551
- protected
552
-
553
- def visit_descendants(types, &block)
554
- each_child_node do |child|
555
- yield child if types.empty? || types.include?(child.type)
556
- child.visit_descendants(types, &block)
557
- end
558
- end
559
-
560
- private
561
-
562
- def visit_ancestors(types)
563
- last_node = self
564
-
565
- while (current_node = last_node.parent)
566
- yield current_node if types.empty? ||
567
- types.include?(current_node.type)
568
- last_node = current_node
569
- end
570
- end
571
-
572
- def begin_value_used?
573
- # the last child node determines the value of the parent
574
- sibling_index == parent.children.size - 1 ? parent.value_used? : false
575
- end
576
-
577
- def for_value_used?
578
- # `for var in enum; body; end`
579
- # (for <var> <enum> <body>)
580
- sibling_index == 2 ? parent.value_used? : true
581
- end
582
-
583
- def case_if_value_used?
584
- # (case <condition> <when...>)
585
- # (if <condition> <truebranch> <falsebranch>)
586
- sibling_index.zero? ? true : parent.value_used?
587
- end
588
-
589
- def while_until_value_used?
590
- # (while <condition> <body>) -> always evaluates to `nil`
591
- sibling_index.zero?
592
- end
593
-
594
- def parent_module_name_part(node)
595
- case node.type
596
- when :class, :module, :casgn
597
- # TODO: if constant name has cbase (leading ::), then we don't need
598
- # to keep traversing up through nested classes/modules
599
- node.defined_module_name
600
- when :sclass
601
- yield parent_module_name_for_sclass(node)
602
- else # block
603
- parent_module_name_for_block(node) { yield nil }
604
- end
605
- end
606
-
607
- def parent_module_name_for_sclass(sclass_node)
608
- # TODO: look for constant definition and see if it is nested
609
- # inside a class or module
610
- subject = sclass_node.children[0]
611
-
612
- if subject.const_type?
613
- "#<Class:#{subject.const_name}>"
614
- elsif subject.self_type?
615
- "#<Class:#{sclass_node.parent_module_name}>"
616
- end
617
- end
618
-
619
- def parent_module_name_for_block(ancestor)
620
- if ancestor.method?(:class_eval)
621
- # `class_eval` with no receiver applies to whatever module or class
622
- # we are currently in
623
- return unless (receiver = ancestor.receiver)
624
-
625
- yield unless receiver.const_type?
626
- receiver.const_name
627
- elsif !new_class_or_module_block?(ancestor)
628
- yield
629
- end
630
- end
631
-
632
- def_node_matcher :new_class_or_module_block?, <<~PATTERN
633
- ^(casgn _ _ (block (send (const _ {:Class :Module}) :new) ...))
634
- PATTERN
635
- end
636
- end
637
- end