rubocop-ast 0.3.0 → 0.4.0

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: 918c6017183db74497fc68166973904312bac7583f7752c2e55d1829574cb248
4
- data.tar.gz: 1d04eb24fcbaec96b4bf0f17694018c31034fce4b3d81a9446ca98b3085e05a4
3
+ metadata.gz: a691b22abba3de79be3aca5f66247b20b5bdd8fe0bcbe1403d5455c4da25fae9
4
+ data.tar.gz: d0984b47a3d0f683447361683acb58afa4fcfffb1597bed575cce1d34fafd90e
5
5
  SHA512:
6
- metadata.gz: 54f6882ebf057c76a9c97212a62b295d03baea85ec7c44e606b412e74edce01b6c4bba93dfafa341756009a8bfa2352c4b2b3b22bdbf689dac08ddd9395a9aff
7
- data.tar.gz: '08e60b802e83dba688bf1a31be417f9880b640194cf3b966849dd2c211de5a1f3797c8a37be3f2d3aa466d6c994b10c31277b0ed3dc708b12fe1c2f7a0f15552'
6
+ metadata.gz: 165cfc53926eecd29099f29554dae5e751bb1bee7c4fc42f49abe93db18ea3dbf6589b7b57e6e16aaabf7e842ea253dd41609ab2af343c44db4181af4c815c79
7
+ data.tar.gz: f150ffa3ae23ae80f4e3572a529fd19d42509e025e013c02c52eb408c60f3feaf55ef1d53304c19586ad2bf3b3b0ca7aac18503bc45b56ed3ad534dc875d894f
@@ -5,6 +5,7 @@ require 'forwardable'
5
5
  require 'set'
6
6
 
7
7
  require_relative 'ast/ext/range'
8
+ require_relative 'ast/ext/set'
8
9
  require_relative 'ast/node_pattern'
9
10
  require_relative 'ast/sexp'
10
11
  require_relative 'ast/node'
@@ -28,6 +29,7 @@ require_relative 'ast/node/break_node'
28
29
  require_relative 'ast/node/case_match_node'
29
30
  require_relative 'ast/node/case_node'
30
31
  require_relative 'ast/node/class_node'
32
+ require_relative 'ast/node/const_node'
31
33
  require_relative 'ast/node/def_node'
32
34
  require_relative 'ast/node/defined_node'
33
35
  require_relative 'ast/node/ensure_node'
@@ -47,6 +49,7 @@ require_relative 'ast/node/or_node'
47
49
  require_relative 'ast/node/pair_node'
48
50
  require_relative 'ast/node/range_node'
49
51
  require_relative 'ast/node/regexp_node'
52
+ require_relative 'ast/node/rescue_node'
50
53
  require_relative 'ast/node/resbody_node'
51
54
  require_relative 'ast/node/return_node'
52
55
  require_relative 'ast/node/self_class_node'
@@ -27,6 +27,7 @@ module RuboCop
27
27
  case_match: CaseMatchNode,
28
28
  case: CaseNode,
29
29
  class: ClassNode,
30
+ const: ConstNode,
30
31
  def: DefNode,
31
32
  defined?: DefinedNode,
32
33
  defs: DefNode,
@@ -48,6 +49,7 @@ module RuboCop
48
49
  or: OrNode,
49
50
  pair: PairNode,
50
51
  regexp: RegexpNode,
52
+ rescue: RescueNode,
51
53
  resbody: ResbodyNode,
52
54
  return: ReturnNode,
53
55
  csend: SendNode,
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ test = :foo
4
+ case test
5
+ when Set[:foo]
6
+ # ok, RUBY_VERSION > 2.4
7
+ else
8
+ # Harmonize `Set#===`
9
+ class Set
10
+ alias === include?
11
+ end
12
+ end
@@ -38,7 +38,7 @@ module RuboCop
38
38
  IMMUTABLE_LITERALS = (LITERALS - MUTABLE_LITERALS).freeze
39
39
 
