steep 1.10.0 → 2.0.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/CHANGELOG.md +84 -1
- data/CLAUDE.md +114 -0
- data/README.md +1 -1
- data/Rakefile +15 -3
- data/Steepfile +13 -13
- data/lib/steep/annotation_parser.rb +5 -1
- data/lib/steep/annotations_helper.rb +12 -2
- data/lib/steep/ast/node/type_application.rb +22 -16
- data/lib/steep/ast/node/type_assertion.rb +7 -4
- data/lib/steep/ast/types/factory.rb +3 -2
- data/lib/steep/cli.rb +246 -2
- data/lib/steep/daemon/configuration.rb +19 -0
- data/lib/steep/daemon/server.rb +476 -0
- data/lib/steep/daemon.rb +201 -0
- data/lib/steep/diagnostic/ruby.rb +50 -8
- data/lib/steep/diagnostic/signature.rb +31 -8
- data/lib/steep/drivers/check.rb +301 -140
- data/lib/steep/drivers/print_project.rb +9 -10
- data/lib/steep/drivers/query.rb +102 -0
- data/lib/steep/drivers/start_server.rb +19 -0
- data/lib/steep/drivers/stop_server.rb +20 -0
- data/lib/steep/drivers/watch.rb +2 -2
- data/lib/steep/index/rbs_index.rb +38 -13
- data/lib/steep/index/signature_symbol_provider.rb +24 -3
- data/lib/steep/interface/builder.rb +48 -15
- data/lib/steep/interface/shape.rb +13 -5
- data/lib/steep/locator.rb +377 -0
- data/lib/steep/project/dsl.rb +26 -5
- data/lib/steep/project/group.rb +8 -2
- data/lib/steep/project/target.rb +16 -2
- data/lib/steep/project.rb +21 -2
- data/lib/steep/server/base_worker.rb +2 -2
- data/lib/steep/server/change_buffer.rb +2 -1
- data/lib/steep/server/custom_methods.rb +12 -0
- data/lib/steep/server/inline_source_change_detector.rb +94 -0
- data/lib/steep/server/interaction_worker.rb +51 -74
- data/lib/steep/server/lsp_formatter.rb +48 -12
- data/lib/steep/server/master.rb +100 -18
- data/lib/steep/server/target_group_files.rb +124 -151
- data/lib/steep/server/type_check_controller.rb +276 -123
- data/lib/steep/server/type_check_worker.rb +104 -3
- data/lib/steep/services/completion_provider/rbs.rb +74 -0
- data/lib/steep/services/completion_provider/ruby.rb +652 -0
- data/lib/steep/services/completion_provider/type_name.rb +243 -0
- data/lib/steep/services/completion_provider.rb +39 -662
- data/lib/steep/services/content_change.rb +14 -1
- data/lib/steep/services/file_loader.rb +4 -2
- data/lib/steep/services/goto_service.rb +271 -68
- data/lib/steep/services/hover_provider/content.rb +67 -0
- data/lib/steep/services/hover_provider/rbs.rb +8 -9
- data/lib/steep/services/hover_provider/ruby.rb +123 -64
- data/lib/steep/services/hover_provider/singleton_methods.rb +4 -0
- data/lib/steep/services/signature_service.rb +129 -54
- data/lib/steep/services/type_check_service.rb +72 -27
- data/lib/steep/signature/validator.rb +30 -18
- data/lib/steep/source/ignore_ranges.rb +14 -4
- data/lib/steep/source.rb +16 -2
- data/lib/steep/tagged_logging.rb +39 -0
- data/lib/steep/type_construction.rb +94 -21
- data/lib/steep/type_inference/block_params.rb +7 -7
- data/lib/steep/type_inference/context.rb +4 -2
- data/lib/steep/type_inference/logic_type_interpreter.rb +21 -3
- data/lib/steep/type_inference/method_call.rb +4 -0
- data/lib/steep/type_inference/type_env.rb +1 -1
- data/lib/steep/typing.rb +0 -2
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +42 -32
- data/manual/ruby-diagnostics.md +67 -0
- data/sample/Steepfile +1 -0
- data/sample/lib/conference.rb +1 -0
- data/sample/lib/deprecated.rb +6 -0
- data/sample/lib/inline.rb +43 -0
- data/sample/sig/generics.rbs +3 -0
- data/steep.gemspec +4 -5
- metadata +26 -26
- data/lib/steep/services/type_name_completion.rb +0 -236
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
module Steep
|
|
2
|
+
module Server
|
|
3
|
+
class InlineSourceChangeDetector
|
|
4
|
+
class Source
|
|
5
|
+
attr_reader :content
|
|
6
|
+
attr_reader :changes
|
|
7
|
+
attr_reader :last_fingerprint
|
|
8
|
+
|
|
9
|
+
def initialize(content)
|
|
10
|
+
@content = content
|
|
11
|
+
@changes = []
|
|
12
|
+
update_fingerprint!
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def <<(changes)
|
|
16
|
+
@changes << changes
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def updated?
|
|
20
|
+
if changes.empty?
|
|
21
|
+
return false
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
updated_content = changes.inject(content) do |current_content, change|
|
|
25
|
+
change.apply_to(current_content)
|
|
26
|
+
end
|
|
27
|
+
changes.clear
|
|
28
|
+
|
|
29
|
+
if updated_content == content
|
|
30
|
+
return false
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
@content = updated_content
|
|
34
|
+
|
|
35
|
+
update_fingerprint!
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def update_fingerprint!
|
|
39
|
+
buffer = RBS::Buffer.new(name: Pathname("test.rb"), content: content)
|
|
40
|
+
prism = Prism.parse(content)
|
|
41
|
+
result = RBS::InlineParser.parse(buffer, prism)
|
|
42
|
+
|
|
43
|
+
new_fingerprint = result.type_fingerprint
|
|
44
|
+
|
|
45
|
+
(new_fingerprint != last_fingerprint).tap do
|
|
46
|
+
@last_fingerprint = new_fingerprint
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def clear
|
|
51
|
+
@changes.clear
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
attr_reader :sources
|
|
56
|
+
|
|
57
|
+
def initialize
|
|
58
|
+
@sources = {}
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def add_source(path, content)
|
|
62
|
+
sources.key?(path) and raise "Source already exists for #{path}"
|
|
63
|
+
sources[path] = Source.new(content)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def replace_source(path, content)
|
|
67
|
+
source = sources.fetch(path)
|
|
68
|
+
if source.content == content
|
|
69
|
+
source.clear
|
|
70
|
+
else
|
|
71
|
+
source << Services::ContentChange.string(content)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def accumulate_change(file_path, changes)
|
|
76
|
+
changes.each do |change|
|
|
77
|
+
sources.fetch(file_path) << change
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def type_updated_paths(paths)
|
|
82
|
+
paths.select { sources[_1]&.updated? }.to_set
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def has_source?(path)
|
|
86
|
+
sources.key?(path)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def reset
|
|
90
|
+
sources.each_value { _1.updated? }
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -154,19 +154,25 @@ module Steep
|
|
|
154
154
|
Steep.logger.info "path: #{job.path}, line: #{job.line}, column: #{job.column}, trigger: #{job.trigger}"
|
|
155
155
|
|
|
156
156
|
case
|
|
157
|
-
when target = project.target_for_source_path(job.path)
|
|
157
|
+
when target = project.target_for_inline_source_path(job.path) || project.target_for_source_path(job.path)
|
|
158
158
|
file = service.source_files[job.path] or return
|
|
159
159
|
subtyping = service.signature_services.fetch(target.name).current_subtyping or return
|
|
160
160
|
|
|
161
|
-
provider = Services::CompletionProvider.new(source_text: file.content, path: job.path, subtyping: subtyping)
|
|
162
|
-
items = begin
|
|
163
|
-
provider.run(line: job.line, column: job.column)
|
|
164
|
-
rescue Parser::SyntaxError
|
|
165
|
-
[] #: Array[Services::CompletionProvider::item]
|
|
166
|
-
end
|
|
161
|
+
provider = Services::CompletionProvider::Ruby.new(source_text: file.content, path: job.path, subtyping: subtyping)
|
|
167
162
|
|
|
168
|
-
|
|
169
|
-
format_completion_item(
|
|
163
|
+
if (prefix_size, items = provider.run_at_comment(line: job.line, column: job.column))
|
|
164
|
+
completion_items = items.map { format_completion_item(_1) }
|
|
165
|
+
completion_items.concat builtin_types(prefix_size, job.line, job.column)
|
|
166
|
+
else
|
|
167
|
+
items = begin
|
|
168
|
+
provider.run(line: job.line, column: job.column)
|
|
169
|
+
rescue Parser::SyntaxError
|
|
170
|
+
[] #: Array[Services::CompletionProvider::item]
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
completion_items = items.map do |item|
|
|
174
|
+
format_completion_item(item)
|
|
175
|
+
end
|
|
170
176
|
end
|
|
171
177
|
|
|
172
178
|
Steep.logger.debug "items = #{completion_items.inspect}"
|
|
@@ -179,71 +185,14 @@ module Steep
|
|
|
179
185
|
sig_service = service.signature_services[target.name] or raise
|
|
180
186
|
relative_path = job.path
|
|
181
187
|
|
|
182
|
-
|
|
188
|
+
completion = Services::CompletionProvider::RBS.new(relative_path, sig_service)
|
|
189
|
+
prefix_size, type_names = completion.run(job.line, job.column)
|
|
183
190
|
|
|
184
|
-
|
|
185
|
-
when Services::SignatureService::SyntaxErrorStatus, Services::SignatureService::AncestorErrorStatus
|
|
186
|
-
if buffer = sig_service.latest_env.buffers.find {|buf| Pathname(buf.name) == Pathname(relative_path) }
|
|
187
|
-
dirs = sig_service.latest_env.signatures.fetch(buffer)[0]
|
|
188
|
-
else
|
|
189
|
-
dirs = [] #: Array[RBS::AST::Directives::t]
|
|
190
|
-
end
|
|
191
|
-
else
|
|
192
|
-
signature = sig_service.files.fetch(relative_path).signature
|
|
193
|
-
signature.is_a?(Array) or raise
|
|
194
|
-
buffer, dirs, decls = signature
|
|
195
|
-
|
|
196
|
-
locator = RBS::Locator.new(buffer: buffer, dirs: dirs, decls: decls)
|
|
197
|
-
|
|
198
|
-
_hd, tail = locator.find2(line: job.line, column: job.column)
|
|
199
|
-
tail ||= [] #: Array[RBS::Locator::component]
|
|
200
|
-
|
|
201
|
-
tail.reverse_each do |t|
|
|
202
|
-
case t
|
|
203
|
-
when RBS::AST::Declarations::Module, RBS::AST::Declarations::Class
|
|
204
|
-
if (last_type_name = context&.[](1)).is_a?(RBS::TypeName)
|
|
205
|
-
context = [context, last_type_name + t.name]
|
|
206
|
-
else
|
|
207
|
-
context = [context, t.name.absolute!]
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
buffer = RBS::Buffer.new(name: relative_path, content: sig_service.files.fetch(relative_path).content)
|
|
214
|
-
prefix = Services::TypeNameCompletion::Prefix.parse(buffer, line: job.line, column: job.column)
|
|
215
|
-
|
|
216
|
-
completion = Services::TypeNameCompletion.new(env: sig_service.latest_env, context: context, dirs: dirs)
|
|
217
|
-
type_names = completion.find_type_names(prefix)
|
|
218
|
-
prefix_size = prefix ? prefix.size : 0
|
|
219
|
-
|
|
220
|
-
completion_items = type_names.map do |type_name|
|
|
221
|
-
absolute_name, relative_name = completion.resolve_name_in_context(type_name)
|
|
191
|
+
completion_items = type_names.map do |absolute_name, relative_name|
|
|
222
192
|
format_completion_item_for_rbs(sig_service, absolute_name, job, relative_name.to_s, prefix_size)
|
|
223
193
|
end
|
|
224
194
|
|
|
225
|
-
|
|
226
|
-
completion_items << LSP::Interface::CompletionItem.new(
|
|
227
|
-
label: name,
|
|
228
|
-
detail: "(builtin type)",
|
|
229
|
-
text_edit: LSP::Interface::TextEdit.new(
|
|
230
|
-
range: LSP::Interface::Range.new(
|
|
231
|
-
start: LSP::Interface::Position.new(
|
|
232
|
-
line: job.line - 1,
|
|
233
|
-
character: job.column - prefix_size
|
|
234
|
-
),
|
|
235
|
-
end: LSP::Interface::Position.new(
|
|
236
|
-
line: job.line - 1,
|
|
237
|
-
character: job.column
|
|
238
|
-
)
|
|
239
|
-
),
|
|
240
|
-
new_text: name
|
|
241
|
-
),
|
|
242
|
-
kind: LSP::Constant::CompletionItemKind::KEYWORD,
|
|
243
|
-
filter_text: name,
|
|
244
|
-
sort_text: "zz__#{name}"
|
|
245
|
-
)
|
|
246
|
-
end
|
|
195
|
+
completion_items.concat(builtin_types(prefix_size, job.line, job.column))
|
|
247
196
|
|
|
248
197
|
LSP::Interface::CompletionList.new(
|
|
249
198
|
is_incomplete: !sig_service.status.is_a?(Services::SignatureService::LoadedStatus),
|
|
@@ -280,10 +229,13 @@ module Steep
|
|
|
280
229
|
|
|
281
230
|
case class_entry
|
|
282
231
|
when RBS::Environment::ClassEntry, RBS::Environment::ModuleEntry
|
|
283
|
-
comments = class_entry.
|
|
284
|
-
decl = class_entry.
|
|
232
|
+
comments = class_entry.each_decl.map {|decl| decl.is_a?(RBS::AST::Declarations::Base) ? decl.comment : nil }.compact
|
|
233
|
+
decl = class_entry.primary_decl
|
|
285
234
|
when RBS::Environment::ClassAliasEntry, RBS::Environment::ModuleAliasEntry
|
|
286
|
-
comments = [
|
|
235
|
+
comments = [] #: Array[RBS::AST::Comment]
|
|
236
|
+
if comment = class_entry.decl.comment
|
|
237
|
+
comments << comment
|
|
238
|
+
end
|
|
287
239
|
decl = class_entry.decl
|
|
288
240
|
end
|
|
289
241
|
|
|
@@ -476,7 +428,7 @@ module Steep
|
|
|
476
428
|
|
|
477
429
|
def process_signature_help(job)
|
|
478
430
|
Steep.logger.tagged("##{__method__}") do
|
|
479
|
-
if target = project.target_for_source_path(job.path)
|
|
431
|
+
if target = project.target_for_inline_source_path(job.path) || project.target_for_source_path(job.path)
|
|
480
432
|
file = service.source_files[job.path] or return
|
|
481
433
|
subtyping = service.signature_services.fetch(target.name).current_subtyping or return
|
|
482
434
|
source =
|
|
@@ -514,6 +466,31 @@ module Steep
|
|
|
514
466
|
# Reuse the latest result to keep SignatureHelp opened while typing
|
|
515
467
|
@last_signature_help_result if @last_signature_help_line == job.line
|
|
516
468
|
end
|
|
469
|
+
|
|
470
|
+
def builtin_types(prefix_size, line, column)
|
|
471
|
+
["untyped", "void", "bool", "class", "module", "instance", "nil", "top", "bot"].map do |name|
|
|
472
|
+
LSP::Interface::CompletionItem.new(
|
|
473
|
+
label: name,
|
|
474
|
+
detail: "(builtin type)",
|
|
475
|
+
text_edit: LSP::Interface::TextEdit.new(
|
|
476
|
+
range: LSP::Interface::Range.new(
|
|
477
|
+
start: LSP::Interface::Position.new(
|
|
478
|
+
line: line - 1,
|
|
479
|
+
character: column - prefix_size
|
|
480
|
+
),
|
|
481
|
+
end: LSP::Interface::Position.new(
|
|
482
|
+
line: line - 1,
|
|
483
|
+
character: column
|
|
484
|
+
)
|
|
485
|
+
),
|
|
486
|
+
new_text: name
|
|
487
|
+
),
|
|
488
|
+
kind: LSP::Constant::CompletionItemKind::KEYWORD,
|
|
489
|
+
filter_text: name,
|
|
490
|
+
sort_text: "zz__#{name}"
|
|
491
|
+
)
|
|
492
|
+
end
|
|
493
|
+
end
|
|
517
494
|
end
|
|
518
495
|
end
|
|
519
496
|
end
|
|
@@ -19,10 +19,10 @@ module Steep
|
|
|
19
19
|
|
|
20
20
|
def format_hover_content(content)
|
|
21
21
|
case content
|
|
22
|
-
when HoverProvider::
|
|
22
|
+
when HoverProvider::VariableContent
|
|
23
23
|
local_variable(content.name, content.type)
|
|
24
24
|
|
|
25
|
-
when HoverProvider::
|
|
25
|
+
when HoverProvider::MethodCallContent
|
|
26
26
|
io = StringIO.new
|
|
27
27
|
call = content.method_call
|
|
28
28
|
|
|
@@ -76,7 +76,7 @@ module Steep
|
|
|
76
76
|
|
|
77
77
|
io.string
|
|
78
78
|
|
|
79
|
-
when HoverProvider::
|
|
79
|
+
when HoverProvider::DefinitionContent
|
|
80
80
|
io = StringIO.new
|
|
81
81
|
|
|
82
82
|
method_name =
|
|
@@ -115,13 +115,13 @@ module Steep
|
|
|
115
115
|
)
|
|
116
116
|
|
|
117
117
|
io.string
|
|
118
|
-
when HoverProvider::
|
|
118
|
+
when HoverProvider::ConstantContent
|
|
119
119
|
io = StringIO.new
|
|
120
120
|
|
|
121
121
|
decl_summary =
|
|
122
122
|
case
|
|
123
123
|
when decl = content.class_decl
|
|
124
|
-
declaration_summary(decl.
|
|
124
|
+
declaration_summary(decl.primary_decl)
|
|
125
125
|
when decl = content.constant_decl
|
|
126
126
|
declaration_summary(decl.decl)
|
|
127
127
|
when decl = content.class_alias
|
|
@@ -144,14 +144,14 @@ module Steep
|
|
|
144
144
|
end
|
|
145
145
|
|
|
146
146
|
io.string
|
|
147
|
-
when HoverProvider::
|
|
147
|
+
when HoverProvider::TypeContent
|
|
148
148
|
<<~MD
|
|
149
149
|
```rbs
|
|
150
150
|
#{content.type}
|
|
151
151
|
```
|
|
152
152
|
MD
|
|
153
153
|
|
|
154
|
-
when HoverProvider::
|
|
154
|
+
when HoverProvider::TypeAssertionContent
|
|
155
155
|
<<~MD
|
|
156
156
|
```rbs
|
|
157
157
|
#{content.asserted_type}
|
|
@@ -160,7 +160,7 @@ module Steep
|
|
|
160
160
|
↑ Converted from `#{content.original_type.to_s}`
|
|
161
161
|
MD
|
|
162
162
|
|
|
163
|
-
when HoverProvider::
|
|
163
|
+
when HoverProvider::TypeAliasContent, HoverProvider::InterfaceTypeContent
|
|
164
164
|
io = StringIO.new()
|
|
165
165
|
|
|
166
166
|
io.puts <<~MD
|
|
@@ -178,7 +178,7 @@ module Steep
|
|
|
178
178
|
|
|
179
179
|
io.string
|
|
180
180
|
|
|
181
|
-
when HoverProvider::
|
|
181
|
+
when HoverProvider::ClassTypeContent
|
|
182
182
|
io = StringIO.new
|
|
183
183
|
|
|
184
184
|
io << <<~MD
|
|
@@ -187,7 +187,15 @@ module Steep
|
|
|
187
187
|
```
|
|
188
188
|
MD
|
|
189
189
|
|
|
190
|
-
|
|
190
|
+
comment =
|
|
191
|
+
case content.decl
|
|
192
|
+
when RBS::AST::Declarations::Base
|
|
193
|
+
content.decl.comment
|
|
194
|
+
when RBS::AST::Ruby::Declarations::Base
|
|
195
|
+
nil
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
if comment
|
|
191
199
|
io.puts "----"
|
|
192
200
|
|
|
193
201
|
class_name =
|
|
@@ -235,10 +243,24 @@ module Steep
|
|
|
235
243
|
when Services::CompletionProvider::InstanceVariableItem
|
|
236
244
|
instance_variable(item.identifier, item.type)
|
|
237
245
|
when Services::CompletionProvider::SimpleMethodNameItem
|
|
238
|
-
|
|
246
|
+
item_comment =
|
|
247
|
+
case item.method_member
|
|
248
|
+
when RBS::AST::Members::Base
|
|
249
|
+
item.method_member.comment
|
|
250
|
+
when RBS::AST::Ruby::Members::Base
|
|
251
|
+
nil
|
|
252
|
+
end
|
|
253
|
+
format_method_item_doc(item.method_types, [], { item.method_name => item_comment })
|
|
239
254
|
when Services::CompletionProvider::ComplexMethodNameItem
|
|
240
255
|
method_names = item.method_names.map(&:relative).uniq
|
|
241
|
-
comments = item.method_definitions.transform_values
|
|
256
|
+
comments = item.method_definitions.transform_values do |member|
|
|
257
|
+
case member
|
|
258
|
+
when RBS::AST::Members::Base
|
|
259
|
+
member.comment
|
|
260
|
+
when RBS::AST::Ruby::Members::Base
|
|
261
|
+
nil
|
|
262
|
+
end
|
|
263
|
+
end
|
|
242
264
|
format_method_item_doc(item.method_types, method_names, comments)
|
|
243
265
|
when Services::CompletionProvider::GeneratedMethodNameItem
|
|
244
266
|
format_method_item_doc(item.method_types, [], {}, "🤖 Generated method for receiver type")
|
|
@@ -419,6 +441,20 @@ module Steep
|
|
|
419
441
|
"#{decl.name}: #{decl.type}"
|
|
420
442
|
when RBS::AST::Declarations::Constant
|
|
421
443
|
"#{decl.name.relative!}: #{decl.type}"
|
|
444
|
+
when RBS::AST::Ruby::Declarations::ClassDecl
|
|
445
|
+
"class #{decl.class_name.relative!}"
|
|
446
|
+
when RBS::AST::Ruby::Declarations::ModuleDecl
|
|
447
|
+
"module #{decl.module_name.relative!}"
|
|
448
|
+
when RBS::AST::Ruby::Declarations::ConstantDecl
|
|
449
|
+
"#{decl.constant_name.relative!}: #{decl.type}"
|
|
450
|
+
when RBS::AST::Ruby::Declarations::ClassModuleAliasDecl
|
|
451
|
+
keyword =
|
|
452
|
+
if decl.annotation.is_a?(RBS::AST::Ruby::Annotations::ClassAliasAnnotation)
|
|
453
|
+
"class"
|
|
454
|
+
else
|
|
455
|
+
"module"
|
|
456
|
+
end
|
|
457
|
+
"#{keyword} #{decl.new_name} = #{decl.old_name}"
|
|
422
458
|
end
|
|
423
459
|
end
|
|
424
460
|
|
data/lib/steep/server/master.rb
CHANGED
|
@@ -207,14 +207,14 @@ module Steep
|
|
|
207
207
|
|
|
208
208
|
def start
|
|
209
209
|
Steep.logger.tagged "master" do
|
|
210
|
-
tags = Steep.logger.
|
|
210
|
+
tags = Steep.logger.current_tags.dup
|
|
211
211
|
|
|
212
212
|
# @type var worker_threads: Array[Thread]
|
|
213
213
|
worker_threads = []
|
|
214
214
|
|
|
215
215
|
if interaction_worker
|
|
216
216
|
worker_threads << Thread.new do
|
|
217
|
-
Steep.logger.
|
|
217
|
+
Steep.logger.push_tags(*tags, "from-worker@interaction")
|
|
218
218
|
interaction_worker.reader.read do |message|
|
|
219
219
|
job_queue << ReceiveMessageJob.new(source: interaction_worker, message: message)
|
|
220
220
|
end
|
|
@@ -223,7 +223,7 @@ module Steep
|
|
|
223
223
|
|
|
224
224
|
typecheck_workers.each do |worker|
|
|
225
225
|
worker_threads << Thread.new do
|
|
226
|
-
Steep.logger.
|
|
226
|
+
Steep.logger.push_tags(*tags, "from-worker@#{worker.name}")
|
|
227
227
|
worker.reader.read do |message|
|
|
228
228
|
job_queue << ReceiveMessageJob.new(source: worker, message: message)
|
|
229
229
|
end
|
|
@@ -238,7 +238,7 @@ module Steep
|
|
|
238
238
|
end
|
|
239
239
|
|
|
240
240
|
write_thread = Thread.new do
|
|
241
|
-
Steep.logger.
|
|
241
|
+
Steep.logger.push_tags(*tags)
|
|
242
242
|
Steep.logger.tagged "write" do
|
|
243
243
|
while job = write_queue.deq
|
|
244
244
|
# @type var job: SendMessageJob
|
|
@@ -257,7 +257,7 @@ module Steep
|
|
|
257
257
|
end
|
|
258
258
|
|
|
259
259
|
loop_thread = Thread.new do
|
|
260
|
-
Steep.logger.
|
|
260
|
+
Steep.logger.push_tags(*tags)
|
|
261
261
|
Steep.logger.tagged "main" do
|
|
262
262
|
while job = job_queue.deq
|
|
263
263
|
case job
|
|
@@ -408,7 +408,8 @@ module Steep
|
|
|
408
408
|
if content.valid_encoding?
|
|
409
409
|
content
|
|
410
410
|
else
|
|
411
|
-
|
|
411
|
+
base64_encoded = [content].pack("m")
|
|
412
|
+
{ text: base64_encoded, binary: true }
|
|
412
413
|
end
|
|
413
414
|
end
|
|
414
415
|
broadcast_notification(CustomMethods::FileLoad.notification({ content: input }))
|
|
@@ -423,7 +424,7 @@ module Steep
|
|
|
423
424
|
setup_file_system_watcher()
|
|
424
425
|
end
|
|
425
426
|
|
|
426
|
-
controller.changed_paths.clear()
|
|
427
|
+
# controller.changed_paths.clear()
|
|
427
428
|
|
|
428
429
|
# if typecheck_automatically
|
|
429
430
|
# if request = controller.make_request(guid: progress.guid, include_unchanged: true, progress: progress)
|
|
@@ -442,11 +443,9 @@ module Steep
|
|
|
442
443
|
|
|
443
444
|
path = PathHelper.to_pathname!(uri)
|
|
444
445
|
|
|
445
|
-
unless controller.
|
|
446
|
+
unless controller.open_paths.include?(path)
|
|
446
447
|
updated_watched_files << path
|
|
447
448
|
|
|
448
|
-
controller.push_changes(path)
|
|
449
|
-
|
|
450
449
|
case type
|
|
451
450
|
when LSP::Constant::FileChangeType::CREATED, LSP::Constant::FileChangeType::CHANGED
|
|
452
451
|
content = path.read
|
|
@@ -456,6 +455,15 @@ module Steep
|
|
|
456
455
|
|
|
457
456
|
content or raise
|
|
458
457
|
|
|
458
|
+
case
|
|
459
|
+
when controller.code_path?(path)
|
|
460
|
+
controller.add_dirty_code_path(path)
|
|
461
|
+
when controller.signature_path?(path)
|
|
462
|
+
controller.add_dirty_signature_path(path)
|
|
463
|
+
when controller.inline_path?(path)
|
|
464
|
+
controller.add_dirty_inline_path(path, content)
|
|
465
|
+
end
|
|
466
|
+
|
|
459
467
|
broadcast_notification(CustomMethods::FileReset.notification({ uri: uri, content: content }))
|
|
460
468
|
end
|
|
461
469
|
end
|
|
@@ -485,7 +493,21 @@ module Steep
|
|
|
485
493
|
when "textDocument/didChange"
|
|
486
494
|
if path = pathname(message[:params][:textDocument][:uri])
|
|
487
495
|
broadcast_notification(message)
|
|
488
|
-
|
|
496
|
+
|
|
497
|
+
Steep.logger.debug { path.to_s }
|
|
498
|
+
|
|
499
|
+
case
|
|
500
|
+
when controller.code_path?(path)
|
|
501
|
+
Steep.logger.debug { "code_path?" }
|
|
502
|
+
controller.add_dirty_code_path(path)
|
|
503
|
+
when controller.signature_path?(path)
|
|
504
|
+
Steep.logger.debug { "signature_path?" }
|
|
505
|
+
controller.add_dirty_signature_path(path)
|
|
506
|
+
when controller.inline_path?(path)
|
|
507
|
+
Steep.logger.debug { "inline_path?" }
|
|
508
|
+
changes = Services::ContentChange.from_lsp(message[:params][:contentChanges])
|
|
509
|
+
controller.add_dirty_inline_path(path, changes)
|
|
510
|
+
end
|
|
489
511
|
|
|
490
512
|
if typecheck_automatically
|
|
491
513
|
start_type_checking_queue.execute do
|
|
@@ -513,7 +535,12 @@ module Steep
|
|
|
513
535
|
|
|
514
536
|
if path = pathname(uri)
|
|
515
537
|
if target = project.group_for_path(path)
|
|
516
|
-
controller.
|
|
538
|
+
if controller.inline_path?(path)
|
|
539
|
+
controller.open_inline_path(path, text)
|
|
540
|
+
else
|
|
541
|
+
controller.open_path(path)
|
|
542
|
+
end
|
|
543
|
+
|
|
517
544
|
# broadcast_notification(CustomMethods::FileReset.notification({ uri: uri, content: text }))
|
|
518
545
|
|
|
519
546
|
start_type_checking_queue.execute do
|
|
@@ -525,7 +552,7 @@ module Steep
|
|
|
525
552
|
|
|
526
553
|
when "textDocument/didClose"
|
|
527
554
|
if path = pathname(message[:params][:textDocument][:uri])
|
|
528
|
-
controller.
|
|
555
|
+
controller.close_path(path)
|
|
529
556
|
end
|
|
530
557
|
|
|
531
558
|
when "textDocument/hover", "textDocument/completion", "textDocument/signatureHelp"
|
|
@@ -605,6 +632,38 @@ module Steep
|
|
|
605
632
|
)
|
|
606
633
|
end
|
|
607
634
|
|
|
635
|
+
when CustomMethods::Query__Definition::METHOD
|
|
636
|
+
params = message[:params] #: CustomMethods::Query__Definition::params
|
|
637
|
+
result_controller << group_request do |group|
|
|
638
|
+
typecheck_workers.each do |worker|
|
|
639
|
+
group << send_request(method: CustomMethods::Query__Definition::METHOD, params: params, worker: worker)
|
|
640
|
+
end
|
|
641
|
+
|
|
642
|
+
group.on_completion do |handlers|
|
|
643
|
+
kind = "unknown" #: CustomMethods::Query__Definition::kind
|
|
644
|
+
locations = [] #: Array[CustomMethods::Query__Definition::location]
|
|
645
|
+
|
|
646
|
+
handlers.each do |handler|
|
|
647
|
+
result = handler.result #: CustomMethods::Query__Definition::result
|
|
648
|
+
next unless result
|
|
649
|
+
|
|
650
|
+
if kind == "unknown"
|
|
651
|
+
kind = result[:kind]
|
|
652
|
+
end
|
|
653
|
+
locations.concat(result[:locations])
|
|
654
|
+
end
|
|
655
|
+
|
|
656
|
+
locations.uniq!
|
|
657
|
+
|
|
658
|
+
enqueue_write_job SendMessageJob.to_client(
|
|
659
|
+
message: CustomMethods::Query__Definition.response(
|
|
660
|
+
message[:id],
|
|
661
|
+
{ name: params[:name], kind: kind, locations: locations }
|
|
662
|
+
)
|
|
663
|
+
)
|
|
664
|
+
end
|
|
665
|
+
end
|
|
666
|
+
|
|
608
667
|
when CustomMethods::TypeCheck::METHOD
|
|
609
668
|
id = message[:id]
|
|
610
669
|
params = message[:params] #: CustomMethods::TypeCheck::params
|
|
@@ -621,6 +680,9 @@ module Steep
|
|
|
621
680
|
params[:library_paths].each do |target_name, path|
|
|
622
681
|
request.library_paths << [target_name.to_sym, Pathname(path)]
|
|
623
682
|
end
|
|
683
|
+
params[:inline_paths].each do |target_name, path|
|
|
684
|
+
request.inline_paths << [target_name.to_sym, Pathname(path)]
|
|
685
|
+
end
|
|
624
686
|
|
|
625
687
|
start_type_check(request: request, last_request: nil)
|
|
626
688
|
|
|
@@ -632,7 +694,12 @@ module Steep
|
|
|
632
694
|
progress = work_done_progress(SecureRandom.uuid)
|
|
633
695
|
progress.begin("Type checking #{groups.empty? ? "project" : groups.join(", ")}", request_id: fresh_request_id)
|
|
634
696
|
|
|
635
|
-
|
|
697
|
+
if groups.empty?
|
|
698
|
+
request = controller.make_all_request(progress: progress)
|
|
699
|
+
else
|
|
700
|
+
request = controller.make_group_request(groups, progress: progress)
|
|
701
|
+
end
|
|
702
|
+
|
|
636
703
|
request.needs_response = false
|
|
637
704
|
start_type_check(request: request, last_request: current_type_check_request, report_progress_threshold: 0)
|
|
638
705
|
|
|
@@ -744,7 +811,14 @@ module Steep
|
|
|
744
811
|
|
|
745
812
|
unless request
|
|
746
813
|
progress or raise
|
|
747
|
-
request =
|
|
814
|
+
request =
|
|
815
|
+
if include_unchanged
|
|
816
|
+
controller.make_all_request(guid: progress.guid, progress: progress)
|
|
817
|
+
else
|
|
818
|
+
controller.make_request(guid: progress.guid, progress: progress)
|
|
819
|
+
end
|
|
820
|
+
return unless request
|
|
821
|
+
|
|
748
822
|
request.needs_response = needs_response ? true : false
|
|
749
823
|
end
|
|
750
824
|
|
|
@@ -752,6 +826,14 @@ module Steep
|
|
|
752
826
|
request.merge!(last_request)
|
|
753
827
|
end
|
|
754
828
|
|
|
829
|
+
Steep.logger.debug {
|
|
830
|
+
{
|
|
831
|
+
code_paths: request.code_paths.map { _1[1].to_s },
|
|
832
|
+
signature_paths: request.signature_paths.map { _1[1].to_s },
|
|
833
|
+
inline_paths: request.inline_paths.map { _1[1].to_s }
|
|
834
|
+
}.inspect
|
|
835
|
+
}
|
|
836
|
+
|
|
755
837
|
if request.total > report_progress_threshold
|
|
756
838
|
request.report_progress!
|
|
757
839
|
end
|
|
@@ -854,8 +936,8 @@ module Steep
|
|
|
854
936
|
end
|
|
855
937
|
|
|
856
938
|
Thread.new do
|
|
857
|
-
tags = Steep.logger.
|
|
858
|
-
Steep.logger.
|
|
939
|
+
tags = Steep.logger.current_tags.dup
|
|
940
|
+
Steep.logger.push_tags(*tags, "from-worker@#{new_worker.name}")
|
|
859
941
|
new_worker.reader.read do |message|
|
|
860
942
|
job_queue << ReceiveMessageJob.new(source: new_worker, message: message)
|
|
861
943
|
end
|
|
@@ -936,7 +1018,7 @@ module Steep
|
|
|
936
1018
|
|
|
937
1019
|
def enqueue_write_job(job)
|
|
938
1020
|
Steep.logger.info { "Write_queue has #{write_queue.size} items"}
|
|
939
|
-
write_queue.push(job)
|
|
1021
|
+
write_queue.push(job)
|
|
940
1022
|
end
|
|
941
1023
|
|
|
942
1024
|
def work_done_progress(guid)
|