solargraph 0.17.4 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/solargraph.rb +16 -12
- data/lib/solargraph/api_map.rb +516 -588
- data/lib/solargraph/api_map/completion.rb +16 -0
- data/lib/solargraph/api_map/source_to_yard.rb +2 -2
- data/lib/solargraph/language_server.rb +12 -0
- data/lib/solargraph/language_server/completion_item_kinds.rb +31 -0
- data/lib/solargraph/language_server/error_codes.rb +16 -0
- data/lib/solargraph/language_server/host.rb +305 -0
- data/lib/solargraph/language_server/message.rb +70 -0
- data/lib/solargraph/language_server/message/base.rb +64 -0
- data/lib/solargraph/language_server/message/cancel_request.rb +11 -0
- data/lib/solargraph/language_server/message/client.rb +5 -0
- data/lib/solargraph/language_server/message/client/register_capability.rb +13 -0
- data/lib/solargraph/language_server/message/completion_item.rb +9 -0
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +23 -0
- data/lib/solargraph/language_server/message/exit_notification.rb +12 -0
- data/lib/solargraph/language_server/message/extended.rb +15 -0
- data/lib/solargraph/language_server/message/extended/document.rb +18 -0
- data/lib/solargraph/language_server/message/extended/search.rb +18 -0
- data/lib/solargraph/language_server/message/initialize.rb +39 -0
- data/lib/solargraph/language_server/message/initialized.rb +10 -0
- data/lib/solargraph/language_server/message/method_not_found.rb +14 -0
- data/lib/solargraph/language_server/message/method_not_implemented.rb +12 -0
- data/lib/solargraph/language_server/message/shutdown.rb +11 -0
- data/lib/solargraph/language_server/message/text_document.rb +21 -0
- data/lib/solargraph/language_server/message/text_document/base.rb +17 -0
- data/lib/solargraph/language_server/message/text_document/completion.rb +69 -0
- data/lib/solargraph/language_server/message/text_document/definition.rb +38 -0
- data/lib/solargraph/language_server/message/text_document/did_change.rb +15 -0
- data/lib/solargraph/language_server/message/text_document/did_close.rb +12 -0
- data/lib/solargraph/language_server/message/text_document/did_open.rb +13 -0
- data/lib/solargraph/language_server/message/text_document/did_save.rb +15 -0
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +31 -0
- data/lib/solargraph/language_server/message/text_document/formatting.rb +36 -0
- data/lib/solargraph/language_server/message/text_document/hover.rb +19 -0
- data/lib/solargraph/language_server/message/text_document/on_type_formatting.rb +29 -0
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +23 -0
- data/lib/solargraph/language_server/message/workspace.rb +11 -0
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +9 -0
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +30 -0
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +31 -0
- data/lib/solargraph/language_server/symbol_kinds.rb +32 -0
- data/lib/solargraph/language_server/transport.rb +7 -0
- data/lib/solargraph/language_server/transport/socket.rb +66 -0
- data/lib/solargraph/language_server/uri_helpers.rb +21 -0
- data/lib/solargraph/library.rb +225 -0
- data/lib/solargraph/live_map.rb +1 -1
- data/lib/solargraph/page.rb +61 -0
- data/lib/solargraph/pin.rb +7 -0
- data/lib/solargraph/pin/attribute.rb +9 -0
- data/lib/solargraph/pin/base.rb +76 -6
- data/lib/solargraph/pin/base_variable.rb +29 -7
- data/lib/solargraph/pin/block_parameter.rb +53 -0
- data/lib/solargraph/pin/constant.rb +6 -2
- data/lib/solargraph/pin/conversions.rb +65 -0
- data/lib/solargraph/pin/directed/attribute.rb +4 -0
- data/lib/solargraph/pin/directed/method.rb +6 -1
- data/lib/solargraph/pin/helper.rb +35 -0
- data/lib/solargraph/pin/keyword.rb +22 -0
- data/lib/solargraph/pin/local_variable.rb +0 -1
- data/lib/solargraph/pin/method.rb +55 -2
- data/lib/solargraph/pin/method_parameter.rb +19 -0
- data/lib/solargraph/pin/namespace.rb +7 -2
- data/lib/solargraph/pin/parameter.rb +23 -0
- data/lib/solargraph/pin/plugin/method.rb +3 -2
- data/lib/solargraph/pin/yard_object.rb +101 -0
- data/lib/solargraph/server.rb +82 -135
- data/lib/solargraph/shell.rb +20 -1
- data/lib/solargraph/source.rb +709 -0
- data/lib/solargraph/source/flawed_builder.rb +10 -0
- data/lib/solargraph/source/fragment.rb +319 -0
- data/lib/solargraph/source/position.rb +26 -0
- data/lib/solargraph/source/range.rb +39 -0
- data/lib/solargraph/suggestion.rb +29 -4
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace.rb +105 -0
- data/lib/solargraph/{api_map → workspace}/config.rb +1 -1
- data/lib/solargraph/yard_map.rb +59 -37
- metadata +168 -5
- data/lib/solargraph/api_map/source.rb +0 -470
- data/lib/solargraph/code_map.rb +0 -868
@@ -0,0 +1,13 @@
|
|
1
|
+
module Solargraph
|
2
|
+
module LanguageServer
|
3
|
+
module Message
|
4
|
+
module TextDocument
|
5
|
+
class DidOpen < Base
|
6
|
+
def process
|
7
|
+
host.open params['textDocument']['uri'], params['textDocument']['text'], params['textDocument']['version']
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Solargraph
|
2
|
+
module LanguageServer
|
3
|
+
module Message
|
4
|
+
module TextDocument
|
5
|
+
class DidSave < Base
|
6
|
+
def process
|
7
|
+
STDERR.puts "TODO: TextDocument saved"
|
8
|
+
# host.open params['textDocument']
|
9
|
+
# publish_diagnostics
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class Solargraph::LanguageServer::Message::TextDocument::DocumentSymbol < Solargraph::LanguageServer::Message::Base
|
2
|
+
include Solargraph::LanguageServer::UriHelpers
|
3
|
+
|
4
|
+
def process
|
5
|
+
pins = host.library.file_symbols(uri_to_file(params['textDocument']['uri']))
|
6
|
+
info = pins.map do |pin|
|
7
|
+
parts = pin.location.split(':')
|
8
|
+
char = parts.pop.to_i
|
9
|
+
line = parts.pop.to_i
|
10
|
+
filename = parts.join(':')
|
11
|
+
{
|
12
|
+
name: pin.path,
|
13
|
+
kind: Solargraph::LanguageServer::SymbolKinds::NAMESPACE,
|
14
|
+
location: {
|
15
|
+
uri: file_to_uri(filename),
|
16
|
+
range: {
|
17
|
+
start: {
|
18
|
+
line: line,
|
19
|
+
character: char
|
20
|
+
},
|
21
|
+
end: {
|
22
|
+
line: line,
|
23
|
+
character: char
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
set_result info
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
module LanguageServer
|
5
|
+
module Message
|
6
|
+
module TextDocument
|
7
|
+
class Formatting < Base
|
8
|
+
def process
|
9
|
+
filename = uri_to_file(params['textDocument']['uri'])
|
10
|
+
original = host.read_text(params['textDocument']['uri'])
|
11
|
+
cmd = "rubocop -a -f fi -s #{Shellwords.escape(filename)}"
|
12
|
+
o, e, s = Open3.capture3(cmd, stdin_data: original)
|
13
|
+
formatted = o.lines[2..-1].join
|
14
|
+
set_result(
|
15
|
+
[
|
16
|
+
{
|
17
|
+
range: {
|
18
|
+
start: {
|
19
|
+
line: 0,
|
20
|
+
character: 0
|
21
|
+
},
|
22
|
+
end: {
|
23
|
+
line: original.lines.length,
|
24
|
+
character: 0
|
25
|
+
}
|
26
|
+
},
|
27
|
+
newText: formatted
|
28
|
+
}
|
29
|
+
]
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module Solargraph::LanguageServer::Message::TextDocument
|
4
|
+
class Hover < Base
|
5
|
+
def process
|
6
|
+
filename = uri_to_file(params['textDocument']['uri'])
|
7
|
+
line = params['position']['line']
|
8
|
+
col = params['position']['character']
|
9
|
+
suggestions = host.library.definitions_at(filename, line, col)
|
10
|
+
contents = suggestions.map(&:hover)
|
11
|
+
set_result(
|
12
|
+
contents: {
|
13
|
+
kind: 'markdown',
|
14
|
+
value: contents.join("\n\n")
|
15
|
+
}
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Solargraph
|
2
|
+
module LanguageServer
|
3
|
+
module Message
|
4
|
+
module TextDocument
|
5
|
+
class OnTypeFormatting < Base
|
6
|
+
def process
|
7
|
+
src = host.library.checkout(uri_to_file(params['textDocument']['uri']))
|
8
|
+
offset = src.get_offset(params['position']['line'], params['position']['character'])
|
9
|
+
if src.string_at?(offset-1) and params['ch'] == '{' and src.code[offset-2,2] == '#{'
|
10
|
+
set_result(
|
11
|
+
[
|
12
|
+
{
|
13
|
+
range: {
|
14
|
+
start: params['position'],
|
15
|
+
end: params['position']
|
16
|
+
},
|
17
|
+
newText: '}'
|
18
|
+
}
|
19
|
+
]
|
20
|
+
)
|
21
|
+
else
|
22
|
+
set_result []
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Solargraph
|
2
|
+
module LanguageServer
|
3
|
+
module Message
|
4
|
+
module TextDocument
|
5
|
+
class SignatureHelp < TextDocument::Base
|
6
|
+
def process
|
7
|
+
filename = uri_to_file(params['textDocument']['uri'])
|
8
|
+
line = params['position']['line']
|
9
|
+
col = params['position']['character']
|
10
|
+
suggestions = host.library.signatures_at(filename, line, col)
|
11
|
+
info = []
|
12
|
+
suggestions.each do |s|
|
13
|
+
info.push s.signature_help
|
14
|
+
end
|
15
|
+
set_result({
|
16
|
+
signatures: info
|
17
|
+
})
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Solargraph
|
2
|
+
module LanguageServer
|
3
|
+
module Message
|
4
|
+
module Workspace
|
5
|
+
autoload :DidChangeWatchedFiles, 'solargraph/language_server/message/workspace/did_change_watched_files'
|
6
|
+
autoload :WorkspaceSymbol, 'solargraph/language_server/message/workspace/workspace_symbol'
|
7
|
+
autoload :DidChangeConfiguration, 'solargraph/language_server/message/workspace/did_change_configuration'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module Solargraph::LanguageServer::Message::Workspace
|
4
|
+
class DidChangeWatchedFiles < Solargraph::LanguageServer::Message::Base
|
5
|
+
CREATED = 1
|
6
|
+
CHANGED = 2
|
7
|
+
DELETED = 3
|
8
|
+
|
9
|
+
include Solargraph::LanguageServer::UriHelpers
|
10
|
+
|
11
|
+
def process
|
12
|
+
params['changes'].each do |change|
|
13
|
+
if change['type'] == CREATED
|
14
|
+
STDERR.puts "TODO: Need to handle a created file?"
|
15
|
+
# host.create change['uri']
|
16
|
+
elsif change['type'] == CHANGED
|
17
|
+
# @todo Should this check if the source is already loaded in the source?
|
18
|
+
# Possibly out of sync with the disk?
|
19
|
+
# host.workspace.handle_changed filename
|
20
|
+
# host.api_map.refresh
|
21
|
+
STDERR.puts "TODO: Workspace changed"
|
22
|
+
elsif change['type'] == DELETED
|
23
|
+
host.delete change['uri']
|
24
|
+
else
|
25
|
+
# @todo Handle error
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class Solargraph::LanguageServer::Message::Workspace::WorkspaceSymbol < Solargraph::LanguageServer::Message::Base
|
2
|
+
include Solargraph::LanguageServer::UriHelpers
|
3
|
+
|
4
|
+
def process
|
5
|
+
pins = host.library.query_symbols(params['query'])
|
6
|
+
info = pins.map do |pin|
|
7
|
+
parts = pin.location.split(':')
|
8
|
+
char = parts.pop.to_i
|
9
|
+
line = parts.pop.to_i
|
10
|
+
filename = parts.join(':')
|
11
|
+
{
|
12
|
+
name: pin.path,
|
13
|
+
kind: Solargraph::LanguageServer::SymbolKinds::NAMESPACE,
|
14
|
+
location: {
|
15
|
+
uri: file_to_uri(filename),
|
16
|
+
range: {
|
17
|
+
start: {
|
18
|
+
line: line,
|
19
|
+
character: char
|
20
|
+
},
|
21
|
+
end: {
|
22
|
+
line: line,
|
23
|
+
character: char
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
set_result info
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Solargraph
|
2
|
+
module LanguageServer
|
3
|
+
module SymbolKinds
|
4
|
+
FILE = 1;
|
5
|
+
MODULE = 2;
|
6
|
+
NAMESPACE = 3;
|
7
|
+
PACKAGE = 4;
|
8
|
+
CLASS = 5;
|
9
|
+
METHOD = 6;
|
10
|
+
PROPERTY = 7;
|
11
|
+
FIELD = 8;
|
12
|
+
CONSTRUCTOR = 9;
|
13
|
+
ENUM = 10;
|
14
|
+
INTERFACE = 11;
|
15
|
+
FUNCTION = 12;
|
16
|
+
VARIABLE = 13;
|
17
|
+
CONSTANT = 14;
|
18
|
+
STRING = 15;
|
19
|
+
NUMBER = 16;
|
20
|
+
BOOLEAN = 17;
|
21
|
+
ARRAY = 18;
|
22
|
+
OBJECT = 19;
|
23
|
+
KEY = 20;
|
24
|
+
NULL = 21;
|
25
|
+
ENUM_MEMBER = 22;
|
26
|
+
STRUCT = 23;
|
27
|
+
EVENT = 24;
|
28
|
+
OPERATOR = 25;
|
29
|
+
TYPE_PARAMETER = 26;
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
module LanguageServer
|
5
|
+
module Transport
|
6
|
+
# A module for running language servers in EventMachine.
|
7
|
+
#
|
8
|
+
module Socket
|
9
|
+
def post_init
|
10
|
+
@in_header = true
|
11
|
+
@content_length = 0
|
12
|
+
@buffer = ''
|
13
|
+
@host = Solargraph::LanguageServer::Host.new
|
14
|
+
EventMachine.add_periodic_timer 0.1 do
|
15
|
+
tmp = @host.flush
|
16
|
+
send_data tmp unless tmp.empty?
|
17
|
+
EventMachine.stop if @host.stopped?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def process request
|
22
|
+
Thread.new do
|
23
|
+
message = @host.start(request)
|
24
|
+
message.send
|
25
|
+
tmp = @host.flush
|
26
|
+
send_data tmp unless tmp.empty?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# @param data [String]
|
31
|
+
def receive_data data
|
32
|
+
data.each_char do |char|
|
33
|
+
@buffer.concat char
|
34
|
+
if @in_header
|
35
|
+
if @buffer.end_with?("\r\n\r\n")
|
36
|
+
@in_header = false
|
37
|
+
@buffer.each_line do |line|
|
38
|
+
parts = line.split(':').map(&:strip)
|
39
|
+
if parts[0] == 'Content-Length'
|
40
|
+
@content_length = parts[1].to_i
|
41
|
+
break
|
42
|
+
end
|
43
|
+
end
|
44
|
+
@buffer.clear
|
45
|
+
end
|
46
|
+
else
|
47
|
+
if @buffer.bytesize == @content_length
|
48
|
+
begin
|
49
|
+
process JSON.parse(@buffer)
|
50
|
+
rescue Exception => e
|
51
|
+
STDERR.puts "Failed to parse request: #{e.message}"
|
52
|
+
STDERR.puts e.backtrace.inspect
|
53
|
+
STDERR.puts "Buffer: #{@buffer}"
|
54
|
+
ensure
|
55
|
+
@buffer.clear
|
56
|
+
@in_header = true
|
57
|
+
@content_length = 0
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Solargraph
|
2
|
+
module LanguageServer
|
3
|
+
module UriHelpers
|
4
|
+
# Convert a file URI to a path.
|
5
|
+
#
|
6
|
+
# @param uri [String]
|
7
|
+
# @return [String]
|
8
|
+
def uri_to_file uri
|
9
|
+
URI.decode(uri).sub(/^file\:\/\//, '').sub(/^\/([a-z]\:)/i, '\1')
|
10
|
+
end
|
11
|
+
|
12
|
+
# Convert a file path to a URI.
|
13
|
+
#
|
14
|
+
# @param file [String]
|
15
|
+
# @return [String]
|
16
|
+
def file_to_uri file
|
17
|
+
"file://#{URI.encode(file.gsub(/^([a-z]\:)/i, '/\1'))}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,225 @@
|
|
1
|
+
module Solargraph
|
2
|
+
# A library handles coordination between a Workspace and an ApiMap.
|
3
|
+
#
|
4
|
+
class Library
|
5
|
+
class FileNotFoundError < Exception; end
|
6
|
+
|
7
|
+
# @param workspace [Solargraph::Workspace]
|
8
|
+
def initialize workspace = Solargraph::Workspace.new(nil)
|
9
|
+
@workspace = workspace
|
10
|
+
api_map
|
11
|
+
end
|
12
|
+
|
13
|
+
# Open a file in the library. Opening a file will make it available for
|
14
|
+
# checkout and merge it into the workspace if applicable.
|
15
|
+
#
|
16
|
+
# @param filename [String]
|
17
|
+
# @param text [String]
|
18
|
+
# @param version [Integer]
|
19
|
+
def open filename, text, version
|
20
|
+
source = Solargraph::Source.load_string(text, filename)
|
21
|
+
source.version = version
|
22
|
+
source_hash[filename] = source
|
23
|
+
workspace.merge source
|
24
|
+
api_map.refresh
|
25
|
+
end
|
26
|
+
|
27
|
+
# Create a file source to be added to the workspace. The source is ignored
|
28
|
+
# if the workspace is not configured to include the file.
|
29
|
+
#
|
30
|
+
# @param filename [String]
|
31
|
+
# @param text [String] The contents of the file
|
32
|
+
# @return [Boolean] True if the file was added to the workspace.
|
33
|
+
def create filename, text
|
34
|
+
result = false
|
35
|
+
if workspace.would_merge?(filename)
|
36
|
+
source = Solargraph::Source.load_string(text, filename)
|
37
|
+
if workspace.merge(source)
|
38
|
+
source_hash[filename] = source
|
39
|
+
api_map.refresh
|
40
|
+
result = true
|
41
|
+
end
|
42
|
+
end
|
43
|
+
result
|
44
|
+
end
|
45
|
+
|
46
|
+
# Delete a file from the library. Deleting a file will make it unavailable
|
47
|
+
# for checkout and optionally remove it from the workspace unless the
|
48
|
+
# workspace configuration determines that it should still exist.
|
49
|
+
#
|
50
|
+
# @param filename [String]
|
51
|
+
def delete filename
|
52
|
+
source = source_hash[filename]
|
53
|
+
return if source.nil?
|
54
|
+
source_hash.delete filename
|
55
|
+
workspace.remove source
|
56
|
+
api_map.refresh
|
57
|
+
end
|
58
|
+
|
59
|
+
# Close a file in the library. Closing a file will make it unavailable for
|
60
|
+
# checkout although it may still exist in the workspace.
|
61
|
+
#
|
62
|
+
# @param filename [String]
|
63
|
+
def close filename
|
64
|
+
source_hash.delete filename
|
65
|
+
end
|
66
|
+
|
67
|
+
# Get completion suggestions at the specified file and location.
|
68
|
+
#
|
69
|
+
# @param filename [String] The file to analyze
|
70
|
+
# @param line [Integer] The zero-based line number
|
71
|
+
# @param column [Integer] The zero-based column number
|
72
|
+
# @return [ApiMap::Completion]
|
73
|
+
def completions_at filename, line, column
|
74
|
+
# @type [Solargraph::Source]
|
75
|
+
source = nil
|
76
|
+
source = read(filename)
|
77
|
+
fragment = Solargraph::Source::Fragment.new(source, source.get_offset(line, column))
|
78
|
+
api_map.complete(fragment)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Get definition suggestions for the expression at the specified file and
|
82
|
+
# location.
|
83
|
+
#
|
84
|
+
# @param filename [String] The file to analyze
|
85
|
+
# @param line [Integer] The zero-based line number
|
86
|
+
# @param column [Integer] The zero-based column number
|
87
|
+
# @return [Array<Solargraph::Pin::Base>]
|
88
|
+
def definitions_at filename, line, column
|
89
|
+
source = read(filename)
|
90
|
+
fragment = Solargraph::Source::Fragment.new(source, source.get_offset(line, column))
|
91
|
+
result = api_map.define(fragment)
|
92
|
+
result
|
93
|
+
end
|
94
|
+
|
95
|
+
# Get signature suggestions for the method at the specified file and
|
96
|
+
# location.
|
97
|
+
#
|
98
|
+
# @param filename [String] The file to analyze
|
99
|
+
# @param line [Integer] The zero-based line number
|
100
|
+
# @param column [Integer] The zero-based column number
|
101
|
+
# @return [Array<Solargraph::Pin::Base>]
|
102
|
+
def signatures_at filename, line, column
|
103
|
+
source = read(filename)
|
104
|
+
fragment = Solargraph::Source::Fragment.new(source, signature_index_before(source, source.get_offset(line, column)))
|
105
|
+
api_map.define(fragment).select{|pin| pin.method?}
|
106
|
+
end
|
107
|
+
|
108
|
+
# Get the pin at the specified location or nil if the pin does not exist.
|
109
|
+
#
|
110
|
+
# @return [Solargraph::Pin::Base]
|
111
|
+
def locate_pin location
|
112
|
+
api_map.locate_pin location
|
113
|
+
end
|
114
|
+
|
115
|
+
# Get an array of pins that match a path.
|
116
|
+
#
|
117
|
+
# @param path [String]
|
118
|
+
# @return [Array<Solargraph::Pin::Base>]
|
119
|
+
def get_path_pins path
|
120
|
+
api_map.get_path_suggestions(path)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Check a file out of the library. If the file is not part of the
|
124
|
+
# workspace, the ApiMap will virtualize it for mapping purposes. If
|
125
|
+
# filename is nil, any source currently checked out of the library
|
126
|
+
# will be removed from the ApiMap. Only one file can be checked out
|
127
|
+
# (virtualized) at a time.
|
128
|
+
#
|
129
|
+
# @raise [FileNotFoundError] if the file is not in the library.
|
130
|
+
#
|
131
|
+
# @param filename [String]
|
132
|
+
# @return [Source]
|
133
|
+
def checkout filename
|
134
|
+
if filename.nil?
|
135
|
+
api_map.virtualize nil
|
136
|
+
nil
|
137
|
+
else
|
138
|
+
read filename
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def refresh force = false
|
143
|
+
api_map.refresh force
|
144
|
+
end
|
145
|
+
|
146
|
+
def document query
|
147
|
+
api_map.document query
|
148
|
+
end
|
149
|
+
|
150
|
+
def search query
|
151
|
+
api_map.search query
|
152
|
+
end
|
153
|
+
|
154
|
+
def query_symbols query
|
155
|
+
api_map.query_symbols query
|
156
|
+
end
|
157
|
+
|
158
|
+
def file_symbols filename
|
159
|
+
read(filename).all_symbols
|
160
|
+
end
|
161
|
+
|
162
|
+
def path_pins path
|
163
|
+
api_map.get_path_suggestions(path)
|
164
|
+
end
|
165
|
+
|
166
|
+
# Get the current text of a file in the library.
|
167
|
+
#
|
168
|
+
# @param filename [String]
|
169
|
+
# @return [String]
|
170
|
+
def read_text filename
|
171
|
+
source = read(filename)
|
172
|
+
source.code
|
173
|
+
end
|
174
|
+
|
175
|
+
# Create a library from a directory.
|
176
|
+
#
|
177
|
+
# @param directory [String] The path to be used for the workspace
|
178
|
+
# @return [Solargraph::Library]
|
179
|
+
def self.load directory
|
180
|
+
Solargraph::Library.new(Solargraph::Workspace.new(directory))
|
181
|
+
end
|
182
|
+
|
183
|
+
private
|
184
|
+
|
185
|
+
# @return [Hash<String, Solargraph::Source>]
|
186
|
+
def source_hash
|
187
|
+
@source_hash ||= {}
|
188
|
+
end
|
189
|
+
|
190
|
+
# @return [Solargraph::ApiMap]
|
191
|
+
def api_map
|
192
|
+
@api_map ||= Solargraph::ApiMap.new(workspace)
|
193
|
+
end
|
194
|
+
|
195
|
+
# @return [Solargraph::Workspace]
|
196
|
+
def workspace
|
197
|
+
@workspace
|
198
|
+
end
|
199
|
+
|
200
|
+
# @return [Solargraph::Source]
|
201
|
+
def read filename
|
202
|
+
source = source_hash[filename]
|
203
|
+
raise FileNotFoundError, "Source not found for #{filename}" if source.nil?
|
204
|
+
api_map.virtualize source
|
205
|
+
source
|
206
|
+
end
|
207
|
+
|
208
|
+
def signature_index_before source, index
|
209
|
+
open_parens = 0
|
210
|
+
cursor = index - 1
|
211
|
+
while cursor >= 0
|
212
|
+
break if cursor < 0
|
213
|
+
if source.code[cursor] == ')'
|
214
|
+
open_parens -= 1
|
215
|
+
elsif source.code[cursor] == '('
|
216
|
+
open_parens += 1
|
217
|
+
end
|
218
|
+
break if open_parens == 1
|
219
|
+
cursor -= 1
|
220
|
+
end
|
221
|
+
cursor = 0 if cursor < 0
|
222
|
+
cursor
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|