solargraph 0.47.2 → 0.49.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/FUNDING.yml +1 -0
- data/.github/workflows/rspec.yml +1 -1
- data/CHANGELOG.md +20 -0
- data/LICENSE +1 -1
- data/README.md +8 -0
- data/SPONSORS.md +2 -4
- data/lib/solargraph/api_map/store.rb +13 -1
- data/lib/solargraph/api_map.rb +30 -12
- data/lib/solargraph/cache.rb +51 -0
- data/lib/solargraph/complex_type/type_methods.rb +10 -6
- data/lib/solargraph/complex_type/unique_type.rb +57 -0
- data/lib/solargraph/complex_type.rb +30 -1
- data/lib/solargraph/convention/rakefile.rb +17 -0
- data/lib/solargraph/convention.rb +2 -0
- data/lib/solargraph/diagnostics/rubocop.rb +17 -3
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +3 -1
- data/lib/solargraph/language_server/host.rb +22 -18
- data/lib/solargraph/language_server/message/extended/download_core.rb +1 -5
- data/lib/solargraph/language_server/message/initialize.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/formatting.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -6
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +10 -3
- data/lib/solargraph/library.rb +21 -20
- data/lib/solargraph/parser/legacy/node_processors/casgn_node.rb +12 -2
- data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +24 -3
- data/lib/solargraph/parser/rubyvm/class_methods.rb +6 -1
- data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +13 -2
- data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +20 -8
- data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +14 -3
- data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +14 -3
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +4 -2
- data/lib/solargraph/parser/rubyvm/node_wrapper.rb +47 -0
- data/lib/solargraph/pin/base.rb +5 -2
- data/lib/solargraph/pin/conversions.rb +2 -6
- data/lib/solargraph/pin/method.rb +100 -10
- data/lib/solargraph/pin/namespace.rb +4 -1
- data/lib/solargraph/pin/parameter.rb +8 -3
- data/lib/solargraph/pin/signature.rb +23 -0
- data/lib/solargraph/pin.rb +1 -0
- data/lib/solargraph/rbs_map/conversions.rb +394 -0
- data/lib/solargraph/rbs_map/core_fills.rb +61 -0
- data/lib/solargraph/rbs_map/core_map.rb +38 -0
- data/lib/solargraph/rbs_map/core_signs.rb +33 -0
- data/lib/solargraph/rbs_map/stdlib_map.rb +36 -0
- data/lib/solargraph/rbs_map.rb +73 -0
- data/lib/solargraph/shell.rb +38 -30
- data/lib/solargraph/source/chain/call.rb +34 -23
- data/lib/solargraph/source/chain.rb +21 -6
- data/lib/solargraph/source_map/clip.rb +5 -0
- data/lib/solargraph/source_map/mapper.rb +2 -0
- data/lib/solargraph/type_checker.rb +71 -65
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +2 -2
- data/lib/solargraph/workspace.rb +11 -14
- data/lib/solargraph/yard_map/mapper/to_method.rb +7 -4
- data/lib/solargraph/yard_map.rb +34 -193
- data/lib/solargraph.rb +2 -2
- data/solargraph.gemspec +8 -6
- metadata +43 -36
- data/lib/solargraph/compat.rb +0 -37
- data/lib/solargraph/yard_map/core_docs.rb +0 -170
- data/lib/solargraph/yard_map/core_fills.rb +0 -208
- data/lib/solargraph/yard_map/core_gen.rb +0 -76
- data/lib/solargraph/yard_map/rdoc_to_yard.rb +0 -140
- data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
- data/yardoc/2.2.2.tar.gz +0 -0
|
@@ -9,13 +9,8 @@ module Solargraph
|
|
|
9
9
|
line = params['position']['line']
|
|
10
10
|
col = params['position']['character']
|
|
11
11
|
suggestions = host.signatures_at(params['textDocument']['uri'], line, col)
|
|
12
|
-
info = []
|
|
13
|
-
suggestions.each do |pin|
|
|
14
|
-
info.concat pin.overloads.map(&:signature_help)
|
|
15
|
-
info.push pin.signature_help
|
|
16
|
-
end
|
|
17
12
|
set_result({
|
|
18
|
-
signatures:
|
|
13
|
+
signatures: suggestions.flat_map { |pin| pin.signature_help }
|
|
19
14
|
})
|
|
20
15
|
rescue FileNotFoundError => e
|
|
21
16
|
Logging.logger.warn "[#{e.class}] #{e.message}"
|
|
@@ -10,22 +10,29 @@ module Solargraph::LanguageServer::Message::Workspace
|
|
|
10
10
|
|
|
11
11
|
def process
|
|
12
12
|
need_catalog = false
|
|
13
|
+
to_create = []
|
|
14
|
+
to_delete = []
|
|
15
|
+
|
|
13
16
|
# @param change [Hash]
|
|
14
17
|
params['changes'].each do |change|
|
|
15
18
|
if change['type'] == CREATED
|
|
16
|
-
|
|
19
|
+
to_create << change['uri']
|
|
17
20
|
need_catalog = true
|
|
18
21
|
elsif change['type'] == CHANGED
|
|
19
22
|
next if host.open?(change['uri'])
|
|
20
|
-
|
|
23
|
+
to_create << change['uri']
|
|
21
24
|
need_catalog = true
|
|
22
25
|
elsif change['type'] == DELETED
|
|
23
|
-
|
|
26
|
+
to_delete << change['uri']
|
|
24
27
|
need_catalog = true
|
|
25
28
|
else
|
|
26
29
|
set_error Solargraph::LanguageServer::ErrorCodes::INVALID_PARAMS, "Unknown change type ##{change['type']} for #{uri_to_file(change['uri'])}"
|
|
27
30
|
end
|
|
28
31
|
end
|
|
32
|
+
|
|
33
|
+
host.create *to_create
|
|
34
|
+
host.delete *to_delete
|
|
35
|
+
|
|
29
36
|
# Force host to catalog libraries after file changes (see castwide/solargraph#139)
|
|
30
37
|
host.catalog if need_catalog
|
|
31
38
|
end
|
data/lib/solargraph/library.rb
CHANGED
|
@@ -106,36 +106,37 @@ module Solargraph
|
|
|
106
106
|
result
|
|
107
107
|
end
|
|
108
108
|
|
|
109
|
-
# Create
|
|
109
|
+
# Create file sources from files on disk. A file is ignored if it is
|
|
110
110
|
# neither open in the library nor included in the workspace.
|
|
111
111
|
#
|
|
112
|
-
# @param
|
|
113
|
-
# @return [Boolean] True if
|
|
114
|
-
def create_from_disk
|
|
112
|
+
# @param filenames [Array<String>]
|
|
113
|
+
# @return [Boolean] True if at least one file was added to the workspace.
|
|
114
|
+
def create_from_disk *filenames
|
|
115
115
|
result = false
|
|
116
116
|
mutex.synchronize do
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
workspace.merge(
|
|
121
|
-
maybe_map source
|
|
122
|
-
result = true
|
|
117
|
+
sources = filenames
|
|
118
|
+
.reject { |filename| File.directory?(filename) || !File.exist?(filename) }
|
|
119
|
+
.map { |filename| Solargraph::Source.load_string(File.read(filename), filename) }
|
|
120
|
+
result = workspace.merge(*sources)
|
|
121
|
+
sources.each { |source| maybe_map source }
|
|
123
122
|
end
|
|
124
123
|
result
|
|
125
124
|
end
|
|
126
125
|
|
|
127
|
-
# Delete
|
|
126
|
+
# Delete files from the library. Deleting a file will make it unavailable
|
|
128
127
|
# for checkout and optionally remove it from the workspace unless the
|
|
129
128
|
# workspace configuration determines that it should still exist.
|
|
130
129
|
#
|
|
131
|
-
# @param
|
|
132
|
-
# @return [Boolean] True if
|
|
133
|
-
def delete
|
|
134
|
-
detach filename
|
|
130
|
+
# @param filenames [Array<String>]
|
|
131
|
+
# @return [Boolean] True if any file was deleted
|
|
132
|
+
def delete *filenames
|
|
135
133
|
result = false
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
134
|
+
filenames.each do |filename|
|
|
135
|
+
detach filename
|
|
136
|
+
mutex.synchronize do
|
|
137
|
+
result ||= workspace.remove(filename)
|
|
138
|
+
@synchronized = !result if synchronized?
|
|
139
|
+
end
|
|
139
140
|
end
|
|
140
141
|
result
|
|
141
142
|
end
|
|
@@ -267,7 +268,7 @@ module Solargraph
|
|
|
267
268
|
next unless source_map_hash.key?(full)
|
|
268
269
|
return Location.new(full, Solargraph::Range.from_to(0, 0, 0, 0))
|
|
269
270
|
end
|
|
270
|
-
api_map.yard_map.require_reference(pin.name)
|
|
271
|
+
# api_map.yard_map.require_reference(pin.name)
|
|
271
272
|
rescue FileNotFoundError
|
|
272
273
|
nil
|
|
273
274
|
end
|
|
@@ -522,7 +523,7 @@ module Solargraph
|
|
|
522
523
|
return unless source
|
|
523
524
|
return unless @current == source || workspace.has_file?(source.filename)
|
|
524
525
|
if source_map_hash.key?(source.filename)
|
|
525
|
-
return if source_map_hash[source.filename].code == source.code &&
|
|
526
|
+
return if source_map_hash[source.filename].code == source.code &&
|
|
526
527
|
source_map_hash[source.filename].source.synchronized? &&
|
|
527
528
|
source.synchronized?
|
|
528
529
|
if source.synchronized?
|
|
@@ -8,16 +8,26 @@ module Solargraph
|
|
|
8
8
|
include Legacy::NodeMethods
|
|
9
9
|
|
|
10
10
|
def process
|
|
11
|
-
here = get_node_start_position(node)
|
|
12
11
|
pins.push Solargraph::Pin::Constant.new(
|
|
13
12
|
location: get_node_location(node),
|
|
14
13
|
closure: region.closure,
|
|
15
|
-
name:
|
|
14
|
+
name: const_name,
|
|
16
15
|
comments: comments_for(node),
|
|
17
16
|
assignment: node.children[2]
|
|
18
17
|
)
|
|
19
18
|
process_children
|
|
20
19
|
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
# @return [String]
|
|
24
|
+
def const_name
|
|
25
|
+
if node.children[0]
|
|
26
|
+
Parser::NodeMethods.unpack_name(node.children[0]) + "::#{node.children[1]}"
|
|
27
|
+
else
|
|
28
|
+
node.children[1].to_s
|
|
29
|
+
end
|
|
30
|
+
end
|
|
21
31
|
end
|
|
22
32
|
end
|
|
23
33
|
end
|
|
@@ -6,11 +6,32 @@ module Solargraph
|
|
|
6
6
|
module NodeProcessors
|
|
7
7
|
class SclassNode < Parser::NodeProcessor::Base
|
|
8
8
|
def process
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
sclass = node.children[0]
|
|
10
|
+
if sclass.is_a?(AST::Node) && sclass.type == :self
|
|
11
|
+
closure = region.closure
|
|
12
|
+
elsif sclass.is_a?(AST::Node) && sclass.type == :casgn
|
|
13
|
+
names = [region.closure.namespace, region.closure.name]
|
|
14
|
+
if sclass.children[0].nil? && names.last != sclass.children[1].to_s
|
|
15
|
+
names << sclass.children[1].to_s
|
|
16
|
+
else
|
|
17
|
+
names.concat [NodeMethods.unpack_name(sclass.children[0]), sclass.children[1].to_s]
|
|
18
|
+
end
|
|
19
|
+
name = names.reject(&:empty?).join('::')
|
|
20
|
+
closure = Solargraph::Pin::Namespace.new(name: name, location: region.closure.location)
|
|
21
|
+
elsif sclass.is_a?(AST::Node) && sclass.type == :const
|
|
22
|
+
names = [region.closure.namespace, region.closure.name]
|
|
23
|
+
also = NodeMethods.unpack_name(sclass)
|
|
24
|
+
if also != region.closure.name
|
|
25
|
+
names << also
|
|
26
|
+
end
|
|
27
|
+
name = names.reject(&:empty?).join('::')
|
|
28
|
+
closure = Solargraph::Pin::Namespace.new(name: name, location: region.closure.location)
|
|
29
|
+
else
|
|
30
|
+
return
|
|
31
|
+
end
|
|
11
32
|
pins.push Solargraph::Pin::Singleton.new(
|
|
12
33
|
location: get_node_location(node),
|
|
13
|
-
closure:
|
|
34
|
+
closure: closure
|
|
14
35
|
)
|
|
15
36
|
process_children region.update(visibility: :public, scope: :class, closure: pins.last)
|
|
16
37
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'solargraph/parser/rubyvm/node_processors'
|
|
2
|
+
require 'solargraph/parser/rubyvm/node_wrapper'
|
|
2
3
|
|
|
3
4
|
module Solargraph
|
|
4
5
|
module Parser
|
|
@@ -7,8 +8,10 @@ module Solargraph
|
|
|
7
8
|
# @param code [String]
|
|
8
9
|
# @param filename [String]
|
|
9
10
|
# @return [Array(Parser::AST::Node, Array<Parser::Source::Comment>)]
|
|
11
|
+
# @sg-ignore
|
|
10
12
|
def parse_with_comments code, filename = nil
|
|
11
13
|
node = RubyVM::AbstractSyntaxTree.parse(code).children[2]
|
|
14
|
+
node &&= RubyVM::AbstractSyntaxTree::NodeWrapper.from(node, code.lines)
|
|
12
15
|
comments = CommentRipper.new(code).parse
|
|
13
16
|
[node, comments]
|
|
14
17
|
rescue ::SyntaxError => e
|
|
@@ -19,8 +22,10 @@ module Solargraph
|
|
|
19
22
|
# @param filename [String, nil]
|
|
20
23
|
# @param line [Integer]
|
|
21
24
|
# @return [Parser::AST::Node]
|
|
25
|
+
# @sg-ignore
|
|
22
26
|
def parse code, filename = nil, line = 0
|
|
23
|
-
RubyVM::AbstractSyntaxTree.parse(code).children[2]
|
|
27
|
+
node = RubyVM::AbstractSyntaxTree.parse(code).children[2]
|
|
28
|
+
node and RubyVM::AbstractSyntaxTree::NodeWrapper.from(node, code.lines)
|
|
24
29
|
rescue ::SyntaxError => e
|
|
25
30
|
raise Parser::SyntaxError, e.message
|
|
26
31
|
end
|
|
@@ -9,12 +9,23 @@ module Solargraph
|
|
|
9
9
|
pins.push Solargraph::Pin::Constant.new(
|
|
10
10
|
location: get_node_location(node),
|
|
11
11
|
closure: region.closure,
|
|
12
|
-
name:
|
|
12
|
+
name: const_name,
|
|
13
13
|
comments: comments_for(node),
|
|
14
|
-
assignment: node.children[1]
|
|
14
|
+
assignment: node.children[2] || node.children[1]
|
|
15
15
|
)
|
|
16
16
|
process_children
|
|
17
17
|
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
# @return [String]
|
|
22
|
+
def const_name
|
|
23
|
+
if Parser.is_ast_node?(node.children[0])
|
|
24
|
+
Parser::NodeMethods.unpack_name(node.children[0])
|
|
25
|
+
else
|
|
26
|
+
node.children[0].to_s
|
|
27
|
+
end
|
|
28
|
+
end
|
|
18
29
|
end
|
|
19
30
|
end
|
|
20
31
|
end
|
|
@@ -6,6 +6,8 @@ module Solargraph
|
|
|
6
6
|
module NodeProcessors
|
|
7
7
|
class DefNode < Parser::NodeProcessor::Base
|
|
8
8
|
def process
|
|
9
|
+
anon_splat = node_has_anon_splat?
|
|
10
|
+
|
|
9
11
|
methpin = Solargraph::Pin::Method.new(
|
|
10
12
|
location: get_node_location(node),
|
|
11
13
|
closure: region.closure,
|
|
@@ -13,17 +15,19 @@ module Solargraph
|
|
|
13
15
|
comments: comments_for(node),
|
|
14
16
|
scope: region.scope || (region.closure.is_a?(Pin::Singleton) ? :class : :instance),
|
|
15
17
|
visibility: region.visibility,
|
|
16
|
-
node: node
|
|
18
|
+
node: node,
|
|
19
|
+
anon_splat: anon_splat
|
|
17
20
|
)
|
|
18
|
-
if methpin.name == 'initialize'
|
|
21
|
+
if methpin.name == 'initialize' && methpin.scope == :instance
|
|
19
22
|
pins.push Solargraph::Pin::Method.new(
|
|
20
23
|
location: methpin.location,
|
|
21
24
|
closure: methpin.closure,
|
|
22
25
|
name: 'new',
|
|
23
26
|
comments: methpin.comments,
|
|
24
27
|
scope: :class,
|
|
25
|
-
parameters: methpin.parameters
|
|
26
|
-
|
|
28
|
+
parameters: methpin.parameters,
|
|
29
|
+
anon_splat: anon_splat
|
|
30
|
+
)
|
|
27
31
|
# @todo Smelly instance variable access.
|
|
28
32
|
pins.last.instance_variable_set(:@return_type, ComplexType::SELF)
|
|
29
33
|
pins.push methpin
|
|
@@ -39,8 +43,9 @@ module Solargraph
|
|
|
39
43
|
scope: :class,
|
|
40
44
|
visibility: :public,
|
|
41
45
|
parameters: methpin.parameters,
|
|
42
|
-
node: methpin.node
|
|
43
|
-
|
|
46
|
+
node: methpin.node,
|
|
47
|
+
anon_splat: anon_splat
|
|
48
|
+
)
|
|
44
49
|
pins.push Solargraph::Pin::Method.new(
|
|
45
50
|
location: methpin.location,
|
|
46
51
|
closure: methpin.closure,
|
|
@@ -49,13 +54,20 @@ module Solargraph
|
|
|
49
54
|
scope: :instance,
|
|
50
55
|
visibility: :private,
|
|
51
56
|
parameters: methpin.parameters,
|
|
52
|
-
node: methpin.node
|
|
53
|
-
|
|
57
|
+
node: methpin.node,
|
|
58
|
+
anon_splat: anon_splat
|
|
59
|
+
)
|
|
54
60
|
else
|
|
55
61
|
pins.push methpin
|
|
56
62
|
end
|
|
57
63
|
process_children region.update(closure: methpin, scope: methpin.scope)
|
|
58
64
|
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def node_has_anon_splat?
|
|
69
|
+
node.children[1]&.children&.first == [nil]
|
|
70
|
+
end
|
|
59
71
|
end
|
|
60
72
|
end
|
|
61
73
|
end
|
|
@@ -11,6 +11,8 @@ module Solargraph
|
|
|
11
11
|
s_visi = region.visibility
|
|
12
12
|
s_visi = :public if region.scope != :class
|
|
13
13
|
loc = get_node_location(node)
|
|
14
|
+
anon_splat = node_has_anon_splat?
|
|
15
|
+
|
|
14
16
|
if node.children[0].is_a?(RubyVM::AbstractSyntaxTree::Node) && node.children[0].type == :SELF
|
|
15
17
|
closure = region.closure
|
|
16
18
|
else
|
|
@@ -26,7 +28,8 @@ module Solargraph
|
|
|
26
28
|
comments: comments_for(node),
|
|
27
29
|
scope: :class,
|
|
28
30
|
visibility: :public,
|
|
29
|
-
node: node
|
|
31
|
+
node: node,
|
|
32
|
+
anon_splat: anon_splat
|
|
30
33
|
)
|
|
31
34
|
pins.push Solargraph::Pin::Method.new(
|
|
32
35
|
location: loc,
|
|
@@ -35,7 +38,8 @@ module Solargraph
|
|
|
35
38
|
comments: comments_for(node),
|
|
36
39
|
scope: :instance,
|
|
37
40
|
visibility: :private,
|
|
38
|
-
node: node
|
|
41
|
+
node: node,
|
|
42
|
+
anon_splat: anon_splat
|
|
39
43
|
)
|
|
40
44
|
else
|
|
41
45
|
pins.push Solargraph::Pin::Method.new(
|
|
@@ -45,11 +49,18 @@ module Solargraph
|
|
|
45
49
|
comments: comments_for(node),
|
|
46
50
|
scope: :class,
|
|
47
51
|
visibility: s_visi,
|
|
48
|
-
node: node
|
|
52
|
+
node: node,
|
|
53
|
+
anon_splat: anon_splat
|
|
49
54
|
)
|
|
50
55
|
end
|
|
51
56
|
process_children region.update(closure: pins.last, scope: :class)
|
|
52
57
|
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def node_has_anon_splat?
|
|
62
|
+
node.children[2]&.children&.first == [nil]
|
|
63
|
+
end
|
|
53
64
|
end
|
|
54
65
|
end
|
|
55
66
|
end
|
|
@@ -6,11 +6,22 @@ module Solargraph
|
|
|
6
6
|
module NodeProcessors
|
|
7
7
|
class SclassNode < Parser::NodeProcessor::Base
|
|
8
8
|
def process
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
sclass = node.children[0]
|
|
10
|
+
if sclass.is_a?(RubyVM::AbstractSyntaxTree::Node) && sclass.type == :SELF
|
|
11
|
+
closure = region.closure
|
|
12
|
+
elsif sclass.is_a?(RubyVM::AbstractSyntaxTree::Node) && %i[CDECL CONST].include?(sclass.type)
|
|
13
|
+
names = [region.closure.namespace, region.closure.name]
|
|
14
|
+
if names.last != sclass.children[0].to_s
|
|
15
|
+
names << sclass.children[0].to_s
|
|
16
|
+
end
|
|
17
|
+
name = names.reject(&:empty?).join('::')
|
|
18
|
+
closure = Solargraph::Pin::Namespace.new(name: name, location: region.closure.location)
|
|
19
|
+
else
|
|
20
|
+
return
|
|
21
|
+
end
|
|
11
22
|
pins.push Solargraph::Pin::Singleton.new(
|
|
12
23
|
location: get_node_location(node),
|
|
13
|
-
closure:
|
|
24
|
+
closure: closure
|
|
14
25
|
)
|
|
15
26
|
process_children region.update(visibility: :public, scope: :class, closure: pins.last)
|
|
16
27
|
end
|
|
@@ -226,8 +226,10 @@ module Solargraph
|
|
|
226
226
|
|
|
227
227
|
# @return [void]
|
|
228
228
|
def process_private_constant
|
|
229
|
-
|
|
230
|
-
|
|
229
|
+
arr = node.children[1]
|
|
230
|
+
return unless Parser.is_ast_node?(arr) && [:ARRAY, :LIST].include?(arr.type)
|
|
231
|
+
|
|
232
|
+
arr.children.compact.each do |child|
|
|
231
233
|
if [:LIT, :STR].include?(child.type)
|
|
232
234
|
cn = child.children[0].to_s
|
|
233
235
|
ref = pins.select{|p| [Solargraph::Pin::Namespace, Solargraph::Pin::Constant].include?(p.class) && p.namespace == region.closure.full_context.namespace && p.name == cn}.first
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'delegate'
|
|
2
|
+
|
|
3
|
+
module RubyVM::AbstractSyntaxTree
|
|
4
|
+
# Wrapper for RubyVM::AbstractSyntaxTree::Node. for return character based column
|
|
5
|
+
class NodeWrapper < SimpleDelegator
|
|
6
|
+
attr_reader :code
|
|
7
|
+
# @param node [RubyVM::AbstractSyntaxTree::Node] wrapped node to return character based column
|
|
8
|
+
# @param code [Array<String>] source code lines for generated this node
|
|
9
|
+
def initialize(node, code)
|
|
10
|
+
@code = code
|
|
11
|
+
super(node)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.from(node, code)
|
|
15
|
+
return node unless node.is_a?(RubyVM::AbstractSyntaxTree::Node) and !node.kind_of?(SimpleDelegator)
|
|
16
|
+
|
|
17
|
+
new(node, code)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def is_a?(type)
|
|
21
|
+
__getobj__.is_a?(type) || super.is_a?(type)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def class
|
|
25
|
+
__getobj__.class
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def first_column
|
|
30
|
+
@first_column ||= begin
|
|
31
|
+
line = @code[__getobj__.first_lineno - 1] || ""
|
|
32
|
+
line.byteslice(0, __getobj__.first_column).length
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def last_column
|
|
37
|
+
@last_column ||= begin
|
|
38
|
+
line = @code[__getobj__.last_lineno - 1] || ""
|
|
39
|
+
line.byteslice(0, __getobj__.last_column).length
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def children
|
|
44
|
+
@children ||= __getobj__.children.map do |node| NodeWrapper.from(node, @code) end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/solargraph/pin/base.rb
CHANGED
|
@@ -21,9 +21,12 @@ module Solargraph
|
|
|
21
21
|
# @return [String]
|
|
22
22
|
attr_reader :path
|
|
23
23
|
|
|
24
|
-
# @
|
|
24
|
+
# @return [::Symbol]
|
|
25
|
+
attr_accessor :source
|
|
26
|
+
|
|
27
|
+
# @param location [Solargraph::Location, nil]
|
|
25
28
|
# @param kind [Integer]
|
|
26
|
-
# @param closure [Solargraph::Pin::Closure]
|
|
29
|
+
# @param closure [Solargraph::Pin::Closure, nil]
|
|
27
30
|
# @param name [String]
|
|
28
31
|
# @param comments [String]
|
|
29
32
|
def initialize location: nil, closure: nil, name: '', comments: ''
|
|
@@ -34,12 +34,9 @@ module Solargraph
|
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
# @return [Hash]
|
|
37
|
+
# @return [Array<Hash>]
|
|
38
38
|
def signature_help
|
|
39
|
-
|
|
40
|
-
label: name + '(' + parameters.map(&:full).join(', ') + ')',
|
|
41
|
-
documentation: documentation
|
|
42
|
-
}
|
|
39
|
+
[]
|
|
43
40
|
end
|
|
44
41
|
|
|
45
42
|
# @return [String]
|
|
@@ -47,7 +44,6 @@ module Solargraph
|
|
|
47
44
|
# This property is not cached in an instance variable because it can
|
|
48
45
|
# change when pins get proxied.
|
|
49
46
|
detail = String.new
|
|
50
|
-
detail += "(#{parameters.map(&:full).join(', ')}) " unless !is_a?(Pin::Method) || parameters.empty?
|
|
51
47
|
detail += "=#{probed? ? '~' : (proxied? ? '^' : '>')} #{return_type.to_s}" unless return_type.undefined?
|
|
52
48
|
detail.strip!
|
|
53
49
|
return nil if detail.empty?
|
|
@@ -18,13 +18,18 @@ module Solargraph
|
|
|
18
18
|
|
|
19
19
|
# @param visibility [::Symbol] :public, :protected, or :private
|
|
20
20
|
# @param explicit [Boolean]
|
|
21
|
-
|
|
21
|
+
# @param parameters [Array<Pin::Parameter>]
|
|
22
|
+
# @param node [Parser::AST::Node, RubyVM::AbstractSyntaxTree::Node]
|
|
23
|
+
# @param attribute [Boolean]
|
|
24
|
+
def initialize visibility: :public, explicit: true, parameters: [], node: nil, attribute: false, signatures: nil, anon_splat: false, **splat
|
|
22
25
|
super(**splat)
|
|
23
26
|
@visibility = visibility
|
|
24
27
|
@explicit = explicit
|
|
25
28
|
@parameters = parameters
|
|
26
29
|
@node = node
|
|
27
30
|
@attribute = attribute
|
|
31
|
+
@signatures = signatures
|
|
32
|
+
@anon_splat = anon_splat
|
|
28
33
|
end
|
|
29
34
|
|
|
30
35
|
# @return [Array<String>]
|
|
@@ -41,7 +46,45 @@ module Solargraph
|
|
|
41
46
|
end
|
|
42
47
|
|
|
43
48
|
def return_type
|
|
44
|
-
@return_type ||=
|
|
49
|
+
@return_type ||= ComplexType.try_parse(*signatures.map(&:return_type).map(&:to_s))
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @return [Array<Signature>]
|
|
53
|
+
def signatures
|
|
54
|
+
@signatures ||= begin
|
|
55
|
+
top_type = generate_complex_type
|
|
56
|
+
result = []
|
|
57
|
+
result.push Signature.new(parameters, top_type) if top_type.defined?
|
|
58
|
+
result.concat(overloads.map { |meth| Signature.new(meth.parameters, meth.return_type) })
|
|
59
|
+
result.push Signature.new(parameters, top_type) if result.empty?
|
|
60
|
+
result
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# @return [String]
|
|
65
|
+
def detail
|
|
66
|
+
# This property is not cached in an instance variable because it can
|
|
67
|
+
# change when pins get proxied.
|
|
68
|
+
detail = String.new
|
|
69
|
+
detail += if signatures.length > 1
|
|
70
|
+
"(*) "
|
|
71
|
+
else
|
|
72
|
+
"(#{signatures.first.parameters.map(&:full).join(', ')}) " unless signatures.first.parameters.empty?
|
|
73
|
+
end.to_s
|
|
74
|
+
detail += "=#{probed? ? '~' : (proxied? ? '^' : '>')} #{return_type.to_s}" unless return_type.undefined?
|
|
75
|
+
detail.strip!
|
|
76
|
+
return nil if detail.empty?
|
|
77
|
+
detail
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# @return [Array<Hash>]
|
|
81
|
+
def signature_help
|
|
82
|
+
@signature_help ||= signatures.map do |sig|
|
|
83
|
+
{
|
|
84
|
+
label: name + '(' + sig.parameters.map(&:full).join(', ') + ')',
|
|
85
|
+
documentation: documentation
|
|
86
|
+
}
|
|
87
|
+
end
|
|
45
88
|
end
|
|
46
89
|
|
|
47
90
|
def path
|
|
@@ -119,27 +162,60 @@ module Solargraph
|
|
|
119
162
|
# @return [Array<Pin::Method>]
|
|
120
163
|
def overloads
|
|
121
164
|
@overloads ||= docstring.tags(:overload).map do |tag|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
# args: tag.parameters.map(&:first),
|
|
126
|
-
parameters: tag.parameters.map do |src|
|
|
165
|
+
Pin::Signature.new(
|
|
166
|
+
tag.parameters.map do |src|
|
|
167
|
+
name, decl = parse_overload_param(src.first)
|
|
127
168
|
Pin::Parameter.new(
|
|
128
169
|
location: location,
|
|
129
170
|
closure: self,
|
|
130
171
|
comments: tag.docstring.all.to_s,
|
|
131
|
-
name:
|
|
172
|
+
name: name,
|
|
173
|
+
decl: decl,
|
|
132
174
|
presence: location ? location.range : nil,
|
|
133
|
-
|
|
175
|
+
return_type: param_type_from_name(tag, src.first)
|
|
134
176
|
)
|
|
135
177
|
end,
|
|
136
|
-
|
|
178
|
+
ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types))
|
|
137
179
|
)
|
|
138
180
|
end
|
|
181
|
+
@overloads
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def anon_splat?
|
|
185
|
+
@anon_splat
|
|
139
186
|
end
|
|
140
187
|
|
|
141
188
|
private
|
|
142
189
|
|
|
190
|
+
def select_decl name, asgn
|
|
191
|
+
if name.start_with?('**')
|
|
192
|
+
:kwrestarg
|
|
193
|
+
elsif name.start_with?('*')
|
|
194
|
+
:restarg
|
|
195
|
+
elsif name.start_with?('&')
|
|
196
|
+
:blockarg
|
|
197
|
+
elsif name.end_with?(':') && asgn
|
|
198
|
+
:kwoptarg
|
|
199
|
+
elsif name.end_with?(':')
|
|
200
|
+
:kwarg
|
|
201
|
+
elsif asgn
|
|
202
|
+
:optarg
|
|
203
|
+
else
|
|
204
|
+
:arg
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def clean_param name
|
|
209
|
+
name.gsub(/[*&:]/, '')
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# @param tag [YARD::Tags::OverloadTag]
|
|
213
|
+
def param_type_from_name(tag, name)
|
|
214
|
+
param = tag.tags(:param).select { |t| t.name == name }.first
|
|
215
|
+
return ComplexType::UNDEFINED unless param
|
|
216
|
+
ComplexType.try_parse(*param.types)
|
|
217
|
+
end
|
|
218
|
+
|
|
143
219
|
# @return [ComplexType]
|
|
144
220
|
def generate_complex_type
|
|
145
221
|
tags = docstring.tags(:return).map(&:types).flatten.reject(&:nil?)
|
|
@@ -240,6 +316,20 @@ module Solargraph
|
|
|
240
316
|
return ComplexType::UNDEFINED if types.empty?
|
|
241
317
|
ComplexType.try_parse(*types.map(&:tag).uniq)
|
|
242
318
|
end
|
|
319
|
+
|
|
320
|
+
# When YARD parses an overload tag, it includes rest modifiers in the parameters names.
|
|
321
|
+
#
|
|
322
|
+
# @param arg [String]
|
|
323
|
+
# @return [Array(String, Symbol)]
|
|
324
|
+
def parse_overload_param(name)
|
|
325
|
+
if name.start_with?('**')
|
|
326
|
+
[name[2..-1], :kwrestarg]
|
|
327
|
+
elsif name.start_with?('*')
|
|
328
|
+
[name[1..-1], :restarg]
|
|
329
|
+
else
|
|
330
|
+
[name, :arg]
|
|
331
|
+
end
|
|
332
|
+
end
|
|
243
333
|
end
|
|
244
334
|
end
|
|
245
335
|
end
|
|
@@ -9,10 +9,12 @@ module Solargraph
|
|
|
9
9
|
# @return [::Symbol] :class or :module
|
|
10
10
|
attr_reader :type
|
|
11
11
|
|
|
12
|
+
attr_reader :parameters
|
|
13
|
+
|
|
12
14
|
# @param type [::Symbol] :class or :module
|
|
13
15
|
# @param visibility [::Symbol] :public or :private
|
|
14
16
|
# @param gates [Array<String>]
|
|
15
|
-
def initialize type: :class, visibility: :public, gates: [''], **splat
|
|
17
|
+
def initialize type: :class, visibility: :public, gates: [''], parameters: [], **splat
|
|
16
18
|
# super(location, namespace, name, comments)
|
|
17
19
|
super(**splat)
|
|
18
20
|
@type = type
|
|
@@ -36,6 +38,7 @@ module Solargraph
|
|
|
36
38
|
@closure = Pin::Namespace.new(name: closure_name, gates: [parts.join('::')])
|
|
37
39
|
@context = nil
|
|
38
40
|
end
|
|
41
|
+
@parameters = parameters
|
|
39
42
|
end
|
|
40
43
|
|
|
41
44
|
def namespace
|