rucoa 0.2.0 → 0.5.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/.rubocop.yml +6 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +11 -2
- data/README.md +39 -6
- data/data/definitions_ruby_3_1 +0 -0
- data/images/diagnostics.gif +0 -0
- data/images/document-formatting.gif +0 -0
- data/images/document-symbol.gif +0 -0
- data/images/selection-ranges.gif +0 -0
- data/lib/rucoa/cli.rb +2 -2
- data/lib/rucoa/configuration.rb +97 -0
- data/lib/rucoa/definition_archiver.rb +29 -0
- data/lib/rucoa/definition_builders/rbs_constant_definition_builder.rb +44 -0
- data/lib/rucoa/definition_builders/rbs_method_definition_builder.rb +106 -0
- data/lib/rucoa/definition_builders/yard_method_definition_builder.rb +191 -0
- data/lib/rucoa/definition_builders.rb +9 -0
- data/lib/rucoa/definition_store.rb +63 -0
- data/lib/rucoa/definitions/base.rb +12 -0
- data/lib/rucoa/definitions/constant_definition.rb +51 -0
- data/lib/rucoa/definitions/method_definition.rb +126 -0
- data/lib/rucoa/definitions/method_parameter_definition.rb +30 -0
- data/lib/rucoa/definitions.rb +9 -0
- data/lib/rucoa/handler_concerns/configuration_requestable.rb +35 -0
- data/lib/rucoa/handler_concerns/diagnostics_publishable.rb +172 -0
- data/lib/rucoa/handler_concerns.rb +8 -0
- data/lib/rucoa/handlers/base.rb +69 -0
- data/lib/rucoa/handlers/exit_handler.rb +11 -0
- data/lib/rucoa/handlers/initialize_handler.rb +29 -0
- data/lib/rucoa/handlers/initialized_handler.rb +23 -0
- data/lib/rucoa/handlers/shutdown_handler.rb +12 -0
- data/lib/rucoa/handlers/text_document_code_action_handler.rb +104 -0
- data/lib/rucoa/handlers/text_document_did_change_handler.rb +12 -0
- data/lib/rucoa/handlers/text_document_did_open_handler.rb +38 -0
- data/lib/rucoa/handlers/text_document_document_symbol_handler.rb +241 -0
- data/lib/rucoa/handlers/text_document_formatting_handler.rb +64 -0
- data/lib/rucoa/handlers/text_document_range_formatting_handler.rb +76 -0
- data/lib/rucoa/handlers/text_document_selection_range_handler.rb +141 -0
- data/lib/rucoa/handlers/text_document_signature_help_handler.rb +68 -0
- data/lib/rucoa/handlers/workspace_did_change_configuration_handler.rb +13 -0
- data/lib/rucoa/handlers.rb +20 -0
- data/lib/rucoa/message_reader.rb +3 -1
- data/lib/rucoa/message_writer.rb +3 -0
- data/lib/rucoa/node_concerns/name_full_qualifiable.rb +20 -0
- data/lib/rucoa/node_concerns.rb +7 -0
- data/lib/rucoa/node_inspector.rb +109 -0
- data/lib/rucoa/nodes/base.rb +43 -0
- data/lib/rucoa/nodes/casgn_node.rb +14 -0
- data/lib/rucoa/nodes/class_node.rb +8 -0
- data/lib/rucoa/nodes/const_node.rb +12 -0
- data/lib/rucoa/nodes/def_node.rb +71 -0
- data/lib/rucoa/nodes/defs_node.rb +12 -0
- data/lib/rucoa/nodes/lvar_node.rb +25 -0
- data/lib/rucoa/nodes/module_node.rb +21 -0
- data/lib/rucoa/nodes/sclass_node.rb +8 -0
- data/lib/rucoa/nodes/send_node.rb +60 -0
- data/lib/rucoa/nodes/str_node.rb +4 -0
- data/lib/rucoa/nodes/sym_node.rb +12 -0
- data/lib/rucoa/nodes.rb +10 -0
- data/lib/rucoa/parser_builder.rb +20 -10
- data/lib/rucoa/range.rb +89 -13
- data/lib/rucoa/rbs_document_loader.rb +43 -0
- data/lib/rucoa/rubocop_autocorrector.rb +1 -1
- data/lib/rucoa/rubocop_configuration_checker.rb +42 -0
- data/lib/rucoa/rubocop_investigator.rb +1 -1
- data/lib/rucoa/server.rb +96 -122
- data/lib/rucoa/source.rb +56 -6
- data/lib/rucoa/source_store.rb +11 -9
- data/lib/rucoa/types/method_type.rb +23 -0
- data/lib/rucoa/types.rb +7 -0
- data/lib/rucoa/version.rb +1 -1
- data/lib/rucoa/yard_glob_document_loader.rb +47 -0
- data/lib/rucoa/yard_string_document_loader.rb +70 -0
- data/lib/rucoa.rb +14 -4
- data/rucoa.gemspec +1 -0
- metadata +70 -6
- data/lib/rucoa/code_action_provider.rb +0 -102
- data/lib/rucoa/diagnostic_provider.rb +0 -159
- data/lib/rucoa/formatting_provider.rb +0 -52
- data/lib/rucoa/selection_range_provider.rb +0 -97
data/lib/rucoa/range.rb
CHANGED
@@ -11,19 +11,106 @@ module Rucoa
|
|
11
11
|
Position.from_parser_range_ending(range)
|
12
12
|
)
|
13
13
|
end
|
14
|
+
|
15
|
+
# @param hash [Hash]
|
16
|
+
# @return [Rucoa::Range]
|
17
|
+
def from_vscode_range(hash)
|
18
|
+
new(
|
19
|
+
Position.from_vscode_position(hash['start']),
|
20
|
+
Position.from_vscode_position(hash['end'])
|
21
|
+
)
|
22
|
+
end
|
14
23
|
end
|
15
24
|
|
25
|
+
# @return [Rucoa::Position]
|
26
|
+
attr_reader :beginning
|
27
|
+
|
28
|
+
# @return [Rucoa::Position]
|
29
|
+
attr_reader :ending
|
30
|
+
|
16
31
|
# @param beginning [Rucoa::Position]
|
17
32
|
# @param ending [Ruoca::Position]
|
18
|
-
|
33
|
+
# @param including_ending [Boolean]
|
34
|
+
def initialize(beginning, ending, including_ending: true)
|
19
35
|
@beginning = beginning
|
20
36
|
@ending = ending
|
37
|
+
@including_ending = including_ending
|
38
|
+
end
|
39
|
+
|
40
|
+
# @param range [Rucoa::Range]
|
41
|
+
# @return [Boolean]
|
42
|
+
# @example returns true when the range is contained in self
|
43
|
+
# range = Rucoa::Range.new(
|
44
|
+
# Rucoa::Position.new(
|
45
|
+
# column: 0,
|
46
|
+
# line: 0
|
47
|
+
# ),
|
48
|
+
# Rucoa::Position.new(
|
49
|
+
# column: 0,
|
50
|
+
# line: 2
|
51
|
+
# )
|
52
|
+
# )
|
53
|
+
# expect(range).to contain(
|
54
|
+
# Rucoa::Range.new(
|
55
|
+
# Rucoa::Position.new(
|
56
|
+
# column: 0,
|
57
|
+
# line: 0
|
58
|
+
# ),
|
59
|
+
# Rucoa::Position.new(
|
60
|
+
# column: 0,
|
61
|
+
# line: 0
|
62
|
+
# )
|
63
|
+
# )
|
64
|
+
# )
|
65
|
+
def contain?(range)
|
66
|
+
include?(range.beginning) && include?(range.ending)
|
21
67
|
end
|
22
68
|
|
23
69
|
# @param position [Rucoa::Position]
|
24
70
|
# @return [Boolean]
|
71
|
+
# @example returns true when the position is included in self
|
72
|
+
# range = Rucoa::Range.new(
|
73
|
+
# Rucoa::Position.new(
|
74
|
+
# column: 0,
|
75
|
+
# line: 0
|
76
|
+
# ),
|
77
|
+
# Rucoa::Position.new(
|
78
|
+
# column: 0,
|
79
|
+
# line: 2
|
80
|
+
# )
|
81
|
+
# )
|
82
|
+
# expect(range).to include(
|
83
|
+
# Rucoa::Position.new(
|
84
|
+
# column: 0,
|
85
|
+
# line: 0
|
86
|
+
# )
|
87
|
+
# )
|
88
|
+
# expect(range).to include(
|
89
|
+
# Rucoa::Position.new(
|
90
|
+
# column: 0,
|
91
|
+
# line: 1
|
92
|
+
# )
|
93
|
+
# )
|
94
|
+
# expect(range).to include(
|
95
|
+
# Rucoa::Position.new(
|
96
|
+
# column: 0,
|
97
|
+
# line: 2
|
98
|
+
# )
|
99
|
+
# )
|
100
|
+
# expect(range).not_to include(
|
101
|
+
# Rucoa::Position.new(
|
102
|
+
# column: 0,
|
103
|
+
# line: 3
|
104
|
+
# )
|
105
|
+
# )
|
25
106
|
def include?(position)
|
26
|
-
|
107
|
+
return false if position.line > @ending.line
|
108
|
+
return false if position.line < @beginning.line
|
109
|
+
return false if position.column < @beginning.column
|
110
|
+
return false if position.column > @ending.column
|
111
|
+
return false if position.column == @ending.column && !@including_ending
|
112
|
+
|
113
|
+
true
|
27
114
|
end
|
28
115
|
|
29
116
|
# @return [Hash]
|
@@ -33,16 +120,5 @@ module Rucoa
|
|
33
120
|
start: @beginning.to_vscode_position
|
34
121
|
}
|
35
122
|
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
# @param position [Rucoa::Position]
|
40
|
-
# @return [Boolean]
|
41
|
-
def exclude?(position)
|
42
|
-
position.line > @ending.line ||
|
43
|
-
position.line < @beginning.line ||
|
44
|
-
(position.line == @beginning.line && position.column < @beginning.column) ||
|
45
|
-
(position.line == @ending.line && position.column >= @ending.column)
|
46
|
-
end
|
47
123
|
end
|
48
124
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rbs'
|
4
|
+
|
5
|
+
module Rucoa
|
6
|
+
class RbsDocumentLoader
|
7
|
+
class << self
|
8
|
+
def call
|
9
|
+
new.call
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# @return [Array<Rucoa::Definitions::Base>]
|
14
|
+
def call
|
15
|
+
declarations.flat_map do |declaration|
|
16
|
+
case declaration
|
17
|
+
when ::RBS::AST::Declarations::Constant
|
18
|
+
[
|
19
|
+
DefinitionBuilders::RbsConstantDefinitionBuilder.call(declaration: declaration)
|
20
|
+
]
|
21
|
+
when ::RBS::AST::Declarations::Class, ::RBS::AST::Declarations::Module
|
22
|
+
declaration.members.grep(::RBS::AST::Members::MethodDefinition).map do |method_definition|
|
23
|
+
DefinitionBuilders::RbsMethodDefinitionBuilder.call(
|
24
|
+
declaration: declaration,
|
25
|
+
method_definition: method_definition
|
26
|
+
)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
[]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# @return [Array<RBS::AST::Declarations::Base>]
|
37
|
+
def declarations
|
38
|
+
::RBS::Environment.from_loader(
|
39
|
+
::RBS::EnvironmentLoader.new
|
40
|
+
).resolve_type_names.declarations
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
module Rucoa
|
6
|
+
class RubocopConfigurationChecker
|
7
|
+
class << self
|
8
|
+
# @return [Boolean]
|
9
|
+
def call
|
10
|
+
new.call
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [Boolean]
|
15
|
+
def call
|
16
|
+
rubocop_configured_for_current_directory?
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# @return [Boolean]
|
22
|
+
def rubocop_configured_for_current_directory?
|
23
|
+
each_current_and_ancestor_pathname.any? do |pathname|
|
24
|
+
pathname.join('.rubocop.yml').exist?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Enumerable<Pathname>]
|
29
|
+
def each_current_and_ancestor_pathname
|
30
|
+
return to_enum(__method__) unless block_given?
|
31
|
+
|
32
|
+
pathname = ::Pathname.pwd
|
33
|
+
loop do
|
34
|
+
yield pathname
|
35
|
+
break if pathname.root?
|
36
|
+
|
37
|
+
pathname = pathname.parent
|
38
|
+
end
|
39
|
+
self
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/rucoa/server.rb
CHANGED
@@ -2,158 +2,132 @@
|
|
2
2
|
|
3
3
|
module Rucoa
|
4
4
|
class Server
|
5
|
-
# @
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
# @return [Hash{String => Class}]
|
6
|
+
METHOD_TO_HANDLER_MAP = {
|
7
|
+
'exit' => Handlers::ExitHandler,
|
8
|
+
'initialize' => Handlers::InitializeHandler,
|
9
|
+
'initialized' => Handlers::InitializedHandler,
|
10
|
+
'shutdown' => Handlers::ShutdownHandler,
|
11
|
+
'textDocument/codeAction' => Handlers::TextDocumentCodeActionHandler,
|
12
|
+
'textDocument/didChange' => Handlers::TextDocumentDidChangeHandler,
|
13
|
+
'textDocument/didOpen' => Handlers::TextDocumentDidOpenHandler,
|
14
|
+
'textDocument/documentSymbol' => Handlers::TextDocumentDocumentSymbolHandler,
|
15
|
+
'textDocument/formatting' => Handlers::TextDocumentFormattingHandler,
|
16
|
+
'textDocument/rangeFormatting' => Handlers::TextDocumentRangeFormattingHandler,
|
17
|
+
'textDocument/selectionRange' => Handlers::TextDocumentSelectionRangeHandler,
|
18
|
+
'textDocument/signatureHelp' => Handlers::TextDocumentSignatureHelpHandler,
|
19
|
+
'workspace/didChangeConfiguration' => Handlers::WorkspaceDidChangeConfigurationHandler
|
20
|
+
}.freeze
|
21
|
+
private_constant :METHOD_TO_HANDLER_MAP
|
22
|
+
|
23
|
+
# @return [Boolean]
|
24
|
+
attr_accessor :shutting_down
|
25
|
+
|
26
|
+
# @return [Rucoa::Configuration]
|
27
|
+
attr_reader :configuration
|
28
|
+
|
29
|
+
# @return [Rucoa::DefinitionStore]
|
30
|
+
attr_reader :definition_store
|
31
|
+
|
32
|
+
# @return [Rucoa::SourceStore]
|
33
|
+
attr_reader :source_store
|
34
|
+
|
35
|
+
# @param input [IO]
|
36
|
+
# @param output [IO]
|
37
|
+
def initialize(input:, output:)
|
38
|
+
@reader = MessageReader.new(input)
|
39
|
+
@writer = MessageWriter.new(output)
|
40
|
+
|
41
|
+
@client_response_handlers = {}
|
42
|
+
@configuration = Configuration.new
|
43
|
+
@server_request_id = 0
|
44
|
+
@shutting_down = false
|
10
45
|
@source_store = SourceStore.new
|
46
|
+
|
47
|
+
@definition_store = DefinitionStore.new
|
48
|
+
@definition_store.definitions += DefinitionArchiver.load
|
11
49
|
end
|
12
50
|
|
13
51
|
# @return [void]
|
14
52
|
def start
|
15
|
-
read do |request|
|
16
|
-
|
17
|
-
if result
|
18
|
-
write(
|
19
|
-
request: request,
|
20
|
-
result: result
|
21
|
-
)
|
22
|
-
end
|
53
|
+
@reader.read do |request|
|
54
|
+
handle(request)
|
23
55
|
end
|
24
56
|
end
|
25
57
|
|
26
|
-
private
|
27
|
-
|
28
|
-
# @param request [Hash]
|
29
|
-
# @return [Object]
|
30
|
-
def handle(request)
|
31
|
-
case request['method']
|
32
|
-
when 'initialize'
|
33
|
-
on_initialize(request)
|
34
|
-
when 'textDocument/codeAction'
|
35
|
-
on_text_document_code_action(request)
|
36
|
-
when 'textDocument/didChange'
|
37
|
-
on_text_document_did_change(request)
|
38
|
-
when 'textDocument/didOpen'
|
39
|
-
on_text_document_did_open(request)
|
40
|
-
when 'textDocument/formatting'
|
41
|
-
on_text_document_formatting(request)
|
42
|
-
when 'textDocument/selectionRange'
|
43
|
-
on_text_document_selection_range(request)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# @yieldparam request [Hash]
|
48
58
|
# @return [void]
|
49
|
-
def
|
50
|
-
|
59
|
+
def finish
|
60
|
+
exit(0)
|
51
61
|
end
|
52
62
|
|
53
|
-
# @
|
54
|
-
# @param
|
63
|
+
# @yieldparam response [Hash]
|
64
|
+
# @param message [Hash]
|
55
65
|
# @return [void]
|
56
|
-
def write(
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
)
|
66
|
+
def write(message, &block)
|
67
|
+
if block
|
68
|
+
write_server_request(message, &block)
|
69
|
+
else
|
70
|
+
write_server_response(message)
|
71
|
+
end
|
63
72
|
end
|
64
73
|
|
65
|
-
# @
|
66
|
-
# @return [
|
67
|
-
def
|
68
|
-
@writer.
|
69
|
-
|
70
|
-
|
71
|
-
diagnostics: DiagnosticProvider.call(
|
72
|
-
source: @source_store.get(uri),
|
73
|
-
uri: uri
|
74
|
-
),
|
75
|
-
uri: uri
|
76
|
-
}
|
77
|
-
)
|
74
|
+
# @note This method is for testing.
|
75
|
+
# @return [Array<Hash>]
|
76
|
+
def responses
|
77
|
+
io = @writer.io
|
78
|
+
io.rewind
|
79
|
+
MessageReader.new(io).read.to_a
|
78
80
|
end
|
79
81
|
|
80
|
-
|
81
|
-
# @return [Hash]
|
82
|
-
def on_initialize(_request)
|
83
|
-
{
|
84
|
-
capabilities: {
|
85
|
-
codeActionProvider: true,
|
86
|
-
documentFormattingProvider: true,
|
87
|
-
selectionRangeProvider: true,
|
88
|
-
textDocumentSync: {
|
89
|
-
change: 1, # Full
|
90
|
-
openClose: true
|
91
|
-
}
|
92
|
-
}
|
93
|
-
}
|
94
|
-
end
|
82
|
+
private
|
95
83
|
|
96
84
|
# @param request [Hash]
|
97
|
-
# @return [
|
98
|
-
def
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
)
|
85
|
+
# @return [void]
|
86
|
+
def handle(request)
|
87
|
+
if request['method']
|
88
|
+
handle_client_request(request)
|
89
|
+
elsif request['id']
|
90
|
+
handle_client_response(request)
|
91
|
+
end
|
105
92
|
end
|
106
93
|
|
107
94
|
# @param request [Hash]
|
108
|
-
# @return [
|
109
|
-
def
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
request.dig('params', 'contentChanges')[0]['text']
|
95
|
+
# @return [void]
|
96
|
+
def handle_client_request(request)
|
97
|
+
find_client_request_handler(request['method'])&.call(
|
98
|
+
request: request,
|
99
|
+
server: self
|
114
100
|
)
|
115
|
-
investigate_diagnostics(uri: uri)
|
116
|
-
nil
|
117
101
|
end
|
118
102
|
|
119
|
-
# @param
|
120
|
-
# @return [
|
121
|
-
def
|
122
|
-
|
123
|
-
@source_store.set(
|
124
|
-
uri,
|
125
|
-
request.dig('params', 'textDocument', 'text')
|
126
|
-
)
|
127
|
-
investigate_diagnostics(uri: uri)
|
128
|
-
nil
|
103
|
+
# @param response [Hash]
|
104
|
+
# @return [void]
|
105
|
+
def handle_client_response(response)
|
106
|
+
@client_response_handlers.delete(response['id'])&.call(response)
|
129
107
|
end
|
130
108
|
|
131
|
-
# @param
|
132
|
-
# @return [
|
133
|
-
def
|
134
|
-
|
135
|
-
source = @source_store.get(uri)
|
136
|
-
return unless source
|
137
|
-
|
138
|
-
FormattingProvider.call(
|
139
|
-
source: source
|
140
|
-
)
|
109
|
+
# @param request_method [String]
|
110
|
+
# @return [Class, nil]
|
111
|
+
def find_client_request_handler(request_method)
|
112
|
+
METHOD_TO_HANDLER_MAP[request_method]
|
141
113
|
end
|
142
114
|
|
143
|
-
# @param
|
144
|
-
# @return [
|
145
|
-
def
|
146
|
-
|
147
|
-
|
115
|
+
# @param message [Hash]
|
116
|
+
# @return [void]
|
117
|
+
def write_server_request(message, &block)
|
118
|
+
@writer.write(
|
119
|
+
message.merge(
|
120
|
+
id: @server_request_id
|
121
|
+
)
|
148
122
|
)
|
149
|
-
|
123
|
+
@client_response_handlers[@server_request_id] = block
|
124
|
+
@server_request_id += 1
|
125
|
+
end
|
150
126
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
)
|
156
|
-
end
|
127
|
+
# @param message [Hash]
|
128
|
+
# @return [void]
|
129
|
+
def write_server_response(message)
|
130
|
+
@writer.write(message)
|
157
131
|
end
|
158
132
|
end
|
159
133
|
end
|
data/lib/rucoa/source.rb
CHANGED
@@ -6,13 +6,59 @@ module Rucoa
|
|
6
6
|
attr_reader :content
|
7
7
|
|
8
8
|
# @return [String]
|
9
|
-
attr_reader :
|
9
|
+
attr_reader :uri
|
10
10
|
|
11
11
|
# @param content [String]
|
12
|
-
# @param
|
13
|
-
def initialize(content:,
|
12
|
+
# @param uri [String, nil]
|
13
|
+
def initialize(content:, uri: nil)
|
14
14
|
@content = content
|
15
|
-
@
|
15
|
+
@uri = uri
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [Array<Rucoa::Definition::Base>]
|
19
|
+
# @example returns definitions from given source
|
20
|
+
# content = <<~RUBY
|
21
|
+
# class Foo
|
22
|
+
# def bar
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
# RUBY
|
26
|
+
# source = Rucoa::Source.new(
|
27
|
+
# content: content,
|
28
|
+
# uri: 'file:///path/to/foo.rb'
|
29
|
+
# )
|
30
|
+
# expect(source.definitions).to match(
|
31
|
+
# [
|
32
|
+
# a_kind_of(Rucoa::Definitions::MethodDefinition)
|
33
|
+
# ]
|
34
|
+
# )
|
35
|
+
def definitions
|
36
|
+
@definitions ||= YardStringDocumentLoader.call(
|
37
|
+
content: @content,
|
38
|
+
path: path
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [String, nil]
|
43
|
+
# @example returns path from given VSCode URI
|
44
|
+
# source = Rucoa::Source.new(
|
45
|
+
# content: '',
|
46
|
+
# uri: 'file:///path/to/foo.rb'
|
47
|
+
# )
|
48
|
+
# expect(source.path).to eq('/path/to/foo.rb')
|
49
|
+
# @example returns nil for untitled URI
|
50
|
+
# source = Rucoa::Source.new(
|
51
|
+
# content: '',
|
52
|
+
# uri: 'untitled:Untitled-1'
|
53
|
+
# )
|
54
|
+
# expect(source.path).to be_nil
|
55
|
+
def path
|
56
|
+
return unless @uri
|
57
|
+
|
58
|
+
path = ::URI.parse(@uri).path
|
59
|
+
return unless path
|
60
|
+
|
61
|
+
::CGI.unescape(path)
|
16
62
|
end
|
17
63
|
|
18
64
|
# @param position [Rucoa::Position]
|
@@ -21,15 +67,19 @@ module Rucoa
|
|
21
67
|
root_and_descendant_nodes.reverse.find do |node|
|
22
68
|
node.include_position?(position)
|
23
69
|
end
|
70
|
+
rescue ::Parser::SyntaxError
|
71
|
+
nil
|
24
72
|
end
|
25
73
|
|
26
|
-
private
|
27
|
-
|
28
74
|
# @return [Rucoa::Nodes::Base, nil]
|
29
75
|
def root_node
|
30
76
|
@root_node ||= Parser.call(@content)
|
77
|
+
rescue ::Parser::SyntaxError
|
78
|
+
nil
|
31
79
|
end
|
32
80
|
|
81
|
+
private
|
82
|
+
|
33
83
|
# @return [Array<Rucoa::Nodes::Base>]
|
34
84
|
def root_and_descendant_nodes
|
35
85
|
return [] unless root_node
|
data/lib/rucoa/source_store.rb
CHANGED
@@ -9,20 +9,22 @@ module Rucoa
|
|
9
9
|
@data = {}
|
10
10
|
end
|
11
11
|
|
12
|
+
# @param source [Rucoa::Source]
|
13
|
+
# @return [void]
|
14
|
+
def update(source)
|
15
|
+
@data[source.uri] = source
|
16
|
+
end
|
17
|
+
|
12
18
|
# @param uri [String]
|
13
19
|
# @return [String, nil]
|
14
20
|
def get(uri)
|
15
21
|
@data[uri]
|
16
22
|
end
|
17
23
|
|
18
|
-
# @
|
19
|
-
# @
|
20
|
-
|
21
|
-
|
22
|
-
@data[uri] = Source.new(
|
23
|
-
content: content,
|
24
|
-
path: path_from_uri(uri)
|
25
|
-
)
|
24
|
+
# @yieldparam uri [String]
|
25
|
+
# @return [Enumerable<String>]
|
26
|
+
def each_uri(&block)
|
27
|
+
@data.each_key(&block)
|
26
28
|
end
|
27
29
|
|
28
30
|
private
|
@@ -31,7 +33,7 @@ module Rucoa
|
|
31
33
|
# @return [String]
|
32
34
|
def path_from_uri(uri)
|
33
35
|
::CGI.unescape(
|
34
|
-
::URI.parse(uri).path
|
36
|
+
::URI.parse(uri).path || 'untitled'
|
35
37
|
)
|
36
38
|
end
|
37
39
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rucoa
|
4
|
+
module Types
|
5
|
+
class MethodType
|
6
|
+
# @return [String]
|
7
|
+
attr_reader :parameters_string
|
8
|
+
|
9
|
+
# @return [String]
|
10
|
+
attr_reader :return_type
|
11
|
+
|
12
|
+
# @param parameters_string [String]
|
13
|
+
# @param return_type [String]
|
14
|
+
def initialize(
|
15
|
+
parameters_string:,
|
16
|
+
return_type:
|
17
|
+
)
|
18
|
+
@parameters_string = parameters_string
|
19
|
+
@return_type = return_type
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/rucoa/types.rb
ADDED
data/lib/rucoa/version.rb
CHANGED