solargraph 0.40.3 → 0.42.0
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/.travis.yml +0 -5
- data/CHANGELOG.md +34 -0
- data/README.md +15 -0
- data/SPONSORS.md +1 -0
- data/lib/.rubocop.yml +4 -3
- data/lib/solargraph.rb +8 -7
- data/lib/solargraph/api_map.rb +40 -111
- data/lib/solargraph/api_map/store.rb +5 -0
- data/lib/solargraph/bench.rb +13 -16
- data/lib/solargraph/compat.rb +15 -1
- data/lib/solargraph/diagnostics/rubocop.rb +10 -2
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +18 -0
- data/lib/solargraph/diagnostics/type_check.rb +1 -1
- data/lib/solargraph/language_server/host.rb +108 -7
- data/lib/solargraph/language_server/host/diagnoser.rb +9 -1
- data/lib/solargraph/language_server/host/sources.rb +1 -1
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +1 -0
- data/lib/solargraph/language_server/message/extended/environment.rb +3 -3
- data/lib/solargraph/language_server/message/initialize.rb +37 -35
- data/lib/solargraph/language_server/message/text_document/formatting.rb +28 -7
- data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
- data/lib/solargraph/library.rb +132 -22
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -1
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +11 -12
- data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +1 -6
- data/lib/solargraph/shell.rb +5 -1
- data/lib/solargraph/source.rb +1 -1
- data/lib/solargraph/source/chain/head.rb +0 -16
- data/lib/solargraph/source/source_chainer.rb +1 -0
- data/lib/solargraph/source_map/mapper.rb +0 -5
- data/lib/solargraph/type_checker.rb +2 -2
- data/lib/solargraph/type_checker/checks.rb +4 -4
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace.rb +1 -0
- data/lib/solargraph/workspace/config.rb +4 -3
- data/lib/solargraph/yard_map.rb +41 -39
- data/lib/solargraph/yard_map/core_fills.rb +1 -0
- data/solargraph.gemspec +1 -0
- metadata +16 -2
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'rubocop'
|
4
3
|
require 'stringio'
|
5
4
|
|
6
5
|
module Solargraph
|
@@ -23,6 +22,7 @@ module Solargraph
|
|
23
22
|
# @param _api_map [Solargraph::ApiMap]
|
24
23
|
# @return [Array<Hash>]
|
25
24
|
def diagnose source, _api_map
|
25
|
+
require_rubocop(rubocop_version)
|
26
26
|
options, paths = generate_options(source.filename, source.code)
|
27
27
|
store = RuboCop::ConfigStore.new
|
28
28
|
runner = RuboCop::Runner.new(options, store)
|
@@ -36,6 +36,13 @@ module Solargraph
|
|
36
36
|
|
37
37
|
private
|
38
38
|
|
39
|
+
# Extracts the rubocop version from _args_
|
40
|
+
#
|
41
|
+
# @return [String]
|
42
|
+
def rubocop_version
|
43
|
+
args.find { |a| a =~ /version=/ }.to_s.split('=').last
|
44
|
+
end
|
45
|
+
|
39
46
|
# @param resp [Hash]
|
40
47
|
# @return [Array<Hash>]
|
41
48
|
def make_array resp
|
@@ -57,7 +64,8 @@ module Solargraph
|
|
57
64
|
range: offense_range(off).to_hash,
|
58
65
|
# 1 = Error, 2 = Warning, 3 = Information, 4 = Hint
|
59
66
|
severity: SEVERITIES[off['severity']],
|
60
|
-
source:
|
67
|
+
source: 'rubocop',
|
68
|
+
code: off['cop_name'],
|
61
69
|
message: off['message'].gsub(/^#{off['cop_name']}\:/, '')
|
62
70
|
}
|
63
71
|
end
|
@@ -7,6 +7,24 @@ module Solargraph
|
|
7
7
|
module RubocopHelpers
|
8
8
|
module_function
|
9
9
|
|
10
|
+
# Requires a specific version of rubocop, or the latest installed version
|
11
|
+
# if _version_ is `nil`.
|
12
|
+
#
|
13
|
+
# @param version [String]
|
14
|
+
# @raise [InvalidRubocopVersionError] if _version_ is not installed
|
15
|
+
def require_rubocop(version = nil)
|
16
|
+
begin
|
17
|
+
gem_path = Gem::Specification.find_by_name('rubocop', version).full_gem_path
|
18
|
+
gem_lib_path = File.join(gem_path, 'lib')
|
19
|
+
$LOAD_PATH.unshift(gem_lib_path) unless $LOAD_PATH.include?(gem_lib_path)
|
20
|
+
rescue Gem::MissingSpecVersionError => e
|
21
|
+
raise InvalidRubocopVersionError,
|
22
|
+
"could not find '#{e.name}' (#{e.requirement}) - "\
|
23
|
+
"did find: [#{e.specs.map { |s| s.version.version }.join(', ')}]"
|
24
|
+
end
|
25
|
+
require 'rubocop'
|
26
|
+
end
|
27
|
+
|
10
28
|
# Generate command-line options for the specified filename and code.
|
11
29
|
#
|
12
30
|
# @param filename [String]
|
@@ -7,7 +7,7 @@ module Solargraph
|
|
7
7
|
#
|
8
8
|
class TypeCheck < Base
|
9
9
|
def diagnose source, api_map
|
10
|
-
return [] unless args.include?('always') || api_map.workspaced?(source.filename)
|
10
|
+
# return [] unless args.include?('always') || api_map.workspaced?(source.filename)
|
11
11
|
severity = Diagnostics::Severities::ERROR
|
12
12
|
level = (args.reverse.find { |a| ['normal', 'typed', 'strict', 'strong'].include?(a) }) || :normal
|
13
13
|
checker = Solargraph::TypeChecker.new(source.filename, api_map: api_map, level: level.to_sym)
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'diff/lcs'
|
3
4
|
require 'observer'
|
5
|
+
require 'securerandom'
|
4
6
|
require 'set'
|
5
7
|
|
6
8
|
module Solargraph
|
@@ -106,9 +108,12 @@ module Solargraph
|
|
106
108
|
end
|
107
109
|
message
|
108
110
|
elsif request['id']
|
109
|
-
|
110
|
-
|
111
|
-
|
111
|
+
if requests[request['id']]
|
112
|
+
requests[request['id']].process(request['result'])
|
113
|
+
requests.delete request['id']
|
114
|
+
else
|
115
|
+
logger.warn "Discarding client response to unrecognized message #{request['id']}"
|
116
|
+
end
|
112
117
|
else
|
113
118
|
logger.warn "Invalid message received."
|
114
119
|
logger.debug request
|
@@ -164,8 +169,6 @@ module Solargraph
|
|
164
169
|
# @return [void]
|
165
170
|
def open_from_disk uri
|
166
171
|
sources.open_from_disk(uri)
|
167
|
-
library = library_for(uri)
|
168
|
-
# library.open_from_disk uri_to_file(uri)
|
169
172
|
diagnoser.schedule uri
|
170
173
|
end
|
171
174
|
|
@@ -192,7 +195,7 @@ module Solargraph
|
|
192
195
|
def diagnose uri
|
193
196
|
if sources.include?(uri)
|
194
197
|
library = library_for(uri)
|
195
|
-
if library.synchronized?
|
198
|
+
if library.mapped? && library.synchronized?
|
196
199
|
logger.info "Diagnosing #{uri}"
|
197
200
|
begin
|
198
201
|
results = library.diagnose uri_to_file(uri)
|
@@ -277,6 +280,7 @@ module Solargraph
|
|
277
280
|
begin
|
278
281
|
lib = Solargraph::Library.load(path, name)
|
279
282
|
libraries.push lib
|
283
|
+
async_library_map lib
|
280
284
|
rescue WorkspaceTooLargeError => e
|
281
285
|
send_notification 'window/showMessage', {
|
282
286
|
'type' => Solargraph::LanguageServer::MessageTypes::WARNING,
|
@@ -631,6 +635,7 @@ module Solargraph
|
|
631
635
|
|
632
636
|
# @return [void]
|
633
637
|
def catalog
|
638
|
+
return unless libraries.all?(&:mapped?)
|
634
639
|
libraries.each(&:catalog)
|
635
640
|
end
|
636
641
|
|
@@ -669,7 +674,8 @@ module Solargraph
|
|
669
674
|
# @return [Source::Updater]
|
670
675
|
def generate_updater params
|
671
676
|
changes = []
|
672
|
-
params['contentChanges'].each do |
|
677
|
+
params['contentChanges'].each do |recvd|
|
678
|
+
chng = check_diff(params['textDocument']['uri'], recvd)
|
673
679
|
changes.push Solargraph::Source::Change.new(
|
674
680
|
(chng['range'].nil? ?
|
675
681
|
nil :
|
@@ -685,6 +691,36 @@ module Solargraph
|
|
685
691
|
)
|
686
692
|
end
|
687
693
|
|
694
|
+
# @param uri [String]
|
695
|
+
# @param change [Hash]
|
696
|
+
# @return [Hash]
|
697
|
+
def check_diff uri, change
|
698
|
+
return change if change['range']
|
699
|
+
source = sources.find(uri)
|
700
|
+
return change if source.code.length + 1 != change['text'].length
|
701
|
+
diffs = Diff::LCS.diff(source.code, change['text'])
|
702
|
+
return change if diffs.length.zero? || diffs.length > 1 || diffs.first.length > 1
|
703
|
+
# @type [Diff::LCS::Change]
|
704
|
+
diff = diffs.first.first
|
705
|
+
return change unless diff.adding? && ['.', ':'].include?(diff.element)
|
706
|
+
position = Solargraph::Position.from_offset(source.code, diff.position)
|
707
|
+
{
|
708
|
+
'range' => {
|
709
|
+
'start' => {
|
710
|
+
'line' => position.line,
|
711
|
+
'character' => position.character
|
712
|
+
},
|
713
|
+
'end' => {
|
714
|
+
'line' => position.line,
|
715
|
+
'character' => position.character
|
716
|
+
}
|
717
|
+
},
|
718
|
+
'text' => diff.element
|
719
|
+
}
|
720
|
+
rescue Solargraph::FileNotFoundError
|
721
|
+
change
|
722
|
+
end
|
723
|
+
|
688
724
|
# @return [Hash]
|
689
725
|
def dynamic_capability_options
|
690
726
|
@dynamic_capability_options ||= {
|
@@ -741,6 +777,71 @@ module Solargraph
|
|
741
777
|
def prepare_rename?
|
742
778
|
client_capabilities['rename'] && client_capabilities['rename']['prepareSupport']
|
743
779
|
end
|
780
|
+
|
781
|
+
def client_supports_progress?
|
782
|
+
client_capabilities['window'] && client_capabilities['window']['workDoneProgress']
|
783
|
+
end
|
784
|
+
|
785
|
+
# @param library [Library]
|
786
|
+
# @return [void]
|
787
|
+
def async_library_map library
|
788
|
+
return if library.mapped?
|
789
|
+
Thread.new do
|
790
|
+
if client_supports_progress?
|
791
|
+
uuid = SecureRandom.uuid
|
792
|
+
send_request 'window/workDoneProgress/create', {
|
793
|
+
token: uuid
|
794
|
+
} do |response|
|
795
|
+
do_async_library_map library, response.nil? ? uuid : nil
|
796
|
+
end
|
797
|
+
else
|
798
|
+
do_async_library_map library
|
799
|
+
end
|
800
|
+
end
|
801
|
+
end
|
802
|
+
|
803
|
+
def do_async_library_map library, uuid = nil
|
804
|
+
total = library.workspace.sources.length
|
805
|
+
if uuid
|
806
|
+
send_notification '$/progress', {
|
807
|
+
token: uuid,
|
808
|
+
value: {
|
809
|
+
kind: 'begin',
|
810
|
+
title: "Mapping workspace",
|
811
|
+
message: "0/#{total} files",
|
812
|
+
cancellable: false,
|
813
|
+
percentage: 0
|
814
|
+
}
|
815
|
+
}
|
816
|
+
end
|
817
|
+
pct = 0
|
818
|
+
mod = 10
|
819
|
+
while library.next_map
|
820
|
+
next unless uuid
|
821
|
+
cur = ((library.source_map_hash.keys.length.to_f / total.to_f) * 100).to_i
|
822
|
+
if cur > pct && cur % mod == 0
|
823
|
+
pct = cur
|
824
|
+
send_notification '$/progress', {
|
825
|
+
token: uuid,
|
826
|
+
value: {
|
827
|
+
kind: 'report',
|
828
|
+
cancellable: false,
|
829
|
+
message: "#{library.source_map_hash.keys.length}/#{total} files",
|
830
|
+
percentage: pct
|
831
|
+
}
|
832
|
+
}
|
833
|
+
end
|
834
|
+
end
|
835
|
+
if uuid
|
836
|
+
send_notification '$/progress', {
|
837
|
+
token: uuid,
|
838
|
+
value: {
|
839
|
+
kind: 'end',
|
840
|
+
message: 'Mapping complete'
|
841
|
+
}
|
842
|
+
}
|
843
|
+
end
|
844
|
+
end
|
744
845
|
end
|
745
846
|
end
|
746
847
|
end
|
@@ -62,7 +62,15 @@ module Solargraph
|
|
62
62
|
end
|
63
63
|
current = mutex.synchronize { queue.shift }
|
64
64
|
return if queue.include?(current)
|
65
|
-
|
65
|
+
begin
|
66
|
+
host.diagnose current
|
67
|
+
rescue InvalidOffsetError
|
68
|
+
# @todo This error can occur when the Source is out of sync with
|
69
|
+
# with the ApiMap. It's probably not the best way to handle it,
|
70
|
+
# but it's quick and easy.
|
71
|
+
Logging.logger.warn "Deferring diagnosis due to invalid offset: #{current}"
|
72
|
+
mutex.synchronize { queue.push current }
|
73
|
+
end
|
66
74
|
end
|
67
75
|
|
68
76
|
private
|
@@ -21,6 +21,7 @@ module Solargraph
|
|
21
21
|
docs = pins
|
22
22
|
.reject { |pin| pin.documentation.empty? && pin.return_type.undefined? }
|
23
23
|
result = params
|
24
|
+
.transform_keys(&:to_sym)
|
24
25
|
.merge(pins.first.resolve_completion_item)
|
25
26
|
.merge(documentation: markup_content(join_docs(docs)))
|
26
27
|
result[:detail] = pins.first.detail
|
@@ -1,8 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Make sure the environment page can report RuboCop's version
|
4
|
-
require 'rubocop'
|
5
|
-
|
6
3
|
module Solargraph
|
7
4
|
module LanguageServer
|
8
5
|
module Message
|
@@ -12,6 +9,9 @@ module Solargraph
|
|
12
9
|
#
|
13
10
|
class Environment < Base
|
14
11
|
def process
|
12
|
+
# Make sure the environment page can report RuboCop's version
|
13
|
+
require 'rubocop'
|
14
|
+
|
15
15
|
page = Solargraph::Page.new(host.options['viewsPath'])
|
16
16
|
content = page.render('environment', layout: true, locals: { config: host.options, folders: host.folders })
|
17
17
|
set_result(
|
@@ -1,49 +1,44 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'benchmark'
|
4
|
-
|
5
3
|
module Solargraph
|
6
4
|
module LanguageServer
|
7
5
|
module Message
|
8
6
|
class Initialize < Base
|
9
7
|
def process
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
changeNotifications: true
|
27
|
-
}
|
8
|
+
host.configure params['initializationOptions']
|
9
|
+
host.client_capabilities = params['capabilities']
|
10
|
+
if support_workspace_folders?
|
11
|
+
host.prepare_folders params['workspaceFolders']
|
12
|
+
elsif params['rootUri']
|
13
|
+
host.prepare UriHelpers.uri_to_file(params['rootUri'])
|
14
|
+
else
|
15
|
+
host.prepare params['rootPath']
|
16
|
+
end
|
17
|
+
result = {
|
18
|
+
capabilities: {
|
19
|
+
textDocumentSync: 2, # @todo What should this be?
|
20
|
+
workspace: {
|
21
|
+
workspaceFolders: {
|
22
|
+
supported: true,
|
23
|
+
changeNotifications: true
|
28
24
|
}
|
29
25
|
}
|
30
26
|
}
|
31
|
-
result[:capabilities].merge! static_completion unless dynamic_registration_for?('textDocument', 'completion')
|
32
|
-
result[:capabilities].merge! static_signature_help unless dynamic_registration_for?('textDocument', 'signatureHelp')
|
33
|
-
# result[:capabilities].merge! static_on_type_formatting unless dynamic_registration_for?('textDocument', 'onTypeFormatting')
|
34
|
-
result[:capabilities].merge! static_hover unless dynamic_registration_for?('textDocument', 'hover')
|
35
|
-
result[:capabilities].merge! static_document_formatting unless dynamic_registration_for?('textDocument', 'formatting')
|
36
|
-
result[:capabilities].merge! static_document_symbols unless dynamic_registration_for?('textDocument', 'documentSymbol')
|
37
|
-
result[:capabilities].merge! static_definitions unless dynamic_registration_for?('textDocument', 'definition')
|
38
|
-
result[:capabilities].merge! static_rename unless dynamic_registration_for?('textDocument', 'rename')
|
39
|
-
result[:capabilities].merge! static_references unless dynamic_registration_for?('textDocument', 'references')
|
40
|
-
result[:capabilities].merge! static_workspace_symbols unless dynamic_registration_for?('workspace', 'symbol')
|
41
|
-
result[:capabilities].merge! static_folding_range unless dynamic_registration_for?('textDocument', 'foldingRange')
|
42
|
-
# @todo Temporarily disabled
|
43
|
-
# result[:capabilities].merge! static_code_action unless dynamic_registration_for?('textDocument', 'codeAction')
|
44
|
-
set_result result
|
45
27
|
}
|
46
|
-
|
28
|
+
result[:capabilities].merge! static_completion unless dynamic_registration_for?('textDocument', 'completion')
|
29
|
+
result[:capabilities].merge! static_signature_help unless dynamic_registration_for?('textDocument', 'signatureHelp')
|
30
|
+
# result[:capabilities].merge! static_on_type_formatting unless dynamic_registration_for?('textDocument', 'onTypeFormatting')
|
31
|
+
result[:capabilities].merge! static_hover unless dynamic_registration_for?('textDocument', 'hover')
|
32
|
+
result[:capabilities].merge! static_document_formatting unless dynamic_registration_for?('textDocument', 'formatting')
|
33
|
+
result[:capabilities].merge! static_document_symbols unless dynamic_registration_for?('textDocument', 'documentSymbol')
|
34
|
+
result[:capabilities].merge! static_definitions unless dynamic_registration_for?('textDocument', 'definition')
|
35
|
+
result[:capabilities].merge! static_rename unless dynamic_registration_for?('textDocument', 'rename')
|
36
|
+
result[:capabilities].merge! static_references unless dynamic_registration_for?('textDocument', 'references')
|
37
|
+
result[:capabilities].merge! static_workspace_symbols unless dynamic_registration_for?('workspace', 'symbol')
|
38
|
+
result[:capabilities].merge! static_folding_range unless dynamic_registration_for?('textDocument', 'foldingRange')
|
39
|
+
# @todo Temporarily disabled
|
40
|
+
# result[:capabilities].merge! static_code_action unless dynamic_registration_for?('textDocument', 'codeAction')
|
41
|
+
set_result result
|
47
42
|
end
|
48
43
|
|
49
44
|
private
|
@@ -56,6 +51,7 @@ module Solargraph
|
|
56
51
|
end
|
57
52
|
|
58
53
|
def static_completion
|
54
|
+
return {} unless host.options['completion']
|
59
55
|
{
|
60
56
|
completionProvider: {
|
61
57
|
resolveProvider: true,
|
@@ -89,18 +85,21 @@ module Solargraph
|
|
89
85
|
end
|
90
86
|
|
91
87
|
def static_hover
|
88
|
+
return {} unless host.options['hover']
|
92
89
|
{
|
93
90
|
hoverProvider: true
|
94
91
|
}
|
95
92
|
end
|
96
93
|
|
97
94
|
def static_document_formatting
|
95
|
+
return {} unless host.options['formatting']
|
98
96
|
{
|
99
97
|
documentFormattingProvider: true
|
100
98
|
}
|
101
99
|
end
|
102
100
|
|
103
101
|
def static_document_symbols
|
102
|
+
return {} unless host.options['symbols']
|
104
103
|
{
|
105
104
|
documentSymbolProvider: true
|
106
105
|
}
|
@@ -113,6 +112,7 @@ module Solargraph
|
|
113
112
|
end
|
114
113
|
|
115
114
|
def static_definitions
|
115
|
+
return {} unless host.options['definitions']
|
116
116
|
{
|
117
117
|
definitionProvider: true
|
118
118
|
}
|
@@ -125,12 +125,14 @@ module Solargraph
|
|
125
125
|
end
|
126
126
|
|
127
127
|
def static_references
|
128
|
+
return {} unless host.options['references']
|
128
129
|
{
|
129
130
|
referencesProvider: true
|
130
131
|
}
|
131
132
|
end
|
132
133
|
|
133
134
|
def static_folding_range
|
135
|
+
return {} unless host.options['folding']
|
134
136
|
{
|
135
137
|
foldingRangeProvider: true
|
136
138
|
}
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'rubocop'
|
4
3
|
require 'securerandom'
|
5
4
|
require 'tmpdir'
|
6
5
|
|
@@ -11,21 +10,22 @@ module Solargraph
|
|
11
10
|
class Formatting < Base
|
12
11
|
include Solargraph::Diagnostics::RubocopHelpers
|
13
12
|
|
14
|
-
class BlankRubocopFormatter < ::RuboCop::Formatter::BaseFormatter; end
|
15
|
-
|
16
13
|
def process
|
17
14
|
file_uri = params['textDocument']['uri']
|
18
15
|
config = config_for(file_uri)
|
19
16
|
original = host.read_text(file_uri)
|
20
17
|
args = cli_args(file_uri, config)
|
21
18
|
|
19
|
+
require_rubocop(config['version'])
|
22
20
|
options, paths = RuboCop::Options.new.parse(args)
|
23
21
|
options[:stdin] = original
|
24
|
-
redirect_stdout do
|
22
|
+
corrections = redirect_stdout do
|
25
23
|
RuboCop::Runner.new(options, RuboCop::ConfigStore.new).run(paths)
|
26
24
|
end
|
27
25
|
result = options[:stdin]
|
28
26
|
|
27
|
+
log_corrections(corrections)
|
28
|
+
|
29
29
|
format original, result
|
30
30
|
rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
|
31
31
|
set_error(Solargraph::LanguageServer::ErrorCodes::INTERNAL_ERROR, "[#{e.class}] #{e.message}")
|
@@ -33,6 +33,17 @@ module Solargraph
|
|
33
33
|
|
34
34
|
private
|
35
35
|
|
36
|
+
def log_corrections(corrections)
|
37
|
+
corrections = corrections&.strip
|
38
|
+
return if corrections&.empty?
|
39
|
+
|
40
|
+
Solargraph.logger.info('Formatting result:')
|
41
|
+
corrections.each_line do |line|
|
42
|
+
next if line.strip.empty?
|
43
|
+
Solargraph.logger.info(line.strip)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
36
47
|
def config_for(file_uri)
|
37
48
|
conf = host.formatter_config(file_uri)
|
38
49
|
return {} unless conf.is_a?(Hash)
|
@@ -40,12 +51,12 @@ module Solargraph
|
|
40
51
|
conf['rubocop'] || {}
|
41
52
|
end
|
42
53
|
|
43
|
-
def cli_args
|
54
|
+
def cli_args file_uri, config
|
55
|
+
file = UriHelpers.uri_to_file(file_uri)
|
44
56
|
args = [
|
45
57
|
config['cops'] == 'all' ? '--auto-correct-all' : '--auto-correct',
|
46
58
|
'--cache', 'false',
|
47
|
-
'--format',
|
48
|
-
'TextDocument::Formatting::BlankRubocopFormatter',
|
59
|
+
'--format', formatter_class(config).name,
|
49
60
|
]
|
50
61
|
|
51
62
|
['except', 'only'].each do |arg|
|
@@ -57,6 +68,16 @@ module Solargraph
|
|
57
68
|
args + [file]
|
58
69
|
end
|
59
70
|
|
71
|
+
def formatter_class(config)
|
72
|
+
if self.class.const_defined?('BlankRubocopFormatter')
|
73
|
+
BlankRubocopFormatter
|
74
|
+
else
|
75
|
+
require_rubocop(config['version'])
|
76
|
+
klass = Class.new(::RuboCop::Formatter::BaseFormatter)
|
77
|
+
self.class.const_set 'BlankRubocopFormatter', klass
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
60
81
|
def cop_list(value)
|
61
82
|
value = value.join(',') if value.respond_to?(:join)
|
62
83
|
return nil if value == '' || !value.is_a?(String)
|