40
40
  EQUALS_ASSIGNMENTS = %i[lvasgn ivasgn cvasgn gvasgn
41
- casgn masgn].freeze
41
+ casgn masgn rasgn mrasgn].freeze
42
42
  SHORTHAND_ASSIGNMENTS = %i[op_asgn or_asgn and_asgn].freeze
43
43
  ASSIGNMENTS = (EQUALS_ASSIGNMENTS + SHORTHAND_ASSIGNMENTS).freeze
44
44
 
@@ -116,12 +116,50 @@ module RuboCop
116
116
 
117
117
  # Returns the index of the receiver node in its siblings. (Sibling index
118
118
  # uses zero based numbering.)
119
+ # Use is discouraged, this is a potentially slow method.
119
120
  #
120
- # @return [Integer] the index of the receiver node in its siblings
121
+ # @return [Integer, nil] the index of the receiver node in its siblings
121
122
  def sibling_index
122
123
  parent&.children&.index { |sibling| sibling.equal?(self) }
123
124
  end
124
125
 
126
+ # Use is discouraged, this is a potentially slow method and can lead
127
+ # to even slower algorithms
128
+ # @return [Node, nil] the right (aka next) sibling
129
+ def right_sibling
130
+ return unless parent
131
+
132
+ parent.children[sibling_index + 1].freeze
133
+ end
134
+
135
+ # Use is discouraged, this is a potentially slow method and can lead
136
+ # to even slower algorithms
137
+ # @return [Node, nil] the left (aka previous) sibling
138
+ def left_sibling
139
+ i = sibling_index
140
+ return if i.nil? || i.zero?
141
+
142
+ parent.children[i - 1].freeze
143
+ end
144
+
145
+ # Use is discouraged, this is a potentially slow method and can lead
146
+ # to even slower algorithms
147
+ # @return [Array<Node>] the left (aka previous) siblings
148
+ def left_siblings
149
+ return [].freeze unless parent
150
+
151
+ parent.children[0...sibling_index].freeze
152
+ end
153
+
154
+ # Use is discouraged, this is a potentially slow method and can lead
155
+ # to even slower algorithms
156
+ # @return [Array<Node>] the right (aka next) siblings
157
+ def right_siblings
158
+ return [].freeze unless parent
159
+
160
+ parent.children[sibling_index + 1..-1].freeze
161
+ end
162
+
125
163
  # Common destructuring method. This can be used to normalize
126
164
  # destructuring for different variations of the node.
127
165
  # Some node types override this with their own custom
@@ -25,7 +25,7 @@ module RuboCop
25
25
  # @return [Array<Node>]
26
26
  def arguments
27
27
  if numblock_type?
28
- [] # Numbered parameters have no block arguments.
28
+ [].freeze # Numbered parameters have no block arguments.
29
29
  else
30
30
  node_parts[1]
31
31
  end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # A node extension for `const` nodes.
6
+ class ConstNode < Node
7
+ # The `send` node associated with this block.
8
+ #
9
+ # @return [Node, nil] the node associated with the scope (e.g. cbase, const, ...)
10
+ def namespace
11
+ children[0]
12
+ end
13
+
14
+ # @return [Symbol] the demodulized name of the constant: "::Foo::Bar" => :Bar
15
+ def short_name
16
+ children[1]
17
+ end
18
+
19
+ # The body of this block.
20
+ #
21
+ # @return [Boolean] if the constant is a Module / Class, according to the standard convention.
22
+ # Note: some classes might have uppercase in which case this method
23
+ # returns false
24
+ def module_name?
25
+ short_name.match?(/[[:lower:]]/)
26
+ end
27
+ alias class_name? module_name?
28
+
29
+ # @return [Boolean] if the constant starts with `::` (aka s(:cbase))
30
+ def absolute?
31
+ each_path.first.cbase_type?
32
+ end
33
+
34
+ # @return [Boolean] if the constant does not start with `::` (aka s(:cbase))
35
+ def relative?
36
+ !absolute?
37
+ end
38
+
39
+ # Yield nodes for the namespace
40
+ #
41
+ # For `::Foo::Bar::BAZ` => yields:
42
+ # s(:cbase), then
43
+ # s(:const, :Foo), then
44
+ # s(:const, s(:const, :Foo), :Bar)
45
+ def each_path(&block)
46
+ return to_enum(__method__) unless block_given?
47
+
48
+ descendants = []
49
+ last = self
50
+ loop do
51
+ last = last.children.first
52
+ break if last.nil?
53
+
54
+ descendants << last
55
+ break unless last.const_type?
56
+ end
57
+ descendants.reverse_each(&block)
58
+
59
+ self
60
+ end
61
+ end
62
+ end
63
+ end
@@ -82,9 +82,9 @@ module RuboCop
82
82
  # and optimizes other calls
