Class: RuboCop::AST::ProcessedSource

Inherits:
Object
  • Object
show all
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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source, ruby_version, path = nil) ⇒ ProcessedSource

Returns a new instance of ProcessedSource.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/rubocop/ast/processed_source.rb', line 26

def initialize(source, ruby_version, path = nil)
  # 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_error = nil

  parse(source, ruby_version)
end

Instance Attribute Details

#astObject (readonly)

Returns the value of attribute ast.



18
19
20
# File 'lib/rubocop/ast/processed_source.rb', line 18

def ast
  @ast
end

#bufferObject (readonly)

Returns the value of attribute buffer.



18
19
20
# File 'lib/rubocop/ast/processed_source.rb', line 18

def buffer
  @buffer
end

#commentsObject (readonly)

Returns the value of attribute comments.



18
19
20
# File 'lib/rubocop/ast/processed_source.rb', line 18

def comments
  @comments
end

#diagnosticsObject (readonly)

Returns the value of attribute diagnostics.



18
19
20
# File 'lib/rubocop/ast/processed_source.rb', line 18

def diagnostics
  @diagnostics
end

#parser_errorObject (readonly)

Returns the value of attribute parser_error.



18
19
20
# File 'lib/rubocop/ast/processed_source.rb', line 18

def parser_error
  @parser_error
end

#pathObject (readonly)

Returns the value of attribute path.



18
19
20
# File 'lib/rubocop/ast/processed_source.rb', line 18

def path
  @path
end

#raw_sourceObject (readonly)

Returns the value of attribute raw_source.



18
19
20
# File 'lib/rubocop/ast/processed_source.rb', line 18

def raw_source
  @raw_source
end

#ruby_versionObject (readonly)

Returns the value of attribute ruby_version.



18
19
20
# File 'lib/rubocop/ast/processed_source.rb', line 18

def ruby_version
  @ruby_version
end

#tokensObject (readonly)

Returns the value of attribute tokens.



18
19
20
# File 'lib/rubocop/ast/processed_source.rb', line 18

def tokens
  @tokens
end

Class Method Details

.from_file(path, ruby_version) ⇒ Object



21
22
23
24
# File 'lib/rubocop/ast/processed_source.rb', line 21

def self.from_file(path, ruby_version)
  file = File.read(path, mode: 'rb')
  new(file, ruby_version, path)
end

Instance Method Details

#[](*args) ⇒ Object



63
64
65
# File 'lib/rubocop/ast/processed_source.rb', line 63

def [](*args)
  lines[*args]
end

#ast_with_commentsObject



41
42
43
44
45
# File 'lib/rubocop/ast/processed_source.rb', line 41

def ast_with_comments
  return if !ast || !comments

  @ast_with_comments ||= Parser::Source::Comment.associate_by_identity(ast, comments)
end

#blank?Boolean

Returns:

  • (Boolean)


102
103
104
# File 'lib/rubocop/ast/processed_source.rb', line 102

def blank?
  ast.nil?
end

#checksumObject

Raw source checksum for tracking infinite loops.



74
75
76
# File 'lib/rubocop/ast/processed_source.rb', line 74

def checksum
  Digest::SHA1.hexdigest(@raw_source)
end

#comment_at_line(line) ⇒ Comment?

Returns the comment at that line, if any.

Returns:

  • (Comment, nil)

    the comment at that line, if any.



107
108
109
# File 'lib/rubocop/ast/processed_source.rb', line 107

def comment_at_line(line)
  comment_index[line]
end

#comments_before_line(line) ⇒ Object

Deprecated.

Use ‘each_comment_in_lines`

Should have been called ‘comments_before_or_at_line`. Doubtful it has of any valid use.



137
138
139
# File 'lib/rubocop/ast/processed_source.rb', line 137

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

Returns:

  • (Boolean)

    if any of the lines in the given ‘source_range` has a comment.



129
130
131
# File 'lib/rubocop/ast/processed_source.rb', line 129

def contains_comment?(source_range)
  each_comment_in_lines(source_range.line..source_range.last_line).any?
end

#current_line(token) ⇒ Object



151
152
153
# File 'lib/rubocop/ast/processed_source.rb', line 151

def current_line(token)
  lines[token.line - 1]
end

#each_comment(&block) ⇒ Object

Deprecated.

Use ‘comments.each`



79
80
81
# File 'lib/rubocop/ast/processed_source.rb', line 79

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`



117
118
119
120
121
122
123
124
125
# File 'lib/rubocop/ast/processed_source.rb', line 117

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

Deprecated.

Use ‘tokens.each`



89
90
91
# File 'lib/rubocop/ast/processed_source.rb', line 89

def each_token(&block)
  tokens.each(&block)
end

#file_pathObject



98
99
100
# File 'lib/rubocop/ast/processed_source.rb', line 98

def file_path
  buffer.name
end

#find_comment(&block) ⇒ Object

Deprecated.

Use ‘comment_at_line`, `each_comment_in_lines`, or `comments.find`



84
85
86
# File 'lib/rubocop/ast/processed_source.rb', line 84

def find_comment(&block)
  comments.find(&block)
end

#find_token(&block) ⇒ Object

Deprecated.

Use ‘tokens.find`



94
95
96
# File 'lib/rubocop/ast/processed_source.rb', line 94

def find_token(&block)
  tokens.find(&block)
end

#first_token_of(range_or_node) ⇒ Object



172
173
174
# File 'lib/rubocop/ast/processed_source.rb', line 172

def first_token_of(range_or_node)
  sorted_tokens[first_token_index(range_or_node)]
end

#following_line(token) ⇒ Object



155
156
157
# File 'lib/rubocop/ast/processed_source.rb', line 155

def following_line(token)
  lines[token.line]
end

#last_token_of(range_or_node) ⇒ Object



176
177
178
# File 'lib/rubocop/ast/processed_source.rb', line 176

def last_token_of(range_or_node)
  sorted_tokens[last_token_index(range_or_node)]
end

#line_indentation(line_number) ⇒ Object



159
160
161
162
163
164
# File 'lib/rubocop/ast/processed_source.rb', line 159

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.

Returns:

  • (Boolean)

    if the given line number has a comment.



112
113
114
# File 'lib/rubocop/ast/processed_source.rb', line 112

def line_with_comment?(line)
  comment_index.include?(line)
end

#linesObject

Returns the source lines, line break characters removed, excluding a possible __END__ and everything that comes after.



49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/rubocop/ast/processed_source.rb', line 49

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



147
148
149
# File 'lib/rubocop/ast/processed_source.rb', line 147

def preceding_line(token)
  lines[token.line - 2]
end

#sorted_tokensObject

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.



183
184
185
186
# File 'lib/rubocop/ast/processed_source.rb', line 183

def sorted_tokens
  # Use stable sort.
  @sorted_tokens ||= tokens.sort_by.with_index { |token, i| [token.begin_pos, i] }
end

#start_with?(string) ⇒ Boolean

Returns:

  • (Boolean)


141
142
143
144
145
# File 'lib/rubocop/ast/processed_source.rb', line 141

def start_with?(string)
  return false if self[0].nil?

  self[0].start_with?(string)
end

#tokens_within(range_or_node) ⇒ Object



166
167
168
169
170
# File 'lib/rubocop/ast/processed_source.rb', line 166

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

Returns:

  • (Boolean)


67
68
69
70
71
# File 'lib/rubocop/ast/processed_source.rb', line 67

def valid_syntax?
  return false if @parser_error

  @diagnostics.none? { |d| INVALID_LEVELS.include?(d.level) }
end