rubocop-ast 0.3.0 → 0.4.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.
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