solargraph 0.23.4 → 0.23.5
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.rb +11 -6
- data/lib/solargraph/api_map.rb +3 -1
- data/lib/solargraph/api_map/probe.rb +33 -7
- data/lib/solargraph/diagnostics.rb +34 -6
- data/lib/solargraph/language_server/host.rb +18 -1
- data/lib/solargraph/language_server/message/text_document/hover.rb +5 -18
- data/lib/solargraph/library.rb +7 -1
- data/lib/solargraph/live_map.rb +5 -4
- data/lib/solargraph/pin/attribute.rb +4 -0
- data/lib/solargraph/pin/block_parameter.rb +4 -0
- data/lib/solargraph/pin/conversions.rb +12 -3
- data/lib/solargraph/pin/plugin/method.rb +0 -1
- data/lib/solargraph/pin/proxy_method.rb +1 -1
- data/lib/solargraph/pin/reference.rb +4 -4
- data/lib/solargraph/plugin/process.rb +6 -5
- data/lib/solargraph/shell.rb +1 -1
- data/lib/solargraph/source.rb +21 -9
- data/lib/solargraph/source/change.rb +4 -2
- data/lib/solargraph/source/fragment.rb +25 -1
- data/lib/solargraph/source/mapper.rb +0 -15
- data/lib/solargraph/source/updater.rb +2 -0
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace.rb +8 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c281911d4b36b81d86b88a11979ee08e9c974cd10cbe83e1d07a03cf3f52185
|
4
|
+
data.tar.gz: 65d1fe2602ac1ac9b9272aaf52a0a4772edd5897465b29d370ee6ebc15cedb44
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d1c5981b4b14c3651833ddc5589c8002ede7d7d690519ee70d8a8e82a59bbfaecdcd6576b0d6706b29d6d92bda3f1a5c990a23286114d81b84ec49b99ca9bb8e
|
7
|
+
data.tar.gz: 0c75eb3da1835a7cd35ee8a594554ec0e6638c4afbe471aa27f05c7233df0841b47d5e313fb53d319b56af6fc46fd1876756dc9b8ace48476ca4e9353c23dba1
|
data/lib/solargraph.rb
CHANGED
@@ -3,17 +3,22 @@ require 'rubygems/package'
|
|
3
3
|
require 'yard-solargraph'
|
4
4
|
|
5
5
|
module Solargraph
|
6
|
-
class InvalidOffsetError < RangeError;
|
7
|
-
class DiagnosticsError < RuntimeError;
|
8
|
-
class FileNotFoundError < RuntimeError;
|
6
|
+
class InvalidOffsetError < RangeError; end
|
7
|
+
class DiagnosticsError < RuntimeError; end
|
8
|
+
class FileNotFoundError < RuntimeError; end
|
9
9
|
class SourceNotAvailableError < StandardError; end
|
10
|
-
|
11
|
-
|
10
|
+
class WorkspaceTooLargeError < RuntimeError
|
11
|
+
# @return [Integer]
|
12
12
|
attr_reader :size
|
13
13
|
|
14
|
+
# @return [Integer]
|
15
|
+
attr_reader :max
|
16
|
+
|
14
17
|
# @param size [Integer] The number of files included in the workspace
|
15
|
-
|
18
|
+
# @param max [Integer] The maximum number of files allowed
|
19
|
+
def initialize size, max
|
16
20
|
@size = size
|
21
|
+
@max = max
|
17
22
|
end
|
18
23
|
end
|
19
24
|
|
data/lib/solargraph/api_map.rb
CHANGED
@@ -336,7 +336,8 @@ module Solargraph
|
|
336
336
|
# @param fragment [Solargraph::Source::Fragment]
|
337
337
|
# @return [Array<Solargraph::Pin::Base>]
|
338
338
|
def define fragment
|
339
|
-
return
|
339
|
+
return get_path_suggestions(fragment.namespace) if fragment.whole_signature == 'self'
|
340
|
+
return [] if fragment.string? or fragment.comment? or fragment.literal? or fragment.whole_signature == 'self'
|
340
341
|
if fragment.base_literal?
|
341
342
|
probe.infer_signature_pins fragment.whole_signature, Pin::ProxyMethod.new(fragment.base_literal), fragment.locals
|
342
343
|
else
|
@@ -526,6 +527,7 @@ module Solargraph
|
|
526
527
|
fqis = qualify(is, fqns)
|
527
528
|
result.concat inner_get_constants(fqis, [:public], skip) unless fqis.nil?
|
528
529
|
end
|
530
|
+
result.concat live_map.get_constants(fqns)
|
529
531
|
result
|
530
532
|
end
|
531
533
|
|
@@ -48,6 +48,7 @@ module Solargraph
|
|
48
48
|
def infer_signature_type signature, context_pin, locals
|
49
49
|
pins = infer_signature_pins(signature, context_pin, locals)
|
50
50
|
pins.each do |pin|
|
51
|
+
return pin.return_type unless pin.return_type.nil?
|
51
52
|
type = resolve_pin_type(pin, locals - [pin])
|
52
53
|
return qualify(type, pin.named_context) unless type.nil?
|
53
54
|
end
|
@@ -59,8 +60,9 @@ module Solargraph
|
|
59
60
|
# Word search is ALWAYS internal
|
60
61
|
def infer_word_pins word, context_pin, locals
|
61
62
|
return [] if word.empty?
|
63
|
+
return infer_self(context_pin) if word == 'self'
|
62
64
|
lvars = locals.select{|pin| pin.name == word}
|
63
|
-
return lvars unless lvars.empty?
|
65
|
+
return resolve_word_types(lvars, locals) unless lvars.empty?
|
64
66
|
return api_map.get_global_variable_pins.select{|pin| pin.name == word} if word.start_with?('$')
|
65
67
|
namespace, scope = extract_namespace_and_scope_from_pin(context_pin)
|
66
68
|
return api_map.pins.select{|pin| word_matches_context?(word, namespace, scope, pin)} if variable_name?(word)
|
@@ -75,7 +77,28 @@ module Solargraph
|
|
75
77
|
result.concat api_map.get_path_suggestions(word) if result.empty?
|
76
78
|
result.concat api_map.get_methods(namespace, scope: scope, visibility: [:public, :private, :protected]).select{|pin| pin.name == word} unless word.include?('::')
|
77
79
|
result.concat api_map.get_constants('', namespace).select{|pin| pin.name == word} if result.empty?
|
78
|
-
result
|
80
|
+
resolve_word_types(result, locals)
|
81
|
+
end
|
82
|
+
|
83
|
+
def resolve_word_types(pins, locals)
|
84
|
+
pins.each do |p|
|
85
|
+
next unless p.return_type.nil?
|
86
|
+
type = resolve_pin_type(p, locals)
|
87
|
+
# @todo Smelly instance variable access
|
88
|
+
p.instance_variable_set(:@return_type, type)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def infer_self context_pin
|
93
|
+
if context_pin.kind == Pin::METHOD
|
94
|
+
if context_pin.scope == :instance
|
95
|
+
return [Pin::ProxyMethod.new(context_pin.namespace)]
|
96
|
+
else
|
97
|
+
return api_map.get_path_suggestions(context_pin.namespace)
|
98
|
+
end
|
99
|
+
else
|
100
|
+
return api_map.get_path_suggestions(context_pin.path)
|
101
|
+
end
|
79
102
|
end
|
80
103
|
|
81
104
|
# Method name search is external by default
|
@@ -154,24 +177,27 @@ module Solargraph
|
|
154
177
|
def resolve_pin_type pin, locals
|
155
178
|
pin.return_type
|
156
179
|
return pin.return_type unless pin.return_type.nil?
|
157
|
-
return resolve_block_parameter(pin) if pin.kind == Pin::BLOCK_PARAMETER
|
180
|
+
return resolve_block_parameter(pin, locals) if pin.kind == Pin::BLOCK_PARAMETER
|
158
181
|
return resolve_variable(pin, locals) if pin.variable?
|
159
182
|
nil
|
160
183
|
end
|
161
184
|
|
162
|
-
def resolve_block_parameter pin
|
185
|
+
def resolve_block_parameter pin, locals
|
163
186
|
return pin.return_type unless pin.return_type.nil?
|
164
187
|
signature = pin.block.receiver
|
165
188
|
# @todo Not sure if assuming the first pin is good here
|
166
|
-
meth =
|
189
|
+
meth = infer_signature_pins(signature, pin.block, locals).first
|
167
190
|
return nil if meth.nil?
|
168
191
|
if (Solargraph::CoreFills::METHODS_WITH_YIELDPARAM_SUBTYPES.include?(meth.path))
|
169
192
|
base = signature.split('.')[0..-2].join('.')
|
170
193
|
return nil if base.nil? or base.empty?
|
171
194
|
# @todo Not sure if assuming the first pin is good here
|
172
|
-
bmeth =
|
195
|
+
bmeth = infer_signature_pins(base, pin.block, locals).first
|
173
196
|
return nil if bmeth.nil?
|
174
|
-
|
197
|
+
btype = bmeth.return_type
|
198
|
+
btype = infer_signature_type(bmeth.signature, pin.block, locals) if btype.nil? and bmeth.variable?
|
199
|
+
subtypes = get_subtypes(btype)
|
200
|
+
return nil if subtypes.nil?
|
175
201
|
return subtypes[0]
|
176
202
|
else
|
177
203
|
unless meth.docstring.nil?
|
@@ -8,11 +8,39 @@ module Solargraph
|
|
8
8
|
autoload :Rubocop, 'solargraph/diagnostics/rubocop'
|
9
9
|
autoload :RequireNotFound, 'solargraph/diagnostics/require_not_found'
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
class << self
|
12
|
+
# Add a reporter with a name to identify it in .solargraph.yml files.
|
13
|
+
#
|
14
|
+
# @param name [String] The name
|
15
|
+
# @param klass [Class<Solargraph::Diagnostics::Base>] The class implementation
|
16
|
+
def register name, klass
|
17
|
+
reporter_hash[name] = klass
|
18
|
+
end
|
19
|
+
|
20
|
+
# Get an array of reporter names.
|
21
|
+
#
|
22
|
+
# @return [Array<String>]
|
23
|
+
def reporters
|
24
|
+
reporter_hash.keys
|
25
|
+
end
|
26
|
+
|
27
|
+
# Find a reporter by name.
|
28
|
+
#
|
29
|
+
# @param name [String] The name with which the reporter was registered
|
30
|
+
# @return [Class<Solargraph::Diagnostics::Base>]
|
31
|
+
def reporter name
|
32
|
+
reporter_hash[name]
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# @return [Hash]
|
38
|
+
def reporter_hash
|
39
|
+
@reporter_hash ||= {}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
register 'rubocop', Rubocop
|
44
|
+
register 'require_not_found', RequireNotFound
|
17
45
|
end
|
18
46
|
end
|
@@ -40,16 +40,27 @@ module Solargraph
|
|
40
40
|
@options ||= default_configuration
|
41
41
|
end
|
42
42
|
|
43
|
+
# Cancel the method with the specified ID.
|
44
|
+
#
|
45
|
+
# @param id [Integer]
|
43
46
|
def cancel id
|
44
47
|
@cancel_semaphore.synchronize { @cancel.push id }
|
45
48
|
end
|
46
49
|
|
50
|
+
# True if the host received a request to cancel the method with the
|
51
|
+
# specified ID.
|
52
|
+
#
|
53
|
+
# @param id [Integer]
|
54
|
+
# @return [Boolean]
|
47
55
|
def cancel? id
|
48
56
|
result = false
|
49
57
|
@cancel_semaphore.synchronize { result = @cancel.include? id }
|
50
58
|
result
|
51
59
|
end
|
52
60
|
|
61
|
+
# Delete the specified ID from the list of cancelled IDs if it exists.
|
62
|
+
#
|
63
|
+
# @param id [Integer]
|
53
64
|
def clear id
|
54
65
|
@cancel_semaphore.synchronize { @cancel.delete id }
|
55
66
|
end
|
@@ -120,6 +131,7 @@ module Solargraph
|
|
120
131
|
|
121
132
|
# True if the specified file is currently open in the library.
|
122
133
|
#
|
134
|
+
# @param uri [String]
|
123
135
|
# @return [Boolean]
|
124
136
|
def open? uri
|
125
137
|
result = nil
|
@@ -129,6 +141,9 @@ module Solargraph
|
|
129
141
|
result
|
130
142
|
end
|
131
143
|
|
144
|
+
# Close the file specified by the URI.
|
145
|
+
#
|
146
|
+
# @param uri [String]
|
132
147
|
def close uri
|
133
148
|
@change_semaphore.synchronize do
|
134
149
|
library.close uri_to_file(uri)
|
@@ -200,7 +215,7 @@ module Solargraph
|
|
200
215
|
rescue WorkspaceTooLargeError => e
|
201
216
|
send_notification 'window/showMessage', {
|
202
217
|
'type' => Solargraph::LanguageServer::MessageTypes::WARNING,
|
203
|
-
'message' => "The workspace is too large to index (#{e.size} files, max #{
|
218
|
+
'message' => "The workspace is too large to index (#{e.size} files, max #{e.max})"
|
204
219
|
}
|
205
220
|
@library = Solargraph::Library.load(nil)
|
206
221
|
end
|
@@ -397,6 +412,8 @@ module Solargraph
|
|
397
412
|
result
|
398
413
|
end
|
399
414
|
|
415
|
+
# @param uri [String]
|
416
|
+
# @return [Array<Solargraph::Pin::Base>]
|
400
417
|
def file_symbols uri
|
401
418
|
library.file_symbols(uri_to_file(uri))
|
402
419
|
end
|
@@ -9,22 +9,17 @@ module Solargraph::LanguageServer::Message::TextDocument
|
|
9
9
|
col = params['position']['character']
|
10
10
|
contents = []
|
11
11
|
suggestions = host.definitions_at(filename, line, col)
|
12
|
-
|
12
|
+
last_link = nil
|
13
13
|
suggestions.each do |pin|
|
14
14
|
parts = []
|
15
|
-
|
16
|
-
if
|
17
|
-
|
18
|
-
else
|
19
|
-
this_path = pin.path
|
20
|
-
end
|
21
|
-
if !this_path.nil? and this_path != last_path
|
22
|
-
parts.push link_documentation(this_path)
|
15
|
+
this_link = pin.link_documentation
|
16
|
+
if !this_link.nil? and this_link != last_link
|
17
|
+
parts.push this_link
|
23
18
|
end
|
24
19
|
parts.push HTMLEntities.new.encode(pin.detail) unless pin.kind == Solargraph::Pin::NAMESPACE or pin.detail.nil?
|
25
20
|
parts.push pin.documentation unless pin.documentation.nil? or pin.documentation.empty?
|
26
21
|
contents.push parts.join("\n\n") unless parts.empty?
|
27
|
-
|
22
|
+
last_link = this_link unless this_link.nil?
|
28
23
|
end
|
29
24
|
set_result(
|
30
25
|
contents: {
|
@@ -33,13 +28,5 @@ module Solargraph::LanguageServer::Message::TextDocument
|
|
33
28
|
}
|
34
29
|
)
|
35
30
|
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
# @todo: DRY this method. It exists in Conversions
|
40
|
-
def link_documentation path
|
41
|
-
uri = "solargraph:/document?query=" + URI.encode(path)
|
42
|
-
"[#{path}](#{uri})"
|
43
|
-
end
|
44
31
|
end
|
45
32
|
end
|
data/lib/solargraph/library.rb
CHANGED
@@ -218,14 +218,19 @@ module Solargraph
|
|
218
218
|
api_map.query_symbols query
|
219
219
|
end
|
220
220
|
|
221
|
+
# @param filename [String]
|
222
|
+
# @return [Array<Solargraph::Pin::Base>]
|
221
223
|
def file_symbols filename
|
222
224
|
read(filename).all_symbols
|
223
225
|
end
|
224
226
|
|
227
|
+
# @param path [String]
|
228
|
+
# @return [Array<Solargraph::Pin::Base>]
|
225
229
|
def path_pins path
|
226
230
|
api_map.get_path_suggestions(path)
|
227
231
|
end
|
228
232
|
|
233
|
+
# @param updater [Solargraph::Source::Updater]
|
229
234
|
def synchronize updater
|
230
235
|
source = read(updater.filename)
|
231
236
|
source.synchronize updater
|
@@ -242,6 +247,7 @@ module Solargraph
|
|
242
247
|
|
243
248
|
# Get diagnostics about a file.
|
244
249
|
#
|
250
|
+
# @param filename [String]
|
245
251
|
# @return [Array<Hash>]
|
246
252
|
def diagnose filename
|
247
253
|
# @todo Only open files get diagnosed. Determine whether anything or
|
@@ -251,7 +257,7 @@ module Solargraph
|
|
251
257
|
result = []
|
252
258
|
source = read(filename)
|
253
259
|
workspace.config.reporters.each do |name|
|
254
|
-
reporter = Diagnostics
|
260
|
+
reporter = Diagnostics.reporter(name)
|
255
261
|
raise DiagnosticsError, "Diagnostics reporter #{name} does not exist" if reporter.nil?
|
256
262
|
result.concat reporter.new.diagnose(source, api_map)
|
257
263
|
end
|
data/lib/solargraph/live_map.rb
CHANGED
@@ -54,13 +54,14 @@ module Solargraph
|
|
54
54
|
suggestions = []
|
55
55
|
result.uniq.each do |r|
|
56
56
|
path = (r['namespace'].empty? ? '' : "#{r['namespace']}::") + r['name']
|
57
|
-
kind =
|
57
|
+
kind = Pin::CONSTANT
|
58
58
|
if r['class'] == 'Class'
|
59
|
-
|
59
|
+
suggestions.push Pin::Namespace.new(nil, r['namespace'], r['name'], YARD::Docstring.new("(defined at runtime)"), :class, :public, nil)
|
60
60
|
elsif r['class'] == 'Module'
|
61
|
-
|
61
|
+
suggestions.push Pin::Namespace.new(nil, r['namespace'], r['name'], YARD::Docstring.new("(defined at runtime)"), :module, :public, nil)
|
62
|
+
else
|
63
|
+
suggestions.push Pin::Constant.new(nil, r['namespace'], r['name'], YARD::Docstring.new("(defined at runtime"), nil, nil, nil, :public)
|
62
64
|
end
|
63
|
-
suggestions.push(Suggestion.new(r['name'], kind: kind, path: path))
|
64
65
|
end
|
65
66
|
cache.set_constants(namespace, root, suggestions)
|
66
67
|
suggestions
|
@@ -21,7 +21,7 @@ module Solargraph
|
|
21
21
|
if @resolve_completion_item.nil?
|
22
22
|
extra = {}
|
23
23
|
alldoc = ''
|
24
|
-
alldoc += link_documentation
|
24
|
+
alldoc += link_documentation unless link_documentation.nil?
|
25
25
|
alldoc += "\n\n" unless alldoc.empty?
|
26
26
|
alldoc += documentation unless documentation.nil?
|
27
27
|
extra[:documentation] = alldoc unless alldoc.empty?
|
@@ -50,10 +50,19 @@ module Solargraph
|
|
50
50
|
@detail
|
51
51
|
end
|
52
52
|
|
53
|
+
# Get a markdown-flavored link to a documentation page.
|
54
|
+
#
|
55
|
+
# @return [String]
|
56
|
+
def link_documentation
|
57
|
+
@link_documentation ||= generate_link
|
58
|
+
end
|
59
|
+
|
53
60
|
private
|
54
61
|
|
55
|
-
def
|
56
|
-
|
62
|
+
def generate_link
|
63
|
+
this_path = path || return_type
|
64
|
+
return nil if this_path.nil?
|
65
|
+
"[#{this_path.gsub('_', '\\\\_')}](solargraph:/document?query=#{URI.encode(this_path)})"
|
57
66
|
end
|
58
67
|
end
|
59
68
|
end
|
@@ -10,16 +10,16 @@ module Solargraph
|
|
10
10
|
# @return [String]
|
11
11
|
attr_reader :name
|
12
12
|
|
13
|
+
# @param location [Source::Location]
|
14
|
+
# @param namespace [String]
|
15
|
+
# @param name [String]
|
13
16
|
def initialize location, namespace, name
|
14
17
|
@location = location
|
15
18
|
@namespace = namespace
|
16
19
|
@name = name
|
17
20
|
end
|
18
21
|
|
19
|
-
# @
|
20
|
-
def resolve api_map
|
21
|
-
end
|
22
|
-
|
22
|
+
# @return [String]
|
23
23
|
def filename
|
24
24
|
location.filename
|
25
25
|
end
|
@@ -61,20 +61,21 @@ module Solargraph
|
|
61
61
|
|
62
62
|
def get_methods args
|
63
63
|
result = []
|
64
|
+
# @type [Class]
|
64
65
|
con = find_constant(args['namespace'], args['root'])
|
65
66
|
unless con.nil?
|
66
67
|
if (args['scope'] == 'class')
|
67
|
-
result.concat con.methods
|
68
|
-
result.concat con.public_methods
|
68
|
+
result.concat con.methods if args['with_private']
|
69
|
+
result.concat con.public_methods
|
69
70
|
elsif (args['scope'] == 'instance')
|
70
|
-
result.concat con.instance_methods
|
71
|
-
result.concat con.public_instance_methods
|
71
|
+
result.concat con.instance_methods if args['with_private']
|
72
|
+
result.concat con.public_instance_methods
|
72
73
|
end
|
73
74
|
end
|
74
75
|
result.keep_if{|m| m.to_s.match(/^[a-z_]/i)}
|
75
76
|
respond_ok (result.uniq.sort.map do |name|
|
76
77
|
# @type [Method]
|
77
|
-
meth = con.method(name)
|
78
|
+
meth = args['scope'] == 'class' ? con.method(name) : con.instance_method(name)
|
78
79
|
{
|
79
80
|
name: name,
|
80
81
|
parameters: build_parameter_array(meth.parameters)
|
data/lib/solargraph/shell.rb
CHANGED
data/lib/solargraph/source.rb
CHANGED
@@ -44,6 +44,7 @@ module Solargraph
|
|
44
44
|
# @return [Array<Solargraph::Pin::Base>]
|
45
45
|
attr_reader :pins
|
46
46
|
|
47
|
+
# @return [Array<Solargraph::Pin::Reference>]
|
47
48
|
attr_reader :requires
|
48
49
|
|
49
50
|
attr_reader :domains
|
@@ -53,15 +54,18 @@ module Solargraph
|
|
53
54
|
include NodeMethods
|
54
55
|
|
55
56
|
def initialize code, filename = nil
|
56
|
-
@code = code
|
57
|
-
@fixed = code
|
58
|
-
@filename = filename
|
59
|
-
# @stubbed_lines = stubbed_lines
|
60
|
-
@version = 0
|
61
57
|
begin
|
62
|
-
|
63
|
-
|
64
|
-
|
58
|
+
@code = code
|
59
|
+
@fixed = code
|
60
|
+
@filename = filename
|
61
|
+
@version = 0
|
62
|
+
begin
|
63
|
+
parse
|
64
|
+
rescue Parser::SyntaxError, EncodingError
|
65
|
+
hard_fix_node
|
66
|
+
end
|
67
|
+
rescue Exception => e
|
68
|
+
raise RuntimeError, "Error parsing #{filename || '(source)'}: [#{e.class}] #{e.message}"
|
65
69
|
end
|
66
70
|
end
|
67
71
|
|
@@ -75,6 +79,7 @@ module Solargraph
|
|
75
79
|
end
|
76
80
|
|
77
81
|
# @todo Name problem
|
82
|
+
# @return [Array<Solargraph::Pin::Reference>]
|
78
83
|
def required
|
79
84
|
requires
|
80
85
|
end
|
@@ -111,6 +116,7 @@ module Solargraph
|
|
111
116
|
pins.select{|pin| pin.kind == Pin::CLASS_VARIABLE}
|
112
117
|
end
|
113
118
|
|
119
|
+
# @return [Array<Solargraph::Pin::Base>]
|
114
120
|
def locals
|
115
121
|
@locals
|
116
122
|
end
|
@@ -130,6 +136,7 @@ module Solargraph
|
|
130
136
|
@symbols
|
131
137
|
end
|
132
138
|
|
139
|
+
# @return [Array<Solargraph::Pin::Symbol>]
|
133
140
|
def symbols
|
134
141
|
symbol_pins
|
135
142
|
end
|
@@ -171,6 +178,11 @@ module Solargraph
|
|
171
178
|
tree_at(line, column).first
|
172
179
|
end
|
173
180
|
|
181
|
+
# True if the specified location is inside a string.
|
182
|
+
#
|
183
|
+
# @param line [Integer]
|
184
|
+
# @param column [Integer]
|
185
|
+
# @return [Boolean]
|
174
186
|
def string_at?(line, column)
|
175
187
|
node = node_at(line, column)
|
176
188
|
# @todo raise InvalidOffset or InvalidRange or something?
|
@@ -232,7 +244,7 @@ module Solargraph
|
|
232
244
|
|
233
245
|
def all_symbols
|
234
246
|
@all_symbols ||= pins.select{ |pin|
|
235
|
-
[Pin::ATTRIBUTE, Pin::CONSTANT, Pin::METHOD, Pin::NAMESPACE].include?(pin.kind)
|
247
|
+
[Pin::ATTRIBUTE, Pin::CONSTANT, Pin::METHOD, Pin::NAMESPACE].include?(pin.kind) and !pin.name.empty?
|
236
248
|
}
|
237
249
|
end
|
238
250
|
|
@@ -25,13 +25,15 @@ module Solargraph
|
|
25
25
|
# @return [String] The updated text.
|
26
26
|
def write text, nullable = false
|
27
27
|
if nullable and !range.nil? and new_text.match(/[\.\[\{\(@\$:]$/)
|
28
|
-
|
28
|
+
[':', '@'].each do |dupable|
|
29
|
+
next unless new_text == dupable
|
29
30
|
offset = Position.to_offset(text, range.start)
|
30
|
-
if text[offset - 1] ==
|
31
|
+
if text[offset - 1] == dupable
|
31
32
|
p = Position.from_offset(text, offset - 1)
|
32
33
|
r = Change.new(Range.new(p, range.start), ' ')
|
33
34
|
text = r.write(text)
|
34
35
|
end
|
36
|
+
break
|
35
37
|
end
|
36
38
|
commit text, "#{new_text[0..-2]} "
|
37
39
|
elsif range.nil?
|
@@ -3,8 +3,14 @@ module Solargraph
|
|
3
3
|
class Fragment
|
4
4
|
include NodeMethods
|
5
5
|
|
6
|
+
# The zero-based line number of the fragment's location.
|
7
|
+
#
|
8
|
+
# @return [Integer]
|
6
9
|
attr_reader :line
|
7
10
|
|
11
|
+
# The zero-based column number of the fragment's location.
|
12
|
+
#
|
13
|
+
# @return [Integer]
|
8
14
|
attr_reader :column
|
9
15
|
|
10
16
|
# @return [Solargraph::Source]
|
@@ -21,10 +27,14 @@ module Solargraph
|
|
21
27
|
@calculated_literal = false
|
22
28
|
end
|
23
29
|
|
30
|
+
# An alias for #column.
|
31
|
+
#
|
32
|
+
# @return [Integer]
|
24
33
|
def character
|
25
34
|
@column
|
26
35
|
end
|
27
36
|
|
37
|
+
# @return [Source::Position]
|
28
38
|
def position
|
29
39
|
@position ||= Position.new(line, column)
|
30
40
|
end
|
@@ -40,6 +50,8 @@ module Solargraph
|
|
40
50
|
@namespace
|
41
51
|
end
|
42
52
|
|
53
|
+
# True if the fragment is inside a method argument.
|
54
|
+
#
|
43
55
|
# @return [Boolean]
|
44
56
|
def argument?
|
45
57
|
@argument ||= !signature_position.nil?
|
@@ -159,6 +171,8 @@ module Solargraph
|
|
159
171
|
|
160
172
|
# Get the word before the current offset. Given the text `foo.bar`, the
|
161
173
|
# word at offset 6 is `ba`.
|
174
|
+
#
|
175
|
+
# @return [String]
|
162
176
|
def word
|
163
177
|
@word ||= word_at(offset)
|
164
178
|
end
|
@@ -194,14 +208,17 @@ module Solargraph
|
|
194
208
|
@whole_word_range ||= word_range_at(offset, true)
|
195
209
|
end
|
196
210
|
|
211
|
+
# @return [Solargraph::Pin::Base]
|
197
212
|
def block
|
198
213
|
@block ||= @source.locate_block_pin(line, character)
|
199
214
|
end
|
200
215
|
|
216
|
+
# @return [Solargraph::Pin::Base]
|
201
217
|
def named_path
|
202
218
|
@named_path ||= @source.locate_named_path_pin(line, character)
|
203
219
|
end
|
204
220
|
|
221
|
+
# @return [Array<Solargraph::Pin::Base>]
|
205
222
|
def locals
|
206
223
|
@locals ||= @source.locals.select{|pin| pin.visible_from?(block, position)}
|
207
224
|
end
|
@@ -227,10 +244,17 @@ module Solargraph
|
|
227
244
|
@base_literal
|
228
245
|
end
|
229
246
|
|
247
|
+
# True if the fragment is inside a literal value.
|
248
|
+
#
|
249
|
+
# @return [Boolean]
|
230
250
|
def literal?
|
231
251
|
!literal.nil?
|
232
252
|
end
|
233
253
|
|
254
|
+
# The fragment's literal type, or nil if the fragment is not inside a
|
255
|
+
# literal value.
|
256
|
+
#
|
257
|
+
# @return [String]
|
234
258
|
def literal
|
235
259
|
if @literal.nil? and !@calculated_actual_literal
|
236
260
|
@calculated_actual_literal = true
|
@@ -299,7 +323,7 @@ module Solargraph
|
|
299
323
|
end
|
300
324
|
if brackets.zero? and parens.zero? and squares.zero?
|
301
325
|
break if ['"', "'", ',', ';', '%'].include?(char)
|
302
|
-
signature = char + signature if char.match(/[a-z0-9:\._
|
326
|
+
signature = char + signature if char.match(/[a-z0-9:\._@\$\?\!]/i) and @code[index - 1] != '%'
|
303
327
|
break if char == '$'
|
304
328
|
if char == '@'
|
305
329
|
signature = "@#{signature}" if @code[index-1, 1] == '@'
|
@@ -18,10 +18,7 @@ module Solargraph
|
|
18
18
|
@filename = filename
|
19
19
|
@code = code
|
20
20
|
@node = node
|
21
|
-
@comments = comments
|
22
21
|
@node_stack = []
|
23
|
-
# @node_tree = []
|
24
|
-
@comment_hash = {}
|
25
22
|
@directives = {}
|
26
23
|
@docstring_hash = associate_comments(node, comments)
|
27
24
|
# @todo Stuff that needs to be resolved
|
@@ -60,18 +57,10 @@ module Solargraph
|
|
60
57
|
frag.strip.gsub(/,$/, '')
|
61
58
|
end
|
62
59
|
|
63
|
-
def comment_hash
|
64
|
-
@comment_hash
|
65
|
-
end
|
66
|
-
|
67
60
|
def filename
|
68
61
|
@filename
|
69
62
|
end
|
70
63
|
|
71
|
-
def comments
|
72
|
-
@comments
|
73
|
-
end
|
74
|
-
|
75
64
|
def pins
|
76
65
|
@pins ||= []
|
77
66
|
end
|
@@ -334,10 +323,6 @@ module Solargraph
|
|
334
323
|
@pins.select{|pin| [Pin::NAMESPACE, Pin::METHOD].include?(pin.kind) and pin.location.range.contain?(position)}.last
|
335
324
|
end
|
336
325
|
|
337
|
-
def get_namespace_pin position
|
338
|
-
@pins.select{|pin| pin.kind == Pin::NAMESPACE and pin.location.range.contain?(position)}.last
|
339
|
-
end
|
340
|
-
|
341
326
|
# @return [YARD::Docstring]
|
342
327
|
def docstring_for node
|
343
328
|
return @docstring_hash[node.loc] if node.respond_to?(:loc)
|
@@ -25,6 +25,7 @@ module Solargraph
|
|
25
25
|
@output = nil
|
26
26
|
end
|
27
27
|
|
28
|
+
# @return [String]
|
28
29
|
def write text, nullable = false
|
29
30
|
can_nullify = (nullable and changes.length == 1)
|
30
31
|
return @output if @input == text and can_nullify == @did_nullify
|
@@ -37,6 +38,7 @@ module Solargraph
|
|
37
38
|
@output
|
38
39
|
end
|
39
40
|
|
41
|
+
# @return [String]
|
40
42
|
def repair text
|
41
43
|
changes.each do |ch|
|
42
44
|
text = ch.repair(text)
|
data/lib/solargraph/version.rb
CHANGED
data/lib/solargraph/workspace.rb
CHANGED
@@ -101,10 +101,16 @@ module Solargraph
|
|
101
101
|
false
|
102
102
|
end
|
103
103
|
|
104
|
+
# True if the workspace contains at least one gemspec file.
|
105
|
+
#
|
106
|
+
# @return [Boolean]
|
104
107
|
def gemspec?
|
105
|
-
|
108
|
+
!gemspecs.empty?
|
106
109
|
end
|
107
110
|
|
111
|
+
# Get an array of all gemspec files in the workspace.
|
112
|
+
#
|
113
|
+
# @return [Array<String>]
|
108
114
|
def gemspecs
|
109
115
|
return [] if directory.nil?
|
110
116
|
@gemspecs ||= Dir[File.join(directory, '**/*.gemspec')]
|
@@ -121,7 +127,7 @@ module Solargraph
|
|
121
127
|
source_hash.clear
|
122
128
|
unless directory.nil?
|
123
129
|
size = config.calculated.length
|
124
|
-
raise WorkspaceTooLargeError.new(size) if config.max_files > 0 and size > config.max_files
|
130
|
+
raise WorkspaceTooLargeError.new(size, config.max_files) if config.max_files > 0 and size > config.max_files
|
125
131
|
|
126
132
|
config.calculated.each do |filename|
|
127
133
|
source_hash[filename] = Solargraph::Source.load(filename)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solargraph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.23.
|
4
|
+
version: 0.23.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Snyder
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-07-
|
11
|
+
date: 2018-07-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|