class RubyLsp::Requests::Support::RuboCopDiagnostic
def autocorrect_action
def autocorrect_action Interface::CodeAction.new( title: "Autocorrect #{@offense.cop_name}", kind: Constant::CodeActionKind::QUICK_FIX, edit: Interface::WorkspaceEdit.new( document_changes: [ Interface::TextDocumentEdit.new( text_document: Interface::OptionalVersionedTextDocumentIdentifier.new( uri: @uri.to_s, version: nil, ), edits: @offense.correctable? ? offense_replacements : [], ), ], ), is_preferred: true, ) end
def code_description
def code_description doc_url = RuboCopRunner.find_cop_by_name(@offense.cop_name)&.documentation_url Interface::CodeDescription.new(href: doc_url) if doc_url end
def disable_line_action
def disable_line_action Interface::CodeAction.new( title: "Disable #{@offense.cop_name} for this line", kind: Constant::CodeActionKind::QUICK_FIX, edit: Interface::WorkspaceEdit.new( document_changes: [ Interface::TextDocumentEdit.new( text_document: Interface::OptionalVersionedTextDocumentIdentifier.new( uri: @uri.to_s, version: nil, ), edits: line_disable_comment, ), ], ), ) end
def initialize(document, offense, uri)
def initialize(document, offense, uri) @document = document @offense = offense @uri = uri end
def length_of_line(line)
def length_of_line(line) if @document.encoding == Constant::PositionEncodingKind::UTF16 line_length = 0 line.codepoints.each do |codepoint| line_length += 1 if codepoint > RubyLsp::Document::Scanner::SURROGATE_PAIR_START line_length += 1 end end line_length else line.length end end
def line_disable_comment
def line_disable_comment new_text = if @offense.source_line.include?(" # rubocop:disable ") ",#{@offense.cop_name}" else " # rubocop:disable #{@offense.cop_name}" end eol = Interface::Position.new( line: @offense.line - 1, character: length_of_line(@offense.source_line), ) # TODO: fails for multiline strings - may be preferable to use block # comments to disable some offenses inline_comment = Interface::TextEdit.new( range: Interface::Range.new(start: eol, end: eol), new_text: new_text, ) [inline_comment] end
def message
def message message = @offense.message message += "\n\nThis offense is not auto-correctable.\n" unless @offense.correctable? message end
def offense_replacements
def offense_replacements @offense.corrector.as_replacements.map do |range, replacement| Interface::TextEdit.new( range: Interface::Range.new( start: Interface::Position.new(line: range.line - 1, character: range.column), end: Interface::Position.new(line: range.last_line - 1, character: range.last_column), ), new_text: replacement, ) end end
def severity
def severity RUBOCOP_TO_LSP_SEVERITY[@offense.severity.name] end
def to_lsp_code_actions
def to_lsp_code_actions code_actions = [] code_actions << autocorrect_action if @offense.correctable? code_actions << disable_line_action code_actions end
def to_lsp_diagnostic
def to_lsp_diagnostic Interface::Diagnostic.new( message: message, source: "RuboCop", code: @offense.cop_name, code_description: code_description, severity: severity, range: Interface::Range.new( start: Interface::Position.new( line: @offense.line - 1, character: @offense.column, ), end: Interface::Position.new( line: @offense.last_line - 1, character: @offense.last_column, ), ), data: { correctable: @offense.correctable?, code_actions: to_lsp_code_actions, }, ) end