solargraph 0.58.3 → 0.59.2
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/.envrc +3 -0
- data/.github/workflows/linting.yml +12 -5
- data/.github/workflows/plugins.yml +54 -34
- data/.github/workflows/rspec.yml +15 -28
- data/.github/workflows/typecheck.yml +6 -3
- data/.rubocop.yml +38 -6
- data/.rubocop_todo.yml +53 -966
- data/CHANGELOG.md +24 -0
- data/Gemfile +3 -1
- data/README.md +3 -3
- data/Rakefile +26 -23
- data/bin/solargraph +2 -1
- data/lib/solargraph/api_map/cache.rb +3 -3
- data/lib/solargraph/api_map/constants.rb +12 -3
- data/lib/solargraph/api_map/index.rb +29 -18
- data/lib/solargraph/api_map/source_to_yard.rb +22 -9
- data/lib/solargraph/api_map/store.rb +40 -30
- data/lib/solargraph/api_map.rb +160 -78
- data/lib/solargraph/bench.rb +2 -3
- data/lib/solargraph/complex_type/conformance.rb +176 -0
- data/lib/solargraph/complex_type/type_methods.rb +31 -18
- data/lib/solargraph/complex_type/unique_type.rb +221 -63
- data/lib/solargraph/complex_type.rb +173 -59
- data/lib/solargraph/convention/active_support_concern.rb +111 -111
- data/lib/solargraph/convention/base.rb +50 -50
- data/lib/solargraph/convention/data_definition/data_assignment_node.rb +1 -1
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +7 -5
- data/lib/solargraph/convention/data_definition.rb +5 -2
- data/lib/solargraph/convention/gemfile.rb +1 -1
- data/lib/solargraph/convention/gemspec.rb +1 -1
- data/lib/solargraph/convention/rakefile.rb +1 -1
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +2 -1
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -3
- data/lib/solargraph/convention/struct_definition.rb +8 -4
- data/lib/solargraph/convention.rb +2 -2
- data/lib/solargraph/converters/dd.rb +2 -0
- data/lib/solargraph/converters/dl.rb +2 -0
- data/lib/solargraph/converters/dt.rb +2 -0
- data/lib/solargraph/converters/misc.rb +2 -0
- data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
- data/lib/solargraph/diagnostics/rubocop.rb +11 -10
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
- data/lib/solargraph/diagnostics/type_check.rb +11 -10
- data/lib/solargraph/diagnostics/update_errors.rb +4 -8
- data/lib/solargraph/diagnostics.rb +55 -55
- data/lib/solargraph/doc_map.rb +38 -39
- data/lib/solargraph/environ.rb +52 -52
- data/lib/solargraph/equality.rb +4 -4
- data/lib/solargraph/gem_pins.rb +4 -15
- data/lib/solargraph/language_server/error_codes.rb +10 -10
- data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
- data/lib/solargraph/language_server/host/dispatch.rb +3 -3
- data/lib/solargraph/language_server/host/message_worker.rb +4 -3
- data/lib/solargraph/language_server/host/sources.rb +2 -1
- data/lib/solargraph/language_server/host.rb +35 -28
- data/lib/solargraph/language_server/message/base.rb +1 -1
- data/lib/solargraph/language_server/message/client/register_capability.rb +1 -3
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +6 -8
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +12 -18
- data/lib/solargraph/language_server/message/extended/document.rb +1 -0
- data/lib/solargraph/language_server/message/extended/document_gems.rb +7 -7
- data/lib/solargraph/language_server/message/extended/download_core.rb +2 -1
- data/lib/solargraph/language_server/message/extended/environment.rb +25 -25
- data/lib/solargraph/language_server/message/extended/search.rb +1 -1
- data/lib/solargraph/language_server/message/initialize.rb +20 -14
- data/lib/solargraph/language_server/message/initialized.rb +28 -28
- data/lib/solargraph/language_server/message/text_document/completion.rb +10 -8
- data/lib/solargraph/language_server/message/text_document/definition.rb +41 -32
- data/lib/solargraph/language_server/message/text_document/document_highlight.rb +17 -10
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -19
- data/lib/solargraph/language_server/message/text_document/formatting.rb +8 -6
- data/lib/solargraph/language_server/message/text_document/hover.rb +5 -5
- data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +13 -6
- data/lib/solargraph/language_server/message/text_document/references.rb +17 -10
- data/lib/solargraph/language_server/message/text_document/rename.rb +20 -13
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +3 -2
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -17
- data/lib/solargraph/language_server/message/text_document.rb +28 -28
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +34 -28
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +38 -30
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +23 -17
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -17
- data/lib/solargraph/language_server/message.rb +1 -1
- data/lib/solargraph/language_server/progress.rb +143 -143
- data/lib/solargraph/language_server/request.rb +4 -2
- data/lib/solargraph/language_server/transport/adapter.rb +68 -68
- data/lib/solargraph/language_server/transport/data_reader.rb +11 -13
- data/lib/solargraph/language_server/uri_helpers.rb +2 -2
- data/lib/solargraph/language_server.rb +20 -20
- data/lib/solargraph/library.rb +57 -38
- data/lib/solargraph/location.rb +17 -14
- data/lib/solargraph/logging.rb +22 -4
- data/lib/solargraph/page.rb +1 -1
- data/lib/solargraph/parser/comment_ripper.rb +19 -4
- data/lib/solargraph/parser/flow_sensitive_typing.rb +324 -108
- data/lib/solargraph/parser/node_processor/base.rb +34 -4
- data/lib/solargraph/parser/node_processor.rb +8 -7
- data/lib/solargraph/parser/parser_gem/class_methods.rb +30 -14
- data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +51 -25
- data/lib/solargraph/parser/parser_gem/node_methods.rb +181 -73
- data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +24 -24
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +13 -11
- data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +11 -12
- data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +36 -36
- data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +24 -24
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -3
- data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +9 -8
- data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +24 -24
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +5 -3
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
- data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +40 -40
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +3 -3
- data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
- data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -5
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +124 -113
- data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +20 -20
- data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +6 -2
- data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
- data/lib/solargraph/parser/parser_gem.rb +2 -0
- data/lib/solargraph/parser/region.rb +9 -3
- data/lib/solargraph/parser/snippet.rb +3 -1
- data/lib/solargraph/parser.rb +2 -0
- data/lib/solargraph/pin/base.rb +126 -82
- data/lib/solargraph/pin/base_variable.rb +273 -24
- data/lib/solargraph/pin/block.rb +29 -6
- data/lib/solargraph/pin/breakable.rb +7 -1
- data/lib/solargraph/pin/callable.rb +65 -21
- data/lib/solargraph/pin/closure.rb +7 -10
- data/lib/solargraph/pin/common.rb +24 -6
- data/lib/solargraph/pin/compound_statement.rb +55 -0
- data/lib/solargraph/pin/constant.rb +3 -5
- data/lib/solargraph/pin/conversions.rb +10 -4
- data/lib/solargraph/pin/delegated_method.rb +19 -8
- data/lib/solargraph/pin/documenting.rb +4 -2
- data/lib/solargraph/pin/instance_variable.rb +5 -1
- data/lib/solargraph/pin/keyword.rb +0 -4
- data/lib/solargraph/pin/local_variable.rb +15 -59
- data/lib/solargraph/pin/method.rb +158 -104
- data/lib/solargraph/pin/method_alias.rb +8 -0
- data/lib/solargraph/pin/namespace.rb +19 -12
- data/lib/solargraph/pin/parameter.rb +102 -36
- data/lib/solargraph/pin/proxy_type.rb +4 -1
- data/lib/solargraph/pin/reference/override.rb +1 -1
- data/lib/solargraph/pin/reference/require.rb +14 -14
- data/lib/solargraph/pin/reference/superclass.rb +2 -0
- data/lib/solargraph/pin/reference/type_alias.rb +16 -0
- data/lib/solargraph/pin/reference.rb +20 -0
- data/lib/solargraph/pin/search.rb +8 -7
- data/lib/solargraph/pin/signature.rb +15 -12
- data/lib/solargraph/pin/singleton.rb +11 -11
- data/lib/solargraph/pin/symbol.rb +2 -1
- data/lib/solargraph/pin/until.rb +2 -4
- data/lib/solargraph/pin/while.rb +2 -4
- data/lib/solargraph/pin.rb +2 -0
- data/lib/solargraph/pin_cache.rb +22 -19
- data/lib/solargraph/position.rb +17 -10
- data/lib/solargraph/range.rb +16 -15
- data/lib/solargraph/rbs_map/conversions.rb +367 -231
- data/lib/solargraph/rbs_map/core_fills.rb +18 -11
- data/lib/solargraph/rbs_map/core_map.rb +24 -17
- data/lib/solargraph/rbs_map/stdlib_map.rb +33 -5
- data/lib/solargraph/rbs_map.rb +76 -32
- data/lib/solargraph/server_methods.rb +1 -1
- data/lib/solargraph/shell.rb +258 -66
- data/lib/solargraph/source/chain/array.rb +3 -12
- data/lib/solargraph/source/chain/block_symbol.rb +13 -13
- data/lib/solargraph/source/chain/block_variable.rb +13 -13
- data/lib/solargraph/source/chain/call.rb +96 -56
- data/lib/solargraph/source/chain/class_variable.rb +1 -1
- data/lib/solargraph/source/chain/constant.rb +5 -1
- data/lib/solargraph/source/chain/global_variable.rb +1 -1
- data/lib/solargraph/source/chain/hash.rb +8 -5
- data/lib/solargraph/source/chain/head.rb +19 -19
- data/lib/solargraph/source/chain/if.rb +12 -10
- data/lib/solargraph/source/chain/instance_variable.rb +24 -1
- data/lib/solargraph/source/chain/link.rb +12 -22
- data/lib/solargraph/source/chain/literal.rb +22 -15
- data/lib/solargraph/source/chain/or.rb +10 -4
- data/lib/solargraph/source/chain/q_call.rb +2 -0
- data/lib/solargraph/source/chain/variable.rb +3 -1
- data/lib/solargraph/source/chain/z_super.rb +1 -3
- data/lib/solargraph/source/chain.rb +51 -38
- data/lib/solargraph/source/change.rb +12 -5
- data/lib/solargraph/source/cursor.rb +33 -18
- data/lib/solargraph/source/encoding_fixes.rb +6 -7
- data/lib/solargraph/source/source_chainer.rb +56 -32
- data/lib/solargraph/source/updater.rb +5 -1
- data/lib/solargraph/source.rb +59 -35
- data/lib/solargraph/source_map/clip.rb +54 -30
- data/lib/solargraph/source_map/data.rb +4 -1
- data/lib/solargraph/source_map/mapper.rb +69 -42
- data/lib/solargraph/source_map.rb +21 -9
- data/lib/solargraph/type_checker/problem.rb +3 -1
- data/lib/solargraph/type_checker/rules.rb +81 -8
- data/lib/solargraph/type_checker.rb +196 -122
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +14 -11
- data/lib/solargraph/workspace/gemspecs.rb +367 -0
- data/lib/solargraph/workspace/require_paths.rb +1 -0
- data/lib/solargraph/workspace.rb +50 -28
- data/lib/solargraph/yard_map/cache.rb +25 -25
- data/lib/solargraph/yard_map/helpers.rb +8 -3
- data/lib/solargraph/yard_map/mapper/to_constant.rb +28 -28
- data/lib/solargraph/yard_map/mapper/to_method.rb +13 -7
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +2 -1
- data/lib/solargraph/yard_map/mapper.rb +13 -8
- data/lib/solargraph/yard_map.rb +17 -18
- data/lib/solargraph/yard_tags.rb +2 -2
- data/lib/solargraph/yardoc.rb +7 -4
- data/lib/solargraph.rb +33 -10
- data/rbs/fills/rubygems/0/dependency.rbs +193 -0
- data/rbs/shims/ast/0/node.rbs +1 -1
- data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
- data/solargraph.gemspec +37 -35
- metadata +41 -42
- data/lib/solargraph/type_checker/checks.rb +0 -124
- data/lib/solargraph/type_checker/param_def.rb +0 -37
- data/lib/solargraph/yard_map/to_method.rb +0 -89
- data/rbs/fills/tuple/tuple.rbs +0 -149
data/lib/solargraph/shell.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require 'benchmark'
|
|
4
4
|
require 'thor'
|
|
5
5
|
require 'yard'
|
|
6
|
+
require 'yaml'
|
|
6
7
|
|
|
7
8
|
module Solargraph
|
|
8
9
|
class Shell < Thor
|
|
@@ -15,7 +16,7 @@ module Solargraph
|
|
|
15
16
|
|
|
16
17
|
map %w[--version -v] => :version
|
|
17
18
|
|
|
18
|
-
desc
|
|
19
|
+
desc '--version, -v', 'Print the version'
|
|
19
20
|
# @return [void]
|
|
20
21
|
def version
|
|
21
22
|
puts Solargraph::VERSION
|
|
@@ -30,15 +31,15 @@ module Solargraph
|
|
|
30
31
|
port = options[:port]
|
|
31
32
|
port = available_port if port.zero?
|
|
32
33
|
Backport.run do
|
|
33
|
-
Signal.trap(
|
|
34
|
+
Signal.trap('INT') do
|
|
34
35
|
Backport.stop
|
|
35
36
|
end
|
|
36
|
-
Signal.trap(
|
|
37
|
+
Signal.trap('TERM') do
|
|
37
38
|
Backport.stop
|
|
38
39
|
end
|
|
39
40
|
# @sg-ignore Wrong argument type for Backport.prepare_tcp_server: adapter expected Backport::Adapter, received Module<Solargraph::LanguageServer::Transport::Adapter>
|
|
40
41
|
Backport.prepare_tcp_server host: options[:host], port: port, adapter: Solargraph::LanguageServer::Transport::Adapter
|
|
41
|
-
|
|
42
|
+
$stderr.puts "Solargraph is listening PORT=#{port} PID=#{Process.pid}"
|
|
42
43
|
end
|
|
43
44
|
end
|
|
44
45
|
|
|
@@ -47,15 +48,15 @@ module Solargraph
|
|
|
47
48
|
def stdio
|
|
48
49
|
require 'backport'
|
|
49
50
|
Backport.run do
|
|
50
|
-
Signal.trap(
|
|
51
|
+
Signal.trap('INT') do
|
|
51
52
|
Backport.stop
|
|
52
53
|
end
|
|
53
|
-
Signal.trap(
|
|
54
|
+
Signal.trap('TERM') do
|
|
54
55
|
Backport.stop
|
|
55
56
|
end
|
|
56
57
|
# @sg-ignore Wrong argument type for Backport.prepare_stdio_server: adapter expected Backport::Adapter, received Module<Solargraph::LanguageServer::Transport::Adapter>
|
|
57
58
|
Backport.prepare_stdio_server adapter: Solargraph::LanguageServer::Transport::Adapter
|
|
58
|
-
|
|
59
|
+
$stderr.puts "Solargraph is listening on stdio PID=#{Process.pid}"
|
|
59
60
|
end
|
|
60
61
|
end
|
|
61
62
|
|
|
@@ -63,11 +64,11 @@ module Solargraph
|
|
|
63
64
|
option :extensions, type: :boolean, aliases: :e, desc: 'Add installed extensions', default: true
|
|
64
65
|
# @param directory [String]
|
|
65
66
|
# @return [void]
|
|
66
|
-
def config
|
|
67
|
+
def config directory = '.'
|
|
67
68
|
matches = []
|
|
68
69
|
if options[:extensions]
|
|
69
70
|
Gem::Specification.each do |g|
|
|
70
|
-
if g.name.match(/^solargraph
|
|
71
|
+
if g.name.match(/^solargraph-[A-Za-z0-9_-]*?-ext/)
|
|
71
72
|
require g.name
|
|
72
73
|
matches.push g.name
|
|
73
74
|
end
|
|
@@ -83,7 +84,7 @@ module Solargraph
|
|
|
83
84
|
File.open(File.join(directory, '.solargraph.yml'), 'w') do |file|
|
|
84
85
|
file.puts conf.to_yaml
|
|
85
86
|
end
|
|
86
|
-
|
|
87
|
+
$stdout.puts 'Configuration file initialized.'
|
|
87
88
|
end
|
|
88
89
|
|
|
89
90
|
desc 'clear', 'Delete all cached documentation'
|
|
@@ -92,7 +93,7 @@ module Solargraph
|
|
|
92
93
|
)
|
|
93
94
|
# @return [void]
|
|
94
95
|
def clear
|
|
95
|
-
puts
|
|
96
|
+
puts 'Deleting all cached documentation (gems, core and stdlib)'
|
|
96
97
|
Solargraph::PinCache.clear
|
|
97
98
|
end
|
|
98
99
|
map 'clear-cache' => :clear
|
|
@@ -118,9 +119,11 @@ module Solargraph
|
|
|
118
119
|
pins = rbs_map.pins || []
|
|
119
120
|
PinCache.serialize_rbs_collection_gem(gemspec, rbs_map.cache_key, pins)
|
|
120
121
|
end
|
|
122
|
+
rescue Gem::MissingSpecError
|
|
123
|
+
warn "Gem '#{gem}' not found"
|
|
121
124
|
end
|
|
122
125
|
|
|
123
|
-
desc 'uncache GEM [...GEM]',
|
|
126
|
+
desc 'uncache GEM [...GEM]', 'Delete specific cached gem documentation'
|
|
124
127
|
long_desc %(
|
|
125
128
|
Specify one or more gem names to clear. 'core' or 'stdlib' may
|
|
126
129
|
also be specified to clear cached system documentation.
|
|
@@ -146,23 +149,75 @@ module Solargraph
|
|
|
146
149
|
end
|
|
147
150
|
end
|
|
148
151
|
|
|
149
|
-
desc 'gems [GEM[=VERSION]]', 'Cache documentation for
|
|
152
|
+
desc 'gems [GEM[=VERSION]...] [STDLIB...] [core]', 'Cache documentation for
|
|
153
|
+
installed libraries'
|
|
154
|
+
long_desc %( This command will cache the
|
|
155
|
+
generated type documentation for the specified libraries. While
|
|
156
|
+
Solargraph will generate this on the fly when needed, it takes
|
|
157
|
+
time. This command will generate it in advance, which can be
|
|
158
|
+
useful for CI scenarios.
|
|
159
|
+
|
|
160
|
+
With no arguments, it will cache all libraries in the current
|
|
161
|
+
workspace. If a gem or standard library name is specified, it
|
|
162
|
+
will cache that library's type documentation.
|
|
163
|
+
|
|
164
|
+
An equals sign after a gem will allow a specific gem version
|
|
165
|
+
to be cached.
|
|
166
|
+
|
|
167
|
+
The 'core' argument can be used to cache the type
|
|
168
|
+
documentation for the core Ruby libraries.
|
|
169
|
+
|
|
170
|
+
If the library is already cached, it will be rebuilt if the
|
|
171
|
+
--rebuild option is set.
|
|
172
|
+
|
|
173
|
+
Cached documentation is stored in #{PinCache.base_dir}, which
|
|
174
|
+
can be stored between CI runs.
|
|
175
|
+
)
|
|
150
176
|
option :rebuild, type: :boolean, desc: 'Rebuild existing documentation', default: false
|
|
151
177
|
# @param names [Array<String>]
|
|
152
178
|
# @return [void]
|
|
153
179
|
def gems *names
|
|
154
|
-
|
|
180
|
+
# print time with ms
|
|
181
|
+
workspace = Solargraph::Workspace.new('.')
|
|
182
|
+
|
|
155
183
|
if names.empty?
|
|
156
|
-
Gem::Specification.to_a.each { |spec| do_cache spec,
|
|
157
|
-
|
|
184
|
+
Gem::Specification.to_a.each { |spec| do_cache spec, rebuild: options[:rebuild] }
|
|
185
|
+
$stderr.puts "Documentation cached for all #{Gem::Specification.count} gems."
|
|
158
186
|
else
|
|
187
|
+
warn("Caching these gems: #{names}")
|
|
159
188
|
names.each do |name|
|
|
160
|
-
|
|
161
|
-
|
|
189
|
+
if name == 'core'
|
|
190
|
+
# @sg-ignore cache_core and core? are dynamically defined
|
|
191
|
+
PinCache.cache_core(out: $stdout) # if !PinCache.core? || options[:rebuild]
|
|
192
|
+
next
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
gemspec = workspace.find_gem(*name.split('='))
|
|
196
|
+
if gemspec.nil?
|
|
197
|
+
warn "Gem '#{name}' not found"
|
|
198
|
+
else
|
|
199
|
+
if options[:rebuild] || !PinCache.has_yard?(gemspec)
|
|
200
|
+
pins = GemPins.build_yard_pins(['yard-activesupport-concern'], gemspec)
|
|
201
|
+
PinCache.serialize_yard_gem(gemspec, pins)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
workspace = Solargraph::Workspace.new(Dir.pwd)
|
|
205
|
+
rbs_map = RbsMap.from_gemspec(gemspec, workspace.rbs_collection_path, workspace.rbs_collection_config_path)
|
|
206
|
+
if options[:rebuild] || !PinCache.has_rbs_collection?(gemspec, rbs_map.cache_key)
|
|
207
|
+
# cache pins even if result is zero, so we don't retry building pins
|
|
208
|
+
pins = rbs_map.pins || []
|
|
209
|
+
PinCache.serialize_rbs_collection_gem(gemspec, rbs_map.cache_key, pins)
|
|
210
|
+
end
|
|
211
|
+
end
|
|
162
212
|
rescue Gem::MissingSpecError
|
|
163
213
|
warn "Gem '#{name}' not found"
|
|
214
|
+
rescue Gem::Requirement::BadRequirementError => e
|
|
215
|
+
warn "Gem '#{name}' failed while loading"
|
|
216
|
+
warn e.message
|
|
217
|
+
# @sg-ignore Need to add nil check here
|
|
218
|
+
warn e.backtrace.join("\n")
|
|
164
219
|
end
|
|
165
|
-
|
|
220
|
+
warn "Documentation cached for #{names.count} gems."
|
|
166
221
|
end
|
|
167
222
|
end
|
|
168
223
|
|
|
@@ -179,7 +234,7 @@ module Solargraph
|
|
|
179
234
|
|
|
180
235
|
Type checking levels are normal, typed, strict, and strong.
|
|
181
236
|
)
|
|
182
|
-
option :level, type: :string, aliases: [
|
|
237
|
+
option :level, type: :string, aliases: %i[mode m l], desc: 'Type checking level', default: 'normal'
|
|
183
238
|
option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
|
|
184
239
|
# @return [void]
|
|
185
240
|
def typecheck *files
|
|
@@ -187,7 +242,10 @@ module Solargraph
|
|
|
187
242
|
workspace = Solargraph::Workspace.new(directory)
|
|
188
243
|
level = options[:level].to_sym
|
|
189
244
|
rules = workspace.rules(level)
|
|
190
|
-
api_map =
|
|
245
|
+
api_map =
|
|
246
|
+
Solargraph::ApiMap.load_with_cache(directory, $stdout,
|
|
247
|
+
loose_unions:
|
|
248
|
+
!rules.require_all_unique_types_support_call?)
|
|
191
249
|
probcount = 0
|
|
192
250
|
if files.empty?
|
|
193
251
|
files = api_map.source_maps.map(&:filename)
|
|
@@ -195,23 +253,28 @@ module Solargraph
|
|
|
195
253
|
files.map! { |file| File.realpath(file) }
|
|
196
254
|
end
|
|
197
255
|
filecount = 0
|
|
198
|
-
|
|
199
|
-
time = Benchmark.measure {
|
|
256
|
+
time = Benchmark.measure do
|
|
200
257
|
files.each do |file|
|
|
201
|
-
checker = TypeChecker.new(file, api_map: api_map, level: options[:level].to_sym,
|
|
258
|
+
checker = TypeChecker.new(file, api_map: api_map, rules: rules, level: options[:level].to_sym,
|
|
259
|
+
workspace: workspace)
|
|
202
260
|
problems = checker.problems
|
|
203
261
|
next if problems.empty?
|
|
204
262
|
problems.sort! { |a, b| a.location.range.start.line <=> b.location.range.start.line }
|
|
205
|
-
puts problems.map { |prob|
|
|
263
|
+
puts problems.map { |prob|
|
|
264
|
+
"#{prob.location.filename}:#{prob.location.range.start.line + 1} - #{prob.message}"
|
|
265
|
+
}.join("\n")
|
|
206
266
|
filecount += 1
|
|
207
267
|
probcount += problems.length
|
|
208
268
|
end
|
|
209
|
-
|
|
210
|
-
}
|
|
269
|
+
end
|
|
211
270
|
puts "Typecheck finished in #{time.real} seconds."
|
|
212
|
-
puts "#{probcount} problem#{probcount != 1
|
|
271
|
+
puts "#{probcount} problem#{if probcount != 1
|
|
272
|
+
's'
|
|
273
|
+
end} found#{if files.length != 1
|
|
274
|
+
" in #{filecount} of #{files.length} files"
|
|
275
|
+
end}."
|
|
213
276
|
# "
|
|
214
|
-
exit 1 if probcount
|
|
277
|
+
exit 1 if probcount.positive?
|
|
215
278
|
end
|
|
216
279
|
|
|
217
280
|
desc 'scan', 'Test the workspace for problems'
|
|
@@ -228,21 +291,27 @@ module Solargraph
|
|
|
228
291
|
directory = File.realpath(options[:directory])
|
|
229
292
|
# @type [Solargraph::ApiMap, nil]
|
|
230
293
|
api_map = nil
|
|
231
|
-
time = Benchmark.measure
|
|
294
|
+
time = Benchmark.measure do
|
|
232
295
|
api_map = Solargraph::ApiMap.load_with_cache(directory, $stdout)
|
|
296
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
233
297
|
api_map.pins.each do |pin|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
298
|
+
puts pin_description(pin) if options[:verbose]
|
|
299
|
+
pin.typify api_map
|
|
300
|
+
pin.probe api_map
|
|
301
|
+
rescue StandardError => e
|
|
302
|
+
# @todo to add nil check here
|
|
303
|
+
# @todo should warn on nil dereference below
|
|
304
|
+
warn "Error testing #{pin_description(pin)} #{if pin.location
|
|
305
|
+
"at #{pin.location.filename}:#{pin.location.range.start.line + 1}"
|
|
306
|
+
end}"
|
|
307
|
+
warn "[#{e.class}]: #{e.message}"
|
|
308
|
+
# @todo Need to add nil check here
|
|
309
|
+
# @todo flow sensitive typing should be able to handle redefinition
|
|
310
|
+
warn e.backtrace.join("\n")
|
|
311
|
+
exit 1
|
|
244
312
|
end
|
|
245
|
-
|
|
313
|
+
end
|
|
314
|
+
# @sg-ignore Need to add nil check here
|
|
246
315
|
puts "Scanned #{directory} (#{api_map.pins.length} pins) in #{time.real} seconds."
|
|
247
316
|
end
|
|
248
317
|
|
|
@@ -256,12 +325,15 @@ module Solargraph
|
|
|
256
325
|
puts "#{workspace.filenames.length} files total."
|
|
257
326
|
end
|
|
258
327
|
|
|
259
|
-
desc 'pin [PATH]', 'Describe a pin'
|
|
328
|
+
desc 'pin [PATH]', 'Describe a pin'
|
|
260
329
|
option :rbs, type: :boolean, desc: 'Output the pin as RBS', default: false
|
|
261
|
-
option :typify, type: :boolean, desc: 'Output the calculated return type of the pin from annotations',
|
|
330
|
+
option :typify, type: :boolean, desc: 'Output the calculated return type of the pin from annotations',
|
|
331
|
+
default: false
|
|
262
332
|
option :references, type: :boolean, desc: 'Show references', default: false
|
|
263
|
-
option :probe, type: :boolean, desc: 'Output the calculated return type of the pin from annotations and inference',
|
|
264
|
-
|
|
333
|
+
option :probe, type: :boolean, desc: 'Output the calculated return type of the pin from annotations and inference',
|
|
334
|
+
default: false
|
|
335
|
+
option :stack, type: :boolean, desc: 'Show entire stack of a method pin by including definitions in superclasses',
|
|
336
|
+
default: false
|
|
265
337
|
# @param path [String] The path to the method pin, e.g. 'Class#method' or 'Class.method'
|
|
266
338
|
# @return [void]
|
|
267
339
|
def pin path
|
|
@@ -286,10 +358,11 @@ module Solargraph
|
|
|
286
358
|
pin = pins.first
|
|
287
359
|
case pin
|
|
288
360
|
when nil
|
|
289
|
-
|
|
361
|
+
warn "Pin not found for path '#{path}'"
|
|
290
362
|
exit 1
|
|
291
363
|
when Pin::Namespace
|
|
292
364
|
if options[:references]
|
|
365
|
+
# @sg-ignore Need to add nil check here
|
|
293
366
|
superclass_tag = api_map.qualify_superclass(pin.return_type.tag)
|
|
294
367
|
superclass_pin = api_map.get_path_pins(superclass_tag).first if superclass_tag
|
|
295
368
|
references[:superclass] = superclass_pin if superclass_pin
|
|
@@ -313,36 +386,133 @@ module Solargraph
|
|
|
313
386
|
end
|
|
314
387
|
end
|
|
315
388
|
|
|
389
|
+
desc 'profile [FILE]', 'Profile go-to-definition performance using vernier'
|
|
390
|
+
option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
|
|
391
|
+
option :output_dir, type: :string, aliases: :o, desc: 'The output directory for profiles', default: './tmp/profiles'
|
|
392
|
+
option :line, type: :numeric, aliases: :l, desc: 'Line number (0-based)', default: 4
|
|
393
|
+
option :column, type: :numeric, aliases: :c, desc: 'Column number', default: 10
|
|
394
|
+
option :memory, type: :boolean, aliases: :m, desc: 'Include memory usage counter', default: true
|
|
395
|
+
# @param file [String, nil]
|
|
396
|
+
# @return [void]
|
|
397
|
+
def profile file = nil
|
|
398
|
+
begin
|
|
399
|
+
require 'vernier'
|
|
400
|
+
rescue LoadError
|
|
401
|
+
$stderr.puts 'vernier gem not found. Please install this dependency:'
|
|
402
|
+
$stderr.puts
|
|
403
|
+
$stderr.puts " gem 'vernier', '>1.0', '<2'"
|
|
404
|
+
|
|
405
|
+
return
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
hooks = []
|
|
409
|
+
hooks << :memory_usage if options[:memory]
|
|
410
|
+
|
|
411
|
+
directory = File.realpath(options[:directory])
|
|
412
|
+
FileUtils.mkdir_p(options[:output_dir])
|
|
413
|
+
|
|
414
|
+
host = Solargraph::LanguageServer::Host.new
|
|
415
|
+
host.client_capabilities.merge!({ 'window' => { 'workDoneProgress' => true } })
|
|
416
|
+
# @param method [String] The message method
|
|
417
|
+
# @param params [Hash] The method parameters
|
|
418
|
+
# @return [void]
|
|
419
|
+
def host.send_notification method, params
|
|
420
|
+
puts "Notification: #{method} - #{params}"
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
puts 'Parsing and mapping source files...'
|
|
424
|
+
prepare_start = Time.now
|
|
425
|
+
Vernier.profile(out: "#{options[:output_dir]}/parse_benchmark.json.gz", hooks: hooks) do
|
|
426
|
+
puts 'Mapping libraries'
|
|
427
|
+
host.prepare(directory)
|
|
428
|
+
sleep 0.2 until host.libraries.all?(&:mapped?)
|
|
429
|
+
end
|
|
430
|
+
prepare_time = Time.now - prepare_start
|
|
431
|
+
|
|
432
|
+
puts 'Building the catalog...'
|
|
433
|
+
catalog_start = Time.now
|
|
434
|
+
Vernier.profile(out: "#{options[:output_dir]}/catalog_benchmark.json.gz", hooks: hooks) do
|
|
435
|
+
host.catalog
|
|
436
|
+
end
|
|
437
|
+
catalog_time = Time.now - catalog_start
|
|
438
|
+
|
|
439
|
+
# Determine test file
|
|
440
|
+
if file
|
|
441
|
+
test_file = File.join(directory, file)
|
|
442
|
+
else
|
|
443
|
+
test_file = File.join(directory, 'lib', 'other.rb')
|
|
444
|
+
unless File.exist?(test_file)
|
|
445
|
+
# Fallback to any Ruby file in the workspace
|
|
446
|
+
workspace = Solargraph::Workspace.new(directory)
|
|
447
|
+
test_file = workspace.filenames.find { |f| f.end_with?('.rb') }
|
|
448
|
+
unless test_file
|
|
449
|
+
warn 'No Ruby files found in workspace'
|
|
450
|
+
return
|
|
451
|
+
end
|
|
452
|
+
end
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
file_uri = Solargraph::LanguageServer::UriHelpers.file_to_uri(File.absolute_path(test_file))
|
|
456
|
+
|
|
457
|
+
puts "Profiling go-to-definition for #{test_file}"
|
|
458
|
+
puts "Position: line #{options[:line]}, column #{options[:column]}"
|
|
459
|
+
|
|
460
|
+
definition_start = Time.now
|
|
461
|
+
Vernier.profile(out: "#{options[:output_dir]}/definition_benchmark.json.gz", hooks: hooks) do
|
|
462
|
+
message = Solargraph::LanguageServer::Message::TextDocument::Definition.new(
|
|
463
|
+
host, {
|
|
464
|
+
'params' => {
|
|
465
|
+
'textDocument' => { 'uri' => file_uri },
|
|
466
|
+
'position' => { 'line' => options[:line], 'character' => options[:column] }
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
)
|
|
470
|
+
puts 'Processing go-to-definition request...'
|
|
471
|
+
result = message.process
|
|
472
|
+
|
|
473
|
+
puts "Result: #{result.inspect}"
|
|
474
|
+
end
|
|
475
|
+
definition_time = Time.now - definition_start
|
|
476
|
+
|
|
477
|
+
puts "\n=== Timing Results ==="
|
|
478
|
+
puts "Parsing & mapping: #{(prepare_time * 1000).round(2)}ms"
|
|
479
|
+
puts "Catalog building: #{(catalog_time * 1000).round(2)}ms"
|
|
480
|
+
puts "Go-to-definition: #{(definition_time * 1000).round(2)}ms"
|
|
481
|
+
total_time = prepare_time + catalog_time + definition_time
|
|
482
|
+
puts "Total time: #{(total_time * 1000).round(2)}ms"
|
|
483
|
+
|
|
484
|
+
puts "\nProfiles saved to:"
|
|
485
|
+
puts " - #{File.expand_path('parse_benchmark.json.gz', options[:output_dir])}"
|
|
486
|
+
puts " - #{File.expand_path('catalog_benchmark.json.gz', options[:output_dir])}"
|
|
487
|
+
puts " - #{File.expand_path('definition_benchmark.json.gz', options[:output_dir])}"
|
|
488
|
+
|
|
489
|
+
puts "\nUpload the JSON files to https://vernier.prof/ to view the profiles."
|
|
490
|
+
puts 'Or use https://rubygems.org/gems/profile-viewer to view them locally.'
|
|
491
|
+
end
|
|
492
|
+
|
|
316
493
|
private
|
|
317
494
|
|
|
318
495
|
# @param pin [Solargraph::Pin::Base]
|
|
319
496
|
# @return [String]
|
|
320
497
|
def pin_description pin
|
|
321
498
|
desc = if pin.path.nil? || pin.path.empty?
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
499
|
+
if pin.closure
|
|
500
|
+
# @sg-ignore Need to add nil check here
|
|
501
|
+
"#{pin.closure.path} | #{pin.name}"
|
|
502
|
+
else
|
|
503
|
+
"#{pin.context.namespace} | #{pin.name}"
|
|
504
|
+
end
|
|
505
|
+
else
|
|
506
|
+
pin.path
|
|
507
|
+
end
|
|
508
|
+
# @sg-ignore Need to add nil check here
|
|
330
509
|
desc += " (#{pin.location.filename} #{pin.location.range.start.line})" if pin.location
|
|
331
510
|
desc
|
|
332
511
|
end
|
|
333
512
|
|
|
334
|
-
# @param
|
|
335
|
-
# @param api_map [ApiMap]
|
|
513
|
+
# @param type [ComplexType, ComplexType::UniqueType]
|
|
336
514
|
# @return [void]
|
|
337
|
-
def
|
|
338
|
-
# @todo if the rebuild: option is passed as a positional arg,
|
|
339
|
-
# typecheck doesn't complain on the below line
|
|
340
|
-
api_map.cache_gem(gemspec, rebuild: options.rebuild, out: $stdout)
|
|
341
|
-
end
|
|
342
|
-
|
|
343
|
-
# @param type [ComplexType]
|
|
344
|
-
# @return [void]
|
|
345
|
-
def print_type(type)
|
|
515
|
+
def print_type type
|
|
346
516
|
if options[:rbs]
|
|
347
517
|
puts type.to_rbs
|
|
348
518
|
else
|
|
@@ -352,12 +522,34 @@ module Solargraph
|
|
|
352
522
|
|
|
353
523
|
# @param pin [Solargraph::Pin::Base]
|
|
354
524
|
# @return [void]
|
|
355
|
-
def print_pin
|
|
525
|
+
def print_pin pin
|
|
356
526
|
if options[:rbs]
|
|
357
527
|
puts pin.to_rbs
|
|
358
528
|
else
|
|
359
529
|
puts pin.inspect
|
|
360
530
|
end
|
|
361
531
|
end
|
|
532
|
+
|
|
533
|
+
# @param gemspec [Gem::Specification, nil]
|
|
534
|
+
# @param rebuild [Boolean]
|
|
535
|
+
# @return [void]
|
|
536
|
+
def do_cache gemspec, rebuild: false
|
|
537
|
+
if gemspec.nil?
|
|
538
|
+
warn "Gem '#{gemspec&.name}' not found"
|
|
539
|
+
else
|
|
540
|
+
if rebuild || !PinCache.has_yard?(gemspec)
|
|
541
|
+
pins = GemPins.build_yard_pins(['yard-activesupport-concern'], gemspec)
|
|
542
|
+
PinCache.serialize_yard_gem(gemspec, pins)
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
workspace = Solargraph::Workspace.new(Dir.pwd)
|
|
546
|
+
rbs_map = RbsMap.from_gemspec(gemspec, workspace.rbs_collection_path, workspace.rbs_collection_config_path)
|
|
547
|
+
if rebuild || !PinCache.has_rbs_collection?(gemspec, rbs_map.cache_key)
|
|
548
|
+
# cache pins even if result is zero, so we don't retry building pins
|
|
549
|
+
pins = rbs_map.pins || []
|
|
550
|
+
PinCache.serialize_rbs_collection_gem(gemspec, rbs_map.cache_key, pins)
|
|
551
|
+
end
|
|
552
|
+
end
|
|
553
|
+
end
|
|
362
554
|
end
|
|
363
555
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Solargraph
|
|
2
4
|
class Source
|
|
3
5
|
class Chain
|
|
@@ -17,18 +19,7 @@ module Solargraph
|
|
|
17
19
|
# @param name_pin [Pin::Base]
|
|
18
20
|
# @param locals [::Array<Pin::Parameter, Pin::LocalVariable>]
|
|
19
21
|
def resolve api_map, name_pin, locals
|
|
20
|
-
|
|
21
|
-
child.infer(api_map, name_pin, locals).simplify_literals
|
|
22
|
-
end
|
|
23
|
-
type = if child_types.length == 0 || child_types.any?(&:undefined?)
|
|
24
|
-
ComplexType::UniqueType.new('Array', rooted: true)
|
|
25
|
-
elsif child_types.uniq.length == 1 && child_types.first.defined?
|
|
26
|
-
ComplexType::UniqueType.new('Array', [], child_types.uniq, rooted: true, parameters_type: :list)
|
|
27
|
-
elsif child_types.length == 0
|
|
28
|
-
ComplexType::UniqueType.new('Array', rooted: true, parameters_type: :list)
|
|
29
|
-
else
|
|
30
|
-
ComplexType::UniqueType.new('Array', [], child_types, rooted: true, parameters_type: :fixed)
|
|
31
|
-
end
|
|
22
|
+
type = ComplexType::UniqueType.new('Array', rooted: true)
|
|
32
23
|
[Pin::ProxyType.anonymous(type, source: :chain)]
|
|
33
24
|
end
|
|
34
25
|
end
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
class Source
|
|
5
|
-
class Chain
|
|
6
|
-
class BlockSymbol < Link
|
|
7
|
-
def resolve api_map, name_pin, locals
|
|
8
|
-
[Pin::ProxyType.anonymous(ComplexType.try_parse('::Proc'), source: :chain)]
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class Source
|
|
5
|
+
class Chain
|
|
6
|
+
class BlockSymbol < Link
|
|
7
|
+
def resolve api_map, name_pin, locals
|
|
8
|
+
[Pin::ProxyType.anonymous(ComplexType.try_parse('::Proc'), source: :chain)]
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
class Source
|
|
5
|
-
class Chain
|
|
6
|
-
class BlockVariable < Link
|
|
7
|
-
def resolve api_map, name_pin, locals
|
|
8
|
-
[Pin::ProxyType.anonymous(ComplexType.try_parse('::Proc'), source: :chain)]
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class Source
|
|
5
|
+
class Chain
|
|
6
|
+
class BlockVariable < Link
|
|
7
|
+
def resolve api_map, name_pin, locals
|
|
8
|
+
[Pin::ProxyType.anonymous(ComplexType.try_parse('::Proc'), source: :chain)]
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|