solargraph 0.28.3 → 0.29.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/lib/solargraph/api_map/store.rb +13 -0
- data/lib/solargraph/api_map.rb +43 -10
- data/lib/solargraph/bundle.rb +3 -0
- data/lib/solargraph/complex_type.rb +5 -4
- data/lib/solargraph/core_fills.rb +3 -2
- data/lib/solargraph/language_server/host.rb +0 -1
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +0 -3
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +4 -3
- data/lib/solargraph/language_server/message/extended/document_gems.rb +7 -0
- data/lib/solargraph/language_server/transport/socket.rb +7 -1
- data/lib/solargraph/library.rb +1 -1
- data/lib/solargraph/page.rb +3 -6
- data/lib/solargraph/pin/base.rb +8 -3
- data/lib/solargraph/pin/base_variable.rb +1 -1
- data/lib/solargraph/pin/block_parameter.rb +5 -0
- data/lib/solargraph/pin/conversions.rb +1 -1
- data/lib/solargraph/pin/documenting.rb +30 -7
- data/lib/solargraph/pin/method.rb +59 -1
- data/lib/solargraph/pin/method_alias.rb +19 -0
- data/lib/solargraph/pin/yard_pin/method.rb +2 -2
- data/lib/solargraph/pin.rb +1 -1
- data/lib/solargraph/source/chain/call.rb +39 -20
- data/lib/solargraph/source/node_chainer.rb +1 -1
- data/lib/solargraph/source/node_methods.rb +81 -0
- data/lib/solargraph/source.rb +63 -1
- data/lib/solargraph/source_map/clip.rb +1 -1
- data/lib/solargraph/source_map/mapper.rb +9 -421
- data/lib/solargraph/source_map/node_processor/alias_node.rb +21 -0
- data/lib/solargraph/source_map/node_processor/args_node.rb +28 -0
- data/lib/solargraph/source_map/node_processor/base.rb +68 -0
- data/lib/solargraph/source_map/node_processor/begin_node.rb +11 -0
- data/lib/solargraph/source_map/node_processor/block_node.rb +14 -0
- data/lib/solargraph/source_map/node_processor/casgn_node.rb +14 -0
- data/lib/solargraph/source_map/node_processor/cvasgn_node.rb +14 -0
- data/lib/solargraph/source_map/node_processor/def_node.rb +54 -0
- data/lib/solargraph/source_map/node_processor/defs_node.rb +21 -0
- data/lib/solargraph/source_map/node_processor/gvasgn_node.rb +12 -0
- data/lib/solargraph/source_map/node_processor/ivasgn_node.rb +18 -0
- data/lib/solargraph/source_map/node_processor/lvasgn_node.rb +16 -0
- data/lib/solargraph/source_map/node_processor/namespace_node.rb +26 -0
- data/lib/solargraph/source_map/node_processor/orasgn_node.rb +12 -0
- data/lib/solargraph/source_map/node_processor/sclass_node.rb +11 -0
- data/lib/solargraph/source_map/node_processor/send_node.rb +150 -0
- data/lib/solargraph/source_map/node_processor/sym_node.rb +11 -0
- data/lib/solargraph/source_map/node_processor.rb +75 -0
- data/lib/solargraph/source_map/region.rb +58 -0
- data/lib/solargraph/source_map.rb +15 -0
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace.rb +19 -4
- data/lib/solargraph/yard_map.rb +17 -10
- data/lib/yard-solargraph.rb +0 -2
- metadata +60 -55
- data/lib/solargraph/pin/helper.rb +0 -41
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c715438f197d1c368427a61e4b745993ce0cca12b3db96d647f922be67c39e90
|
|
4
|
+
data.tar.gz: 1b82249c56fdb3014c69ec43e12cdac30b9f029cffb8d09896c4e19da7e24a81
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d9b8ed3db0337ef27ff07e1bb28c6bdac6e37bee655333b8465366a0ed3bf01c614dca4dcbaed4ddb1f535abd32639bd53553b3ab044fcb0b4311aa73778d732
|
|
7
|
+
data.tar.gz: 83f8266b77ff13d9750a889f04bbda44b15c39d2a2dbe0dca975f5a5af1835d3d78ee06e806906b65d7fb66dba08a7d09756df0ecbc7e69a9bc13fab29340e47
|
|
@@ -109,6 +109,19 @@ module Solargraph
|
|
|
109
109
|
result
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
+
def named_macros
|
|
113
|
+
@named_macros ||= begin
|
|
114
|
+
result = {}
|
|
115
|
+
pins.each do |pin|
|
|
116
|
+
pin.macros.select{|m| m.tag.tag_name == 'macro'}.each do |macro|
|
|
117
|
+
next if macro.tag.name.nil? || macro.tag.name.empty?
|
|
118
|
+
result[macro.tag.name] = macro
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
result
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
112
125
|
private
|
|
113
126
|
|
|
114
127
|
# @param fqns [String]
|
data/lib/solargraph/api_map.rb
CHANGED
|
@@ -21,7 +21,6 @@ module Solargraph
|
|
|
21
21
|
attr_reader :unresolved_requires
|
|
22
22
|
|
|
23
23
|
# @param pins [Array<Solargraph::Pin::Base>]
|
|
24
|
-
# def initialize workspace = Solargraph::Workspace.new(nil)
|
|
25
24
|
def initialize pins: []
|
|
26
25
|
# @todo Extensions don't work yet
|
|
27
26
|
# require_extensions
|
|
@@ -40,9 +39,15 @@ module Solargraph
|
|
|
40
39
|
@store = Store.new(pins + YardMap.new.pins)
|
|
41
40
|
@unresolved_requires = []
|
|
42
41
|
}
|
|
42
|
+
resolved = resolve_method_aliases
|
|
43
|
+
unless resolved.nil?
|
|
44
|
+
@mutex.synchronize { @store = Store.new(resolved) }
|
|
45
|
+
end
|
|
43
46
|
self
|
|
44
47
|
end
|
|
45
48
|
|
|
49
|
+
# Map a single source.
|
|
50
|
+
#
|
|
46
51
|
# @param source [Source]
|
|
47
52
|
# @return [self]
|
|
48
53
|
def map source
|
|
@@ -50,8 +55,11 @@ module Solargraph
|
|
|
50
55
|
self
|
|
51
56
|
end
|
|
52
57
|
|
|
53
|
-
|
|
54
|
-
|
|
58
|
+
def named_macro name
|
|
59
|
+
store.named_macros[name]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Catalog a bundle.
|
|
55
63
|
#
|
|
56
64
|
# @param bundle [Bundle]
|
|
57
65
|
# @return [self]
|
|
@@ -106,6 +114,10 @@ module Solargraph
|
|
|
106
114
|
@store = new_store
|
|
107
115
|
@unresolved_requires = yard_map.unresolved_requires
|
|
108
116
|
}
|
|
117
|
+
resolved = resolve_method_aliases
|
|
118
|
+
unless resolved.nil?
|
|
119
|
+
@mutex.synchronize { @store = Store.new(resolved) }
|
|
120
|
+
end
|
|
109
121
|
self
|
|
110
122
|
end
|
|
111
123
|
|
|
@@ -143,7 +155,7 @@ module Solargraph
|
|
|
143
155
|
store.pins
|
|
144
156
|
end
|
|
145
157
|
|
|
146
|
-
# An array of
|
|
158
|
+
# An array of pins based on Ruby keywords (`if`, `end`, etc.).
|
|
147
159
|
#
|
|
148
160
|
# @return [Array<Solargraph::Pin::Keyword>]
|
|
149
161
|
def self.keywords
|
|
@@ -305,7 +317,13 @@ module Solargraph
|
|
|
305
317
|
result.concat get_methods('Object')
|
|
306
318
|
else
|
|
307
319
|
unless type.nil? || type.name == 'void'
|
|
308
|
-
|
|
320
|
+
# @todo This method does not qualify the complex type's namespace
|
|
321
|
+
# because it can cause namespace conflicts, e.g., `Foo` vs.
|
|
322
|
+
# `Other::Foo`. It still takes a context argument because it
|
|
323
|
+
# uses context to determine whether protected and private methods
|
|
324
|
+
# are visible.
|
|
325
|
+
# namespace = qualify(type.namespace, context)
|
|
326
|
+
namespace = type.namespace
|
|
309
327
|
visibility = [:public]
|
|
310
328
|
if namespace == context || super_and_sub?(namespace, context)
|
|
311
329
|
visibility.push :protected
|
|
@@ -330,12 +348,13 @@ module Solargraph
|
|
|
330
348
|
# @param scope [Symbol] :instance or :class
|
|
331
349
|
# @return [Array<Solargraph::Pin::Base>]
|
|
332
350
|
def get_method_stack fqns, name, scope: :instance
|
|
333
|
-
# @todo This cache is still causing problems
|
|
334
|
-
|
|
335
|
-
|
|
351
|
+
# @todo This cache is still causing problems, but only when using
|
|
352
|
+
# Solargraph on Solargraph itself.
|
|
353
|
+
# cached = cache.get_method_stack(fqns, name, scope)
|
|
354
|
+
# return cached unless cached.nil?
|
|
336
355
|
result = get_methods(fqns, scope: scope, visibility: [:private, :protected, :public]).select{|p| p.name == name}
|
|
337
|
-
cache.set_method_stack(fqns, name, scope, result)
|
|
338
|
-
result
|
|
356
|
+
# cache.set_method_stack(fqns, name, scope, result)
|
|
357
|
+
# result
|
|
339
358
|
end
|
|
340
359
|
|
|
341
360
|
# Get an array of all suggestions that match the specified path.
|
|
@@ -621,5 +640,19 @@ module Solargraph
|
|
|
621
640
|
end
|
|
622
641
|
false
|
|
623
642
|
end
|
|
643
|
+
|
|
644
|
+
# @return [Array<Pin::Base>, nil]
|
|
645
|
+
def resolve_method_aliases
|
|
646
|
+
aliased = false
|
|
647
|
+
result = pins.map do |pin|
|
|
648
|
+
next pin unless pin.is_a?(Pin::MethodAlias)
|
|
649
|
+
origin = get_method_stack(pin.namespace, pin.original, scope: pin.scope).select{|pin| pin.class == Pin::Method}.first
|
|
650
|
+
next pin if origin.nil?
|
|
651
|
+
aliased = true
|
|
652
|
+
Pin::Method.new(pin.location, pin.namespace, pin.name, origin.comments, origin.scope, origin.visibility, origin.parameters)
|
|
653
|
+
end
|
|
654
|
+
return nil unless aliased
|
|
655
|
+
result
|
|
656
|
+
end
|
|
624
657
|
end
|
|
625
658
|
end
|
data/lib/solargraph/bundle.rb
CHANGED
|
@@ -28,6 +28,7 @@ module Solargraph
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def method_missing name, *args, &block
|
|
31
|
+
return if first.nil?
|
|
31
32
|
return first.send(name, *args, &block) if respond_to_missing?(name)
|
|
32
33
|
super
|
|
33
34
|
end
|
|
@@ -76,7 +77,7 @@ module Solargraph
|
|
|
76
77
|
elsif char == '<'
|
|
77
78
|
point_stack += 1
|
|
78
79
|
elsif char == '>'
|
|
79
|
-
if subtype_string.end_with?('=')
|
|
80
|
+
if subtype_string.end_with?('=') && curly_stack > 0
|
|
80
81
|
subtype_string += char
|
|
81
82
|
elsif base.end_with?('=')
|
|
82
83
|
raise ComplexTypeError, "Invalid hash thing" unless key_types.nil?
|
|
@@ -106,13 +107,13 @@ module Solargraph
|
|
|
106
107
|
subtype_string += char if paren_stack == 0
|
|
107
108
|
raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack < 0
|
|
108
109
|
next
|
|
109
|
-
elsif char == ','
|
|
110
|
+
elsif char == ',' && point_stack == 0 && curly_stack == 0 && paren_stack == 0
|
|
110
111
|
types.push ComplexType.new([UniqueType.new(base.strip, subtype_string.strip)])
|
|
111
112
|
base = ''
|
|
112
113
|
subtype_string = ''
|
|
113
114
|
next
|
|
114
115
|
end
|
|
115
|
-
if point_stack == 0
|
|
116
|
+
if point_stack == 0 && curly_stack == 0 && paren_stack == 0
|
|
116
117
|
base += char
|
|
117
118
|
else
|
|
118
119
|
subtype_string += char
|
|
@@ -120,7 +121,7 @@ module Solargraph
|
|
|
120
121
|
end
|
|
121
122
|
base.strip!
|
|
122
123
|
subtype_string.strip!
|
|
123
|
-
raise ComplexTypeError, "Unclosed subtype in #{type_string}" if point_stack != 0
|
|
124
|
+
raise ComplexTypeError, "Unclosed subtype in #{type_string}" if point_stack != 0 || curly_stack != 0 || paren_stack != 0
|
|
124
125
|
types.push ComplexType.new([UniqueType.new(base, subtype_string)])
|
|
125
126
|
end
|
|
126
127
|
unless key_types.nil?
|
|
@@ -20,13 +20,14 @@ module Solargraph
|
|
|
20
20
|
].freeze
|
|
21
21
|
|
|
22
22
|
METHODS_WITH_YIELDPARAM_SUBTYPES = %w[
|
|
23
|
-
Array#each Array#map Array#any? Array#all?
|
|
23
|
+
Array#each Array#map Array#any? Array#all? Array#index
|
|
24
24
|
Enumerable#each_entry Enumerable#map Enumerable#any? Enumerable#all?
|
|
25
25
|
Set#each
|
|
26
26
|
].freeze
|
|
27
27
|
|
|
28
28
|
CUSTOM_RETURN_TYPES = {
|
|
29
|
-
'String#split' => 'Array<String>'
|
|
29
|
+
'String#split' => 'Array<String>',
|
|
30
|
+
'String#lines' => 'Array<String>'
|
|
30
31
|
}.freeze
|
|
31
32
|
end
|
|
32
33
|
end
|
|
@@ -14,9 +14,9 @@ module Solargraph
|
|
|
14
14
|
fetcher = Gem::SpecFetcher.new
|
|
15
15
|
tuple = fetcher.search_for_dependency(Gem::Dependency.new('solargraph')).flatten.first
|
|
16
16
|
if tuple.nil?
|
|
17
|
-
msg =
|
|
17
|
+
msg = 'An error occurred checking the Solargraph gem version.'
|
|
18
18
|
STDERR.puts msg
|
|
19
|
-
host.show_message(msg, MessageTypes::ERROR)
|
|
19
|
+
host.show_message(msg, MessageTypes::ERROR)
|
|
20
20
|
else
|
|
21
21
|
available = Gem::Version.new(tuple.version)
|
|
22
22
|
current = Gem::Version.new(Solargraph::VERSION)
|
|
@@ -24,10 +24,11 @@ module Solargraph
|
|
|
24
24
|
host.show_message_request "Solagraph gem version #{available} is available.",
|
|
25
25
|
LanguageServer::MessageTypes::INFO,
|
|
26
26
|
['Update now'] do |result|
|
|
27
|
-
|
|
27
|
+
next unless result == 'Update now'
|
|
28
28
|
o, s = Open3.capture2("gem update solargraph")
|
|
29
29
|
if s == 0
|
|
30
30
|
host.show_message 'Successfully updated the Solargraph gem.', LanguageServer::MessageTypes::INFO
|
|
31
|
+
host.send_notification '$/solargraph/restart'
|
|
31
32
|
else
|
|
32
33
|
host.show_message 'An error occurred while updating the gem.', LanguageServer::MessageTypes::ERROR
|
|
33
34
|
end
|
|
@@ -14,6 +14,13 @@ module Solargraph
|
|
|
14
14
|
o, s = Open3.capture2(cmd)
|
|
15
15
|
if s != 0
|
|
16
16
|
host.show_message "An error occurred while building gem documentation.", LanguageServer::MessageTypes::ERROR
|
|
17
|
+
set_result({
|
|
18
|
+
status: 'err'
|
|
19
|
+
})
|
|
20
|
+
else
|
|
21
|
+
set_result({
|
|
22
|
+
status: 'ok'
|
|
23
|
+
})
|
|
17
24
|
end
|
|
18
25
|
end
|
|
19
26
|
end
|
|
@@ -33,7 +33,13 @@ module Solargraph
|
|
|
33
33
|
EventMachine.add_periodic_timer 0.1 do
|
|
34
34
|
tmp = @host.flush
|
|
35
35
|
send_data tmp unless tmp.empty?
|
|
36
|
-
|
|
36
|
+
if @host.stopped?
|
|
37
|
+
if @host.options['transport'] == 'external'
|
|
38
|
+
@host = Solargraph::LanguageServer::Host.new
|
|
39
|
+
else
|
|
40
|
+
EventMachine.stop
|
|
41
|
+
end
|
|
42
|
+
end
|
|
37
43
|
end
|
|
38
44
|
end
|
|
39
45
|
end
|
data/lib/solargraph/library.rb
CHANGED
|
@@ -174,7 +174,7 @@ module Solargraph
|
|
|
174
174
|
referenced.any?{|r| r == pin}
|
|
175
175
|
end
|
|
176
176
|
# HACK for language clients that exclude special characters from the start of variable names
|
|
177
|
-
if strip && match = cursor.word.match(/^[^a-z0-9_]+/)
|
|
177
|
+
if strip && match = cursor.word.match(/^[^a-z0-9_]+/i)
|
|
178
178
|
found.map! do |loc|
|
|
179
179
|
Solargraph::Location.new(loc.filename, Solargraph::Range.from_to(loc.range.start.line, loc.range.start.column + match[0].length, loc.range.ending.line, loc.range.ending.column))
|
|
180
180
|
end
|
data/lib/solargraph/page.rb
CHANGED
|
@@ -2,7 +2,7 @@ require 'ostruct'
|
|
|
2
2
|
require 'tilt'
|
|
3
3
|
require 'kramdown'
|
|
4
4
|
require 'htmlentities'
|
|
5
|
-
require '
|
|
5
|
+
require 'reverse_markdown'
|
|
6
6
|
|
|
7
7
|
module Solargraph
|
|
8
8
|
class Page
|
|
@@ -18,16 +18,13 @@ module Solargraph
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def htmlify text
|
|
21
|
-
helper = Solargraph::Pin::Helper.new
|
|
22
|
-
html = helper.html_markup_rdoc(text)
|
|
23
|
-
conv = ReverseMarkdown.convert(html, github_flavored: true)
|
|
24
21
|
Kramdown::Document.new(
|
|
25
|
-
|
|
22
|
+
text.to_s.lines.map{|l| l.gsub(/^ /, "\t")}.join,
|
|
26
23
|
input: 'GFM',
|
|
27
24
|
entity_output: :symbolic,
|
|
28
25
|
syntax_highlighter_opts: {
|
|
29
26
|
block: {
|
|
30
|
-
line_numbers: false
|
|
27
|
+
line_numbers: false
|
|
31
28
|
},
|
|
32
29
|
default_lang: :ruby
|
|
33
30
|
},
|
data/lib/solargraph/pin/base.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'reverse_markdown'
|
|
2
|
-
|
|
3
1
|
module Solargraph
|
|
4
2
|
module Pin
|
|
5
3
|
# The base class for map pins.
|
|
@@ -126,7 +124,7 @@ module Solargraph
|
|
|
126
124
|
|
|
127
125
|
# @return [Array<YARD::Tags::MacroDirective>]
|
|
128
126
|
def macros
|
|
129
|
-
@macros ||=
|
|
127
|
+
@macros ||= collect_macros
|
|
130
128
|
end
|
|
131
129
|
|
|
132
130
|
# Perform a quick check to see if this pin possibly includes YARD
|
|
@@ -222,6 +220,13 @@ module Solargraph
|
|
|
222
220
|
t1.name == t2.name &&
|
|
223
221
|
t1.types == t2.types
|
|
224
222
|
end
|
|
223
|
+
|
|
224
|
+
# @return [Array<YARD::Tags::Handlers::Directive>]
|
|
225
|
+
def collect_macros
|
|
226
|
+
return [] unless maybe_directives?
|
|
227
|
+
parse = YARD::Docstring.parser.parse(comments)
|
|
228
|
+
parse.directives.select{ |d| d.tag.tag_name == 'macro' }
|
|
229
|
+
end
|
|
225
230
|
end
|
|
226
231
|
end
|
|
227
232
|
end
|
|
@@ -65,7 +65,7 @@ module Solargraph
|
|
|
65
65
|
|
|
66
66
|
def generate_complex_type
|
|
67
67
|
tag = docstring.tag(:type)
|
|
68
|
-
return ComplexType.parse(*tag.types) unless tag.nil?
|
|
68
|
+
return ComplexType.parse(*tag.types) unless tag.nil? || tag.types.nil? || tag.types.empty?
|
|
69
69
|
return ComplexType.parse(@literal) unless @literal.nil?
|
|
70
70
|
ComplexType.new
|
|
71
71
|
end
|
|
@@ -56,9 +56,14 @@ module Solargraph
|
|
|
56
56
|
params.each do |p|
|
|
57
57
|
next unless p.name == name
|
|
58
58
|
found = p
|
|
59
|
+
break
|
|
60
|
+
end
|
|
61
|
+
if found.nil? and !index.nil?
|
|
62
|
+
found = params[index] if params[index] && (params[index].name.nil? || params[index].name.empty?)
|
|
59
63
|
end
|
|
60
64
|
@return_complex_type = ComplexType.parse(*found.types) unless found.nil? or found.types.nil?
|
|
61
65
|
end
|
|
66
|
+
super
|
|
62
67
|
@return_complex_type
|
|
63
68
|
end
|
|
64
69
|
|
|
@@ -70,8 +70,8 @@ module Solargraph
|
|
|
70
70
|
|
|
71
71
|
def generate_link
|
|
72
72
|
this_path = path || return_type.tag
|
|
73
|
+
return nil if this_path.nil? || this_path == 'undefined'
|
|
73
74
|
return this_path if comments.empty?
|
|
74
|
-
return nil if this_path.nil? or this_path == 'undefined'
|
|
75
75
|
"[#{this_path.gsub('_', '\\\\_')}](solargraph:/document?query=#{URI.encode(this_path)})"
|
|
76
76
|
end
|
|
77
77
|
end
|
|
@@ -1,18 +1,41 @@
|
|
|
1
|
+
require 'rdoc'
|
|
2
|
+
require 'reverse_markdown'
|
|
3
|
+
require 'kramdown'
|
|
4
|
+
|
|
1
5
|
module Solargraph
|
|
2
6
|
module Pin
|
|
7
|
+
# A module to add the Pin::Base#documentation method.
|
|
8
|
+
#
|
|
3
9
|
module Documenting
|
|
4
10
|
# @return [String]
|
|
5
11
|
def documentation
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
12
|
+
@documentation ||= begin
|
|
13
|
+
html = Kramdown::Document.new(
|
|
14
|
+
normalize_indentation(docstring.to_s),
|
|
15
|
+
input: 'GFM',
|
|
16
|
+
entity_output: :symbolic,
|
|
17
|
+
syntax_highlighter: nil
|
|
18
|
+
).to_html
|
|
19
|
+
ReverseMarkdown.convert(html, github_flavored: true)
|
|
9
20
|
end
|
|
10
|
-
@documentation
|
|
11
21
|
end
|
|
12
22
|
|
|
13
|
-
|
|
14
|
-
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
# @param text [String]
|
|
26
|
+
# @return [String]
|
|
27
|
+
def normalize_indentation text
|
|
28
|
+
text.lines.map { |l| remove_odd_spaces(l).gsub(/^ /, "\t") }.join
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @param line [String]
|
|
32
|
+
# @return [String]
|
|
33
|
+
def remove_odd_spaces line
|
|
34
|
+
return line unless line.start_with?(' ')
|
|
35
|
+
spaces = line.match(/^ +/)[0].length
|
|
36
|
+
return line unless spaces.odd?
|
|
37
|
+
line[1..-1]
|
|
15
38
|
end
|
|
16
39
|
end
|
|
17
40
|
end
|
|
18
|
-
end
|
|
41
|
+
end
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
module Solargraph
|
|
2
2
|
module Pin
|
|
3
3
|
class Method < Base
|
|
4
|
+
include Source::NodeMethods
|
|
5
|
+
|
|
4
6
|
# @return [Symbol] :instance or :class
|
|
5
7
|
attr_reader :scope
|
|
6
8
|
|
|
@@ -10,11 +12,15 @@ module Solargraph
|
|
|
10
12
|
# @return [Array<String>]
|
|
11
13
|
attr_reader :parameters
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
# @return [Parser::AST::Node]
|
|
16
|
+
attr_reader :node
|
|
17
|
+
|
|
18
|
+
def initialize location, namespace, name, comments, scope, visibility, args, node = nil
|
|
14
19
|
super(location, namespace, name, comments)
|
|
15
20
|
@scope = scope
|
|
16
21
|
@visibility = visibility
|
|
17
22
|
@parameters = args
|
|
23
|
+
@node = node
|
|
18
24
|
end
|
|
19
25
|
|
|
20
26
|
# @return [Array<String>]
|
|
@@ -81,6 +87,20 @@ module Solargraph
|
|
|
81
87
|
visibility == other.visibility
|
|
82
88
|
end
|
|
83
89
|
|
|
90
|
+
def infer api_map
|
|
91
|
+
decl = super
|
|
92
|
+
return decl unless decl.undefined?
|
|
93
|
+
type = see_reference(api_map)
|
|
94
|
+
return type unless type.nil?
|
|
95
|
+
infer_from_return_nodes(api_map)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def try_merge! pin
|
|
99
|
+
return false unless super
|
|
100
|
+
@node = pin.node
|
|
101
|
+
true
|
|
102
|
+
end
|
|
103
|
+
|
|
84
104
|
private
|
|
85
105
|
|
|
86
106
|
# @return [ComplexType]
|
|
@@ -98,6 +118,44 @@ module Solargraph
|
|
|
98
118
|
ComplexType::UNDEFINED
|
|
99
119
|
end
|
|
100
120
|
end
|
|
121
|
+
|
|
122
|
+
# @param api_map [ApiMap]
|
|
123
|
+
def infer_from_return_nodes api_map
|
|
124
|
+
return ComplexType::UNDEFINED if node.nil? ||
|
|
125
|
+
(node.type == :def && node.children[2].nil?) ||
|
|
126
|
+
(node.type == :defs && node.children[3].nil?)
|
|
127
|
+
result = []
|
|
128
|
+
nodes = node.type == :def ? returns_from(node.children[2]) : returns_from(node.children[3])
|
|
129
|
+
nodes.each do |n|
|
|
130
|
+
next if n.loc.nil?
|
|
131
|
+
clip = api_map.clip_at(location.filename, Solargraph::Position.new(n.loc.expression.last_line, n.loc.expression.last_column))
|
|
132
|
+
type = clip.infer
|
|
133
|
+
result.push type unless type.undefined?
|
|
134
|
+
end
|
|
135
|
+
return ComplexType::UNDEFINED if result.empty?
|
|
136
|
+
ComplexType.parse(*result.map(&:tag))
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# @param [ApiMap]
|
|
140
|
+
def see_reference api_map
|
|
141
|
+
docstring.ref_tags.each do |ref|
|
|
142
|
+
next unless ref.tag_name == 'return' && ref.owner
|
|
143
|
+
parts = ref.owner.to_s.split(/[\.#]/)
|
|
144
|
+
if parts.first.empty?
|
|
145
|
+
path = "#{namespace}#{ref.owner.to_s}"
|
|
146
|
+
else
|
|
147
|
+
fqns = api_map.qualify(parts.first, namespace)
|
|
148
|
+
return ComplexType::UNDEFINED if fqns.nil?
|
|
149
|
+
path = fqns + ref.owner.to_s[parts.first.length] + parts.last
|
|
150
|
+
end
|
|
151
|
+
pins = api_map.get_path_pins(path)
|
|
152
|
+
pins.each do |pin|
|
|
153
|
+
type = pin.infer(api_map)
|
|
154
|
+
return type unless type.undefined?
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
nil
|
|
158
|
+
end
|
|
101
159
|
end
|
|
102
160
|
end
|
|
103
161
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Solargraph
|
|
2
|
+
module Pin
|
|
3
|
+
# Use this class to track method aliases for later remapping. Common
|
|
4
|
+
# examples are aliases for superclass methods or methods from included
|
|
5
|
+
# modules.
|
|
6
|
+
#
|
|
7
|
+
class MethodAlias < Method
|
|
8
|
+
attr_reader :original
|
|
9
|
+
|
|
10
|
+
def initialize location, namespace, name, scope, original
|
|
11
|
+
# @todo Determine how to handle these parameters. Among other things,
|
|
12
|
+
# determine if the visibility is defined by the location of the
|
|
13
|
+
# alias call or the original method.
|
|
14
|
+
super(location, namespace, name, '', scope, :public, [])
|
|
15
|
+
@original = original
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -6,7 +6,7 @@ module Solargraph
|
|
|
6
6
|
|
|
7
7
|
def initialize code_object, location, name = nil, scope = nil, visibility = nil
|
|
8
8
|
comments = (code_object.docstring ? code_object.docstring.all : nil)
|
|
9
|
-
super(location, code_object.namespace.to_s, name || code_object.name.to_s, comments, scope || code_object.scope, visibility || code_object.visibility, get_parameters(code_object))
|
|
9
|
+
super(location, code_object.namespace.to_s, name || code_object.name.to_s, comments, scope || code_object.scope, visibility || code_object.visibility, get_parameters(code_object), nil)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def return_complex_type
|
|
@@ -28,7 +28,7 @@ module Solargraph
|
|
|
28
28
|
args.push p
|
|
29
29
|
end
|
|
30
30
|
args
|
|
31
|
-
end
|
|
31
|
+
end
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
end
|
data/lib/solargraph/pin.rb
CHANGED
|
@@ -2,10 +2,10 @@ module Solargraph
|
|
|
2
2
|
# The namespace for pins used in maps.
|
|
3
3
|
#
|
|
4
4
|
module Pin
|
|
5
|
-
autoload :Helper, 'solargraph/pin/helper'
|
|
6
5
|
autoload :Conversions, 'solargraph/pin/conversions'
|
|
7
6
|
autoload :Base, 'solargraph/pin/base'
|
|
8
7
|
autoload :Method, 'solargraph/pin/method'
|
|
8
|
+
autoload :MethodAlias, 'solargraph/pin/method_alias'
|
|
9
9
|
autoload :Attribute, 'solargraph/pin/attribute'
|
|
10
10
|
autoload :BaseVariable, 'solargraph/pin/base_variable'
|
|
11
11
|
autoload :InstanceVariable, 'solargraph/pin/instance_variable'
|
|
@@ -42,16 +42,18 @@ module Solargraph
|
|
|
42
42
|
def inferred_pins pins, api_map, context, locals
|
|
43
43
|
result = pins.map do |p|
|
|
44
44
|
if CoreFills::METHODS_RETURNING_SELF.include?(p.path)
|
|
45
|
-
next Solargraph::Pin::Method.new(p.location, p.namespace, p.name, "@return [#{context.tag}]", p.scope, p.visibility, p.parameters)
|
|
45
|
+
next Solargraph::Pin::Method.new(p.location, p.namespace, p.name, "@return [#{context.tag}]", p.scope, p.visibility, p.parameters, p.node)
|
|
46
46
|
end
|
|
47
47
|
if CoreFills::METHODS_RETURNING_SUBTYPES.include?(p.path) && !context.subtypes.empty?
|
|
48
|
-
next Solargraph::Pin::Method.new(p.location, p.namespace, p.name, "@return [#{context.subtypes.first.tag}]", p.scope, p.visibility, p.parameters)
|
|
48
|
+
next Solargraph::Pin::Method.new(p.location, p.namespace, p.name, "@return [#{context.subtypes.first.tag}]", p.scope, p.visibility, p.parameters, p.node)
|
|
49
|
+
end
|
|
50
|
+
if p.kind == Pin::METHOD && !p.macros.empty?
|
|
51
|
+
result = process_macro(p, api_map, context, locals)
|
|
52
|
+
next result unless result.return_type.undefined?
|
|
53
|
+
elsif !p.directives.empty?
|
|
54
|
+
result = process_directive(p, api_map, context, locals)
|
|
55
|
+
next result unless result.return_type.undefined?
|
|
49
56
|
end
|
|
50
|
-
# @todo Temporarily disabled macros
|
|
51
|
-
# if p.kind == Pin::METHOD && !p.macros.empty?
|
|
52
|
-
# result = process_macro(p, api_map, context, locals)
|
|
53
|
-
# next result unless result.return_type.undefined?
|
|
54
|
-
# end
|
|
55
57
|
next p if p.kind == Pin::METHOD || p.kind == Pin::ATTRIBUTE || p.kind == Pin::NAMESPACE
|
|
56
58
|
type = p.infer(api_map)
|
|
57
59
|
next p if p.return_complex_type == type
|
|
@@ -67,22 +69,39 @@ module Solargraph
|
|
|
67
69
|
# @param pin [Pin::Method]
|
|
68
70
|
# @param api_map [ApiMap]
|
|
69
71
|
# @param context [ComplexType]
|
|
72
|
+
# @return [Pin::Base]
|
|
70
73
|
def process_macro pin, api_map, context, locals
|
|
71
74
|
pin.macros.each do |macro|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
75
|
+
result = inner_process_macro(pin, macro, api_map, context, locals)
|
|
76
|
+
return result unless result.return_type.undefined?
|
|
77
|
+
end
|
|
78
|
+
Pin::ProxyType.new(nil, nil, nil, ComplexType::UNDEFINED)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def process_directive pin, api_map, context, locals
|
|
82
|
+
pin.directives.each do |dir|
|
|
83
|
+
macro = api_map.named_macro(dir.tag.name)
|
|
84
|
+
next if macro.nil?
|
|
85
|
+
result = inner_process_macro(pin, macro, api_map, context, locals)
|
|
86
|
+
return result unless result.return_type.undefined?
|
|
87
|
+
end
|
|
88
|
+
Pin::ProxyType.new(nil, nil, nil, ComplexType::UNDEFINED)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def inner_process_macro pin, macro, api_map, context, locals
|
|
92
|
+
vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals)) }
|
|
93
|
+
txt = macro.tag.text.clone
|
|
94
|
+
i = 1
|
|
95
|
+
vals.each do |v|
|
|
96
|
+
txt.gsub!(/\$#{i}/, v.context.namespace)
|
|
97
|
+
i += 1
|
|
98
|
+
end
|
|
99
|
+
docstring = YARD::Docstring.parser.parse(txt).to_docstring
|
|
100
|
+
tag = docstring.tag(:return)
|
|
101
|
+
unless tag.nil? || tag.types.nil?
|
|
102
|
+
return Pin::ProxyType.anonymous(ComplexType.parse(*tag.types))
|
|
84
103
|
end
|
|
85
|
-
|
|
104
|
+
Pin::ProxyType.new(nil, nil, nil, ComplexType::UNDEFINED)
|
|
86
105
|
end
|
|
87
106
|
end
|
|
88
107
|
end
|