83
83
  module RestArguments
84
84
  include ParameterizedNode
85
- # @return [Array] arguments, if any
85
+ # @return [Array<Node>] arguments, if any
86
86
  def arguments
87
- children[first_argument_index..-1]
87
+ children[first_argument_index..-1].freeze
88
88
  end
89
89
 
90
90
  # A shorthand for getting the first argument of the node.
@@ -13,12 +13,33 @@ module RuboCop
13
13
  node_parts[2]
14
14
  end
15
15
 
16
+ # Returns an array of all the exceptions in the `rescue` clause.
17
+ #
18
+ # @return [Array<Node>] an array of exception nodes
19
+ def exceptions
20
+ exceptions_node = node_parts[0]
21
+ if exceptions_node.nil?
22
+ []
23
+ elsif exceptions_node.array_type?
24
+ exceptions_node.values
25
+ else
26
+ [exceptions_node]
27
+ end
28
+ end
29
+
16
30
  # Returns the exception variable of the `rescue` clause.
17
31
  #
18
32
  # @return [Node, nil] The exception variable of the `resbody`.
19
33
  def exception_variable
20
34
  node_parts[1]
21
35
  end
36
+
37
+ # Returns the index of the `resbody` branch within the exception handling statement.
38
+ #
39
+ # @return [Integer] the index of the `resbody` branch
40
+ def branch_index
41
+ parent.resbody_branches.index(self)
42
+ end
22
43
  end
23
44
  end
24
45
  end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # A node extension for `rescue` nodes. This will be used in place of a
6
+ # plain node when the builder constructs the AST, making its methods
7
+ # available to all `rescue` nodes within RuboCop.
8
+ class RescueNode < Node
9
+ # Returns the body of the rescue node.
10
+ #
11
+ # @return [Node, nil] The body of the rescue node.
12
+ def body
13
+ node_parts[0]
14
+ end
15
+
16
+ # Returns an array of all the rescue branches in the exception handling statement.
17
+ #
18
+ # @return [Array<ResbodyNode>] an array of `resbody` nodes
19
+ def resbody_branches
20
+ node_parts[1...-1]
21
+ end
22
+
23
+ # Returns an array of all the rescue branches in the exception handling statement.
24
+ #
25
+ # @return [Array<Node, nil>] an array of the bodies of the rescue branches
26
+ # and the else (if any). Note that these bodies could be nil.
27
+ def branches
28
+ bodies = resbody_branches.map(&:body)
29
+ bodies.push(else_branch) if else?
30
+ bodies
31
+ end
32
+
33
+ # Returns the else branch of the exception handling statement, if any.
34
+ #
35
+ # @return [Node] the else branch node of the exception handling statement
36
+ # @return [nil] if the exception handling statement does not have an else branch.
37
+ def else_branch
38
+ node_parts[-1]
39
+ end
40
+
41
+ # Checks whether this exception handling statement has an `else` branch.
42
+ #
43
+ # @return [Boolean] whether the exception handling statement has an `else` branch
44
+ def else?
45
+ loc.else
46
+ end
47
+ end
48
+ end
49
+ end
@@ -205,7 +205,7 @@ module RuboCop
205
205
 
206
206
  def initialize(str, root = 'node0', node_var = root)
207
207
  @string = str
208
- # For def_node_pattern, root == node_var
208
+ # For def_node_matcher, root == node_var
209
209
  # For def_node_search, root is the root node to search on,
210
210
  # and node_var is the current descendant being searched.
211
211
  @root = root
