solargraph 0.58.3 → 0.60.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/.envrc +3 -0
- data/.github/workflows/linting.yml +12 -5
- data/.github/workflows/plugins.yml +54 -34
- data/.github/workflows/rspec.yml +18 -28
- data/.github/workflows/typecheck.yml +6 -3
- data/.rubocop.yml +39 -6
- data/.rubocop_todo.yml +53 -966
- data/CHANGELOG.md +35 -0
- data/Gemfile +6 -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 +42 -20
- data/lib/solargraph/api_map/source_to_yard.rb +22 -9
- data/lib/solargraph/api_map/store.rb +61 -36
- data/lib/solargraph/api_map.rb +192 -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 +225 -63
- data/lib/solargraph/complex_type.rb +177 -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 +39 -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 +222 -72
- 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 +64 -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 +156 -84
- 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 +67 -23
- data/lib/solargraph/pin/closure.rb +7 -10
- data/lib/solargraph/pin/common.rb +36 -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 +205 -111
- 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 +278 -191
- 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/rbs_translator.rb +206 -0
- data/lib/solargraph/server_methods.rb +1 -1
- data/lib/solargraph/shell.rb +330 -71
- 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 +91 -119
- 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 +28 -131
- data/lib/solargraph/source_map.rb +35 -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 +19 -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/directives/attribute_directive.rb +65 -0
- data/lib/solargraph/yard_map/directives/domain_directive.rb +30 -0
- data/lib/solargraph/yard_map/directives/method_directive.rb +51 -0
- data/lib/solargraph/yard_map/directives/override_directive.rb +30 -0
- data/lib/solargraph/yard_map/directives/parse_directive.rb +53 -0
- data/lib/solargraph/yard_map/directives/visibility_directive.rb +70 -0
- data/lib/solargraph/yard_map/directives.rb +35 -0
- data/lib/solargraph/yard_map/helpers.rb +8 -3
- data/lib/solargraph/yard_map/macro.rb +113 -0
- 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 +31 -8
- data/lib/solargraph/yard_map.rb +19 -18
- data/lib/solargraph/yard_tags.rb +2 -2
- data/lib/solargraph/yardoc.rb +7 -4
- data/lib/solargraph.rb +34 -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 +38 -35
- metadata +64 -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
|
@@ -19,7 +19,7 @@ module Solargraph
|
|
|
19
19
|
Solargraph::Pin::Method.new(name: 'class', scope: :instance,
|
|
20
20
|
closure: Solargraph::Pin::Namespace.new(name: 'Object', source: :core_fill), comments: '@return [::Class<self>]',
|
|
21
21
|
source: :core_fill)
|
|
22
|
-
]
|
|
22
|
+
].freeze
|
|
23
23
|
|
|
24
24
|
OVERRIDES = [
|
|
25
25
|
Override.from_comment('BasicObject#instance_eval', '@yieldreceiver [self]',
|
|
@@ -38,43 +38,50 @@ module Solargraph
|
|
|
38
38
|
source: :core_fill),
|
|
39
39
|
# RBS does not define Class with a generic, so all calls to
|
|
40
40
|
# generic() return an 'untyped'. We can do better:
|
|
41
|
-
Override.method_return('Class#allocate', 'self', source: :core_fill)
|
|
42
|
-
]
|
|
41
|
+
Override.method_return('Class#allocate', 'self', source: :core_fill)
|
|
42
|
+
].freeze
|
|
43
43
|
|
|
44
44
|
# @todo I don't see any direct link in RBS to build this from -
|
|
45
45
|
# presumably RBS is using duck typing to match interfaces
|
|
46
46
|
# against concrete classes
|
|
47
47
|
INCLUDES = [
|
|
48
48
|
Solargraph::Pin::Reference::Include.new(name: '_ToAry',
|
|
49
|
-
closure: Solargraph::Pin::Namespace.new(name: 'Array',
|
|
49
|
+
closure: Solargraph::Pin::Namespace.new(name: 'Array',
|
|
50
|
+
source: :core_fill),
|
|
50
51
|
generic_values: ['generic<Elem>'],
|
|
51
52
|
source: :core_fill),
|
|
52
53
|
Solargraph::Pin::Reference::Include.new(name: '_ToAry',
|
|
53
|
-
closure: Solargraph::Pin::Namespace.new(name: 'Set',
|
|
54
|
+
closure: Solargraph::Pin::Namespace.new(name: 'Set',
|
|
55
|
+
source: :core_fill),
|
|
54
56
|
generic_values: ['generic<Elem>'],
|
|
55
57
|
source: :core_fill),
|
|
56
58
|
Solargraph::Pin::Reference::Include.new(name: '_Each',
|
|
57
|
-
closure: Solargraph::Pin::Namespace.new(name: 'Array',
|
|
59
|
+
closure: Solargraph::Pin::Namespace.new(name: 'Array',
|
|
60
|
+
source: :core_fill),
|
|
58
61
|
generic_values: ['generic<Elem>'],
|
|
59
62
|
source: :core_fill),
|
|
60
63
|
Solargraph::Pin::Reference::Include.new(name: '_Each',
|
|
61
|
-
closure: Solargraph::Pin::Namespace.new(name: 'Set',
|
|
64
|
+
closure: Solargraph::Pin::Namespace.new(name: 'Set',
|
|
65
|
+
source: :core_fill),
|
|
62
66
|
generic_values: ['generic<Elem>'],
|
|
63
67
|
source: :core_fill),
|
|
64
68
|
Solargraph::Pin::Reference::Include.new(name: '_ToS',
|
|
65
|
-
closure: Solargraph::Pin::Namespace.new(name: 'Object',
|
|
69
|
+
closure: Solargraph::Pin::Namespace.new(name: 'Object',
|
|
70
|
+
source: :core_fill),
|
|
66
71
|
source: :core_fill),
|
|
67
72
|
Solargraph::Pin::Reference::Include.new(name: '_ToS',
|
|
68
|
-
closure: Solargraph::Pin::Namespace.new(name: 'String',
|
|
73
|
+
closure: Solargraph::Pin::Namespace.new(name: 'String',
|
|
74
|
+
source: :core_fill),
|
|
69
75
|
source: :core_fill)
|
|
70
|
-
]
|
|
76
|
+
].freeze
|
|
71
77
|
|
|
72
78
|
# HACK: Add Errno exception classes
|
|
73
79
|
errno = Solargraph::Pin::Namespace.new(name: 'Errno', source: :core_fill)
|
|
74
80
|
errnos = []
|
|
75
81
|
Errno.constants.each do |const|
|
|
76
82
|
errnos.push Solargraph::Pin::Namespace.new(type: :class, name: const.to_s, closure: errno, source: :core_fill)
|
|
77
|
-
errnos.push Solargraph::Pin::Reference::Superclass.new(closure: errnos.last, name: 'SystemCallError',
|
|
83
|
+
errnos.push Solargraph::Pin::Reference::Superclass.new(closure: errnos.last, name: 'SystemCallError',
|
|
84
|
+
source: :core_fill)
|
|
78
85
|
end
|
|
79
86
|
ERRNOS = errnos
|
|
80
87
|
|
|
@@ -15,31 +15,38 @@ module Solargraph
|
|
|
15
15
|
|
|
16
16
|
def initialize; end
|
|
17
17
|
|
|
18
|
+
# @param out [IO, nil] output stream for logging
|
|
18
19
|
# @return [Enumerable<Pin::Base>]
|
|
19
|
-
def pins
|
|
20
|
+
def pins out: $stderr
|
|
20
21
|
return @pins if @pins
|
|
22
|
+
@pins = cache_core(out: out)
|
|
23
|
+
end
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
# @param out [StringIO, IO, nil] output stream for logging
|
|
26
|
+
# @return [Array<Pin::Base>]
|
|
27
|
+
def cache_core out: $stderr
|
|
28
|
+
new_pins = []
|
|
23
29
|
cache = PinCache.deserialize_core
|
|
24
|
-
if cache
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
return cache if cache
|
|
31
|
+
new_pins.concat conversions.pins
|
|
32
|
+
|
|
33
|
+
# Avoid RBS::DuplicatedDeclarationError by loading in a different EnvironmentLoader
|
|
34
|
+
fill_loader = RBS::EnvironmentLoader.new(core_root: nil, repository: RBS::Repository.new(no_stdlib: false))
|
|
35
|
+
fill_loader.add(path: Pathname(FILLS_DIRECTORY))
|
|
36
|
+
out&.puts 'Caching RBS pins for Ruby core'
|
|
37
|
+
fill_conversions = Conversions.new(loader: fill_loader)
|
|
38
|
+
new_pins.concat fill_conversions.pins
|
|
28
39
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
fill_loader.add(path: Pathname(FILLS_DIRECTORY))
|
|
32
|
-
fill_conversions = Conversions.new(loader: fill_loader)
|
|
33
|
-
@pins.concat fill_conversions.pins
|
|
40
|
+
# add some overrides
|
|
41
|
+
new_pins.concat RbsMap::CoreFills::ALL
|
|
34
42
|
|
|
35
|
-
|
|
43
|
+
# process overrides, then remove any which couldn't be resolved
|
|
44
|
+
processed = ApiMap::Store.new(new_pins).pins.reject { |p| p.is_a?(Solargraph::Pin::Reference::Override) }
|
|
45
|
+
new_pins.replace processed
|
|
36
46
|
|
|
37
|
-
|
|
38
|
-
@pins.replace processed
|
|
47
|
+
PinCache.serialize_core new_pins
|
|
39
48
|
|
|
40
|
-
|
|
41
|
-
end
|
|
42
|
-
@pins
|
|
49
|
+
new_pins
|
|
43
50
|
end
|
|
44
51
|
|
|
45
52
|
private
|
|
@@ -12,19 +12,22 @@ module Solargraph
|
|
|
12
12
|
# @type [Hash{String => RbsMap}]
|
|
13
13
|
@stdlib_maps_hash = {}
|
|
14
14
|
|
|
15
|
+
# @param rebuild [Boolean] build pins regardless of whether we
|
|
16
|
+
# have cached them already
|
|
15
17
|
# @param library [String]
|
|
16
|
-
|
|
18
|
+
# @param out [StringIO, IO, nil] where to log messages
|
|
19
|
+
def initialize library, rebuild: false, out: $stderr
|
|
17
20
|
cached_pins = PinCache.deserialize_stdlib_require library
|
|
18
|
-
if cached_pins
|
|
21
|
+
if cached_pins && !rebuild
|
|
19
22
|
@pins = cached_pins
|
|
20
23
|
@resolved = true
|
|
21
24
|
@loaded = true
|
|
22
25
|
logger.debug { "Deserialized #{cached_pins.length} cached pins for stdlib require #{library.inspect}" }
|
|
23
|
-
|
|
24
|
-
super
|
|
26
|
+
elsif self.class.source.has? library, nil
|
|
27
|
+
super(library, out: out)
|
|
25
28
|
unless resolved?
|
|
26
29
|
@pins = []
|
|
27
|
-
logger.
|
|
30
|
+
logger.debug { "StdlibMap could not resolve #{library.inspect}" }
|
|
28
31
|
return
|
|
29
32
|
end
|
|
30
33
|
generated_pins = pins
|
|
@@ -33,6 +36,31 @@ module Solargraph
|
|
|
33
36
|
end
|
|
34
37
|
end
|
|
35
38
|
|
|
39
|
+
# @return [RBS::Collection::Sources::Stdlib]
|
|
40
|
+
def self.source
|
|
41
|
+
@source ||= RBS::Collection::Sources::Stdlib.instance
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @param name [String]
|
|
45
|
+
# @param version [String, nil]
|
|
46
|
+
# @return [Array<Hash{String => String}>, nil]
|
|
47
|
+
def self.stdlib_dependencies name, version = nil
|
|
48
|
+
if source.has?(name, version)
|
|
49
|
+
# @sg-ignore we are relying on undocumented behavior where
|
|
50
|
+
# passing version=nil gives the latest version it has
|
|
51
|
+
source.dependencies_of(name, version)
|
|
52
|
+
else
|
|
53
|
+
[]
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def resolve_dependencies?
|
|
58
|
+
# there are 'virtual' dependencies for stdlib gems in RBS that
|
|
59
|
+
# aren't represented in the actual gemspecs that we'd
|
|
60
|
+
# otherwise use
|
|
61
|
+
true
|
|
62
|
+
end
|
|
63
|
+
|
|
36
64
|
# @param library [String]
|
|
37
65
|
# @return [StdlibMap]
|
|
38
66
|
def self.load library
|
data/lib/solargraph/rbs_map.rb
CHANGED
|
@@ -16,17 +16,14 @@ module Solargraph
|
|
|
16
16
|
# @type [Hash{String => RbsMap}]
|
|
17
17
|
@@rbs_maps_hash = {}
|
|
18
18
|
|
|
19
|
-
attr_reader :library
|
|
20
|
-
|
|
21
|
-
attr_reader :rbs_collection_paths
|
|
22
|
-
|
|
23
|
-
attr_reader :rbs_collection_config_path
|
|
19
|
+
attr_reader :library, :rbs_collection_paths, :rbs_collection_config_path
|
|
24
20
|
|
|
25
21
|
# @param library [String]
|
|
26
22
|
# @param version [String, nil]
|
|
27
23
|
# @param rbs_collection_config_path [String, Pathname, nil]
|
|
28
24
|
# @param rbs_collection_paths [Array<Pathname, String>]
|
|
29
|
-
|
|
25
|
+
# @param out [StringIO, IO, nil] where to log messages
|
|
26
|
+
def initialize library, version = nil, rbs_collection_config_path: nil, rbs_collection_paths: [], out: $stderr
|
|
30
27
|
if rbs_collection_config_path.nil? && !rbs_collection_paths.empty?
|
|
31
28
|
raise 'Please provide rbs_collection_config_path if you provide rbs_collection_paths'
|
|
32
29
|
end
|
|
@@ -37,6 +34,28 @@ module Solargraph
|
|
|
37
34
|
add_library loader, library, version
|
|
38
35
|
end
|
|
39
36
|
|
|
37
|
+
CACHE_KEY_GEM_EXPORT = 'gem-export'
|
|
38
|
+
CACHE_KEY_UNRESOLVED = 'unresolved'
|
|
39
|
+
CACHE_KEY_STDLIB = 'stdlib'
|
|
40
|
+
CACHE_KEY_LOCAL = 'local'
|
|
41
|
+
|
|
42
|
+
# @param cache_key [String, nil]
|
|
43
|
+
# @return [String, nil] a description of the source of the RBS info
|
|
44
|
+
def self.rbs_source_desc cache_key
|
|
45
|
+
case cache_key
|
|
46
|
+
when CACHE_KEY_GEM_EXPORT
|
|
47
|
+
'RBS gem export'
|
|
48
|
+
when CACHE_KEY_UNRESOLVED
|
|
49
|
+
nil
|
|
50
|
+
when CACHE_KEY_STDLIB
|
|
51
|
+
'RBS standard library'
|
|
52
|
+
when CACHE_KEY_LOCAL
|
|
53
|
+
'local RBS shims'
|
|
54
|
+
else
|
|
55
|
+
'RBS collection'
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
40
59
|
# @return [RBS::EnvironmentLoader]
|
|
41
60
|
def loader
|
|
42
61
|
@loader ||= RBS::EnvironmentLoader.new(core_root: nil, repository: repository)
|
|
@@ -47,10 +66,15 @@ module Solargraph
|
|
|
47
66
|
# updated upstream for the same library and version. May change
|
|
48
67
|
# if the config for where information comes form changes.
|
|
49
68
|
def cache_key
|
|
50
|
-
|
|
69
|
+
return CACHE_KEY_UNRESOLVED unless resolved?
|
|
70
|
+
|
|
71
|
+
@cache_key ||= begin
|
|
51
72
|
# @type [String, nil]
|
|
52
73
|
data = nil
|
|
74
|
+
# @type gem_config [nil, Hash{String => Hash{String => String}}]
|
|
75
|
+
gem_config = nil
|
|
53
76
|
if rbs_collection_config_path
|
|
77
|
+
# @sg-ignore rbs_collection_config_path is not nil here
|
|
54
78
|
lockfile_path = RBS::Collection::Config.to_lockfile_path(Pathname.new(rbs_collection_config_path))
|
|
55
79
|
if lockfile_path.exist?
|
|
56
80
|
collection_config = RBS::Collection::Config.from_path lockfile_path
|
|
@@ -58,16 +82,21 @@ module Solargraph
|
|
|
58
82
|
data = gem_config&.to_s
|
|
59
83
|
end
|
|
60
84
|
end
|
|
61
|
-
if
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
85
|
+
if gem_config.nil?
|
|
86
|
+
CACHE_KEY_STDLIB
|
|
87
|
+
else
|
|
88
|
+
# @type [String]
|
|
89
|
+
source = gem_config.dig('source', 'type')
|
|
90
|
+
case source
|
|
91
|
+
when 'rubygems'
|
|
92
|
+
CACHE_KEY_GEM_EXPORT
|
|
93
|
+
when 'local'
|
|
94
|
+
CACHE_KEY_LOCAL
|
|
95
|
+
when 'stdlib'
|
|
96
|
+
CACHE_KEY_STDLIB
|
|
66
97
|
else
|
|
67
|
-
'
|
|
98
|
+
Digest::SHA1.hexdigest(data || '')
|
|
68
99
|
end
|
|
69
|
-
else
|
|
70
|
-
Digest::SHA1.hexdigest(data)
|
|
71
100
|
end
|
|
72
101
|
end
|
|
73
102
|
end
|
|
@@ -77,6 +106,10 @@ module Solargraph
|
|
|
77
106
|
# @param rbs_collection_config_path [String, Pathname, nil]
|
|
78
107
|
# @return [RbsMap]
|
|
79
108
|
def self.from_gemspec gemspec, rbs_collection_path, rbs_collection_config_path
|
|
109
|
+
# prefers stdlib RBS if available
|
|
110
|
+
rbs_map = RbsMap::StdlibMap.new(gemspec.name)
|
|
111
|
+
return rbs_map if rbs_map.resolved?
|
|
112
|
+
|
|
80
113
|
rbs_map = RbsMap.new(gemspec.name, gemspec.version,
|
|
81
114
|
rbs_collection_paths: [rbs_collection_path].compact,
|
|
82
115
|
rbs_collection_config_path: rbs_collection_config_path)
|
|
@@ -88,18 +121,26 @@ module Solargraph
|
|
|
88
121
|
rbs_collection_config_path: rbs_collection_config_path)
|
|
89
122
|
end
|
|
90
123
|
|
|
124
|
+
# @param out [IO, nil] where to log messages
|
|
91
125
|
# @return [Array<Pin::Base>]
|
|
92
|
-
def pins
|
|
93
|
-
@pins ||= resolved?
|
|
126
|
+
def pins out: $stderr
|
|
127
|
+
@pins ||= if resolved?
|
|
128
|
+
conversions.pins
|
|
129
|
+
else
|
|
130
|
+
[]
|
|
131
|
+
end
|
|
94
132
|
end
|
|
95
133
|
|
|
96
134
|
# @generic T
|
|
97
135
|
# @param path [String]
|
|
98
136
|
# @param klass [Class<generic<T>>]
|
|
137
|
+
#
|
|
138
|
+
# @sg-ignore Need to be able to resolve generics based on a
|
|
139
|
+
# Class<generic<T>> param
|
|
99
140
|
# @return [generic<T>, nil]
|
|
100
141
|
def path_pin path, klass = Pin::Base
|
|
101
142
|
pin = pins.find { |p| p.path == path }
|
|
102
|
-
pin if pin
|
|
143
|
+
pin if pin.is_a?(klass)
|
|
103
144
|
end
|
|
104
145
|
|
|
105
146
|
# @param path [String]
|
|
@@ -130,29 +171,32 @@ module Solargraph
|
|
|
130
171
|
|
|
131
172
|
private
|
|
132
173
|
|
|
133
|
-
# @return [RBS::EnvironmentLoader]
|
|
134
|
-
def loader
|
|
135
|
-
@loader ||= RBS::EnvironmentLoader.new(core_root: nil, repository: repository)
|
|
136
|
-
end
|
|
137
|
-
|
|
138
174
|
# @return [Conversions]
|
|
139
175
|
def conversions
|
|
140
176
|
@conversions ||= Conversions.new(loader: loader)
|
|
141
177
|
end
|
|
142
178
|
|
|
179
|
+
def resolve_dependencies?
|
|
180
|
+
# we need to resolve dependencies via gemfile.lock manually for
|
|
181
|
+
# YARD regardless, so use same mechanism here so we don't
|
|
182
|
+
# duplicate work generating pins from dependencies
|
|
183
|
+
false
|
|
184
|
+
end
|
|
185
|
+
|
|
143
186
|
# @param loader [RBS::EnvironmentLoader]
|
|
144
187
|
# @param library [String]
|
|
145
|
-
# @param version [String, nil]
|
|
188
|
+
# @param version [String, nil] the version of the library to load, or nil for any
|
|
189
|
+
# @param out [StringIO, IO, nil] where to log messages
|
|
146
190
|
# @return [Boolean] true if adding the library succeeded
|
|
147
|
-
def add_library loader, library, version
|
|
191
|
+
def add_library loader, library, version, out: $stderr
|
|
148
192
|
@resolved = if loader.has_library?(library: library, version: version)
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
193
|
+
loader.add library: library, version: version, resolve_dependencies: resolve_dependencies?
|
|
194
|
+
logger.debug { "#{short_name} successfully loaded library #{library}:#{version}" }
|
|
195
|
+
true
|
|
196
|
+
else
|
|
197
|
+
logger.info { "#{short_name} did not find data for library #{library}:#{version}" }
|
|
198
|
+
false
|
|
199
|
+
end
|
|
156
200
|
end
|
|
157
201
|
|
|
158
202
|
# @return [String]
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
# Convert RBS types to complex types and pins.
|
|
5
|
+
#
|
|
6
|
+
module RbsTranslator
|
|
7
|
+
RBS_TO_YARD_TYPE = {
|
|
8
|
+
'bool' => 'Boolean',
|
|
9
|
+
'string' => 'String',
|
|
10
|
+
'int' => 'Integer',
|
|
11
|
+
'untyped' => '',
|
|
12
|
+
'NilClass' => 'nil'
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
# @param type [RBS::Types::Bases::Base]
|
|
16
|
+
# @return [ComplexType]
|
|
17
|
+
def self.to_complex_type(type)
|
|
18
|
+
tag = type_to_tag(type)
|
|
19
|
+
ComplexType.try_parse(tag).force_rooted
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @param param_type [RBS::Types::Function::Param]
|
|
23
|
+
# @param name [String]
|
|
24
|
+
# @param decl [Symbol]
|
|
25
|
+
# @param closure [Pin::Closure]
|
|
26
|
+
# @return [Pin::Parameter]
|
|
27
|
+
def self.to_parameter_pin(param_type, name, decl, closure)
|
|
28
|
+
return_type = if decl == :restarg
|
|
29
|
+
ComplexType.parse('Array')
|
|
30
|
+
elsif decl == :kwrestarg
|
|
31
|
+
ComplexType.parse('Hash{Symbol => Object}')
|
|
32
|
+
else
|
|
33
|
+
RbsTranslator.to_complex_type(param_type.type)
|
|
34
|
+
end
|
|
35
|
+
Solargraph::Pin::Parameter.new(decl: decl, name: name, closure: closure, return_type: return_type, source: :rbs, type_location: to_sg_location(param_type.location) || closure.type_location)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @param method_type [RBS::MethodType]
|
|
39
|
+
# @param closure [Pin::Closure]
|
|
40
|
+
# @param parameter_names [Array<String>]
|
|
41
|
+
# @return [Array<Pin::Parameter>]
|
|
42
|
+
def self.to_parameter_pins method_type, closure, parameter_names = []
|
|
43
|
+
if defined?(RBS::Types::UntypedFunction) && method_type.type.is_a?(RBS::Types::UntypedFunction)
|
|
44
|
+
return [
|
|
45
|
+
Solargraph::Pin::Parameter.new(decl: :restarg, name: 'arg', closure: closure, source: :rbs)
|
|
46
|
+
]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
arg_num = 0
|
|
50
|
+
params = []
|
|
51
|
+
method_type.type.required_positionals.each do |param|
|
|
52
|
+
params.push RbsTranslator.to_parameter_pin(param, param.name&.to_s || parameter_names[arg_num] || "arg_#{arg_num}", :arg, closure)
|
|
53
|
+
arg_num += 1
|
|
54
|
+
end
|
|
55
|
+
method_type.type.optional_positionals.each do |param|
|
|
56
|
+
params.push RbsTranslator.to_parameter_pin(param, param.name&.to_s || parameter_names[arg_num] || "arg_#{arg_num}", :optarg, closure)
|
|
57
|
+
arg_num += 1
|
|
58
|
+
end
|
|
59
|
+
if method_type.type.rest_positionals
|
|
60
|
+
params.push RbsTranslator.to_parameter_pin(method_type.type.rest_positionals, method_type.type.rest_positionals.name&.to_s || parameter_names[arg_num] || "arg_#{arg_num}", :restarg, closure)
|
|
61
|
+
arg_num += 1
|
|
62
|
+
end
|
|
63
|
+
method_type.type.required_keywords.each do |param|
|
|
64
|
+
params.push RbsTranslator.to_parameter_pin(param.last, param.first.to_s, :kwarg, closure)
|
|
65
|
+
arg_num += 1
|
|
66
|
+
end
|
|
67
|
+
method_type.type.optional_keywords.each do |param|
|
|
68
|
+
params.push RbsTranslator.to_parameter_pin(param.last, param.first.to_s, :kwoptarg, closure)
|
|
69
|
+
arg_num += 1
|
|
70
|
+
end
|
|
71
|
+
if method_type.type.rest_keywords
|
|
72
|
+
params.push RbsTranslator.to_parameter_pin(method_type.type.rest_keywords, method_type.type.rest_keywords.name&.to_s || parameter_names[arg_num] || "arg_#{arg_num}", :kwrestarg, closure)
|
|
73
|
+
end
|
|
74
|
+
params
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @param method_type [RBS::MethodType]
|
|
78
|
+
# @param closure [Pin::Closure]
|
|
79
|
+
# @param parameter_names [Array<String>]
|
|
80
|
+
# @return [Pin::Signature]
|
|
81
|
+
def self.to_signature method_type, closure, parameter_names = []
|
|
82
|
+
# There may be edge cases here around different signatures
|
|
83
|
+
# having different type params / orders - we may need to match
|
|
84
|
+
# this data model and have generics live in signatures to
|
|
85
|
+
# handle those correctly
|
|
86
|
+
generics = method_type.type_params.map(&:name).map(&:to_s).uniq
|
|
87
|
+
parameters = to_parameter_pins(method_type, closure, parameter_names)
|
|
88
|
+
return_type = to_complex_type(method_type.type.return_type)
|
|
89
|
+
block = if method_type.block
|
|
90
|
+
block_parameters = to_parameter_pins(method_type.block, closure)
|
|
91
|
+
block_return_type = to_complex_type(method_type.block.type.return_type)
|
|
92
|
+
Pin::Signature.new(generics: generics, parameters: block_parameters, return_type: block_return_type, source: :rbs, type_location: closure.location, closure: closure)
|
|
93
|
+
end
|
|
94
|
+
Pin::Signature.new(generics: generics, parameters: parameters, return_type: return_type, block: block, source: :rbs, type_location: closure.location, closure: closure)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# @param type_name [RBS::TypeName]
|
|
98
|
+
# @param type_args [Enumerable<RBS::Types::Bases::Base>]
|
|
99
|
+
# @return [ComplexType::UniqueType]
|
|
100
|
+
def self.build_unique_type(type_name, type_args = [])
|
|
101
|
+
base = RBS_TO_YARD_TYPE[type_name.relative!.to_s] || type_name.relative!.to_s
|
|
102
|
+
params = type_args.map do |a|
|
|
103
|
+
RbsTranslator.to_complex_type(a)
|
|
104
|
+
end
|
|
105
|
+
if base == 'Hash' && params.length == 2
|
|
106
|
+
ComplexType::UniqueType.new(base, [params.first], [params.last], rooted: true, parameters_type: :hash)
|
|
107
|
+
else
|
|
108
|
+
ComplexType::UniqueType.new(base, [], params.reject(&:undefined?), rooted: true, parameters_type: :list)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# @param location [RBS::Location, nil]
|
|
113
|
+
# @return [Solargraph::Location, nil]
|
|
114
|
+
def self.to_sg_location(location)
|
|
115
|
+
return nil if location&.name.nil?
|
|
116
|
+
|
|
117
|
+
start_pos = Position.new(location.start_line - 1, location.start_column)
|
|
118
|
+
end_pos = Position.new(location.end_line - 1, location.end_column)
|
|
119
|
+
range = Range.new(start_pos, end_pos)
|
|
120
|
+
Location.new(location.name.to_s, range)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
class << self
|
|
124
|
+
private
|
|
125
|
+
|
|
126
|
+
# @param type [RBS::Types::Bases::Base]
|
|
127
|
+
# @return [String]
|
|
128
|
+
def type_to_tag type
|
|
129
|
+
case type
|
|
130
|
+
when RBS::Types::Optional
|
|
131
|
+
"#{type_to_tag(type.type)}, nil"
|
|
132
|
+
when RBS::Types::Bases::Bool
|
|
133
|
+
'Boolean'
|
|
134
|
+
when RBS::Types::Tuple
|
|
135
|
+
"Array(#{type.types.map { |t| type_to_tag(t) }.join(', ')})"
|
|
136
|
+
when RBS::Types::Literal
|
|
137
|
+
type.literal.inspect
|
|
138
|
+
when RBS::Types::Union
|
|
139
|
+
type.types.map { |t| type_to_tag(t) }.join(', ')
|
|
140
|
+
when RBS::Types::Record
|
|
141
|
+
# @todo Better record support
|
|
142
|
+
'Hash'
|
|
143
|
+
when RBS::Types::Bases::Nil
|
|
144
|
+
'nil'
|
|
145
|
+
when RBS::Types::Bases::Void
|
|
146
|
+
'void'
|
|
147
|
+
when RBS::Types::Variable
|
|
148
|
+
"#{Solargraph::ComplexType::GENERIC_TAG_NAME}<#{type.name}>"
|
|
149
|
+
when RBS::Types::Bases::Self, RBS::Types::Bases::Instance
|
|
150
|
+
'self'
|
|
151
|
+
when RBS::Types::Bases::Top
|
|
152
|
+
# `Top` is the most super superclass
|
|
153
|
+
'BasicObject'
|
|
154
|
+
when RBS::Types::Intersection
|
|
155
|
+
type.types.map { |member| type_to_tag(member) }.join(', ')
|
|
156
|
+
when RBS::Types::Proc
|
|
157
|
+
'Proc'
|
|
158
|
+
when RBS::Types::ClassInstance, RBS::Types::Alias, RBS::Types::Interface
|
|
159
|
+
# `Alias` is a top-level type alias, e.g., 'bool' in "type bool = true | false"
|
|
160
|
+
# @todo ensure these get resolved after processing all aliases
|
|
161
|
+
# @todo handle recursive aliases
|
|
162
|
+
#
|
|
163
|
+
# `Interface represents a mix-in module which can be considered a
|
|
164
|
+
# subtype of a consumer of it
|
|
165
|
+
#
|
|
166
|
+
type_tag(type.name, type.args)
|
|
167
|
+
when RBS::Types::ClassSingleton
|
|
168
|
+
# e.g., singleton(String)
|
|
169
|
+
type_tag(type.name)
|
|
170
|
+
when RBS::Types::Bases::Any, RBS::Types::Bases::Bottom
|
|
171
|
+
# `Bottom`` is used in contexts where nothing will ever return
|
|
172
|
+
# - e.g., it could be the return type of 'exit()' or 'raise'
|
|
173
|
+
# @todo define a specific bottom type and use it to
|
|
174
|
+
# determine dead code
|
|
175
|
+
#
|
|
176
|
+
'undefined'
|
|
177
|
+
else
|
|
178
|
+
Solargraph.logger.warn "Unrecognized RBS type: #{type.class} at #{type.location}"
|
|
179
|
+
'undefined'
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# @param type_name [RBS::TypeName]
|
|
184
|
+
# @param type_args [Enumerable<RBS::Types::Bases::Base>]
|
|
185
|
+
# @return [String]
|
|
186
|
+
def type_tag(type_name, type_args = [])
|
|
187
|
+
build_type(type_name, type_args).tags
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# @param type_name [RBS::TypeName]
|
|
191
|
+
# @param type_args [Enumerable<RBS::Types::Bases::Base>]
|
|
192
|
+
# @return [ComplexType::UniqueType]
|
|
193
|
+
def build_type(type_name, type_args = [])
|
|
194
|
+
base = RBS_TO_YARD_TYPE[type_name.relative!.to_s] || type_name.relative!.to_s
|
|
195
|
+
params = type_args.map { |a| type_to_tag(a) }.map do |t|
|
|
196
|
+
ComplexType.try_parse(t)
|
|
197
|
+
end
|
|
198
|
+
if base == 'Hash' && params.length == 2
|
|
199
|
+
ComplexType::UniqueType.new(base, [params.first], [params.last], rooted: true, parameters_type: :hash)
|
|
200
|
+
else
|
|
201
|
+
ComplexType::UniqueType.new(base, [], params.reject(&:undefined?), rooted: true, parameters_type: :list)
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|