rubocop-ordered_methods 0.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ade6d192050ac40f268177e3ede23b40f57d569041c6191baa855bfcef87a2c2
4
- data.tar.gz: b39ded0724baf7c35b2d48506bebbe0924a04be6fe0c300a75090bf7e9deb7af
3
+ metadata.gz: efe0a069919334996c9317cf8d9dd03bb19fe984a9d8d7a294f017dcb361ec96
4
+ data.tar.gz: b8c6b15fbfa6d2b44c99b051ebfb4a2ba047c2958f16cf9015b4f2d87f674fe5
5
5
  SHA512:
6
- metadata.gz: 79368459e3709585a1741e6d5374b5e9d5176562f494a344ceed58208c512bf8c9f324ef8200bd9de9645b95a2d6a05d4bc584af97329997328bad44db2426ff
7
- data.tar.gz: 1c3dcbf99709710ad10fec4e0085f1fd8caf9094082d27cb8a8b77fc6e081d0942bbfd41953b2bd715d184d3430a92ee463665913c51fcfcdac483c141a69f89
6
+ metadata.gz: cca41398955b51c5d968fc84b4ec0833339224c696de865d6421834491da2113b12d7e4bfce8fe1771b53f18a0ae872e350ffff96fccce4610b71eca38b3583d
7
+ data.tar.gz: 57f61650ad8df63193aa45f9fa35133c85698a134d9a6ee3bfa305b9de074763cc45d7fc26a64da216ba79f86d5b19e5fec84084ee989f266e82dc56251f00fd
@@ -1,3 +1,5 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
1
3
  require: rubocop-ordered_methods
2
4
 
3
5
  Metrics/BlockLength:
@@ -0,0 +1,21 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2019-02-17 13:54:25 -0500 using RuboCop version 0.64.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 1
10
+ Metrics/AbcSize:
11
+ Max: 17
12
+
13
+ # Offense count: 1
14
+ # Configuration parameters: CountComments.
15
+ Metrics/ClassLength:
16
+ Max: 101
17
+
18
+ # Offense count: 1
19
+ # Configuration parameters: CountComments, ExcludedMethods.
20
+ Metrics/MethodLength:
21
+ Max: 11
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # RuboCop OrderedMethods
2
2
 