@@ -159,6 +159,20 @@ module RuboCop
159
159
  .length
160
160
  end
161
161
 
162
+ def tokens_within(range_or_node)
163
+ begin_index = first_token_index(range_or_node)
164
+ end_index = last_token_index(range_or_node)
165
+ sorted_tokens[begin_index..end_index]
166
+ end
167
+
168
+ def first_token_of(range_or_node)
169
+ sorted_tokens[first_token_index(range_or_node)]
170
+ end
171
+
172
+ def last_token_of(range_or_node)
173
+ sorted_tokens[last_token_index(range_or_node)]
174
+ end
175
+
162
176
  private
163
177
 
164
178
  def comment_index
@@ -240,6 +254,31 @@ module RuboCop
240
254
  end
241
255
  end
242
256
  end
257
+
258
+ def first_token_index(range_or_node)
259
+ begin_pos = source_range(range_or_node).begin_pos
260
+ sorted_tokens.bsearch_index { |token| token.begin_pos >= begin_pos }
261
+ end
262
+
263
+ def last_token_index(range_or_node)
264
+ end_pos = source_range(range_or_node).end_pos
265
+ sorted_tokens.bsearch_index { |token| token.end_pos >= end_pos }
266
+ end
267
+
268
+ # The tokens list is always sorted by token position, except for cases when heredoc
269
+ # is passed as a method argument. In this case tokens are interleaved by
270
+ # heredoc contents' tokens.
271
+ def sorted_tokens
272
+ @sorted_tokens ||= tokens.sort_by(&:begin_pos)
273
+ end
274
+
275
+ def source_range(range_or_node)
276
+ if range_or_node.respond_to?(:source_range)
277
+ range_or_node.source_range
278
+ else
279
+ range_or_node
280
+ end
281
+ end
243
282
  end
244
283
  end
245
284
  end
@@ -28,7 +28,7 @@ module RuboCop
28
28
  arg_expr pin match_rest if_guard unless_guard
29
29
  match_with_trailing_comma].freeze
30
30
  MANY_CHILD_NODES = %i[dstr dsym xstr regexp array hash pair
31
- mlhs masgn or_asgn and_asgn
31
+ mlhs masgn or_asgn and_asgn rasgn mrasgn
32
32
  undef alias args super yield or and
33
33
  while_post until_post iflipflop eflipflop
34
34
  match_with_lvasgn begin kwbegin return
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module AST
5
5
  module Version
6
- STRING = '0.3.0'
6
+ STRING = '0.4.0'
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-ast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-08-02 00:00:00.000000000 Z
13
+ date: 2020-09-11 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: parser
@@ -60,6 +60,7 @@ files:
60
60
  - lib/rubocop/ast.rb
61
61
  - lib/rubocop/ast/builder.rb
62
62
  - lib/rubocop/ast/ext/range.rb
63
+ - lib/rubocop/ast/ext/set.rb
63
64
  - lib/rubocop/ast/node.rb
64
65
  - lib/rubocop/ast/node/alias_node.rb
65
66
  - lib/rubocop/ast/node/and_node.rb
@@ -70,6 +71,7 @@ files:
70
71
  - lib/rubocop/ast/node/case_match_node.rb
71
72
  - lib/rubocop/ast/node/case_node.rb
72
73
  - lib/rubocop/ast/node/class_node.rb
74
+ - lib/rubocop/ast/node/const_node.rb
73
75
  - lib/rubocop/ast/node/def_node.rb
74
76
  - lib/rubocop/ast/node/defined_node.rb
75
77
  - lib/rubocop/ast/node/ensure_node.rb
@@ -101,6 +103,7 @@ files:
101
103
  - lib/rubocop/ast/node/range_node.rb
102
104
  - lib/rubocop/ast/node/regexp_node.rb
103
105
  - lib/rubocop/ast/node/resbody_node.rb
106
+ - lib/rubocop/ast/node/rescue_node.rb
104
107
  - lib/rubocop/ast/node/return_node.rb
105
108
  - lib/rubocop/ast/node/self_class_node.rb
106
109
  - lib/rubocop/ast/node/send_node.rb