rubocop-ast 0.1.0 → 0.4.2

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -5
  3. data/lib/rubocop/ast.rb +5 -1
  4. data/lib/rubocop/ast/builder.rb +5 -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 +63 -8
  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 +4 -23
  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/hash_node.rb +21 -8
  18. data/lib/rubocop/ast/node/if_node.rb +7 -14
  19. data/lib/rubocop/ast/node/index_node.rb +5 -3
  20. data/lib/rubocop/ast/node/indexasgn_node.rb +5 -3
  21. data/lib/rubocop/ast/node/int_node.rb +1 -0
  22. data/lib/rubocop/ast/node/lambda_node.rb +10 -3
  23. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +0 -7
  24. data/lib/rubocop/ast/node/mixin/parameterized_node.rb +55 -0
  25. data/lib/rubocop/ast/node/next_node.rb +12 -0
  26. data/lib/rubocop/ast/node/pair_node.rb +2 -2
  27. data/lib/rubocop/ast/node/resbody_node.rb +21 -0
  28. data/lib/rubocop/ast/node/rescue_node.rb +49 -0
  29. data/lib/rubocop/ast/node/return_node.rb +1 -13
  30. data/lib/rubocop/ast/node/send_node.rb +7 -1
  31. data/lib/rubocop/ast/node/super_node.rb +2 -0
  32. data/lib/rubocop/ast/node/when_node.rb +3 -9
  33. data/lib/rubocop/ast/node/yield_node.rb +2 -0
  34. data/lib/rubocop/ast/node_pattern.rb +99 -86
  35. data/lib/rubocop/ast/processed_source.rb +94 -16
  36. data/lib/rubocop/ast/traversal.rb +2 -2
  37. data/lib/rubocop/ast/version.rb +1 -1
  38. metadata +12 -8
  39. data/lib/rubocop/ast/node/retry_node.rb +0 -17
@@ -71,20 +71,24 @@ module RuboCop
71
71
  Digest::SHA1.hexdigest(@raw_source)
72
72
  end
73
73
 
74
- def each_comment
75
- comments.each { |comment| yield comment }
74
+ # @deprecated Use `comments.each`
75
+ def each_comment(&block)
76
+ comments.each(&block)
76
77
  end
77
78
 
78
- def find_comment
79
- 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)
80
82
  end
81
83
 
82
- def each_token
83
- tokens.each { |token| yield token }
84
+ # @deprecated Use `tokens.each`
85
+ def each_token(&block)
86
+ tokens.each(&block)
84
87
  end
85
88
 
86
- def find_token
87
- tokens.find { |token| yield token }
89
+ # @deprecated Use `tokens.find`
90
+ def find_token(&block)
91
+ tokens.find(&block)
88
92
  end
89
93
 
90
94
  def file_path
@@ -95,12 +99,39 @@ module RuboCop
95
99
  ast.nil?
96
100
  end
97
101
 
98
- def commented?(source_range)
99
- 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]
100
105
  end
101
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.
102
133
  def comments_before_line(line)
103
- comments.select { |c| c.location.line <= line }
134
+ each_comment_in_lines(0..line).to_a
104
135
  end
105
136
 
106
137
  def start_with?(string)
@@ -128,10 +159,26 @@ module RuboCop
128
159
  .length
129
160
  end
130
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
+
131
176
  private
132
177
 
133
- def comment_lines
134
- @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
135
182
  end
136
183
 
137
184
  def parse(source, ruby_version)
@@ -142,6 +189,9 @@ module RuboCop
142
189
  @buffer.source = source
143
190
  rescue EncodingError => e
144
191
  @parser_error = e
192
+ @ast = nil
193
+ @comments = []
194
+ @tokens = []
145
195
  return
146
196
  end
147
197
 
@@ -151,13 +201,15 @@ module RuboCop
151
201
  def tokenize(parser)
152
202
  begin
153
203
  ast, comments, tokens = parser.tokenize(@buffer)
154
-
155
- ast.respond_to?(:complete!) && ast.complete!
204
+ ast ||= nil # force `false` to `nil`, see https://github.com/whitequark/parser/pull/722
156
205
  rescue Parser::SyntaxError
157
206
  # All errors are in diagnostics. No need to handle exception.
207
+ comments = []
208
+ tokens = []
158
209
  end
159
210
 
160
- tokens = tokens.map { |t| Token.from_parser_token(t) } if tokens
211
+ ast&.complete!
212
+ tokens.map! { |t| Token.from_parser_token(t) }
161
213
 
162
214
  [ast, comments, tokens]
163
215
  end
@@ -202,6 +254,32 @@ module RuboCop
202
254
  end
203
255
  end
204
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
+ # Use stable sort.
273
+ @sorted_tokens ||= tokens.sort_by.with_index { |token, i| [token.begin_pos, i] }
274
+ end
275
+
276
+ def source_range(range_or_node)
277
+ if range_or_node.respond_to?(:source_range)
278
+ range_or_node.source_range
279
+ else
280
+ range_or_node
281
+ end
282
+ end
205
283
  end
206
284
  end
207
285
  end
@@ -28,13 +28,13 @@ 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
35
35
  in_match match_alt
36
36
  match_as array_pattern array_pattern_with_tail
37
- hash_pattern const_pattern
37
+ hash_pattern const_pattern find_pattern
38
38
  index indexasgn].freeze
39
39
  SECOND_CHILD_ONLY = %i[lvasgn ivasgn cvasgn gvasgn optarg kwarg
40
40
  kwoptarg].freeze
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module AST
5
5
  module Version
6
- STRING = '0.1.0'
6
+ STRING = '0.4.2'
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.1.0
4
+ version: 0.4.2
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-06-26 00:00:00.000000000 Z
13
+ date: 2020-09-18 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
@@ -94,12 +97,13 @@ files:
94
97
  - lib/rubocop/ast/node/mixin/parameterized_node.rb
95
98
  - lib/rubocop/ast/node/mixin/predicate_operator_node.rb
96
99
  - lib/rubocop/ast/node/module_node.rb
100
+ - lib/rubocop/ast/node/next_node.rb
97
101
  - lib/rubocop/ast/node/or_node.rb
98
102
  - lib/rubocop/ast/node/pair_node.rb
99
103
  - lib/rubocop/ast/node/range_node.rb
100
104
  - lib/rubocop/ast/node/regexp_node.rb
101
105
  - lib/rubocop/ast/node/resbody_node.rb
102
- - lib/rubocop/ast/node/retry_node.rb
106
+ - lib/rubocop/ast/node/rescue_node.rb
103
107
  - lib/rubocop/ast/node/return_node.rb
104
108
  - lib/rubocop/ast/node/self_class_node.rb
105
109
  - lib/rubocop/ast/node/send_node.rb
@@ -125,7 +129,7 @@ metadata:
125
129
  source_code_uri: https://github.com/rubocop-hq/rubocop-ast/
126
130
  documentation_uri: https://docs.rubocop.org/rubocop-ast/
127
131
  bug_tracker_uri: https://github.com/rubocop-hq/rubocop-ast/issues
128
- post_install_message:
132
+ post_install_message:
129
133
  rdoc_options: []
130
134
  require_paths:
131
135
  - lib
@@ -141,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
145
  version: '0'
142
146
  requirements: []
143
147
  rubygems_version: 3.1.2
144
- signing_key:
148
+ signing_key:
145
149
  specification_version: 4
146
150
  summary: RuboCop tools to deal with Ruby code AST.
147
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