rubocop-ast 0.0.3 → 0.4.1

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +21 -4
  3. data/lib/rubocop/ast.rb +9 -1
  4. data/lib/rubocop/ast/builder.rb +8 -1
  5. data/lib/rubocop/ast/ext/range.rb +28 -0
  6. data/lib/rubocop/ast/ext/set.rb +12 -0
  7. data/lib/rubocop/ast/node.rb +81 -10
  8. data/lib/rubocop/ast/node/array_node.rb +2 -8
  9. data/lib/rubocop/ast/node/block_node.rb +1 -1
  10. data/lib/rubocop/ast/node/break_node.rb +1 -6
  11. data/lib/rubocop/ast/node/case_match_node.rb +3 -9
  12. data/lib/rubocop/ast/node/case_node.rb +13 -9
  13. data/lib/rubocop/ast/node/const_node.rb +65 -0
  14. data/lib/rubocop/ast/node/def_node.rb +5 -24
  15. data/lib/rubocop/ast/node/defined_node.rb +2 -0
  16. data/lib/rubocop/ast/node/float_node.rb +1 -0
  17. data/lib/rubocop/ast/node/forward_args_node.rb +15 -0
  18. data/lib/rubocop/ast/node/hash_node.rb +21 -8
  19. data/lib/rubocop/ast/node/if_node.rb +7 -14
  20. data/lib/rubocop/ast/node/index_node.rb +48 -0
  21. data/lib/rubocop/ast/node/indexasgn_node.rb +50 -0
  22. data/lib/rubocop/ast/node/int_node.rb +1 -0
  23. data/lib/rubocop/ast/node/lambda_node.rb +65 -0
  24. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +2 -8
  25. data/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb +99 -3
  26. data/lib/rubocop/ast/node/mixin/parameterized_node.rb +56 -0
  27. data/lib/rubocop/ast/node/next_node.rb +12 -0
  28. data/lib/rubocop/ast/node/pair_node.rb +2 -2
  29. data/lib/rubocop/ast/node/regexp_node.rb +56 -0
  30. data/lib/rubocop/ast/node/resbody_node.rb +21 -0
  31. data/lib/rubocop/ast/node/rescue_node.rb +49 -0
  32. data/lib/rubocop/ast/node/return_node.rb +1 -13
  33. data/lib/rubocop/ast/node/send_node.rb +9 -2
  34. data/lib/rubocop/ast/node/super_node.rb +2 -0
  35. data/lib/rubocop/ast/node/when_node.rb +3 -9
  36. data/lib/rubocop/ast/node/yield_node.rb +2 -0
  37. data/lib/rubocop/ast/node_pattern.rb +184 -115
  38. data/lib/rubocop/ast/processed_source.rb +98 -16
  39. data/lib/rubocop/ast/traversal.rb +6 -4
  40. data/lib/rubocop/ast/version.rb +1 -1
  41. metadata +16 -9
  42. data/lib/rubocop/ast/node/retry_node.rb +0 -17
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'digest/sha1'
4
4
 
5
+ # rubocop:disable Metrics/ClassLength
5
6
  module RuboCop
6
7
  module AST
7
8
  # ProcessedSource contains objects which are generated by Parser
@@ -70,20 +71,24 @@ module RuboCop
70
71
  Digest::SHA1.hexdigest(@raw_source)
71
72
  end
72
73
 
73
- def each_comment
74
- comments.each { |comment| yield comment }
74
+ # @deprecated Use `comments.each`
75
+ def each_comment(&block)
76
+ comments.each(&block)
75
77
  end
76
78
 
77
- def find_comment
78
- comments.find { |comment| yield comment }
79
+ # @deprecated Use `comment_at_line`, `each_comment_in_lines`, or `comments.find`
80
+ def find_comment(&block)
81
+ comments.find(&block)
79
82
  end
80
83
 
81
- def each_token
82
- tokens.each { |token| yield token }
84
+ # @deprecated Use `tokens.each`
85
+ def each_token(&block)
86
+ tokens.each(&block)
83
87
  end
84
88
 
85
- def find_token
86
- tokens.find { |token| yield token }
89
+ # @deprecated Use `tokens.find`
90
+ def find_token(&block)
91
+ tokens.find(&block)
87
92
  end
88
93
 
89
94
  def file_path
@@ -94,12 +99,39 @@ module RuboCop
94
99
  ast.nil?
95
100
  end
96
101
 
97
- def commented?(source_range)
98
- comment_lines.include?(source_range.line)
102
+ # @return [Comment, nil] the comment at that line, if any.
103
+ def comment_at_line(line)
104
+ comment_index[line]
99
105
  end
100
106
 
