steep 1.1.1 → 1.2.0.pre.1
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 +20 -0
- data/Gemfile +0 -1
- data/Gemfile.lock +12 -11
- data/Gemfile.steep +1 -1
- data/Gemfile.steep.lock +9 -9
- data/README.md +3 -3
- data/Steepfile +23 -0
- data/bin/steep-prof +2 -1
- data/lib/steep/annotation_parser.rb +1 -1
- data/lib/steep/ast/types/class.rb +4 -0
- data/lib/steep/ast/types/factory.rb +86 -602
- data/lib/steep/ast/types/instance.rb +4 -0
- data/lib/steep/ast/types/literal.rb +1 -1
- data/lib/steep/ast/types/proc.rb +22 -8
- data/lib/steep/ast/types/self.rb +4 -0
- data/lib/steep/ast/types/union.rb +1 -1
- data/lib/steep/cli.rb +24 -1
- data/lib/steep/diagnostic/ruby.rb +17 -22
- data/lib/steep/drivers/checkfile.rb +205 -0
- data/lib/steep/drivers/validate.rb +3 -1
- data/lib/steep/equatable.rb +2 -0
- data/lib/steep/interface/block.rb +21 -11
- data/lib/steep/interface/builder.rb +756 -0
- data/lib/steep/interface/function.rb +32 -24
- data/lib/steep/interface/method_type.rb +191 -78
- data/lib/steep/interface/shape.rb +132 -0
- data/lib/steep/interface/substitution.rb +23 -12
- data/lib/steep/interface/type_param.rb +1 -2
- data/lib/steep/path_helper.rb +1 -1
- data/lib/steep/project.rb +5 -7
- data/lib/steep/server/base_worker.rb +2 -2
- data/lib/steep/server/change_buffer.rb +4 -3
- data/lib/steep/server/interaction_worker.rb +1 -1
- data/lib/steep/server/master.rb +69 -9
- data/lib/steep/server/type_check_worker.rb +13 -11
- data/lib/steep/server/worker_process.rb +9 -7
- data/lib/steep/services/completion_provider.rb +15 -3
- data/lib/steep/services/hover_provider/singleton_methods.rb +5 -6
- data/lib/steep/services/signature_service.rb +13 -8
- data/lib/steep/services/type_check_service.rb +2 -0
- data/lib/steep/signature/validator.rb +1 -1
- data/lib/steep/subtyping/check.rb +154 -103
- data/lib/steep/subtyping/relation.rb +3 -3
- data/lib/steep/subtyping/result.rb +20 -2
- data/lib/steep/subtyping/variable_variance.rb +9 -0
- data/lib/steep/type_construction.rb +558 -299
- data/lib/steep/type_inference/block_params.rb +169 -86
- data/lib/steep/type_inference/logic_type_interpreter.rb +9 -14
- data/lib/steep/type_inference/method_params.rb +12 -7
- data/lib/steep/type_inference/send_args.rb +41 -35
- data/lib/steep/type_inference/type_env_builder.rb +1 -1
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +71 -2
- data/rbs_collection.steep.lock.yaml +18 -30
- data/rbs_collection.steep.yaml +1 -0
- data/sig/shims/language-server_protocol.rbs +20 -0
- data/sig/shims/tagged_logging.rbs +6 -0
- data/sig/steep/ast/annotation/collection.rbs +6 -6
- data/sig/steep/ast/types/class.rbs +3 -0
- data/sig/steep/ast/types/factory.rbs +38 -32
- data/sig/steep/ast/types/instance.rbs +3 -0
- data/sig/steep/ast/types/intersection.rbs +1 -1
- data/sig/steep/ast/types/literal.rbs +7 -7
- data/sig/steep/ast/types/name.rbs +14 -13
- data/sig/steep/ast/types/proc.rbs +3 -1
- data/sig/steep/ast/types/self.rbs +3 -0
- data/sig/steep/ast/types/var.rbs +1 -1
- data/sig/steep/diagnostic/ruby.rbs +30 -34
- data/sig/steep/drivers/annotations.rbs +17 -0
- data/sig/steep/drivers/check.rbs +33 -0
- data/sig/steep/drivers/checkfile.rbs +26 -0
- data/sig/steep/drivers/diagnostic_printer.rbs +25 -0
- data/sig/steep/drivers/init.rbs +19 -0
- data/sig/steep/drivers/langserver.rbs +35 -0
- data/sig/steep/drivers/print_project.rbs +15 -0
- data/sig/steep/drivers/stats.rbs +37 -0
- data/sig/steep/drivers/utils/driver_helper.rbs +23 -0
- data/sig/steep/drivers/utils/jobs_count.rbs +11 -0
- data/sig/steep/drivers/validate.rbs +15 -0
- data/sig/steep/drivers/vendor.rbs +19 -0
- data/sig/steep/drivers/watch.rbs +27 -0
- data/sig/steep/drivers/worker.rbs +31 -0
- data/sig/steep/equatable.rbs +11 -0
- data/sig/steep/index/rbs_index.rbs +91 -0
- data/sig/steep/index/signature_symbol_provider.rbs +29 -0
- data/sig/steep/index/source_index.rbs +63 -0
- data/sig/steep/interface/block.rbs +3 -1
- data/sig/steep/interface/builder.rbs +152 -0
- data/sig/steep/interface/function.rbs +67 -55
- data/sig/steep/interface/method_type.rbs +60 -12
- data/sig/steep/interface/shape.rbs +61 -0
- data/sig/steep/interface/substitution.rbs +18 -22
- data/sig/steep/interface/type_param.rbs +9 -1
- data/sig/steep/path_helper.rbs +7 -0
- data/sig/steep/project/pattern.rbs +10 -10
- data/sig/steep/project/target.rbs +2 -2
- data/sig/steep/project.rbs +15 -8
- data/sig/steep/server/base_worker.rbs +49 -0
- data/sig/steep/server/change_buffer.rbs +32 -0
- data/sig/steep/server/interaction_worker.rbs +41 -0
- data/sig/steep/server/lsp_formatter.rbs +29 -0
- data/sig/steep/server/master.rbs +260 -0
- data/sig/steep/server/type_check_worker.rbs +135 -0
- data/sig/steep/server/worker_process.rbs +29 -0
- data/sig/steep/services/completion_provider.rbs +5 -5
- data/sig/steep/services/content_change.rbs +14 -12
- data/sig/steep/services/file_loader.rbs +12 -4
- data/sig/steep/services/hover_provider/singleton_methods.rbs +1 -1
- data/sig/steep/services/path_assignment.rbs +7 -7
- data/sig/steep/services/signature_service.rbs +67 -40
- data/sig/steep/services/type_check_service.rbs +53 -39
- data/sig/steep/subtyping/check.rbs +80 -44
- data/sig/steep/subtyping/relation.rbs +24 -22
- data/sig/steep/subtyping/result.rbs +48 -30
- data/sig/steep/subtyping/variable_variance.rbs +2 -0
- data/sig/steep/type_construction.rbs +132 -23
- data/sig/steep/type_inference/block_params.rbs +120 -18
- data/sig/steep/type_inference/context.rbs +45 -20
- data/sig/steep/type_inference/context_array.rbs +37 -0
- data/sig/steep/type_inference/logic_type_interpreter.rbs +3 -1
- data/sig/steep/type_inference/method_params.rbs +13 -9
- data/sig/steep/type_inference/send_args.rbs +229 -0
- data/sig/steep/type_inference/type_env_builder.rbs +1 -1
- data/sig/steep/typing.rbs +4 -4
- data/sig/steep.rbs +4 -2
- data/smoke/block/e.rb +12 -0
- data/smoke/block/e.rbs +4 -0
- data/smoke/block/test_expectations.yml +12 -0
- data/smoke/regression/block_param_split.rb +7 -0
- data/smoke/regression/block_param_split.rbs +3 -0
- data/smoke/regression/empty_yield.rb +5 -0
- data/smoke/regression/empty_yield.rbs +3 -0
- data/smoke/regression/test_expectations.yml +12 -0
- data/smoke/yield/test_expectations.yml +4 -4
- data/steep.gemspec +2 -1
- metadata +61 -9
- data/lib/steep/interface/interface.rb +0 -34
- data/sig/steep/interface/interface.rbs +0 -23
- data/sig/version.rbs +0 -3
data/lib/steep/ast/types/proc.rb
CHANGED
@@ -4,20 +4,22 @@ module Steep
|
|
4
4
|
class Proc
|
5
5
|
attr_reader :location
|
6
6
|
attr_reader :type
|
7
|
+
attr_reader :self_type
|
7
8
|
attr_reader :block
|
8
9
|
|
9
|
-
def initialize(type:, block:, location: type.location)
|
10
|
+
def initialize(type:, block:, self_type:, location: type.location)
|
10
11
|
@type = type
|
11
12
|
@block = block
|
13
|
+
@self_type = self_type
|
12
14
|
@location = location
|
13
15
|
end
|
14
16
|
|
15
17
|
def ==(other)
|
16
|
-
other.is_a?(self.class) && other.type == type && other.block == block
|
18
|
+
other.is_a?(self.class) && other.type == type && other.block == block && other.self_type == self_type
|
17
19
|
end
|
18
20
|
|
19
21
|
def hash
|
20
|
-
self.class.hash ^ type.hash ^ block.hash
|
22
|
+
self.class.hash ^ type.hash ^ block.hash ^ self_type.hash
|
21
23
|
end
|
22
24
|
|
23
25
|
alias eql? ==
|
@@ -26,15 +28,21 @@ module Steep
|
|
26
28
|
self.class.new(
|
27
29
|
type: type.subst(s),
|
28
30
|
block: block&.subst(s),
|
31
|
+
self_type: self_type&.subst(s),
|
29
32
|
location: location
|
30
33
|
)
|
31
34
|
end
|
32
35
|
|
33
36
|
def to_s
|
37
|
+
s =
|
38
|
+
if self_type
|
39
|
+
"[self: #{self_type}] "
|
40
|
+
end
|
41
|
+
|
34
42
|
if block
|
35
|
-
"^#{type.params} #{block} -> #{type.return_type}"
|
43
|
+
"^#{type.params} #{s}#{block} -> #{type.return_type}"
|
36
44
|
else
|
37
|
-
"^#{type.params} -> #{type.return_type}"
|
45
|
+
"^#{type.params} #{s}-> #{type.return_type}"
|
38
46
|
end
|
39
47
|
end
|
40
48
|
|
@@ -42,6 +50,7 @@ module Steep
|
|
42
50
|
@fvs ||= Set[].tap do |fvs|
|
43
51
|
fvs.merge(type.free_variables)
|
44
52
|
fvs.merge(block.free_variables) if block
|
53
|
+
fvs.merge(self_type.free_variables) if self_type
|
45
54
|
end
|
46
55
|
end
|
47
56
|
|
@@ -53,21 +62,25 @@ module Steep
|
|
53
62
|
children.push(*block.type.params.each_type.to_a)
|
54
63
|
children.push(block.type.return_type)
|
55
64
|
end
|
65
|
+
if self_type
|
66
|
+
children.push(self_type)
|
67
|
+
end
|
56
68
|
[0] + level_of_children(children)
|
57
69
|
end
|
58
70
|
|
59
71
|
def closed?
|
60
|
-
type.closed? && (block.nil? || block.closed?)
|
72
|
+
type.closed? && (block.nil? || block.closed?) && (self_type ? self_type.closed? : false)
|
61
73
|
end
|
62
74
|
|
63
75
|
def with_location(new_location)
|
64
|
-
self.class.new(location: new_location, block: block, type: type)
|
76
|
+
self.class.new(location: new_location, block: block, type: type, self_type: self_type)
|
65
77
|
end
|
66
78
|
|
67
79
|
def map_type(&block)
|
68
80
|
self.class.new(
|
69
81
|
type: type.map_type(&block),
|
70
82
|
block: self.block&.map_type(&block),
|
83
|
+
self_type: self_type ? yield(self_type) : nil,
|
71
84
|
location: location
|
72
85
|
)
|
73
86
|
end
|
@@ -94,9 +107,10 @@ module Steep
|
|
94
107
|
end
|
95
108
|
|
96
109
|
def each_child(&block)
|
97
|
-
if
|
110
|
+
if block
|
98
111
|
type.each_child(&block)
|
99
112
|
self.block&.type&.each_child(&block)
|
113
|
+
self_type.each_child(&block) if self_type
|
100
114
|
else
|
101
115
|
enum_for :each_child
|
102
116
|
end
|
data/lib/steep/ast/types/self.rb
CHANGED
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, :binstub]
|
21
|
+
[:init, :check, :validate, :annotations, :version, :project, :watch, :langserver, :stats, :binstub, :checkfile]
|
22
22
|
end
|
23
23
|
|
24
24
|
def process_global_options
|
@@ -123,6 +123,29 @@ module Steep
|
|
123
123
|
end.run
|
124
124
|
end
|
125
125
|
|
126
|
+
def process_checkfile
|
127
|
+
Drivers::Checkfile.new(stdout: stdout, stderr: stderr).tap do |check|
|
128
|
+
OptionParser.new do |opts|
|
129
|
+
opts.banner = "Usage: steep checkfile [options] [files]"
|
130
|
+
|
131
|
+
opts.on("--steepfile=PATH") {|path| check.steepfile = Pathname(path) }
|
132
|
+
opts.on("--all-rbs", "Type check all RBS files") { check.all_rbs = true }
|
133
|
+
opts.on("--all-ruby", "Type check all Ruby files") { check.all_ruby = true }
|
134
|
+
opts.on("--stdin", "Read files to type check from stdin") do
|
135
|
+
while line = stdin.gets()
|
136
|
+
object = JSON.parse(line, symbolize_names: true)
|
137
|
+
Steep.logger.info { "Loading content of `#{object[:path]}` from stdin: #{object[:content].lines[0].chomp}" }
|
138
|
+
check.stdin_input[Pathname(object[:path])] = object[:content]
|
139
|
+
end
|
140
|
+
end
|
141
|
+
handle_jobs_option check, opts
|
142
|
+
handle_logging_options opts
|
143
|
+
end.parse!(argv)
|
144
|
+
|
145
|
+
check.command_line_args.push *argv
|
146
|
+
end.run
|
147
|
+
end
|
148
|
+
|
126
149
|
def process_stats
|
127
150
|
Drivers::Stats.new(stdout: stdout, stderr: stderr).tap do |check|
|
128
151
|
OptionParser.new do |opts|
|
@@ -87,13 +87,11 @@ module Steep
|
|
87
87
|
|
88
88
|
class UnexpectedPositionalArgument < Base
|
89
89
|
attr_reader :node
|
90
|
-
attr_reader :
|
91
|
-
attr_reader :method_name
|
90
|
+
attr_reader :params
|
92
91
|
|
93
|
-
def initialize(node:,
|
92
|
+
def initialize(node:, params:)
|
94
93
|
super(node: node)
|
95
|
-
@
|
96
|
-
@method_type = method_type
|
94
|
+
@params = params
|
97
95
|
end
|
98
96
|
|
99
97
|
def header_line
|
@@ -103,10 +101,9 @@ module Steep
|
|
103
101
|
|
104
102
|
class InsufficientPositionalArguments < Base
|
105
103
|
attr_reader :node
|
106
|
-
attr_reader :
|
107
|
-
attr_reader :method_type
|
104
|
+
attr_reader :params
|
108
105
|
|
109
|
-
def initialize(node:,
|
106
|
+
def initialize(node:, params:)
|
110
107
|
send = case node.type
|
111
108
|
when :send, :csend
|
112
109
|
node
|
@@ -121,8 +118,7 @@ module Steep
|
|
121
118
|
end
|
122
119
|
|
123
120
|
super(node: node, location: loc)
|
124
|
-
@
|
125
|
-
@method_type = method_type
|
121
|
+
@params = params
|
126
122
|
end
|
127
123
|
|
128
124
|
def header_line
|
@@ -132,10 +128,9 @@ module Steep
|
|
132
128
|
|
133
129
|
class UnexpectedKeywordArgument < Base
|
134
130
|
attr_reader :node
|
135
|
-
attr_reader :
|
136
|
-
attr_reader :method_type
|
131
|
+
attr_reader :params
|
137
132
|
|
138
|
-
def initialize(node:,
|
133
|
+
def initialize(node:, params:)
|
139
134
|
loc = case node.type
|
140
135
|
when :pair
|
141
136
|
node.children[0].location.expression
|
@@ -145,8 +140,7 @@ module Steep
|
|
145
140
|
raise
|
146
141
|
end
|
147
142
|
super(node: node, location: loc)
|
148
|
-
@
|
149
|
-
@method_type = method_type
|
143
|
+
@params = params
|
150
144
|
end
|
151
145
|
|
152
146
|
def header_line
|
@@ -160,7 +154,7 @@ module Steep
|
|
160
154
|
attr_reader :method_type
|
161
155
|
attr_reader :missing_keywords
|
162
156
|
|
163
|
-
def initialize(node:,
|
157
|
+
def initialize(node:, params:, missing_keywords:)
|
164
158
|
send = case node.type
|
165
159
|
when :send, :csend
|
166
160
|
node
|
@@ -176,8 +170,7 @@ module Steep
|
|
176
170
|
|
177
171
|
super(node: node, location: loc)
|
178
172
|
|
179
|
-
@
|
180
|
-
@method_type = method_type
|
173
|
+
@params = params
|
181
174
|
@missing_keywords = missing_keywords
|
182
175
|
end
|
183
176
|
|
@@ -220,14 +213,12 @@ module Steep
|
|
220
213
|
attr_reader :node
|
221
214
|
attr_reader :expected
|
222
215
|
attr_reader :actual
|
223
|
-
attr_reader :receiver_type
|
224
216
|
attr_reader :result
|
225
217
|
|
226
218
|
include ResultPrinter
|
227
219
|
|
228
|
-
def initialize(node:,
|
220
|
+
def initialize(node:, expected:, actual:, result:)
|
229
221
|
super(node: node)
|
230
|
-
@receiver_type = receiver_type
|
231
222
|
@expected = expected
|
232
223
|
@actual = actual
|
233
224
|
@result = result
|
@@ -512,7 +503,11 @@ module Steep
|
|
512
503
|
end
|
513
504
|
|
514
505
|
def header_line
|
515
|
-
|
506
|
+
if method
|
507
|
+
"No superclass method `#{method}` defined"
|
508
|
+
else
|
509
|
+
"`super` is not allowed from outside of method"
|
510
|
+
end
|
516
511
|
end
|
517
512
|
end
|
518
513
|
|
@@ -0,0 +1,205 @@
|
|
1
|
+
module Steep
|
2
|
+
module Drivers
|
3
|
+
class Checkfile
|
4
|
+
LSP = LanguageServer::Protocol
|
5
|
+
|
6
|
+
attr_reader :stdout
|
7
|
+
attr_reader :stderr
|
8
|
+
attr_reader :command_line_args
|
9
|
+
attr_accessor :all_ruby, :all_rbs
|
10
|
+
attr_reader :stdin_input
|
11
|
+
|
12
|
+
include Utils::DriverHelper
|
13
|
+
include Utils::JobsCount
|
14
|
+
|
15
|
+
def initialize(stdout:, stderr:)
|
16
|
+
@stdout = stdout
|
17
|
+
@stderr = stderr
|
18
|
+
@command_line_args = []
|
19
|
+
|
20
|
+
@all_rbs = false
|
21
|
+
@all_ruby = false
|
22
|
+
@stdin_input = {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def run
|
26
|
+
return 0 if command_line_args.empty? && !all_rbs && !all_ruby && stdin_input.empty?
|
27
|
+
|
28
|
+
project = load_config()
|
29
|
+
|
30
|
+
client_read, server_write = IO.pipe
|
31
|
+
server_read, client_write = IO.pipe
|
32
|
+
|
33
|
+
client_reader = LanguageServer::Protocol::Transport::Io::Reader.new(client_read)
|
34
|
+
client_writer = LanguageServer::Protocol::Transport::Io::Writer.new(client_write)
|
35
|
+
|
36
|
+
server_reader = LanguageServer::Protocol::Transport::Io::Reader.new(server_read)
|
37
|
+
server_writer = LanguageServer::Protocol::Transport::Io::Writer.new(server_write)
|
38
|
+
|
39
|
+
# @type var target_paths: Set[Pathname]
|
40
|
+
target_paths = Set[]
|
41
|
+
# @type var signature_paths: Set[Pathname]
|
42
|
+
signature_paths = Set[]
|
43
|
+
|
44
|
+
loader = Services::FileLoader.new(base_dir: project.base_dir)
|
45
|
+
project.targets.each do |target|
|
46
|
+
ruby_patterns =
|
47
|
+
case
|
48
|
+
when all_ruby
|
49
|
+
[]
|
50
|
+
when command_line_args.empty?
|
51
|
+
nil
|
52
|
+
else
|
53
|
+
command_line_args
|
54
|
+
end
|
55
|
+
|
56
|
+
if ruby_patterns
|
57
|
+
loader.each_path_in_patterns(target.source_pattern, ruby_patterns) do |path|
|
58
|
+
target_paths << path
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
rbs_patterns =
|
63
|
+
case
|
64
|
+
when all_rbs
|
65
|
+
[]
|
66
|
+
when command_line_args.empty?
|
67
|
+
nil
|
68
|
+
else
|
69
|
+
command_line_args
|
70
|
+
end
|
71
|
+
|
72
|
+
if rbs_patterns
|
73
|
+
loader.each_path_in_patterns(target.signature_pattern, rbs_patterns) do |path|
|
74
|
+
signature_paths << path
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
stdin_input.each_key do |path|
|
80
|
+
case ts = project.targets_for_path(path)
|
81
|
+
when Array
|
82
|
+
signature_paths << path
|
83
|
+
when Project::Target
|
84
|
+
target_paths << path
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
files = target_paths + signature_paths
|
89
|
+
|
90
|
+
count =
|
91
|
+
if files.size >= jobs_count
|
92
|
+
jobs_count
|
93
|
+
else
|
94
|
+
files.size + 2
|
95
|
+
end
|
96
|
+
|
97
|
+
Steep.logger.info { "Starting #{count} workers for #{files.size} files..." }
|
98
|
+
|
99
|
+
typecheck_workers = Server::WorkerProcess.spawn_typecheck_workers(
|
100
|
+
steepfile: project.steepfile_path,
|
101
|
+
args: [],
|
102
|
+
delay_shutdown: true,
|
103
|
+
steep_command: steep_command,
|
104
|
+
count: count
|
105
|
+
)
|
106
|
+
|
107
|
+
master = Server::Master.new(
|
108
|
+
project: project,
|
109
|
+
reader: server_reader,
|
110
|
+
writer: server_writer,
|
111
|
+
interaction_worker: nil,
|
112
|
+
typecheck_workers: typecheck_workers
|
113
|
+
)
|
114
|
+
master.typecheck_automatically = false
|
115
|
+
|
116
|
+
main_thread = Thread.start do
|
117
|
+
master.start()
|
118
|
+
end
|
119
|
+
main_thread.abort_on_exception = true
|
120
|
+
|
121
|
+
Steep.logger.info { "Initializing server" }
|
122
|
+
initialize_id = request_id()
|
123
|
+
client_writer.write({ method: :initialize, id: initialize_id, params: {} })
|
124
|
+
wait_for_response_id(reader: client_reader, id: initialize_id)
|
125
|
+
|
126
|
+
stdin_input.each do |path, content|
|
127
|
+
uri = PathHelper.to_uri(project.absolute_path(path))
|
128
|
+
|
129
|
+
master.broadcast_notification(
|
130
|
+
{
|
131
|
+
method: "textDocument/didChange",
|
132
|
+
params: {
|
133
|
+
textDocument: { uri: uri, version: 0 },
|
134
|
+
contentChanges: [{ text: content }]
|
135
|
+
}
|
136
|
+
}
|
137
|
+
)
|
138
|
+
master.broadcast_notification(
|
139
|
+
{
|
140
|
+
method: "textDocument/didSave",
|
141
|
+
params: {
|
142
|
+
textDocument: { uri: uri }
|
143
|
+
}
|
144
|
+
}
|
145
|
+
)
|
146
|
+
end
|
147
|
+
|
148
|
+
ping_guid = master.fresh_request_id()
|
149
|
+
client_writer.write({ method: "$/ping", id: ping_guid, params: {} })
|
150
|
+
wait_for_response_id(reader: client_reader, id: ping_guid)
|
151
|
+
|
152
|
+
request_guid = master.fresh_request_id()
|
153
|
+
request = Server::Master::TypeCheckRequest.new(guid: request_guid)
|
154
|
+
|
155
|
+
target_paths.each do |path|
|
156
|
+
request.code_paths << project.absolute_path(path)
|
157
|
+
end
|
158
|
+
signature_paths.each do |path|
|
159
|
+
request.signature_paths << project.absolute_path(path)
|
160
|
+
end
|
161
|
+
|
162
|
+
master.start_type_check(request, last_request: nil, start_progress: true)
|
163
|
+
|
164
|
+
Steep.logger.info { "Starting type checking: #{request_guid}" }
|
165
|
+
|
166
|
+
diagnostic_notifications = []
|
167
|
+
error_messages = []
|
168
|
+
client_reader.read do |response|
|
169
|
+
case
|
170
|
+
when response[:method] == "textDocument/publishDiagnostics"
|
171
|
+
params = response[:params]
|
172
|
+
|
173
|
+
if path = PathHelper.to_pathname(params[:uri])
|
174
|
+
stdout.puts(
|
175
|
+
{
|
176
|
+
path: project.relative_path(path).to_s,
|
177
|
+
diagnostics: params[:diagnostics]
|
178
|
+
}.to_json
|
179
|
+
)
|
180
|
+
end
|
181
|
+
when response[:method] == "window/showMessage"
|
182
|
+
# Assuming ERROR message means unrecoverable error.
|
183
|
+
message = response[:params]
|
184
|
+
if message[:type] == LSP::Constant::MessageType::ERROR
|
185
|
+
error_messages << message[:message]
|
186
|
+
end
|
187
|
+
when response[:method] == "$/progress"
|
188
|
+
if response[:params][:token] == request_guid
|
189
|
+
if response[:params][:value][:kind] == "end"
|
190
|
+
break
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
Steep.logger.info { "Shutting down..." }
|
197
|
+
|
198
|
+
shutdown_exit(reader: client_reader, writer: client_writer)
|
199
|
+
main_thread.join()
|
200
|
+
|
201
|
+
0
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
@@ -29,7 +29,9 @@ module Steep
|
|
29
29
|
when Services::SignatureService::SyntaxErrorStatus, Services::SignatureService::AncestorErrorStatus
|
30
30
|
controller.status.diagnostics
|
31
31
|
when Services::SignatureService::LoadedStatus
|
32
|
-
|
32
|
+
factory = AST::Types::Factory.new(builder: controller.latest_builder)
|
33
|
+
builder = Interface::Builder.new(factory)
|
34
|
+
check = Subtyping::Check.new(builder: builder)
|
33
35
|
Signature::Validator.new(checker: check).tap {|v| v.validate() }.each_error.to_a
|
34
36
|
end
|
35
37
|
end
|
data/lib/steep/equatable.rb
CHANGED
@@ -3,10 +3,12 @@ module Steep
|
|
3
3
|
class Block
|
4
4
|
attr_reader :type
|
5
5
|
attr_reader :optional
|
6
|
+
attr_reader :self_type
|
6
7
|
|
7
|
-
def initialize(type:, optional:)
|
8
|
+
def initialize(type:, optional:, self_type:)
|
8
9
|
@type = type
|
9
10
|
@optional = optional
|
11
|
+
@self_type = self_type
|
10
12
|
end
|
11
13
|
|
12
14
|
def optional?
|
@@ -20,18 +22,19 @@ module Steep
|
|
20
22
|
def to_optional
|
21
23
|
self.class.new(
|
22
24
|
type: type,
|
25
|
+
self_type: self_type,
|
23
26
|
optional: true
|
24
27
|
)
|
25
28
|
end
|
26
29
|
|
27
30
|
def ==(other)
|
28
|
-
other.is_a?(self.class) && other.type == type && other.optional == optional
|
31
|
+
other.is_a?(self.class) && other.type == type && other.optional == optional && other.self_type == self_type
|
29
32
|
end
|
30
33
|
|
31
34
|
alias eql? ==
|
32
35
|
|
33
36
|
def hash
|
34
|
-
type.hash ^ optional.hash
|
37
|
+
type.hash ^ optional.hash ^ self_type.hash
|
35
38
|
end
|
36
39
|
|
37
40
|
def closed?
|
@@ -40,27 +43,28 @@ module Steep
|
|
40
43
|
|
41
44
|
def subst(s)
|
42
45
|
ty = type.subst(s)
|
43
|
-
|
46
|
+
st = self_type.subst(s) if self_type
|
47
|
+
|
48
|
+
if ty == type && st == self_type
|
44
49
|
self
|
45
50
|
else
|
46
|
-
self.class.new(
|
47
|
-
type: ty,
|
48
|
-
optional: optional
|
49
|
-
)
|
51
|
+
self.class.new(type: ty, self_type: st, optional: optional)
|
50
52
|
end
|
51
53
|
end
|
52
54
|
|
53
55
|
def free_variables()
|
54
|
-
@fvs ||= type.free_variables
|
56
|
+
@fvs ||= type.free_variables + (self_type&.free_variables || Set[])
|
55
57
|
end
|
56
58
|
|
57
59
|
def to_s
|
58
|
-
|
60
|
+
self_binding = self_type ? "[self: #{self_type}] " : ""
|
61
|
+
"#{optional? ? "?" : ""}{ #{type.params} #{self_binding}-> #{type.return_type} }"
|
59
62
|
end
|
60
63
|
|
61
64
|
def map_type(&block)
|
62
65
|
self.class.new(
|
63
66
|
type: type.map_type(&block),
|
67
|
+
self_type: self_type&.map_type(&block),
|
64
68
|
optional: optional
|
65
69
|
)
|
66
70
|
end
|
@@ -73,9 +77,15 @@ module Steep
|
|
73
77
|
location: nil
|
74
78
|
)
|
75
79
|
|
80
|
+
self_types = [self.self_type, other.self_type].compact
|
81
|
+
|
76
82
|
self.class.new(
|
77
83
|
type: type,
|
78
|
-
optional: optional
|
84
|
+
optional: optional,
|
85
|
+
self_type:
|
86
|
+
unless self_types.empty?
|
87
|
+
AST::Types::Union.build(types: self_types)
|
88
|
+
end
|
79
89
|
)
|
80
90
|
end
|
81
91
|
end
|