standard 0.1.0 → 1.51.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +11 -0
- data/.github/workflows/test.yml +24 -0
- data/.github/workflows/update.yml +54 -0
- data/.gitignore +3 -0
- data/.standard.yml +1 -1
- data/CHANGELOG.md +703 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +71 -37
- data/LICENSE.txt +3 -4
- data/README.md +459 -264
- data/Rakefile +5 -4
- data/bin/console +0 -4
- data/bin/rake +27 -0
- data/bin/run +9 -0
- data/config/base.yml +1065 -193
- data/config/default.yml +8 -0
- data/config/ruby-1.8.yml +10 -2
- data/config/ruby-1.9.yml +11 -1
- data/config/ruby-2.0.yml +4 -0
- data/config/ruby-2.1.yml +4 -0
- data/config/ruby-2.2.yml +13 -5
- data/config/ruby-2.3.yml +10 -0
- data/config/ruby-2.4.yml +10 -0
- data/config/ruby-2.5.yml +10 -0
- data/config/ruby-2.6.yml +13 -0
- data/config/ruby-2.7.yml +10 -0
- data/config/ruby-3.0.yml +13 -0
- data/config/ruby-3.1.yml +11 -0
- data/config/ruby-3.2.yml +4 -0
- data/config/ruby-3.3.yml +7 -0
- data/docs/ARCHITECTURE.md +33 -0
- data/docs/RELEASE.md +41 -0
- data/docs/RUBY_VERSIONS.md +51 -0
- data/docs/UPGRADING.md +31 -0
- data/lib/ruby_lsp/standard/addon.rb +58 -0
- data/lib/ruby_lsp/standard/wraps_built_in_lsp_standardizer.rb +44 -0
- data/lib/standard/base/plugin.rb +69 -0
- data/lib/standard/base.rb +8 -0
- data/lib/standard/builds_config.rb +11 -1
- data/lib/standard/cli.rb +1 -7
- data/lib/standard/creates_config_store/assigns_rubocop_yaml.rb +2 -18
- data/lib/standard/creates_config_store/configures_ignored_paths.rb +2 -2
- data/lib/standard/creates_config_store/merges_user_config_extensions.rb +37 -0
- data/lib/standard/creates_config_store/sets_target_ruby_version.rb +21 -8
- data/lib/standard/creates_config_store.rb +5 -0
- data/lib/standard/formatter.rb +92 -37
- data/lib/standard/loads_runner.rb +17 -3
- data/lib/standard/loads_yaml_config.rb +18 -11
- data/lib/standard/lsp/diagnostic.rb +174 -0
- data/lib/standard/lsp/kills_server.rb +10 -0
- data/lib/standard/lsp/logger.rb +21 -0
- data/lib/standard/lsp/routes.rb +175 -0
- data/lib/standard/lsp/server.rb +37 -0
- data/lib/standard/lsp/standardizer.rb +34 -0
- data/lib/standard/lsp/stdin_rubocop_runner.rb +71 -0
- data/lib/standard/merges_settings.rb +22 -11
- data/lib/standard/plugin/combines_plugin_configs.rb +15 -0
- data/lib/standard/plugin/creates_runner_context.rb +15 -0
- data/lib/standard/plugin/determines_class_constant.rb +56 -0
- data/lib/standard/plugin/initializes_plugins.rb +23 -0
- data/lib/standard/plugin/merges_plugins_into_rubocop_config.rb +177 -0
- data/lib/standard/plugin/standardizes_configured_plugins.rb +37 -0
- data/lib/standard/plugin.rb +11 -0
- data/lib/standard/railtie.rb +1 -1
- data/lib/standard/rake.rb +8 -1
- data/lib/standard/{parses_cli_option.rb → resolves_yaml_option.rb} +9 -2
- data/lib/standard/rubocop/ext.rb +17 -0
- data/lib/standard/runners/genignore.rb +44 -0
- data/lib/standard/runners/help.rb +9 -5
- data/lib/standard/runners/lsp.rb +11 -0
- data/lib/standard/runners/rubocop.rb +14 -18
- data/lib/standard/runners/verbose_version.rb +14 -0
- data/lib/standard/version.rb +1 -1
- data/lib/standard.rb +6 -4
- data/standard.gemspec +22 -20
- metadata +72 -73
- data/.circleci/config.yml +0 -35
- data/lib/standard/cop/semantic_blocks.rb +0 -162
- data/lib/standard/detects_fixability.rb +0 -20
@@ -1,23 +1,36 @@
|
|
1
1
|
class Standard::CreatesConfigStore
|
2
2
|
class SetsTargetRubyVersion
|
3
|
+
# This is minimum version that Rubocop can parse, not the minimum
|
4
|
+
# version it can run on (e.g. TargetRubyVersion). See the following
|
5
|
+
# for more details:
|
6
|
+
#
|
7
|
+
# https://docs.rubocop.org/rubocop/configuration.html#setting-the-target-ruby-version
|
8
|
+
#
|
9
|
+
# https://github.com/rubocop/rubocop/blob/master/lib/rubocop/target_ruby.rb
|
10
|
+
MIN_TARGET_RUBY_VERSION = "2.0"
|
11
|
+
|
3
12
|
def call(options_config, standard_config)
|
4
|
-
options_config["AllCops"]["TargetRubyVersion"] =
|
5
|
-
|
13
|
+
options_config["AllCops"]["TargetRubyVersion"] = normalize_version(
|
14
|
+
min_target_ruby_version_supported(standard_config[:ruby_version])
|
6
15
|
)
|
7
16
|
end
|
8
17
|
|
9
18
|
private
|
10
19
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
|
20
|
+
def min_target_ruby_version_supported(desired_target_ruby_version)
|
21
|
+
return desired_target_ruby_version unless Gem::Version.correct?(desired_target_ruby_version)
|
22
|
+
|
23
|
+
min_target_ruby_version = Gem::Version.new(MIN_TARGET_RUBY_VERSION)
|
24
|
+
if desired_target_ruby_version < min_target_ruby_version
|
25
|
+
min_target_ruby_version
|
15
26
|
else
|
16
|
-
|
27
|
+
desired_target_ruby_version
|
17
28
|
end
|
18
29
|
end
|
19
30
|
|
20
|
-
def
|
31
|
+
def normalize_version(version)
|
32
|
+
return version unless Gem::Version.correct?(version)
|
33
|
+
|
21
34
|
major, minor = version.segments
|
22
35
|
"#{major}.#{minor}".to_f # lol
|
23
36
|
end
|
@@ -3,6 +3,7 @@ require "rubocop"
|
|
3
3
|
require_relative "creates_config_store/assigns_rubocop_yaml"
|
4
4
|
require_relative "creates_config_store/sets_target_ruby_version"
|
5
5
|
require_relative "creates_config_store/configures_ignored_paths"
|
6
|
+
require_relative "creates_config_store/merges_user_config_extensions"
|
6
7
|
|
7
8
|
module Standard
|
8
9
|
class CreatesConfigStore
|
@@ -10,12 +11,16 @@ module Standard
|
|
10
11
|
@assigns_rubocop_yaml = AssignsRubocopYaml.new
|
11
12
|
@sets_target_ruby_version = SetsTargetRubyVersion.new
|
12
13
|
@configures_ignored_paths = ConfiguresIgnoredPaths.new
|
14
|
+
@combines_plugin_configs = Plugin::CombinesPluginConfigs.new
|
15
|
+
@merges_user_config_extensions = MergesUserConfigExtensions.new
|
13
16
|
end
|
14
17
|
|
15
18
|
def call(standard_config)
|
16
19
|
RuboCop::ConfigStore.new.tap do |config_store|
|
17
20
|
options_config = @assigns_rubocop_yaml.call(config_store, standard_config)
|
18
21
|
@sets_target_ruby_version.call(options_config, standard_config)
|
22
|
+
@combines_plugin_configs.call(options_config, standard_config)
|
23
|
+
@merges_user_config_extensions.call(options_config, standard_config)
|
19
24
|
@configures_ignored_paths.call(options_config, standard_config)
|
20
25
|
end
|
21
26
|
end
|
data/lib/standard/formatter.rb
CHANGED
@@ -1,35 +1,42 @@
|
|
1
|
+
require "yaml"
|
1
2
|
require "rubocop"
|
2
|
-
require_relative "detects_fixability"
|
3
3
|
|
4
4
|
module Standard
|
5
5
|
class Formatter < RuboCop::Formatter::BaseFormatter
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def initialize(*args)
|
12
|
-
super
|
13
|
-
@detects_fixability = DetectsFixability.new
|
6
|
+
STANDARD_GREETING = <<~MSG
|
7
|
+
standard: Use Ruby Standard Style (https://github.com/standardrb/standard)
|
8
|
+
MSG
|
9
|
+
|
10
|
+
def started(_target_files)
|
14
11
|
@header_printed_already = false
|
15
|
-
@
|
16
|
-
@
|
12
|
+
@total_correction_count = 0
|
13
|
+
@total_correctable_count = 0
|
14
|
+
@total_uncorrected_count = 0
|
15
|
+
print_todo_warning
|
17
16
|
end
|
18
17
|
|
19
18
|
def file_finished(file, offenses)
|
20
|
-
|
21
|
-
@any_uncorrected_offenses = true
|
19
|
+
track_stats(offenses)
|
22
20
|
|
23
|
-
|
24
|
-
|
21
|
+
if (uncorrected_offenses = offenses.reject(&:corrected?)).any?
|
22
|
+
print_header_once
|
25
23
|
|
26
|
-
|
27
|
-
|
24
|
+
uncorrected_offenses.each do |o|
|
25
|
+
output.printf(" %s:%d:%d: %s\n", path_to(file), o.line, o.real_column, o.message.tr("\n", " "))
|
26
|
+
end
|
28
27
|
end
|
29
28
|
end
|
30
29
|
|
31
|
-
def
|
32
|
-
|
30
|
+
def track_stats(offenses)
|
31
|
+
corrected = offenses.count(&:corrected?)
|
32
|
+
@total_correction_count += corrected
|
33
|
+
@total_correctable_count += offenses.count(&:correctable?) - corrected
|
34
|
+
@total_uncorrected_count += offenses.count - corrected
|
35
|
+
end
|
36
|
+
|
37
|
+
def finished(_inspected_files)
|
38
|
+
print_fix_suggestion
|
39
|
+
print_todo_congratulations
|
33
40
|
end
|
34
41
|
|
35
42
|
private
|
@@ -37,25 +44,48 @@ module Standard
|
|
37
44
|
def print_header_once
|
38
45
|
return if @header_printed_already
|
39
46
|
|
40
|
-
output.print
|
41
|
-
standard: Use Ruby Standard Style (https://github.com/testdouble/standard)
|
42
|
-
HEADER
|
47
|
+
output.print STANDARD_GREETING
|
43
48
|
|
44
49
|
@header_printed_already = true
|
45
50
|
end
|
46
51
|
|
47
|
-
def
|
48
|
-
if
|
49
|
-
|
50
|
-
|
52
|
+
def print_fix_suggestion
|
53
|
+
if (fix_mode = potential_fix_mode)
|
54
|
+
run_mode = determine_run_mode
|
55
|
+
|
56
|
+
command = if run_mode == :rake
|
57
|
+
"rake standard:#{fix_mode}"
|
51
58
|
else
|
52
|
-
"standardrb
|
59
|
+
"standardrb --#{fix_mode.to_s.tr("_", "-")}"
|
53
60
|
end
|
54
61
|
|
55
|
-
output.print
|
56
|
-
|
62
|
+
output.print fixable_error_message(command)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def print_todo_warning
|
67
|
+
todo_file = options[:todo_file]
|
68
|
+
return unless todo_file
|
69
|
+
|
70
|
+
todo_ignore_files = options[:todo_ignore_files]
|
71
|
+
return unless todo_ignore_files&.any?
|
72
|
+
|
73
|
+
output.print <<~HEADER
|
74
|
+
WARNING: this project is being migrated to standard gradually via `#{todo_file}` and is ignoring these files:
|
75
|
+
HEADER
|
76
|
+
|
77
|
+
todo_ignore_files.each do |f|
|
78
|
+
output.printf(" %s\n", f)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def print_todo_congratulations
|
83
|
+
if @total_uncorrected_count == 0 &&
|
84
|
+
options[:todo_file] &&
|
85
|
+
options[:todo_ignore_files]&.none?
|
86
|
+
output.print <<~HEADER
|
87
|
+
Congratulations, you've successfully migrated this project to Standard! Delete `#{options[:todo_file]}` in celebration.
|
57
88
|
HEADER
|
58
|
-
@fix_suggestion_printed_already = true
|
59
89
|
end
|
60
90
|
end
|
61
91
|
|
@@ -63,17 +93,42 @@ module Standard
|
|
63
93
|
Pathname.new(file).relative_path_from(Pathname.new(Dir.pwd))
|
64
94
|
end
|
65
95
|
|
66
|
-
def
|
67
|
-
|
68
|
-
|
96
|
+
def potential_fix_mode
|
97
|
+
return nil unless @total_correctable_count > 0
|
98
|
+
|
99
|
+
if !options[:autocorrect]
|
100
|
+
:fix
|
101
|
+
elsif options[:autocorrect] && options[:safe_autocorrect]
|
102
|
+
:fix_unsafely
|
103
|
+
end
|
69
104
|
end
|
70
105
|
|
71
|
-
def
|
72
|
-
|
106
|
+
def determine_run_mode
|
107
|
+
if File.split($PROGRAM_NAME).last == "rake"
|
108
|
+
:rake
|
109
|
+
else
|
110
|
+
:cli
|
111
|
+
end
|
73
112
|
end
|
74
113
|
|
75
|
-
def
|
76
|
-
|
114
|
+
def fixable_error_message(command)
|
115
|
+
sales_pitch = if !options[:autocorrect]
|
116
|
+
if @total_correctable_count > 1
|
117
|
+
"fix up to #{@total_correctable_count} problems"
|
118
|
+
else
|
119
|
+
"potentially fix one problem"
|
120
|
+
end
|
121
|
+
elsif options[:autocorrect] && options[:safe_autocorrect]
|
122
|
+
if @total_correctable_count > 1
|
123
|
+
"DANGEROUSLY fix #{@total_correctable_count} problems"
|
124
|
+
else
|
125
|
+
"DANGEROUSLY fix one problem"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
<<~MSG
|
130
|
+
standard: Run `#{command}` to #{sales_pitch}.
|
131
|
+
MSG
|
77
132
|
end
|
78
133
|
end
|
79
134
|
end
|
@@ -1,9 +1,23 @@
|
|
1
|
+
require_relative "runners/rubocop"
|
2
|
+
require_relative "runners/version"
|
3
|
+
require_relative "runners/verbose_version"
|
4
|
+
require_relative "runners/lsp"
|
5
|
+
require_relative "runners/genignore"
|
6
|
+
require_relative "runners/help"
|
7
|
+
|
1
8
|
module Standard
|
2
9
|
class LoadsRunner
|
3
|
-
|
10
|
+
RUNNERS = {
|
11
|
+
rubocop: ::Standard::Runners::Rubocop,
|
12
|
+
version: ::Standard::Runners::Version,
|
13
|
+
verbose_version: ::Standard::Runners::VerboseVersion,
|
14
|
+
lsp: ::Standard::Runners::Lsp,
|
15
|
+
genignore: ::Standard::Runners::Genignore,
|
16
|
+
help: ::Standard::Runners::Help
|
17
|
+
}.freeze
|
18
|
+
|
4
19
|
def call(command)
|
5
|
-
|
6
|
-
::Standard::Runners.const_get(command.to_s.capitalize).new
|
20
|
+
RUNNERS[command].new
|
7
21
|
end
|
8
22
|
end
|
9
23
|
end
|
@@ -1,18 +1,15 @@
|
|
1
1
|
require "yaml"
|
2
2
|
require "pathname"
|
3
3
|
require_relative "file_finder"
|
4
|
-
require_relative "
|
4
|
+
require_relative "resolves_yaml_option"
|
5
5
|
|
6
6
|
module Standard
|
7
7
|
class LoadsYamlConfig
|
8
|
-
def
|
9
|
-
|
10
|
-
|
8
|
+
def call(standard_yaml_path, todo_yaml_path)
|
9
|
+
standard_yaml = load_standard_yaml(standard_yaml_path)
|
10
|
+
todo_yaml = load_standard_yaml(todo_yaml_path)
|
11
11
|
|
12
|
-
|
13
|
-
yaml_path = @parses_cli_option.call(argv, "--config") ||
|
14
|
-
FileFinder.new.call(".standard.yml", search_path)
|
15
|
-
construct_config(yaml_path, load_standard_yaml(yaml_path))
|
12
|
+
construct_config(standard_yaml_path, standard_yaml, todo_yaml_path, todo_yaml)
|
16
13
|
end
|
17
14
|
|
18
15
|
private
|
@@ -25,18 +22,28 @@ module Standard
|
|
25
22
|
end
|
26
23
|
end
|
27
24
|
|
28
|
-
def construct_config(yaml_path, standard_yaml)
|
25
|
+
def construct_config(yaml_path, standard_yaml, todo_path, todo_yaml)
|
29
26
|
{
|
30
|
-
ruby_version:
|
27
|
+
ruby_version: normalized_ruby_version(standard_yaml["ruby_version"]),
|
31
28
|
fix: !!standard_yaml["fix"],
|
32
29
|
format: standard_yaml["format"],
|
33
30
|
parallel: !!standard_yaml["parallel"],
|
34
|
-
ignore: expand_ignore_config(standard_yaml["ignore"]),
|
31
|
+
ignore: expand_ignore_config(standard_yaml["ignore"]) + expand_ignore_config(todo_yaml["ignore"]),
|
35
32
|
default_ignores: standard_yaml.key?("default_ignores") ? !!standard_yaml["default_ignores"] : true,
|
36
33
|
config_root: yaml_path ? Pathname.new(yaml_path).dirname.to_s : nil,
|
34
|
+
todo_file: todo_path,
|
35
|
+
todo_ignore_files: Array(todo_yaml["ignore"]).map { |f| (Hash === f) ? f.keys.first : f },
|
36
|
+
plugins: Array(standard_yaml["plugins"]),
|
37
|
+
extend_config: Array(standard_yaml["extend_config"])
|
37
38
|
}
|
38
39
|
end
|
39
40
|
|
41
|
+
def normalized_ruby_version(version)
|
42
|
+
return version if version && !Gem::Version.correct?(version)
|
43
|
+
|
44
|
+
Gem::Version.new(version || RUBY_VERSION)
|
45
|
+
end
|
46
|
+
|
40
47
|
def expand_ignore_config(ignore_config)
|
41
48
|
arrayify(ignore_config).map { |rule|
|
42
49
|
if rule.is_a?(String)
|
@@ -0,0 +1,174 @@
|
|
1
|
+
module Standard
|
2
|
+
module Lsp
|
3
|
+
class Diagnostic
|
4
|
+
Constant = LanguageServer::Protocol::Constant
|
5
|
+
Interface = LanguageServer::Protocol::Interface
|
6
|
+
|
7
|
+
RUBOCOP_TO_LSP_SEVERITY = {
|
8
|
+
info: Constant::DiagnosticSeverity::HINT,
|
9
|
+
refactor: Constant::DiagnosticSeverity::INFORMATION,
|
10
|
+
convention: Constant::DiagnosticSeverity::INFORMATION,
|
11
|
+
warning: Constant::DiagnosticSeverity::WARNING,
|
12
|
+
error: Constant::DiagnosticSeverity::ERROR,
|
13
|
+
fatal: Constant::DiagnosticSeverity::ERROR
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
def initialize(document_encoding, offense, uri, cop_class)
|
17
|
+
@document_encoding = document_encoding
|
18
|
+
@offense = offense
|
19
|
+
@uri = uri
|
20
|
+
@cop_class = cop_class
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_lsp_code_actions
|
24
|
+
code_actions = []
|
25
|
+
|
26
|
+
code_actions << autocorrect_action if correctable?
|
27
|
+
code_actions << disable_line_action
|
28
|
+
|
29
|
+
code_actions
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_lsp_diagnostic(config)
|
33
|
+
highlighted = @offense.highlighted_area
|
34
|
+
Interface::Diagnostic.new(
|
35
|
+
message: message,
|
36
|
+
source: "Standard Ruby",
|
37
|
+
code: @offense.cop_name,
|
38
|
+
code_description: code_description(config),
|
39
|
+
severity: severity,
|
40
|
+
range: Interface::Range.new(
|
41
|
+
start: Interface::Position.new(
|
42
|
+
line: @offense.line - 1,
|
43
|
+
character: highlighted.begin_pos
|
44
|
+
),
|
45
|
+
end: Interface::Position.new(
|
46
|
+
line: @offense.line - 1,
|
47
|
+
character: highlighted.end_pos
|
48
|
+
)
|
49
|
+
),
|
50
|
+
data: {
|
51
|
+
correctable: correctable?,
|
52
|
+
code_actions: to_lsp_code_actions
|
53
|
+
}
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def message
|
60
|
+
message = @offense.message
|
61
|
+
message += "\n\nThis offense is not auto-correctable.\n" unless correctable?
|
62
|
+
message
|
63
|
+
end
|
64
|
+
|
65
|
+
def severity
|
66
|
+
RUBOCOP_TO_LSP_SEVERITY[@offense.severity.name]
|
67
|
+
end
|
68
|
+
|
69
|
+
def code_description(config)
|
70
|
+
return unless @cop_class
|
71
|
+
|
72
|
+
if (doc_url = @cop_class.documentation_url(config))
|
73
|
+
Interface::CodeDescription.new(href: doc_url)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def autocorrect_action
|
78
|
+
Interface::CodeAction.new(
|
79
|
+
title: "Autocorrect #{@offense.cop_name}",
|
80
|
+
kind: Constant::CodeActionKind::QUICK_FIX,
|
81
|
+
edit: Interface::WorkspaceEdit.new(
|
82
|
+
document_changes: [
|
83
|
+
Interface::TextDocumentEdit.new(
|
84
|
+
text_document: Interface::OptionalVersionedTextDocumentIdentifier.new(
|
85
|
+
uri: ensure_uri_scheme(@uri.to_s).to_s,
|
86
|
+
version: nil
|
87
|
+
),
|
88
|
+
edits: correctable? ? offense_replacements : []
|
89
|
+
)
|
90
|
+
]
|
91
|
+
),
|
92
|
+
is_preferred: true
|
93
|
+
)
|
94
|
+
end
|
95
|
+
|
96
|
+
def offense_replacements
|
97
|
+
@offense.corrector.as_replacements.map do |range, replacement|
|
98
|
+
Interface::TextEdit.new(
|
99
|
+
range: Interface::Range.new(
|
100
|
+
start: Interface::Position.new(line: range.line - 1, character: range.column),
|
101
|
+
end: Interface::Position.new(line: range.last_line - 1, character: range.last_column)
|
102
|
+
),
|
103
|
+
new_text: replacement
|
104
|
+
)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def disable_line_action
|
109
|
+
Interface::CodeAction.new(
|
110
|
+
title: "Disable #{@offense.cop_name} for this line",
|
111
|
+
kind: Constant::CodeActionKind::QUICK_FIX,
|
112
|
+
edit: Interface::WorkspaceEdit.new(
|
113
|
+
document_changes: [
|
114
|
+
Interface::TextDocumentEdit.new(
|
115
|
+
text_document: Interface::OptionalVersionedTextDocumentIdentifier.new(
|
116
|
+
uri: ensure_uri_scheme(@uri.to_s).to_s,
|
117
|
+
version: nil
|
118
|
+
),
|
119
|
+
edits: line_disable_comment
|
120
|
+
)
|
121
|
+
]
|
122
|
+
)
|
123
|
+
)
|
124
|
+
end
|
125
|
+
|
126
|
+
def line_disable_comment
|
127
|
+
new_text = if @offense.source_line.include?(" # standard:disable ")
|
128
|
+
",#{@offense.cop_name}"
|
129
|
+
else
|
130
|
+
" # standard:disable #{@offense.cop_name}"
|
131
|
+
end
|
132
|
+
|
133
|
+
eol = Interface::Position.new(
|
134
|
+
line: @offense.line - 1,
|
135
|
+
character: length_of_line(@offense.source_line)
|
136
|
+
)
|
137
|
+
|
138
|
+
# TODO: fails for multiline strings - may be preferable to use block
|
139
|
+
# comments to disable some offenses
|
140
|
+
inline_comment = Interface::TextEdit.new(
|
141
|
+
range: Interface::Range.new(start: eol, end: eol),
|
142
|
+
new_text: new_text
|
143
|
+
)
|
144
|
+
|
145
|
+
[inline_comment]
|
146
|
+
end
|
147
|
+
|
148
|
+
def length_of_line(line)
|
149
|
+
if @document_encoding == Encoding::UTF_16LE
|
150
|
+
line_length = 0
|
151
|
+
line.codepoints.each do |codepoint|
|
152
|
+
line_length += 1
|
153
|
+
if codepoint > RubyLsp::Document::Scanner::SURROGATE_PAIR_START
|
154
|
+
line_length += 1
|
155
|
+
end
|
156
|
+
end
|
157
|
+
line_length
|
158
|
+
else
|
159
|
+
line.length
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def correctable?
|
164
|
+
!@offense.corrector.nil?
|
165
|
+
end
|
166
|
+
|
167
|
+
def ensure_uri_scheme(uri)
|
168
|
+
uri = URI.parse(uri)
|
169
|
+
uri.scheme = "file" if uri.scheme.nil?
|
170
|
+
uri
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Standard
|
2
|
+
module Lsp
|
3
|
+
class Logger
|
4
|
+
def initialize(prefix: "[server]")
|
5
|
+
@prefix = prefix
|
6
|
+
@puts_onces = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def puts(message)
|
10
|
+
warn [@prefix, message].compact.join(" ")
|
11
|
+
end
|
12
|
+
|
13
|
+
def puts_once(message)
|
14
|
+
return if @puts_onces.include?(message)
|
15
|
+
|
16
|
+
@puts_onces << message
|
17
|
+
puts(message)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|