steep 0.49.0 → 0.51.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/Gemfile +4 -1
- data/Gemfile.lock +9 -6
- data/lib/steep/ast/annotation/collection.rb +10 -8
- data/lib/steep/ast/types/factory.rb +5 -5
- data/lib/steep/cli.rb +13 -0
- data/lib/steep/diagnostic/deprecated/unknown_constant_assigned.rb +28 -0
- data/lib/steep/diagnostic/ruby.rb +34 -15
- data/lib/steep/drivers/check.rb +3 -2
- 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 +8 -3
- data/lib/steep/signature/validator.rb +12 -5
- data/lib/steep/source.rb +19 -13
- data/lib/steep/type_construction.rb +238 -170
- 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/proc_type_expected.rb +3 -0
- data/smoke/diagnostics/test_expectations.yml +92 -10
- 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 +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 502d495f9b623c5d90a041a1e0bb7854be76251a8ac0f3567c1c91911eb641ee
|
4
|
+
data.tar.gz: 7845d6d26f38ceae87407d507f3f67b8d35bae18ecdd5f4ee9fdb841d434a4ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2e61987da5ef5d78381affeb2f4fbb8b84dd2a6fede0baa60c68f54a3464e3cb7eea0e2822f22a66d62f1de3b9f8b223cd6399dceb927397a3dab0bed3fea5d
|
7
|
+
data.tar.gz: ee91ba6b1a4d8f35ec1fbc157efd2fb54f27b11e398af09a7ef3d4f403ae0ae2fab3258404316c6ded646f688b61ff38b47a514fec83cd9fe1b4fcf136fdc441
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,29 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.51.0 (2022-04-01)
|
6
|
+
|
7
|
+
* Completion for constant ([\#524](https://github.com/soutaro/steep/pull/524))
|
8
|
+
* Better hover/completion message ([\#525](https://github.com/soutaro/steep/pull/525))
|
9
|
+
* Show available commands when using `--help` ([\#523](https://github.com/soutaro/steep/pull/523))
|
10
|
+
|
11
|
+
## 0.50.0 (2022-03-22)
|
12
|
+
|
13
|
+
* CLI option for override steep command at spawn worker ([\#511](https://github.com/soutaro/steep/pull/511))
|
14
|
+
* LSP related improvements for Sublime LSP ([\#513](https://github.com/soutaro/steep/pull/513))
|
15
|
+
* Support Windows environment ([\#514](https://github.com/soutaro/steep/pull/514))
|
16
|
+
* Let `&:foo` proc work with methods with optional parameters ([\#516](https://github.com/soutaro/steep/pull/516))
|
17
|
+
* Fix unexpected error when or-asgn/and-asgn ([\#517](https://github.com/soutaro/steep/pull/517))
|
18
|
+
* Fix goto-definition from method call inside block ([\#518](https://github.com/soutaro/steep/pull/518))
|
19
|
+
* Better splat in array typing ([\#519](https://github.com/soutaro/steep/pull/519))
|
20
|
+
|
21
|
+
## 0.49.1 (2022-03-11)
|
22
|
+
|
23
|
+
* Fix lambda typing ([\#506](https://github.com/soutaro/steep/pull/506))
|
24
|
+
* Validate type descendants ([\#507](https://github.com/soutaro/steep/pull/507))
|
25
|
+
* Fix print error with absolute path ([\#508](https://github.com/soutaro/steep/pull/508))
|
26
|
+
* Skip non-target ruby code on `steep stats` ([\#509](https://github.com/soutaro/steep/pull/509))
|
27
|
+
|
5
28
|
## 0.49.0 (2022-03-08)
|
6
29
|
|
7
30
|
* Better typing for `#flat_map` ([\#504](https://github.com/soutaro/steep/pull/504))
|
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.51.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
|
@@ -24,13 +24,13 @@ PATH
|
|
24
24
|
GEM
|
25
25
|
remote: https://rubygems.org/
|
26
26
|
specs:
|
27
|
-
activesupport (7.0.2.
|
27
|
+
activesupport (7.0.2.3)
|
28
28
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
29
29
|
i18n (>= 1.6, < 2)
|
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.0)
|
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
@@ -23,6 +23,14 @@ module Steep
|
|
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
|
@@ -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)
|
@@ -669,6 +675,19 @@ module Steep
|
|
669
675
|
end
|
670
676
|
end
|
671
677
|
|
678
|
+
class ProcTypeExpected < Base
|
679
|
+
attr_reader :type
|
680
|
+
|
681
|
+
def initialize(node:, type:)
|
682
|
+
super(node: node)
|
683
|
+
@type = type
|
684
|
+
end
|
685
|
+
|
686
|
+
def header_line
|
687
|
+
"Proc type is expected but `#{type.to_s}` is specified"
|
688
|
+
end
|
689
|
+
end
|
690
|
+
|
672
691
|
class UnsupportedSyntax < Base
|
673
692
|
attr_reader :message
|
674
693
|
|
@@ -731,7 +750,7 @@ module Steep
|
|
731
750
|
ImplicitBreakValueMismatch => :warning,
|
732
751
|
FallbackAny => :information,
|
733
752
|
ElseOnExhaustiveCase => :warning,
|
734
|
-
|
753
|
+
UnknownConstant => :warning,
|
735
754
|
MethodDefinitionMissing => :information
|
736
755
|
}
|
737
756
|
).freeze
|
@@ -744,7 +763,7 @@ module Steep
|
|
744
763
|
ImplicitBreakValueMismatch => nil,
|
745
764
|
FallbackAny => nil,
|
746
765
|
ElseOnExhaustiveCase => nil,
|
747
|
-
|
766
|
+
UnknownConstant => nil,
|
748
767
|
MethodDefinitionMissing => nil
|
749
768
|
}
|
750
769
|
).freeze
|
@@ -757,7 +776,7 @@ module Steep
|
|
757
776
|
ImplicitBreakValueMismatch => nil,
|
758
777
|
FallbackAny => nil,
|
759
778
|
ElseOnExhaustiveCase => nil,
|
760
|
-
|
779
|
+
UnknownConstant => nil,
|
761
780
|
MethodDefinitionMissing => nil,
|
762
781
|
UnexpectedJump => nil
|
763
782
|
}
|
data/lib/steep/drivers/check.rb
CHANGED
@@ -39,6 +39,7 @@ module Steep
|
|
39
39
|
steepfile: project.steepfile_path,
|
40
40
|
args: command_line_patterns,
|
41
41
|
delay_shutdown: true,
|
42
|
+
steep_command: steep_command,
|
42
43
|
count: jobs_count
|
43
44
|
)
|
44
45
|
|
@@ -214,8 +215,8 @@ module Steep
|
|
214
215
|
total = errors.sum {|notification| notification[:diagnostics].size }
|
215
216
|
|
216
217
|
errors.each do |notification|
|
217
|
-
path =
|
218
|
-
buffer = RBS::Buffer.new(name: path, content: path.read)
|
218
|
+
path = Pathname(URI.parse(notification[:uri]).path)
|
219
|
+
buffer = RBS::Buffer.new(name: project.relative_path(path), content: path.read)
|
219
220
|
printer = DiagnosticPrinter.new(buffer: buffer, stdout: stdout)
|
220
221
|
|
221
222
|
notification[:diagnostics].each do |diag|
|
@@ -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(
|