solargraph 0.56.2 → 0.58.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/linting.yml +127 -0
- data/.github/workflows/plugins.yml +183 -7
- data/.github/workflows/rspec.yml +55 -5
- data/.github/workflows/typecheck.yml +6 -3
- data/.gitignore +5 -0
- data/.overcommit.yml +72 -0
- data/.rspec +1 -0
- data/.rubocop.yml +66 -0
- data/.rubocop_todo.yml +1279 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +69 -0
- data/README.md +8 -4
- data/Rakefile +125 -13
- data/bin/solargraph +8 -5
- data/lib/solargraph/api_map/cache.rb +3 -2
- data/lib/solargraph/api_map/constants.rb +279 -0
- data/lib/solargraph/api_map/index.rb +49 -31
- data/lib/solargraph/api_map/source_to_yard.rb +13 -4
- data/lib/solargraph/api_map/store.rb +144 -26
- data/lib/solargraph/api_map.rb +217 -245
- data/lib/solargraph/bench.rb +1 -0
- data/lib/solargraph/complex_type/type_methods.rb +6 -0
- data/lib/solargraph/complex_type/unique_type.rb +19 -12
- data/lib/solargraph/complex_type.rb +24 -3
- data/lib/solargraph/convention/active_support_concern.rb +111 -0
- data/lib/solargraph/convention/base.rb +17 -0
- data/lib/solargraph/convention/data_definition/data_assignment_node.rb +1 -0
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +4 -2
- data/lib/solargraph/convention/data_definition.rb +2 -1
- data/lib/solargraph/convention/gemspec.rb +1 -1
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +1 -0
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +3 -1
- data/lib/solargraph/convention/struct_definition.rb +36 -13
- data/lib/solargraph/convention.rb +31 -2
- data/lib/solargraph/diagnostics/rubocop.rb +6 -1
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
- data/lib/solargraph/doc_map.rb +44 -13
- data/lib/solargraph/environ.rb +9 -2
- data/lib/solargraph/equality.rb +1 -0
- data/lib/solargraph/gem_pins.rb +21 -11
- data/lib/solargraph/language_server/host/dispatch.rb +2 -0
- data/lib/solargraph/language_server/host/message_worker.rb +3 -0
- data/lib/solargraph/language_server/host.rb +12 -5
- data/lib/solargraph/language_server/message/base.rb +2 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/definition.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/formatting.rb +19 -2
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +1 -0
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
- data/lib/solargraph/language_server/progress.rb +8 -0
- data/lib/solargraph/language_server/request.rb +4 -1
- data/lib/solargraph/library.rb +11 -18
- data/lib/solargraph/location.rb +3 -0
- data/lib/solargraph/logging.rb +11 -2
- data/lib/solargraph/page.rb +3 -0
- data/lib/solargraph/parser/comment_ripper.rb +8 -1
- data/lib/solargraph/parser/flow_sensitive_typing.rb +33 -5
- data/lib/solargraph/parser/node_processor/base.rb +1 -1
- data/lib/solargraph/parser/node_processor.rb +6 -2
- data/lib/solargraph/parser/parser_gem/class_methods.rb +3 -13
- data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +3 -1
- data/lib/solargraph/parser/parser_gem/node_methods.rb +5 -16
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +3 -2
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +2 -0
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -0
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +64 -8
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +12 -3
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +36 -16
- data/lib/solargraph/parser/region.rb +3 -0
- data/lib/solargraph/parser/snippet.rb +2 -0
- data/lib/solargraph/pin/base.rb +77 -14
- data/lib/solargraph/pin/base_variable.rb +6 -5
- data/lib/solargraph/pin/block.rb +3 -2
- data/lib/solargraph/pin/callable.rb +14 -1
- data/lib/solargraph/pin/closure.rb +5 -7
- data/lib/solargraph/pin/common.rb +6 -2
- data/lib/solargraph/pin/constant.rb +2 -0
- data/lib/solargraph/pin/local_variable.rb +1 -2
- data/lib/solargraph/pin/method.rb +28 -9
- data/lib/solargraph/pin/method_alias.rb +3 -0
- data/lib/solargraph/pin/parameter.rb +24 -10
- data/lib/solargraph/pin/proxy_type.rb +5 -1
- data/lib/solargraph/pin/reference/override.rb +15 -1
- data/lib/solargraph/pin/reference/superclass.rb +5 -0
- data/lib/solargraph/pin/reference.rb +17 -0
- data/lib/solargraph/pin/search.rb +6 -1
- data/lib/solargraph/pin/signature.rb +2 -0
- data/lib/solargraph/pin/symbol.rb +5 -0
- data/lib/solargraph/pin_cache.rb +64 -4
- data/lib/solargraph/position.rb +3 -0
- data/lib/solargraph/range.rb +5 -0
- data/lib/solargraph/rbs_map/conversions.rb +29 -6
- data/lib/solargraph/rbs_map/core_fills.rb +18 -0
- data/lib/solargraph/rbs_map/core_map.rb +14 -7
- data/lib/solargraph/rbs_map.rb +14 -1
- data/lib/solargraph/shell.rb +85 -1
- data/lib/solargraph/source/chain/call.rb +7 -3
- data/lib/solargraph/source/chain/constant.rb +3 -66
- data/lib/solargraph/source/chain/if.rb +1 -1
- data/lib/solargraph/source/chain/link.rb +11 -2
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain.rb +11 -2
- data/lib/solargraph/source/change.rb +2 -2
- data/lib/solargraph/source/cursor.rb +2 -3
- data/lib/solargraph/source/source_chainer.rb +1 -1
- data/lib/solargraph/source.rb +6 -3
- data/lib/solargraph/source_map/clip.rb +18 -26
- data/lib/solargraph/source_map/data.rb +4 -0
- data/lib/solargraph/source_map/mapper.rb +2 -2
- data/lib/solargraph/source_map.rb +28 -16
- data/lib/solargraph/type_checker/param_def.rb +2 -0
- data/lib/solargraph/type_checker/rules.rb +30 -8
- data/lib/solargraph/type_checker.rb +301 -186
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +21 -5
- data/lib/solargraph/workspace/require_paths.rb +97 -0
- data/lib/solargraph/workspace.rb +30 -67
- data/lib/solargraph/yard_map/mapper/to_method.rb +4 -3
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -0
- data/lib/solargraph/yard_map/to_method.rb +2 -1
- data/lib/solargraph/yardoc.rb +39 -3
- data/lib/solargraph.rb +2 -0
- data/rbs/fills/bundler/0/bundler.rbs +4271 -0
- data/rbs/fills/open3/0/open3.rbs +172 -0
- data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
- data/rbs/fills/rubygems/0/errors.rbs +364 -0
- data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
- data/rbs/fills/rubygems/0/specification.rbs +1753 -0
- data/rbs/fills/{tuple.rbs → tuple/tuple.rbs} +2 -3
- data/rbs_collection.yaml +4 -4
- data/sig/shims/ast/0/node.rbs +5 -0
- data/sig/shims/ast/2.4/.rbs_meta.yaml +9 -0
- data/sig/shims/ast/2.4/ast.rbs +73 -0
- data/sig/shims/parser/3.2.0.1/builders/default.rbs +195 -0
- data/sig/shims/parser/3.2.0.1/manifest.yaml +7 -0
- data/sig/shims/parser/3.2.0.1/parser.rbs +201 -0
- data/sig/shims/parser/3.2.0.1/polyfill.rbs +4 -0
- data/sig/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
- data/sig/shims/thor/1.2.0.1/manifest.yaml +7 -0
- data/sig/shims/thor/1.2.0.1/thor.rbs +17 -0
- data/solargraph.gemspec +26 -5
- metadata +181 -13
- data/lib/.rubocop.yml +0 -22
- data/lib/solargraph/parser/node_methods.rb +0 -97
|
@@ -65,6 +65,7 @@ module Solargraph
|
|
|
65
65
|
# STDERR.puts "Skipping interface #{decl.name.relative!}"
|
|
66
66
|
interface_decl_to_pin decl, closure
|
|
67
67
|
when RBS::AST::Declarations::TypeAlias
|
|
68
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1114
|
|
68
69
|
type_aliases[decl.name.to_s] = decl
|
|
69
70
|
when RBS::AST::Declarations::Module
|
|
70
71
|
module_decl_to_pin decl
|
|
@@ -163,9 +164,10 @@ module Solargraph
|
|
|
163
164
|
generic_defaults[param.name.to_s] = ComplexType.parse(tag).force_rooted
|
|
164
165
|
end
|
|
165
166
|
end
|
|
167
|
+
class_name = decl.name.relative!.to_s
|
|
166
168
|
class_pin = Solargraph::Pin::Namespace.new(
|
|
167
169
|
type: :class,
|
|
168
|
-
name:
|
|
170
|
+
name: class_name,
|
|
169
171
|
closure: Solargraph::Pin::ROOT_PIN,
|
|
170
172
|
comments: decl.comment&.string,
|
|
171
173
|
type_location: location_decl_to_pin_location(decl.location),
|
|
@@ -180,11 +182,12 @@ module Solargraph
|
|
|
180
182
|
if decl.super_class
|
|
181
183
|
type = build_type(decl.super_class.name, decl.super_class.args)
|
|
182
184
|
generic_values = type.all_params.map(&:to_s)
|
|
185
|
+
superclass_name = decl.super_class.name.to_s
|
|
183
186
|
pins.push Solargraph::Pin::Reference::Superclass.new(
|
|
184
187
|
type_location: location_decl_to_pin_location(decl.super_class.location),
|
|
185
188
|
closure: class_pin,
|
|
186
189
|
generic_values: generic_values,
|
|
187
|
-
name:
|
|
190
|
+
name: superclass_name,
|
|
188
191
|
source: :rbs
|
|
189
192
|
)
|
|
190
193
|
end
|
|
@@ -345,7 +348,7 @@ module Solargraph
|
|
|
345
348
|
}
|
|
346
349
|
|
|
347
350
|
# @param decl [RBS::AST::Members::MethodDefinition, RBS::AST::Members::AttrReader, RBS::AST::Members::AttrAccessor]
|
|
348
|
-
# @param closure [Pin::
|
|
351
|
+
# @param closure [Pin::Closure]
|
|
349
352
|
# @param context [Context]
|
|
350
353
|
# @param scope [Symbol] :instance or :class
|
|
351
354
|
# @param name [String] The name of the method
|
|
@@ -424,6 +427,7 @@ module Solargraph
|
|
|
424
427
|
# @param pin [Pin::Method]
|
|
425
428
|
# @return [void]
|
|
426
429
|
def method_def_to_sigs decl, pin
|
|
430
|
+
# @param overload [RBS::AST::Members::MethodDefinition::Overload]
|
|
427
431
|
decl.overloads.map do |overload|
|
|
428
432
|
type_location = location_decl_to_pin_location(overload.method_type.location)
|
|
429
433
|
generics = overload.method_type.type_params.map(&:name).map(&:to_s)
|
|
@@ -464,33 +468,50 @@ module Solargraph
|
|
|
464
468
|
parameters = []
|
|
465
469
|
arg_num = -1
|
|
466
470
|
type.type.required_positionals.each do |param|
|
|
471
|
+
# @sg-ignore RBS generic type understanding issue
|
|
467
472
|
name = param.name ? param.name.to_s : "arg_#{arg_num += 1}"
|
|
473
|
+
# @sg-ignore RBS generic type understanding issue
|
|
468
474
|
parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted, source: :rbs, type_location: type_location)
|
|
469
475
|
end
|
|
470
476
|
type.type.optional_positionals.each do |param|
|
|
477
|
+
# @sg-ignore RBS generic type understanding issue
|
|
471
478
|
name = param.name ? param.name.to_s : "arg_#{arg_num += 1}"
|
|
472
479
|
parameters.push Solargraph::Pin::Parameter.new(decl: :optarg, name: name, closure: pin,
|
|
480
|
+
# @sg-ignore RBS generic type understanding issue
|
|
473
481
|
return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted,
|
|
474
482
|
type_location: type_location,
|
|
475
483
|
source: :rbs)
|
|
476
484
|
end
|
|
477
485
|
if type.type.rest_positionals
|
|
478
486
|
name = type.type.rest_positionals.name ? type.type.rest_positionals.name.to_s : "arg_#{arg_num += 1}"
|
|
479
|
-
|
|
487
|
+
inner_rest_positional_type =
|
|
488
|
+
ComplexType.try_parse(other_type_to_tag(type.type.rest_positionals.type))
|
|
489
|
+
rest_positional_type = ComplexType::UniqueType.new('Array',
|
|
490
|
+
[],
|
|
491
|
+
[inner_rest_positional_type],
|
|
492
|
+
rooted: true, parameters_type: :list)
|
|
493
|
+
parameters.push Solargraph::Pin::Parameter.new(decl: :restarg, name: name, closure: pin,
|
|
494
|
+
source: :rbs, type_location: type_location,
|
|
495
|
+
return_type: rest_positional_type,)
|
|
480
496
|
end
|
|
481
497
|
type.type.trailing_positionals.each do |param|
|
|
498
|
+
# @sg-ignore RBS generic type understanding issue
|
|
482
499
|
name = param.name ? param.name.to_s : "arg_#{arg_num += 1}"
|
|
483
500
|
parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, source: :rbs, type_location: type_location)
|
|
484
501
|
end
|
|
485
502
|
type.type.required_keywords.each do |orig, param|
|
|
503
|
+
# @sg-ignore RBS generic type understanding issue
|
|
486
504
|
name = orig ? orig.to_s : "arg_#{arg_num += 1}"
|
|
487
505
|
parameters.push Solargraph::Pin::Parameter.new(decl: :kwarg, name: name, closure: pin,
|
|
506
|
+
# @sg-ignore RBS generic type understanding issue
|
|
488
507
|
return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted,
|
|
489
508
|
source: :rbs, type_location: type_location)
|
|
490
509
|
end
|
|
491
510
|
type.type.optional_keywords.each do |orig, param|
|
|
511
|
+
# @sg-ignore RBS generic type understanding issue
|
|
492
512
|
name = orig ? orig.to_s : "arg_#{arg_num += 1}"
|
|
493
513
|
parameters.push Solargraph::Pin::Parameter.new(decl: :kwoptarg, name: name, closure: pin,
|
|
514
|
+
# @sg-ignore RBS generic type understanding issue
|
|
494
515
|
return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted,
|
|
495
516
|
type_location: type_location,
|
|
496
517
|
source: :rbs)
|
|
@@ -699,13 +720,13 @@ module Solargraph
|
|
|
699
720
|
# @return [ComplexType::UniqueType]
|
|
700
721
|
def build_type(type_name, type_args = [])
|
|
701
722
|
base = RBS_TO_YARD_TYPE[type_name.relative!.to_s] || type_name.relative!.to_s
|
|
702
|
-
params = type_args.map { |a| other_type_to_tag(a) }.
|
|
723
|
+
params = type_args.map { |a| other_type_to_tag(a) }.map do |t|
|
|
703
724
|
ComplexType.try_parse(t).force_rooted
|
|
704
725
|
end
|
|
705
726
|
if base == 'Hash' && params.length == 2
|
|
706
727
|
ComplexType::UniqueType.new(base, [params.first], [params.last], rooted: true, parameters_type: :hash)
|
|
707
728
|
else
|
|
708
|
-
ComplexType::UniqueType.new(base, [], params, rooted: true, parameters_type: :list)
|
|
729
|
+
ComplexType::UniqueType.new(base, [], params.reject(&:undefined?), rooted: true, parameters_type: :list)
|
|
709
730
|
end
|
|
710
731
|
end
|
|
711
732
|
|
|
@@ -782,7 +803,9 @@ module Solargraph
|
|
|
782
803
|
# @param namespace [Pin::Namespace]
|
|
783
804
|
# @return [void]
|
|
784
805
|
def add_mixins decl, namespace
|
|
806
|
+
# @param mixin [RBS::AST::Members::Include, RBS::AST::Members::Members::Extend, RBS::AST::Members::Members::Prepend]
|
|
785
807
|
decl.each_mixin do |mixin|
|
|
808
|
+
# @todo are we handling prepend correctly?
|
|
786
809
|
klass = mixin.is_a?(RBS::AST::Members::Include) ? Pin::Reference::Include : Pin::Reference::Extend
|
|
787
810
|
type = build_type(mixin.name, mixin.args)
|
|
788
811
|
generic_values = type.all_params.map(&:to_s)
|
|
@@ -48,6 +48,24 @@ module Solargraph
|
|
|
48
48
|
Solargraph::Pin::Reference::Include.new(name: '_ToAry',
|
|
49
49
|
closure: Solargraph::Pin::Namespace.new(name: 'Array', source: :core_fill),
|
|
50
50
|
generic_values: ['generic<Elem>'],
|
|
51
|
+
source: :core_fill),
|
|
52
|
+
Solargraph::Pin::Reference::Include.new(name: '_ToAry',
|
|
53
|
+
closure: Solargraph::Pin::Namespace.new(name: 'Set', source: :core_fill),
|
|
54
|
+
generic_values: ['generic<Elem>'],
|
|
55
|
+
source: :core_fill),
|
|
56
|
+
Solargraph::Pin::Reference::Include.new(name: '_Each',
|
|
57
|
+
closure: Solargraph::Pin::Namespace.new(name: 'Array', source: :core_fill),
|
|
58
|
+
generic_values: ['generic<Elem>'],
|
|
59
|
+
source: :core_fill),
|
|
60
|
+
Solargraph::Pin::Reference::Include.new(name: '_Each',
|
|
61
|
+
closure: Solargraph::Pin::Namespace.new(name: 'Set', source: :core_fill),
|
|
62
|
+
generic_values: ['generic<Elem>'],
|
|
63
|
+
source: :core_fill),
|
|
64
|
+
Solargraph::Pin::Reference::Include.new(name: '_ToS',
|
|
65
|
+
closure: Solargraph::Pin::Namespace.new(name: 'Object', source: :core_fill),
|
|
66
|
+
source: :core_fill),
|
|
67
|
+
Solargraph::Pin::Reference::Include.new(name: '_ToS',
|
|
68
|
+
closure: Solargraph::Pin::Namespace.new(name: 'String', source: :core_fill),
|
|
51
69
|
source: :core_fill)
|
|
52
70
|
]
|
|
53
71
|
|
|
@@ -5,15 +5,17 @@ module Solargraph
|
|
|
5
5
|
# Ruby core pins
|
|
6
6
|
#
|
|
7
7
|
class CoreMap
|
|
8
|
+
include Logging
|
|
8
9
|
|
|
9
10
|
def resolved?
|
|
10
11
|
true
|
|
11
12
|
end
|
|
12
13
|
|
|
13
|
-
FILLS_DIRECTORY = File.join(File.dirname(__FILE__), '..', '..', '..', 'rbs', 'fills')
|
|
14
|
+
FILLS_DIRECTORY = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'rbs', 'fills'))
|
|
14
15
|
|
|
15
16
|
def initialize; end
|
|
16
17
|
|
|
18
|
+
# @return [Enumerable<Pin::Base>]
|
|
17
19
|
def pins
|
|
18
20
|
return @pins if @pins
|
|
19
21
|
|
|
@@ -22,9 +24,16 @@ module Solargraph
|
|
|
22
24
|
if cache
|
|
23
25
|
@pins.replace cache
|
|
24
26
|
else
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
@pins.concat conversions.pins
|
|
28
|
+
|
|
29
|
+
# Avoid RBS::DuplicatedDeclarationError by loading in a different EnvironmentLoader
|
|
30
|
+
fill_loader = RBS::EnvironmentLoader.new(core_root: nil, repository: RBS::Repository.new(no_stdlib: false))
|
|
31
|
+
fill_loader.add(path: Pathname(FILLS_DIRECTORY))
|
|
32
|
+
fill_conversions = Conversions.new(loader: fill_loader)
|
|
33
|
+
@pins.concat fill_conversions.pins
|
|
34
|
+
|
|
27
35
|
@pins.concat RbsMap::CoreFills::ALL
|
|
36
|
+
|
|
28
37
|
processed = ApiMap::Store.new(pins).pins.reject { |p| p.is_a?(Solargraph::Pin::Reference::Override) }
|
|
29
38
|
@pins.replace processed
|
|
30
39
|
|
|
@@ -33,16 +42,14 @@ module Solargraph
|
|
|
33
42
|
@pins
|
|
34
43
|
end
|
|
35
44
|
|
|
36
|
-
def loader
|
|
37
|
-
@loader ||= RBS::EnvironmentLoader.new(repository: RBS::Repository.new(no_stdlib: false))
|
|
38
|
-
end
|
|
39
|
-
|
|
40
45
|
private
|
|
41
46
|
|
|
47
|
+
# @return [RBS::EnvironmentLoader]
|
|
42
48
|
def loader
|
|
43
49
|
@loader ||= RBS::EnvironmentLoader.new(repository: RBS::Repository.new(no_stdlib: false))
|
|
44
50
|
end
|
|
45
51
|
|
|
52
|
+
# @return [Conversions]
|
|
46
53
|
def conversions
|
|
47
54
|
@conversions ||= Conversions.new(loader: loader)
|
|
48
55
|
end
|
data/lib/solargraph/rbs_map.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'digest'
|
|
3
4
|
require 'pathname'
|
|
4
5
|
require 'rbs'
|
|
5
6
|
|
|
@@ -23,6 +24,7 @@ module Solargraph
|
|
|
23
24
|
|
|
24
25
|
# @param library [String]
|
|
25
26
|
# @param version [String, nil]
|
|
27
|
+
# @param rbs_collection_config_path [String, Pathname, nil]
|
|
26
28
|
# @param rbs_collection_paths [Array<Pathname, String>]
|
|
27
29
|
def initialize library, version = nil, rbs_collection_config_path: nil, rbs_collection_paths: []
|
|
28
30
|
if rbs_collection_config_path.nil? && !rbs_collection_paths.empty?
|
|
@@ -35,16 +37,18 @@ module Solargraph
|
|
|
35
37
|
add_library loader, library, version
|
|
36
38
|
end
|
|
37
39
|
|
|
40
|
+
# @return [RBS::EnvironmentLoader]
|
|
38
41
|
def loader
|
|
39
42
|
@loader ||= RBS::EnvironmentLoader.new(core_root: nil, repository: repository)
|
|
40
43
|
end
|
|
41
44
|
|
|
42
|
-
# @return
|
|
45
|
+
# @return [String] representing the version of the RBS info fetched
|
|
43
46
|
# for the given library. Must change when the RBS info is
|
|
44
47
|
# updated upstream for the same library and version. May change
|
|
45
48
|
# if the config for where information comes form changes.
|
|
46
49
|
def cache_key
|
|
47
50
|
@hextdigest ||= begin
|
|
51
|
+
# @type [String, nil]
|
|
48
52
|
data = nil
|
|
49
53
|
if rbs_collection_config_path
|
|
50
54
|
lockfile_path = RBS::Collection::Config.to_lockfile_path(Pathname.new(rbs_collection_config_path))
|
|
@@ -68,6 +72,10 @@ module Solargraph
|
|
|
68
72
|
end
|
|
69
73
|
end
|
|
70
74
|
|
|
75
|
+
# @param gemspec [Gem::Specification, Bundler::LazySpecification]
|
|
76
|
+
# @param rbs_collection_path [String, Pathname, nil]
|
|
77
|
+
# @param rbs_collection_config_path [String, Pathname, nil]
|
|
78
|
+
# @return [RbsMap]
|
|
71
79
|
def self.from_gemspec gemspec, rbs_collection_path, rbs_collection_config_path
|
|
72
80
|
rbs_map = RbsMap.new(gemspec.name, gemspec.version,
|
|
73
81
|
rbs_collection_paths: [rbs_collection_path].compact,
|
|
@@ -80,6 +88,7 @@ module Solargraph
|
|
|
80
88
|
rbs_collection_config_path: rbs_collection_config_path)
|
|
81
89
|
end
|
|
82
90
|
|
|
91
|
+
# @return [Array<Pin::Base>]
|
|
83
92
|
def pins
|
|
84
93
|
@pins ||= resolved? ? conversions.pins : []
|
|
85
94
|
end
|
|
@@ -103,6 +112,7 @@ module Solargraph
|
|
|
103
112
|
@resolved
|
|
104
113
|
end
|
|
105
114
|
|
|
115
|
+
# @return [RBS::Repository]
|
|
106
116
|
def repository
|
|
107
117
|
@repository ||= RBS::Repository.new(no_stdlib: false).tap do |repo|
|
|
108
118
|
@rbs_collection_paths.each do |dir|
|
|
@@ -120,16 +130,19 @@ module Solargraph
|
|
|
120
130
|
|
|
121
131
|
private
|
|
122
132
|
|
|
133
|
+
# @return [RBS::EnvironmentLoader]
|
|
123
134
|
def loader
|
|
124
135
|
@loader ||= RBS::EnvironmentLoader.new(core_root: nil, repository: repository)
|
|
125
136
|
end
|
|
126
137
|
|
|
138
|
+
# @return [Conversions]
|
|
127
139
|
def conversions
|
|
128
140
|
@conversions ||= Conversions.new(loader: loader)
|
|
129
141
|
end
|
|
130
142
|
|
|
131
143
|
# @param loader [RBS::EnvironmentLoader]
|
|
132
144
|
# @param library [String]
|
|
145
|
+
# @param version [String, nil]
|
|
133
146
|
# @return [Boolean] true if adding the library succeeded
|
|
134
147
|
def add_library loader, library, version
|
|
135
148
|
@resolved = if loader.has_library?(library: library, version: version)
|
data/lib/solargraph/shell.rb
CHANGED
|
@@ -36,6 +36,7 @@ module Solargraph
|
|
|
36
36
|
Signal.trap("TERM") do
|
|
37
37
|
Backport.stop
|
|
38
38
|
end
|
|
39
|
+
# @sg-ignore Wrong argument type for Backport.prepare_tcp_server: adapter expected Backport::Adapter, received Module<Solargraph::LanguageServer::Transport::Adapter>
|
|
39
40
|
Backport.prepare_tcp_server host: options[:host], port: port, adapter: Solargraph::LanguageServer::Transport::Adapter
|
|
40
41
|
STDERR.puts "Solargraph is listening PORT=#{port} PID=#{Process.pid}"
|
|
41
42
|
end
|
|
@@ -52,6 +53,7 @@ module Solargraph
|
|
|
52
53
|
Signal.trap("TERM") do
|
|
53
54
|
Backport.stop
|
|
54
55
|
end
|
|
56
|
+
# @sg-ignore Wrong argument type for Backport.prepare_stdio_server: adapter expected Backport::Adapter, received Module<Solargraph::LanguageServer::Transport::Adapter>
|
|
55
57
|
Backport.prepare_stdio_server adapter: Solargraph::LanguageServer::Transport::Adapter
|
|
56
58
|
STDERR.puts "Solargraph is listening on stdio PID=#{Process.pid}"
|
|
57
59
|
end
|
|
@@ -77,6 +79,7 @@ module Solargraph
|
|
|
77
79
|
conf['extensions'].push m
|
|
78
80
|
end
|
|
79
81
|
end
|
|
82
|
+
# @param file [File]
|
|
80
83
|
File.open(File.join(directory, '.solargraph.yml'), 'w') do |file|
|
|
81
84
|
file.puts conf.to_yaml
|
|
82
85
|
end
|
|
@@ -170,6 +173,9 @@ module Solargraph
|
|
|
170
173
|
# @return [void]
|
|
171
174
|
def typecheck *files
|
|
172
175
|
directory = File.realpath(options[:directory])
|
|
176
|
+
workspace = Solargraph::Workspace.new(directory)
|
|
177
|
+
level = options[:level].to_sym
|
|
178
|
+
rules = workspace.rules(level)
|
|
173
179
|
api_map = Solargraph::ApiMap.load_with_cache(directory, $stdout)
|
|
174
180
|
probcount = 0
|
|
175
181
|
if files.empty?
|
|
@@ -181,7 +187,7 @@ module Solargraph
|
|
|
181
187
|
|
|
182
188
|
time = Benchmark.measure {
|
|
183
189
|
files.each do |file|
|
|
184
|
-
checker = TypeChecker.new(file, api_map: api_map, level: options[:level].to_sym)
|
|
190
|
+
checker = TypeChecker.new(file, api_map: api_map, level: options[:level].to_sym, workspace: workspace)
|
|
185
191
|
problems = checker.problems
|
|
186
192
|
next if problems.empty?
|
|
187
193
|
problems.sort! { |a, b| a.location.range.start.line <=> b.location.range.start.line }
|
|
@@ -239,6 +245,63 @@ module Solargraph
|
|
|
239
245
|
puts "#{workspace.filenames.length} files total."
|
|
240
246
|
end
|
|
241
247
|
|
|
248
|
+
desc 'pin [PATH]', 'Describe a pin', hide: true
|
|
249
|
+
option :rbs, type: :boolean, desc: 'Output the pin as RBS', default: false
|
|
250
|
+
option :typify, type: :boolean, desc: 'Output the calculated return type of the pin from annotations', default: false
|
|
251
|
+
option :references, type: :boolean, desc: 'Show references', default: false
|
|
252
|
+
option :probe, type: :boolean, desc: 'Output the calculated return type of the pin from annotations and inference', default: false
|
|
253
|
+
option :stack, type: :boolean, desc: 'Show entire stack of a method pin by including definitions in superclasses', default: false
|
|
254
|
+
# @param path [String] The path to the method pin, e.g. 'Class#method' or 'Class.method'
|
|
255
|
+
# @return [void]
|
|
256
|
+
def pin path
|
|
257
|
+
api_map = Solargraph::ApiMap.load_with_cache('.', $stderr)
|
|
258
|
+
is_method = path.include?('#') || path.include?('.')
|
|
259
|
+
if is_method && options[:stack]
|
|
260
|
+
scope, ns, meth = if path.include? '#'
|
|
261
|
+
[:instance, *path.split('#', 2)]
|
|
262
|
+
else
|
|
263
|
+
[:class, *path.split('.', 2)]
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# @sg-ignore Wrong argument type for
|
|
267
|
+
# Solargraph::ApiMap#get_method_stack: rooted_tag
|
|
268
|
+
# expected String, received Array<String>
|
|
269
|
+
pins = api_map.get_method_stack(ns, meth, scope: scope)
|
|
270
|
+
else
|
|
271
|
+
pins = api_map.get_path_pins path
|
|
272
|
+
end
|
|
273
|
+
# @type [Hash{Symbol => Pin::Base}]
|
|
274
|
+
references = {}
|
|
275
|
+
pin = pins.first
|
|
276
|
+
case pin
|
|
277
|
+
when nil
|
|
278
|
+
$stderr.puts "Pin not found for path '#{path}'"
|
|
279
|
+
exit 1
|
|
280
|
+
when Pin::Namespace
|
|
281
|
+
if options[:references]
|
|
282
|
+
superclass_tag = api_map.qualify_superclass(pin.return_type.tag)
|
|
283
|
+
superclass_pin = api_map.get_path_pins(superclass_tag).first if superclass_tag
|
|
284
|
+
references[:superclass] = superclass_pin if superclass_pin
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
pins.each do |pin|
|
|
289
|
+
if options[:typify] || options[:probe]
|
|
290
|
+
type = ComplexType::UNDEFINED
|
|
291
|
+
type = pin.typify(api_map) if options[:typify]
|
|
292
|
+
type = pin.probe(api_map) if options[:probe] && type.undefined?
|
|
293
|
+
print_type(type)
|
|
294
|
+
next
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
print_pin(pin)
|
|
298
|
+
end
|
|
299
|
+
references.each do |key, refpin|
|
|
300
|
+
puts "\n# #{key.to_s.capitalize}:\n\n"
|
|
301
|
+
print_pin(refpin)
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
242
305
|
private
|
|
243
306
|
|
|
244
307
|
# @param pin [Solargraph::Pin::Base]
|
|
@@ -258,11 +321,32 @@ module Solargraph
|
|
|
258
321
|
end
|
|
259
322
|
|
|
260
323
|
# @param gemspec [Gem::Specification]
|
|
324
|
+
# @param api_map [ApiMap]
|
|
261
325
|
# @return [void]
|
|
262
326
|
def do_cache gemspec, api_map
|
|
263
327
|
# @todo if the rebuild: option is passed as a positional arg,
|
|
264
328
|
# typecheck doesn't complain on the below line
|
|
265
329
|
api_map.cache_gem(gemspec, rebuild: options.rebuild, out: $stdout)
|
|
266
330
|
end
|
|
331
|
+
|
|
332
|
+
# @param type [ComplexType]
|
|
333
|
+
# @return [void]
|
|
334
|
+
def print_type(type)
|
|
335
|
+
if options[:rbs]
|
|
336
|
+
puts type.to_rbs
|
|
337
|
+
else
|
|
338
|
+
puts type.rooted_tag
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
# @param pin [Solargraph::Pin::Base]
|
|
343
|
+
# @return [void]
|
|
344
|
+
def print_pin(pin)
|
|
345
|
+
if options[:rbs]
|
|
346
|
+
puts pin.to_rbs
|
|
347
|
+
else
|
|
348
|
+
puts pin.inspect
|
|
349
|
+
end
|
|
350
|
+
end
|
|
267
351
|
end
|
|
268
352
|
end
|
|
@@ -98,7 +98,10 @@ module Solargraph
|
|
|
98
98
|
match = ol.parameters.any?(&:restarg?)
|
|
99
99
|
break
|
|
100
100
|
end
|
|
101
|
-
|
|
101
|
+
arg_name_pin = Pin::ProxyType.anonymous(name_pin.context,
|
|
102
|
+
gates: name_pin.gates,
|
|
103
|
+
source: :chain)
|
|
104
|
+
atype = atypes[idx] ||= arg.infer(api_map, arg_name_pin, locals)
|
|
102
105
|
unless param.compatible_arg?(atype, api_map) || param.restarg?
|
|
103
106
|
match = false
|
|
104
107
|
break
|
|
@@ -137,7 +140,7 @@ module Solargraph
|
|
|
137
140
|
#
|
|
138
141
|
# qualify(), however, happens in the namespace where
|
|
139
142
|
# the docs were written - from the method pin.
|
|
140
|
-
type = with_params(new_return_type.self_to_type(self_type), self_type).qualify(api_map, p.
|
|
143
|
+
type = with_params(new_return_type.self_to_type(self_type), self_type).qualify(api_map, *p.gates) if new_return_type.defined?
|
|
141
144
|
type ||= ComplexType::UNDEFINED
|
|
142
145
|
end
|
|
143
146
|
break if type.defined?
|
|
@@ -266,8 +269,9 @@ module Solargraph
|
|
|
266
269
|
method_pin = find_method_pin(name_pin)
|
|
267
270
|
return [] unless method_pin
|
|
268
271
|
|
|
272
|
+
# @param signature_pin [Pin::Signature]
|
|
269
273
|
method_pin.signatures.map(&:block).compact.map do |signature_pin|
|
|
270
|
-
return_type = signature_pin.return_type.qualify(api_map, name_pin.
|
|
274
|
+
return_type = signature_pin.return_type.qualify(api_map, *name_pin.gates)
|
|
271
275
|
signature_pin.proxy(return_type)
|
|
272
276
|
end
|
|
273
277
|
end
|
|
@@ -15,73 +15,10 @@ module Solargraph
|
|
|
15
15
|
gates = ['']
|
|
16
16
|
else
|
|
17
17
|
base = word
|
|
18
|
-
gates =
|
|
18
|
+
gates = name_pin.gates
|
|
19
19
|
end
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
# @todo 'Wrong argument type for
|
|
23
|
-
# Solargraph::Source::Chain::Constant#deep_constant_type:
|
|
24
|
-
# gate expected String, received generic<Elem>' is because
|
|
25
|
-
# we lose 'rooted' information in the 'Chain::Array' class
|
|
26
|
-
# internally, leaving ::Array#each shadowed when it
|
|
27
|
-
# shouldn't be.
|
|
28
|
-
type = deep_constant_type(gate, api_map)
|
|
29
|
-
# Use deep inference to resolve root
|
|
30
|
-
parts[0..-2].each do |sym|
|
|
31
|
-
pins = api_map.get_constants('', type.namespace).select{ |pin| pin.name == sym }
|
|
32
|
-
type = first_pin_type(pins, api_map)
|
|
33
|
-
break if type.undefined?
|
|
34
|
-
end
|
|
35
|
-
next if type.undefined?
|
|
36
|
-
result = api_map.get_constants('', type.namespace).select { |pin| pin.name == parts.last }
|
|
37
|
-
return result unless result.empty?
|
|
38
|
-
end
|
|
39
|
-
[]
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
private
|
|
43
|
-
|
|
44
|
-
# @param pin [Pin::Closure]
|
|
45
|
-
# @return [::Array<String>]
|
|
46
|
-
def crawl_gates pin
|
|
47
|
-
clos = pin
|
|
48
|
-
until clos.nil?
|
|
49
|
-
if clos.is_a?(Pin::Namespace)
|
|
50
|
-
gates = clos.gates
|
|
51
|
-
gates.push('') if gates.empty?
|
|
52
|
-
return gates
|
|
53
|
-
end
|
|
54
|
-
clos = clos.closure
|
|
55
|
-
end
|
|
56
|
-
['']
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# @param pins [::Array<Pin::Base>]
|
|
60
|
-
# @param api_map [ApiMap]
|
|
61
|
-
# @return [ComplexType]
|
|
62
|
-
def first_pin_type(pins, api_map)
|
|
63
|
-
type = ComplexType::UNDEFINED
|
|
64
|
-
pins.each do |pin|
|
|
65
|
-
type = pin.typify(api_map)
|
|
66
|
-
break if type.defined?
|
|
67
|
-
type = pin.probe(api_map)
|
|
68
|
-
break if type.defined?
|
|
69
|
-
end
|
|
70
|
-
type
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
# @param gate [String]
|
|
74
|
-
# @param api_map [ApiMap]
|
|
75
|
-
# @return [ComplexType]
|
|
76
|
-
def deep_constant_type(gate, api_map)
|
|
77
|
-
type = ComplexType::ROOT
|
|
78
|
-
return type if gate == ''
|
|
79
|
-
gate.split('::').each do |word|
|
|
80
|
-
pins = api_map.get_constants('', type.namespace).select { |pin| pin.name == word }
|
|
81
|
-
type = first_pin_type(pins, api_map)
|
|
82
|
-
break if type.undefined?
|
|
83
|
-
end
|
|
84
|
-
type
|
|
20
|
+
fqns = api_map.resolve(base, gates)
|
|
21
|
+
api_map.get_path_pins(fqns)
|
|
85
22
|
end
|
|
86
23
|
end
|
|
87
24
|
end
|
|
@@ -17,7 +17,13 @@ module Solargraph
|
|
|
17
17
|
@word = word
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
# @sg-ignore
|
|
20
|
+
# @sg-ignore two problems - Declared return type
|
|
21
|
+
# ::Solargraph::Source::Chain::Array does not match inferred
|
|
22
|
+
# type ::Array(::Class<::Solargraph::Source::Chain::Link>,
|
|
23
|
+
# ::String) for
|
|
24
|
+
# Solargraph::Source::Chain::Link#equality_fields
|
|
25
|
+
# and
|
|
26
|
+
# Not enough arguments to Module#protected
|
|
21
27
|
protected def equality_fields
|
|
22
28
|
[self.class, word]
|
|
23
29
|
end
|
|
@@ -32,13 +38,14 @@ module Solargraph
|
|
|
32
38
|
|
|
33
39
|
# @param api_map [ApiMap]
|
|
34
40
|
# @param name_pin [Pin::Base]
|
|
35
|
-
# @param locals [::
|
|
41
|
+
# @param locals [::Array<Pin::Base>]
|
|
36
42
|
# @return [::Array<Pin::Base>]
|
|
37
43
|
def resolve api_map, name_pin, locals
|
|
38
44
|
[]
|
|
39
45
|
end
|
|
40
46
|
|
|
41
47
|
# debugging description of contents; not for machine use
|
|
48
|
+
# @return [String]
|
|
42
49
|
def desc
|
|
43
50
|
word
|
|
44
51
|
end
|
|
@@ -74,6 +81,8 @@ module Solargraph
|
|
|
74
81
|
end
|
|
75
82
|
|
|
76
83
|
# debugging description of contents; not for machine use
|
|
84
|
+
#
|
|
85
|
+
# @return [String]
|
|
77
86
|
def desc
|
|
78
87
|
word
|
|
79
88
|
end
|
|
@@ -15,6 +15,7 @@ module Solargraph
|
|
|
15
15
|
#
|
|
16
16
|
class Chain
|
|
17
17
|
include Equality
|
|
18
|
+
include Logging
|
|
18
19
|
|
|
19
20
|
autoload :Link, 'solargraph/source/chain/link'
|
|
20
21
|
autoload :Call, 'solargraph/source/chain/call'
|
|
@@ -75,7 +76,9 @@ module Solargraph
|
|
|
75
76
|
|
|
76
77
|
# Determine potential Pins returned by this chain of words
|
|
77
78
|
#
|
|
78
|
-
# @param api_map [ApiMap]
|
|
79
|
+
# @param api_map [ApiMap]
|
|
80
|
+
#
|
|
81
|
+
# @param name_pin [Pin::Base] A pin
|
|
79
82
|
# representing the place in which expression is evaluated (e.g.,
|
|
80
83
|
# a Method pin, or a Module or Class pin if not run within a
|
|
81
84
|
# method - both in terms of the closure around the chain, as well
|
|
@@ -192,6 +195,7 @@ module Solargraph
|
|
|
192
195
|
|
|
193
196
|
include Logging
|
|
194
197
|
|
|
198
|
+
# @return [String]
|
|
195
199
|
def desc
|
|
196
200
|
links.map(&:desc).to_s
|
|
197
201
|
end
|
|
@@ -260,12 +264,17 @@ module Solargraph
|
|
|
260
264
|
ComplexType::UNDEFINED
|
|
261
265
|
elsif types.length > 1
|
|
262
266
|
# Move nil to the end by convention
|
|
267
|
+
|
|
268
|
+
# @param a [ComplexType::UniqueType]
|
|
263
269
|
sorted = types.flat_map(&:items).sort { |a, _| a.tag == 'nil' ? 1 : 0 }
|
|
264
270
|
ComplexType.new(sorted.uniq)
|
|
265
271
|
else
|
|
266
272
|
ComplexType.new(types)
|
|
267
273
|
end
|
|
268
|
-
|
|
274
|
+
if context.nil? || context.return_type.undefined?
|
|
275
|
+
# up to downstream to resolve self type
|
|
276
|
+
return type
|
|
277
|
+
end
|
|
269
278
|
|
|
270
279
|
type.self_to_type(context.return_type)
|
|
271
280
|
end
|
|
@@ -28,7 +28,7 @@ module Solargraph
|
|
|
28
28
|
# syntax errors will be repaired.
|
|
29
29
|
# @return [String] The updated text.
|
|
30
30
|
def write text, nullable = false
|
|
31
|
-
if nullable and !range.nil? and new_text.match(/[
|
|
31
|
+
if nullable and !range.nil? and new_text.match(/[.\[{(@$:]$/)
|
|
32
32
|
[':', '@'].each do |dupable|
|
|
33
33
|
next unless new_text == dupable
|
|
34
34
|
offset = Position.to_offset(text, range.start)
|
|
@@ -59,7 +59,7 @@ module Solargraph
|
|
|
59
59
|
else
|
|
60
60
|
result = commit text, fixed
|
|
61
61
|
off = Position.to_offset(text, range.start)
|
|
62
|
-
match = result[0, off].match(/[
|
|
62
|
+
match = result[0, off].match(/[.:]+\z/)
|
|
63
63
|
if match
|
|
64
64
|
result = result[0, off].sub(/#{match[0]}\z/, ' ' * match[0].length) + result[off..-1]
|
|
65
65
|
end
|