steep 0.51.0 → 0.52.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +13 -6
- data/.github/workflows/ruby.yml +3 -1
- data/CHANGELOG.md +19 -0
- data/Gemfile.lock +5 -5
- data/lib/steep/ast/types/factory.rb +2 -1
- data/lib/steep/cli.rb +79 -1
- data/lib/steep/server/interaction_worker.rb +5 -151
- data/lib/steep/server/lsp_formatter.rb +234 -0
- data/lib/steep/services/hover_provider/rbs.rb +63 -0
- data/lib/steep/services/hover_provider/ruby.rb +168 -0
- data/lib/steep/services/hover_provider/singleton_methods.rb +21 -0
- data/lib/steep/shims/filter_map.rb +30 -0
- data/lib/steep/source.rb +53 -6
- data/lib/steep/subtyping/check.rb +2 -2
- data/lib/steep/type_construction.rb +34 -7
- data/lib/steep/type_inference/context.rb +4 -0
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +13 -8
- data/smoke/diagnostics/test_expectations.yml +0 -10
- data/steep.gemspec +1 -1
- metadata +9 -5
- data/lib/steep/services/hover_content.rb +0 -254
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c9d5eb873780b31a2431d2e6c4efdc558fbb3a4a42c08cbe2580bb191db5bc8
|
4
|
+
data.tar.gz: dee794e9cb098309b9875396ed1dc9904a4c6882aeadb27c83c26604ebcbc87d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba05f88c28a78414ffcd41744558bdea978b72621f422571cb1450b7b0d56fb77c2b65329064226863db2517d4769a6f54e7c47ce92eef59d97f0403bb9e9425
|
7
|
+
data.tar.gz: 6e260b48940214b7c0910bf2678c587b469e163e70265f197ef8fd17a1703a68fd9488c77c3d1f8254939c074281717593e49812875fb705615189cd3ec4cdf0
|
data/.github/dependabot.yml
CHANGED
@@ -1,8 +1,15 @@
|
|
1
1
|
version: 2
|
2
|
+
|
2
3
|
updates:
|
3
|
-
- package-ecosystem: bundler
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
- package-ecosystem: bundler
|
5
|
+
directory: "/"
|
6
|
+
schedule:
|
7
|
+
interval: daily
|
8
|
+
time: "20:00"
|
9
|
+
open-pull-requests-limit: 10
|
10
|
+
|
11
|
+
- package-ecosystem: "github-actions"
|
12
|
+
directory: "/"
|
13
|
+
schedule:
|
14
|
+
# Check for updates to GitHub Actions every weekday
|
15
|
+
interval: "daily"
|
data/.github/workflows/ruby.yml
CHANGED
@@ -14,6 +14,7 @@ jobs:
|
|
14
14
|
container_tag:
|
15
15
|
- "2.7"
|
16
16
|
- "3.0"
|
17
|
+
- "3.1"
|
17
18
|
- "master-nightly-focal"
|
18
19
|
task:
|
19
20
|
- test
|
@@ -22,9 +23,10 @@ jobs:
|
|
22
23
|
container:
|
23
24
|
image: rubylang/ruby:${{ matrix.container_tag }}
|
24
25
|
steps:
|
25
|
-
- uses: actions/checkout@
|
26
|
+
- uses: actions/checkout@v3
|
26
27
|
- name: Run test
|
27
28
|
run: |
|
29
|
+
git config --global --add safe.directory /__w/steep/steep
|
28
30
|
ruby -v
|
29
31
|
gem install bundler
|
30
32
|
bundle install --jobs 4 --retry 3
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,25 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.52.2 (2022-05-02)
|
6
|
+
|
7
|
+
* Handle class declaration with non-const super class ([\#546](https://github.com/soutaro/steep/pull/546))
|
8
|
+
* Remove `#to_a` error message ([\#545](https://github.com/soutaro/steep/pull/545))
|
9
|
+
* Add `#filter_map` shim ([\#544](https://github.com/soutaro/steep/pull/544))
|
10
|
+
|
11
|
+
## 0.52.1 (2022-04-25)
|
12
|
+
|
13
|
+
* Better union type inference (it type checks `Array#filter_map` now!) ([\#531](https://github.com/soutaro/steep/pull/531))
|
14
|
+
* Improve method call hover message ([\#537](https://github.com/soutaro/steep/pull/537), [\#538](https://github.com/soutaro/steep/pull/538))
|
15
|
+
* Make `NilClass#!` a special method to improve flow-sensitive typing ([\#539](https://github.com/soutaro/steep/pull/539))
|
16
|
+
* Fix `steep binstub` ([\#540](https://github.com/soutaro/steep/pull/540), [\#541](https://github.com/soutaro/steep/pull/541))
|
17
|
+
|
18
|
+
## 0.52.0 (2022-04-05)
|
19
|
+
|
20
|
+
* Add `steep binstub` command ([\#527](https://github.com/soutaro/steep/pull/527))
|
21
|
+
* Let hover and completion work in heredoc ([\#528](https://github.com/soutaro/steep/pull/528))
|
22
|
+
* Better constant typing ([\#529](https://github.com/soutaro/steep/pull/529))
|
23
|
+
|
5
24
|
## 0.51.0 (2022-04-01)
|
6
25
|
|
7
26
|
* Completion for constant ([\#524](https://github.com/soutaro/steep/pull/524))
|
data/Gemfile.lock
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
steep (0.
|
4
|
+
steep (0.52.2)
|
5
5
|
activesupport (>= 5.1)
|
6
6
|
language_server-protocol (>= 3.15, < 4.0)
|
7
7
|
listen (~> 3.0)
|
8
8
|
parallel (>= 1.0.0)
|
9
9
|
parser (>= 3.0)
|
10
10
|
rainbow (>= 2.2.2, < 4.0)
|
11
|
-
rbs (>= 2.3.
|
11
|
+
rbs (>= 2.3.2)
|
12
12
|
terminal-table (>= 2, < 4)
|
13
13
|
|
14
14
|
PATH
|
@@ -24,7 +24,7 @@ PATH
|
|
24
24
|
GEM
|
25
25
|
remote: https://rubygems.org/
|
26
26
|
specs:
|
27
|
-
activesupport (7.0.2.
|
27
|
+
activesupport (7.0.2.4)
|
28
28
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
29
29
|
i18n (>= 1.6, < 2)
|
30
30
|
minitest (>= 5.1)
|
@@ -44,14 +44,14 @@ GEM
|
|
44
44
|
minitest-slow_test (0.2.0)
|
45
45
|
minitest (>= 5.0)
|
46
46
|
parallel (1.22.1)
|
47
|
-
parser (3.1.
|
47
|
+
parser (3.1.2.0)
|
48
48
|
ast (~> 2.4.1)
|
49
49
|
rainbow (3.1.1)
|
50
50
|
rake (13.0.6)
|
51
51
|
rb-fsevent (0.11.1)
|
52
52
|
rb-inotify (0.10.1)
|
53
53
|
ffi (~> 1.0)
|
54
|
-
rbs (2.3.
|
54
|
+
rbs (2.3.2)
|
55
55
|
stackprof (0.2.19)
|
56
56
|
terminal-table (3.0.2)
|
57
57
|
unicode-display_width (>= 1.1.1, < 3)
|
@@ -431,7 +431,8 @@ module Steep
|
|
431
431
|
case defined_in
|
432
432
|
when RBS::BuiltinNames::BasicObject.name,
|
433
433
|
RBS::BuiltinNames::TrueClass.name,
|
434
|
-
RBS::BuiltinNames::FalseClass.name
|
434
|
+
RBS::BuiltinNames::FalseClass.name,
|
435
|
+
AST::Builtin::NilClass.module_name
|
435
436
|
return method_type.with(
|
436
437
|
type: method_type.type.with(
|
437
438
|
return_type: AST::Types::Logic::Not.new(location: method_type.type.return_type.location)
|
data/lib/steep/cli.rb
CHANGED
@@ -18,7 +18,7 @@ module Steep
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def self.available_commands
|
21
|
-
[:init, :check, :validate, :annotations, :version, :project, :watch, :langserver, :stats]
|
21
|
+
[:init, :check, :validate, :annotations, :version, :project, :watch, :langserver, :stats, :binstub]
|
22
22
|
end
|
23
23
|
|
24
24
|
def process_global_options
|
@@ -208,6 +208,84 @@ module Steep
|
|
208
208
|
end.run
|
209
209
|
end
|
210
210
|
|
211
|
+
def process_binstub
|
212
|
+
path = Pathname("bin/steep")
|
213
|
+
root_path = Pathname.pwd
|
214
|
+
force = false
|
215
|
+
|
216
|
+
OptionParser.new do |opts|
|
217
|
+
opts.banner = <<BANNER
|
218
|
+
Usage: steep binstub [options]
|
219
|
+
|
220
|
+
Generate a binstub to execute Steep with setting up Bundler and rbenv/rvm.
|
221
|
+
Use the executable for LSP integration setup.
|
222
|
+
|
223
|
+
Options:
|
224
|
+
BANNER
|
225
|
+
handle_logging_options opts
|
226
|
+
|
227
|
+
opts.on("-o PATH", "--output=PATH", "The path of the executable file (defaults to `bin/steep`)") do |v|
|
228
|
+
path = Pathname(v)
|
229
|
+
end
|
230
|
+
|
231
|
+
opts.on("--root=PATH", "The repository root path (defaults to `.`)") do |v|
|
232
|
+
root_path = (Pathname.pwd + v).cleanpath
|
233
|
+
end
|
234
|
+
|
235
|
+
opts.on("--[no-]force", "Overwrite file (defaults to false)") do
|
236
|
+
force = true
|
237
|
+
end
|
238
|
+
end.parse!(argv)
|
239
|
+
|
240
|
+
binstub_path = (Pathname.pwd + path).cleanpath
|
241
|
+
bindir_path = binstub_path.parent
|
242
|
+
|
243
|
+
bindir_path.mkpath
|
244
|
+
|
245
|
+
gemfile_path =
|
246
|
+
if defined?(Bundler)
|
247
|
+
Bundler.default_gemfile.relative_path_from(bindir_path)
|
248
|
+
else
|
249
|
+
Pathname("../Gemfile")
|
250
|
+
end
|
251
|
+
|
252
|
+
if binstub_path.file?
|
253
|
+
if force
|
254
|
+
stdout.puts Rainbow("#{path} already exists. Overwriting...").yellow
|
255
|
+
else
|
256
|
+
stdout.puts Rainbow(''"⚠️ #{path} already exists. Bye! 👋").red
|
257
|
+
return 0
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
template = <<TEMPLATE
|
262
|
+
#!/usr/bin/env bash
|
263
|
+
|
264
|
+
BINSTUB_DIR=$(cd $(dirname $0); pwd)
|
265
|
+
GEMFILE=$(readlink -f ${BINSTUB_DIR}/#{gemfile_path})
|
266
|
+
ROOT_DIR=$(readlink -f ${BINSTUB_DIR}/#{root_path.relative_path_from(bindir_path)})
|
267
|
+
|
268
|
+
STEEP="bundle exec --gemfile=${GEMFILE} steep"
|
269
|
+
|
270
|
+
if type "rbenv" > /dev/null 2>&1; then
|
271
|
+
STEEP="rbenv exec ${STEEP}"
|
272
|
+
else
|
273
|
+
if type "rvm" > /dev/null 2>&1; then
|
274
|
+
STEEP="rvm ${ROOT_DIR} do ${STEEP}"
|
275
|
+
fi
|
276
|
+
fi
|
277
|
+
|
278
|
+
exec $STEEP $@
|
279
|
+
TEMPLATE
|
280
|
+
|
281
|
+
binstub_path.write(template)
|
282
|
+
binstub_path.chmod(0755)
|
283
|
+
|
284
|
+
stdout.puts Rainbow("Successfully generated executable #{path} 🎉").blue
|
285
|
+
|
286
|
+
0
|
287
|
+
end
|
288
|
+
|
211
289
|
def process_version
|
212
290
|
stdout.puts Steep::VERSION
|
213
291
|
0
|
@@ -78,8 +78,7 @@ module Steep
|
|
78
78
|
Steep.measure "Generating hover response" do
|
79
79
|
Steep.logger.info { "path=#{job.path}, line=#{job.line}, column=#{job.column}" }
|
80
80
|
|
81
|
-
|
82
|
-
content = hover.content_for(path: job.path, line: job.line, column: job.column)
|
81
|
+
content = Services::HoverProvider.content_for(service: service, path: job.path, line: job.line, column: job.column)
|
83
82
|
if content
|
84
83
|
range = content.location.yield_self do |location|
|
85
84
|
lsp_range = location.as_lsp_range
|
@@ -89,7 +88,10 @@ module Steep
|
|
89
88
|
end
|
90
89
|
|
91
90
|
LSP::Interface::Hover.new(
|
92
|
-
contents: {
|
91
|
+
contents: {
|
92
|
+
kind: "markdown",
|
93
|
+
value: LSPFormatter.format_hover_content(content).to_s
|
94
|
+
},
|
93
95
|
range: range
|
94
96
|
)
|
95
97
|
end
|
@@ -100,101 +102,6 @@ module Steep
|
|
100
102
|
end
|
101
103
|
end
|
102
104
|
|
103
|
-
def format_hover(content)
|
104
|
-
case content
|
105
|
-
when Services::HoverContent::TypeAliasContent
|
106
|
-
comment = content.decl.comment&.string || ''
|
107
|
-
|
108
|
-
<<-MD
|
109
|
-
#{comment}
|
110
|
-
|
111
|
-
```rbs
|
112
|
-
#{retrieve_decl_information(content.decl)}
|
113
|
-
```
|
114
|
-
MD
|
115
|
-
when Services::HoverContent::InterfaceContent
|
116
|
-
comment = content.decl.comment&.string || ''
|
117
|
-
|
118
|
-
<<-MD
|
119
|
-
#{comment}
|
120
|
-
|
121
|
-
```rbs
|
122
|
-
#{retrieve_decl_information(content.decl)}
|
123
|
-
```
|
124
|
-
MD
|
125
|
-
when Services::HoverContent::ClassContent
|
126
|
-
comment = content.decl.comment&.string || ''
|
127
|
-
|
128
|
-
<<-MD
|
129
|
-
#{comment}
|
130
|
-
|
131
|
-
```rbs
|
132
|
-
#{retrieve_decl_information(content.decl)}
|
133
|
-
```
|
134
|
-
MD
|
135
|
-
when Services::HoverContent::VariableContent
|
136
|
-
"`#{content.name}`: `#{content.type.to_s}`"
|
137
|
-
when Services::HoverContent::MethodCallContent
|
138
|
-
method_name = case content.method_name
|
139
|
-
when Services::HoverContent::InstanceMethodName
|
140
|
-
"#{content.method_name.class_name}##{content.method_name.method_name}"
|
141
|
-
when Services::HoverContent::SingletonMethodName
|
142
|
-
"#{content.method_name.class_name}.#{content.method_name.method_name}"
|
143
|
-
else
|
144
|
-
nil
|
145
|
-
end
|
146
|
-
|
147
|
-
if method_name
|
148
|
-
string = <<HOVER
|
149
|
-
```
|
150
|
-
#{method_name} ~> #{content.type}
|
151
|
-
```
|
152
|
-
HOVER
|
153
|
-
if content.definition
|
154
|
-
if content.definition.comments
|
155
|
-
string << "\n----\n\n#{content.definition.comments.map(&:string).join("\n\n")}"
|
156
|
-
end
|
157
|
-
|
158
|
-
string << "\n----\n\n#{content.definition.method_types.map {|x| "- `#{x}`\n" }.join()}"
|
159
|
-
end
|
160
|
-
else
|
161
|
-
"`#{content.type}`"
|
162
|
-
end
|
163
|
-
when Services::HoverContent::DefinitionContent
|
164
|
-
string = <<HOVER
|
165
|
-
```
|
166
|
-
def #{content.method_name}: #{content.method_type}
|
167
|
-
```
|
168
|
-
HOVER
|
169
|
-
if (comment = content.comment_string)
|
170
|
-
string << "\n----\n\n#{comment}\n"
|
171
|
-
end
|
172
|
-
|
173
|
-
if content.definition.method_types.size > 1
|
174
|
-
string << "\n----\n\n#{content.definition.method_types.map {|x| "- `#{x}`\n" }.join()}"
|
175
|
-
end
|
176
|
-
|
177
|
-
string
|
178
|
-
when Services::HoverContent::ConstantContent
|
179
|
-
ss = []
|
180
|
-
if content.class_or_module?
|
181
|
-
ss << ["```rbs", retrieve_decl_information(content.decl.primary.decl), "```"].join("\n")
|
182
|
-
end
|
183
|
-
|
184
|
-
if content.constant?
|
185
|
-
ss << ["```rbs", "#{content.full_name}: #{content.type}", "```"].join("\n")
|
186
|
-
end
|
187
|
-
|
188
|
-
if s = content.comment_string
|
189
|
-
ss << s
|
190
|
-
end
|
191
|
-
|
192
|
-
ss.join("\n\n----\n\n")
|
193
|
-
when Services::HoverContent::TypeContent
|
194
|
-
"`#{content.type}`"
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
105
|
def process_completion(job)
|
199
106
|
Steep.logger.tagged("#response_to_completion") do
|
200
107
|
Steep.measure "Generating response" do
|
@@ -356,59 +263,6 @@ HOVER
|
|
356
263
|
end
|
357
264
|
end
|
358
265
|
|
359
|
-
def name_and_params(name, params)
|
360
|
-
if params.empty?
|
361
|
-
"#{name}"
|
362
|
-
else
|
363
|
-
ps = params.each.map do |param|
|
364
|
-
s = ""
|
365
|
-
if param.unchecked?
|
366
|
-
s << "unchecked "
|
367
|
-
end
|
368
|
-
case param.variance
|
369
|
-
when :invariant
|
370
|
-
# nop
|
371
|
-
when :covariant
|
372
|
-
s << "out "
|
373
|
-
when :contravariant
|
374
|
-
s << "in "
|
375
|
-
end
|
376
|
-
s + param.name.to_s
|
377
|
-
end
|
378
|
-
|
379
|
-
"#{name}[#{ps.join(", ")}]"
|
380
|
-
end
|
381
|
-
end
|
382
|
-
|
383
|
-
def name_and_args(name, args)
|
384
|
-
if name && args
|
385
|
-
if args.empty?
|
386
|
-
"#{name}"
|
387
|
-
else
|
388
|
-
"#{name}[#{args.join(", ")}]"
|
389
|
-
end
|
390
|
-
end
|
391
|
-
end
|
392
|
-
|
393
|
-
def retrieve_decl_information(decl)
|
394
|
-
case decl
|
395
|
-
when RBS::AST::Declarations::Class
|
396
|
-
super_class = if super_class = decl.super_class
|
397
|
-
" < #{name_and_args(super_class.name, super_class.args)}"
|
398
|
-
end
|
399
|
-
"class #{name_and_params(decl.name, decl.type_params)}#{super_class}"
|
400
|
-
when RBS::AST::Declarations::Module
|
401
|
-
self_type = unless decl.self_types.empty?
|
402
|
-
" : #{decl.self_types.join(", ")}"
|
403
|
-
end
|
404
|
-
"module #{name_and_params(decl.name, decl.type_params)}#{self_type}"
|
405
|
-
when RBS::AST::Declarations::Alias
|
406
|
-
"type #{decl.name} = #{decl.type}"
|
407
|
-
when RBS::AST::Declarations::Interface
|
408
|
-
"interface #{name_and_params(decl.name, decl.type_params)}"
|
409
|
-
end
|
410
|
-
end
|
411
|
-
|
412
266
|
def format_completion_item(item)
|
413
267
|
range = LanguageServer::Protocol::Interface::Range.new(
|
414
268
|
start: LanguageServer::Protocol::Interface::Position.new(
|
@@ -0,0 +1,234 @@
|
|
1
|
+
module Steep
|
2
|
+
module Server
|
3
|
+
module LSPFormatter
|
4
|
+
include Services
|
5
|
+
|
6
|
+
class CommentBuilder
|
7
|
+
def initialize
|
8
|
+
@array = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.build
|
12
|
+
builder = CommentBuilder.new
|
13
|
+
yield builder
|
14
|
+
builder.to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
unless @array.empty?
|
19
|
+
@array.join("\n\n----\n\n")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def <<(string)
|
24
|
+
if string
|
25
|
+
s = string.rstrip.gsub(/^[ \t]*<!--(?~-->)-->\n/, "").gsub(/\A([ \t]*\n)+/, "")
|
26
|
+
unless @array.include?(s)
|
27
|
+
@array << s
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def push
|
33
|
+
s = ""
|
34
|
+
yield s
|
35
|
+
self << s
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
module_function
|
40
|
+
|
41
|
+
def format_hover_content(content)
|
42
|
+
case content
|
43
|
+
when HoverProvider::Ruby::VariableContent
|
44
|
+
"`#{content.name}`: `#{content.type.to_s}`"
|
45
|
+
|
46
|
+
when HoverProvider::Ruby::MethodCallContent
|
47
|
+
CommentBuilder.build do |builder|
|
48
|
+
call = content.method_call
|
49
|
+
builder.push do |s|
|
50
|
+
case call
|
51
|
+
when TypeInference::MethodCall::Typed
|
52
|
+
mt = call.actual_method_type.with(
|
53
|
+
type: call.actual_method_type.type.with(return_type: call.return_type)
|
54
|
+
)
|
55
|
+
s << "```rbs\n#{mt.to_s}\n```\n\n"
|
56
|
+
when TypeInference::MethodCall::Error
|
57
|
+
s << "```rbs\n( ??? ) -> #{call.return_type.to_s}\n```\n\n"
|
58
|
+
end
|
59
|
+
|
60
|
+
s << to_list(call.method_decls) do |decl|
|
61
|
+
"`#{decl.method_name}`"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
call.method_decls.each do |decl|
|
66
|
+
if comment = decl.method_def.comment
|
67
|
+
builder << <<EOM
|
68
|
+
**#{decl.method_name.to_s}**
|
69
|
+
|
70
|
+
```rbs
|
71
|
+
#{decl.method_type}
|
72
|
+
```
|
73
|
+
|
74
|
+
#{decl.method_def.comment.string.gsub(/\A([ \t]*\n)+/, "")}
|
75
|
+
EOM
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
when HoverProvider::Ruby::DefinitionContent
|
81
|
+
CommentBuilder.build do |builder|
|
82
|
+
builder << <<EOM
|
83
|
+
```
|
84
|
+
#{content.method_name}: #{content.method_type}
|
85
|
+
```
|
86
|
+
EOM
|
87
|
+
if comments = content.definition&.comments
|
88
|
+
comments.each do |comment|
|
89
|
+
builder << comment.string
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
if content.definition.method_types.size > 1
|
94
|
+
builder << to_list(content.definition.method_types) {|type| "`#{type.to_s}`" }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
when HoverProvider::Ruby::ConstantContent
|
98
|
+
CommentBuilder.build do |builder|
|
99
|
+
if content.class_or_module?
|
100
|
+
builder << <<EOM
|
101
|
+
```rbs
|
102
|
+
#{declaration_summary(content.decl.primary.decl)}
|
103
|
+
```
|
104
|
+
EOM
|
105
|
+
end
|
106
|
+
|
107
|
+
if content.constant?
|
108
|
+
builder << <<EOM
|
109
|
+
```rbs
|
110
|
+
#{content.full_name}: #{content.type}
|
111
|
+
```
|
112
|
+
EOM
|
113
|
+
end
|
114
|
+
|
115
|
+
content.comments.each do |comment|
|
116
|
+
builder << comment.string
|
117
|
+
end
|
118
|
+
end
|
119
|
+
when HoverProvider::Ruby::TypeContent
|
120
|
+
"`#{content.type}`"
|
121
|
+
when HoverProvider::RBS::TypeAliasContent
|
122
|
+
CommentBuilder.build do |builder|
|
123
|
+
builder << <<EOM
|
124
|
+
```rbs
|
125
|
+
#{declaration_summary(content.decl)}
|
126
|
+
```
|
127
|
+
EOM
|
128
|
+
if comment = content.decl.comment
|
129
|
+
builder << comment.string
|
130
|
+
end
|
131
|
+
end
|
132
|
+
when HoverProvider::RBS::ClassContent
|
133
|
+
CommentBuilder.build do |builder|
|
134
|
+
builder << <<EOM
|
135
|
+
```rbs
|
136
|
+
#{declaration_summary(content.decl)}
|
137
|
+
```
|
138
|
+
EOM
|
139
|
+
if comment = content.decl.comment
|
140
|
+
builder << comment.string
|
141
|
+
end
|
142
|
+
end
|
143
|
+
when HoverProvider::RBS::InterfaceContent
|
144
|
+
CommentBuilder.build do |builder|
|
145
|
+
builder << <<EOM
|
146
|
+
```rbs
|
147
|
+
#{declaration_summary(content.decl)}
|
148
|
+
```
|
149
|
+
EOM
|
150
|
+
if comment = content.decl.comment
|
151
|
+
builder << comment.string
|
152
|
+
end
|
153
|
+
end
|
154
|
+
else
|
155
|
+
raise content.class.to_s
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def to_list(collection, &block)
|
160
|
+
buffer = ""
|
161
|
+
|
162
|
+
strings =
|
163
|
+
if block
|
164
|
+
collection.map(&block)
|
165
|
+
else
|
166
|
+
collection.map(&:to_s)
|
167
|
+
end
|
168
|
+
|
169
|
+
strings.each do |s|
|
170
|
+
buffer << "- #{s}\n"
|
171
|
+
end
|
172
|
+
|
173
|
+
buffer
|
174
|
+
end
|
175
|
+
|
176
|
+
def name_and_args(name, args)
|
177
|
+
if args.empty?
|
178
|
+
"#{name}"
|
179
|
+
else
|
180
|
+
"#{name}[#{args.map(&:to_s).join(", ")}]"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def name_and_params(name, params)
|
185
|
+
if params.empty?
|
186
|
+
"#{name}"
|
187
|
+
else
|
188
|
+
ps = params.each.map do |param|
|
189
|
+
s = ""
|
190
|
+
if param.unchecked?
|
191
|
+
s << "unchecked "
|
192
|
+
end
|
193
|
+
case param.variance
|
194
|
+
when :invariant
|
195
|
+
# nop
|
196
|
+
when :covariant
|
197
|
+
s << "out "
|
198
|
+
when :contravariant
|
199
|
+
s << "in "
|
200
|
+
end
|
201
|
+
s << param.name.to_s
|
202
|
+
|
203
|
+
if param.upper_bound
|
204
|
+
s << " < #{param.upper_bound.to_s}"
|
205
|
+
end
|
206
|
+
|
207
|
+
s
|
208
|
+
end
|
209
|
+
|
210
|
+
"#{name}[#{ps.join(", ")}]"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def declaration_summary(decl)
|
215
|
+
case decl
|
216
|
+
when RBS::AST::Declarations::Class
|
217
|
+
super_class = if super_class = decl.super_class
|
218
|
+
" < #{name_and_args(super_class.name, super_class.args)}"
|
219
|
+
end
|
220
|
+
"class #{name_and_params(decl.name, decl.type_params)}#{super_class}"
|
221
|
+
when RBS::AST::Declarations::Module
|
222
|
+
self_type = unless decl.self_types.empty?
|
223
|
+
" : #{decl.self_types.map {|s| name_and_args(s.name, s.args) }.join(", ")}"
|
224
|
+
end
|
225
|
+
"module #{name_and_params(decl.name, decl.type_params)}#{self_type}"
|
226
|
+
when RBS::AST::Declarations::Alias
|
227
|
+
"type #{decl.name} = #{decl.type}"
|
228
|
+
when RBS::AST::Declarations::Interface
|
229
|
+
"interface #{name_and_params(decl.name, decl.type_params)}"
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|