class RuboCop::LSP::Runtime

Runtime for Language Server Protocol of RuboCop. @api private

Attributes

layout_mode[W]
lint_mode[W]
safe_autocorrect[W]

Public Class Methods

new(config_store) click to toggle source
# File lib/rubocop/lsp/runtime.rb, line 21
def initialize(config_store)
  @config_store = config_store
  @logged_paths = []
  @safe_autocorrect = true
  @lint_mode = false
  @layout_mode = false
end

Public Instance Methods

format(path, text, command:) click to toggle source

This abuses the ‘–stdin` option of rubocop and reads the formatted text from the `options` that rubocop mutates. This depends on `parallel: false` as well as the fact that RuboCop doesn’t otherwise dup or reassign that options object. Risky business!

Reassigning ‘options` is done here:

https://github.com/rubocop/rubocop/blob/v1.52.0/lib/rubocop/cop/team.rb#L131

Printing ‘options`

https://github.com/rubocop/rubocop/blob/v1.52.0/lib/rubocop/cli/command/execute_runner.rb#L95

Setting ‘parallel: true` would break this here:

https://github.com/rubocop/rubocop/blob/v1.52.0/lib/rubocop/runner.rb#L72
# File lib/rubocop/lsp/runtime.rb, line 40
def format(path, text, command:)
  safe_autocorrect = if command
                       command == 'rubocop.formatAutocorrects'
                     else
                       @safe_autocorrect
                     end

  formatting_options = {
    stdin: text, force_exclusion: true, autocorrect: true, safe_autocorrect: safe_autocorrect
  }
  formatting_options[:only] = config_only_options if @lint_mode || @layout_mode

  redirect_stdout { run_rubocop(formatting_options, path) }

  formatting_options[:stdin]
end
offenses(path, text) click to toggle source
# File lib/rubocop/lsp/runtime.rb, line 57
def offenses(path, text)
  diagnostic_options = {
    stdin: text, force_exclusion: true, formatters: ['json'], format: 'json'
  }
  diagnostic_options[:only] = config_only_options if @lint_mode || @layout_mode

  json = redirect_stdout { run_rubocop(diagnostic_options, path) }
  results = JSON.parse(json, symbolize_names: true)

  if results[:files].empty?
    unless @logged_paths.include?(path)
      Logger.log "Ignoring file, per configuration: #{path}"
      @logged_paths << path
    end
    return []
  end

  results.dig(:files, 0, :offenses)
end

Private Instance Methods

config_only_options() click to toggle source
# File lib/rubocop/lsp/runtime.rb, line 79
def config_only_options
  only_options = []
  only_options << 'Lint' if @lint_mode
  only_options << 'Layout' if @layout_mode
  only_options
end
redirect_stdout(&block) click to toggle source
# File lib/rubocop/lsp/runtime.rb, line 86
def redirect_stdout(&block)
  stdout = StringIO.new

  RuboCop::Server::Helper.redirect(stdout: stdout, &block)

  stdout.string
end
run_rubocop(options, path) click to toggle source
# File lib/rubocop/lsp/runtime.rb, line 94
def run_rubocop(options, path)
  runner = RuboCop::Runner.new(options, @config_store)

  runner.run([path])
end