107
+ # @return [Boolean] if the given line number has a comment.
108
+ def line_with_comment?(line)
109
+ comment_index.include?(line)
110
+ end
111
+
112
+ # Enumerates on the comments contained with the given `line_range`
113
+ def each_comment_in_lines(line_range)
114
+ return to_enum(:each_comment_in_lines, line_range) unless block_given?
115
+
116
+ line_range.each do |line|
117
+ if (comment = comment_index[line])
118
+ yield comment
119
+ end
120
+ end
121
+ end
122
+
123
+ # @return [Boolean] if any of the lines in the given `source_range` has a comment.
124
+ # Consider using `each_comment_in_lines` instead
125
+ def contains_comment?(source_range)
126
+ each_comment_in_lines(source_range.line..source_range.last_line).any?
127
+ end
128
+ # @deprecated use contains_comment?
129
+ alias commented? contains_comment?
130
+
131
+ # @deprecated Use `each_comment_in_lines`
132
+ # Should have been called `comments_before_or_at_line`. Doubtful it has of any valid use.
101
133
  def comments_before_line(line)
102
- comments.select { |c| c.location.line <= line }
134
+ each_comment_in_lines(0..line).to_a
103
135
  end
104
136
 
105
137
  def start_with?(string)
@@ -127,10 +159,26 @@ module RuboCop
127
159
  .length
128
160
  end
129
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
+
130
176
  private
131
177
 
132
- def comment_lines
133
- @comment_lines ||= comments.map { |c| c.location.line }
178
+ def comment_index
179
+ @comment_index ||= {}.tap do |hash|
180
+ comments.each { |c| hash[c.location.line] = c }
181
+ end
134
182
  end
135
183
 
136
184
  def parse(source, ruby_version)
@@ -141,6 +189,9 @@ module RuboCop
141
189
  @buffer.source = source
142
190
  rescue EncodingError => e
143
191
  @parser_error = e
192
+ @ast = nil
193
+ @comments = []
194
+ @tokens = []
144
195
  return
145
196
  end
146
197
 
@@ -150,13 +201,15 @@ module RuboCop
150
201
  def tokenize(parser)
151
202
  begin
152
203
  ast, comments, tokens = parser.tokenize(@buffer)
153
-
154
- ast.respond_to?(:complete!) && ast.complete!
204
+ ast ||= nil # force `false` to `nil`, see https://github.com/whitequark/parser/pull/722
155
205
  rescue Parser::SyntaxError
156
206
  # All errors are in diagnostics. No need to handle exception.
207
+ comments = []
208
+ tokens = []
157
209
  end
158
210
 
159
- tokens = tokens.map { |t| Token.from_parser_token(t) } if tokens
211
+ ast&.complete!
212
+ tokens.map! { |t| Token.from_parser_token(t) }
160
213
 
161
214
  [ast, comments, tokens]
162
215
  end
@@ -176,6 +229,9 @@ module RuboCop
176
229
  when 2.7
177
230
  require 'parser/ruby27'
178
231
  Parser::Ruby27
232
+ when 2.8
233
+ require 'parser/ruby28'
234
+ Parser::Ruby28
179
235
  else
180
236
  raise ArgumentError,
181
237
  "RuboCop found unknown Ruby version: #{ruby_version.inspect}"
@@ -198,6 +254,32 @@ module RuboCop
198
254
  end
199
255
  end
200
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
201
282
  end
202
283
  end
203
284
  end
285
+ # rubocop:enable Metrics/ClassLength
@@ -19,21 +19,23 @@ module RuboCop
19
19
  rational str sym regopt self lvar
20
20
  ivar cvar gvar nth_ref back_ref cbase
21
21
  arg restarg blockarg shadowarg
22
- kwrestarg zsuper lambda redo retry
22
+ kwrestarg zsuper redo retry
23
23
  forward_args forwarded_args
24
- match_var match_nil_pattern empty_else].freeze
24
+ match_var match_nil_pattern empty_else
25
+ forward_arg lambda procarg0 __ENCODING__].freeze
25
26
  ONE_CHILD_NODE = %i[splat kwsplat block_pass not break next
26
27
  preexe postexe match_current_line defined?
27
28
  arg_expr pin match_rest if_guard unless_guard
28
29
  match_with_trailing_comma].freeze
29
30
  MANY_CHILD_NODES = %i[dstr dsym xstr regexp array hash pair
30
- mlhs masgn or_asgn and_asgn
31
+ mlhs masgn or_asgn and_asgn rasgn mrasgn
31
32
  undef alias args super yield or and
32
33
  while_post until_post iflipflop eflipflop
33
34
  match_with_lvasgn begin kwbegin return
34
35
  in_match match_alt
35
36
  match_as array_pattern array_pattern_with_tail
36
- hash_pattern const_pattern].freeze
37
+ hash_pattern const_pattern find_pattern
38
+ index indexasgn].freeze
37
39
  SECOND_CHILD_ONLY = %i[lvasgn ivasgn cvasgn gvasgn optarg kwarg
38
40
  kwoptarg].freeze
39
41
 
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module AST
5
5
  module Version
