solargraph 0.60.4 → 0.62.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 +24 -2
- data/.github/workflows/plugins.yml +19 -1
- data/.github/workflows/rspec.yml +17 -2
- data/.github/workflows/typecheck.yml +6 -0
- data/CHANGELOG.md +54 -0
- data/Gemfile +0 -3
- data/lib/solargraph/api_map/index.rb +28 -4
- data/lib/solargraph/api_map/store.rb +19 -0
- data/lib/solargraph/api_map.rb +91 -80
- data/lib/solargraph/cache_dir.rb +58 -0
- data/lib/solargraph/collection/base.rb +50 -0
- data/lib/solargraph/collection/core.rb +17 -0
- data/lib/solargraph/collection/gem.rb +59 -0
- data/lib/solargraph/collection/stdlib.rb +25 -0
- data/lib/solargraph/collection.rb +30 -0
- data/lib/solargraph/complex_type/unique_type.rb +13 -0
- data/lib/solargraph/complex_type.rb +23 -3
- data/lib/solargraph/convention.rb +5 -7
- data/lib/solargraph/diagnostics/require_not_found.rb +0 -4
- data/lib/solargraph/diagnostics/type_check.rb +0 -1
- data/lib/solargraph/external.rb +187 -0
- data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
- data/lib/solargraph/language_server/host/dispatch.rb +4 -2
- data/lib/solargraph/language_server/host.rb +10 -2
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +10 -3
- data/lib/solargraph/language_server/message/text_document/definition.rb +5 -2
- data/lib/solargraph/language_server/message/text_document/hover.rb +1 -2
- data/lib/solargraph/library.rb +26 -53
- data/lib/solargraph/metagem.rb +80 -0
- data/lib/solargraph/parser/node_processor/base.rb +6 -0
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +22 -3
- data/lib/solargraph/parser/parser_gem/node_methods.rb +29 -6
- data/lib/solargraph/parser/parser_gem/node_processors/class_definition/class_assignment_node.rb +98 -0
- data/lib/solargraph/parser/parser_gem/node_processors/class_definition.rb +54 -0
- data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/data_definition/data_assignment_node.rb +65 -0
- data/lib/solargraph/parser/parser_gem/node_processors/data_definition/data_definition_node.rb +97 -0
- data/lib/solargraph/parser/parser_gem/node_processors/data_definition.rb +110 -0
- data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +2 -0
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +185 -0
- data/lib/solargraph/parser/parser_gem/node_processors/struct_definition/struct_assignment_node.rb +66 -0
- data/lib/solargraph/parser/parser_gem/node_processors/struct_definition/struct_definition_node.rb +108 -0
- data/lib/solargraph/parser/parser_gem/node_processors/struct_definition.rb +170 -0
- data/lib/solargraph/parser/parser_gem/node_processors.rb +33 -29
- data/lib/solargraph/pin/base.rb +25 -1
- data/lib/solargraph/pin/base_variable.rb +31 -1
- data/lib/solargraph/pin/callable.rb +11 -2
- data/lib/solargraph/pin/closure.rb +17 -0
- data/lib/solargraph/pin/delegated_method.rb +5 -0
- data/lib/solargraph/pin/duck_method.rb +36 -16
- data/lib/solargraph/pin/factory_parameter.rb +84 -0
- data/lib/solargraph/pin/instance_variable.rb +45 -0
- data/lib/solargraph/pin/method.rb +10 -0
- data/lib/solargraph/pin/method_alias.rb +4 -0
- data/lib/solargraph/pin/parameter.rb +1 -1
- data/lib/solargraph/pin/reference/included_mixin.rb +22 -0
- data/lib/solargraph/pin/reference.rb +1 -0
- data/lib/solargraph/pin.rb +1 -0
- data/lib/solargraph/plugin/active_support.rb +100 -0
- data/lib/solargraph/plugin/addon.rb +16 -0
- data/lib/solargraph/plugin/base.rb +25 -0
- data/lib/solargraph/plugin/panel.rb +37 -0
- data/lib/solargraph/plugin.rb +26 -0
- data/lib/solargraph/rbs_collection.rb +119 -0
- data/lib/solargraph/rbs_map/base.rb +31 -0
- data/lib/solargraph/rbs_map/conversions.rb +109 -48
- data/lib/solargraph/rbs_map/{core_map.rb → core.rb} +18 -39
- data/lib/solargraph/rbs_map/core_fills.rb +1 -1
- data/lib/solargraph/rbs_map/gem.rb +16 -0
- data/lib/solargraph/rbs_map/helpers.rb +61 -0
- data/lib/solargraph/rbs_map/path.rb +19 -0
- data/lib/solargraph/rbs_map/stdlib.rb +24 -0
- data/lib/solargraph/rbs_map.rb +7 -198
- data/lib/solargraph/rbs_translator.rb +105 -70
- data/lib/solargraph/repo.rb +177 -0
- data/lib/solargraph/shell.rb +49 -99
- data/lib/solargraph/source/chain/call.rb +58 -14
- data/lib/solargraph/source/chain/literal.rb +17 -17
- data/lib/solargraph/source/chain/parameter.rb +79 -0
- data/lib/solargraph/source/chain.rb +8 -0
- data/lib/solargraph/source/node_map.rb +27 -0
- data/lib/solargraph/source/source_chainer.rb +40 -44
- data/lib/solargraph/source.rb +17 -0
- data/lib/solargraph/source_map/call.rb +18 -0
- data/lib/solargraph/source_map/clip.rb +5 -3
- data/lib/solargraph/source_map/mapper.rb +6 -2
- data/lib/solargraph/source_map.rb +28 -9
- data/lib/solargraph/type_checker/rules.rb +3 -2
- data/lib/solargraph/type_checker.rb +4 -1
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace.rb +0 -1
- data/lib/solargraph/yard_map/cache.rb +1 -1
- data/lib/solargraph/yard_map/directives/attribute_directive.rb +1 -1
- data/lib/solargraph/yard_map/directives/domain_directive.rb +1 -1
- data/lib/solargraph/yard_map/directives/method_directive.rb +1 -1
- data/lib/solargraph/yard_map/directives/override_directive.rb +1 -1
- data/lib/solargraph/yard_map/directives/parse_directive.rb +1 -1
- data/lib/solargraph/yard_map/directives/scope_directive.rb +178 -0
- data/lib/solargraph/yard_map/directives/visibility_directive.rb +1 -1
- data/lib/solargraph/yard_map/directives.rb +5 -2
- data/lib/solargraph/yard_map/helpers.rb +1 -1
- data/lib/solargraph/yard_map/macro.rb +85 -6
- data/lib/solargraph/yard_map/mapper/to_constant.rb +1 -1
- data/lib/solargraph/yard_map/mapper/to_method.rb +1 -1
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -1
- data/lib/solargraph/yard_map/mapper.rb +2 -2
- data/lib/solargraph/yard_map.rb +1 -1
- data/lib/solargraph/yardoc.rb +43 -60
- data/lib/solargraph.rb +8 -3
- data/rbs/fills/boolean/0/boolean.rbs +12 -0
- data/solargraph.gemspec +2 -2
- metadata +41 -18
- data/lib/solargraph/convention/active_support_concern.rb +0 -111
- data/lib/solargraph/convention/data_definition/data_assignment_node.rb +0 -61
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +0 -93
- data/lib/solargraph/convention/data_definition.rb +0 -108
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +0 -62
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +0 -103
- data/lib/solargraph/convention/struct_definition.rb +0 -168
- data/lib/solargraph/doc_map.rb +0 -439
- data/lib/solargraph/gem_pins.rb +0 -87
- data/lib/solargraph/pin_cache.rb +0 -248
- data/lib/solargraph/rbs_map/stdlib_map.rb +0 -71
- data/lib/solargraph/workspace/gemspecs.rb +0 -373
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module Parser
|
|
5
|
+
module ParserGem
|
|
6
|
+
module NodeProcessors
|
|
7
|
+
module StructDefinition
|
|
8
|
+
autoload :StructDefintionNode, 'solargraph/parser/parser_gem/node_processors/struct_definition/struct_definition_node'
|
|
9
|
+
autoload :StructAssignmentNode, 'solargraph/parser/parser_gem/node_processors/struct_definition/struct_assignment_node'
|
|
10
|
+
|
|
11
|
+
class StructNode < Parser::NodeProcessor::Base
|
|
12
|
+
# @return [Boolean] continue processing the next processor of the same node.
|
|
13
|
+
def process
|
|
14
|
+
return true if struct_definition_node.nil?
|
|
15
|
+
|
|
16
|
+
loc = get_node_location(node)
|
|
17
|
+
nspin = Solargraph::Pin::Namespace.new(
|
|
18
|
+
type: :class,
|
|
19
|
+
location: loc,
|
|
20
|
+
closure: region.closure,
|
|
21
|
+
# @sg-ignore flow sensitive typing needs to handle attrs
|
|
22
|
+
name: struct_definition_node.class_name,
|
|
23
|
+
docstring: docstring,
|
|
24
|
+
visibility: :public,
|
|
25
|
+
gates: region.closure.gates.freeze,
|
|
26
|
+
source: :struct_definition
|
|
27
|
+
)
|
|
28
|
+
pins.push nspin
|
|
29
|
+
|
|
30
|
+
# define initialize method
|
|
31
|
+
initialize_method_pin = Pin::Method.new(
|
|
32
|
+
name: 'initialize',
|
|
33
|
+
parameters: [],
|
|
34
|
+
scope: :instance,
|
|
35
|
+
location: get_node_location(node),
|
|
36
|
+
closure: nspin,
|
|
37
|
+
visibility: :private,
|
|
38
|
+
docstring: docstring,
|
|
39
|
+
source: :struct_definition
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
pins.push initialize_method_pin
|
|
43
|
+
|
|
44
|
+
# @sg-ignore flow sensitive typing needs to handle attrs
|
|
45
|
+
struct_definition_node.attributes.map do |attribute_node, attribute_name|
|
|
46
|
+
initialize_method_pin.parameters.push(
|
|
47
|
+
Pin::Parameter.new(
|
|
48
|
+
name: attribute_name,
|
|
49
|
+
decl: struct_definition_node.keyword_init? ? :kwoptarg : :arg,
|
|
50
|
+
location: get_node_location(attribute_node),
|
|
51
|
+
closure: initialize_method_pin,
|
|
52
|
+
source: :struct_definition
|
|
53
|
+
)
|
|
54
|
+
)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# define attribute accessors and instance variables
|
|
58
|
+
# @sg-ignore flow sensitive typing needs to handle attrs
|
|
59
|
+
struct_definition_node.attributes.each do |attribute_node, attribute_name|
|
|
60
|
+
[attribute_name, "#{attribute_name}="].each do |name|
|
|
61
|
+
docs = docstring.tags.find { |t| t.tag_name == 'param' && t.name == attribute_name }
|
|
62
|
+
|
|
63
|
+
attribute_type = ComplexType.parse(tag_string(docs))
|
|
64
|
+
return_type_comment = attribute_comment(docs, false)
|
|
65
|
+
param_comment = attribute_comment(docs, true)
|
|
66
|
+
|
|
67
|
+
method_pin = Pin::Method.new(
|
|
68
|
+
name: name,
|
|
69
|
+
parameters: [],
|
|
70
|
+
scope: :instance,
|
|
71
|
+
location: get_node_location(attribute_node),
|
|
72
|
+
closure: nspin,
|
|
73
|
+
docstring: YARD::Docstring.new(return_type_comment),
|
|
74
|
+
# even assignments return the value
|
|
75
|
+
comments: return_type_comment,
|
|
76
|
+
return_type: attribute_type,
|
|
77
|
+
visibility: :public,
|
|
78
|
+
source: :struct_definition
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
if name.end_with?('=')
|
|
82
|
+
method_pin.parameters << Pin::Parameter.new(
|
|
83
|
+
name: attribute_name,
|
|
84
|
+
location: get_node_location(attribute_node),
|
|
85
|
+
closure: method_pin,
|
|
86
|
+
return_type: attribute_type,
|
|
87
|
+
comments: param_comment,
|
|
88
|
+
source: :struct_definition
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
pins.push Pin::InstanceVariable.new(name: "@#{attribute_name}",
|
|
92
|
+
closure: method_pin,
|
|
93
|
+
location: get_node_location(attribute_node),
|
|
94
|
+
return_type: attribute_type,
|
|
95
|
+
comments: "@type [#{attribute_type.rooted_tags}]",
|
|
96
|
+
source: :struct_definition)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
pins.push method_pin
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
process_children region.update(closure: nspin, visibility: :public)
|
|
104
|
+
false
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
private
|
|
108
|
+
|
|
109
|
+
# @return [StructDefinition::StructDefintionNode, StructDefinition::StructAssignmentNode, nil]
|
|
110
|
+
def struct_definition_node
|
|
111
|
+
@struct_definition_node ||= if StructDefintionNode.match?(node)
|
|
112
|
+
StructDefintionNode.new(node)
|
|
113
|
+
elsif StructAssignmentNode.match?(node)
|
|
114
|
+
StructAssignmentNode.new(node)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Gets/generates the relevant docstring for this struct & it's attributes
|
|
119
|
+
# @return [YARD::Docstring]
|
|
120
|
+
def docstring
|
|
121
|
+
@docstring ||= parse_comments
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Parses any relevant comments for a struct int a yard docstring
|
|
125
|
+
# @return [YARD::Docstring]
|
|
126
|
+
def parse_comments
|
|
127
|
+
struct_comments = comments_for(node) || ''
|
|
128
|
+
# @sg-ignore Need to add nil check here
|
|
129
|
+
struct_definition_node.attributes.each do |attr_node, attr_name|
|
|
130
|
+
comment = comments_for(attr_node)
|
|
131
|
+
next if comment.nil?
|
|
132
|
+
|
|
133
|
+
# We should support specific comments for an attribute, and that can be either a @return on an @param
|
|
134
|
+
# But since we merge into the struct_comments, then we should interpret either as a param
|
|
135
|
+
comment = "@param #{attr_name}#{comment[7..]}" if comment.start_with?('@return')
|
|
136
|
+
|
|
137
|
+
struct_comments += "\n#{comment}"
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
Solargraph::Source.parse_docstring(struct_comments).to_docstring
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# @param tag [YARD::Tags::Tag, nil] The param tag for this attribute.xtract_
|
|
144
|
+
#
|
|
145
|
+
# @return [String]
|
|
146
|
+
def tag_string tag
|
|
147
|
+
tag&.types&.join(',') || 'undefined'
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# @param tag [YARD::Tags::Tag, nil] The param tag for this attribute. If nil, this method is a no-op
|
|
151
|
+
# @param for_setter [Boolean] If true, will return a @param tag instead of a @return tag
|
|
152
|
+
#
|
|
153
|
+
# @return [String] The formatted comment for the attribute
|
|
154
|
+
def attribute_comment tag, for_setter
|
|
155
|
+
return '' if tag.nil?
|
|
156
|
+
|
|
157
|
+
suffix = "[#{tag_string(tag)}] #{tag.text}"
|
|
158
|
+
|
|
159
|
+
if for_setter
|
|
160
|
+
"@param #{tag.name} #{suffix}"
|
|
161
|
+
else
|
|
162
|
+
"@return #{suffix}"
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
@@ -6,31 +6,34 @@ module Solargraph
|
|
|
6
6
|
module Parser
|
|
7
7
|
module ParserGem
|
|
8
8
|
module NodeProcessors
|
|
9
|
-
autoload :BeginNode,
|
|
10
|
-
autoload :DefNode,
|
|
11
|
-
autoload :DefsNode,
|
|
12
|
-
autoload :SendNode,
|
|
13
|
-
autoload :NamespaceNode,
|
|
14
|
-
autoload :SclassNode,
|
|
15
|
-
autoload :IvasgnNode,
|
|
16
|
-
autoload :IfNode,
|
|
17
|
-
autoload :CvasgnNode,
|
|
18
|
-
autoload :LvasgnNode,
|
|
19
|
-
autoload :GvasgnNode,
|
|
20
|
-
autoload :CasgnNode,
|
|
21
|
-
autoload :MasgnNode,
|
|
22
|
-
autoload :AliasNode,
|
|
23
|
-
autoload :ArgsNode,
|
|
24
|
-
autoload :BlockNode,
|
|
25
|
-
autoload :OrasgnNode,
|
|
26
|
-
autoload :OpasgnNode,
|
|
27
|
-
autoload :SymNode,
|
|
28
|
-
autoload :ResbodyNode,
|
|
29
|
-
autoload :UntilNode,
|
|
30
|
-
autoload :WhenNode,
|
|
31
|
-
autoload :WhileNode,
|
|
32
|
-
autoload :AndNode,
|
|
33
|
-
autoload :OrNode,
|
|
9
|
+
autoload :BeginNode, 'solargraph/parser/parser_gem/node_processors/begin_node'
|
|
10
|
+
autoload :DefNode, 'solargraph/parser/parser_gem/node_processors/def_node'
|
|
11
|
+
autoload :DefsNode, 'solargraph/parser/parser_gem/node_processors/defs_node'
|
|
12
|
+
autoload :SendNode, 'solargraph/parser/parser_gem/node_processors/send_node'
|
|
13
|
+
autoload :NamespaceNode, 'solargraph/parser/parser_gem/node_processors/namespace_node'
|
|
14
|
+
autoload :SclassNode, 'solargraph/parser/parser_gem/node_processors/sclass_node'
|
|
15
|
+
autoload :IvasgnNode, 'solargraph/parser/parser_gem/node_processors/ivasgn_node'
|
|
16
|
+
autoload :IfNode, 'solargraph/parser/parser_gem/node_processors/if_node'
|
|
17
|
+
autoload :CvasgnNode, 'solargraph/parser/parser_gem/node_processors/cvasgn_node'
|
|
18
|
+
autoload :LvasgnNode, 'solargraph/parser/parser_gem/node_processors/lvasgn_node'
|
|
19
|
+
autoload :GvasgnNode, 'solargraph/parser/parser_gem/node_processors/gvasgn_node'
|
|
20
|
+
autoload :CasgnNode, 'solargraph/parser/parser_gem/node_processors/casgn_node'
|
|
21
|
+
autoload :MasgnNode, 'solargraph/parser/parser_gem/node_processors/masgn_node'
|
|
22
|
+
autoload :AliasNode, 'solargraph/parser/parser_gem/node_processors/alias_node'
|
|
23
|
+
autoload :ArgsNode, 'solargraph/parser/parser_gem/node_processors/args_node'
|
|
24
|
+
autoload :BlockNode, 'solargraph/parser/parser_gem/node_processors/block_node'
|
|
25
|
+
autoload :OrasgnNode, 'solargraph/parser/parser_gem/node_processors/orasgn_node'
|
|
26
|
+
autoload :OpasgnNode, 'solargraph/parser/parser_gem/node_processors/opasgn_node'
|
|
27
|
+
autoload :SymNode, 'solargraph/parser/parser_gem/node_processors/sym_node'
|
|
28
|
+
autoload :ResbodyNode, 'solargraph/parser/parser_gem/node_processors/resbody_node'
|
|
29
|
+
autoload :UntilNode, 'solargraph/parser/parser_gem/node_processors/until_node'
|
|
30
|
+
autoload :WhenNode, 'solargraph/parser/parser_gem/node_processors/when_node'
|
|
31
|
+
autoload :WhileNode, 'solargraph/parser/parser_gem/node_processors/while_node'
|
|
32
|
+
autoload :AndNode, 'solargraph/parser/parser_gem/node_processors/and_node'
|
|
33
|
+
autoload :OrNode, 'solargraph/parser/parser_gem/node_processors/or_node'
|
|
34
|
+
autoload :ClassDefinition, 'solargraph/parser/parser_gem/node_processors/class_definition'
|
|
35
|
+
autoload :StructDefinition, 'solargraph/parser/parser_gem/node_processors/struct_definition'
|
|
36
|
+
autoload :DataDefinition, 'solargraph/parser/parser_gem/node_processors/data_definition'
|
|
34
37
|
end
|
|
35
38
|
end
|
|
36
39
|
|
|
@@ -44,8 +47,8 @@ module Solargraph
|
|
|
44
47
|
register :defs, ParserGem::NodeProcessors::DefsNode
|
|
45
48
|
register :if, ParserGem::NodeProcessors::IfNode
|
|
46
49
|
register :send, ParserGem::NodeProcessors::SendNode
|
|
47
|
-
register :class,
|
|
48
|
-
register :class,
|
|
50
|
+
register :class, ParserGem::NodeProcessors::StructDefinition::StructNode
|
|
51
|
+
register :class, ParserGem::NodeProcessors::DataDefinition::DataNode
|
|
49
52
|
register :class, ParserGem::NodeProcessors::NamespaceNode
|
|
50
53
|
register :module, ParserGem::NodeProcessors::NamespaceNode
|
|
51
54
|
register :sclass, ParserGem::NodeProcessors::SclassNode
|
|
@@ -53,8 +56,9 @@ module Solargraph
|
|
|
53
56
|
register :cvasgn, ParserGem::NodeProcessors::CvasgnNode
|
|
54
57
|
register :lvasgn, ParserGem::NodeProcessors::LvasgnNode
|
|
55
58
|
register :gvasgn, ParserGem::NodeProcessors::GvasgnNode
|
|
56
|
-
register :casgn,
|
|
57
|
-
register :casgn,
|
|
59
|
+
register :casgn, ParserGem::NodeProcessors::StructDefinition::StructNode
|
|
60
|
+
register :casgn, ParserGem::NodeProcessors::DataDefinition::DataNode
|
|
61
|
+
register :casgn, ParserGem::NodeProcessors::ClassDefinition::ClassNode
|
|
58
62
|
register :casgn, ParserGem::NodeProcessors::CasgnNode
|
|
59
63
|
register :masgn, ParserGem::NodeProcessors::MasgnNode
|
|
60
64
|
register :alias, ParserGem::NodeProcessors::AliasNode
|
data/lib/solargraph/pin/base.rb
CHANGED
|
@@ -158,7 +158,17 @@ module Solargraph
|
|
|
158
158
|
# @param other [self]
|
|
159
159
|
# @return [Pin::Closure, nil]
|
|
160
160
|
def combine_closure other
|
|
161
|
-
choose_pin_attr_with_same_name(other, :closure)
|
|
161
|
+
chosen = choose_pin_attr_with_same_name(other, :closure)
|
|
162
|
+
return chosen unless chosen.is_a?(Pin::Namespace) && chosen.generics.empty?
|
|
163
|
+
|
|
164
|
+
# Combined types may name type parameters only the other closure declares
|
|
165
|
+
own = closure
|
|
166
|
+
return own if own.is_a?(Pin::Namespace) && !own.generics.empty?
|
|
167
|
+
|
|
168
|
+
theirs = other.closure
|
|
169
|
+
return theirs if theirs.is_a?(Pin::Namespace) && !theirs.generics.empty?
|
|
170
|
+
|
|
171
|
+
chosen
|
|
162
172
|
end
|
|
163
173
|
|
|
164
174
|
# @param other [self]
|
|
@@ -435,6 +445,7 @@ module Solargraph
|
|
|
435
445
|
# @param context_type [ComplexType] The receiver type
|
|
436
446
|
# @return [self]
|
|
437
447
|
def resolve_generics definitions, context_type
|
|
448
|
+
definitions = declaring_definitions(definitions)
|
|
438
449
|
transform_types { |t| t&.resolve_generics(definitions, context_type) }
|
|
439
450
|
end
|
|
440
451
|
|
|
@@ -731,6 +742,19 @@ module Solargraph
|
|
|
731
742
|
|
|
732
743
|
private
|
|
733
744
|
|
|
745
|
+
# Declarations of a reopened generic may spell its parameters
|
|
746
|
+
# differently, so bind by position against this pin's own one.
|
|
747
|
+
#
|
|
748
|
+
# @param definitions [Pin::Namespace, nil]
|
|
749
|
+
# @return [Pin::Namespace, nil]
|
|
750
|
+
def declaring_definitions definitions
|
|
751
|
+
own = closure
|
|
752
|
+
return definitions unless definitions.is_a?(Pin::Namespace) && own.is_a?(Pin::Namespace)
|
|
753
|
+
return definitions unless own.path == definitions.path && !own.generics.empty?
|
|
754
|
+
|
|
755
|
+
own
|
|
756
|
+
end
|
|
757
|
+
|
|
734
758
|
# @return [void]
|
|
735
759
|
def parse_comments
|
|
736
760
|
# HACK: Avoid a NoMethodError on nil with empty overload tags
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'rbs'
|
|
4
|
+
|
|
3
5
|
module Solargraph
|
|
4
6
|
module Pin
|
|
5
7
|
class BaseVariable < Base
|
|
@@ -14,6 +16,9 @@ module Solargraph
|
|
|
14
16
|
# @return [Range, nil]
|
|
15
17
|
attr_reader :presence
|
|
16
18
|
|
|
19
|
+
# @return [String, nil]
|
|
20
|
+
attr_reader :type_assertion
|
|
21
|
+
|
|
17
22
|
# @param return_type [ComplexType, nil]
|
|
18
23
|
# @param assignment [Parser::AST::Node, nil] First assignment
|
|
19
24
|
# that was made to this variable
|
|
@@ -45,12 +50,16 @@ module Solargraph
|
|
|
45
50
|
# @see https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types
|
|
46
51
|
# @see https://en.wikipedia.org/wiki/Intersection_type#TypeScript_example
|
|
47
52
|
# @param presence [Range, nil]
|
|
53
|
+
# @param type_assertion [String, nil] RBS type from a trailing
|
|
54
|
+
# rbs-inline `#: TYPE` comment on the assignment
|
|
48
55
|
# @param [Hash{Symbol => Object}] splat
|
|
49
56
|
def initialize assignment: nil, assignments: [], mass_assignment: nil,
|
|
50
57
|
presence: nil, return_type: nil,
|
|
51
58
|
intersection_return_type: nil, exclude_return_type: nil,
|
|
59
|
+
type_assertion: nil,
|
|
52
60
|
**splat
|
|
53
61
|
super(**splat)
|
|
62
|
+
@type_assertion = type_assertion
|
|
54
63
|
@assignments = (assignment.nil? ? [] : [assignment]) + assignments
|
|
55
64
|
# @type [nil, ::Array(Parser::AST::Node, Integer)]
|
|
56
65
|
@mass_assignment = mass_assignment
|
|
@@ -95,7 +104,8 @@ module Solargraph
|
|
|
95
104
|
return_type: combine_return_type(other),
|
|
96
105
|
intersection_return_type: combine_types(other, :intersection_return_type),
|
|
97
106
|
exclude_return_type: combine_types(other, :exclude_return_type),
|
|
98
|
-
presence: combine_presence(other)
|
|
107
|
+
presence: combine_presence(other),
|
|
108
|
+
type_assertion: choose(other, :type_assertion)
|
|
99
109
|
})
|
|
100
110
|
super(other, new_attrs)
|
|
101
111
|
end
|
|
@@ -170,6 +180,9 @@ module Solargraph
|
|
|
170
180
|
end
|
|
171
181
|
end
|
|
172
182
|
types
|
|
183
|
+
rescue FileNotFoundError
|
|
184
|
+
# @todo Necessary for pins from source maps that are not part of the workspace
|
|
185
|
+
[ComplexType::UNDEFINED]
|
|
173
186
|
end
|
|
174
187
|
|
|
175
188
|
# @param api_map [ApiMap]
|
|
@@ -364,12 +377,29 @@ module Solargraph
|
|
|
364
377
|
:instance
|
|
365
378
|
end
|
|
366
379
|
|
|
380
|
+
# An rbs-inline type assertion takes precedence over a @type tag,
|
|
381
|
+
# as inline RBS method signatures do over YARD tags.
|
|
382
|
+
#
|
|
367
383
|
# @return [ComplexType, nil]
|
|
368
384
|
def generate_complex_type
|
|
385
|
+
asserted = type_from_assertion
|
|
386
|
+
return asserted unless asserted.nil?
|
|
369
387
|
tag = docstring.tag(:type)
|
|
370
388
|
return ComplexType.try_parse(*tag.types) unless tag.nil? || tag.types.nil? || tag.types.empty?
|
|
371
389
|
nil
|
|
372
390
|
end
|
|
391
|
+
|
|
392
|
+
# @return [ComplexType, nil]
|
|
393
|
+
def type_from_assertion
|
|
394
|
+
assertion = type_assertion
|
|
395
|
+
return nil if assertion.nil? || assertion.empty?
|
|
396
|
+
@type_from_assertion ||= begin
|
|
397
|
+
rbs_type = RBS::Parser.parse_type(assertion, require_eof: true)
|
|
398
|
+
RbsTranslator.to_complex_type(rbs_type) unless rbs_type.nil?
|
|
399
|
+
rescue RBS::ParsingError
|
|
400
|
+
nil
|
|
401
|
+
end
|
|
402
|
+
end
|
|
373
403
|
end
|
|
374
404
|
end
|
|
375
405
|
end
|
|
@@ -14,12 +14,15 @@ module Solargraph
|
|
|
14
14
|
# @param block [Signature, nil]
|
|
15
15
|
# @param return_type [ComplexType, nil]
|
|
16
16
|
# @param parameters [::Array<Pin::Parameter>]
|
|
17
|
+
# @param block_required [Boolean] Whether callers must pass a block, per
|
|
18
|
+
# an RBS non-optional block (`{ ... }` rather than `?{ ... }`).
|
|
17
19
|
# @param [Hash{Symbol => Object}] splat
|
|
18
|
-
def initialize block: nil, return_type: nil, parameters: [], **splat
|
|
20
|
+
def initialize block: nil, return_type: nil, parameters: [], block_required: false, **splat
|
|
19
21
|
super(**splat)
|
|
20
22
|
@block = block
|
|
21
23
|
@return_type = return_type
|
|
22
24
|
@parameters = parameters
|
|
25
|
+
@block_required = block_required
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
def reset_generated!
|
|
@@ -55,6 +58,7 @@ module Solargraph
|
|
|
55
58
|
def combine_with other, attrs = {}
|
|
56
59
|
new_attrs = {
|
|
57
60
|
block: combine_blocks(other),
|
|
61
|
+
block_required: block_required? || other.block_required?,
|
|
58
62
|
return_type: combine_return_type(other)
|
|
59
63
|
}.merge(attrs)
|
|
60
64
|
new_attrs[:parameters] = choose_parameters(other).clone.freeze unless new_attrs.key?(:parameters)
|
|
@@ -241,7 +245,7 @@ module Solargraph
|
|
|
241
245
|
argcount = arguments.length
|
|
242
246
|
parcount = mandatory_positional_param_count
|
|
243
247
|
parcount -= 1 if !parameters.empty? && parameters.last.block?
|
|
244
|
-
return false if block? && !with_block
|
|
248
|
+
return false if block? && block_required? && !with_block
|
|
245
249
|
# @todo this and its caller should be changed so that this can
|
|
246
250
|
# look at the kwargs provided and check names against what
|
|
247
251
|
# we acccept
|
|
@@ -267,6 +271,11 @@ module Solargraph
|
|
|
267
271
|
!!@block
|
|
268
272
|
end
|
|
269
273
|
|
|
274
|
+
# @return [Boolean]
|
|
275
|
+
def block_required?
|
|
276
|
+
!!@block_required
|
|
277
|
+
end
|
|
278
|
+
|
|
270
279
|
protected
|
|
271
280
|
|
|
272
281
|
attr_writer :block
|
|
@@ -6,6 +6,23 @@ module Solargraph
|
|
|
6
6
|
# @return [::Symbol] :class or :instance
|
|
7
7
|
attr_reader :scope
|
|
8
8
|
|
|
9
|
+
# Override the pin's scope.
|
|
10
|
+
#
|
|
11
|
+
# Scope is normally determined by the syntax that declared the pin, but
|
|
12
|
+
# YARD's `@!scope` directive can change it after the fact. Any values
|
|
13
|
+
# derived from the scope, such as the pin's path and context, are
|
|
14
|
+
# recalculated.
|
|
15
|
+
#
|
|
16
|
+
# @param scope [::Symbol] :class or :instance
|
|
17
|
+
# @return [void]
|
|
18
|
+
def scope= scope
|
|
19
|
+
return if @scope == scope
|
|
20
|
+
|
|
21
|
+
@scope = scope
|
|
22
|
+
# remove cached values generated from scope
|
|
23
|
+
reset_generated!
|
|
24
|
+
end
|
|
25
|
+
|
|
9
26
|
# @param scope [::Symbol] :class or :instance
|
|
10
27
|
# @param generics [::Array<Pin::String>, nil]
|
|
11
28
|
# @param generic_defaults [Hash{String => ComplexType}]
|
|
@@ -5,6 +5,11 @@ module Solargraph
|
|
|
5
5
|
# A DelegatedMethod is a more complicated version of a MethodAlias that
|
|
6
6
|
# allows aliasing a method from a different closure (class/module etc).
|
|
7
7
|
class DelegatedMethod < Pin::Method
|
|
8
|
+
# @return [Boolean]
|
|
9
|
+
def body?
|
|
10
|
+
false
|
|
11
|
+
end
|
|
12
|
+
|
|
8
13
|
# A DelegatedMethod can be constructed with either a :resolved_method
|
|
9
14
|
# pin, or a :receiver_chain. When a :receiver_chain is supplied, it
|
|
10
15
|
# will be used to *dynamically* resolve a receiver type within the
|
|
@@ -1,16 +1,36 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
module Pin
|
|
5
|
-
# DuckMethod pins are used to add completion items for type tags that
|
|
6
|
-
# use duck typing, e.g., `@param file [#read]`.
|
|
7
|
-
#
|
|
8
|
-
class DuckMethod < Pin::Method
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module Pin
|
|
5
|
+
# DuckMethod pins are used to add completion items for type tags that
|
|
6
|
+
# use duck typing, e.g., `@param file [#read]`.
|
|
7
|
+
#
|
|
8
|
+
class DuckMethod < Pin::Method
|
|
9
|
+
# A duck-type tag has no syntax for arguments, so the default empty
|
|
10
|
+
# #parameters would synthesize a zero-arg signature no real call matches.
|
|
11
|
+
#
|
|
12
|
+
# @param splat [Hash{Symbol => Object}]
|
|
13
|
+
def initialize **splat
|
|
14
|
+
super(parameters: accepts_any_arguments, **splat)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @return [::Array<Pin::Parameter>]
|
|
18
|
+
def accepts_any_arguments
|
|
19
|
+
[
|
|
20
|
+
Pin::Parameter.new(decl: :restarg, name: 'args', closure: self, source: :api_map),
|
|
21
|
+
Pin::Parameter.new(decl: :kwrestarg, name: 'kwargs', closure: self, source: :api_map)
|
|
22
|
+
]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# A synthetic pin sits in no ancestor chain and has no closure. Letting
|
|
26
|
+
# the inherited walk find a type sends #typify on to `closure.gates`,
|
|
27
|
+
# which raises.
|
|
28
|
+
#
|
|
29
|
+
# @param _api_map [ApiMap]
|
|
30
|
+
# @return [Array<Pin::Method>]
|
|
31
|
+
def rest_of_stack _api_map
|
|
32
|
+
[]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module Pin
|
|
5
|
+
# A method parameter with a literal value used in a factory method.
|
|
6
|
+
#
|
|
7
|
+
# @example
|
|
8
|
+
# RSpec.shared_examples 'some examples'
|
|
9
|
+
#
|
|
10
|
+
# FactoryParameter.new(
|
|
11
|
+
# method_name: 'shared_examples',
|
|
12
|
+
# method_namespace: 'RSpec',
|
|
13
|
+
# method_scope: :class,
|
|
14
|
+
# param_name: 'name',
|
|
15
|
+
# value: 'some examples',
|
|
16
|
+
# decl: :arg,
|
|
17
|
+
# return_type: 'void'
|
|
18
|
+
# )
|
|
19
|
+
class FactoryParameter < Base
|
|
20
|
+
# @return [String]
|
|
21
|
+
attr_reader :method_name
|
|
22
|
+
# @return [String]
|
|
23
|
+
attr_reader :method_namespace
|
|
24
|
+
# @return [Symbol] :class or :instance
|
|
25
|
+
attr_reader :method_scope
|
|
26
|
+
# @return [String, nil]
|
|
27
|
+
attr_reader :param_name
|
|
28
|
+
# @return [::String, ::Symbol] The literal value
|
|
29
|
+
attr_reader :value
|
|
30
|
+
# @return [::Symbol] :arg, :optarg, :kwarg, :kwoptarg, :restarg, :kwrestarg, :block, :blockarg
|
|
31
|
+
attr_reader :decl
|
|
32
|
+
# @return [Location, nil]
|
|
33
|
+
attr_reader :location
|
|
34
|
+
|
|
35
|
+
# @param method_name [String] The name of the method that this parameter belongs to
|
|
36
|
+
# @param method_namespace [String] The class of the method that this parameter belongs to
|
|
37
|
+
# @param method_scope [Symbol] The scope of the method, either :class or :instance
|
|
38
|
+
# @param param_name [String, nil] The name of the parameter
|
|
39
|
+
# @param value [String, Symbol] The value of the parameter
|
|
40
|
+
# @param decl [::Symbol] :arg, :kwarg
|
|
41
|
+
# @param location [Location, nil] The location of the parameter in the source code
|
|
42
|
+
# @param return_type [String, nil] The return type of the method that this parameter belongs to
|
|
43
|
+
def initialize method_name:,
|
|
44
|
+
method_namespace:,
|
|
45
|
+
method_scope:,
|
|
46
|
+
param_name:,
|
|
47
|
+
value:,
|
|
48
|
+
return_type:,
|
|
49
|
+
decl: :arg,
|
|
50
|
+
location: nil
|
|
51
|
+
super(location: location)
|
|
52
|
+
@method_name = method_name
|
|
53
|
+
@method_namespace = method_namespace
|
|
54
|
+
@method_scope = method_scope
|
|
55
|
+
@param_name = param_name
|
|
56
|
+
@value = value
|
|
57
|
+
@decl = decl
|
|
58
|
+
@return_type = return_type
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def name
|
|
62
|
+
param_name
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def text_documentation
|
|
66
|
+
"#{method_path}(#{param_name}) = #{value.inspect}"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @return [String]
|
|
70
|
+
def method_path
|
|
71
|
+
# @sg-ignore false failure on method_scope "Wrong argument type for Solargraph::Pin::Base#==: other expected
|
|
72
|
+
# Solargraph::Pin::Base, received :instance"
|
|
73
|
+
@method_path ||= "#{method_namespace}#{method_scope == :instance ? '#' : '.'}#{method_name}"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
def inner_desc
|
|
79
|
+
"method_path=#{method_path}, value=#{value.inspect}, decl=#{decl.inspect}, " \
|
|
80
|
+
"return_type=#{return_type&.to_s || 'nil'}"
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -33,6 +33,51 @@ module Solargraph
|
|
|
33
33
|
def nearly? other
|
|
34
34
|
super && binder == other.binder
|
|
35
35
|
end
|
|
36
|
+
|
|
37
|
+
# Same-file requirement only applies when +presence+ is set; an
|
|
38
|
+
# unnarrowed ivar has none and can be assigned and read in
|
|
39
|
+
# different files (e.g. ancestor class's method vs. descendant's).
|
|
40
|
+
#
|
|
41
|
+
# @param other_closure [Pin::Closure]
|
|
42
|
+
# @param other_loc [Location]
|
|
43
|
+
def visible_at? other_closure, other_loc
|
|
44
|
+
return false if presence && location&.filename != other_loc.filename
|
|
45
|
+
# @sg-ignore flow sensitive typing needs to handle attrs
|
|
46
|
+
return false if presence && !presence.include?(other_loc.range.start)
|
|
47
|
+
|
|
48
|
+
visible_in_closure?(other_closure)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
# Unlike BaseVariable, doesn't stop at a lexically-mismatched
|
|
54
|
+
# Namespace pin: #get_instance_variable_pins already restricts
|
|
55
|
+
# candidates to the reading namespace and its ancestors, so
|
|
56
|
+
# reaching one here means visible via inheritance.
|
|
57
|
+
#
|
|
58
|
+
# @param viewing_closure [Pin::Closure]
|
|
59
|
+
# @return [Boolean]
|
|
60
|
+
def visible_in_closure? viewing_closure
|
|
61
|
+
return false if closure.nil?
|
|
62
|
+
|
|
63
|
+
# top-level ivars aren't visible from within a method
|
|
64
|
+
# @sg-ignore Need to add nil check here
|
|
65
|
+
return false if viewing_closure.is_a?(Pin::Method) && closure.context.tags == 'Class<>'
|
|
66
|
+
|
|
67
|
+
# @sg-ignore Need to add nil check here
|
|
68
|
+
return true if viewing_closure.binder.namespace == closure.binder.namespace
|
|
69
|
+
|
|
70
|
+
# @sg-ignore Need to add nil check here
|
|
71
|
+
return true if viewing_closure.return_type == closure.context
|
|
72
|
+
|
|
73
|
+
return true if viewing_closure.is_a?(Pin::Namespace)
|
|
74
|
+
|
|
75
|
+
parent_of_viewing_closure = viewing_closure.closure
|
|
76
|
+
|
|
77
|
+
return false if parent_of_viewing_closure.nil?
|
|
78
|
+
|
|
79
|
+
visible_in_closure?(parent_of_viewing_closure)
|
|
80
|
+
end
|
|
36
81
|
end
|
|
37
82
|
end
|
|
38
83
|
end
|