class Solargraph::Diagnostics::Rubocop

This reporter provides linting through RuboCop.

Constants

SEVERITIES

Conversion of RuboCop severity names to LSP constants

Public Instance Methods

diagnose(source, _api_map) click to toggle source

@param source [Solargraph::Source] @param _api_map [Solargraph::ApiMap] @return [Array<Hash>]

# File lib/solargraph/diagnostics/rubocop.rb, line 25
def diagnose source, _api_map
  @source = source
  require_rubocop(rubocop_version)
  options, paths = generate_options(source.filename, source.code)
  store = RuboCop::ConfigStore.new
  runner = RuboCop::Runner.new(options, store)
  result = redirect_stdout{ runner.run(paths) }
  
  return [] if result.empty?
  
  make_array JSON.parse(result)
rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
  raise DiagnosticsError, "Error in RuboCop configuration: #{e.message}"
rescue JSON::ParserError => e
  raise DiagnosticsError, "RuboCop returned invalid data: #{e.message}"
end

Private Instance Methods

make_array(resp) click to toggle source

@param resp [Hash] @return [Array<Hash>]

# File lib/solargraph/diagnostics/rubocop.rb, line 53
def make_array resp
  diagnostics = []
  resp['files'].each do |file|
    file['offenses'].each do |off|
      diagnostics.push offense_to_diagnostic(off)
    end
  end
  diagnostics
end
offense_ending_position(off) click to toggle source

@param off [Hash] @return [Position]

# File lib/solargraph/diagnostics/rubocop.rb, line 92
def offense_ending_position off
  if off['location']['start_line'] != off['location']['last_line']
    Position.new(off['location']['start_line'], 0)
  else
    start_line = off['location']['start_line'] - 1
    last_column = off['location']['last_column']
    line = @source.code.lines[start_line]
    col_off = if line.nil? || line.empty?
      1
    else
      0
    end

    Position.new(
      start_line, last_column - col_off
    )
  end
end
offense_range(off) click to toggle source

@param off [Hash] @return [Range]

# File lib/solargraph/diagnostics/rubocop.rb, line 80
def offense_range off
  Range.new(offense_start_position(off), offense_ending_position(off))
end
offense_start_position(off) click to toggle source

@param off [Hash] @return [Position]

# File lib/solargraph/diagnostics/rubocop.rb, line 86
def offense_start_position off
  Position.new(off['location']['start_line'] - 1, off['location']['start_column'] - 1)
end
offense_to_diagnostic(off) click to toggle source

Convert a RuboCop offense to an LSP diagnostic

@param off [Hash] Offense received from Rubocop @return [Hash] LSP diagnostic

# File lib/solargraph/diagnostics/rubocop.rb, line 67
def offense_to_diagnostic off
  {
    range: offense_range(off).to_hash,
    # 1 = Error, 2 = Warning, 3 = Information, 4 = Hint
    severity: SEVERITIES[off['severity']],
    source: 'rubocop',
    code: off['cop_name'],
    message: off['message'].gsub(/^#{off['cop_name']}\:/, '')
  }
end
rubocop_version() click to toggle source

Extracts the rubocop version from args

@return [String]

# File lib/solargraph/diagnostics/rubocop.rb, line 47
def rubocop_version
  args.find { |a| a =~ /version=/ }.to_s.split('=').last
end