steep 0.49.1 → 0.52.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 +22 -0
- data/Gemfile +4 -1
- data/Gemfile.lock +8 -5
- data/lib/steep/ast/annotation/collection.rb +10 -8
- data/lib/steep/ast/types/factory.rb +5 -5
- data/lib/steep/cli.rb +83 -1
- data/lib/steep/diagnostic/deprecated/unknown_constant_assigned.rb +28 -0
- data/lib/steep/diagnostic/ruby.rb +21 -15
- data/lib/steep/drivers/check.rb +1 -0
- data/lib/steep/drivers/langserver.rb +2 -2
- data/lib/steep/drivers/stats.rb +1 -0
- data/lib/steep/drivers/utils/jobs_count.rb +1 -1
- data/lib/steep/drivers/watch.rb +1 -1
- data/lib/steep/index/source_index.rb +18 -1
- data/lib/steep/interface/function.rb +5 -0
- data/lib/steep/module_helper.rb +4 -7
- data/lib/steep/project.rb +15 -1
- data/lib/steep/server/interaction_worker.rb +47 -4
- data/lib/steep/server/master.rb +10 -5
- data/lib/steep/server/type_check_worker.rb +19 -4
- data/lib/steep/server/worker_process.rb +15 -6
- data/lib/steep/services/completion_provider.rb +109 -1
- data/lib/steep/services/goto_service.rb +23 -10
- data/lib/steep/services/hover_content.rb +52 -4
- data/lib/steep/services/type_check_service.rb +6 -3
- data/lib/steep/source.rb +71 -18
- data/lib/steep/type_construction.rb +209 -162
- data/lib/steep/type_inference/constant_env.rb +33 -15
- data/lib/steep/type_inference/context.rb +6 -7
- data/lib/steep/type_inference/type_env.rb +16 -54
- data/lib/steep/version.rb +1 -1
- data/smoke/const/test_expectations.yml +24 -19
- data/smoke/diagnostics/test_expectations.yml +77 -17
- data/smoke/integer/test_expectations.yml +24 -4
- data/smoke/method/test_expectations.yml +30 -0
- data/smoke/regression/test_expectations.yml +24 -0
- data/smoke/yield/test_expectations.yml +20 -0
- data/steep.gemspec +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f6846cc048d7515ef655b81cf7f399e5852a96c390d90c7f859c07cc6a5c0f94
|
4
|
+
data.tar.gz: fecb8b0b0be4e338f3ccf0375064f39167693c0b25b68e3b4ea2f103f117260f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c08fa692eda8915ef4ce4fe725aecb2a9823c2da188900a3811fdf1d02c6b0369dae8755aed83fe9cc80a376c3309df29efcf849681cd2a9a249559ff6c3ae2
|
7
|
+
data.tar.gz: 77953f34eb6ab001dfee4f03e0ec1250f1128fedae9e5b427e0037b97b6b809c5bb8ae4c94d9d93f3af3a702de7dd33a182399fe2b7a81ba8ac0d2708c422579
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,28 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.52.0 (2022-04-05)
|
6
|
+
|
7
|
+
* Add `steep binstub` command ([\#527](https://github.com/soutaro/steep/pull/527))
|
8
|
+
* Let hover and completion work in heredoc ([\#528](https://github.com/soutaro/steep/pull/528))
|
9
|
+
* Better constant typing ([\#529](https://github.com/soutaro/steep/pull/529))
|
10
|
+
|
11
|
+
## 0.51.0 (2022-04-01)
|
12
|
+
|
13
|
+
* Completion for constant ([\#524](https://github.com/soutaro/steep/pull/524))
|
14
|
+
* Better hover/completion message ([\#525](https://github.com/soutaro/steep/pull/525))
|
15
|
+
* Show available commands when using `--help` ([\#523](https://github.com/soutaro/steep/pull/523))
|
16
|
+
|
17
|
+
## 0.50.0 (2022-03-22)
|
18
|
+
|
19
|
+
* CLI option for override steep command at spawn worker ([\#511](https://github.com/soutaro/steep/pull/511))
|
20
|
+
* LSP related improvements for Sublime LSP ([\#513](https://github.com/soutaro/steep/pull/513))
|
21
|
+
* Support Windows environment ([\#514](https://github.com/soutaro/steep/pull/514))
|
22
|
+
* Let `&:foo` proc work with methods with optional parameters ([\#516](https://github.com/soutaro/steep/pull/516))
|
23
|
+
* Fix unexpected error when or-asgn/and-asgn ([\#517](https://github.com/soutaro/steep/pull/517))
|
24
|
+
* Fix goto-definition from method call inside block ([\#518](https://github.com/soutaro/steep/pull/518))
|
25
|
+
* Better splat in array typing ([\#519](https://github.com/soutaro/steep/pull/519))
|
26
|
+
|
5
27
|
## 0.49.1 (2022-03-11)
|
6
28
|
|
7
29
|
* Fix lambda typing ([\#506](https://github.com/soutaro/steep/pull/506))
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
steep (0.
|
4
|
+
steep (0.52.0)
|
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.
|
11
|
+
rbs (>= 2.3.0)
|
12
12
|
terminal-table (>= 2, < 4)
|
13
13
|
|
14
14
|
PATH
|
@@ -30,7 +30,7 @@ GEM
|
|
30
30
|
minitest (>= 5.1)
|
31
31
|
tzinfo (~> 2.0)
|
32
32
|
ast (2.4.2)
|
33
|
-
concurrent-ruby (1.1.
|
33
|
+
concurrent-ruby (1.1.10)
|
34
34
|
ffi (1.15.5)
|
35
35
|
i18n (1.10.0)
|
36
36
|
concurrent-ruby (~> 1.0)
|
@@ -41,7 +41,9 @@ GEM
|
|
41
41
|
minitest (5.15.0)
|
42
42
|
minitest-hooks (1.5.0)
|
43
43
|
minitest (> 5.3)
|
44
|
-
|
44
|
+
minitest-slow_test (0.2.0)
|
45
|
+
minitest (>= 5.0)
|
46
|
+
parallel (1.22.1)
|
45
47
|
parser (3.1.1.0)
|
46
48
|
ast (~> 2.4.1)
|
47
49
|
rainbow (3.1.1)
|
@@ -49,7 +51,7 @@ GEM
|
|
49
51
|
rb-fsevent (0.11.1)
|
50
52
|
rb-inotify (0.10.1)
|
51
53
|
ffi (~> 1.0)
|
52
|
-
rbs (2.
|
54
|
+
rbs (2.3.1)
|
53
55
|
stackprof (0.2.19)
|
54
56
|
terminal-table (3.0.2)
|
55
57
|
unicode-display_width (>= 1.1.1, < 3)
|
@@ -63,6 +65,7 @@ PLATFORMS
|
|
63
65
|
DEPENDENCIES
|
64
66
|
minitest (~> 5.15)
|
65
67
|
minitest-hooks
|
68
|
+
minitest-slow_test
|
66
69
|
rake
|
67
70
|
stackprof
|
68
71
|
steep!
|
@@ -4,7 +4,7 @@ module Steep
|
|
4
4
|
class Collection
|
5
5
|
attr_reader :annotations
|
6
6
|
attr_reader :factory
|
7
|
-
attr_reader :
|
7
|
+
attr_reader :context
|
8
8
|
|
9
9
|
attr_reader :var_type_annotations
|
10
10
|
attr_reader :const_type_annotations
|
@@ -19,10 +19,10 @@ module Steep
|
|
19
19
|
attr_reader :dynamic_annotations
|
20
20
|
attr_reader :break_type_annotation
|
21
21
|
|
22
|
-
def initialize(annotations:, factory:,
|
22
|
+
def initialize(annotations:, factory:, context:)
|
23
23
|
@annotations = annotations
|
24
24
|
@factory = factory
|
25
|
-
@
|
25
|
+
@context = context
|
26
26
|
|
27
27
|
@var_type_annotations = {}
|
28
28
|
@method_type_annotations = {}
|
@@ -64,7 +64,7 @@ module Steep
|
|
64
64
|
|
65
65
|
def absolute_type(type)
|
66
66
|
if type
|
67
|
-
factory.absolute_type(type,
|
67
|
+
factory.absolute_type(type, context: context)
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
@@ -140,7 +140,7 @@ module Steep
|
|
140
140
|
end
|
141
141
|
|
142
142
|
def merge_block_annotations(annotations)
|
143
|
-
if annotations.
|
143
|
+
if annotations.context != context || annotations.factory != factory
|
144
144
|
raise "Cannot merge another annotation: self=#{self}, other=#{annotations}"
|
145
145
|
end
|
146
146
|
|
@@ -148,9 +148,11 @@ module Steep
|
|
148
148
|
annotation.is_a?(BlockType) || annotation.is_a?(BreakType)
|
149
149
|
end
|
150
150
|
|
151
|
-
self.class.new(
|
152
|
-
|
153
|
-
|
151
|
+
self.class.new(
|
152
|
+
annotations: retained_annotations + annotations.annotations,
|
153
|
+
factory: factory,
|
154
|
+
context: context
|
155
|
+
)
|
154
156
|
end
|
155
157
|
|
156
158
|
def any?(&block)
|
@@ -18,7 +18,7 @@ module Steep
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def type_name_resolver
|
21
|
-
@type_name_resolver ||= RBS::TypeNameResolver.
|
21
|
+
@type_name_resolver ||= RBS::Resolver::TypeNameResolver.new(definition_builder.env)
|
22
22
|
end
|
23
23
|
|
24
24
|
def type_opt(type)
|
@@ -810,15 +810,15 @@ module Steep
|
|
810
810
|
@env ||= definition_builder.env
|
811
811
|
end
|
812
812
|
|
813
|
-
def absolute_type(type,
|
813
|
+
def absolute_type(type, context:)
|
814
814
|
absolute_type = type_1(type).map_type_name do |name|
|
815
|
-
absolute_type_name(name,
|
815
|
+
absolute_type_name(name, context: context) || name.absolute!
|
816
816
|
end
|
817
817
|
type(absolute_type)
|
818
818
|
end
|
819
819
|
|
820
|
-
def absolute_type_name(type_name,
|
821
|
-
type_name_resolver.resolve(type_name, context:
|
820
|
+
def absolute_type_name(type_name, context:)
|
821
|
+
type_name_resolver.resolve(type_name, context: context)
|
822
822
|
end
|
823
823
|
|
824
824
|
def instance_type(type_name, args: nil, location: nil)
|
data/lib/steep/cli.rb
CHANGED
@@ -18,11 +18,19 @@ 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
|
25
25
|
OptionParser.new do |opts|
|
26
|
+
opts.banner = <<~USAGE
|
27
|
+
Usage: steep [options]
|
28
|
+
|
29
|
+
available commands: #{CLI.available_commands.join(', ')}
|
30
|
+
|
31
|
+
Options:
|
32
|
+
USAGE
|
33
|
+
|
26
34
|
opts.on("--version") do
|
27
35
|
process_version
|
28
36
|
exit 0
|
@@ -72,6 +80,11 @@ module Steep
|
|
72
80
|
opts.on("-j N", "--jobs=N", "Specify the number of type check workers (defaults: #{default})") do |count|
|
73
81
|
command.jobs_count = Integer(count) if Integer(count) > 0
|
74
82
|
end
|
83
|
+
|
84
|
+
command.steep_command = "steep"
|
85
|
+
opts.on("--steep-command=COMMAND", "Specify command to exec Steep CLI for worker (defaults: steep)") do |cmd|
|
86
|
+
command.steep_command = cmd
|
87
|
+
end
|
75
88
|
end
|
76
89
|
|
77
90
|
def process_init
|
@@ -195,6 +208,75 @@ module Steep
|
|
195
208
|
end.run
|
196
209
|
end
|
197
210
|
|
211
|
+
def process_binstub
|
212
|
+
path = Pathname("bin/steep")
|
213
|
+
force = false
|
214
|
+
|
215
|
+
OptionParser.new do |opts|
|
216
|
+
opts.banner = <<BANNER
|
217
|
+
Usage: steep binstub [options]
|
218
|
+
|
219
|
+
Generate a binstub to execute Steep with setting up Bundler and rbenv/rvm.
|
220
|
+
Use the executable for LSP integration setup.
|
221
|
+
|
222
|
+
Options:
|
223
|
+
BANNER
|
224
|
+
handle_logging_options opts
|
225
|
+
|
226
|
+
opts.on("-o PATH", "--output=PATH", "The path of the executable file (defaults to `bin/steep`)") do |v|
|
227
|
+
path = Pathname(v)
|
228
|
+
end
|
229
|
+
|
230
|
+
opts.on("--[no-]force", "Overwrite file (defaults to false)") do
|
231
|
+
force = true
|
232
|
+
end
|
233
|
+
end.parse!(argv)
|
234
|
+
|
235
|
+
path.parent.mkpath
|
236
|
+
|
237
|
+
gemfile_path =
|
238
|
+
if defined?(Bundler)
|
239
|
+
Bundler.default_gemfile.relative_path_from(Pathname.pwd + path.parent)
|
240
|
+
else
|
241
|
+
Pathname("../Gemfile")
|
242
|
+
end
|
243
|
+
|
244
|
+
if path.file?
|
245
|
+
if force
|
246
|
+
stdout.puts Rainbow("#{path} already exists. Overwriting...").yellow
|
247
|
+
else
|
248
|
+
stdout.puts Rainbow(''"⚠️ #{path} already exists. Bye! 👋").red
|
249
|
+
return 0
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
template = <<TEMPLATE
|
254
|
+
#!/usr/bin/env bash
|
255
|
+
|
256
|
+
BINSTUB_DIR=$(cd $(dirname $0); pwd)
|
257
|
+
GEMFILE=${BINSTUB_DIR}/#{gemfile_path}
|
258
|
+
|
259
|
+
STEEP="bundle exec --gemfile=${GEMFILE} steep"
|
260
|
+
|
261
|
+
if type "rbenv" > /dev/null 2>&1; then
|
262
|
+
STEEP="rbenv exec ${STEEP}"
|
263
|
+
else
|
264
|
+
if type "rvm" > /dev/null 2>&1; then
|
265
|
+
STEEP="rvm ${REPO_ROOT} do ${STEEP}"
|
266
|
+
fi
|
267
|
+
fi
|
268
|
+
|
269
|
+
exec $STEEP $@
|
270
|
+
TEMPLATE
|
271
|
+
|
272
|
+
path.write(template)
|
273
|
+
path.chmod(0755)
|
274
|
+
|
275
|
+
stdout.puts Rainbow("Successfully generated executable #{path} 🎉").blue
|
276
|
+
|
277
|
+
0
|
278
|
+
end
|
279
|
+
|
198
280
|
def process_version
|
199
281
|
stdout.puts Steep::VERSION
|
200
282
|
0
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Steep.logger.error "Diagnostic `Ruby::UnknownConstantAssigned` is deprecated. Use `Ruby::UnknownConstant` instead."
|
2
|
+
|
3
|
+
module Steep
|
4
|
+
module Diagnostic
|
5
|
+
module Ruby
|
6
|
+
class UnknownConstantAssigned < Base
|
7
|
+
attr_reader :context
|
8
|
+
attr_reader :name
|
9
|
+
|
10
|
+
def initialize(node:, context:, name:)
|
11
|
+
const = node.children[0]
|
12
|
+
loc = if const
|
13
|
+
const.loc.expression.join(node.loc.name)
|
14
|
+
else
|
15
|
+
node.loc.name
|
16
|
+
end
|
17
|
+
super(node: node, location: loc)
|
18
|
+
@context = context
|
19
|
+
@name = name
|
20
|
+
end
|
21
|
+
|
22
|
+
def header_line
|
23
|
+
"Cannot find the declaration of constant `#{name}`"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -551,27 +551,33 @@ module Steep
|
|
551
551
|
end
|
552
552
|
end
|
553
553
|
|
554
|
-
class
|
555
|
-
attr_reader :context
|
554
|
+
class UnknownConstant < Base
|
556
555
|
attr_reader :name
|
556
|
+
attr_reader :kind
|
557
557
|
|
558
|
-
def initialize(node:,
|
559
|
-
|
560
|
-
loc = if const
|
561
|
-
const.loc.expression.join(node.loc.name)
|
562
|
-
else
|
563
|
-
node.loc.name
|
564
|
-
end
|
565
|
-
super(node: node, location: loc)
|
566
|
-
@context = context
|
558
|
+
def initialize(node:, name:)
|
559
|
+
super(node: node, location: node.loc.name)
|
567
560
|
@name = name
|
561
|
+
@kind = :constant
|
562
|
+
end
|
563
|
+
|
564
|
+
def class!
|
565
|
+
@kind = :class
|
566
|
+
self
|
567
|
+
end
|
568
|
+
|
569
|
+
def module!
|
570
|
+
@kind = :module
|
571
|
+
self
|
568
572
|
end
|
569
573
|
|
570
574
|
def header_line
|
571
|
-
"Cannot find the declaration of
|
575
|
+
"Cannot find the declaration of #{kind}: `#{name}`"
|
572
576
|
end
|
573
577
|
end
|
574
578
|
|
579
|
+
autoload :UnknownConstantAssigned, "steep/diagnostic/deprecated/unknown_constant_assigned"
|
580
|
+
|
575
581
|
class FallbackAny < Base
|
576
582
|
def initialize(node:)
|
577
583
|
super(node: node)
|
@@ -744,7 +750,7 @@ module Steep
|
|
744
750
|
ImplicitBreakValueMismatch => :warning,
|
745
751
|
FallbackAny => :information,
|
746
752
|
ElseOnExhaustiveCase => :warning,
|
747
|
-
|
753
|
+
UnknownConstant => :warning,
|
748
754
|
MethodDefinitionMissing => :information
|
749
755
|
}
|
750
756
|
).freeze
|
@@ -757,7 +763,7 @@ module Steep
|
|
757
763
|
ImplicitBreakValueMismatch => nil,
|
758
764
|
FallbackAny => nil,
|
759
765
|
ElseOnExhaustiveCase => nil,
|
760
|
-
|
766
|
+
UnknownConstant => nil,
|
761
767
|
MethodDefinitionMissing => nil
|
762
768
|
}
|
763
769
|
).freeze
|
@@ -770,7 +776,7 @@ module Steep
|
|
770
776
|
ImplicitBreakValueMismatch => nil,
|
771
777
|
FallbackAny => nil,
|
772
778
|
ElseOnExhaustiveCase => nil,
|
773
|
-
|
779
|
+
UnknownConstant => nil,
|
774
780
|
MethodDefinitionMissing => nil,
|
775
781
|
UnexpectedJump => nil
|
776
782
|
}
|
data/lib/steep/drivers/check.rb
CHANGED
@@ -37,8 +37,8 @@ module Steep
|
|
37
37
|
def run
|
38
38
|
@project = load_config()
|
39
39
|
|
40
|
-
interaction_worker = Server::WorkerProcess.spawn_worker(:interaction, name: "interaction", steepfile: project.steepfile_path)
|
41
|
-
typecheck_workers = Server::WorkerProcess.spawn_typecheck_workers(steepfile: project.steepfile_path, args: [], count: jobs_count)
|
40
|
+
interaction_worker = Server::WorkerProcess.spawn_worker(:interaction, name: "interaction", steepfile: project.steepfile_path, steep_command: steep_command)
|
41
|
+
typecheck_workers = Server::WorkerProcess.spawn_typecheck_workers(steepfile: project.steepfile_path, args: [], steep_command: steep_command, count: jobs_count)
|
42
42
|
|
43
43
|
master = Server::Master.new(
|
44
44
|
project: project,
|
data/lib/steep/drivers/stats.rb
CHANGED
data/lib/steep/drivers/watch.rb
CHANGED
@@ -41,7 +41,7 @@ module Steep
|
|
41
41
|
server_reader = LanguageServer::Protocol::Transport::Io::Reader.new(server_read)
|
42
42
|
server_writer = LanguageServer::Protocol::Transport::Io::Writer.new(server_write)
|
43
43
|
|
44
|
-
typecheck_workers = Server::WorkerProcess.spawn_typecheck_workers(steepfile: project.steepfile_path, args: dirs.map(&:to_s), count: jobs_count)
|
44
|
+
typecheck_workers = Server::WorkerProcess.spawn_typecheck_workers(steepfile: project.steepfile_path, args: dirs.map(&:to_s), steep_command: steep_command, count: jobs_count)
|
45
45
|
|
46
46
|
master = Server::Master.new(
|
47
47
|
project: project,
|
@@ -16,7 +16,7 @@ module Steep
|
|
16
16
|
|
17
17
|
def add_definition(node)
|
18
18
|
case node.type
|
19
|
-
when :casgn, :
|
19
|
+
when :casgn, :const
|
20
20
|
@definitions << node
|
21
21
|
else
|
22
22
|
raise "Unexpected constant definition: #{node.type}"
|
@@ -145,6 +145,23 @@ module Steep
|
|
145
145
|
raise
|
146
146
|
end
|
147
147
|
end
|
148
|
+
|
149
|
+
def reference(constant_node: nil)
|
150
|
+
case
|
151
|
+
when constant_node
|
152
|
+
constant_index.each do |name, entry|
|
153
|
+
if entry.references.include?(constant_node)
|
154
|
+
return name
|
155
|
+
end
|
156
|
+
|
157
|
+
if entry.definitions.include?(constant_node)
|
158
|
+
return name
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
nil
|
163
|
+
end
|
164
|
+
end
|
148
165
|
end
|
149
166
|
end
|
150
167
|
end
|
@@ -879,6 +879,11 @@ module Steep
|
|
879
879
|
!has_positional? && !has_keywords?
|
880
880
|
end
|
881
881
|
|
882
|
+
# Returns true if all arguments are non-required.
|
883
|
+
def optional?
|
884
|
+
required.empty? && required_keywords.empty?
|
885
|
+
end
|
886
|
+
|
882
887
|
# self + params returns a new params for overloading.
|
883
888
|
#
|
884
889
|
def +(other)
|
data/lib/steep/module_helper.rb
CHANGED
@@ -1,12 +1,9 @@
|
|
1
1
|
module Steep
|
2
2
|
module ModuleHelper
|
3
|
-
def module_name_from_node(
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
name = node.children[1]
|
8
|
-
RBS::TypeName.new(name: name, namespace: namespace)
|
9
|
-
end
|
3
|
+
def module_name_from_node(parent_node, constant_name)
|
4
|
+
namespace = namespace_from_node(parent_node) or return
|
5
|
+
name = constant_name
|
6
|
+
RBS::TypeName.new(name: name, namespace: namespace)
|
10
7
|
end
|
11
8
|
|
12
9
|
def namespace_from_node(node)
|
data/lib/steep/project.rb
CHANGED
@@ -16,7 +16,21 @@ module Steep
|
|
16
16
|
steepfile_path.parent
|
17
17
|
end
|
18
18
|
|
19
|
-
def relative_path(
|
19
|
+
def relative_path(orig_path)
|
20
|
+
path = if Gem.win_platform?
|
21
|
+
path_str = URI.decode_www_form_component(
|
22
|
+
orig_path.to_s.delete_prefix("/")
|
23
|
+
)
|
24
|
+
unless path_str.start_with?(%r{[a-z]:/}i)
|
25
|
+
# FIXME: Sometimes drive letter is missing, taking from base_dir
|
26
|
+
path_str = base_dir.to_s.split("/")[0] + "/" + path_str
|
27
|
+
end
|
28
|
+
Pathname.new(
|
29
|
+
path_str
|
30
|
+
)
|
31
|
+
else
|
32
|
+
orig_path
|
33
|
+
end
|
20
34
|
path.relative_path_from(base_dir)
|
21
35
|
end
|
22
36
|
|
@@ -89,7 +89,7 @@ module Steep
|
|
89
89
|
end
|
90
90
|
|
91
91
|
LSP::Interface::Hover.new(
|
92
|
-
contents: { kind: "markdown", value: format_hover(content) },
|
92
|
+
contents: { kind: "markdown", value: format_hover(content)&.gsub(/<!--(?~-->)-->/, "") },
|
93
93
|
range: range
|
94
94
|
)
|
95
95
|
end
|
@@ -175,6 +175,21 @@ HOVER
|
|
175
175
|
end
|
176
176
|
|
177
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")
|
178
193
|
when Services::HoverContent::TypeContent
|
179
194
|
"`#{content.type}`"
|
180
195
|
end
|
@@ -271,7 +286,7 @@ HOVER
|
|
271
286
|
),
|
272
287
|
end: LanguageServer::Protocol::Interface::Position.new(
|
273
288
|
line: job.line - 1,
|
274
|
-
character: job.column
|
289
|
+
character: job.column
|
275
290
|
)
|
276
291
|
)
|
277
292
|
|
@@ -327,7 +342,16 @@ HOVER
|
|
327
342
|
if comment
|
328
343
|
LSP::Interface::MarkupContent.new(
|
329
344
|
kind: LSP::Constant::MarkupKind::MARKDOWN,
|
330
|
-
value: comment.string
|
345
|
+
value: comment.string.gsub(/<!--(?~-->)-->/, "")
|
346
|
+
)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
def format_comments(comments)
|
351
|
+
unless comments.empty?
|
352
|
+
LSP::Interface::MarkupContent.new(
|
353
|
+
kind: LSP::Constant::MarkupKind::MARKDOWN,
|
354
|
+
value: comments.map(&:string).join("\n----\n").gsub(/<!--(?~-->)-->/, "")
|
331
355
|
)
|
332
356
|
end
|
333
357
|
end
|
@@ -408,6 +432,25 @@ HOVER
|
|
408
432
|
new_text: item.identifier
|
409
433
|
)
|
410
434
|
)
|
435
|
+
when Services::CompletionProvider::ConstantItem
|
436
|
+
case
|
437
|
+
when item.class? || item.module?
|
438
|
+
kind = LanguageServer::Protocol::Constant::CompletionItemKind::CLASS
|
439
|
+
detail = item.full_name.to_s
|
440
|
+
else
|
441
|
+
kind = LanguageServer::Protocol::Constant::CompletionItemKind::CONSTANT
|
442
|
+
detail = item.type.to_s
|
443
|
+
end
|
444
|
+
LanguageServer::Protocol::Interface::CompletionItem.new(
|
445
|
+
label: item.identifier,
|
446
|
+
kind: kind,
|
447
|
+
detail: detail,
|
448
|
+
documentation: format_comments(item.comments),
|
449
|
+
text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
|
450
|
+
range: range,
|
451
|
+
new_text: item.identifier
|
452
|
+
)
|
453
|
+
)
|
411
454
|
when Services::CompletionProvider::MethodNameItem
|
412
455
|
method_type_snippet = method_type_to_snippet(item.method_type)
|
413
456
|
LanguageServer::Protocol::Interface::CompletionItem.new(
|
@@ -418,7 +461,7 @@ HOVER
|
|
418
461
|
new_text: "#{item.identifier}#{method_type_snippet}",
|
419
462
|
range: range
|
420
463
|
),
|
421
|
-
documentation: item.comment
|
464
|
+
documentation: format_comment(item.comment),
|
422
465
|
insert_text_format: LanguageServer::Protocol::Constant::InsertTextFormat::SNIPPET,
|
423
466
|
sort_text: item.inherited? ? 'z' : 'a' # Ensure language server puts non-inherited methods before inherited methods
|
424
467
|
)
|
data/lib/steep/server/master.rb
CHANGED
@@ -49,9 +49,14 @@ module Steep
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def checking_path?(path)
|
52
|
-
library_paths.
|
53
|
-
|
54
|
-
|
52
|
+
[library_paths, signature_paths, code_paths].any? do |paths|
|
53
|
+
if Gem.win_platform?
|
54
|
+
# FIXME: Sometimes drive letter is missing, so comparing without drive letter.
|
55
|
+
paths.any? {|p| p.to_s.split("/", 2)[1] == path.to_s.split("/", 2)[1]}
|
56
|
+
else
|
57
|
+
paths.include?(path)
|
58
|
+
end
|
59
|
+
end
|
55
60
|
end
|
56
61
|
|
57
62
|
def checked(path)
|
@@ -496,7 +501,7 @@ module Steep
|
|
496
501
|
partialResult: true
|
497
502
|
},
|
498
503
|
completion_provider: LSP::Interface::CompletionOptions.new(
|
499
|
-
trigger_characters: [".", "@"],
|
504
|
+
trigger_characters: [".", "@", ":"],
|
500
505
|
work_done_progress: true
|
501
506
|
),
|
502
507
|
workspace_symbol_provider: true,
|
@@ -739,7 +744,7 @@ module Steep
|
|
739
744
|
{ kind: "end" }
|
740
745
|
else
|
741
746
|
progress_string = ("▮"*(percentage/5)) + ("▯"*(20 - percentage/5))
|
742
|
-
{ kind: "report", percentage: percentage, message: "#{progress_string}
|
747
|
+
{ kind: "report", percentage: percentage, message: "#{progress_string}" }
|
743
748
|
end
|
744
749
|
|
745
750
|
job_queue << SendMessageJob.to_client(
|