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 =
'(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.


22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/rubocop/ast/processed_source.rb', line 22

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


14
15
16
# File 'lib/rubocop/ast/processed_source.rb', line 14

def ast
  @ast
end

#bufferObject (readonly)

Returns the value of attribute buffer


14
15
16
# File 'lib/rubocop/ast/processed_source.rb', line 14

def buffer
  @buffer
end

#commentsObject (readonly)

Returns the value of attribute comments


14
15
16
# File 'lib/rubocop/ast/processed_source.rb', line 14

def comments
  @comments
end

#diagnosticsObject (readonly)

Returns the value of attribute diagnostics


14
15
16
# File 'lib/rubocop/ast/processed_source.rb', line 14

def diagnostics
  @diagnostics
end

#parser_errorObject (readonly)

Returns the value of attribute parser_error


14
15
16
# File 'lib/rubocop/ast/processed_source.rb', line 14

def parser_error
  @parser_error
end

#pathObject (readonly)

Returns the value of attribute path


14
15
16
# File 'lib/rubocop/ast/processed_source.rb', line 14

def path
  @path
end

#raw_sourceObject (readonly)

Returns the value of attribute raw_source


14
15
16
# File 'lib/rubocop/ast/processed_source.rb', line 14

def raw_source
  @raw_source
end

#ruby_versionObject (readonly)

Returns the value of attribute ruby_version


14
15
16
# File 'lib/rubocop/ast/processed_source.rb', line 14

def ruby_version
  @ruby_version
end

#tokensObject (readonly)

Returns the value of attribute tokens


14
15
16
# File 'lib/rubocop/ast/processed_source.rb', line 14

def tokens
  @tokens
end

Class Method Details

.from_file(path, ruby_version) ⇒ Object


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

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

Instance Method Details

#[](*args) ⇒ Object


59
60
61
# File 'lib/rubocop/ast/processed_source.rb', line 59

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

#ast_with_commentsObject


37
38
39
40
41
# File 'lib/rubocop/ast/processed_source.rb', line 37

def ast_with_comments
  return if !ast || !comments

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

#blank?Boolean

Returns:

  • (Boolean)

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

def blank?
  ast.nil?
end

#checksumObject

Raw source checksum for tracking infinite loops.


70
71
72
# File 'lib/rubocop/ast/processed_source.rb', line 70

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.


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

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.


133
134
135
# File 'lib/rubocop/ast/processed_source.rb', line 133

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.


125
126
127
# File 'lib/rubocop/ast/processed_source.rb', line 125

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

#current_line(token) ⇒ Object


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

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

#each_comment(&block) ⇒ Object

Deprecated.

Use `comments.each`


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

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`


113
114
115
116
117
118
119
120
121
# File 'lib/rubocop/ast/processed_source.rb', line 113

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`


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

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

#file_pathObject


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

def file_path
  buffer.name
end

#find_comment(&block) ⇒ Object

Deprecated.

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


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

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

#find_token(&block) ⇒ Object

Deprecated.

Use `tokens.find`


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

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

#first_token_of(range_or_node) ⇒ Object


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

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

#following_line(token) ⇒ Object


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

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

#last_token_of(range_or_node) ⇒ Object


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

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

#line_indentation(line_number) ⇒ Object


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

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.


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

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.


45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/rubocop/ast/processed_source.rb', line 45

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


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

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

#start_with?(string) ⇒ Boolean

Returns:

  • (Boolean)

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

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

  self[0].start_with?(string)
end

#tokens_within(range_or_node) ⇒ Object


162
163
164
165
166
# File 'lib/rubocop/ast/processed_source.rb', line 162

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)

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

def valid_syntax?
  return false if @parser_error

  @diagnostics.none? { |d| %i[error fatal].include?(d.level) }
end