solargraph 0.40.4 → 0.41.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/CHANGELOG.md +14 -0
- data/README.md +15 -0
- data/SPONSORS.md +1 -0
- data/lib/.rubocop.yml +1 -1
- data/lib/solargraph.rb +8 -7
- data/lib/solargraph/api_map.rb +52 -75
- data/lib/solargraph/bench.rb +16 -19
- 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/language_server/host.rb +69 -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 +30 -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 +93 -21
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -1
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -1
- data/lib/solargraph/source/chain/head.rb +0 -16
- data/lib/solargraph/source/source_chainer.rb +2 -1
- data/lib/solargraph/source_map/mapper.rb +0 -5
- data/lib/solargraph/type_checker/checks.rb +4 -4
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +4 -3
- data/lib/solargraph/yard_map/core_fills.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eed08215481576c83b9ff5014648c0fa5fe7e458eb59eabcf86632496e4a9f32
|
4
|
+
data.tar.gz: 8f036f65304ecf1401504a84a49bc34ed6d9be97308be8a1e080be884af100fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '024920c42f1f1e37f604b616481bca07b91ec52ed9fd315e6e12a6cc0ab7c0a88ef9ecd827866ab52d66d2f43b679a97c68d3877b88adc5092fc9c2dc2dca5a1'
|
7
|
+
data.tar.gz: 02c6de30fdac85feedbee8e8b3cbd35ea846a9cbb3a5cb8c476053208a63ae5781a45382fcca43e760875f3f5f911675bdec3f8ba318b122ef6ea0c42f735a29
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
## 0.41.0 - May 30, 2021
|
2
|
+
- Chain constant at last double colon with more than two nested namespaces
|
3
|
+
- Fill Integer#times return type (#440)
|
4
|
+
- Validate included modules in type checks (#424)
|
5
|
+
- Faster language server initialization
|
6
|
+
- Server response to initialize is near immediate
|
7
|
+
- Workspace is mapped in a background thread
|
8
|
+
- Supported clients report mapping progress
|
9
|
+
- Log RuboCop corrections at info level (#426)
|
10
|
+
- Allow configuring the version of RuboCop to require (#430)
|
11
|
+
- Fix source of diagnostic (#434)
|
12
|
+
- Fix file argument in RuboCop (#435)
|
13
|
+
- Config ignores directories with .rb extension (#423)
|
14
|
+
|
1
15
|
## 0.40.4 - March 3, 2021
|
2
16
|
- Fix optarg and blockarg ordering
|
3
17
|
- Override specialization for #initialize
|
data/README.md
CHANGED
@@ -79,6 +79,21 @@ Run `bundle install` and use `bundle exec yard gems` to generate the documentati
|
|
79
79
|
|
80
80
|
In order to make sure you're using the correct dependencies, you can start the language server with Bundler. In VS Code, there's a `solargraph.useBundler` option. Other clients will vary, but the command you probably want to run is `bundle exec solargraph socket` or `bundle exec solargraph stdio`.
|
81
81
|
|
82
|
+
### Rubocop Version
|
83
|
+
|
84
|
+
If you have multiple versions of [`rubocop`](https://rubygems.org/gems/rubocop) installed and you would like to choose a version other than the latest to use, this specific version can be configured.
|
85
|
+
|
86
|
+
In `.solargraph.yml`:
|
87
|
+
|
88
|
+
```yaml
|
89
|
+
---
|
90
|
+
reporters:
|
91
|
+
- rubocop:version=0.61.0 # diagnostics
|
92
|
+
formatter:
|
93
|
+
rubocop:
|
94
|
+
version: 0.61.0 # formatting
|
95
|
+
```
|
96
|
+
|
82
97
|
### Integrating Other Editors
|
83
98
|
|
84
99
|
The [language server protocol](https://microsoft.github.io/language-server-protocol/specification) is the recommended way for integrating Solargraph into editors and IDEs. Clients can connect using either stdio or TCP. Language client developers should refer to [https://solargraph.org/guides/language-server](https://solargraph.org/guides/language-server).
|
data/SPONSORS.md
CHANGED
data/lib/.rubocop.yml
CHANGED
data/lib/solargraph.rb
CHANGED
@@ -9,13 +9,14 @@ require 'solargraph/version'
|
|
9
9
|
# static analysis, and language server libraries.
|
10
10
|
#
|
11
11
|
module Solargraph
|
12
|
-
class InvalidOffsetError
|
13
|
-
class DiagnosticsError
|
14
|
-
class FileNotFoundError
|
15
|
-
class SourceNotAvailableError
|
16
|
-
class ComplexTypeError
|
17
|
-
class WorkspaceTooLargeError
|
18
|
-
class BundleNotFoundError
|
12
|
+
class InvalidOffsetError < RangeError; end
|
13
|
+
class DiagnosticsError < RuntimeError; end
|
14
|
+
class FileNotFoundError < RuntimeError; end
|
15
|
+
class SourceNotAvailableError < StandardError; end
|
16
|
+
class ComplexTypeError < StandardError; end
|
17
|
+
class WorkspaceTooLargeError < RuntimeError; end
|
18
|
+
class BundleNotFoundError < StandardError; end
|
19
|
+
class InvalidRubocopVersionError < RuntimeError; end
|
19
20
|
|
20
21
|
autoload :Position, 'solargraph/position'
|
21
22
|
autoload :Range, 'solargraph/range'
|
data/lib/solargraph/api_map.rb
CHANGED
@@ -33,7 +33,12 @@ module Solargraph
|
|
33
33
|
# @param pins [Array<Pin::Base>]
|
34
34
|
# @return [self]
|
35
35
|
def index pins
|
36
|
-
|
36
|
+
# @todo This implementation is incomplete. It should probably create a
|
37
|
+
# Bench.
|
38
|
+
@source_map_hash = {}
|
39
|
+
implicit.clear
|
40
|
+
cache.clear
|
41
|
+
@store = Store.new(yard_map.pins + pins)
|
37
42
|
self
|
38
43
|
end
|
39
44
|
|
@@ -42,97 +47,55 @@ module Solargraph
|
|
42
47
|
# @param source [Source]
|
43
48
|
# @return [self]
|
44
49
|
def map source
|
45
|
-
|
50
|
+
map = Solargraph::SourceMap.map(source)
|
51
|
+
catalog Bench.new(source_maps: [map])
|
46
52
|
self
|
47
53
|
end
|
48
54
|
|
49
|
-
# @param name [String]
|
50
|
-
# @return [YARD::Tags::MacroDirective, nil]
|
51
|
-
def named_macro name
|
52
|
-
store.named_macros[name]
|
53
|
-
end
|
54
|
-
|
55
55
|
# Catalog a bench.
|
56
56
|
#
|
57
57
|
# @param bench [Bench]
|
58
|
-
# @return [self]
|
59
58
|
def catalog bench
|
60
|
-
new_map_hash = {}
|
61
|
-
# Bench always needs to be merged if it adds or removes sources
|
62
|
-
merged = (bench.sources.length == source_map_hash.values.length)
|
63
|
-
bench.sources.each do |source|
|
64
|
-
if source_map_hash.key?(source.filename)
|
65
|
-
if source_map_hash[source.filename].code == source.code &&
|
66
|
-
source_map_hash[source.filename].source.synchronized? &&
|
67
|
-
source.synchronized?
|
68
|
-
new_map_hash[source.filename] = source_map_hash[source.filename]
|
69
|
-
elsif !source.synchronized?
|
70
|
-
new_map_hash[source.filename] = source_map_hash[source.filename]
|
71
|
-
# @todo Smelly instance variable access
|
72
|
-
new_map_hash[source.filename].instance_variable_set(:@source, source)
|
73
|
-
else
|
74
|
-
map = Solargraph::SourceMap.map(source)
|
75
|
-
if source_map_hash[source.filename].try_merge!(map)
|
76
|
-
new_map_hash[source.filename] = source_map_hash[source.filename]
|
77
|
-
else
|
78
|
-
new_map_hash[source.filename] = map
|
79
|
-
merged = false
|
80
|
-
end
|
81
|
-
end
|
82
|
-
else
|
83
|
-
map = Solargraph::SourceMap.map(source)
|
84
|
-
new_map_hash[source.filename] = map
|
85
|
-
merged = false
|
86
|
-
end
|
87
|
-
end
|
88
|
-
return self if bench.pins.empty? && @store && merged
|
89
59
|
implicit.clear
|
60
|
+
@cache.clear
|
61
|
+
@source_map_hash = bench.source_maps.map { |s| [s.filename, s] }.to_h
|
90
62
|
pins = []
|
91
|
-
|
92
|
-
|
93
|
-
|
63
|
+
@required = Set.new
|
64
|
+
local_path_hash.clear
|
65
|
+
source_map_hash.each_value do |map|
|
94
66
|
pins.concat map.pins
|
95
|
-
|
96
|
-
|
97
|
-
pins.concat bench.pins
|
98
|
-
reqs.merge bench.workspace.config.required
|
99
|
-
@required = reqs
|
100
|
-
bench.sources.each do |src|
|
101
|
-
implicit.merge new_map_hash[src.filename].environ
|
67
|
+
@required.merge map.requires.map(&:name)
|
68
|
+
implicit.merge map.environ
|
102
69
|
end
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
else
|
115
|
-
false
|
116
|
-
end
|
117
|
-
end
|
70
|
+
@required.merge implicit.requires
|
71
|
+
external_requires = []
|
72
|
+
@required.each do |req|
|
73
|
+
result = bench.load_paths.find do |path|
|
74
|
+
full = Pathname.new(path).join("#{req}.rb").to_s
|
75
|
+
@source_map_hash.key?(full)
|
76
|
+
end
|
77
|
+
if result
|
78
|
+
local_path_hash[req] = Pathname.new(result).join("#{req}.rb").to_s
|
79
|
+
else
|
80
|
+
external_requires.push req unless result
|
118
81
|
end
|
119
82
|
end
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
new_store = Store.new(yard_map.pins + implicit.pins + pins)
|
125
|
-
@cache.clear
|
126
|
-
@source_map_hash = new_map_hash
|
127
|
-
@store = new_store
|
83
|
+
br = @required.include?('bundler/require') ? bench.gemnames.to_h { |gs| [gs.name, gs] } : {}
|
84
|
+
@required.merge br.keys
|
85
|
+
yard_map.change(external_requires, br, bench.gemnames)
|
86
|
+
@store = Store.new(yard_map.pins + implicit.pins + pins)
|
128
87
|
@unresolved_requires = yard_map.unresolved_requires
|
129
|
-
workspace_filenames.clear
|
130
|
-
workspace_filenames.concat bench.workspace.filenames
|
131
88
|
@rebindable_method_names = nil
|
132
89
|
store.block_pins.each { |blk| blk.rebind(self) }
|
133
90
|
self
|
134
91
|
end
|
135
92
|
|
93
|
+
# @param name [String]
|
94
|
+
# @return [YARD::Tags::MacroDirective, nil]
|
95
|
+
def named_macro name
|
96
|
+
store.named_macros[name]
|
97
|
+
end
|
98
|
+
|
136
99
|
def required
|
137
100
|
@required ||= Set.new
|
138
101
|
end
|
@@ -173,7 +136,10 @@ module Solargraph
|
|
173
136
|
def self.load directory
|
174
137
|
api_map = new
|
175
138
|
workspace = Solargraph::Workspace.new(directory)
|
176
|
-
api_map.catalog Bench.new(workspace: workspace)
|
139
|
+
# api_map.catalog Bench.new(workspace: workspace)
|
140
|
+
library = Library.new(workspace)
|
141
|
+
library.map!
|
142
|
+
api_map.catalog library.bench
|
177
143
|
api_map
|
178
144
|
end
|
179
145
|
|
@@ -531,6 +497,15 @@ module Solargraph
|
|
531
497
|
@yard_map ||= YardMap.new
|
532
498
|
end
|
533
499
|
|
500
|
+
# Check if the host class includes the specified module.
|
501
|
+
#
|
502
|
+
# @param host [String] The class
|
503
|
+
# @param mod [String] The module
|
504
|
+
# @return [Boolean]
|
505
|
+
def type_include?(host, mod)
|
506
|
+
store.get_includes(host).include?(mod)
|
507
|
+
end
|
508
|
+
|
534
509
|
private
|
535
510
|
|
536
511
|
# @return [Array<String>]
|
@@ -544,7 +519,9 @@ module Solargraph
|
|
544
519
|
attr_reader :source_map_hash
|
545
520
|
|
546
521
|
# @return [ApiMap::Store]
|
547
|
-
|
522
|
+
def store
|
523
|
+
@store ||= Store.new
|
524
|
+
end
|
548
525
|
|
549
526
|
# @return [Solargraph::ApiMap::Cache]
|
550
527
|
attr_reader :cache
|
data/lib/solargraph/bench.rb
CHANGED
@@ -1,30 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'set'
|
4
|
+
|
3
5
|
module Solargraph
|
4
|
-
#
|
5
|
-
# ApiMap.
|
6
|
+
# A container of source maps and gem specs to be cataloged in an ApiMap.
|
6
7
|
#
|
7
8
|
class Bench
|
8
|
-
# @return [
|
9
|
-
attr_reader :
|
10
|
-
|
11
|
-
# @return [Array<Source>]
|
12
|
-
attr_reader :opened
|
9
|
+
# @return [Set<SourceMap>]
|
10
|
+
attr_reader :source_maps
|
13
11
|
|
14
|
-
# @return [
|
15
|
-
attr_reader :
|
12
|
+
# @return [Set<String>]
|
13
|
+
attr_reader :load_paths
|
16
14
|
|
17
|
-
# @
|
18
|
-
|
19
|
-
def initialize workspace: Workspace.new, opened: [], pins: []
|
20
|
-
@workspace = workspace
|
21
|
-
@opened = opened
|
22
|
-
@pins = pins
|
23
|
-
end
|
15
|
+
# @return [Set<String>]
|
16
|
+
attr_reader :gemnames
|
24
17
|
|
25
|
-
# @
|
26
|
-
|
27
|
-
|
18
|
+
# @param source_maps [Array<SourceMap>, Set<SourceMap>]
|
19
|
+
# @param load_paths [Array<String>, Set<String>]
|
20
|
+
# @param gemnames [Array<String>, Set<String>]
|
21
|
+
def initialize source_maps: [], load_paths: [], gemnames: []
|
22
|
+
@source_maps = source_maps.to_set
|
23
|
+
@load_paths = load_paths.to_set
|
24
|
+
@gemnames = gemnames.to_set
|
28
25
|
end
|
29
26
|
end
|
30
27
|
end
|
data/lib/solargraph/compat.rb
CHANGED
@@ -1,9 +1,23 @@
|
|
1
|
+
unless Hash.method_defined?(:transform_keys)
|
2
|
+
class Hash
|
3
|
+
def transform_keys &block
|
4
|
+
result = {}
|
5
|
+
each_pair do |k, v|
|
6
|
+
result[block.call(k)] = v
|
7
|
+
end
|
8
|
+
result
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
1
13
|
unless Hash.method_defined?(:transform_values)
|
2
14
|
class Hash
|
3
15
|
def transform_values &block
|
16
|
+
result = {}
|
4
17
|
each_pair do |k, v|
|
5
|
-
|
18
|
+
result[k] = block.call(v)
|
6
19
|
end
|
20
|
+
result
|
7
21
|
end
|
8
22
|
end
|
9
23
|
end
|
@@ -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]
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'observer'
|
4
4
|
require 'set'
|
5
|
+
require 'securerandom'
|
5
6
|
|
6
7
|
module Solargraph
|
7
8
|
module LanguageServer
|
@@ -192,7 +193,7 @@ module Solargraph
|
|
192
193
|
def diagnose uri
|
193
194
|
if sources.include?(uri)
|
194
195
|
library = library_for(uri)
|
195
|
-
if library.synchronized?
|
196
|
+
if library.mapped? && library.synchronized?
|
196
197
|
logger.info "Diagnosing #{uri}"
|
197
198
|
begin
|
198
199
|
results = library.diagnose uri_to_file(uri)
|
@@ -277,6 +278,7 @@ module Solargraph
|
|
277
278
|
begin
|
278
279
|
lib = Solargraph::Library.load(path, name)
|
279
280
|
libraries.push lib
|
281
|
+
async_library_map lib
|
280
282
|
rescue WorkspaceTooLargeError => e
|
281
283
|
send_notification 'window/showMessage', {
|
282
284
|
'type' => Solargraph::LanguageServer::MessageTypes::WARNING,
|
@@ -631,6 +633,7 @@ module Solargraph
|
|
631
633
|
|
632
634
|
# @return [void]
|
633
635
|
def catalog
|
636
|
+
return unless libraries.all?(&:mapped?)
|
634
637
|
libraries.each(&:catalog)
|
635
638
|
end
|
636
639
|
|
@@ -741,6 +744,71 @@ module Solargraph
|
|
741
744
|
def prepare_rename?
|
742
745
|
client_capabilities['rename'] && client_capabilities['rename']['prepareSupport']
|
743
746
|
end
|
747
|
+
|
748
|
+
def client_supports_progress?
|
749
|
+
client_capabilities['window'] && client_capabilities['window']['workDoneProgress']
|
750
|
+
end
|
751
|
+
|
752
|
+
# @param library [Library]
|
753
|
+
# @return [void]
|
754
|
+
def async_library_map library
|
755
|
+
return if library.mapped?
|
756
|
+
Thread.new do
|
757
|
+
if client_supports_progress?
|
758
|
+
uuid = SecureRandom.uuid
|
759
|
+
send_request 'window/workDoneProgress/create', {
|
760
|
+
token: uuid
|
761
|
+
} do |response|
|
762
|
+
do_async_library_map library, response.nil? ? uuid : nil
|
763
|
+
end
|
764
|
+
else
|
765
|
+
do_async_library_map library
|
766
|
+
end
|
767
|
+
end
|
768
|
+
end
|
769
|
+
|
770
|
+
def do_async_library_map library, uuid = nil
|
771
|
+
total = library.workspace.sources.length
|
772
|
+
if uuid
|
773
|
+
send_notification '$/progress', {
|
774
|
+
token: uuid,
|
775
|
+
value: {
|
776
|
+
kind: 'begin',
|
777
|
+
title: "Mapping workspace",
|
778
|
+
message: "0/#{total} files",
|
779
|
+
cancellable: false,
|
780
|
+
percentage: 0
|
781
|
+
}
|
782
|
+
}
|
783
|
+
end
|
784
|
+
pct = 0
|
785
|
+
mod = 10
|
786
|
+
while library.next_map
|
787
|
+
next unless uuid
|
788
|
+
cur = ((library.source_map_hash.keys.length.to_f / total.to_f) * 100).to_i
|
789
|
+
if cur > pct && cur % mod == 0
|
790
|
+
pct = cur
|
791
|
+
send_notification '$/progress', {
|
792
|
+
token: uuid,
|
793
|
+
value: {
|
794
|
+
kind: 'report',
|
795
|
+
cancellable: false,
|
796
|
+
message: "#{library.source_map_hash.keys.length}/#{total} files",
|
797
|
+
percentage: pct
|
798
|
+
}
|
799
|
+
}
|
800
|
+
end
|
801
|
+
end
|
802
|
+
if uuid
|
803
|
+
send_notification '$/progress', {
|
804
|
+
token: uuid,
|
805
|
+
value: {
|
806
|
+
kind: 'end',
|
807
|
+
message: 'Mapping complete'
|
808
|
+
}
|
809
|
+
}
|
810
|
+
end
|
811
|
+
end
|
744
812
|
end
|
745
813
|
end
|
746
814
|
end
|
@@ -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
|
@@ -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)
|
@@ -17,7 +17,7 @@ module Solargraph
|
|
17
17
|
if !this_link.nil? && this_link != last_link
|
18
18
|
parts.push this_link
|
19
19
|
end
|
20
|
-
parts.push pin.detail.gsub(':', '\\:') unless pin.is_a?(Pin::Namespace) || pin.detail.nil?
|
20
|
+
parts.push "`" + pin.detail.gsub(':', '\\:') + "`" unless pin.is_a?(Pin::Namespace) || pin.detail.nil?
|
21
21
|
parts.push pin.documentation unless pin.documentation.nil? || pin.documentation.empty?
|
22
22
|
unless parts.empty?
|
23
23
|
data = parts.join("\n\n")
|
data/lib/solargraph/library.rb
CHANGED
@@ -20,9 +20,7 @@ module Solargraph
|
|
20
20
|
def initialize workspace = Solargraph::Workspace.new, name = nil
|
21
21
|
@workspace = workspace
|
22
22
|
@name = name
|
23
|
-
|
24
|
-
@synchronized = true
|
25
|
-
@catalog_mutex = Mutex.new
|
23
|
+
@synchronized = false
|
26
24
|
end
|
27
25
|
|
28
26
|
def inspect
|
@@ -48,9 +46,13 @@ module Solargraph
|
|
48
46
|
# @return [void]
|
49
47
|
def attach source
|
50
48
|
mutex.synchronize do
|
51
|
-
@
|
49
|
+
if @current && @current.filename != source.filename && source_map_hash.key?(@current.filename) && !workspace.has_file?(@current.filename)
|
50
|
+
source_map_hash.delete @current.filename
|
51
|
+
@synchronized = false
|
52
|
+
end
|
52
53
|
@current = source
|
53
|
-
|
54
|
+
maybe_map @current
|
55
|
+
api_map.catalog bench unless synchronized?
|
54
56
|
end
|
55
57
|
end
|
56
58
|
|
@@ -110,9 +112,9 @@ module Solargraph
|
|
110
112
|
mutex.synchronize do
|
111
113
|
next if File.directory?(filename) || !File.exist?(filename)
|
112
114
|
next unless contain?(filename) || open?(filename) || workspace.would_merge?(filename)
|
113
|
-
@synchronized = false
|
114
115
|
source = Solargraph::Source.load_string(File.read(filename), filename)
|
115
116
|
workspace.merge(source)
|
117
|
+
maybe_map source
|
116
118
|
result = true
|
117
119
|
end
|
118
120
|
result
|
@@ -158,6 +160,8 @@ module Solargraph
|
|
158
160
|
position = Position.new(line, column)
|
159
161
|
cursor = Source::Cursor.new(read(filename), position)
|
160
162
|
api_map.clip(cursor).complete
|
163
|
+
rescue FileNotFoundError => e
|
164
|
+
handle_file_not_found filename, e
|
161
165
|
end
|
162
166
|
|
163
167
|
# Get definition suggestions for the expression at the specified file and
|
@@ -186,6 +190,8 @@ module Solargraph
|
|
186
190
|
else
|
187
191
|
api_map.clip(cursor).define.map { |pin| pin.realize(api_map) }
|
188
192
|
end
|
193
|
+
rescue FileNotFoundError => e
|
194
|
+
handle_file_not_found(filename, e)
|
189
195
|
end
|
190
196
|
|
191
197
|
# Get signature suggestions for the method at the specified file and
|
@@ -260,14 +266,12 @@ module Solargraph
|
|
260
266
|
# @param query [String]
|
261
267
|
# @return [Array<YARD::CodeObjects::Base>]
|
262
268
|
def document query
|
263
|
-
catalog
|
264
269
|
api_map.document query
|
265
270
|
end
|
266
271
|
|
267
272
|
# @param query [String]
|
268
273
|
# @return [Array<String>]
|
269
274
|
def search query
|
270
|
-
catalog
|
271
275
|
api_map.search query
|
272
276
|
end
|
273
277
|
|
@@ -276,7 +280,6 @@ module Solargraph
|
|
276
280
|
# @param query [String]
|
277
281
|
# @return [Array<Pin::Base>]
|
278
282
|
def query_symbols query
|
279
|
-
catalog
|
280
283
|
api_map.query_symbols query
|
281
284
|
end
|
282
285
|
|
@@ -295,10 +298,13 @@ module Solargraph
|
|
295
298
|
# @param path [String]
|
296
299
|
# @return [Array<Solargraph::Pin::Base>]
|
297
300
|
def path_pins path
|
298
|
-
catalog
|
299
301
|
api_map.get_path_suggestions(path)
|
300
302
|
end
|
301
303
|
|
304
|
+
def source_maps
|
305
|
+
source_map_hash.values
|
306
|
+
end
|
307
|
+
|
302
308
|
# Get the current text of a file in the library.
|
303
309
|
#
|
304
310
|
# @param filename [String]
|
@@ -318,7 +324,6 @@ module Solargraph
|
|
318
324
|
# be an option to do so.
|
319
325
|
#
|
320
326
|
return [] unless open?(filename)
|
321
|
-
catalog
|
322
327
|
result = []
|
323
328
|
source = read(filename)
|
324
329
|
repargs = {}
|
@@ -346,7 +351,7 @@ module Solargraph
|
|
346
351
|
#
|
347
352
|
# @return [void]
|
348
353
|
def catalog
|
349
|
-
|
354
|
+
mutex.synchronize do
|
350
355
|
break if synchronized?
|
351
356
|
logger.info "Cataloging #{workspace.directory.empty? ? 'generic workspace' : workspace.directory}"
|
352
357
|
api_map.catalog bench
|
@@ -355,6 +360,16 @@ module Solargraph
|
|
355
360
|
end
|
356
361
|
end
|
357
362
|
|
363
|
+
def bench
|
364
|
+
source_maps = @current ? [@current] : []
|
365
|
+
source_maps.concat source_map_hash.values
|
366
|
+
Bench.new(
|
367
|
+
source_maps: source_maps,
|
368
|
+
load_paths: workspace.require_paths,
|
369
|
+
gemnames: workspace.gemnames
|
370
|
+
)
|
371
|
+
end
|
372
|
+
|
358
373
|
# Get an array of foldable ranges for the specified file.
|
359
374
|
#
|
360
375
|
# @deprecated The library should not need to handle folding ranges. The
|
@@ -381,14 +396,49 @@ module Solargraph
|
|
381
396
|
# @param source [Source]
|
382
397
|
# @return [Boolean] True if the source was merged into the workspace.
|
383
398
|
def merge source
|
399
|
+
Logging.logger.debug "Merging source: #{source.filename}"
|
384
400
|
result = false
|
385
401
|
mutex.synchronize do
|
386
402
|
result = workspace.merge(source)
|
387
|
-
|
403
|
+
maybe_map source
|
388
404
|
end
|
405
|
+
# catalog
|
389
406
|
result
|
390
407
|
end
|
391
408
|
|
409
|
+
def source_map_hash
|
410
|
+
@source_map_hash ||= {}
|
411
|
+
end
|
412
|
+
|
413
|
+
def mapped?
|
414
|
+
(workspace.filenames - source_map_hash.keys).empty?
|
415
|
+
end
|
416
|
+
|
417
|
+
def next_map
|
418
|
+
return false if mapped?
|
419
|
+
mutex.synchronize do
|
420
|
+
@synchronized = false
|
421
|
+
src = workspace.sources.find { |s| !source_map_hash.key?(s.filename) }
|
422
|
+
if src
|
423
|
+
Logging.logger.debug "Mapping #{src.filename}"
|
424
|
+
source_map_hash[src.filename] = Solargraph::SourceMap.map(src)
|
425
|
+
else
|
426
|
+
false
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
def map!
|
432
|
+
workspace.sources.each do |src|
|
433
|
+
source_map_hash[src.filename] = Solargraph::SourceMap.map(src)
|
434
|
+
end
|
435
|
+
self
|
436
|
+
end
|
437
|
+
|
438
|
+
def pins
|
439
|
+
@pins ||= []
|
440
|
+
end
|
441
|
+
|
392
442
|
private
|
393
443
|
|
394
444
|
# @return [Mutex]
|
@@ -401,14 +451,6 @@ module Solargraph
|
|
401
451
|
@api_map ||= Solargraph::ApiMap.new
|
402
452
|
end
|
403
453
|
|
404
|
-
# @return [Bench]
|
405
|
-
def bench
|
406
|
-
Bench.new(
|
407
|
-
workspace: workspace,
|
408
|
-
opened: @current ? [@current] : []
|
409
|
-
)
|
410
|
-
end
|
411
|
-
|
412
454
|
# Get the source for an open file or create a new source if the file
|
413
455
|
# exists on disk. Sources created from disk are not added to the open
|
414
456
|
# workspace files, i.e., the version on disk remains the authoritative
|
@@ -422,5 +464,35 @@ module Solargraph
|
|
422
464
|
raise FileNotFoundError, "File not found: #{filename}" unless workspace.has_file?(filename)
|
423
465
|
workspace.source(filename)
|
424
466
|
end
|
467
|
+
|
468
|
+
def handle_file_not_found filename, error
|
469
|
+
if workspace.source(filename)
|
470
|
+
Solargraph.logger.debug "#{filename} is not cataloged in the ApiMap"
|
471
|
+
nil
|
472
|
+
else
|
473
|
+
raise error
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
def maybe_map source
|
478
|
+
if source_map_hash.key?(source.filename)
|
479
|
+
return if source_map_hash[source.filename].code == source.code &&
|
480
|
+
source_map_hash[source.filename].source.synchronized? &&
|
481
|
+
source.synchronized?
|
482
|
+
if source.synchronized?
|
483
|
+
new_map = Solargraph::SourceMap.map(source)
|
484
|
+
unless source_map_hash[source.filename].try_merge!(new_map)
|
485
|
+
source_map_hash[source.filename] = new_map
|
486
|
+
@synchronized = false
|
487
|
+
end
|
488
|
+
else
|
489
|
+
# @todo Smelly instance variable access
|
490
|
+
source_map_hash[source.filename].instance_variable_set(:@source, source)
|
491
|
+
end
|
492
|
+
else
|
493
|
+
source_map_hash[source.filename] = Solargraph::SourceMap.map(source)
|
494
|
+
@synchronized = false
|
495
|
+
end
|
496
|
+
end
|
425
497
|
end
|
426
498
|
end
|
@@ -109,7 +109,6 @@ module Solargraph
|
|
109
109
|
end
|
110
110
|
|
111
111
|
def node_to_argchains node
|
112
|
-
# @todo Process array, splat, argscat
|
113
112
|
return [] unless Parser.is_ast_node?(node)
|
114
113
|
if [:ZARRAY, :ARRAY, :LIST].include?(node.type)
|
115
114
|
node.children[0..-2].map { |c| NodeChainer.chain(c) }
|
@@ -13,22 +13,6 @@ module Solargraph
|
|
13
13
|
# return super_pins(api_map, name_pin) if word == 'super'
|
14
14
|
[]
|
15
15
|
end
|
16
|
-
|
17
|
-
# @todo This is temporary. Chain heads need to handle arguments to
|
18
|
-
# `super`.
|
19
|
-
# def arguments
|
20
|
-
# []
|
21
|
-
# end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
# # @param api_map [ApiMap]
|
26
|
-
# # @param name_pin [Pin::Base]
|
27
|
-
# # @return [Array<Pin::Base>]
|
28
|
-
# def super_pins api_map, name_pin
|
29
|
-
# pins = api_map.get_method_stack(name_pin.namespace, name_pin.name, scope: name_pin.scope)
|
30
|
-
# pins.reject{|p| p.path == name_pin.path}
|
31
|
-
# end
|
32
16
|
end
|
33
17
|
end
|
34
18
|
end
|
@@ -34,6 +34,7 @@ module Solargraph
|
|
34
34
|
# Special handling for files that end with an integer and a period
|
35
35
|
return Chain.new([Chain::Literal.new('Integer'), Chain::UNDEFINED_CALL]) if phrase =~ /^[0-9]+\.$/
|
36
36
|
return Chain.new([Chain::Literal.new('Symbol')]) if phrase.start_with?(':') && !phrase.start_with?('::')
|
37
|
+
return SourceChainer.chain(source, Position.new(position.line, position.character + 1)) if end_of_phrase.strip == '::' && source.code[Position.to_offset(source.code, position)].to_s.match?(/[a-z]/i)
|
37
38
|
begin
|
38
39
|
return Chain.new([]) if phrase.end_with?('..')
|
39
40
|
node = nil
|
@@ -64,7 +65,7 @@ module Solargraph
|
|
64
65
|
elsif end_of_phrase.strip == '::'
|
65
66
|
chain.links.push Chain::UNDEFINED_CONSTANT
|
66
67
|
end
|
67
|
-
elsif chain.links.last.is_a?(Source::Chain::Constant) && end_of_phrase.strip == '::'
|
68
|
+
elsif chain.links.last.is_a?(Source::Chain::Constant) && end_of_phrase.strip == '::'
|
68
69
|
chain.links.push Source::Chain::UNDEFINED_CONSTANT
|
69
70
|
end
|
70
71
|
chain
|
@@ -71,11 +71,6 @@ module Solargraph
|
|
71
71
|
pos = Solargraph::Position.new(comment_position.line + line_num - 1, comment_position.column)
|
72
72
|
process_directive(source_position, pos, d)
|
73
73
|
last_line = line_num + 1
|
74
|
-
# @todo The below call assumes the topmost comment line. The above
|
75
|
-
# process occasionally emits incorrect comment positions due to
|
76
|
-
# blank lines in comment blocks, but at least it processes all the
|
77
|
-
# directives.
|
78
|
-
# process_directive(source_position, comment_position, d)
|
79
74
|
end
|
80
75
|
end
|
81
76
|
|
@@ -75,7 +75,7 @@ module Solargraph
|
|
75
75
|
true
|
76
76
|
end
|
77
77
|
|
78
|
-
# @param type [ComplexType]
|
78
|
+
# @param type [ComplexType::UniqueType]
|
79
79
|
# @return [String]
|
80
80
|
def fuzz type
|
81
81
|
if type.parameters?
|
@@ -86,13 +86,13 @@ module Solargraph
|
|
86
86
|
end
|
87
87
|
|
88
88
|
# @param api_map [ApiMap]
|
89
|
-
# @param cls1 [ComplexType]
|
90
|
-
# @param cls2 [ComplexType]
|
89
|
+
# @param cls1 [ComplexType::UniqueType]
|
90
|
+
# @param cls2 [ComplexType::UniqueType]
|
91
91
|
# @return [Boolean]
|
92
92
|
def either_way?(api_map, cls1, cls2)
|
93
93
|
f1 = fuzz(cls1)
|
94
94
|
f2 = fuzz(cls2)
|
95
|
-
api_map.super_and_sub?(f1, f2) || api_map.super_and_sub?(f2, f1)
|
95
|
+
api_map.type_include?(f1, f2) || api_map.super_and_sub?(f1, f2) || api_map.super_and_sub?(f2, f1)
|
96
96
|
end
|
97
97
|
end
|
98
98
|
end
|
data/lib/solargraph/version.rb
CHANGED
@@ -170,9 +170,10 @@ module Solargraph
|
|
170
170
|
# @param globs [Array<String>]
|
171
171
|
# @return [Array<String>]
|
172
172
|
def process_globs globs
|
173
|
-
result =
|
174
|
-
|
175
|
-
|
173
|
+
result = globs.flat_map do |glob|
|
174
|
+
Dir[File.join directory, glob]
|
175
|
+
.map{ |f| f.gsub(/\\/, '/') }
|
176
|
+
.select { |f| File.file?(f) }
|
176
177
|
end
|
177
178
|
result
|
178
179
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solargraph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.41.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Snyder
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backport
|