solargraph 0.47.2 → 0.54.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/plugins.yml +40 -0
- data/.github/workflows/rspec.yml +4 -8
- data/.github/workflows/typecheck.yml +34 -0
- data/.yardopts +2 -2
- data/CHANGELOG.md +166 -3
- data/LICENSE +1 -1
- data/README.md +19 -16
- data/SPONSORS.md +2 -9
- data/lib/solargraph/api_map/cache.rb +50 -20
- data/lib/solargraph/api_map/source_to_yard.rb +17 -10
- data/lib/solargraph/api_map/store.rb +68 -15
- data/lib/solargraph/api_map.rb +238 -112
- data/lib/solargraph/bench.rb +3 -2
- data/lib/solargraph/cache.rb +77 -0
- data/lib/solargraph/complex_type/type_methods.rb +116 -35
- data/lib/solargraph/complex_type/unique_type.rb +261 -33
- data/lib/solargraph/complex_type.rb +149 -30
- data/lib/solargraph/convention/rakefile.rb +17 -0
- data/lib/solargraph/convention.rb +2 -3
- data/lib/solargraph/converters/dd.rb +5 -0
- data/lib/solargraph/converters/dl.rb +3 -0
- data/lib/solargraph/converters/dt.rb +3 -0
- data/lib/solargraph/diagnostics/rubocop.rb +23 -8
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +4 -1
- data/lib/solargraph/diagnostics/type_check.rb +1 -0
- data/lib/solargraph/diagnostics.rb +2 -2
- data/lib/solargraph/doc_map.rb +187 -0
- data/lib/solargraph/gem_pins.rb +72 -0
- data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
- data/lib/solargraph/language_server/host/dispatch.rb +22 -5
- data/lib/solargraph/language_server/host/message_worker.rb +4 -0
- data/lib/solargraph/language_server/host/sources.rb +8 -65
- data/lib/solargraph/language_server/host.rb +88 -93
- data/lib/solargraph/language_server/message/base.rb +1 -1
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
- data/lib/solargraph/language_server/message/extended/download_core.rb +1 -5
- data/lib/solargraph/language_server/message/initialize.rb +27 -0
- data/lib/solargraph/language_server/message/initialized.rb +1 -0
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +4 -1
- data/lib/solargraph/language_server/message/text_document/formatting.rb +5 -4
- data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -6
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +24 -0
- data/lib/solargraph/language_server/message/text_document.rb +1 -1
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +10 -3
- data/lib/solargraph/language_server/message.rb +1 -0
- data/lib/solargraph/language_server/progress.rb +118 -0
- data/lib/solargraph/language_server/transport/adapter.rb +16 -1
- data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
- data/lib/solargraph/language_server.rb +1 -0
- data/lib/solargraph/library.rb +231 -104
- data/lib/solargraph/location.rb +1 -0
- data/lib/solargraph/page.rb +6 -0
- data/lib/solargraph/parser/comment_ripper.rb +4 -0
- data/lib/solargraph/parser/node_methods.rb +47 -7
- data/lib/solargraph/parser/node_processor/base.rb +11 -1
- data/lib/solargraph/parser/node_processor.rb +1 -0
- data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +31 -9
- data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +57 -41
- data/lib/solargraph/parser/parser_gem/node_methods.rb +495 -0
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +53 -0
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +14 -4
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/cvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/def_node.rb +7 -20
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +2 -2
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +47 -0
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +42 -0
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +7 -5
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sym_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors.rb +56 -0
- data/lib/solargraph/parser/parser_gem.rb +12 -0
- data/lib/solargraph/parser/region.rb +1 -1
- data/lib/solargraph/parser/snippet.rb +2 -0
- data/lib/solargraph/parser.rb +9 -10
- data/lib/solargraph/pin/base.rb +69 -11
- data/lib/solargraph/pin/base_variable.rb +40 -7
- data/lib/solargraph/pin/block.rb +81 -33
- data/lib/solargraph/pin/closure.rb +17 -2
- data/lib/solargraph/pin/common.rb +7 -3
- data/lib/solargraph/pin/conversions.rb +34 -8
- data/lib/solargraph/pin/delegated_method.rb +101 -0
- data/lib/solargraph/pin/documenting.rb +25 -32
- data/lib/solargraph/pin/instance_variable.rb +4 -0
- data/lib/solargraph/pin/local_variable.rb +13 -1
- data/lib/solargraph/pin/method.rb +273 -17
- data/lib/solargraph/pin/namespace.rb +17 -1
- data/lib/solargraph/pin/parameter.rb +40 -28
- data/lib/solargraph/pin/reference/override.rb +2 -2
- data/lib/solargraph/pin/reference.rb +8 -0
- data/lib/solargraph/pin/search.rb +4 -4
- data/lib/solargraph/pin/signature.rb +143 -0
- data/lib/solargraph/pin.rb +2 -1
- data/lib/solargraph/range.rb +4 -6
- data/lib/solargraph/rbs_map/conversions.rb +607 -0
- data/lib/solargraph/rbs_map/core_fills.rb +50 -0
- data/lib/solargraph/rbs_map/core_map.rb +28 -0
- data/lib/solargraph/rbs_map/stdlib_map.rb +33 -0
- data/lib/solargraph/rbs_map.rb +92 -0
- data/lib/solargraph/shell.rb +85 -59
- data/lib/solargraph/source/chain/array.rb +32 -0
- data/lib/solargraph/source/chain/block_symbol.rb +13 -0
- data/lib/solargraph/source/chain/call.rb +125 -61
- data/lib/solargraph/source/chain/constant.rb +15 -1
- data/lib/solargraph/source/chain/if.rb +23 -0
- data/lib/solargraph/source/chain/link.rb +8 -2
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain/z_super.rb +3 -3
- data/lib/solargraph/source/chain.rb +64 -14
- data/lib/solargraph/source/change.rb +3 -0
- data/lib/solargraph/source/cursor.rb +2 -0
- data/lib/solargraph/source/source_chainer.rb +8 -5
- data/lib/solargraph/source/updater.rb +1 -0
- data/lib/solargraph/source.rb +18 -63
- data/lib/solargraph/source_map/clip.rb +31 -23
- data/lib/solargraph/source_map/mapper.rb +23 -7
- data/lib/solargraph/source_map.rb +36 -11
- data/lib/solargraph/type_checker/checks.rb +10 -2
- data/lib/solargraph/type_checker.rb +229 -100
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +2 -2
- data/lib/solargraph/workspace/config.rb +15 -11
- data/lib/solargraph/workspace.rb +41 -17
- data/lib/solargraph/yard_map/cache.rb +6 -0
- data/lib/solargraph/yard_map/helpers.rb +1 -1
- data/lib/solargraph/yard_map/mapper/to_method.rb +23 -7
- data/lib/solargraph/yard_map/mapper.rb +1 -1
- data/lib/solargraph/yard_map/to_method.rb +11 -4
- data/lib/solargraph/yard_map.rb +1 -443
- data/lib/solargraph/yard_tags.rb +20 -0
- data/lib/solargraph/yardoc.rb +52 -0
- data/lib/solargraph.rb +8 -6
- data/solargraph.gemspec +19 -8
- metadata +164 -99
- data/.travis.yml +0 -19
- data/lib/solargraph/api_map/bundler_methods.rb +0 -22
- data/lib/solargraph/compat.rb +0 -37
- data/lib/solargraph/convention/rspec.rb +0 -30
- data/lib/solargraph/documentor.rb +0 -76
- data/lib/solargraph/language_server/host/cataloger.rb +0 -56
- data/lib/solargraph/parser/legacy/node_methods.rb +0 -325
- data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
- data/lib/solargraph/parser/legacy/node_processors/args_node.rb +0 -35
- data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
- data/lib/solargraph/parser/legacy/node_processors/cvasgn_node.rb +0 -23
- data/lib/solargraph/parser/legacy/node_processors/def_node.rb +0 -63
- data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +0 -21
- data/lib/solargraph/parser/legacy/node_processors.rb +0 -54
- data/lib/solargraph/parser/legacy.rb +0 -12
- data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -144
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -160
- data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -315
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
- data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
- data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -22
- data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -57
- data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
- data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
- data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
- data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
- data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
- data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
- data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
- data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -45
- data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -21
- data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -277
- data/lib/solargraph/parser/rubyvm/node_processors/sym_node.rb +0 -18
- data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -63
- data/lib/solargraph/parser/rubyvm.rb +0 -40
- 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/lib/yard-solargraph.rb +0 -33
- data/yardoc/2.2.2.tar.gz +0 -0
data/lib/solargraph/source.rb
CHANGED
@@ -8,7 +8,6 @@ module Solargraph
|
|
8
8
|
class Source
|
9
9
|
autoload :Updater, 'solargraph/source/updater'
|
10
10
|
autoload :Change, 'solargraph/source/change'
|
11
|
-
autoload :Mapper, 'solargraph/source/mapper'
|
12
11
|
autoload :EncodingFixes, 'solargraph/source/encoding_fixes'
|
13
12
|
autoload :Cursor, 'solargraph/source/cursor'
|
14
13
|
autoload :Chain, 'solargraph/source/chain'
|
@@ -33,7 +32,7 @@ module Solargraph
|
|
33
32
|
attr_reader :version
|
34
33
|
|
35
34
|
# @param code [String]
|
36
|
-
# @param filename [String]
|
35
|
+
# @param filename [String, nil]
|
37
36
|
# @param version [Integer]
|
38
37
|
def initialize code, filename = nil, version = 0
|
39
38
|
@code = normalize(code)
|
@@ -93,50 +92,6 @@ module Solargraph
|
|
93
92
|
stack
|
94
93
|
end
|
95
94
|
|
96
|
-
# Start synchronizing the source. This method updates the code without
|
97
|
-
# parsing a new AST. The resulting Source object will be marked not
|
98
|
-
# synchronized (#synchronized? == false).
|
99
|
-
#
|
100
|
-
# @param updater [Source::Updater]
|
101
|
-
# @return [Source]
|
102
|
-
def start_synchronize updater
|
103
|
-
raise 'Invalid synchronization' unless updater.filename == filename
|
104
|
-
real_code = updater.write(@code)
|
105
|
-
src = Source.allocate
|
106
|
-
src.filename = filename
|
107
|
-
src.code = real_code
|
108
|
-
src.version = updater.version
|
109
|
-
src.parsed = parsed?
|
110
|
-
src.repaired = updater.repair(@repaired)
|
111
|
-
src.synchronized = false
|
112
|
-
src.node = @node
|
113
|
-
src.comments = @comments
|
114
|
-
src.error_ranges = error_ranges
|
115
|
-
src.last_updater = updater
|
116
|
-
return src.finish_synchronize unless real_code.lines.length == @code.lines.length
|
117
|
-
src
|
118
|
-
end
|
119
|
-
|
120
|
-
# Finish synchronizing a source that was updated via #start_synchronize.
|
121
|
-
# This method returns self if the source is already synchronized. Otherwise
|
122
|
-
# it parses the AST and returns a new synchronized Source.
|
123
|
-
#
|
124
|
-
# @return [Source]
|
125
|
-
def finish_synchronize
|
126
|
-
return self if synchronized?
|
127
|
-
synced = Source.new(@code, filename)
|
128
|
-
if synced.parsed?
|
129
|
-
synced.version = version
|
130
|
-
return synced
|
131
|
-
end
|
132
|
-
synced = Source.new(@repaired, filename)
|
133
|
-
synced.error_ranges.concat (error_ranges + last_updater.changes.map(&:range))
|
134
|
-
synced.code = @code
|
135
|
-
synced.synchronized = true
|
136
|
-
synced.version = version
|
137
|
-
synced
|
138
|
-
end
|
139
|
-
|
140
95
|
# Synchronize the Source with an update. This method applies changes to the
|
141
96
|
# code, parses the new code's AST, and returns the resulting Source object.
|
142
97
|
#
|
@@ -213,6 +168,7 @@ module Solargraph
|
|
213
168
|
end
|
214
169
|
end
|
215
170
|
|
171
|
+
# @return [::Array<Range>]
|
216
172
|
def string_ranges
|
217
173
|
@string_ranges ||= Parser.string_ranges(node)
|
218
174
|
end
|
@@ -250,7 +206,7 @@ module Solargraph
|
|
250
206
|
end
|
251
207
|
|
252
208
|
# @param node [Parser::AST::Node]
|
253
|
-
# @return [String]
|
209
|
+
# @return [String, nil]
|
254
210
|
def comments_for node
|
255
211
|
rng = Range.from_node(node)
|
256
212
|
stringified_comments[rng.start.line] ||= begin
|
@@ -301,7 +257,7 @@ module Solargraph
|
|
301
257
|
|
302
258
|
# Get a hash of comments grouped by the line numbers of the associated code.
|
303
259
|
#
|
304
|
-
# @return [Hash{Integer =>
|
260
|
+
# @return [Hash{Integer => String}]
|
305
261
|
def associated_comments
|
306
262
|
@associated_comments ||= begin
|
307
263
|
result = {}
|
@@ -323,6 +279,8 @@ module Solargraph
|
|
323
279
|
|
324
280
|
private
|
325
281
|
|
282
|
+
# @param line [Integer]
|
283
|
+
# @return [Integer]
|
326
284
|
def first_not_empty_from line
|
327
285
|
cursor = line
|
328
286
|
cursor += 1 while cursor < code_lines.length && code_lines[cursor].strip.empty?
|
@@ -332,7 +290,7 @@ module Solargraph
|
|
332
290
|
|
333
291
|
# @param top [Parser::AST::Node]
|
334
292
|
# @param result [Array<Range>]
|
335
|
-
# @param parent [Symbol]
|
293
|
+
# @param parent [Symbol, nil]
|
336
294
|
# @return [void]
|
337
295
|
def inner_folding_ranges top, result = [], parent = nil
|
338
296
|
return unless Parser.is_ast_node?(top)
|
@@ -411,7 +369,7 @@ module Solargraph
|
|
411
369
|
result
|
412
370
|
end
|
413
371
|
|
414
|
-
# @param n [Parser::AST::Node]
|
372
|
+
# @param n [Parser::AST::Node, nil]
|
415
373
|
# @return [Array<Parser::AST::Node>]
|
416
374
|
def string_nodes_in n
|
417
375
|
result = []
|
@@ -425,30 +383,23 @@ module Solargraph
|
|
425
383
|
result
|
426
384
|
end
|
427
385
|
|
428
|
-
# @param node [Parser::AST::Node]
|
386
|
+
# @param node [Parser::AST::Node, nil]
|
429
387
|
# @param position [Position]
|
430
388
|
# @param stack [Array<Parser::AST::Node>]
|
431
389
|
# @return [void]
|
432
390
|
def inner_tree_at node, position, stack
|
433
391
|
return if node.nil?
|
434
392
|
here = Range.from_node(node)
|
435
|
-
if here.contain?(position)
|
393
|
+
if here.contain?(position)
|
436
394
|
stack.unshift node
|
437
395
|
node.children.each do |c|
|
438
396
|
next unless Parser.is_ast_node?(c)
|
439
|
-
next if
|
397
|
+
next if c.loc.expression.nil?
|
440
398
|
inner_tree_at(c, position, stack)
|
441
399
|
end
|
442
400
|
end
|
443
401
|
end
|
444
402
|
|
445
|
-
def colonized range, position, node
|
446
|
-
node.type == :COLON2 &&
|
447
|
-
range.ending.line == position.line &&
|
448
|
-
range.ending.character == position.character - 2 &&
|
449
|
-
code[Position.to_offset(code, Position.new(position.line, position.character - 2)), 2] == '::'
|
450
|
-
end
|
451
|
-
|
452
403
|
protected
|
453
404
|
|
454
405
|
# @return [String]
|
@@ -464,7 +415,7 @@ module Solargraph
|
|
464
415
|
@code = val
|
465
416
|
end
|
466
417
|
|
467
|
-
# @return [Parser::AST::Node]
|
418
|
+
# @return [Parser::AST::Node, nil]
|
468
419
|
attr_writer :node
|
469
420
|
|
470
421
|
# @return [Array<Range>]
|
@@ -476,7 +427,7 @@ module Solargraph
|
|
476
427
|
# @return [Boolean]
|
477
428
|
attr_writer :parsed
|
478
429
|
|
479
|
-
# @return [
|
430
|
+
# @return [Hash{Integer => String}
|
480
431
|
attr_writer :comments
|
481
432
|
|
482
433
|
# @return [Boolean]
|
@@ -503,7 +454,7 @@ module Solargraph
|
|
503
454
|
end
|
504
455
|
|
505
456
|
# @param code [String]
|
506
|
-
# @param filename [String]
|
457
|
+
# @param filename [String, nil]
|
507
458
|
# @param version [Integer]
|
508
459
|
# @return [Solargraph::Source]
|
509
460
|
def load_string code, filename = nil, version = 0
|
@@ -516,6 +467,10 @@ module Solargraph
|
|
516
467
|
# HACK: Pass a dummy code object to the parser for plugins that
|
517
468
|
# expect it not to be nil
|
518
469
|
YARD::Docstring.parser.parse(comments, YARD::CodeObjects::Base.new(:root, 'stub'))
|
470
|
+
rescue StandardError => e
|
471
|
+
Solargraph.logger.info "YARD failed to parse docstring: [#{e.class}] #{e.message}"
|
472
|
+
Solargraph.logger.debug "Unparsed comment: #{comments}"
|
473
|
+
YARD::Docstring.parser
|
519
474
|
end
|
520
475
|
end
|
521
476
|
end
|
@@ -11,16 +11,23 @@ module Solargraph
|
|
11
11
|
def initialize api_map, cursor
|
12
12
|
@api_map = api_map
|
13
13
|
@cursor = cursor
|
14
|
+
block.rebind(api_map) if block.is_a?(Pin::Block)
|
14
15
|
end
|
15
16
|
|
16
|
-
# @return [Array<Pin::Base>]
|
17
|
+
# @return [Array<Pin::Base>] Relevant pins for infering the type of the Cursor's position
|
17
18
|
def define
|
18
19
|
return [] if cursor.comment? || cursor.chain.literal?
|
19
20
|
result = cursor.chain.define(api_map, block, locals)
|
21
|
+
result.concat file_global_methods
|
20
22
|
result.concat((source_map.pins + source_map.locals).select{ |p| p.name == cursor.word && p.location.range.contain?(cursor.position) }) if result.empty?
|
21
23
|
result
|
22
24
|
end
|
23
25
|
|
26
|
+
# @return [Array<Pin::Base>]
|
27
|
+
def types
|
28
|
+
infer.namespaces.map { |namespace| api_map.get_path_pins(namespace) }.flatten
|
29
|
+
end
|
30
|
+
|
24
31
|
# @return [Completion]
|
25
32
|
def complete
|
26
33
|
return package_completions([]) if !source_map.source.parsed? || cursor.string?
|
@@ -43,19 +50,25 @@ module Solargraph
|
|
43
50
|
# @return [ComplexType]
|
44
51
|
def infer
|
45
52
|
result = cursor.chain.infer(api_map, block, locals)
|
53
|
+
if result.tag == 'Class'
|
54
|
+
# HACK: Exception to return BasicObject from Class#new
|
55
|
+
dfn = cursor.chain.define(api_map, block, locals).first
|
56
|
+
return ComplexType.try_parse('BasicObject') if dfn && dfn.path == 'Class#new'
|
57
|
+
end
|
46
58
|
return result unless result.tag == 'self'
|
47
|
-
ComplexType.try_parse(cursor.chain.base.infer(api_map, block, locals).
|
59
|
+
ComplexType.try_parse(cursor.chain.base.infer(api_map, block, locals).tag)
|
48
60
|
end
|
49
61
|
|
50
62
|
# Get an array of all the locals that are visible from the cursors's
|
51
63
|
# position. Locals can be local variables, method parameters, or block
|
52
64
|
# parameters. The array starts with the nearest local pin.
|
53
65
|
#
|
54
|
-
# @return [Array<Solargraph::Pin::Base>]
|
66
|
+
# @return [::Array<Solargraph::Pin::Base>]
|
55
67
|
def locals
|
56
68
|
@locals ||= source_map.locals_at(location)
|
57
69
|
end
|
58
70
|
|
71
|
+
# @return [::Array<String>]
|
59
72
|
def gates
|
60
73
|
block.gates
|
61
74
|
end
|
@@ -88,11 +101,12 @@ module Solargraph
|
|
88
101
|
@source_map ||= api_map.source_map(cursor.filename)
|
89
102
|
end
|
90
103
|
|
104
|
+
# @return [Location]
|
91
105
|
def location
|
92
106
|
Location.new(source_map.filename, Solargraph::Range.new(cursor.position, cursor.position))
|
93
107
|
end
|
94
108
|
|
95
|
-
# @return [Solargraph::Pin::
|
109
|
+
# @return [Solargraph::Pin::Closure]
|
96
110
|
def block
|
97
111
|
@block ||= source_map.locate_block_pin(cursor.node_position.line, cursor.node_position.character)
|
98
112
|
end
|
@@ -104,22 +118,7 @@ module Solargraph
|
|
104
118
|
@context_pin ||= source_map.locate_named_path_pin(cursor.node_position.line, cursor.node_position.character)
|
105
119
|
end
|
106
120
|
|
107
|
-
# @return [Array<Pin::
|
108
|
-
def yielded_self_pins
|
109
|
-
return [] unless block.is_a?(Pin::Block) && block.receiver
|
110
|
-
chain = Parser.chain(block.receiver, source_map.source.filename)
|
111
|
-
receiver_pin = chain.define(api_map, context_pin, locals).first
|
112
|
-
return [] if receiver_pin.nil?
|
113
|
-
result = []
|
114
|
-
ys = receiver_pin.docstring.tag(:yieldpublic)
|
115
|
-
unless ys.nil? || ys.types.empty?
|
116
|
-
ysct = ComplexType.try_parse(*ys.types).qualify(api_map, receiver_pin.context.namespace)
|
117
|
-
result.concat api_map.get_complex_type_methods(ysct, '', false)
|
118
|
-
end
|
119
|
-
result
|
120
|
-
end
|
121
|
-
|
122
|
-
# @return [Array<Pin::KeywordParam]
|
121
|
+
# @return [Array<Pin::KeywordParam>]
|
123
122
|
def complete_keyword_parameters
|
124
123
|
return [] unless cursor.argument? && cursor.chain.links.one? && cursor.word =~ /^[a-z0-9_]*:?$/
|
125
124
|
pins = signify
|
@@ -143,7 +142,7 @@ module Solargraph
|
|
143
142
|
result
|
144
143
|
end
|
145
144
|
|
146
|
-
# @param result [
|
145
|
+
# @param result [Enumerable<Pin::Base>]
|
147
146
|
# @return [Completion]
|
148
147
|
def package_completions result
|
149
148
|
frag_start = cursor.start_of_word.to_s.downcase
|
@@ -154,6 +153,7 @@ module Solargraph
|
|
154
153
|
Completion.new(filtered, cursor.range)
|
155
154
|
end
|
156
155
|
|
156
|
+
# @return [Completion]
|
157
157
|
def tag_complete
|
158
158
|
result = []
|
159
159
|
match = source_map.code[0..cursor.offset-1].match(/[\[<, ]([a-z0-9_:]*)\z/i)
|
@@ -172,6 +172,7 @@ module Solargraph
|
|
172
172
|
package_completions(result)
|
173
173
|
end
|
174
174
|
|
175
|
+
# @return [Completion]
|
175
176
|
def code_complete
|
176
177
|
result = []
|
177
178
|
result.concat complete_keyword_parameters
|
@@ -209,16 +210,23 @@ module Solargraph
|
|
209
210
|
return package_completions(api_map.get_global_variable_pins)
|
210
211
|
end
|
211
212
|
result.concat locals
|
213
|
+
result.concat file_global_methods unless block.binder.namespace.empty?
|
212
214
|
result.concat api_map.get_constants(context_pin.context.namespace, *gates)
|
213
215
|
result.concat api_map.get_methods(block.binder.namespace, scope: block.binder.scope, visibility: [:public, :private, :protected])
|
214
216
|
result.concat api_map.get_methods('Kernel')
|
215
|
-
# result.concat ApiMap.keywords
|
216
217
|
result.concat api_map.keyword_pins.to_a
|
217
|
-
result.concat yielded_self_pins
|
218
218
|
end
|
219
219
|
end
|
220
220
|
package_completions(result)
|
221
221
|
end
|
222
|
+
|
223
|
+
# @return [Array<Pin::Base>]
|
224
|
+
def file_global_methods
|
225
|
+
return [] if cursor.word.empty?
|
226
|
+
source_map.pins.select do |pin|
|
227
|
+
pin.is_a?(Pin::Method) && pin.namespace == '' && pin.name.start_with?(cursor.word)
|
228
|
+
end
|
229
|
+
end
|
222
230
|
end
|
223
231
|
end
|
224
232
|
end
|
@@ -12,7 +12,7 @@ module Solargraph
|
|
12
12
|
|
13
13
|
private_class_method :new
|
14
14
|
|
15
|
-
|
15
|
+
DIRECTIVE_REGEXP = /(@\!method|@\!attribute|@\!visibility|@\!domain|@\!macro|@\!parse|@\!override)/.freeze
|
16
16
|
|
17
17
|
# Generate the data.
|
18
18
|
#
|
@@ -24,6 +24,8 @@ module Solargraph
|
|
24
24
|
@code = source.code
|
25
25
|
@comments = source.comments
|
26
26
|
@pins, @locals = Parser.map(source)
|
27
|
+
@pins.each { |p| p.source = :code }
|
28
|
+
@locals.each { |l| l.source = :code }
|
27
29
|
process_comment_directives
|
28
30
|
[@pins, @locals]
|
29
31
|
# rescue Exception => e
|
@@ -62,8 +64,12 @@ module Solargraph
|
|
62
64
|
pins.select{|pin| pin.is_a?(Pin::Closure) and pin.location.range.contain?(position)}.last
|
63
65
|
end
|
64
66
|
|
67
|
+
# @param source_position [Position]
|
68
|
+
# @param comment_position [Position]
|
69
|
+
# @param comment [String]
|
70
|
+
# @return [void]
|
65
71
|
def process_comment source_position, comment_position, comment
|
66
|
-
return unless comment.encode('UTF-8', invalid: :replace, replace: '?') =~
|
72
|
+
return unless comment.encode('UTF-8', invalid: :replace, replace: '?') =~ DIRECTIVE_REGEXP
|
67
73
|
cmnt = remove_inline_comment_hashes(comment)
|
68
74
|
parse = Solargraph::Source.parse_docstring(cmnt)
|
69
75
|
last_line = 0
|
@@ -77,6 +83,8 @@ module Solargraph
|
|
77
83
|
end
|
78
84
|
|
79
85
|
# @param comment [String]
|
86
|
+
# @param tag [String]
|
87
|
+
# @param start [Integer]
|
80
88
|
# @return [Integer]
|
81
89
|
def find_directive_line_number comment, tag, start
|
82
90
|
# Avoid overruning the index
|
@@ -105,7 +113,8 @@ module Solargraph
|
|
105
113
|
begin
|
106
114
|
src = Solargraph::Source.load_string("def #{directive.tag.name};end", @source.filename)
|
107
115
|
region = Parser::Region.new(source: src, closure: namespace)
|
108
|
-
|
116
|
+
method_gen_pins = Parser.process_node(src.node, region).first.select { |pin| pin.is_a?(Pin::Method) }
|
117
|
+
gen_pin = method_gen_pins.last
|
109
118
|
return if gen_pin.nil?
|
110
119
|
# Move the location to the end of the line so it gets recognized
|
111
120
|
# as originating from a comment
|
@@ -135,7 +144,7 @@ module Solargraph
|
|
135
144
|
)
|
136
145
|
end
|
137
146
|
if t.nil? || t.include?('w')
|
138
|
-
|
147
|
+
method_pin = Solargraph::Pin::Method.new(
|
139
148
|
location: location,
|
140
149
|
closure: namespace,
|
141
150
|
name: "#{directive.tag.name}=",
|
@@ -144,7 +153,8 @@ module Solargraph
|
|
144
153
|
visibility: :public,
|
145
154
|
attribute: true
|
146
155
|
)
|
147
|
-
pins.
|
156
|
+
pins.push method_pin
|
157
|
+
method_pin.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last)
|
148
158
|
if pins.last.return_type.defined?
|
149
159
|
pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', pins.last.return_type.to_s.split(', '), 'value')
|
150
160
|
end
|
@@ -196,20 +206,26 @@ module Solargraph
|
|
196
206
|
namespace.domains.concat directive.tag.types unless directive.tag.types.nil?
|
197
207
|
when 'override'
|
198
208
|
pins.push Pin::Reference::Override.new(location, directive.tag.name, docstring.tags)
|
209
|
+
when 'macro'
|
210
|
+
# @todo Handle macros
|
199
211
|
end
|
200
212
|
end
|
201
213
|
|
214
|
+
# @param line1 [Integer]
|
215
|
+
# @param line2 [Integer]
|
202
216
|
def no_empty_lines?(line1, line2)
|
203
217
|
@code.lines[line1..line2].none? { |line| line.strip.empty? }
|
204
218
|
end
|
205
219
|
|
220
|
+
# @param comment [String]
|
221
|
+
# @return [String]
|
206
222
|
def remove_inline_comment_hashes comment
|
207
223
|
ctxt = ''
|
208
224
|
num = nil
|
209
225
|
started = false
|
210
226
|
comment.lines.each { |l|
|
211
227
|
# Trim the comment and minimum leading whitespace
|
212
|
-
p = l.encode('UTF-8', invalid: :replace, replace: '?').gsub(
|
228
|
+
p = l.encode('UTF-8', invalid: :replace, replace: '?').gsub(/^#+/, '')
|
213
229
|
if num.nil? && !p.strip.empty?
|
214
230
|
num = p.index(/[^ ]/)
|
215
231
|
started = true
|
@@ -224,7 +240,7 @@ module Solargraph
|
|
224
240
|
|
225
241
|
# @return [void]
|
226
242
|
def process_comment_directives
|
227
|
-
return unless @code.encode('UTF-8', invalid: :replace, replace: '?') =~
|
243
|
+
return unless @code.encode('UTF-8', invalid: :replace, replace: '?') =~ DIRECTIVE_REGEXP
|
228
244
|
code_lines = @code.lines
|
229
245
|
@source.associated_comments.each do |line, comments|
|
230
246
|
src_pos = line ? Position.new(line, code_lines[line].to_s.chomp.index(/[^\s]/) || 0) : Position.new(code_lines.length, 0)
|
@@ -1,8 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'yard'
|
4
|
-
require '
|
5
|
-
require 'set'
|
4
|
+
require 'solargraph/yard_tags'
|
6
5
|
|
7
6
|
module Solargraph
|
8
7
|
# An index of pins and other ApiMap-related data for a Source.
|
@@ -18,7 +17,7 @@ module Solargraph
|
|
18
17
|
# @return [Array<Pin::Base>]
|
19
18
|
attr_reader :pins
|
20
19
|
|
21
|
-
# @return [Array<Pin::
|
20
|
+
# @return [Array<Pin::LocalVariable>]
|
22
21
|
attr_reader :locals
|
23
22
|
|
24
23
|
# @param source [Source]
|
@@ -30,19 +29,25 @@ module Solargraph
|
|
30
29
|
@pins = pins
|
31
30
|
@locals = locals
|
32
31
|
environ.merge Convention.for_local(self) unless filename.nil?
|
32
|
+
self.convention_pins = environ.pins
|
33
33
|
@pin_class_hash = pins.to_set.classify(&:class).transform_values(&:to_a)
|
34
34
|
@pin_select_cache = {}
|
35
35
|
end
|
36
36
|
|
37
|
+
# @param klass [Class]
|
38
|
+
# @return [Array<Pin::Base>]
|
37
39
|
def pins_by_class klass
|
38
40
|
@pin_select_cache[klass] ||= @pin_class_hash.select { |key, _| key <= klass }.values.flatten
|
39
41
|
end
|
40
42
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
# A hash representing the state of the source map's API.
|
44
|
+
#
|
45
|
+
# ApiMap#catalog uses this value to determine whether it needs to clear its
|
46
|
+
# cache.
|
47
|
+
#
|
48
|
+
# @return [Integer]
|
49
|
+
def api_hash
|
50
|
+
@api_hash ||= (pins_by_class(Pin::Constant) + pins_by_class(Pin::Namespace).select { |pin| pin.namespace.to_s > '' } + pins_by_class(Pin::Reference) + pins_by_class(Pin::Method).map(&:node)).hash
|
46
51
|
end
|
47
52
|
|
48
53
|
# @return [String]
|
@@ -65,11 +70,12 @@ module Solargraph
|
|
65
70
|
@environ ||= Environ.new
|
66
71
|
end
|
67
72
|
|
73
|
+
# all pins except Solargraph::Pin::Reference::Reference
|
68
74
|
# @return [Array<Pin::Base>]
|
69
75
|
def document_symbols
|
70
|
-
@document_symbols ||= pins.select
|
76
|
+
@document_symbols ||= (pins + convention_pins).select do |pin|
|
71
77
|
pin.path && !pin.path.empty?
|
72
|
-
|
78
|
+
end
|
73
79
|
end
|
74
80
|
|
75
81
|
# @param query [String]
|
@@ -97,10 +103,16 @@ module Solargraph
|
|
97
103
|
(pins + locals).select { |pin| pin.location == location }
|
98
104
|
end
|
99
105
|
|
106
|
+
# @param line [Integer]
|
107
|
+
# @param character [Integer]
|
108
|
+
# @return [Pin::Method,Pin::Namespace]
|
100
109
|
def locate_named_path_pin line, character
|
101
110
|
_locate_pin line, character, Pin::Namespace, Pin::Method
|
102
111
|
end
|
103
112
|
|
113
|
+
# @param line [Integer]
|
114
|
+
# @param character [Integer]
|
115
|
+
# @return [Pin::Namespace,Pin::Method,Pin::Block]
|
104
116
|
def locate_block_pin line, character
|
105
117
|
_locate_pin line, character, Pin::Namespace, Pin::Method, Pin::Block
|
106
118
|
end
|
@@ -159,10 +171,23 @@ module Solargraph
|
|
159
171
|
|
160
172
|
private
|
161
173
|
|
174
|
+
# @return [Array<Pin::Base>]
|
175
|
+
def convention_pins
|
176
|
+
@convention_pins || []
|
177
|
+
end
|
178
|
+
|
179
|
+
# @param pins [Array<Pin::Base>]
|
180
|
+
# @return [Array<Pin::Base>]
|
181
|
+
def convention_pins=(pins)
|
182
|
+
# unmemoizing the document_symbols in case it was called from any of convnetions
|
183
|
+
@document_symbols = nil
|
184
|
+
@convention_pins = pins
|
185
|
+
end
|
186
|
+
|
162
187
|
# @param line [Integer]
|
163
188
|
# @param character [Integer]
|
164
189
|
# @param klasses [Array<Class>]
|
165
|
-
# @return [Pin::Base]
|
190
|
+
# @return [Pin::Base, nil]
|
166
191
|
def _locate_pin line, character, *klasses
|
167
192
|
position = Position.new(line, character)
|
168
193
|
found = nil
|
@@ -51,8 +51,13 @@ module Solargraph
|
|
51
51
|
# @return [Boolean]
|
52
52
|
def any_types_match? api_map, expected, inferred
|
53
53
|
return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
|
54
|
+
# walk through the union expected type and see if any members
|
55
|
+
# of the union match the inferred type
|
54
56
|
expected.each do |exp|
|
55
57
|
next if exp.duck_type?
|
58
|
+
# @todo: there should be a level of typechecking where all
|
59
|
+
# unique types in the inferred must match one of the
|
60
|
+
# expected unique types
|
56
61
|
inferred.each do |inf|
|
57
62
|
# return true if exp == inf || api_map.super_and_sub?(fuzz(inf), fuzz(exp))
|
58
63
|
return true if exp == inf || either_way?(api_map, inf, exp)
|
@@ -103,9 +108,12 @@ module Solargraph
|
|
103
108
|
# @param cls2 [ComplexType::UniqueType]
|
104
109
|
# @return [Boolean]
|
105
110
|
def either_way?(api_map, cls1, cls2)
|
106
|
-
|
107
|
-
|
111
|
+
# @todo there should be a level of typechecking which uses the
|
112
|
+
# full tag with parameters to determine compatibility
|
113
|
+
f1 = cls1.name
|
114
|
+
f2 = cls2.name
|
108
115
|
api_map.type_include?(f1, f2) || api_map.super_and_sub?(f1, f2) || api_map.super_and_sub?(f2, f1)
|
116
|
+
# api_map.type_include?(f1, f2) || api_map.super_and_sub?(f1, f2) || api_map.super_and_sub?(f2, f1)
|
109
117
|
end
|
110
118
|
end
|
111
119
|
end
|