solargraph 0.54.0 → 0.55.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/CHANGELOG.md +58 -0
- data/lib/solargraph/api_map/cache.rb +10 -1
- data/lib/solargraph/api_map/index.rb +167 -0
- data/lib/solargraph/api_map/store.rb +75 -122
- data/lib/solargraph/api_map.rb +109 -41
- data/lib/solargraph/bench.rb +17 -1
- data/lib/solargraph/complex_type/type_methods.rb +17 -11
- data/lib/solargraph/complex_type/unique_type.rb +181 -17
- data/lib/solargraph/complex_type.rb +103 -24
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +51 -0
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +100 -0
- data/lib/solargraph/convention/struct_definition.rb +101 -0
- data/lib/solargraph/convention.rb +2 -0
- data/lib/solargraph/doc_map.rb +43 -18
- data/lib/solargraph/equality.rb +33 -0
- data/lib/solargraph/language_server/host/message_worker.rb +51 -5
- data/lib/solargraph/language_server/host.rb +13 -11
- data/lib/solargraph/language_server/message/base.rb +19 -12
- data/lib/solargraph/language_server/message/initialize.rb +3 -1
- data/lib/solargraph/language_server/message/text_document/completion.rb +0 -3
- data/lib/solargraph/language_server/message/text_document/definition.rb +3 -3
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +3 -3
- data/lib/solargraph/language_server/message/text_document/formatting.rb +4 -0
- data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +3 -3
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -2
- data/lib/solargraph/language_server/progress.rb +19 -2
- data/lib/solargraph/library.rb +31 -41
- data/lib/solargraph/location.rb +29 -1
- data/lib/solargraph/parser/comment_ripper.rb +11 -6
- data/lib/solargraph/parser/flow_sensitive_typing.rb +226 -0
- data/lib/solargraph/parser/node_methods.rb +15 -1
- data/lib/solargraph/parser/parser_gem/class_methods.rb +11 -6
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +10 -10
- data/lib/solargraph/parser/parser_gem/node_methods.rb +6 -4
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +21 -0
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +23 -19
- data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +21 -1
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +21 -0
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +8 -2
- data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +26 -5
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +41 -0
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +28 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +28 -0
- data/lib/solargraph/parser/parser_gem/node_processors.rb +10 -0
- data/lib/solargraph/parser.rb +3 -5
- data/lib/solargraph/pin/base.rb +47 -17
- data/lib/solargraph/pin/base_variable.rb +11 -4
- data/lib/solargraph/pin/block.rb +8 -26
- data/lib/solargraph/pin/breakable.rb +9 -0
- data/lib/solargraph/pin/callable.rb +147 -0
- data/lib/solargraph/pin/closure.rb +8 -3
- data/lib/solargraph/pin/common.rb +2 -6
- data/lib/solargraph/pin/conversions.rb +3 -2
- data/lib/solargraph/pin/instance_variable.rb +2 -2
- data/lib/solargraph/pin/local_variable.rb +7 -1
- data/lib/solargraph/pin/method.rb +76 -48
- data/lib/solargraph/pin/namespace.rb +14 -11
- data/lib/solargraph/pin/parameter.rb +24 -17
- data/lib/solargraph/pin/proxy_type.rb +13 -7
- data/lib/solargraph/pin/signature.rb +3 -129
- data/lib/solargraph/pin/until.rb +18 -0
- data/lib/solargraph/pin/while.rb +18 -0
- data/lib/solargraph/pin.rb +7 -1
- data/lib/solargraph/position.rb +7 -0
- data/lib/solargraph/range.rb +9 -4
- data/lib/solargraph/rbs_map/conversions.rb +84 -45
- data/lib/solargraph/rbs_map/core_fills.rb +16 -9
- data/lib/solargraph/rbs_map.rb +1 -0
- data/lib/solargraph/shell.rb +19 -2
- data/lib/solargraph/source/chain/array.rb +10 -8
- data/lib/solargraph/source/chain/block_symbol.rb +1 -1
- data/lib/solargraph/source/chain/block_variable.rb +1 -1
- data/lib/solargraph/source/chain/call.rb +125 -61
- data/lib/solargraph/source/chain/constant.rb +1 -1
- data/lib/solargraph/source/chain/hash.rb +8 -2
- data/lib/solargraph/source/chain/if.rb +5 -0
- data/lib/solargraph/source/chain/link.rb +28 -5
- data/lib/solargraph/source/chain/literal.rb +27 -2
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain/z_super.rb +1 -1
- data/lib/solargraph/source/chain.rb +131 -63
- data/lib/solargraph/source/cursor.rb +3 -2
- data/lib/solargraph/source/source_chainer.rb +2 -2
- data/lib/solargraph/source.rb +104 -86
- data/lib/solargraph/source_map/clip.rb +8 -6
- data/lib/solargraph/source_map/data.rb +30 -0
- data/lib/solargraph/source_map.rb +28 -16
- data/lib/solargraph/type_checker/checks.rb +4 -0
- data/lib/solargraph/type_checker/rules.rb +6 -1
- data/lib/solargraph/type_checker.rb +48 -21
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +3 -5
- data/lib/solargraph/workspace/config.rb +7 -3
- data/lib/solargraph/workspace.rb +1 -1
- data/lib/solargraph/yard_map/mapper/to_constant.rb +1 -0
- data/lib/solargraph/yard_map/mapper/to_method.rb +42 -15
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -0
- data/lib/solargraph/yard_map/mapper.rb +1 -0
- data/lib/solargraph/yardoc.rb +1 -1
- data/lib/solargraph.rb +1 -0
- data/solargraph.gemspec +5 -5
- metadata +41 -25
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module Solargraph
|
|
4
4
|
class SourceMap
|
|
5
|
-
# A static analysis tool for obtaining definitions,
|
|
6
|
-
# signatures, and type inferences from a
|
|
5
|
+
# A static analysis tool for obtaining definitions, Completions,
|
|
6
|
+
# signatures, and type inferences from a Cursor.
|
|
7
7
|
#
|
|
8
8
|
class Clip
|
|
9
9
|
# @param api_map [ApiMap]
|
|
@@ -11,7 +11,9 @@ module Solargraph
|
|
|
11
11
|
def initialize api_map, cursor
|
|
12
12
|
@api_map = api_map
|
|
13
13
|
@cursor = cursor
|
|
14
|
-
|
|
14
|
+
block_pin = block
|
|
15
|
+
block_pin.rebind(api_map) if block_pin.is_a?(Pin::Block) && !Solargraph::Range.from_node(block_pin.receiver).contain?(cursor.range.start)
|
|
16
|
+
@in_block = nil
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
# @return [Array<Pin::Base>] Relevant pins for infering the type of the Cursor's position
|
|
@@ -40,7 +42,7 @@ module Solargraph
|
|
|
40
42
|
end
|
|
41
43
|
end
|
|
42
44
|
|
|
43
|
-
# @return [Array<Pin::
|
|
45
|
+
# @return [Array<Pin::Method>]
|
|
44
46
|
def signify
|
|
45
47
|
return [] unless cursor.argument?
|
|
46
48
|
chain = Parser.chain(cursor.recipient_node, cursor.filename)
|
|
@@ -53,10 +55,10 @@ module Solargraph
|
|
|
53
55
|
if result.tag == 'Class'
|
|
54
56
|
# HACK: Exception to return BasicObject from Class#new
|
|
55
57
|
dfn = cursor.chain.define(api_map, block, locals).first
|
|
56
|
-
return ComplexType.try_parse('BasicObject') if dfn && dfn.path == 'Class#new'
|
|
58
|
+
return ComplexType.try_parse('::BasicObject') if dfn && dfn.path == 'Class#new'
|
|
57
59
|
end
|
|
58
60
|
return result unless result.tag == 'self'
|
|
59
|
-
|
|
61
|
+
cursor.chain.base.infer(api_map, block, locals)
|
|
60
62
|
end
|
|
61
63
|
|
|
62
64
|
# Get an array of all the locals that are visible from the cursors's
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class SourceMap
|
|
5
|
+
class Data
|
|
6
|
+
def initialize source
|
|
7
|
+
@source = source
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def pins
|
|
11
|
+
generate
|
|
12
|
+
@pins || []
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def locals
|
|
16
|
+
generate
|
|
17
|
+
@locals || []
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def generate
|
|
23
|
+
return if @generated
|
|
24
|
+
|
|
25
|
+
@generated = true
|
|
26
|
+
@pins, @locals = Mapper.map(@source)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -4,40 +4,41 @@ require 'yard'
|
|
|
4
4
|
require 'solargraph/yard_tags'
|
|
5
5
|
|
|
6
6
|
module Solargraph
|
|
7
|
-
# An index of
|
|
7
|
+
# An index of Pins and other ApiMap-related data for a single Source
|
|
8
|
+
# that can be queried.
|
|
8
9
|
#
|
|
9
10
|
class SourceMap
|
|
10
11
|
autoload :Mapper, 'solargraph/source_map/mapper'
|
|
11
12
|
autoload :Clip, 'solargraph/source_map/clip'
|
|
12
13
|
autoload :Completion, 'solargraph/source_map/completion'
|
|
14
|
+
autoload :Data, 'solargraph/source_map/data'
|
|
13
15
|
|
|
14
16
|
# @return [Source]
|
|
15
17
|
attr_reader :source
|
|
16
18
|
|
|
17
19
|
# @return [Array<Pin::Base>]
|
|
18
|
-
|
|
20
|
+
def pins
|
|
21
|
+
data.pins
|
|
22
|
+
end
|
|
19
23
|
|
|
20
24
|
# @return [Array<Pin::LocalVariable>]
|
|
21
|
-
|
|
25
|
+
def locals
|
|
26
|
+
data.locals
|
|
27
|
+
end
|
|
22
28
|
|
|
23
29
|
# @param source [Source]
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
# HACK: Keep the library from changing this
|
|
28
|
-
@source = source.dup
|
|
29
|
-
@pins = pins
|
|
30
|
-
@locals = locals
|
|
30
|
+
def initialize source
|
|
31
|
+
@source = source
|
|
32
|
+
|
|
31
33
|
environ.merge Convention.for_local(self) unless filename.nil?
|
|
32
34
|
self.convention_pins = environ.pins
|
|
33
|
-
@pin_class_hash = pins.to_set.classify(&:class).transform_values(&:to_a)
|
|
34
35
|
@pin_select_cache = {}
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
# @param klass [Class]
|
|
38
39
|
# @return [Array<Pin::Base>]
|
|
39
40
|
def pins_by_class klass
|
|
40
|
-
@pin_select_cache[klass] ||=
|
|
41
|
+
@pin_select_cache[klass] ||= pin_class_hash.select { |key, _| key <= klass }.values.flatten
|
|
41
42
|
end
|
|
42
43
|
|
|
43
44
|
# A hash representing the state of the source map's API.
|
|
@@ -47,7 +48,7 @@ module Solargraph
|
|
|
47
48
|
#
|
|
48
49
|
# @return [Integer]
|
|
49
50
|
def api_hash
|
|
50
|
-
@api_hash ||= (pins_by_class(Pin::Constant) + pins_by_class(Pin::Namespace).select { |pin| pin.namespace.to_s > '' } + pins_by_class(Pin::Reference) + pins_by_class(Pin::Method).map(&:node)).hash
|
|
51
|
+
@api_hash ||= (pins_by_class(Pin::Constant) + pins_by_class(Pin::Namespace).select { |pin| pin.namespace.to_s > '' } + pins_by_class(Pin::Reference) + pins_by_class(Pin::Method).map(&:node) + locals).hash
|
|
51
52
|
end
|
|
52
53
|
|
|
53
54
|
# @return [String]
|
|
@@ -117,10 +118,13 @@ module Solargraph
|
|
|
117
118
|
_locate_pin line, character, Pin::Namespace, Pin::Method, Pin::Block
|
|
118
119
|
end
|
|
119
120
|
|
|
121
|
+
# @todo Candidate for deprecation
|
|
122
|
+
#
|
|
120
123
|
# @param other_map [SourceMap]
|
|
121
124
|
# @return [Boolean]
|
|
122
125
|
def try_merge! other_map
|
|
123
126
|
return false if pins.length != other_map.pins.length || locals.length != other_map.locals.length || requires.map(&:name).uniq.sort != other_map.requires.map(&:name).uniq.sort
|
|
127
|
+
|
|
124
128
|
pins.each_index do |i|
|
|
125
129
|
return false unless pins[i].try_merge!(other_map.pins[i])
|
|
126
130
|
end
|
|
@@ -161,16 +165,24 @@ module Solargraph
|
|
|
161
165
|
SourceMap.map(source)
|
|
162
166
|
end
|
|
163
167
|
|
|
168
|
+
# @deprecated
|
|
164
169
|
# @param source [Source]
|
|
165
170
|
# @return [SourceMap]
|
|
166
171
|
def map source
|
|
167
|
-
|
|
168
|
-
new(source, *result)
|
|
172
|
+
new(source)
|
|
169
173
|
end
|
|
170
174
|
end
|
|
171
175
|
|
|
172
176
|
private
|
|
173
177
|
|
|
178
|
+
def pin_class_hash
|
|
179
|
+
@pin_class_hash ||= pins.to_set.classify(&:class).transform_values(&:to_a)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def data
|
|
183
|
+
@data ||= Data.new(source)
|
|
184
|
+
end
|
|
185
|
+
|
|
174
186
|
# @return [Array<Pin::Base>]
|
|
175
187
|
def convention_pins
|
|
176
188
|
@convention_pins || []
|
|
@@ -179,7 +191,7 @@ module Solargraph
|
|
|
179
191
|
# @param pins [Array<Pin::Base>]
|
|
180
192
|
# @return [Array<Pin::Base>]
|
|
181
193
|
def convention_pins=(pins)
|
|
182
|
-
# unmemoizing the document_symbols in case it was called from any of
|
|
194
|
+
# unmemoizing the document_symbols in case it was called from any of conventions
|
|
183
195
|
@document_symbols = nil
|
|
184
196
|
@convention_pins = pins
|
|
185
197
|
end
|
|
@@ -50,6 +50,8 @@ module Solargraph
|
|
|
50
50
|
# @param inferred [ComplexType]
|
|
51
51
|
# @return [Boolean]
|
|
52
52
|
def any_types_match? api_map, expected, inferred
|
|
53
|
+
expected = expected.downcast_to_literal_if_possible
|
|
54
|
+
inferred = inferred.downcast_to_literal_if_possible
|
|
53
55
|
return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
|
|
54
56
|
# walk through the union expected type and see if any members
|
|
55
57
|
# of the union match the inferred type
|
|
@@ -71,6 +73,8 @@ module Solargraph
|
|
|
71
73
|
# @param expected [ComplexType]
|
|
72
74
|
# @return [Boolean]
|
|
73
75
|
def all_types_match? api_map, inferred, expected
|
|
76
|
+
expected = expected.downcast_to_literal_if_possible
|
|
77
|
+
inferred = inferred.downcast_to_literal_if_possible
|
|
74
78
|
return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
|
|
75
79
|
inferred.each do |inf|
|
|
76
80
|
next if inf.duck_type?
|
|
@@ -9,7 +9,8 @@ module Solargraph
|
|
|
9
9
|
normal: 0,
|
|
10
10
|
typed: 1,
|
|
11
11
|
strict: 2,
|
|
12
|
-
strong: 3
|
|
12
|
+
strong: 3,
|
|
13
|
+
alpha: 4
|
|
13
14
|
}.freeze
|
|
14
15
|
|
|
15
16
|
# @return [Symbol]
|
|
@@ -52,6 +53,10 @@ module Solargraph
|
|
|
52
53
|
def validate_tags?
|
|
53
54
|
rank > LEVELS[:normal]
|
|
54
55
|
end
|
|
56
|
+
|
|
57
|
+
def require_all_return_types_match_inferred?
|
|
58
|
+
rank >= LEVELS[:alpha]
|
|
59
|
+
end
|
|
55
60
|
end
|
|
56
61
|
end
|
|
57
62
|
end
|
|
@@ -29,6 +29,7 @@ module Solargraph
|
|
|
29
29
|
# @todo Smarter directory resolution
|
|
30
30
|
@api_map = api_map || Solargraph::ApiMap.load(File.dirname(filename))
|
|
31
31
|
@rules = Rules.new(level)
|
|
32
|
+
# @type [Array<Range>]
|
|
32
33
|
@marked_ranges = []
|
|
33
34
|
end
|
|
34
35
|
|
|
@@ -90,11 +91,11 @@ module Solargraph
|
|
|
90
91
|
def method_return_type_problems_for pin
|
|
91
92
|
return [] if pin.is_a?(Pin::MethodAlias)
|
|
92
93
|
result = []
|
|
93
|
-
declared = pin.typify(api_map).
|
|
94
|
+
declared = pin.typify(api_map).self_to_type(pin.full_context).qualify(api_map, pin.full_context.tag)
|
|
94
95
|
if declared.undefined?
|
|
95
96
|
if pin.return_type.undefined? && rules.require_type_tags?
|
|
96
97
|
if pin.attribute?
|
|
97
|
-
inferred = pin.probe(api_map).
|
|
98
|
+
inferred = pin.probe(api_map).self_to_type(pin.full_context)
|
|
98
99
|
result.push Problem.new(pin.location, "Missing @return tag for #{pin.path}", pin: pin) unless inferred.defined?
|
|
99
100
|
else
|
|
100
101
|
result.push Problem.new(pin.location, "Missing @return tag for #{pin.path}", pin: pin)
|
|
@@ -106,14 +107,14 @@ module Solargraph
|
|
|
106
107
|
end
|
|
107
108
|
elsif rules.validate_tags?
|
|
108
109
|
unless pin.node.nil? || declared.void? || virtual_pin?(pin) || abstract?(pin)
|
|
109
|
-
inferred = pin.probe(api_map).
|
|
110
|
+
inferred = pin.probe(api_map).self_to_type(pin.full_context)
|
|
110
111
|
if inferred.undefined?
|
|
111
112
|
unless rules.ignore_all_undefined? || external?(pin)
|
|
112
113
|
result.push Problem.new(pin.location, "#{pin.path} return type could not be inferred", pin: pin)
|
|
113
114
|
end
|
|
114
115
|
else
|
|
115
|
-
unless (rules.
|
|
116
|
-
result.push Problem.new(pin.location, "Declared return type #{declared} does not match inferred type #{inferred} for #{pin.path}", pin: pin)
|
|
116
|
+
unless (rules.require_all_return_types_match_inferred? ? all_types_match?(api_map, inferred, declared) : any_types_match?(api_map, declared, inferred))
|
|
117
|
+
result.push Problem.new(pin.location, "Declared return type #{declared.rooted_tags} does not match inferred type #{inferred.rooted_tags} for #{pin.path}", pin: pin)
|
|
117
118
|
end
|
|
118
119
|
end
|
|
119
120
|
end
|
|
@@ -154,7 +155,7 @@ module Solargraph
|
|
|
154
155
|
break if par.decl == :restarg || par.decl == :kwrestarg || par.decl == :blockarg
|
|
155
156
|
unless params[par.name]
|
|
156
157
|
if pin.attribute?
|
|
157
|
-
inferred = pin.probe(api_map).
|
|
158
|
+
inferred = pin.probe(api_map).self_to_type(pin.full_context)
|
|
158
159
|
if inferred.undefined?
|
|
159
160
|
result.push Problem.new(pin.location, "Missing @param tag for #{par.name} on #{pin.path}", pin: pin)
|
|
160
161
|
end
|
|
@@ -377,7 +378,7 @@ module Solargraph
|
|
|
377
378
|
break
|
|
378
379
|
end
|
|
379
380
|
ptype = params.key?(par.name) ? params[par.name][:qualified] : ComplexType::UNDEFINED
|
|
380
|
-
ptype = ptype.
|
|
381
|
+
ptype = ptype.self_to_type(par.context)
|
|
381
382
|
if ptype.nil?
|
|
382
383
|
# @todo Some level (strong, I guess) should require the param here
|
|
383
384
|
else
|
|
@@ -413,7 +414,7 @@ module Solargraph
|
|
|
413
414
|
# @param locals [Array<Pin::LocalVariable>]
|
|
414
415
|
# @param location [Location]
|
|
415
416
|
# @param pin [Pin::Method]
|
|
416
|
-
# @param params [Hash{String =>
|
|
417
|
+
# @param params [Hash{String => Hash{Symbol => String, Solargraph::ComplexType}}]
|
|
417
418
|
# @param idx [Integer]
|
|
418
419
|
#
|
|
419
420
|
# @return [Array<Problem>]
|
|
@@ -467,13 +468,24 @@ module Solargraph
|
|
|
467
468
|
end
|
|
468
469
|
|
|
469
470
|
# @param pin [Pin::Method]
|
|
470
|
-
# @return [Hash{String => Hash{Symbol =>
|
|
471
|
+
# @return [Hash{String => Hash{Symbol => String, ComplexType}}]
|
|
471
472
|
def param_hash(pin)
|
|
472
|
-
|
|
473
|
-
return {} if tags.empty?
|
|
473
|
+
# @type [Hash{String => Hash{Symbol => String, ComplexType}}]
|
|
474
474
|
result = {}
|
|
475
|
+
pin.parameters.each do |param|
|
|
476
|
+
type = param.typify(api_map)
|
|
477
|
+
next if type.nil? || type.undefined?
|
|
478
|
+
result[param.name.to_s] = {
|
|
479
|
+
tagged: type.tags,
|
|
480
|
+
qualified: type
|
|
481
|
+
}
|
|
482
|
+
end
|
|
483
|
+
# see if we have additional tags to pay attention to from YARD -
|
|
484
|
+
# e.g., kwargs in a **restkwargs splat
|
|
485
|
+
tags = pin.docstring.tags(:param)
|
|
475
486
|
tags.each do |tag|
|
|
476
|
-
next if
|
|
487
|
+
next if result.key? tag.name.to_s
|
|
488
|
+
next if tag.types.nil?
|
|
477
489
|
result[tag.name.to_s] = {
|
|
478
490
|
tagged: tag.types.join(', '),
|
|
479
491
|
qualified: Solargraph::ComplexType.try_parse(*tag.types).qualify(api_map, pin.full_context.namespace)
|
|
@@ -483,15 +495,29 @@ module Solargraph
|
|
|
483
495
|
end
|
|
484
496
|
|
|
485
497
|
# @param pins [Array<Pin::Method>]
|
|
486
|
-
# @return [Hash{String => Hash{Symbol =>
|
|
498
|
+
# @return [Hash{String => Hash{Symbol => String, ComplexType}}]
|
|
487
499
|
def first_param_hash(pins)
|
|
488
|
-
pins.
|
|
500
|
+
return {} if pins.empty?
|
|
501
|
+
first_pin_type = pins.first.typify(api_map)
|
|
502
|
+
first_pin = pins.first.proxy first_pin_type
|
|
503
|
+
param_names = first_pin.parameter_names
|
|
504
|
+
results = param_hash(first_pin)
|
|
505
|
+
pins[1..].each do |pin|
|
|
489
506
|
# @todo this assignment from parametric use of Hash should not lose its generic
|
|
490
507
|
# @type [Hash{String => Hash{Symbol => BasicObject}}]
|
|
491
|
-
|
|
492
|
-
|
|
508
|
+
|
|
509
|
+
# documentation of types in superclasses should fail back to
|
|
510
|
+
# subclasses if the subclass hasn't documented something
|
|
511
|
+
superclass_results = param_hash(pin)
|
|
512
|
+
superclass_results.each do |param_name, details|
|
|
513
|
+
next unless param_names.include?(param_name)
|
|
514
|
+
|
|
515
|
+
results[param_name] ||= {}
|
|
516
|
+
results[param_name][:tagged] ||= details[:tagged]
|
|
517
|
+
results[param_name][:qualified] ||= details[:qualified]
|
|
518
|
+
end
|
|
493
519
|
end
|
|
494
|
-
|
|
520
|
+
results
|
|
495
521
|
end
|
|
496
522
|
|
|
497
523
|
# @param pin [Pin::Base]
|
|
@@ -512,7 +538,7 @@ module Solargraph
|
|
|
512
538
|
!internal? pin
|
|
513
539
|
end
|
|
514
540
|
|
|
515
|
-
# @param pin [Pin::
|
|
541
|
+
# @param pin [Pin::BaseVariable]
|
|
516
542
|
def declared_externally? pin
|
|
517
543
|
return true if pin.assignment.nil?
|
|
518
544
|
chain = Solargraph::Parser.chain(pin.assignment, filename)
|
|
@@ -562,7 +588,7 @@ module Solargraph
|
|
|
562
588
|
return [] unless pin.explicit?
|
|
563
589
|
return [] if parameters.empty? && arguments.empty?
|
|
564
590
|
return [] if pin.anon_splat?
|
|
565
|
-
unchecked = arguments.
|
|
591
|
+
unchecked = arguments.dup # creates copy of and unthaws array
|
|
566
592
|
add_params = 0
|
|
567
593
|
if unchecked.empty? && parameters.any? { |param| param.decl == :kwarg }
|
|
568
594
|
return [Problem.new(location, "Missing keyword arguments to #{pin.path}")]
|
|
@@ -584,7 +610,8 @@ module Solargraph
|
|
|
584
610
|
kwargs.delete param.name.to_sym
|
|
585
611
|
settled_kwargs += 1
|
|
586
612
|
elsif param.decl == :kwarg
|
|
587
|
-
|
|
613
|
+
last_arg_last_link = arguments.last.links.last
|
|
614
|
+
return [] if last_arg_last_link.is_a?(Solargraph::Source::Chain::Hash) && last_arg_last_link.splatted?
|
|
588
615
|
return [Problem.new(location, "Missing keyword argument #{param.name} to #{pin.path}")]
|
|
589
616
|
end
|
|
590
617
|
end
|
|
@@ -638,7 +665,7 @@ module Solargraph
|
|
|
638
665
|
(pin.closure && pin.closure.docstring.has_tag?('abstract'))
|
|
639
666
|
end
|
|
640
667
|
|
|
641
|
-
# @param pin [Pin::
|
|
668
|
+
# @param pin [Pin::Method]
|
|
642
669
|
# @return [Array<Source::Chain>]
|
|
643
670
|
def fake_args_for(pin)
|
|
644
671
|
args = []
|
data/lib/solargraph/version.rb
CHANGED
|
@@ -35,11 +35,9 @@
|
|
|
35
35
|
<li>
|
|
36
36
|
Core Cache Directory: N/A <%# @todo Fix %>
|
|
37
37
|
</li>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
</li>
|
|
42
|
-
<% end %>
|
|
38
|
+
<li>
|
|
39
|
+
Parser Target Version: <%= Solargraph::Parser.version %>
|
|
40
|
+
</li>
|
|
43
41
|
<li>
|
|
44
42
|
Using Bundler: <%= ENV.key?('BUNDLE_BIN_PATH') %>
|
|
45
43
|
</li>
|
|
@@ -15,7 +15,7 @@ module Solargraph
|
|
|
15
15
|
attr_reader :directory
|
|
16
16
|
|
|
17
17
|
# @todo To make this strongly typed we'll need a record syntax
|
|
18
|
-
# @return [Hash{String =>
|
|
18
|
+
# @return [Hash{String => Array, Hash, Integer, nil}]
|
|
19
19
|
attr_reader :raw_data
|
|
20
20
|
|
|
21
21
|
# @param directory [String]
|
|
@@ -90,6 +90,7 @@ module Solargraph
|
|
|
90
90
|
|
|
91
91
|
# A hash of options supported by the formatter
|
|
92
92
|
#
|
|
93
|
+
# @sg-ignore pending https://github.com/castwide/solargraph/pull/905
|
|
93
94
|
# @return [Hash]
|
|
94
95
|
def formatter
|
|
95
96
|
raw_data['formatter']
|
|
@@ -104,6 +105,7 @@ module Solargraph
|
|
|
104
105
|
|
|
105
106
|
# The maximum number of files to parse from the workspace.
|
|
106
107
|
#
|
|
108
|
+
# @sg-ignore pending https://github.com/castwide/solargraph/pull/905
|
|
107
109
|
# @return [Integer]
|
|
108
110
|
def max_files
|
|
109
111
|
raw_data['max_files']
|
|
@@ -123,7 +125,7 @@ module Solargraph
|
|
|
123
125
|
File.join(@directory, '.solargraph.yml')
|
|
124
126
|
end
|
|
125
127
|
|
|
126
|
-
# @return [Hash{String => Array
|
|
128
|
+
# @return [Hash{String => Array<undefined>, Hash{String => undefined}, Integer}]
|
|
127
129
|
def config_data
|
|
128
130
|
workspace_config = read_config(workspace_config_path)
|
|
129
131
|
global_config = read_config(global_config_path)
|
|
@@ -226,7 +228,9 @@ module Solargraph
|
|
|
226
228
|
|
|
227
229
|
# @return [Array<String>]
|
|
228
230
|
def excluded_directories
|
|
229
|
-
@
|
|
231
|
+
# @type [Array<String>]
|
|
232
|
+
excluded = @raw_data['exclude']
|
|
233
|
+
excluded
|
|
230
234
|
.select { |g| glob_is_directory?(g) }
|
|
231
235
|
.map { |g| File.absolute_path(glob_to_directory(g), directory) }
|
|
232
236
|
end
|
data/lib/solargraph/workspace.rb
CHANGED
|
@@ -45,7 +45,7 @@ module Solargraph
|
|
|
45
45
|
# or add it to the sources if the workspace is configured to include it.
|
|
46
46
|
# The source is ignored if the configuration excludes it.
|
|
47
47
|
#
|
|
48
|
-
# @param
|
|
48
|
+
# @param sources [Array<Solargraph::Source>]
|
|
49
49
|
# @return [Boolean] True if the source was added to the workspace
|
|
50
50
|
def merge *sources
|
|
51
51
|
unless directory == '*' || sources.all? { |source| source_hash.key?(source.filename) }
|
|
@@ -16,29 +16,55 @@ module Solargraph
|
|
|
16
16
|
def self.make code_object, name = nil, scope = nil, visibility = nil, closure = nil, spec = nil
|
|
17
17
|
closure ||= Solargraph::Pin::Namespace.new(
|
|
18
18
|
name: code_object.namespace.to_s,
|
|
19
|
-
gates: [code_object.namespace.to_s]
|
|
19
|
+
gates: [code_object.namespace.to_s],
|
|
20
|
+
type: code_object.namespace.is_a?(YARD::CodeObjects::ClassObject) ? :class : :module,
|
|
21
|
+
source: :yardoc,
|
|
20
22
|
)
|
|
21
23
|
location = object_location(code_object, spec)
|
|
22
24
|
name ||= code_object.name.to_s
|
|
23
25
|
return_type = ComplexType::SELF if name == 'new'
|
|
24
26
|
comments = code_object.docstring ? code_object.docstring.all.to_s : ''
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
27
|
+
final_scope = scope || code_object.scope
|
|
28
|
+
final_visibility = visibility || code_object.visibility
|
|
29
|
+
if code_object.is_alias?
|
|
30
|
+
origin_code_object = code_object.namespace.aliases[code_object]
|
|
31
|
+
pin = Pin::MethodAlias.new(
|
|
32
|
+
name: name,
|
|
33
|
+
location: location,
|
|
34
|
+
original: origin_code_object.name.to_s,
|
|
35
|
+
closure: closure,
|
|
36
|
+
comments: comments,
|
|
37
|
+
scope: final_scope,
|
|
38
|
+
visibility: final_visibility,
|
|
39
|
+
explicit: code_object.is_explicit?,
|
|
40
|
+
return_type: return_type,
|
|
41
|
+
parameters: [],
|
|
42
|
+
source: :yardoc,
|
|
43
|
+
)
|
|
44
|
+
else
|
|
45
|
+
pin = Pin::Method.new(
|
|
46
|
+
location: location,
|
|
47
|
+
closure: closure,
|
|
48
|
+
name: name,
|
|
49
|
+
comments: comments,
|
|
50
|
+
scope: final_scope,
|
|
51
|
+
visibility: final_visibility,
|
|
52
|
+
# @todo Might need to convert overloads to signatures
|
|
53
|
+
explicit: code_object.is_explicit?,
|
|
54
|
+
return_type: return_type,
|
|
55
|
+
attribute: code_object.is_attribute?,
|
|
56
|
+
parameters: [],
|
|
57
|
+
source: :yardoc,
|
|
58
|
+
)
|
|
59
|
+
pin.parameters.concat get_parameters(code_object, location, comments, pin)
|
|
60
|
+
end
|
|
61
|
+
logger.debug { "ToMethod.make: Just created method pin: #{pin.inspect}" }
|
|
38
62
|
pin
|
|
39
63
|
end
|
|
40
64
|
|
|
41
65
|
class << self
|
|
66
|
+
include Logging
|
|
67
|
+
|
|
42
68
|
private
|
|
43
69
|
|
|
44
70
|
# @param code_object [YARD::CodeObjects::Base]
|
|
@@ -59,7 +85,8 @@ module Solargraph
|
|
|
59
85
|
name: arg_name(a),
|
|
60
86
|
presence: nil,
|
|
61
87
|
decl: arg_type(a),
|
|
62
|
-
asgn_code: a[1]
|
|
88
|
+
asgn_code: a[1],
|
|
89
|
+
source: :yardoc,
|
|
63
90
|
)
|
|
64
91
|
end
|
|
65
92
|
end
|
data/lib/solargraph/yardoc.rb
CHANGED
|
@@ -35,7 +35,7 @@ module Solargraph
|
|
|
35
35
|
# @param gemspec [Gem::Specification]
|
|
36
36
|
# @return [String]
|
|
37
37
|
def path_for(gemspec)
|
|
38
|
-
File.join(Solargraph::Cache.
|
|
38
|
+
File.join(Solargraph::Cache.base_dir, "yard-#{YARD::VERSION}", "#{gemspec.name}-#{gemspec.version}.yardoc")
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
# Load a gem's yardoc and return its code objects.
|
data/lib/solargraph.rb
CHANGED
|
@@ -42,6 +42,7 @@ module Solargraph
|
|
|
42
42
|
autoload :Logging, 'solargraph/logging'
|
|
43
43
|
autoload :TypeChecker, 'solargraph/type_checker'
|
|
44
44
|
autoload :Environ, 'solargraph/environ'
|
|
45
|
+
autoload :Equality, 'solargraph/equality'
|
|
45
46
|
autoload :Convention, 'solargraph/convention'
|
|
46
47
|
autoload :Parser, 'solargraph/parser'
|
|
47
48
|
autoload :RbsMap, 'solargraph/rbs_map'
|
data/solargraph.gemspec
CHANGED
|
@@ -24,10 +24,10 @@ Gem::Specification.new do |s|
|
|
|
24
24
|
s.required_ruby_version = '>= 3.0'
|
|
25
25
|
|
|
26
26
|
s.add_runtime_dependency 'backport', '~> 1.2'
|
|
27
|
-
s.add_runtime_dependency 'benchmark'
|
|
27
|
+
s.add_runtime_dependency 'benchmark', '~> 0.4'
|
|
28
28
|
s.add_runtime_dependency 'bundler', '~> 2.0'
|
|
29
29
|
s.add_runtime_dependency 'diff-lcs', '~> 1.4'
|
|
30
|
-
s.add_runtime_dependency 'jaro_winkler', '~> 1.6'
|
|
30
|
+
s.add_runtime_dependency 'jaro_winkler', '~> 1.6', '>= 1.6.1'
|
|
31
31
|
s.add_runtime_dependency 'kramdown', '~> 2.3'
|
|
32
32
|
s.add_runtime_dependency 'kramdown-parser-gfm', '~> 1.1'
|
|
33
33
|
s.add_runtime_dependency 'logger', '~> 1.6'
|
|
@@ -35,19 +35,19 @@ Gem::Specification.new do |s|
|
|
|
35
35
|
s.add_runtime_dependency 'ostruct', '~> 0.6'
|
|
36
36
|
s.add_runtime_dependency 'parser', '~> 3.0'
|
|
37
37
|
s.add_runtime_dependency 'rbs', '~> 3.3'
|
|
38
|
-
s.add_runtime_dependency 'reverse_markdown', '
|
|
38
|
+
s.add_runtime_dependency 'reverse_markdown', '~> 3.0'
|
|
39
39
|
s.add_runtime_dependency 'rubocop', '~> 1.38'
|
|
40
40
|
s.add_runtime_dependency 'thor', '~> 1.0'
|
|
41
41
|
s.add_runtime_dependency 'tilt', '~> 2.0'
|
|
42
42
|
s.add_runtime_dependency 'yard', '~> 0.9', '>= 0.9.24'
|
|
43
43
|
s.add_runtime_dependency 'yard-solargraph', '~> 0.1'
|
|
44
44
|
|
|
45
|
-
s.add_development_dependency 'pry'
|
|
45
|
+
s.add_development_dependency 'pry', '~> 0.15'
|
|
46
46
|
s.add_development_dependency 'public_suffix', '~> 3.1'
|
|
47
47
|
s.add_development_dependency 'rake', '~> 13.2'
|
|
48
48
|
s.add_development_dependency 'rspec', '~> 3.5'
|
|
49
49
|
s.add_development_dependency 'simplecov', '~> 0.14'
|
|
50
50
|
s.add_development_dependency 'webmock', '~> 3.6'
|
|
51
51
|
# work around missing yard dependency needed as of Ruby 3.5
|
|
52
|
-
s.add_development_dependency 'irb'
|
|
52
|
+
s.add_development_dependency 'irb', '~> 1.15'
|
|
53
53
|
end
|