Class: RuboCop::AST::ProcessedSource
- Inherits:
-
Object
- Object
- RuboCop::AST::ProcessedSource
- Defined in:
- lib/rubocop/ast/processed_source.rb
Overview
ProcessedSource contains objects which are generated by Parser and other information such as disabled lines for cops. It also provides a convenient way to access source lines.
Constant Summary collapse
- STRING_SOURCE_NAME =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'(string)'
Instance Attribute Summary collapse
-
#ast ⇒ Object
readonly
Returns the value of attribute ast.
-
#buffer ⇒ Object
readonly
Returns the value of attribute buffer.
-
#comments ⇒ Object
readonly
Returns the value of attribute comments.
-
#diagnostics ⇒ Object
readonly
Returns the value of attribute diagnostics.
-
#parser_engine ⇒ Object
readonly
Returns the value of attribute parser_engine.
-
#parser_error ⇒ Object
readonly
Returns the value of attribute parser_error.
-
#path ⇒ Object
readonly
Returns the value of attribute path.
-
#raw_source ⇒ Object
readonly
Returns the value of attribute raw_source.
-
#ruby_version ⇒ Object
readonly
Returns the value of attribute ruby_version.
-
#tokens ⇒ Object
readonly
Returns the value of attribute tokens.
Class Method Summary collapse
Instance Method Summary collapse
- #[](*args) ⇒ Object
- #ast_with_comments ⇒ Object
- #blank? ⇒ Boolean
-
#checksum ⇒ Object
Raw source checksum for tracking infinite loops.
-
#comment_at_line(line) ⇒ Comment?
The comment at that line, if any.
-
#comments_before_line(line) ⇒ Object
deprecated
Deprecated.
Use ‘each_comment_in_lines`
-
#contains_comment?(source_range) ⇒ Boolean
(also: #commented?)
Consider using ‘each_comment_in_lines` instead.
- #current_line(token) ⇒ Object
-
#each_comment(&block) ⇒ Object
deprecated
Deprecated.
Use ‘comments.each`
-
#each_comment_in_lines(line_range) ⇒ Object
Enumerates on the comments contained with the given ‘line_range`.
-
#each_token(&block) ⇒ Object
deprecated
Deprecated.
Use ‘tokens.each`
- #file_path ⇒ Object
-
#find_comment(&block) ⇒ Object
deprecated
Deprecated.
Use ‘comment_at_line`, `each_comment_in_lines`, or `comments.find`
-
#find_token(&block) ⇒ Object
deprecated
Deprecated.
Use ‘tokens.find`
- #first_token_of(range_or_node) ⇒ Object
- #following_line(token) ⇒ Object
-
#initialize(source, ruby_version, path = nil, parser_engine: :parser_whitequark) ⇒ ProcessedSource
constructor
A new instance of ProcessedSource.
- #last_token_of(range_or_node) ⇒ Object
- #line_indentation(line_number) ⇒ Object
-
#line_with_comment?(line) ⇒ Boolean
If the given line number has a comment.
-
#lines ⇒ Object
Returns the source lines, line break characters removed, excluding a possible __END__ and everything that comes after.
- #preceding_line(token) ⇒ Object
-
#sorted_tokens ⇒ Object
The tokens list is always sorted by token position, except for cases when heredoc is passed as a method argument.
- #start_with?(string) ⇒ Boolean
- #tokens_within(range_or_node) ⇒ Object
- #valid_syntax? ⇒ Boolean
Constructor Details
#initialize(source, ruby_version, path = nil, parser_engine: :parser_whitequark) ⇒ ProcessedSource
Returns a new instance of ProcessedSource.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/rubocop/ast/processed_source.rb', line 28 def initialize(source, ruby_version, path = nil, parser_engine: :parser_whitequark) parser_engine = parser_engine.to_sym unless PARSER_ENGINES.include?(parser_engine) raise ArgumentError, 'The keyword argument `parser_engine` accepts `parser_whitequark` ' \ "or `parser_prism`, but `#{parser_engine}` was passed." end # Defaults source encoding to UTF-8, regardless of the encoding it has # been read with, which could be non-utf8 depending on the default # external encoding. (+source).force_encoding(Encoding::UTF_8) unless source.encoding == Encoding::UTF_8 @raw_source = source @path = path @diagnostics = [] @ruby_version = ruby_version @parser_engine = parser_engine @parser_error = nil parse(source, ruby_version, parser_engine) end |
Instance Attribute Details
#ast ⇒ Object (readonly)
Returns the value of attribute ast.
20 21 22 |
# File 'lib/rubocop/ast/processed_source.rb', line 20 def ast @ast end |
#buffer ⇒ Object (readonly)
Returns the value of attribute buffer.
20 21 22 |
# File 'lib/rubocop/ast/processed_source.rb', line 20 def buffer @buffer end |
#comments ⇒ Object (readonly)
Returns the value of attribute comments.
20 21 22 |
# File 'lib/rubocop/ast/processed_source.rb', line 20 def comments @comments end |
#diagnostics ⇒ Object (readonly)
Returns the value of attribute diagnostics.
20 21 22 |
# File 'lib/rubocop/ast/processed_source.rb', line 20 def diagnostics @diagnostics end |
#parser_engine ⇒ Object (readonly)
Returns the value of attribute parser_engine.
20 21 22 |
# File 'lib/rubocop/ast/processed_source.rb', line 20 def parser_engine @parser_engine end |
#parser_error ⇒ Object (readonly)
Returns the value of attribute parser_error.
20 21 22 |
# File 'lib/rubocop/ast/processed_source.rb', line 20 def parser_error @parser_error end |
#path ⇒ Object (readonly)
Returns the value of attribute path.
20 21 22 |
# File 'lib/rubocop/ast/processed_source.rb', line 20 def path @path end |
#raw_source ⇒ Object (readonly)
Returns the value of attribute raw_source.
20 21 22 |
# File 'lib/rubocop/ast/processed_source.rb', line 20 def raw_source @raw_source end |
#ruby_version ⇒ Object (readonly)
Returns the value of attribute ruby_version.
20 21 22 |
# File 'lib/rubocop/ast/processed_source.rb', line 20 def ruby_version @ruby_version end |
#tokens ⇒ Object (readonly)
Returns the value of attribute tokens.
20 21 22 |
# File 'lib/rubocop/ast/processed_source.rb', line 20 def tokens @tokens end |
Class Method Details
.from_file(path, ruby_version, parser_engine: :parser_whitequark) ⇒ Object
23 24 25 26 |
# File 'lib/rubocop/ast/processed_source.rb', line 23 def self.from_file(path, ruby_version, parser_engine: :parser_whitequark) file = File.read(path, mode: 'rb') new(file, ruby_version, path, parser_engine: parser_engine) end |
Instance Method Details
#[](*args) ⇒ Object
72 73 74 |
# File 'lib/rubocop/ast/processed_source.rb', line 72 def [](*args) lines[*args] end |
#ast_with_comments ⇒ Object
50 51 52 53 54 |
# File 'lib/rubocop/ast/processed_source.rb', line 50 def ast_with_comments return if !ast || !comments @ast_with_comments ||= Parser::Source::Comment.associate_by_identity(ast, comments) end |
#blank? ⇒ Boolean
111 112 113 |
# File 'lib/rubocop/ast/processed_source.rb', line 111 def blank? ast.nil? end |
#checksum ⇒ Object
Raw source checksum for tracking infinite loops.
83 84 85 |
# File 'lib/rubocop/ast/processed_source.rb', line 83 def checksum Digest::SHA1.hexdigest(@raw_source) end |
#comment_at_line(line) ⇒ Comment?
Returns the comment at that line, if any.
116 117 118 |
# File 'lib/rubocop/ast/processed_source.rb', line 116 def comment_at_line(line) comment_index[line] end |
#comments_before_line(line) ⇒ Object
Use ‘each_comment_in_lines`
Should have been called ‘comments_before_or_at_line`. Doubtful it has of any valid use.
146 147 148 |
# File 'lib/rubocop/ast/processed_source.rb', line 146 def comments_before_line(line) each_comment_in_lines(0..line).to_a end |
#contains_comment?(source_range) ⇒ Boolean Also known as: commented?
Consider using ‘each_comment_in_lines` instead
138 139 140 |
# File 'lib/rubocop/ast/processed_source.rb', line 138 def contains_comment?(source_range) each_comment_in_lines(source_range.line..source_range.last_line).any? end |
#current_line(token) ⇒ Object
160 161 162 |
# File 'lib/rubocop/ast/processed_source.rb', line 160 def current_line(token) lines[token.line - 1] end |
#each_comment(&block) ⇒ Object
Use ‘comments.each`
88 89 90 |
# File 'lib/rubocop/ast/processed_source.rb', line 88 def each_comment(&block) comments.each(&block) end |
#each_comment_in_lines(line_range) ⇒ Object
Enumerates on the comments contained with the given ‘line_range`
126 127 128 129 130 131 132 133 134 |
# File 'lib/rubocop/ast/processed_source.rb', line 126 def each_comment_in_lines(line_range) return to_enum(:each_comment_in_lines, line_range) unless block_given? line_range.each do |line| if (comment = comment_index[line]) yield comment end end end |
#each_token(&block) ⇒ Object
Use ‘tokens.each`
98 99 100 |
# File 'lib/rubocop/ast/processed_source.rb', line 98 def each_token(&block) tokens.each(&block) end |
#file_path ⇒ Object
107 108 109 |
# File 'lib/rubocop/ast/processed_source.rb', line 107 def file_path buffer.name end |
#find_comment(&block) ⇒ Object
Use ‘comment_at_line`, `each_comment_in_lines`, or `comments.find`
93 94 95 |
# File 'lib/rubocop/ast/processed_source.rb', line 93 def find_comment(&block) comments.find(&block) end |
#find_token(&block) ⇒ Object
Use ‘tokens.find`
103 104 105 |
# File 'lib/rubocop/ast/processed_source.rb', line 103 def find_token(&block) tokens.find(&block) end |
#first_token_of(range_or_node) ⇒ Object
181 182 183 |
# File 'lib/rubocop/ast/processed_source.rb', line 181 def first_token_of(range_or_node) sorted_tokens[first_token_index(range_or_node)] end |
#following_line(token) ⇒ Object
164 165 166 |
# File 'lib/rubocop/ast/processed_source.rb', line 164 def following_line(token) lines[token.line] end |
#last_token_of(range_or_node) ⇒ Object
185 186 187 |
# File 'lib/rubocop/ast/processed_source.rb', line 185 def last_token_of(range_or_node) sorted_tokens[last_token_index(range_or_node)] end |
#line_indentation(line_number) ⇒ Object
168 169 170 171 172 173 |
# File 'lib/rubocop/ast/processed_source.rb', line 168 def line_indentation(line_number) lines[line_number - 1] .match(/^(\s*)/)[1] .to_s .length end |
#line_with_comment?(line) ⇒ Boolean
Returns if the given line number has a comment.
121 122 123 |
# File 'lib/rubocop/ast/processed_source.rb', line 121 def line_with_comment?(line) comment_index.include?(line) end |
#lines ⇒ Object
Returns the source lines, line break characters removed, excluding a possible __END__ and everything that comes after.
58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/rubocop/ast/processed_source.rb', line 58 def lines @lines ||= begin all_lines = @buffer.source_lines last_token_line = tokens.any? ? tokens.last.line : all_lines.size result = [] all_lines.each_with_index do |line, ix| break if ix >= last_token_line && line == '__END__' result << line end result end end |
#preceding_line(token) ⇒ Object
156 157 158 |
# File 'lib/rubocop/ast/processed_source.rb', line 156 def preceding_line(token) lines[token.line - 2] end |
#sorted_tokens ⇒ Object
The tokens list is always sorted by token position, except for cases when heredoc is passed as a method argument. In this case tokens are interleaved by heredoc contents’ tokens.
192 193 194 195 |
# File 'lib/rubocop/ast/processed_source.rb', line 192 def sorted_tokens # Use stable sort. @sorted_tokens ||= tokens.sort_by.with_index { |token, i| [token.begin_pos, i] } end |
#start_with?(string) ⇒ Boolean
150 151 152 153 154 |
# File 'lib/rubocop/ast/processed_source.rb', line 150 def start_with?(string) return false if self[0].nil? self[0].start_with?(string) end |
#tokens_within(range_or_node) ⇒ Object
175 176 177 178 179 |
# File 'lib/rubocop/ast/processed_source.rb', line 175 def tokens_within(range_or_node) begin_index = first_token_index(range_or_node) end_index = last_token_index(range_or_node) sorted_tokens[begin_index..end_index] end |
#valid_syntax? ⇒ Boolean
76 77 78 79 80 |
# File 'lib/rubocop/ast/processed_source.rb', line 76 def valid_syntax? return false if @parser_error @diagnostics.none? { |d| INVALID_LEVELS.include?(d.level) } end |