solargraph 0.52.0 → 0.53.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/.github/workflows/plugins.yml +40 -0
- data/.github/workflows/rspec.yml +1 -3
- data/.github/workflows/typecheck.yml +34 -0
- data/CHANGELOG.md +30 -0
- data/README.md +13 -16
- data/SPONSORS.md +1 -7
- data/lib/solargraph/api_map/cache.rb +59 -21
- data/lib/solargraph/api_map/store.rb +45 -9
- data/lib/solargraph/api_map.rb +152 -93
- data/lib/solargraph/bench.rb +2 -2
- data/lib/solargraph/cache.rb +29 -5
- data/lib/solargraph/complex_type/type_methods.rb +53 -8
- data/lib/solargraph/complex_type/unique_type.rb +149 -59
- data/lib/solargraph/complex_type.rb +62 -9
- data/lib/solargraph/convention.rb +0 -1
- data/lib/solargraph/converters/dd.rb +5 -0
- data/lib/solargraph/converters/dl.rb +3 -0
- data/lib/solargraph/converters/dt.rb +3 -0
- data/lib/solargraph/diagnostics/rubocop.rb +8 -7
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -0
- data/lib/solargraph/diagnostics/type_check.rb +1 -0
- data/lib/solargraph/diagnostics.rb +2 -2
- data/lib/solargraph/doc_map.rb +146 -0
- data/lib/solargraph/gem_pins.rb +64 -0
- data/lib/solargraph/language_server/host/cataloger.rb +1 -0
- data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
- data/lib/solargraph/language_server/host/dispatch.rb +10 -4
- data/lib/solargraph/language_server/host/message_worker.rb +4 -0
- data/lib/solargraph/language_server/host/sources.rb +7 -4
- data/lib/solargraph/language_server/host.rb +15 -6
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
- data/lib/solargraph/language_server/message/initialize.rb +5 -2
- data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
- data/lib/solargraph/language_server/message/text_document.rb +0 -1
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
- data/lib/solargraph/language_server/transport/adapter.rb +16 -1
- data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
- data/lib/solargraph/library.rb +58 -11
- data/lib/solargraph/location.rb +1 -0
- data/lib/solargraph/parser/comment_ripper.rb +3 -0
- data/lib/solargraph/parser/node_methods.rb +47 -8
- data/lib/solargraph/parser/node_processor/base.rb +9 -0
- data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +29 -3
- data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +42 -34
- data/lib/solargraph/parser/{legacy → parser_gem}/node_methods.rb +201 -29
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/args_node.rb +4 -1
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/def_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sclass_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +2 -2
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/sym_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors.rb +54 -0
- data/lib/solargraph/parser/parser_gem.rb +12 -0
- data/lib/solargraph/parser/snippet.rb +2 -0
- data/lib/solargraph/parser.rb +8 -11
- data/lib/solargraph/pin/base.rb +63 -8
- data/lib/solargraph/pin/base_variable.rb +6 -2
- data/lib/solargraph/pin/block.rb +11 -6
- data/lib/solargraph/pin/closure.rb +17 -2
- data/lib/solargraph/pin/common.rb +7 -3
- data/lib/solargraph/pin/conversions.rb +33 -3
- data/lib/solargraph/pin/documenting.rb +25 -34
- data/lib/solargraph/pin/instance_variable.rb +4 -0
- data/lib/solargraph/pin/local_variable.rb +13 -1
- data/lib/solargraph/pin/method.rb +109 -15
- data/lib/solargraph/pin/namespace.rb +16 -10
- data/lib/solargraph/pin/parameter.rb +41 -10
- data/lib/solargraph/pin/reference/override.rb +2 -2
- data/lib/solargraph/pin/reference.rb +8 -0
- data/lib/solargraph/pin/search.rb +3 -3
- data/lib/solargraph/pin/signature.rb +114 -2
- data/lib/solargraph/pin.rb +0 -1
- data/lib/solargraph/range.rb +2 -2
- data/lib/solargraph/rbs_map/conversions.rb +212 -25
- data/lib/solargraph/rbs_map/core_fills.rb +4 -26
- data/lib/solargraph/rbs_map/core_map.rb +1 -0
- data/lib/solargraph/rbs_map/core_signs.rb +2 -0
- data/lib/solargraph/rbs_map/stdlib_map.rb +2 -8
- data/lib/solargraph/rbs_map.rb +19 -9
- data/lib/solargraph/shell.rb +62 -59
- data/lib/solargraph/source/chain/array.rb +4 -1
- data/lib/solargraph/source/chain/block_symbol.rb +13 -0
- data/lib/solargraph/source/chain/call.rb +95 -26
- data/lib/solargraph/source/chain/constant.rb +15 -1
- data/lib/solargraph/source/chain/if.rb +23 -0
- data/lib/solargraph/source/chain/link.rb +7 -1
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain/z_super.rb +2 -2
- data/lib/solargraph/source/chain.rb +20 -4
- data/lib/solargraph/source/change.rb +3 -0
- data/lib/solargraph/source/cursor.rb +2 -0
- data/lib/solargraph/source/source_chainer.rb +6 -5
- data/lib/solargraph/source.rb +15 -16
- data/lib/solargraph/source_map/clip.rb +11 -7
- data/lib/solargraph/source_map/mapper.rb +10 -0
- data/lib/solargraph/source_map.rb +13 -3
- data/lib/solargraph/type_checker/checks.rb +10 -2
- data/lib/solargraph/type_checker.rb +74 -19
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +8 -6
- data/lib/solargraph/workspace.rb +1 -1
- data/lib/solargraph/yard_map/cache.rb +6 -0
- data/lib/solargraph/yard_map/helpers.rb +1 -1
- data/lib/solargraph/yard_map/mapper/to_method.rb +11 -1
- data/lib/solargraph/yard_map/to_method.rb +11 -4
- data/lib/solargraph/yard_map.rb +0 -292
- data/lib/solargraph/yardoc.rb +52 -0
- data/lib/solargraph.rb +4 -1
- data/solargraph.gemspec +2 -2
- metadata +35 -57
- data/lib/solargraph/api_map/bundler_methods.rb +0 -22
- data/lib/solargraph/documentor.rb +0 -76
- data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
- data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
- data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +0 -18
- data/lib/solargraph/parser/legacy/node_processors.rb +0 -55
- data/lib/solargraph/parser/legacy.rb +0 -12
- data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -151
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -163
- data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -317
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
- data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
- data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -33
- data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
- data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +0 -75
- data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -68
- data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
- data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
- data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
- data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
- data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
- data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
- data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
- data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -51
- data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -32
- data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -279
- data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -64
- data/lib/solargraph/parser/rubyvm/node_wrapper.rb +0 -47
- data/lib/solargraph/parser/rubyvm.rb +0 -40
@@ -0,0 +1,146 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
# A collection of pins generated from required gems.
|
5
|
+
#
|
6
|
+
class DocMap
|
7
|
+
# @return [Array<String>]
|
8
|
+
attr_reader :requires
|
9
|
+
|
10
|
+
# @return [Array<Gem::Specification>]
|
11
|
+
attr_reader :dependencies
|
12
|
+
|
13
|
+
# @return [Array<Pin::Base>]
|
14
|
+
attr_reader :pins
|
15
|
+
|
16
|
+
# @return [Array<Gem::Specification>]
|
17
|
+
attr_reader :uncached_gemspecs
|
18
|
+
|
19
|
+
# @param requires [Array<String>]
|
20
|
+
# @param dependencies [Array<Gem::Specification>]
|
21
|
+
def initialize(requires, dependencies)
|
22
|
+
@requires = requires
|
23
|
+
@dependencies = dependencies
|
24
|
+
generate
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Array<Gem::Specification>]
|
28
|
+
def gemspecs
|
29
|
+
@gemspecs ||= required_gem_map.values.compact
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Array<String>]
|
33
|
+
def unresolved_requires
|
34
|
+
@unresolved_requires ||= required_gem_map.select { |_, gemspec| gemspec.nil? }.keys
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [Hash{Gem::Specification => Array[Pin::Base]}]
|
38
|
+
def self.gems_in_memory
|
39
|
+
@gems_in_memory ||= {}
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# @return [Hash{String => Gem::Specification, nil}]
|
45
|
+
def required_gem_map
|
46
|
+
@required_gem_map ||= requires.to_h { |path| [path, resolve_path_to_gemspec(path)] }
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [Hash{String => Gem::Specification}]
|
50
|
+
def dependency_map
|
51
|
+
@dependency_map ||= dependencies.to_h { |gemspec| [gemspec.name, gemspec] }
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [void]
|
55
|
+
def generate
|
56
|
+
@pins = []
|
57
|
+
@uncached_gemspecs = []
|
58
|
+
required_gem_map.each do |path, gemspec|
|
59
|
+
if gemspec
|
60
|
+
try_cache gemspec
|
61
|
+
else
|
62
|
+
try_stdlib_map path
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# @param gemspec [Gem::Specification]
|
68
|
+
# @return [void]
|
69
|
+
def try_cache gemspec
|
70
|
+
return if try_gem_in_memory(gemspec)
|
71
|
+
cache_file = File.join('gems', "#{gemspec.name}-#{gemspec.version}.ser")
|
72
|
+
if Cache.exist?(cache_file)
|
73
|
+
gempins = Cache.load(cache_file)
|
74
|
+
self.class.gems_in_memory[gemspec] = gempins
|
75
|
+
@pins.concat gempins
|
76
|
+
else
|
77
|
+
Solargraph.logger.debug "No pin cache for #{gemspec.name} #{gemspec.version}"
|
78
|
+
@uncached_gemspecs.push gemspec
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# @param path [String] require path that might be in the RBS stdlib collection
|
83
|
+
# @return [void]
|
84
|
+
def try_stdlib_map path
|
85
|
+
map = RbsMap::StdlibMap.load(path)
|
86
|
+
if map.resolved?
|
87
|
+
Solargraph.logger.debug "Loading stdlib pins for #{path}"
|
88
|
+
@pins.concat map.pins
|
89
|
+
else
|
90
|
+
# @todo Temporarily ignoring unresolved `require 'set'`
|
91
|
+
Solargraph.logger.warn "Require path #{path} could not be resolved" unless path == 'set'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# @param gemspec [Gem::Specification]
|
96
|
+
# @return [Boolean]
|
97
|
+
def try_gem_in_memory gemspec
|
98
|
+
gempins = DocMap.gems_in_memory[gemspec]
|
99
|
+
return false unless gempins
|
100
|
+
Solargraph.logger.debug "Found #{gemspec.name} #{gemspec.version} in memory"
|
101
|
+
@pins.concat gempins
|
102
|
+
true
|
103
|
+
end
|
104
|
+
|
105
|
+
# @param path [String]
|
106
|
+
# @return [Gem::Specification, nil]
|
107
|
+
def resolve_path_to_gemspec path
|
108
|
+
gemspec = Gem::Specification.find_by_path(path)
|
109
|
+
if gemspec.nil?
|
110
|
+
gem_name_guess = path.split('/').first
|
111
|
+
begin
|
112
|
+
# this can happen when the gem is included via a local path in
|
113
|
+
# a Gemfile; Gem doesn't try to index the paths in that case.
|
114
|
+
#
|
115
|
+
# See if we can make a good guess:
|
116
|
+
potential_gemspec = Gem::Specification.find_by_name(gem_name_guess)
|
117
|
+
file = "lib/#{path}.rb"
|
118
|
+
gemspec = potential_gemspec if potential_gemspec.files.any? { |gemspec_file| file == gemspec_file }
|
119
|
+
rescue Gem::MissingSpecError
|
120
|
+
Solargraph.logger.debug "Require path #{path} could not be resolved to a gem via find_by_path or guess of #{gem_name_guess}"
|
121
|
+
nil
|
122
|
+
end
|
123
|
+
end
|
124
|
+
return gemspec if dependencies.empty? || gemspec.nil?
|
125
|
+
|
126
|
+
if dependency_map.key?(gemspec.name)
|
127
|
+
return gemspec if gemspec.version == dependency_map[gemspec.name].version
|
128
|
+
|
129
|
+
change_gemspec_version gemspec, dependency_map[by_path.name].version
|
130
|
+
else
|
131
|
+
Solargraph.logger.warn "Gem #{gemspec.name} is not an expected dependency"
|
132
|
+
gemspec
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# @param gemspec [Gem::Specification]
|
137
|
+
# @param version [Gem::Version]
|
138
|
+
# @return [Gem::Specification]
|
139
|
+
def change_gemspec_version gemspec, version
|
140
|
+
Gem::Specification.find_by_name(gemspec.name, "= #{version}")
|
141
|
+
rescue Gem::MissingSpecError
|
142
|
+
Solargraph.logger.info "Gem #{gemspec.name} version #{version} not found. Using #{gemspec.version} instead"
|
143
|
+
gemspec
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rbs'
|
4
|
+
|
5
|
+
module Solargraph
|
6
|
+
# A utility for building gem pins from a combination of YARD and RBS
|
7
|
+
# documentation.
|
8
|
+
#
|
9
|
+
module GemPins
|
10
|
+
# Build an array of pins from a gem specification. The process starts with
|
11
|
+
# YARD, enhances the resulting pins with RBS definitions, and appends RBS
|
12
|
+
# pins that don't exist in the YARD mapping.
|
13
|
+
#
|
14
|
+
# @param gemspec [Gem::Specification]
|
15
|
+
# @return [Array<Pin::Base>]
|
16
|
+
def self.build(gemspec)
|
17
|
+
yard_pins = build_yard_pins(gemspec)
|
18
|
+
rbs_map = RbsMap.from_gemspec(gemspec)
|
19
|
+
in_yard = Set.new
|
20
|
+
combined = yard_pins.map do |yard|
|
21
|
+
in_yard.add yard.path
|
22
|
+
next yard unless yard.is_a?(Pin::Method)
|
23
|
+
rbs = rbs_map.path_pin(yard.path)
|
24
|
+
next yard unless rbs
|
25
|
+
# @todo Could not include: attribute and anon_splat
|
26
|
+
# @sg-ignore
|
27
|
+
yard.class.new(
|
28
|
+
location: yard.location,
|
29
|
+
closure: yard.closure,
|
30
|
+
name: yard.name,
|
31
|
+
comments: yard.comments,
|
32
|
+
scope: yard.scope,
|
33
|
+
parameters: rbs.parameters,
|
34
|
+
generics: rbs.generics,
|
35
|
+
node: yard.node,
|
36
|
+
signatures: yard.signatures,
|
37
|
+
return_type: best_return_type(rbs.return_type, yard.return_type)
|
38
|
+
)
|
39
|
+
end
|
40
|
+
in_rbs = rbs_map.pins.reject { |pin| in_yard.include?(pin.path) }
|
41
|
+
combined + in_rbs
|
42
|
+
end
|
43
|
+
|
44
|
+
class << self
|
45
|
+
private
|
46
|
+
|
47
|
+
# @param gemspec [Gem::Specification]
|
48
|
+
# @return [Array<Pin::Base>]
|
49
|
+
def build_yard_pins(gemspec)
|
50
|
+
Yardoc.cache(gemspec) unless Yardoc.cached?(gemspec)
|
51
|
+
yardoc = Yardoc.load!(gemspec)
|
52
|
+
YardMap::Mapper.new(yardoc, gemspec).map
|
53
|
+
end
|
54
|
+
|
55
|
+
# Select the first defined type.
|
56
|
+
#
|
57
|
+
# @param choices [Array<ComplexType>]
|
58
|
+
# @return [ComplexType]
|
59
|
+
def best_return_type *choices
|
60
|
+
choices.find { |pin| pin.defined? } || choices.first || ComplexType::UNDEFINED
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -38,7 +38,7 @@ module Solargraph
|
|
38
38
|
|
39
39
|
# Start the diagnosis thread.
|
40
40
|
#
|
41
|
-
# @return [self]
|
41
|
+
# @return [self, nil]
|
42
42
|
def start
|
43
43
|
return unless @stopped
|
44
44
|
@stopped = false
|
@@ -81,7 +81,7 @@ module Solargraph
|
|
81
81
|
# @return [Mutex]
|
82
82
|
attr_reader :mutex
|
83
83
|
|
84
|
-
# @return [Array]
|
84
|
+
# @return [::Array]
|
85
85
|
attr_reader :queue
|
86
86
|
end
|
87
87
|
end
|
@@ -6,6 +6,12 @@ module Solargraph
|
|
6
6
|
# Methods for associating sources with libraries via URIs.
|
7
7
|
#
|
8
8
|
module Dispatch
|
9
|
+
# @abstract
|
10
|
+
# @return [Host::Diagnoser]
|
11
|
+
def diagnoser
|
12
|
+
raise NotImplementedError, 'Host::Dispatch requires a diagnoser method'
|
13
|
+
end
|
14
|
+
|
9
15
|
# @return [Sources]
|
10
16
|
def sources
|
11
17
|
@sources ||= begin
|
@@ -15,7 +21,7 @@ module Solargraph
|
|
15
21
|
end
|
16
22
|
end
|
17
23
|
|
18
|
-
# @return [Array<Library>]
|
24
|
+
# @return [::Array<Library>]
|
19
25
|
def libraries
|
20
26
|
@libraries ||= []
|
21
27
|
end
|
@@ -27,9 +33,9 @@ module Solargraph
|
|
27
33
|
# @return [void]
|
28
34
|
def update_libraries uri
|
29
35
|
src = sources.find(uri)
|
30
|
-
libraries.
|
31
|
-
|
32
|
-
|
36
|
+
using = libraries.select { |lib| lib.contain?(src.filename) }
|
37
|
+
using.push generic_library_for(uri) if using.empty?
|
38
|
+
using.each { |lib| lib.merge src }
|
33
39
|
diagnoser.schedule uri
|
34
40
|
end
|
35
41
|
|
@@ -16,6 +16,7 @@ module Solargraph
|
|
16
16
|
end
|
17
17
|
|
18
18
|
# pending handle messages
|
19
|
+
# @return [Array<Hash>]
|
19
20
|
def messages
|
20
21
|
@messages ||= []
|
21
22
|
end
|
@@ -24,6 +25,7 @@ module Solargraph
|
|
24
25
|
@stopped
|
25
26
|
end
|
26
27
|
|
28
|
+
# @return [void]
|
27
29
|
def stop
|
28
30
|
@stopped = true
|
29
31
|
end
|
@@ -37,6 +39,7 @@ module Solargraph
|
|
37
39
|
end
|
38
40
|
end
|
39
41
|
|
42
|
+
# @return [void]
|
40
43
|
def start
|
41
44
|
return unless @stopped
|
42
45
|
@stopped = false
|
@@ -45,6 +48,7 @@ module Solargraph
|
|
45
48
|
end
|
46
49
|
end
|
47
50
|
|
51
|
+
# @return [void]
|
48
52
|
def tick
|
49
53
|
message = @mutex.synchronize do
|
50
54
|
@resource.wait(@mutex) if messages.empty?
|
@@ -43,6 +43,7 @@ module Solargraph
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
# @param uri [String]
|
46
47
|
# @return [void]
|
47
48
|
def add_uri(uri)
|
48
49
|
queue.push(uri)
|
@@ -72,6 +73,8 @@ module Solargraph
|
|
72
73
|
open_source_hash[uri] = source
|
73
74
|
end
|
74
75
|
|
76
|
+
# @param uri [String]
|
77
|
+
# @return [void]
|
75
78
|
def open_from_disk uri
|
76
79
|
source = Solargraph::Source.load(UriHelpers.uri_to_file(uri))
|
77
80
|
open_source_hash[uri] = source
|
@@ -83,7 +86,7 @@ module Solargraph
|
|
83
86
|
#
|
84
87
|
# @param uri [String]
|
85
88
|
# @param updater [Source::Updater]
|
86
|
-
# @return [
|
89
|
+
# @return [void]
|
87
90
|
def update uri, updater
|
88
91
|
src = find(uri)
|
89
92
|
mutex.synchronize { open_source_hash[uri] = src.synchronize(updater) }
|
@@ -109,7 +112,7 @@ module Solargraph
|
|
109
112
|
# @raise [FileNotFoundError] if the URI does not match an open source.
|
110
113
|
#
|
111
114
|
# @param uri [String]
|
112
|
-
# @return [Source]
|
115
|
+
# @return [Solargraph::Source]
|
113
116
|
def find uri
|
114
117
|
open_source_hash[uri] || raise(Solargraph::FileNotFoundError, "Host could not find #{uri}")
|
115
118
|
end
|
@@ -136,7 +139,7 @@ module Solargraph
|
|
136
139
|
|
137
140
|
private
|
138
141
|
|
139
|
-
# @return [Hash]
|
142
|
+
# @return [Hash{String => Solargraph::Source}]
|
140
143
|
def open_source_hash
|
141
144
|
@open_source_hash ||= {}
|
142
145
|
end
|
@@ -146,7 +149,7 @@ module Solargraph
|
|
146
149
|
|
147
150
|
# An array of source URIs that are waiting to finish synchronizing.
|
148
151
|
#
|
149
|
-
# @return [Array<String>]
|
152
|
+
# @return [::Array<String>]
|
150
153
|
def queue
|
151
154
|
@queue ||= []
|
152
155
|
end
|
@@ -3,7 +3,6 @@
|
|
3
3
|
require 'diff/lcs'
|
4
4
|
require 'observer'
|
5
5
|
require 'securerandom'
|
6
|
-
require 'set'
|
7
6
|
|
8
7
|
module Solargraph
|
9
8
|
module LanguageServer
|
@@ -59,7 +58,7 @@ module Solargraph
|
|
59
58
|
logger.level = LOG_LEVELS[options['logLevel']] || DEFAULT_LOG_LEVEL
|
60
59
|
end
|
61
60
|
|
62
|
-
# @return [Hash]
|
61
|
+
# @return [Hash{String => [Boolean, String]}]
|
63
62
|
def options
|
64
63
|
@options ||= default_configuration
|
65
64
|
end
|
@@ -101,8 +100,8 @@ module Solargraph
|
|
101
100
|
# Start processing a request from the client. After the message is
|
102
101
|
# processed, caller is responsible for sending the response.
|
103
102
|
#
|
104
|
-
# @param request [Hash] The contents of the message.
|
105
|
-
# @return [Solargraph::LanguageServer::Message::Base] The message handler.
|
103
|
+
# @param request [Hash{String => unspecified}] The contents of the message.
|
104
|
+
# @return [Solargraph::LanguageServer::Message::Base, nil] The message handler.
|
106
105
|
def receive request
|
107
106
|
if request['method']
|
108
107
|
logger.info "Server received #{request['method']}"
|
@@ -127,6 +126,7 @@ module Solargraph
|
|
127
126
|
else
|
128
127
|
logger.warn "Invalid message received."
|
129
128
|
logger.debug request
|
129
|
+
nil
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
@@ -505,6 +505,8 @@ module Solargraph
|
|
505
505
|
library.read_text(filename)
|
506
506
|
end
|
507
507
|
|
508
|
+
# @param uri [String]
|
509
|
+
# @return [Hash]
|
508
510
|
def formatter_config uri
|
509
511
|
library = library_for(uri)
|
510
512
|
library.workspace.config.formatter
|
@@ -632,7 +634,7 @@ module Solargraph
|
|
632
634
|
requests.keys
|
633
635
|
end
|
634
636
|
|
635
|
-
# @return [Hash{String =>
|
637
|
+
# @return [Hash{String => [Boolean,String]}]
|
636
638
|
def default_configuration
|
637
639
|
{
|
638
640
|
'completion' => true,
|
@@ -663,6 +665,7 @@ module Solargraph
|
|
663
665
|
libraries.each(&:catalog)
|
664
666
|
end
|
665
667
|
|
668
|
+
# @return [Hash{String => BasicObject}]
|
666
669
|
def client_capabilities
|
667
670
|
@client_capabilities ||= {}
|
668
671
|
end
|
@@ -687,7 +690,7 @@ module Solargraph
|
|
687
690
|
# A hash of client requests by ID. The host uses this to keep track of
|
688
691
|
# pending responses.
|
689
692
|
#
|
690
|
-
# @return [Hash{Integer =>
|
693
|
+
# @return [Hash{Integer => Solargraph::LanguageServer::Host}]
|
691
694
|
def requests
|
692
695
|
@requests ||= {}
|
693
696
|
end
|
@@ -779,6 +782,9 @@ module Solargraph
|
|
779
782
|
'textDocument/definition' => {
|
780
783
|
definitionProvider: true
|
781
784
|
},
|
785
|
+
'textDocument/typeDefinition' => {
|
786
|
+
typeDefinitionProvider: true
|
787
|
+
},
|
782
788
|
'textDocument/references' => {
|
783
789
|
referencesProvider: true
|
784
790
|
},
|
@@ -832,6 +838,9 @@ module Solargraph
|
|
832
838
|
end
|
833
839
|
end
|
834
840
|
|
841
|
+
# @param library [Library]
|
842
|
+
# @param uuid [String, nil]
|
843
|
+
# @return [void]
|
835
844
|
def do_async_library_map library, uuid = nil
|
836
845
|
total = library.workspace.sources.length
|
837
846
|
if uuid
|
@@ -29,7 +29,7 @@ module Solargraph
|
|
29
29
|
end
|
30
30
|
|
31
31
|
# @param text [String]
|
32
|
-
# @return [Hash{Symbol => String}]
|
32
|
+
# @return [Hash{Symbol => String}, nil]
|
33
33
|
def markup_content text
|
34
34
|
return nil if text.strip.empty?
|
35
35
|
{
|
@@ -38,6 +38,8 @@ module Solargraph
|
|
38
38
|
}
|
39
39
|
end
|
40
40
|
|
41
|
+
# @param pins [Array<Pin::Base>]
|
42
|
+
# @return [String]
|
41
43
|
def join_docs pins
|
42
44
|
result = []
|
43
45
|
last_link = nil
|
@@ -1,6 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
|
4
|
+
# @todo PR the RBS gem to add this
|
5
|
+
# @!parse
|
6
|
+
# module ::Gem
|
7
|
+
# class SpecFetcher; end
|
8
|
+
# end
|
4
9
|
|
5
10
|
module Solargraph
|
6
11
|
module LanguageServer
|
@@ -11,16 +16,23 @@ module Solargraph
|
|
11
16
|
# is true, notify the client when the gem is up to date.
|
12
17
|
#
|
13
18
|
class CheckGemVersion < Base
|
19
|
+
# @return [Gem::SpecFetcher]
|
14
20
|
def self.fetcher
|
15
21
|
@fetcher ||= Gem::SpecFetcher.new
|
16
22
|
end
|
17
23
|
|
24
|
+
# @param obj [Gem::SpecFetcher]
|
25
|
+
# @return [Gem::SpecFetcher]
|
18
26
|
def self.fetcher= obj
|
19
27
|
@fetcher = obj
|
20
28
|
end
|
21
29
|
|
22
30
|
GEM_ZERO = Gem::Version.new('0.0.0')
|
23
31
|
|
32
|
+
# @param host [Solargraph::LanguageServer::Host]
|
33
|
+
# @param request [Hash]
|
34
|
+
# @param current [Gem::Version]
|
35
|
+
# @param available [Gem::Version, nil]
|
24
36
|
def initialize host, request, current: Gem::Version.new(Solargraph::VERSION), available: nil
|
25
37
|
super(host, request)
|
26
38
|
@current = current
|
@@ -54,6 +54,7 @@ module Solargraph
|
|
54
54
|
params['workspaceFolders']
|
55
55
|
end
|
56
56
|
|
57
|
+
# @return [Hash{Symbol => undefined}]
|
57
58
|
def static_completion
|
58
59
|
return {} unless host.options['completion']
|
59
60
|
{
|
@@ -64,6 +65,7 @@ module Solargraph
|
|
64
65
|
}
|
65
66
|
end
|
66
67
|
|
68
|
+
# @return [Hash{Symbol => BasicObject}]
|
67
69
|
def static_code_action
|
68
70
|
{
|
69
71
|
codeActionProvider: true,
|
@@ -71,6 +73,7 @@ module Solargraph
|
|
71
73
|
}
|
72
74
|
end
|
73
75
|
|
76
|
+
# @return [Hash{Symbol => BasicObject}]
|
74
77
|
def static_signature_help
|
75
78
|
{
|
76
79
|
signatureHelpProvider: {
|
@@ -123,9 +126,9 @@ module Solargraph
|
|
123
126
|
end
|
124
127
|
|
125
128
|
def static_type_definitions
|
126
|
-
return {} unless host.options['
|
129
|
+
return {} unless host.options['typeDefinitions']
|
127
130
|
{
|
128
|
-
|
131
|
+
typeDefinitionProvider: true
|
129
132
|
}
|
130
133
|
end
|
131
134
|
|
@@ -12,7 +12,6 @@ module Solargraph
|
|
12
12
|
autoload :DidSave, 'solargraph/language_server/message/text_document/did_save'
|
13
13
|
autoload :Hover, 'solargraph/language_server/message/text_document/hover'
|
14
14
|
autoload :SignatureHelp, 'solargraph/language_server/message/text_document/signature_help'
|
15
|
-
autoload :DiagnosticsQueue, 'solargraph/language_server/message/text_document/diagnostics_queue'
|
16
15
|
autoload :OnTypeFormatting, 'solargraph/language_server/message/text_document/on_type_formatting'
|
17
16
|
autoload :Definition, 'solargraph/language_server/message/text_document/definition'
|
18
17
|
autoload :TypeDefinition, 'solargraph/language_server/message/text_document/type_definition'
|
@@ -11,8 +11,12 @@ module Solargraph::LanguageServer::Message::Workspace
|
|
11
11
|
|
12
12
|
private
|
13
13
|
|
14
|
+
# @return [void]
|
14
15
|
def register_from_options
|
16
|
+
Solargraph.logger.debug "Registering capabilities from options: #{host.options.inspect}"
|
17
|
+
# @type [Array<String>]
|
15
18
|
y = []
|
19
|
+
# @type [Array<String>]
|
16
20
|
n = []
|
17
21
|
(host.options['completion'] ? y : n).push('textDocument/completion')
|
18
22
|
(host.options['hover'] ? y : n).push('textDocument/hover', 'textDocument/signatureHelp')
|
@@ -20,6 +24,7 @@ module Solargraph::LanguageServer::Message::Workspace
|
|
20
24
|
(host.options['formatting'] ? y : n).push('textDocument/formatting')
|
21
25
|
(host.options['symbols'] ? y : n).push('textDocument/documentSymbol', 'workspace/symbol')
|
22
26
|
(host.options['definitions'] ? y : n).push('textDocument/definition')
|
27
|
+
(host.options['typeDefinitions'] ? y : n).push('textDocument/typeDefinition')
|
23
28
|
(host.options['references'] ? y : n).push('textDocument/references')
|
24
29
|
(host.options['folding'] ? y : n).push('textDocument/folding')
|
25
30
|
(host.options['highlights'] ? y : n).push('textDocument/documentHighlight')
|
@@ -8,6 +8,17 @@ module Solargraph
|
|
8
8
|
# A common module for running language servers in Backport.
|
9
9
|
#
|
10
10
|
module Adapter
|
11
|
+
# This runs in the context of Backport::Adapter, which
|
12
|
+
# provides write() - but if we didn't hide this behind a parse
|
13
|
+
# tag, it would override the one in the class.
|
14
|
+
#
|
15
|
+
# @!method write(text)
|
16
|
+
# @abstract
|
17
|
+
# Write the change to the specified text.
|
18
|
+
# @param text [String] The text to be changed.
|
19
|
+
# @return [String] The updated text.
|
20
|
+
|
21
|
+
# @return [void]
|
11
22
|
def opening
|
12
23
|
@host = Solargraph::LanguageServer::Host.new
|
13
24
|
@host.add_observer self
|
@@ -18,15 +29,18 @@ module Solargraph
|
|
18
29
|
end
|
19
30
|
end
|
20
31
|
|
32
|
+
# @return [void]
|
21
33
|
def closing
|
22
34
|
@host.stop
|
23
35
|
end
|
24
36
|
|
25
37
|
# @param data [String]
|
38
|
+
# @return [void]
|
26
39
|
def receiving data
|
27
40
|
@data_reader.receive data
|
28
41
|
end
|
29
42
|
|
43
|
+
# @return [void]
|
30
44
|
def update
|
31
45
|
if @host.stopped?
|
32
46
|
shutdown
|
@@ -38,12 +52,13 @@ module Solargraph
|
|
38
52
|
|
39
53
|
private
|
40
54
|
|
41
|
-
# @param request [
|
55
|
+
# @param request [Hash]
|
42
56
|
# @return [void]
|
43
57
|
def process request
|
44
58
|
@host.process(request)
|
45
59
|
end
|
46
60
|
|
61
|
+
# @return [void]
|
47
62
|
def shutdown
|
48
63
|
Backport.stop unless @host.options['transport'] == 'external'
|
49
64
|
end
|
@@ -16,6 +16,7 @@ module Solargraph
|
|
16
16
|
# client.
|
17
17
|
#
|
18
18
|
# @yieldparam [Hash] The message received from the client
|
19
|
+
# @return [void]
|
19
20
|
def set_message_handler &block
|
20
21
|
@message_handler = block
|
21
22
|
end
|
@@ -26,6 +27,7 @@ module Solargraph
|
|
26
27
|
# will be buffered and subsequent data will be appended to the buffer.
|
27
28
|
#
|
28
29
|
# @param data [String]
|
30
|
+
# @return [void]
|
29
31
|
def receive data
|
30
32
|
data.each_char do |char|
|
31
33
|
@buffer.concat char
|