rucoa 0.1.0 → 0.4.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 +7 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +4 -1
- data/README.md +7 -4
- data/lib/rucoa/cli.rb +2 -2
- data/lib/rucoa/configuration.rb +71 -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 +61 -0
- data/lib/rucoa/handlers/initialize_handler.rb +23 -0
- data/lib/rucoa/handlers/initialized_handler.rb +13 -0
- data/lib/rucoa/handlers/text_document_code_action_handler.rb +104 -0
- data/lib/rucoa/handlers/text_document_did_change_handler.rb +31 -0
- data/lib/rucoa/handlers/text_document_did_open_handler.rb +31 -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/workspace_did_change_configuration_handler.rb +13 -0
- data/lib/rucoa/handlers.rb +17 -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/nodes/base.rb +13 -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 +12 -0
- data/lib/rucoa/nodes/defs_node.rb +12 -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 +17 -0
- data/lib/rucoa/nodes/str_node.rb +4 -0
- data/lib/rucoa/nodes/sym_node.rb +12 -0
- data/lib/rucoa/nodes.rb +9 -0
- data/lib/rucoa/parser_builder.rb +19 -10
- data/lib/rucoa/range.rb +32 -15
- data/lib/rucoa/rubocop_autocorrector.rb +38 -0
- data/lib/rucoa/rubocop_configuration_checker.rb +42 -0
- data/lib/rucoa/{rubocop_runner.rb → rubocop_investigator.rb} +9 -8
- data/lib/rucoa/server.rb +80 -97
- data/lib/rucoa/source.rb +2 -2
- data/lib/rucoa/source_store.rb +7 -1
- data/lib/rucoa/version.rb +1 -1
- data/lib/rucoa.rb +8 -4
- metadata +32 -5
- data/lib/rucoa/diagnostic_provider.rb +0 -112
- data/lib/rucoa/selection_range_provider.rb +0 -97
@@ -0,0 +1,241 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
module Rucoa
|
6
|
+
module Handlers
|
7
|
+
class TextDocumentDocumentSymbolHandler < Base
|
8
|
+
DOCUMENT_SYMBOL_KIND_FOR_FILE = 1
|
9
|
+
DOCUMENT_SYMBOL_KIND_FOR_MODULE = 2
|
10
|
+
DOCUMENT_SYMBOL_KIND_FOR_NAMESPACE = 3
|
11
|
+
DOCUMENT_SYMBOL_KIND_FOR_PACKAGE = 4
|
12
|
+
DOCUMENT_SYMBOL_KIND_FOR_CLASS = 5
|
13
|
+
DOCUMENT_SYMBOL_KIND_FOR_METHOD = 6
|
14
|
+
DOCUMENT_SYMBOL_KIND_FOR_PROPERTY = 7
|
15
|
+
DOCUMENT_SYMBOL_KIND_FOR_FIELD = 8
|
16
|
+
DOCUMENT_SYMBOL_KIND_FOR_CONSTRUCTOR = 9
|
17
|
+
DOCUMENT_SYMBOL_KIND_FOR_ENUM = 10
|
18
|
+
DOCUMENT_SYMBOL_KIND_FOR_INTERFACE = 11
|
19
|
+
DOCUMENT_SYMBOL_KIND_FOR_FUNCTION = 12
|
20
|
+
DOCUMENT_SYMBOL_KIND_FOR_VARIABLE = 13
|
21
|
+
DOCUMENT_SYMBOL_KIND_FOR_CONSTANT = 14
|
22
|
+
DOCUMENT_SYMBOL_KIND_FOR_STRING = 15
|
23
|
+
DOCUMENT_SYMBOL_KIND_FOR_NUMBER = 16
|
24
|
+
DOCUMENT_SYMBOL_KIND_FOR_BOOLEAN = 17
|
25
|
+
DOCUMENT_SYMBOL_KIND_FOR_ARRAY = 18
|
26
|
+
DOCUMENT_SYMBOL_KIND_FOR_OBJECT = 19
|
27
|
+
DOCUMENT_SYMBOL_KIND_FOR_KEY = 20
|
28
|
+
DOCUMENT_SYMBOL_KIND_FOR_NULL = 21
|
29
|
+
DOCUMENT_SYMBOL_KIND_FOR_ENUMMEMBER = 22
|
30
|
+
DOCUMENT_SYMBOL_KIND_FOR_STRUCT = 23
|
31
|
+
DOCUMENT_SYMBOL_KIND_FOR_EVENT = 24
|
32
|
+
DOCUMENT_SYMBOL_KIND_FOR_OPERATOR = 25
|
33
|
+
DOCUMENT_SYMBOL_KIND_FOR_TYPEPARAMETER = 26
|
34
|
+
|
35
|
+
# @return [Set<String>]
|
36
|
+
ATTRIBUTE_METHOD_NAMES = ::Set[
|
37
|
+
'attr_accessor',
|
38
|
+
'attr_reader',
|
39
|
+
'attr_writer',
|
40
|
+
]
|
41
|
+
|
42
|
+
def call
|
43
|
+
return unless respondable?
|
44
|
+
|
45
|
+
respond(document_symbols)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# @return [Array<Hash>]
|
51
|
+
def document_symbols
|
52
|
+
visit(source.root_node)
|
53
|
+
document_symbol_stack.first[:children]
|
54
|
+
end
|
55
|
+
|
56
|
+
# @param node [Rucoa::Nodes::Base]
|
57
|
+
# @return [void]
|
58
|
+
def visit(node)
|
59
|
+
document_symbols = create_document_symbols_for(node)
|
60
|
+
document_symbol_stack.last[:children].push(*document_symbols)
|
61
|
+
with_document_symbol_stack(document_symbols.first) do
|
62
|
+
with_singleton_class_stack(node) do
|
63
|
+
node.each_child_node do |child_node|
|
64
|
+
visit(child_node)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# @param document_symbol [Hash, nil]
|
71
|
+
# @return [void]
|
72
|
+
def with_document_symbol_stack(document_symbol)
|
73
|
+
unless document_symbol
|
74
|
+
yield
|
75
|
+
return
|
76
|
+
end
|
77
|
+
|
78
|
+
document_symbol_stack.push(document_symbol)
|
79
|
+
yield
|
80
|
+
document_symbol_stack.pop
|
81
|
+
end
|
82
|
+
|
83
|
+
# @param node [Rucoa::Nodes::Base]
|
84
|
+
def with_singleton_class_stack(node)
|
85
|
+
unless node.is_a?(Rucoa::Nodes::SclassNode)
|
86
|
+
yield
|
87
|
+
return
|
88
|
+
end
|
89
|
+
|
90
|
+
singleton_class_stack.push(node)
|
91
|
+
yield
|
92
|
+
singleton_class_stack.pop
|
93
|
+
end
|
94
|
+
|
95
|
+
# @param node [Rucoa::Nodes::Base]
|
96
|
+
# @return [Array<Hash>]
|
97
|
+
def create_document_symbols_for(node)
|
98
|
+
case node
|
99
|
+
when Nodes::CasgnNode
|
100
|
+
create_document_symbols_for_casgn(node)
|
101
|
+
when Nodes::ClassNode
|
102
|
+
create_document_symbols_for_class(node)
|
103
|
+
when Nodes::DefNode
|
104
|
+
create_document_symbols_for_def(node)
|
105
|
+
when Nodes::DefsNode
|
106
|
+
create_document_symbols_for_defs(node)
|
107
|
+
when Nodes::ModuleNode
|
108
|
+
create_document_symbols_for_module(node)
|
109
|
+
when Nodes::SendNode
|
110
|
+
create_document_symbols_for_send(node)
|
111
|
+
else
|
112
|
+
[]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# @param node [Rucoa::Nodes::CasgnNode]
|
117
|
+
# @return [Array<Hash>]
|
118
|
+
def create_document_symbols_for_casgn(node)
|
119
|
+
[
|
120
|
+
{
|
121
|
+
children: [],
|
122
|
+
kind: DOCUMENT_SYMBOL_KIND_FOR_CONSTANT,
|
123
|
+
name: node.name,
|
124
|
+
range: Range.from_parser_range(node.location.expression).to_vscode_range,
|
125
|
+
selectionRange: Range.from_parser_range(node.location.name).to_vscode_range
|
126
|
+
}
|
127
|
+
]
|
128
|
+
end
|
129
|
+
|
130
|
+
# @param node [Rucoa::Nodes::ClassNode]
|
131
|
+
# @return [Array<Hash>]
|
132
|
+
def create_document_symbols_for_class(node)
|
133
|
+
[
|
134
|
+
{
|
135
|
+
children: [],
|
136
|
+
kind: DOCUMENT_SYMBOL_KIND_FOR_CLASS,
|
137
|
+
name: node.name,
|
138
|
+
range: Range.from_parser_range(node.location.expression).to_vscode_range,
|
139
|
+
selectionRange: Range.from_parser_range(node.location.name).to_vscode_range
|
140
|
+
}
|
141
|
+
]
|
142
|
+
end
|
143
|
+
|
144
|
+
# @param node [Rucoa::Nodes::ModuleNode]
|
145
|
+
# @return [Array<Hash>]
|
146
|
+
def create_document_symbols_for_module(node)
|
147
|
+
[
|
148
|
+
{
|
149
|
+
children: [],
|
150
|
+
kind: DOCUMENT_SYMBOL_KIND_FOR_MODULE,
|
151
|
+
name: node.name,
|
152
|
+
range: Range.from_parser_range(node.location.expression).to_vscode_range,
|
153
|
+
selectionRange: Range.from_parser_range(node.location.name).to_vscode_range
|
154
|
+
}
|
155
|
+
]
|
156
|
+
end
|
157
|
+
|
158
|
+
# @param node [Rucoa::Nodes::DefNode]
|
159
|
+
# @return [Array<Hash>]
|
160
|
+
def create_document_symbols_for_def(node)
|
161
|
+
[
|
162
|
+
{
|
163
|
+
children: [],
|
164
|
+
kind: DOCUMENT_SYMBOL_KIND_FOR_METHOD,
|
165
|
+
name: singleton_class_stack.empty? ? "##{node.name}" : ".#{node.name}",
|
166
|
+
range: Range.from_parser_range(node.location.expression).to_vscode_range,
|
167
|
+
selectionRange: Range.from_parser_range(node.location.name).to_vscode_range
|
168
|
+
}
|
169
|
+
]
|
170
|
+
end
|
171
|
+
|
172
|
+
# @param node [Rucoa::Nodes::DefNode]
|
173
|
+
# @return [Array<Hash>]
|
174
|
+
def create_document_symbols_for_defs(node)
|
175
|
+
[
|
176
|
+
{
|
177
|
+
children: [],
|
178
|
+
kind: DOCUMENT_SYMBOL_KIND_FOR_METHOD,
|
179
|
+
name: ".#{node.name}",
|
180
|
+
range: Range.from_parser_range(node.location.expression).to_vscode_range,
|
181
|
+
selectionRange: Range.from_parser_range(node.location.name).to_vscode_range
|
182
|
+
}
|
183
|
+
]
|
184
|
+
end
|
185
|
+
|
186
|
+
# @param node [Rucoa::Nodes::SendNode]
|
187
|
+
# @return [Array<Hash>]
|
188
|
+
def create_document_symbols_for_send(node)
|
189
|
+
return [] unless ATTRIBUTE_METHOD_NAMES.include?(node.name)
|
190
|
+
|
191
|
+
simple_types = ::Set[
|
192
|
+
:str,
|
193
|
+
:sym
|
194
|
+
]
|
195
|
+
node.arguments.select do |argument|
|
196
|
+
simple_types.include?(argument.type)
|
197
|
+
end.map do |argument|
|
198
|
+
{
|
199
|
+
children: [],
|
200
|
+
kind: DOCUMENT_SYMBOL_KIND_FOR_FIELD,
|
201
|
+
name: argument.value.to_s,
|
202
|
+
range: Range.from_parser_range(argument.location.expression).to_vscode_range,
|
203
|
+
selectionRange: Range.from_parser_range(argument.location.expression).to_vscode_range
|
204
|
+
}
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
# @return [Boolean]
|
209
|
+
def respondable?
|
210
|
+
configuration.enables_document_symbol? && source
|
211
|
+
end
|
212
|
+
|
213
|
+
# @return [Rucoa::Source]
|
214
|
+
def source
|
215
|
+
@source ||= @server.source_store.get(uri)
|
216
|
+
end
|
217
|
+
|
218
|
+
# @return [String]
|
219
|
+
def uri
|
220
|
+
request.dig('params', 'textDocument', 'uri')
|
221
|
+
end
|
222
|
+
|
223
|
+
# @return [Arrah<Hash>]
|
224
|
+
def document_symbol_stack
|
225
|
+
@document_symbol_stack ||= [dummy_document_symbol]
|
226
|
+
end
|
227
|
+
|
228
|
+
# @return [Hash]
|
229
|
+
def dummy_document_symbol
|
230
|
+
{
|
231
|
+
children: []
|
232
|
+
}
|
233
|
+
end
|
234
|
+
|
235
|
+
# @return [Array<Rucoa::Nodes::SclassNode>]
|
236
|
+
def singleton_class_stack
|
237
|
+
@singleton_class_stack ||= []
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rucoa
|
4
|
+
module Handlers
|
5
|
+
class TextDocumentFormattingHandler < Base
|
6
|
+
def call
|
7
|
+
respond(edits)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# @return [Boolean]
|
13
|
+
def formattable?
|
14
|
+
configuration.enables_formatting? &&
|
15
|
+
source &&
|
16
|
+
RubocopConfigurationChecker.call
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [Array<Hash>]
|
20
|
+
def edits
|
21
|
+
return [] unless formattable?
|
22
|
+
|
23
|
+
[text_edit]
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Rucoa::Source, nil]
|
27
|
+
def source
|
28
|
+
@source ||= source_store.get(uri)
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [String]
|
32
|
+
def uri
|
33
|
+
request.dig('params', 'textDocument', 'uri')
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Hash]
|
37
|
+
def text_edit
|
38
|
+
{
|
39
|
+
newText: new_text,
|
40
|
+
range: range
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [String]
|
45
|
+
def new_text
|
46
|
+
RubocopAutocorrector.call(source: source)
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [Hash]
|
50
|
+
def range
|
51
|
+
Range.new(
|
52
|
+
Position.new(
|
53
|
+
column: 0,
|
54
|
+
line: 1
|
55
|
+
),
|
56
|
+
Position.new(
|
57
|
+
column: @source.content.lines.last.length,
|
58
|
+
line: @source.content.lines.count + 1
|
59
|
+
)
|
60
|
+
).to_vscode_range
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rucoa
|
4
|
+
module Handlers
|
5
|
+
class TextDocumentRangeFormattingHandler < Base
|
6
|
+
def call
|
7
|
+
respond(edits)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# @return [Array<Hash>]
|
13
|
+
def edits
|
14
|
+
return [] unless formattable?
|
15
|
+
|
16
|
+
correctable_replacements.map do |replacement_range, replacement|
|
17
|
+
{
|
18
|
+
newText: replacement,
|
19
|
+
range: replacement_range.to_vscode_range
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Boolean]
|
25
|
+
def formattable?
|
26
|
+
configuration.enables_formatting? &&
|
27
|
+
source &&
|
28
|
+
RubocopConfigurationChecker.call
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Rucoa::Source]
|
32
|
+
def source
|
33
|
+
@source ||= source_store.get(uri)
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [String]
|
37
|
+
def uri
|
38
|
+
request.dig('params', 'textDocument', 'uri')
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [Rucoa::Range]
|
42
|
+
def range
|
43
|
+
@range ||= Range.from_vscode_range(
|
44
|
+
request.dig('params', 'range')
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [Array<RuboCop::Cop::Corrector>]
|
49
|
+
def correctable_offenses
|
50
|
+
offenses.select(&:corrector)
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [Array(Rucoa::Range, String)]
|
54
|
+
def correctable_replacements
|
55
|
+
replacements.select do |replacement_range, _|
|
56
|
+
range.contains?(replacement_range)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# @return [Array<RuboCop::Cop::Offense>]
|
61
|
+
def offenses
|
62
|
+
RubocopInvestigator.call(source: source)
|
63
|
+
end
|
64
|
+
|
65
|
+
# @return [Array(Rucoa::Range, String)]
|
66
|
+
def replacements
|
67
|
+
correctable_offenses.map(&:corrector).flat_map(&:as_replacements).map do |replacement_range, replacement|
|
68
|
+
[
|
69
|
+
Range.from_parser_range(replacement_range),
|
70
|
+
replacement
|
71
|
+
]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rucoa
|
4
|
+
module Handlers
|
5
|
+
class TextDocumentSelectionRangeHandler < Base
|
6
|
+
def call
|
7
|
+
return unless respondable?
|
8
|
+
|
9
|
+
respond(
|
10
|
+
positions.filter_map do |position|
|
11
|
+
SelectionRangeProvider.call(
|
12
|
+
position: position,
|
13
|
+
source: source
|
14
|
+
)
|
15
|
+
end
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# @return [Boolean]
|
22
|
+
def respondable?
|
23
|
+
configuration.enables_selection_range? &&
|
24
|
+
source
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Rucoa::Source]
|
28
|
+
def source
|
29
|
+
@source ||= source_store.get(uri)
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Array<Rucoa::Position>]
|
33
|
+
def positions
|
34
|
+
request.dig('params', 'positions').map do |position|
|
35
|
+
Position.from_vscode_position(position)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [String]
|
40
|
+
def uri
|
41
|
+
request.dig('params', 'textDocument', 'uri')
|
42
|
+
end
|
43
|
+
|
44
|
+
class SelectionRangeProvider
|
45
|
+
class << self
|
46
|
+
# @param source [Rucoa::Source]
|
47
|
+
# @param position [Rucoa::Position]
|
48
|
+
# @return [Hash, nil]
|
49
|
+
def call(position:, source:)
|
50
|
+
new(
|
51
|
+
position: position,
|
52
|
+
source: source
|
53
|
+
).call
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# @param position [Rucoa::Position]
|
58
|
+
# @param source [Rucoa::Source]
|
59
|
+
def initialize(position:, source:)
|
60
|
+
@position = position
|
61
|
+
@source = source
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [Hash, nil]
|
65
|
+
def call
|
66
|
+
ranges.reverse.reduce(nil) do |result, range|
|
67
|
+
{
|
68
|
+
parent: result,
|
69
|
+
range: range.to_vscode_range
|
70
|
+
}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
# @return [Rucoa::Nodes::Base, nil]
|
77
|
+
def node_at_position
|
78
|
+
if instance_variable_defined?(:@node_at_position)
|
79
|
+
@node_at_position
|
80
|
+
else
|
81
|
+
@node_at_position = @source.node_at(@position)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# @return [Array<Rucoa::Range>]
|
86
|
+
def ranges
|
87
|
+
return [] unless node_at_position
|
88
|
+
|
89
|
+
[node_at_position, *node_at_position.ancestors].flat_map do |node|
|
90
|
+
NodeToRangesMapper.call(node)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class NodeToRangesMapper
|
95
|
+
class << self
|
96
|
+
# @param node [Rucoa::Nodes::Base]
|
97
|
+
# @return [Array<Rucoa::Range>]
|
98
|
+
def call(node)
|
99
|
+
new(node).call
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# @param node [Rucoa::Nodes::Base]
|
104
|
+
def initialize(node)
|
105
|
+
@node = node
|
106
|
+
end
|
107
|
+
|
108
|
+
# @return [Array<Rucoa::Range>]
|
109
|
+
def call
|
110
|
+
case @node
|
111
|
+
when Nodes::StrNode
|
112
|
+
[
|
113
|
+
inner_range,
|
114
|
+
expression_range
|
115
|
+
]
|
116
|
+
else
|
117
|
+
[
|
118
|
+
expression_range
|
119
|
+
]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
# @return [Rucoa::Range]
|
126
|
+
def inner_range
|
127
|
+
Range.new(
|
128
|
+
Position.from_parser_range_ending(@node.location.begin),
|
129
|
+
Position.from_parser_range_beginning(@node.location.end)
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
# @return [Rucoa::Range]
|
134
|
+
def expression_range
|
135
|
+
Range.from_parser_range(@node.location.expression)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rucoa
|
4
|
+
module Handlers
|
5
|
+
autoload :Base, 'rucoa/handlers/base'
|
6
|
+
autoload :InitializeHandler, 'rucoa/handlers/initialize_handler'
|
7
|
+
autoload :InitializedHandler, 'rucoa/handlers/initialized_handler'
|
8
|
+
autoload :TextDocumentCodeActionHandler, 'rucoa/handlers/text_document_code_action_handler'
|
9
|
+
autoload :TextDocumentDidChangeHandler, 'rucoa/handlers/text_document_did_change_handler'
|
10
|
+
autoload :TextDocumentDidOpenHandler, 'rucoa/handlers/text_document_did_open_handler'
|
11
|
+
autoload :TextDocumentDocumentSymbolHandler, 'rucoa/handlers/text_document_document_symbol_handler'
|
12
|
+
autoload :TextDocumentFormattingHandler, 'rucoa/handlers/text_document_formatting_handler'
|
13
|
+
autoload :TextDocumentRangeFormattingHandler, 'rucoa/handlers/text_document_range_formatting_handler'
|
14
|
+
autoload :TextDocumentSelectionRangeHandler, 'rucoa/handlers/text_document_selection_range_handler'
|
15
|
+
autoload :WorkspaceDidChangeConfigurationHandler, 'rucoa/handlers/workspace_did_change_configuration_handler'
|
16
|
+
end
|
17
|
+
end
|
data/lib/rucoa/message_reader.rb
CHANGED
@@ -11,8 +11,10 @@ module Rucoa
|
|
11
11
|
end
|
12
12
|
|
13
13
|
# @yieldparam message [Hash]
|
14
|
-
# @return [void]
|
14
|
+
# @return [Enumerator<Hash>, void]
|
15
15
|
def read
|
16
|
+
return enum_for(:read) unless block_given?
|
17
|
+
|
16
18
|
while (buffer = @io.gets("\r\n\r\n"))
|
17
19
|
content_length = buffer[/Content-Length: (\d+)/i, 1]
|
18
20
|
raise Errors::ContentLengthHeaderNotFound unless content_length
|
data/lib/rucoa/message_writer.rb
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rucoa
|
4
|
+
module NodeConcerns
|
5
|
+
module NameFullQualifiable
|
6
|
+
# @return [String]
|
7
|
+
def full_qualified_name
|
8
|
+
[
|
9
|
+
name,
|
10
|
+
*each_ancestor(:class, :constant, :module).map(&:name)
|
11
|
+
].reverse.join('::')
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [String]
|
15
|
+
def name
|
16
|
+
raise NotImplementedError
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/rucoa/nodes/base.rb
CHANGED
@@ -64,6 +64,19 @@ module Rucoa
|
|
64
64
|
self
|
65
65
|
end
|
66
66
|
|
67
|
+
# @note Override.
|
68
|
+
# Some nodes change their type depending on the context.
|
69
|
+
# For example, `const` node can be `casgn` node.
|
70
|
+
# @return [Rucoa::Nodes::Base]
|
71
|
+
def updated(type = nil, children = nil, properties = {})
|
72
|
+
properties[:location] ||= @location
|
73
|
+
ParserBuilder.node_class_for(type || @type).new(
|
74
|
+
type || @type,
|
75
|
+
children || @children,
|
76
|
+
properties
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
67
80
|
# @param position [Rucoa::Position]
|
68
81
|
# @return [Boolean]
|
69
82
|
def include_position?(position)
|