solargraph 0.58.2 → 0.59.0.dev.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 +4 -5
- data/.github/workflows/plugins.yml +41 -34
- data/.github/workflows/rspec.yml +44 -23
- data/.github/workflows/typecheck.yml +2 -2
- data/.rubocop.yml +32 -5
- data/.rubocop_todo.yml +50 -966
- 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 +13 -3
- data/lib/solargraph/api_map/index.rb +23 -18
- data/lib/solargraph/api_map/source_to_yard.rb +22 -9
- data/lib/solargraph/api_map/store.rb +33 -28
- data/lib/solargraph/api_map.rb +150 -82
- data/lib/solargraph/bench.rb +44 -45
- data/lib/solargraph/complex_type/conformance.rb +176 -0
- data/lib/solargraph/complex_type/type_methods.rb +28 -17
- data/lib/solargraph/complex_type/unique_type.rb +218 -57
- data/lib/solargraph/complex_type.rb +170 -57
- data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
- 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 +15 -15
- data/lib/solargraph/convention/gemspec.rb +23 -23
- data/lib/solargraph/convention/rakefile.rb +17 -17
- 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 +78 -78
- data/lib/solargraph/converters/dd.rb +19 -17
- data/lib/solargraph/converters/dl.rb +17 -15
- data/lib/solargraph/converters/dt.rb +17 -15
- data/lib/solargraph/converters/misc.rb +3 -1
- 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 +37 -41
- data/lib/solargraph/doc_map.rb +133 -373
- data/lib/solargraph/equality.rb +4 -4
- data/lib/solargraph/gem_pins.rb +21 -20
- data/lib/solargraph/language_server/error_codes.rb +20 -20
- 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 +30 -22
- data/lib/solargraph/language_server/message/base.rb +97 -97
- data/lib/solargraph/language_server/message/client/register_capability.rb +13 -15
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -60
- 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 +32 -32
- data/lib/solargraph/language_server/message/extended/download_core.rb +20 -19
- data/lib/solargraph/language_server/message/extended/search.rb +20 -20
- data/lib/solargraph/language_server/message/initialize.rb +197 -191
- 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 +23 -16
- 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 +18 -11
- data/lib/solargraph/language_server/message/text_document/references.rb +23 -16
- data/lib/solargraph/language_server/message/text_document/rename.rb +26 -19
- 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/workspace/did_change_configuration.rb +41 -35
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +48 -40
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +32 -26
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -17
- data/lib/solargraph/language_server/message.rb +94 -94
- data/lib/solargraph/language_server/request.rb +29 -27
- data/lib/solargraph/language_server/transport/data_reader.rb +72 -74
- data/lib/solargraph/language_server/uri_helpers.rb +49 -49
- data/lib/solargraph/library.rb +85 -44
- data/lib/solargraph/location.rb +17 -14
- data/lib/solargraph/logging.rb +24 -4
- data/lib/solargraph/page.rb +92 -92
- data/lib/solargraph/parser/comment_ripper.rb +19 -4
- data/lib/solargraph/parser/flow_sensitive_typing.rb +326 -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 +32 -14
- data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +50 -25
- data/lib/solargraph/parser/parser_gem/node_methods.rb +91 -70
- 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 +12 -12
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -3
- data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +38 -37
- 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/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/until_node.rb +29 -29
- 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 +14 -12
- data/lib/solargraph/parser/region.rb +9 -3
- data/lib/solargraph/parser/snippet.rb +3 -1
- data/lib/solargraph/parser.rb +25 -23
- data/lib/solargraph/pin/base.rb +126 -80
- 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 +43 -45
- 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 +153 -104
- data/lib/solargraph/pin/method_alias.rb +8 -0
- data/lib/solargraph/pin/namespace.rb +19 -12
- data/lib/solargraph/pin/parameter.rb +100 -36
- data/lib/solargraph/pin/proxy_type.rb +4 -1
- data/lib/solargraph/pin/reference/override.rb +1 -1
- data/lib/solargraph/pin/reference/superclass.rb +2 -0
- data/lib/solargraph/pin/reference.rb +19 -0
- data/lib/solargraph/pin/search.rb +3 -2
- data/lib/solargraph/pin/signature.rb +15 -12
- 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 +490 -73
- data/lib/solargraph/position.rb +14 -10
- data/lib/solargraph/range.rb +16 -15
- data/lib/solargraph/rbs_map/conversions.rb +343 -214
- data/lib/solargraph/rbs_map/core_fills.rb +91 -84
- 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 +77 -32
- data/lib/solargraph/server_methods.rb +16 -16
- data/lib/solargraph/shell.rb +128 -73
- data/lib/solargraph/source/chain/array.rb +39 -37
- data/lib/solargraph/source/chain/call.rb +96 -56
- data/lib/solargraph/source/chain/class_variable.rb +13 -13
- data/lib/solargraph/source/chain/constant.rb +5 -1
- data/lib/solargraph/source/chain/global_variable.rb +13 -13
- data/lib/solargraph/source/chain/hash.rb +8 -5
- 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 +99 -109
- data/lib/solargraph/source/chain/literal.rb +9 -6
- data/lib/solargraph/source/chain/or.rb +10 -4
- data/lib/solargraph/source/chain/q_call.rb +13 -11
- data/lib/solargraph/source/chain/variable.rb +15 -13
- data/lib/solargraph/source/chain/z_super.rb +28 -30
- data/lib/solargraph/source/chain.rb +49 -38
- data/lib/solargraph/source/change.rb +12 -5
- data/lib/solargraph/source/cursor.rb +23 -17
- 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 +48 -29
- data/lib/solargraph/source_map/data.rb +4 -1
- data/lib/solargraph/source_map/mapper.rb +71 -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 +195 -120
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +13 -10
- data/lib/solargraph/workspace/gemspecs.rb +367 -0
- data/lib/solargraph/workspace/require_paths.rb +1 -0
- data/lib/solargraph/workspace.rb +149 -30
- data/lib/solargraph/yard_map/helpers.rb +8 -3
- 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_tags.rb +20 -20
- data/lib/solargraph/yardoc.rb +33 -23
- data/lib/solargraph.rb +29 -8
- data/rbs/fills/rubygems/0/dependency.rbs +193 -0
- data/rbs/fills/tuple/tuple.rbs +28 -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 +36 -34
- metadata +38 -33
- 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
|
@@ -5,11 +5,10 @@ module Solargraph
|
|
|
5
5
|
#
|
|
6
6
|
class TypeChecker
|
|
7
7
|
autoload :Problem, 'solargraph/type_checker/problem'
|
|
8
|
-
autoload :ParamDef, 'solargraph/type_checker/param_def'
|
|
9
8
|
autoload :Rules, 'solargraph/type_checker/rules'
|
|
10
|
-
autoload :Checks, 'solargraph/type_checker/checks'
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
# @!parse
|
|
11
|
+
# include Solargraph::Parser::ParserGem::NodeMethods
|
|
13
12
|
include Parser::NodeMethods
|
|
14
13
|
|
|
15
14
|
# @return [String]
|
|
@@ -26,8 +25,6 @@ module Solargraph
|
|
|
26
25
|
# @param level [Symbol] Don't complain about anything above this level
|
|
27
26
|
# @param workspace [Workspace, nil] Workspace to use for loading
|
|
28
27
|
# type checker rules modified by user config
|
|
29
|
-
# @param type_checker_rules [Hash{Symbol => Symbol}] Overrides for
|
|
30
|
-
# type checker rules - e.g., :report_undefined => :strong
|
|
31
28
|
# @param rules [Rules] Type checker rules object
|
|
32
29
|
def initialize filename,
|
|
33
30
|
api_map: nil,
|
|
@@ -36,7 +33,8 @@ module Solargraph
|
|
|
36
33
|
rules: workspace ? workspace.rules(level) : Rules.new(level, {})
|
|
37
34
|
@filename = filename
|
|
38
35
|
# @todo Smarter directory resolution
|
|
39
|
-
@api_map = api_map || Solargraph::ApiMap.load(File.dirname(filename)
|
|
36
|
+
@api_map = api_map || Solargraph::ApiMap.load(File.dirname(filename),
|
|
37
|
+
loose_unions: !rules.require_all_unique_types_support_call?)
|
|
40
38
|
@rules = rules
|
|
41
39
|
# @type [Array<Range>]
|
|
42
40
|
@marked_ranges = []
|
|
@@ -49,18 +47,51 @@ module Solargraph
|
|
|
49
47
|
|
|
50
48
|
# @return [Source]
|
|
51
49
|
def source
|
|
52
|
-
|
|
50
|
+
source_map.source
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @param inferred [ComplexType, ComplexType::UniqueType]
|
|
54
|
+
# @param expected [ComplexType, ComplexType::UniqueType]
|
|
55
|
+
def return_type_conforms_to? inferred, expected
|
|
56
|
+
conforms_to?(inferred, expected, :return_type)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @param inferred [ComplexType, ComplexType::UniqueType]
|
|
60
|
+
# @param expected [ComplexType, ComplexType::UniqueType]
|
|
61
|
+
def arg_conforms_to? inferred, expected
|
|
62
|
+
conforms_to?(inferred, expected, :method_call)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# @param inferred [ComplexType, ComplexType::UniqueType]
|
|
66
|
+
# @param expected [ComplexType, ComplexType::UniqueType]
|
|
67
|
+
def assignment_conforms_to? inferred, expected
|
|
68
|
+
conforms_to?(inferred, expected, :assignment)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# @param inferred [ComplexType, ComplexType::UniqueType]
|
|
72
|
+
# @param expected [ComplexType, ComplexType::UniqueType]
|
|
73
|
+
# @param scenario [Symbol]
|
|
74
|
+
def conforms_to? inferred, expected, scenario
|
|
75
|
+
rules_arr = []
|
|
76
|
+
rules_arr << :allow_empty_params unless rules.require_inferred_type_params?
|
|
77
|
+
rules_arr << :allow_any_match unless rules.require_all_unique_types_match_expected?
|
|
78
|
+
rules_arr << :allow_undefined unless rules.require_no_undefined_args?
|
|
79
|
+
rules_arr << :allow_unresolved_generic unless rules.require_generics_resolved?
|
|
80
|
+
rules_arr << :allow_unmatched_interface unless rules.require_interfaces_resolved?
|
|
81
|
+
rules_arr << :allow_reverse_match unless rules.require_downcasts?
|
|
82
|
+
inferred.conforms_to?(api_map, expected, scenario,
|
|
83
|
+
rules_arr)
|
|
53
84
|
end
|
|
54
85
|
|
|
55
86
|
# @return [Array<Problem>]
|
|
56
87
|
def problems
|
|
57
88
|
@problems ||= begin
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
89
|
+
all = method_tag_problems
|
|
90
|
+
.concat(variable_type_tag_problems)
|
|
91
|
+
.concat(const_problems)
|
|
92
|
+
.concat(call_problems)
|
|
93
|
+
unignored = without_ignored(all)
|
|
94
|
+
unignored.concat(unneeded_sgignore_problems)
|
|
64
95
|
end
|
|
65
96
|
end
|
|
66
97
|
|
|
@@ -70,20 +101,26 @@ module Solargraph
|
|
|
70
101
|
# @return [self]
|
|
71
102
|
def load filename, level = :normal
|
|
72
103
|
source = Solargraph::Source.load(filename)
|
|
73
|
-
|
|
104
|
+
rules = Rules.new(level, {})
|
|
105
|
+
api_map = Solargraph::ApiMap.new(loose_unions:
|
|
106
|
+
!rules.require_all_unique_types_support_call?)
|
|
74
107
|
api_map.map(source)
|
|
75
|
-
new(filename, api_map: api_map, level: level)
|
|
108
|
+
new(filename, api_map: api_map, level: level, rules: rules)
|
|
76
109
|
end
|
|
77
110
|
|
|
78
111
|
# @param code [String]
|
|
79
112
|
# @param filename [String, nil]
|
|
80
113
|
# @param level [Symbol]
|
|
114
|
+
# @param api_map [Solargraph::ApiMap, nil]
|
|
81
115
|
# @return [self]
|
|
82
|
-
def load_string code, filename = nil, level = :normal
|
|
116
|
+
def load_string code, filename = nil, level = :normal, api_map: nil
|
|
83
117
|
source = Solargraph::Source.load_string(code, filename)
|
|
84
|
-
|
|
118
|
+
rules = Rules.new(level, {})
|
|
119
|
+
api_map ||= Solargraph::ApiMap.new(loose_unions:
|
|
120
|
+
!rules.require_all_unique_types_support_call?)
|
|
121
|
+
# @sg-ignore flow sensitive typing needs better handling of ||= on lvars
|
|
85
122
|
api_map.map(source)
|
|
86
|
-
new(filename, api_map: api_map, level: level)
|
|
123
|
+
new(filename, api_map: api_map, level: level, rules: rules)
|
|
87
124
|
end
|
|
88
125
|
end
|
|
89
126
|
|
|
@@ -107,13 +144,18 @@ module Solargraph
|
|
|
107
144
|
result = []
|
|
108
145
|
declared = pin.typify(api_map).self_to_type(pin.full_context).qualify(api_map, *pin.gates)
|
|
109
146
|
if declared.undefined?
|
|
147
|
+
# @sg-ignore Need to add nil check here
|
|
110
148
|
if pin.return_type.undefined? && rules.require_type_tags?
|
|
111
149
|
if pin.attribute?
|
|
112
150
|
inferred = pin.probe(api_map).self_to_type(pin.full_context)
|
|
113
|
-
|
|
151
|
+
unless inferred.defined?
|
|
152
|
+
result.push Problem.new(pin.location, "Missing @return tag for #{pin.path}",
|
|
153
|
+
pin: pin)
|
|
154
|
+
end
|
|
114
155
|
else
|
|
115
156
|
result.push Problem.new(pin.location, "Missing @return tag for #{pin.path}", pin: pin)
|
|
116
157
|
end
|
|
158
|
+
# @sg-ignore Need to add nil check here
|
|
117
159
|
elsif pin.return_type.defined? && !resolved_constant?(pin)
|
|
118
160
|
result.push Problem.new(pin.location, "Unresolved return type #{pin.return_type} for #{pin.path}", pin: pin)
|
|
119
161
|
elsif rules.must_tag_or_infer? && pin.probe(api_map).undefined?
|
|
@@ -127,8 +169,9 @@ module Solargraph
|
|
|
127
169
|
result.push Problem.new(pin.location, "#{pin.path} return type could not be inferred", pin: pin)
|
|
128
170
|
end
|
|
129
171
|
else
|
|
130
|
-
unless
|
|
131
|
-
result.push Problem.new(pin.location,
|
|
172
|
+
unless return_type_conforms_to?(inferred, declared)
|
|
173
|
+
result.push Problem.new(pin.location,
|
|
174
|
+
"Declared return type #{declared.rooted_tags} does not match inferred type #{inferred.rooted_tags} for #{pin.path}", pin: pin)
|
|
132
175
|
end
|
|
133
176
|
end
|
|
134
177
|
end
|
|
@@ -144,7 +187,7 @@ module Solargraph
|
|
|
144
187
|
def resolved_constant? pin
|
|
145
188
|
return true if pin.typify(api_map).defined?
|
|
146
189
|
constant_pins = api_map.get_constants('', *pin.closure.gates)
|
|
147
|
-
|
|
190
|
+
.select { |p| p.name == pin.return_type.namespace }
|
|
148
191
|
return true if constant_pins.find { |p| p.typify(api_map).defined? }
|
|
149
192
|
# will need to probe when a constant name is assigned to a
|
|
150
193
|
# class/module (alias)
|
|
@@ -154,6 +197,7 @@ module Solargraph
|
|
|
154
197
|
|
|
155
198
|
# @param pin [Pin::Base]
|
|
156
199
|
def virtual_pin? pin
|
|
200
|
+
# @sg-ignore Need to add nil check here
|
|
157
201
|
pin.location && source.comment_at?(pin.location.range.ending)
|
|
158
202
|
end
|
|
159
203
|
|
|
@@ -165,19 +209,19 @@ module Solargraph
|
|
|
165
209
|
pin.signatures.each do |sig|
|
|
166
210
|
params = param_details_from_stack(sig, stack)
|
|
167
211
|
if rules.require_type_tags?
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
result.push Problem.new(pin.location, "Missing @param tag for #{par.name} on #{pin.path}", pin: pin)
|
|
175
|
-
end
|
|
176
|
-
else
|
|
212
|
+
sig.parameters.each do |par|
|
|
213
|
+
break if %i[restarg kwrestarg blockarg].include?(par.decl)
|
|
214
|
+
unless params[par.name]
|
|
215
|
+
if pin.attribute?
|
|
216
|
+
inferred = pin.probe(api_map).self_to_type(pin.full_context)
|
|
217
|
+
if inferred.undefined?
|
|
177
218
|
result.push Problem.new(pin.location, "Missing @param tag for #{par.name} on #{pin.path}", pin: pin)
|
|
178
219
|
end
|
|
220
|
+
else
|
|
221
|
+
result.push Problem.new(pin.location, "Missing @param tag for #{par.name} on #{pin.path}", pin: pin)
|
|
179
222
|
end
|
|
180
223
|
end
|
|
224
|
+
end
|
|
181
225
|
end
|
|
182
226
|
# @param name [String]
|
|
183
227
|
# @param data [Hash{Symbol => BasicObject}]
|
|
@@ -185,7 +229,8 @@ module Solargraph
|
|
|
185
229
|
# @type [ComplexType]
|
|
186
230
|
type = data[:qualified]
|
|
187
231
|
if type.undefined?
|
|
188
|
-
result.push Problem.new(pin.location, "Unresolved type #{data[:tagged]} for #{name} param on #{pin.path}",
|
|
232
|
+
result.push Problem.new(pin.location, "Unresolved type #{data[:tagged]} for #{name} param on #{pin.path}",
|
|
233
|
+
pin: pin)
|
|
189
234
|
end
|
|
190
235
|
end
|
|
191
236
|
end
|
|
@@ -201,6 +246,7 @@ module Solargraph
|
|
|
201
246
|
def variable_type_tag_problems
|
|
202
247
|
result = []
|
|
203
248
|
all_variables.each do |pin|
|
|
249
|
+
# @sg-ignore Need to add nil check here
|
|
204
250
|
if pin.return_type.defined?
|
|
205
251
|
declared = pin.typify(api_map)
|
|
206
252
|
next if declared.duck_type?
|
|
@@ -215,21 +261,21 @@ module Solargraph
|
|
|
215
261
|
result.push Problem.new(pin.location, "Variable type could not be inferred for #{pin.name}", pin: pin)
|
|
216
262
|
end
|
|
217
263
|
else
|
|
218
|
-
unless
|
|
219
|
-
result.push Problem.new(pin.location,
|
|
264
|
+
unless assignment_conforms_to?(inferred, declared)
|
|
265
|
+
result.push Problem.new(pin.location,
|
|
266
|
+
"Declared type #{declared} does not match inferred type #{inferred} for variable #{pin.name}", pin: pin)
|
|
220
267
|
end
|
|
221
268
|
end
|
|
222
269
|
elsif declared_externally?(pin)
|
|
223
270
|
ignored_pins.push pin
|
|
224
271
|
end
|
|
225
272
|
elsif !pin.is_a?(Pin::Parameter) && !resolved_constant?(pin)
|
|
226
|
-
result.push Problem.new(pin.location, "Unresolved type #{pin.return_type} for variable #{pin.name}",
|
|
273
|
+
result.push Problem.new(pin.location, "Unresolved type #{pin.return_type} for variable #{pin.name}",
|
|
274
|
+
pin: pin)
|
|
227
275
|
end
|
|
228
276
|
elsif pin.assignment
|
|
229
277
|
inferred = pin.probe(api_map)
|
|
230
|
-
if inferred.undefined? && declared_externally?(pin)
|
|
231
|
-
ignored_pins.push pin
|
|
232
|
-
end
|
|
278
|
+
ignored_pins.push pin if inferred.undefined? && declared_externally?(pin)
|
|
233
279
|
end
|
|
234
280
|
end
|
|
235
281
|
result
|
|
@@ -247,8 +293,10 @@ module Solargraph
|
|
|
247
293
|
Solargraph::Parser::NodeMethods.const_nodes_from(source.node).each do |const|
|
|
248
294
|
rng = Solargraph::Range.from_node(const)
|
|
249
295
|
chain = Solargraph::Parser.chain(const, filename)
|
|
296
|
+
# @sg-ignore Need to add nil check here
|
|
250
297
|
closure_pin = source_map.locate_closure_pin(rng.start.line, rng.start.column)
|
|
251
298
|
closure_pin.rebind(api_map)
|
|
299
|
+
# @sg-ignore Need to add nil check here
|
|
252
300
|
location = Location.new(filename, rng)
|
|
253
301
|
locals = source_map.locals_at(location)
|
|
254
302
|
pins = chain.define(api_map, closure_pin, locals)
|
|
@@ -265,44 +313,55 @@ module Solargraph
|
|
|
265
313
|
result = []
|
|
266
314
|
Solargraph::Parser::NodeMethods.call_nodes_from(source.node).each do |call|
|
|
267
315
|
rng = Solargraph::Range.from_node(call)
|
|
316
|
+
# @sg-ignore Need to add nil check here
|
|
268
317
|
next if @marked_ranges.any? { |d| d.contain?(rng.start) }
|
|
269
318
|
chain = Solargraph::Parser.chain(call, filename)
|
|
319
|
+
# @sg-ignore Need to add nil check here
|
|
270
320
|
closure_pin = source_map.locate_closure_pin(rng.start.line, rng.start.column)
|
|
271
|
-
namespace_pin = closure_pin
|
|
272
321
|
if call.type == :block
|
|
273
322
|
# blocks in the AST include the method call as well, so the
|
|
274
323
|
# node returned by #call_nodes_from needs to be backed out
|
|
275
324
|
# one closure
|
|
325
|
+
# @todo Need to add nil check here
|
|
326
|
+
# @todo Should warn on nil deference here
|
|
276
327
|
closure_pin = closure_pin.closure
|
|
277
328
|
end
|
|
329
|
+
# @sg-ignore Need to add nil check here
|
|
278
330
|
closure_pin.rebind(api_map)
|
|
331
|
+
# @sg-ignore Need to add nil check here
|
|
279
332
|
location = Location.new(filename, rng)
|
|
280
333
|
locals = source_map.locals_at(location)
|
|
334
|
+
# @sg-ignore Need to add nil check here
|
|
281
335
|
type = chain.infer(api_map, closure_pin, locals)
|
|
282
336
|
if type.undefined? && !rules.ignore_all_undefined?
|
|
283
337
|
base = chain
|
|
284
338
|
missing = chain
|
|
339
|
+
# @type [Solargraph::Pin::Base, nil]
|
|
285
340
|
found = nil
|
|
286
|
-
|
|
341
|
+
# @type [Array<Solargraph::Pin::Base>]
|
|
342
|
+
all_found = []
|
|
287
343
|
until base.links.first.undefined?
|
|
288
|
-
|
|
344
|
+
# @sg-ignore Need to add nil check here
|
|
345
|
+
all_found = base.define(api_map, closure_pin, locals)
|
|
346
|
+
found = all_found.first
|
|
289
347
|
break if found
|
|
290
348
|
missing = base
|
|
291
349
|
base = base.base
|
|
292
350
|
end
|
|
293
|
-
|
|
351
|
+
all_closest = all_found.map { |pin| pin.typify(api_map) }
|
|
352
|
+
closest = ComplexType.new(all_closest.flat_map(&:items).uniq)
|
|
294
353
|
# @todo remove the internal_or_core? check at a higher-than-strict level
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
end
|
|
302
|
-
@marked_ranges.push rng
|
|
354
|
+
# @sg-ignore Need to add nil check here
|
|
355
|
+
if (!found || found.is_a?(Pin::BaseVariable) || (closest.defined? && internal_or_core?(found))) && !(closest.generic? || ignored_pins.include?(found))
|
|
356
|
+
if closest.defined?
|
|
357
|
+
result.push Problem.new(location, "Unresolved call to #{missing.links.last.word} on #{closest}")
|
|
358
|
+
else
|
|
359
|
+
result.push Problem.new(location, "Unresolved call to #{missing.links.last.word}")
|
|
303
360
|
end
|
|
361
|
+
@marked_ranges.push rng
|
|
304
362
|
end
|
|
305
363
|
end
|
|
364
|
+
# @sg-ignore Need to add nil check here
|
|
306
365
|
result.concat argument_problems_for(chain, api_map, closure_pin, locals, location)
|
|
307
366
|
end
|
|
308
367
|
result
|
|
@@ -311,13 +370,12 @@ module Solargraph
|
|
|
311
370
|
# @param chain [Solargraph::Source::Chain]
|
|
312
371
|
# @param api_map [Solargraph::ApiMap]
|
|
313
372
|
# @param closure_pin [Solargraph::Pin::Closure]
|
|
314
|
-
# @param locals [Array<Solargraph::Pin::
|
|
373
|
+
# @param locals [Array<Solargraph::Pin::LocalVariable>]
|
|
315
374
|
# @param location [Solargraph::Location]
|
|
316
375
|
# @return [Array<Problem>]
|
|
317
376
|
def argument_problems_for chain, api_map, closure_pin, locals, location
|
|
318
377
|
result = []
|
|
319
378
|
base = chain
|
|
320
|
-
# @type last_base_link [Solargraph::Source::Chain::Call]
|
|
321
379
|
last_base_link = base.links.last
|
|
322
380
|
return [] unless last_base_link.is_a?(Solargraph::Source::Chain::Call)
|
|
323
381
|
|
|
@@ -340,6 +398,8 @@ module Solargraph
|
|
|
340
398
|
base.base.infer(api_map, closure_pin, locals).namespace
|
|
341
399
|
end
|
|
342
400
|
init = api_map.get_method_stack(fqns, 'initialize').first
|
|
401
|
+
|
|
402
|
+
# @type [::Array<Solargraph::TypeChecker::Problem>]
|
|
343
403
|
init ? arity_problems_for(init, arguments, location) : []
|
|
344
404
|
else
|
|
345
405
|
arity_problems_for(pin, arguments, location)
|
|
@@ -348,7 +408,7 @@ module Solargraph
|
|
|
348
408
|
return [] if !rules.validate_calls? || base.links.first.is_a?(Solargraph::Source::Chain::ZSuper)
|
|
349
409
|
|
|
350
410
|
all_errors = []
|
|
351
|
-
pin.signatures.
|
|
411
|
+
pin.signatures.sort_by { |sig| sig.parameters.length }.each do |sig|
|
|
352
412
|
params = param_details_from_stack(sig, pins)
|
|
353
413
|
|
|
354
414
|
signature_errors = signature_argument_problems_for location, locals, closure_pin, params, arguments, sig, pin
|
|
@@ -368,11 +428,10 @@ module Solargraph
|
|
|
368
428
|
# @param location [Location]
|
|
369
429
|
# @param locals [Array<Pin::LocalVariable>]
|
|
370
430
|
# @param closure_pin [Pin::Closure]
|
|
371
|
-
# @param params [Hash{String =>
|
|
431
|
+
# @param params [Hash{String => undefined}]
|
|
372
432
|
# @param arguments [Array<Source::Chain>]
|
|
373
433
|
# @param sig [Pin::Signature]
|
|
374
434
|
# @param pin [Pin::Method]
|
|
375
|
-
# @param pins [Array<Pin::Method>]
|
|
376
435
|
#
|
|
377
436
|
# @return [Array<Problem>]
|
|
378
437
|
def signature_argument_problems_for location, locals, closure_pin, params, arguments, sig, pin
|
|
@@ -382,31 +441,25 @@ module Solargraph
|
|
|
382
441
|
# when possible, and when not, ensure provably
|
|
383
442
|
# incorrect situations are detected.
|
|
384
443
|
sig.parameters.each_with_index do |par, idx|
|
|
385
|
-
return errors if par.decl == :restarg
|
|
444
|
+
return errors if par.decl == :restarg # bail out and assume the rest is valid pending better arg processing
|
|
386
445
|
argchain = arguments[idx]
|
|
387
446
|
if argchain.nil?
|
|
447
|
+
final_arg = arguments.last
|
|
388
448
|
if par.decl == :arg
|
|
389
|
-
final_arg = arguments.last
|
|
390
449
|
if final_arg && final_arg.node.type == :splat
|
|
391
450
|
argchain = final_arg
|
|
392
451
|
return errors
|
|
393
452
|
else
|
|
394
453
|
errors.push Problem.new(location, "Not enough arguments to #{pin.path}")
|
|
395
454
|
end
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
argchain = final_arg if final_arg && [:kwsplat, :hash].include?(final_arg.node.type)
|
|
455
|
+
elsif final_arg && %i[kwsplat hash].include?(final_arg.node.type)
|
|
456
|
+
argchain = final_arg
|
|
399
457
|
end
|
|
400
458
|
end
|
|
401
459
|
if argchain
|
|
402
|
-
if par.decl
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
else
|
|
406
|
-
if argchain.node.type == :splat && argchain == arguments.last
|
|
407
|
-
final_arg = argchain
|
|
408
|
-
end
|
|
409
|
-
if (final_arg && final_arg.node.type == :splat)
|
|
460
|
+
if par.decl == :arg
|
|
461
|
+
final_arg = argchain if argchain.node.type == :splat && argchain == arguments.last
|
|
462
|
+
if final_arg && final_arg.node.type == :splat
|
|
410
463
|
# The final argument given has been seen and was a
|
|
411
464
|
# splat, which doesn't give us useful types or
|
|
412
465
|
# arities against positional parameters, so let's
|
|
@@ -430,11 +483,15 @@ module Solargraph
|
|
|
430
483
|
else
|
|
431
484
|
argtype = argchain.infer(api_map, closure_pin, locals)
|
|
432
485
|
argtype = argtype.self_to_type(closure_pin.context)
|
|
433
|
-
if argtype.defined? && ptype.defined? && !
|
|
434
|
-
errors.push Problem.new(location,
|
|
486
|
+
if argtype.defined? && ptype.defined? && !arg_conforms_to?(argtype, ptype)
|
|
487
|
+
errors.push Problem.new(location,
|
|
488
|
+
"Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}")
|
|
435
489
|
return errors
|
|
436
490
|
end
|
|
437
491
|
end
|
|
492
|
+
else
|
|
493
|
+
errors.concat kwarg_problems_for sig, argchain, api_map, closure_pin, locals, location, pin, params, idx
|
|
494
|
+
next
|
|
438
495
|
end
|
|
439
496
|
elsif par.decl == :kwarg
|
|
440
497
|
errors.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}")
|
|
@@ -445,13 +502,13 @@ module Solargraph
|
|
|
445
502
|
end
|
|
446
503
|
|
|
447
504
|
# @param sig [Pin::Signature]
|
|
448
|
-
# @param argchain [Source::Chain]
|
|
505
|
+
# @param argchain [Solargraph::Source::Chain]
|
|
449
506
|
# @param api_map [ApiMap]
|
|
450
507
|
# @param closure_pin [Pin::Closure]
|
|
451
508
|
# @param locals [Array<Pin::LocalVariable>]
|
|
452
509
|
# @param location [Location]
|
|
453
510
|
# @param pin [Pin::Method]
|
|
454
|
-
# @param params [Hash{String => Hash{Symbol =>
|
|
511
|
+
# @param params [Hash{String => Hash{Symbol => undefined}}]
|
|
455
512
|
# @param idx [Integer]
|
|
456
513
|
#
|
|
457
514
|
# @return [Array<Problem>]
|
|
@@ -459,29 +516,30 @@ module Solargraph
|
|
|
459
516
|
result = []
|
|
460
517
|
kwargs = convert_hash(argchain.node)
|
|
461
518
|
par = sig.parameters[idx]
|
|
519
|
+
# @type [Solargraph::Source::Chain]
|
|
462
520
|
argchain = kwargs[par.name.to_sym]
|
|
463
521
|
if par.decl == :kwrestarg || (par.decl == :optarg && idx == pin.parameters.length - 1 && par.asgn_code == '{}')
|
|
464
522
|
result.concat kwrestarg_problems_for(api_map, closure_pin, locals, location, pin, params, kwargs)
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
523
|
+
elsif argchain
|
|
524
|
+
data = params[par.name]
|
|
525
|
+
if data.nil?
|
|
526
|
+
# @todo Some level (strong, I guess) should require the param here
|
|
527
|
+
else
|
|
528
|
+
# @type [ComplexType, ComplexType::UniqueType]
|
|
529
|
+
ptype = data[:qualified]
|
|
530
|
+
ptype = ptype.self_to_type(pin.context)
|
|
531
|
+
unless ptype.undefined?
|
|
532
|
+
# @type [ComplexType]
|
|
533
|
+
argtype = argchain.infer(api_map, closure_pin, locals).self_to_type(closure_pin.context)
|
|
534
|
+
# @todo Unresolved call to defined?
|
|
535
|
+
if argtype.defined? && ptype && !arg_conforms_to?(argtype, ptype)
|
|
536
|
+
result.push Problem.new(location,
|
|
537
|
+
"Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}")
|
|
480
538
|
end
|
|
481
539
|
end
|
|
482
|
-
elsif par.decl == :kwarg
|
|
483
|
-
result.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}")
|
|
484
540
|
end
|
|
541
|
+
elsif par.decl == :kwarg
|
|
542
|
+
result.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}")
|
|
485
543
|
end
|
|
486
544
|
result
|
|
487
545
|
end
|
|
@@ -491,19 +549,22 @@ module Solargraph
|
|
|
491
549
|
# @param locals [Array<Pin::LocalVariable>]
|
|
492
550
|
# @param location [Location]
|
|
493
551
|
# @param pin [Pin::Method]
|
|
494
|
-
# @param params [Hash{String =>
|
|
552
|
+
# @param params [Hash{String => nil, Hash}]
|
|
495
553
|
# @param kwargs [Hash{Symbol => Source::Chain}]
|
|
496
554
|
# @return [Array<Problem>]
|
|
497
|
-
def kwrestarg_problems_for
|
|
555
|
+
def kwrestarg_problems_for api_map, closure_pin, locals, location, pin, params, kwargs
|
|
498
556
|
result = []
|
|
499
557
|
kwargs.each_pair do |pname, argchain|
|
|
500
558
|
next unless params.key?(pname.to_s)
|
|
501
|
-
|
|
502
|
-
|
|
559
|
+
# @sg-ignore
|
|
560
|
+
# @type [ComplexType]
|
|
561
|
+
raw_ptype = params[pname.to_s][:qualified]
|
|
562
|
+
ptype = raw_ptype.self_to_type(pin.context)
|
|
503
563
|
argtype = argchain.infer(api_map, closure_pin, locals)
|
|
504
564
|
argtype = argtype.self_to_type(closure_pin.context)
|
|
505
|
-
if argtype.defined? && ptype && !
|
|
506
|
-
result.push Problem.new(location,
|
|
565
|
+
if argtype.defined? && ptype && !arg_conforms_to?(argtype, ptype)
|
|
566
|
+
result.push Problem.new(location,
|
|
567
|
+
"Wrong argument type for #{pin.path}: #{pname} expected #{ptype}, received #{argtype}")
|
|
507
568
|
end
|
|
508
569
|
end
|
|
509
570
|
result
|
|
@@ -513,7 +574,7 @@ module Solargraph
|
|
|
513
574
|
# @param pin [Pin::Method, Pin::Signature]
|
|
514
575
|
# @param relevant_pin [Pin::Method, Pin::Signature] the pin which is under inspection
|
|
515
576
|
# @return [void]
|
|
516
|
-
def add_restkwarg_param_tag_details
|
|
577
|
+
def add_restkwarg_param_tag_details param_details, pin, relevant_pin
|
|
517
578
|
# see if we have additional tags to pay attention to from YARD -
|
|
518
579
|
# e.g., kwargs in a **restkwargs splat
|
|
519
580
|
tags = pin.docstring.tags(:param)
|
|
@@ -534,7 +595,7 @@ module Solargraph
|
|
|
534
595
|
|
|
535
596
|
# @param pin [Pin::Signature]
|
|
536
597
|
# @return [Hash{String => Hash{Symbol => String, ComplexType}}]
|
|
537
|
-
def signature_param_details
|
|
598
|
+
def signature_param_details pin
|
|
538
599
|
# @type [Hash{String => Hash{Symbol => String, ComplexType}}]
|
|
539
600
|
result = {}
|
|
540
601
|
pin.parameters.each do |param|
|
|
@@ -553,6 +614,7 @@ module Solargraph
|
|
|
553
614
|
next if tag.types.nil?
|
|
554
615
|
result[tag.name.to_s] = {
|
|
555
616
|
tagged: tag.types.join(', '),
|
|
617
|
+
# @sg-ignore need to add a nil check here
|
|
556
618
|
qualified: Solargraph::ComplexType.try_parse(*tag.types).qualify(api_map, *pin.closure.gates)
|
|
557
619
|
}
|
|
558
620
|
end
|
|
@@ -567,7 +629,7 @@ module Solargraph
|
|
|
567
629
|
# @param new_param_details [Hash{String => Hash{Symbol => String, ComplexType}}]
|
|
568
630
|
#
|
|
569
631
|
# @return [void]
|
|
570
|
-
def add_to_param_details
|
|
632
|
+
def add_to_param_details param_details, param_names, new_param_details
|
|
571
633
|
new_param_details.each do |param_name, details|
|
|
572
634
|
next unless param_names.include?(param_name)
|
|
573
635
|
|
|
@@ -580,7 +642,7 @@ module Solargraph
|
|
|
580
642
|
# @param signature [Pin::Signature]
|
|
581
643
|
# @param method_pin_stack [Array<Pin::Method>]
|
|
582
644
|
# @return [Hash{String => Hash{Symbol => String, ComplexType}}]
|
|
583
|
-
def param_details_from_stack
|
|
645
|
+
def param_details_from_stack signature, method_pin_stack
|
|
584
646
|
signature_type = signature.typify(api_map)
|
|
585
647
|
signature = signature.proxy signature_type
|
|
586
648
|
param_details = signature_param_details(signature)
|
|
@@ -602,6 +664,7 @@ module Solargraph
|
|
|
602
664
|
# @param pin [Pin::Base]
|
|
603
665
|
def internal? pin
|
|
604
666
|
return false if pin.nil?
|
|
667
|
+
# @sg-ignore flow sensitive typing needs to handle attrs
|
|
605
668
|
pin.location && api_map.bundled?(pin.location.filename)
|
|
606
669
|
end
|
|
607
670
|
|
|
@@ -619,29 +682,32 @@ module Solargraph
|
|
|
619
682
|
|
|
620
683
|
# @param pin [Pin::BaseVariable]
|
|
621
684
|
def declared_externally? pin
|
|
622
|
-
raise
|
|
685
|
+
raise 'No assignment found' if pin.assignment.nil?
|
|
623
686
|
|
|
624
687
|
chain = Solargraph::Parser.chain(pin.assignment, filename)
|
|
688
|
+
# @sg-ignore flow sensitive typing needs to handle attrs
|
|
625
689
|
rng = Solargraph::Range.from_node(pin.assignment)
|
|
690
|
+
# @sg-ignore Need to add nil check here
|
|
626
691
|
closure_pin = source_map.locate_closure_pin(rng.start.line, rng.start.column)
|
|
692
|
+
# @sg-ignore flow sensitive typing needs to handle "if foo.nil?"
|
|
627
693
|
location = Location.new(filename, Range.from_node(pin.assignment))
|
|
628
694
|
locals = source_map.locals_at(location)
|
|
629
695
|
type = chain.infer(api_map, closure_pin, locals)
|
|
630
696
|
if type.undefined? && !rules.ignore_all_undefined?
|
|
631
697
|
base = chain
|
|
632
|
-
|
|
698
|
+
# @type [Solargraph::Pin::Base, nil]
|
|
633
699
|
found = nil
|
|
634
|
-
|
|
700
|
+
# @type [Array<Solargraph::Pin::Base>]
|
|
701
|
+
all_found = []
|
|
635
702
|
until base.links.first.undefined?
|
|
636
|
-
|
|
703
|
+
all_found = base.define(api_map, closure_pin, locals)
|
|
704
|
+
found = all_found.first
|
|
637
705
|
break if found
|
|
638
|
-
missing = base
|
|
639
706
|
base = base.base
|
|
640
707
|
end
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
end
|
|
708
|
+
all_closest = all_found.map { |pin| pin.typify(api_map) }
|
|
709
|
+
closest = ComplexType.new(all_closest.flat_map(&:items).uniq)
|
|
710
|
+
return false if !found || closest.defined? || internal?(found)
|
|
645
711
|
end
|
|
646
712
|
true
|
|
647
713
|
end
|
|
@@ -664,7 +730,7 @@ module Solargraph
|
|
|
664
730
|
# @param arguments [Array<Source::Chain>]
|
|
665
731
|
# @param location [Location]
|
|
666
732
|
# @return [Array<Problem>]
|
|
667
|
-
def parameterized_arity_problems_for
|
|
733
|
+
def parameterized_arity_problems_for pin, parameters, arguments, location
|
|
668
734
|
return [] unless pin.explicit?
|
|
669
735
|
return [] if parameters.empty? && arguments.empty?
|
|
670
736
|
return [] if pin.anon_splat?
|
|
@@ -679,7 +745,7 @@ module Solargraph
|
|
|
679
745
|
settled_kwargs = parameters.count(&:keyword?)
|
|
680
746
|
else
|
|
681
747
|
kwargs = convert_hash(unchecked.last.node)
|
|
682
|
-
if parameters.any? { |param| [
|
|
748
|
+
if parameters.any? { |param| %i[kwarg kwoptarg].include?(param.decl) || param.kwrestarg? }
|
|
683
749
|
if kwargs.empty?
|
|
684
750
|
add_params += 1
|
|
685
751
|
else
|
|
@@ -708,10 +774,12 @@ module Solargraph
|
|
|
708
774
|
return [] if parameters.any?(&:rest?)
|
|
709
775
|
opt = optional_param_count(parameters)
|
|
710
776
|
return [] if unchecked.length <= req + opt
|
|
711
|
-
if req + add_params + 1 == unchecked.length && any_splatted_call?(unchecked.map(&:node)) && (parameters.map(&:decl) & [
|
|
777
|
+
if req + add_params + 1 == unchecked.length && any_splatted_call?(unchecked.map(&:node)) && (parameters.map(&:decl) & %i[
|
|
778
|
+
kwarg kwoptarg kwrestarg
|
|
779
|
+
]).any?
|
|
712
780
|
return []
|
|
713
781
|
end
|
|
714
|
-
return [] if arguments.length - req == parameters.select { |p| [
|
|
782
|
+
return [] if arguments.length - req == parameters.select { |p| %i[optarg kwoptarg].include?(p.decl) }.length
|
|
715
783
|
return [Problem.new(location, "Too many arguments to #{pin.path}")]
|
|
716
784
|
elsif unchecked.length < req - settled_kwargs && (arguments.empty? || (!arguments.last.splat? && !arguments.last.links.last.is_a?(Solargraph::Source::Chain::Hash)))
|
|
717
785
|
# HACK: Kernel#raise signature is incorrect in Ruby 2.7 core docs.
|
|
@@ -727,42 +795,48 @@ module Solargraph
|
|
|
727
795
|
# @todo need to use generic types in method to choose correct
|
|
728
796
|
# signature and generate Integer as return type
|
|
729
797
|
# @return [Integer]
|
|
730
|
-
def required_param_count
|
|
798
|
+
def required_param_count parameters
|
|
731
799
|
parameters.sum { |param| %i[arg kwarg].include?(param.decl) ? 1 : 0 }
|
|
732
800
|
end
|
|
733
801
|
|
|
734
802
|
# @param parameters [Enumerable<Pin::Parameter>]
|
|
735
|
-
#
|
|
803
|
+
#
|
|
736
804
|
# @return [Integer]
|
|
737
|
-
def optional_param_count
|
|
805
|
+
def optional_param_count parameters
|
|
738
806
|
parameters.select { |p| p.decl == :optarg }.length
|
|
739
807
|
end
|
|
740
808
|
|
|
741
809
|
# @param pin [Pin::Method]
|
|
742
810
|
def abstract? pin
|
|
743
811
|
pin.docstring.has_tag?('abstract') ||
|
|
744
|
-
|
|
812
|
+
pin.closure&.docstring&.has_tag?('abstract')
|
|
745
813
|
end
|
|
746
814
|
|
|
747
815
|
# @param pin [Pin::Method]
|
|
748
816
|
# @return [Array<Source::Chain>]
|
|
749
|
-
def fake_args_for
|
|
817
|
+
def fake_args_for pin
|
|
750
818
|
args = []
|
|
751
819
|
with_opts = false
|
|
752
820
|
with_block = false
|
|
821
|
+
# @param pin [Pin::Parameter]
|
|
753
822
|
pin.parameters.each do |pin|
|
|
754
|
-
|
|
823
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
824
|
+
if %i[kwarg kwoptarg kwrestarg].include?(pin.decl)
|
|
755
825
|
with_opts = true
|
|
826
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
756
827
|
elsif pin.decl == :block
|
|
757
828
|
with_block = true
|
|
829
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
758
830
|
elsif pin.decl == :restarg
|
|
759
831
|
args.push Solargraph::Source::Chain.new([Solargraph::Source::Chain::Variable.new(pin.name)], nil, true)
|
|
760
832
|
else
|
|
761
833
|
args.push Solargraph::Source::Chain.new([Solargraph::Source::Chain::Variable.new(pin.name)])
|
|
762
834
|
end
|
|
763
835
|
end
|
|
764
|
-
|
|
765
|
-
|
|
836
|
+
pin_location = pin.location
|
|
837
|
+
starting_line = pin_location ? pin_location.range.start.line : 0
|
|
838
|
+
args.push Solargraph::Parser.chain_string('{}', filename, starting_line) if with_opts
|
|
839
|
+
args.push Solargraph::Parser.chain_string('&', filename, starting_line) if with_block
|
|
766
840
|
args
|
|
767
841
|
end
|
|
768
842
|
|
|
@@ -774,6 +848,7 @@ module Solargraph
|
|
|
774
848
|
# @return [Set<Integer>]
|
|
775
849
|
def all_sg_ignore_lines
|
|
776
850
|
source.associated_comments.select do |_line, text|
|
|
851
|
+
# @sg-ignore Need to add nil check here
|
|
777
852
|
text.include?('@sg-ignore')
|
|
778
853
|
end.keys.to_set
|
|
779
854
|
end
|