6
- STRING = '0.0.3'
6
+ STRING = '0.4.1'
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-ast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
8
8
  - Jonas Arvidsson
9
9
  - Yuji Nakayama
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-05-15 00:00:00.000000000 Z
13
+ date: 2020-09-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: parser
@@ -18,14 +18,14 @@ dependencies:
18
18
  requirements:
19
19
  - - ">="
20
20
  - !ruby/object:Gem::Version
21
- version: 2.7.0.1
21
+ version: 2.7.1.4
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - ">="
27
27
  - !ruby/object:Gem::Version
28
- version: 2.7.0.1
28
+ version: 2.7.1.4
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: bundler
31
31
  requirement: !ruby/object:Gem::Requirement
@@ -59,6 +59,8 @@ files:
59
59
  - lib/rubocop-ast.rb
60
60
  - lib/rubocop/ast.rb
61
61
  - lib/rubocop/ast/builder.rb
62
+ - lib/rubocop/ast/ext/range.rb
63
+ - lib/rubocop/ast/ext/set.rb
62
64
  - lib/rubocop/ast/node.rb
63
65
  - lib/rubocop/ast/node/alias_node.rb
64
66
  - lib/rubocop/ast/node/and_node.rb
@@ -69,6 +71,7 @@ files:
69
71
  - lib/rubocop/ast/node/case_match_node.rb
70
72
  - lib/rubocop/ast/node/case_node.rb
71
73
  - lib/rubocop/ast/node/class_node.rb
74
+ - lib/rubocop/ast/node/const_node.rb
72
75
  - lib/rubocop/ast/node/def_node.rb
73
76
  - lib/rubocop/ast/node/defined_node.rb
74
77
  - lib/rubocop/ast/node/ensure_node.rb
@@ -77,8 +80,11 @@ files:
77
80
  - lib/rubocop/ast/node/forward_args_node.rb
78
81
  - lib/rubocop/ast/node/hash_node.rb
79
82
  - lib/rubocop/ast/node/if_node.rb
83
+ - lib/rubocop/ast/node/index_node.rb
84
+ - lib/rubocop/ast/node/indexasgn_node.rb
80
85
  - lib/rubocop/ast/node/int_node.rb
81
86
  - lib/rubocop/ast/node/keyword_splat_node.rb
87
+ - lib/rubocop/ast/node/lambda_node.rb
82
88
  - lib/rubocop/ast/node/mixin/basic_literal_node.rb
83
89
  - lib/rubocop/ast/node/mixin/binary_operator_node.rb
84
90
  - lib/rubocop/ast/node/mixin/collection_node.rb
@@ -91,12 +97,13 @@ files:
91
97
  - lib/rubocop/ast/node/mixin/parameterized_node.rb
92
98
  - lib/rubocop/ast/node/mixin/predicate_operator_node.rb
93
99
  - lib/rubocop/ast/node/module_node.rb
100
+ - lib/rubocop/ast/node/next_node.rb
94
101
  - lib/rubocop/ast/node/or_node.rb
95
102
  - lib/rubocop/ast/node/pair_node.rb
96
103
  - lib/rubocop/ast/node/range_node.rb
97
104
  - lib/rubocop/ast/node/regexp_node.rb
98
105
  - lib/rubocop/ast/node/resbody_node.rb
99
- - lib/rubocop/ast/node/retry_node.rb
106
+ - lib/rubocop/ast/node/rescue_node.rb
100
107
  - lib/rubocop/ast/node/return_node.rb
101
108
  - lib/rubocop/ast/node/self_class_node.rb
102
109
  - lib/rubocop/ast/node/send_node.rb
@@ -120,9 +127,9 @@ metadata:
120
127
  homepage_uri: https://www.rubocop.org/
121
128
  changelog_uri: https://github.com/rubocop-hq/rubocop-ast/blob/master/CHANGELOG.md
122
129
  source_code_uri: https://github.com/rubocop-hq/rubocop-ast/
123
- documentation_uri: https://docs.rubocop.org/
130
+ documentation_uri: https://docs.rubocop.org/rubocop-ast/
124
131
  bug_tracker_uri: https://github.com/rubocop-hq/rubocop-ast/issues
125
- post_install_message:
132
+ post_install_message:
126
133
  rdoc_options: []
127
134
  require_paths:
128
135
  - lib
@@ -138,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
145
  version: '0'
139
146
  requirements: []
140
147
  rubygems_version: 3.1.2
141
- signing_key:
148
+ signing_key:
142
149
  specification_version: 4
143
150
  summary: RuboCop tools to deal with Ruby code AST.
144
151
  test_files: []
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module AST
5
- # A node extension for `retry` 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 `retry` nodes within RuboCop.
8
- class RetryNode < Node
9
- include MethodDispatchNode
10
- include ParameterizedNode
11
-
12
- def arguments
13
- []
14
- end
15
- end
16
- end
17
- end