3
- Check that methods are defined alphabetically.
3
+ Check that methods are defined alphabetically. Note [caveats](#caveats) for
4
+ autocorrector.
4
5
 
5
6
  ```ruby
6
7
  # bad
@@ -72,6 +73,16 @@ Name | Default value | Configurable values
72
73
  --- | --- | ---
73
74
  IgnoredMethods | `initialize` | Array
74
75
 
76
+ ### Corrector
77
+
78
+ The corrector will attempt to order methods alphabetically. It attempts to
79
+ include surrounding comments and the qualifiers listed in
80
+ `::RuboCop::Cop::Layout::OrderedMethods::QUALIFIERS`.
81
+
82
+ #### Caveats
83
+ The corrector can fail to include surrounding comments and qualifiers for some
84
+ methods.
85
+
75
86
  ## Development
76
87
 
77
88
  ### Setup
@@ -1,2 +1,3 @@
1
1
  require 'rubocop'
2
2
  require_relative 'rubocop/cop/layout/ordered_methods'
3
+ require_relative 'rubocop/cop/correctors/ordered_methods_corrector'
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../layout/ordered_methods'
4
+
5
+ module RuboCop
6
+ module Cop
7
+ # This auto-corrects method order
8
+ class OrderedMethodsCorrector
9
+ class << self
10
+ include IgnoredNode
11
+ extend NodePattern::Macros
12
+
13
+ ALIAS_BEFORE_METHOD_WARNING_FMT = "Won't reorder " \
14
+ '%<first_method_name>s and %<second_method_name>s because ' \
15
+ 'alias for %<first_method_name>s would be declared before ' \
16
+ 'its method definition.'.freeze
17
+ QUALIFIERS = (
18
+ %i[alias_method private_class_method public_class_method] +
19
+ ::RuboCop::Cop::Layout::OrderedMethods::
20
+ VISIBILITY_MODIFIERS
21
+ ).freeze
22
+
23
+ def_node_matcher :alias?, '(:alias ... (sym $_method_name))'
24
+ def_node_matcher :qualifier?, <<-PATTERN
25
+ (send nil? {#{QUALIFIERS.map(&:inspect).join(' ')}}
26
+ ... (sym $_method_name))
27
+ PATTERN
28
+
29
+ def correct(processed_source, node, previous_node)
30
+ @processed_source = processed_source
31
+ @current_node = node
32
+ @previous_node = previous_node
33
+
34
+ verify_alias_method_order
35
+ current_range = with_surroundings(@current_node)
36
+ previous_range = with_surroundings(@previous_node)
37
+ lambda do |corrector|
38
+ corrector.replace(current_range, previous_range.source)
39
+ corrector.replace(previous_range, current_range.source)
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def found_qualifier?(node, next_sibling)
46
+ (qualifier?(next_sibling) || alias?(next_sibling)) == node.method_name
47
+ end
48
+
49
+ # We don't want a method to be defined after its alias
50
+ def moving_after_alias?(current_node, previous_node)
51
+ siblings = current_node.parent.children
52
+ current_node_aliases = siblings.select do |sibling|
53
+ alias?(sibling) == current_node.method_name
54
+ end
55
+ filter = current_node_aliases.delete_if do |cna|
56
+ cna.sibling_index == current_node.sibling_index + 1
57
+ end
58
+ return false if filter.empty?
59
+
60
+ current_node_aliases.any? do |cna|
61
+ previous_node.sibling_index > cna.sibling_index
62
+ end
63
+ end
64
+
65
+ # rubocop:disable Metrics/MethodLength, Style/GuardClause
66
+ def verify_alias_method_order
67
+ if moving_after_alias?(@current_node, @previous_node)
68
+ ignore_node(@current_node)
69
+ raise Warning, format(
70
+ ALIAS_BEFORE_METHOD_WARNING_FMT,
71
+ first_method_name: @current_node.method_name,
72
+ second_method_name: @previous_node.method_name
73
+ )
74
+ end
75
+ if moving_after_alias?(@previous_node, @current_node)
76
+ ignore_node(@previous_node)
77
+ raise Warning, format(
78
+ ALIAS_BEFORE_METHOD_WARNING_FMT,
79
+ first_method_name: @previous_node.method_name,
80
+ second_method_name: @current_node.method_name
81
+ )
82
+ end
83
+ end
84
+ # rubocop:enable Metrics/MethodLength, Style/GuardClause
85
+
86
+ def with_comments(node)
87
+ node.source_range
88
+ .join(with_preceding_comments(node))
89
+ .join(with_succeeding_comments(node))
90
+ end
91
+
92
+ def with_modifiers_and_aliases(node)
93
+ surrounding_range = node.source_range
94
+ siblings = node.parent.children
95
+ qualifier_index = node.sibling_index
96
+ while found_qualifier?(node, siblings[qualifier_index + 1])
97
+ qualifier_index += 1
98
+ end
99
+ found_node_range = with_comments(siblings[qualifier_index])
100
+ surrounding_range.join(found_node_range)
101
+ end
102
+
103
+ def with_preceding_comments(node)
104
+ surrounding_range = node.source_range
105
+ @processed_source.ast_with_comments[node].each do |comment|
106
+ surrounding_range = surrounding_range.join(comment.loc.expression)
107
+ end
108
+ surrounding_range
109
+ end
110
+
111
+ def with_succeeding_comments(node)
112
+ surrounding_range = node.source_range
113
+ @processed_source.each_comment do |comment|
114
+ if comment.loc.expression.begin_pos == surrounding_range.end_pos + 1
115
+ surrounding_range = surrounding_range.join(comment.loc.expression)
116
+ end
117
+ end
118
+ surrounding_range
119
+ end
120
+
121
+ def with_surroundings(node)
122
+ node.source_range
123
+ .join(with_comments(node))
124
+ .join(with_modifiers_and_aliases(node))
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -47,9 +47,20 @@ module RuboCop
47
47
  (send nil? { #{VISIBILITY_MODIFIERS.map(&:inspect).join(' ')} })
48
48
  PATTERN
49
49
 
50
+ def autocorrect(node)
51
+ OrderedMethodsCorrector.correct(
52
+ processed_source,
53
+ node,
54
+ @previous_node
55
+ )
56
+ end
57
+
50
58
  def on_begin(node)
51
59
  consecutive_methods(node.children) do |previous, current|
52
- add_offense(current) unless ordered?(previous, current)
60
+ unless ordered?(previous, current)
61
+ @previous_node = previous
62
+ add_offense(current)
63
+ end
53
64
  end
54
65
  end
55
66
 
@@ -3,7 +3,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
 
4
4
  Gem::Specification.new do |spec|
5
5
  spec.name = 'rubocop-ordered_methods'
6
- spec.version = '0.1'
6
+ spec.version = '0.2'
7
7
  spec.authors = ['Shane Cavanaugh']
8
8
  spec.email = ['shane@shanecav.net']
9
9
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-ordered_methods
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.1'
4
+ version: '0.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shane Cavanaugh
@@ -75,15 +75,16 @@ extra_rdoc_files: []
75
75
  files:
76
76
  - ".gitignore"
77
77
  - ".rubocop.yml"
78
+ - ".rubocop_todo.yml"
78
79
  - ".travis.yml"
79
80
  - CODE_OF_CONDUCT.md
80
81
  - Gemfile
81
- - Gemfile.lock
82
82
  - LICENSE.txt
83
83
  - README.md
84
84
  - Rakefile
85
85
  - bin/console
86
86
  - lib/rubocop-ordered_methods.rb
87
+ - lib/rubocop/cop/correctors/ordered_methods_corrector.rb
87
88
  - lib/rubocop/cop/layout/ordered_methods.rb
88
89
  - rubocop-ordered_methods.gemspec
89
90
  homepage: https://github.com/shanecav84/rubocop-ordered_methods