steep 0.13.0 → 0.16.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitmodules +0 -3
- data/CHANGELOG.md +28 -0
- data/Rakefile +0 -13
- data/bin/setup +0 -2
- data/bin/smoke_runner.rb +0 -1
- data/exe/steep +0 -1
- data/lib/steep.rb +33 -1
- data/lib/steep/annotation_parser.rb +4 -4
- data/lib/steep/ast/buffer.rb +11 -7
- data/lib/steep/ast/builtin.rb +8 -0
- data/lib/steep/ast/types/factory.rb +124 -89
- data/lib/steep/cli.rb +16 -1
- data/lib/steep/drivers/annotations.rb +1 -1
- data/lib/steep/drivers/check.rb +20 -4
- data/lib/steep/drivers/init.rb +5 -5
- data/lib/steep/drivers/langserver.rb +13 -287
- data/lib/steep/drivers/utils/driver_helper.rb +1 -1
- data/lib/steep/drivers/vendor.rb +2 -2
- data/lib/steep/drivers/watch.rb +97 -85
- data/lib/steep/drivers/worker.rb +51 -0
- data/lib/steep/project.rb +9 -5
- data/lib/steep/project/completion_provider.rb +298 -0
- data/lib/steep/project/dsl.rb +14 -0
- data/lib/steep/project/file.rb +54 -47
- data/lib/steep/project/hover_content.rb +17 -8
- data/lib/steep/project/options.rb +25 -3
- data/lib/steep/project/target.rb +40 -24
- data/lib/steep/server/base_worker.rb +56 -0
- data/lib/steep/server/code_worker.rb +151 -0
- data/lib/steep/server/interaction_worker.rb +281 -0
- data/lib/steep/server/master.rb +196 -0
- data/lib/steep/server/signature_worker.rb +148 -0
- data/lib/steep/server/utils.rb +36 -0
- data/lib/steep/server/worker_process.rb +62 -0
- data/lib/steep/signature/errors.rb +1 -1
- data/lib/steep/signature/validator.rb +13 -13
- data/lib/steep/source.rb +1 -1
- data/lib/steep/type_construction.rb +1004 -727
- data/lib/steep/type_inference/constant_env.rb +3 -11
- data/lib/steep/type_inference/context.rb +8 -3
- data/lib/steep/type_inference/context_array.rb +111 -0
- data/lib/steep/type_inference/local_variable_type_env.rb +226 -0
- data/lib/steep/type_inference/logic.rb +130 -0
- data/lib/steep/type_inference/type_env.rb +5 -69
- data/lib/steep/typing.rb +91 -23
- data/lib/steep/version.rb +1 -1
- data/smoke/alias/Steepfile +1 -0
- data/smoke/alias/a.rb +1 -1
- data/smoke/and/Steepfile +1 -0
- data/smoke/array/Steepfile +1 -0
- data/smoke/array/b.rb +0 -2
- data/smoke/block/Steepfile +1 -0
- data/smoke/case/Steepfile +1 -0
- data/smoke/class/Steepfile +1 -0
- data/smoke/const/Steepfile +1 -0
- data/smoke/dstr/Steepfile +1 -0
- data/smoke/ensure/Steepfile +1 -0
- data/smoke/enumerator/Steepfile +1 -0
- data/smoke/extension/Steepfile +1 -0
- data/smoke/extension/c.rb +1 -0
- data/smoke/hash/Steepfile +1 -0
- data/smoke/hello/Steepfile +1 -0
- data/smoke/if/Steepfile +1 -0
- data/smoke/if/a.rb +1 -1
- data/smoke/implements/Steepfile +1 -0
- data/smoke/initialize/Steepfile +1 -0
- data/smoke/integer/Steepfile +1 -0
- data/smoke/interface/Steepfile +1 -0
- data/smoke/kwbegin/Steepfile +1 -0
- data/smoke/lambda/Steepfile +1 -0
- data/smoke/literal/Steepfile +1 -0
- data/smoke/map/Steepfile +1 -0
- data/smoke/method/Steepfile +1 -0
- data/smoke/module/Steepfile +1 -0
- data/smoke/regexp/Steepfile +1 -0
- data/smoke/regexp/b.rb +4 -4
- data/smoke/regression/Steepfile +1 -0
- data/smoke/rescue/Steepfile +1 -0
- data/smoke/rescue/a.rb +1 -1
- data/smoke/self/Steepfile +1 -0
- data/smoke/skip/Steepfile +1 -0
- data/smoke/stdout/Steepfile +1 -0
- data/smoke/super/Steepfile +1 -0
- data/smoke/type_case/Steepfile +1 -0
- data/smoke/yield/Steepfile +1 -0
- data/steep.gemspec +8 -8
- metadata +38 -138
- data/exe/rbs +0 -3
- data/exe/ruby-signature +0 -3
- data/vendor/ruby-signature/.github/workflows/ruby.yml +0 -27
- data/vendor/ruby-signature/.gitignore +0 -12
- data/vendor/ruby-signature/.rubocop.yml +0 -15
- data/vendor/ruby-signature/BSDL +0 -22
- data/vendor/ruby-signature/COPYING +0 -56
- data/vendor/ruby-signature/Gemfile +0 -6
- data/vendor/ruby-signature/README.md +0 -93
- data/vendor/ruby-signature/Rakefile +0 -66
- data/vendor/ruby-signature/bin/annotate-with-rdoc +0 -156
- data/vendor/ruby-signature/bin/console +0 -14
- data/vendor/ruby-signature/bin/query-rdoc +0 -103
- data/vendor/ruby-signature/bin/setup +0 -10
- data/vendor/ruby-signature/bin/sort +0 -88
- data/vendor/ruby-signature/bin/test_runner.rb +0 -17
- data/vendor/ruby-signature/docs/CONTRIBUTING.md +0 -97
- data/vendor/ruby-signature/docs/sigs.md +0 -148
- data/vendor/ruby-signature/docs/stdlib.md +0 -152
- data/vendor/ruby-signature/docs/syntax.md +0 -528
- data/vendor/ruby-signature/exe/rbs +0 -3
- data/vendor/ruby-signature/exe/ruby-signature +0 -7
- data/vendor/ruby-signature/lib/ruby/signature.rb +0 -64
- data/vendor/ruby-signature/lib/ruby/signature/ast/annotation.rb +0 -29
- data/vendor/ruby-signature/lib/ruby/signature/ast/comment.rb +0 -29
- data/vendor/ruby-signature/lib/ruby/signature/ast/declarations.rb +0 -391
- data/vendor/ruby-signature/lib/ruby/signature/ast/members.rb +0 -364
- data/vendor/ruby-signature/lib/ruby/signature/buffer.rb +0 -52
- data/vendor/ruby-signature/lib/ruby/signature/builtin_names.rb +0 -54
- data/vendor/ruby-signature/lib/ruby/signature/cli.rb +0 -534
- data/vendor/ruby-signature/lib/ruby/signature/constant.rb +0 -28
- data/vendor/ruby-signature/lib/ruby/signature/constant_table.rb +0 -152
- data/vendor/ruby-signature/lib/ruby/signature/definition.rb +0 -172
- data/vendor/ruby-signature/lib/ruby/signature/definition_builder.rb +0 -921
- data/vendor/ruby-signature/lib/ruby/signature/environment.rb +0 -283
- data/vendor/ruby-signature/lib/ruby/signature/environment_loader.rb +0 -138
- data/vendor/ruby-signature/lib/ruby/signature/environment_walker.rb +0 -126
- data/vendor/ruby-signature/lib/ruby/signature/errors.rb +0 -189
- data/vendor/ruby-signature/lib/ruby/signature/location.rb +0 -104
- data/vendor/ruby-signature/lib/ruby/signature/method_type.rb +0 -125
- data/vendor/ruby-signature/lib/ruby/signature/namespace.rb +0 -93
- data/vendor/ruby-signature/lib/ruby/signature/parser.y +0 -1343
- data/vendor/ruby-signature/lib/ruby/signature/prototype/rb.rb +0 -441
- data/vendor/ruby-signature/lib/ruby/signature/prototype/rbi.rb +0 -579
- data/vendor/ruby-signature/lib/ruby/signature/prototype/runtime.rb +0 -383
- data/vendor/ruby-signature/lib/ruby/signature/substitution.rb +0 -48
- data/vendor/ruby-signature/lib/ruby/signature/test.rb +0 -28
- data/vendor/ruby-signature/lib/ruby/signature/test/errors.rb +0 -63
- data/vendor/ruby-signature/lib/ruby/signature/test/hook.rb +0 -290
- data/vendor/ruby-signature/lib/ruby/signature/test/setup.rb +0 -58
- data/vendor/ruby-signature/lib/ruby/signature/test/spy.rb +0 -324
- data/vendor/ruby-signature/lib/ruby/signature/test/test_helper.rb +0 -185
- data/vendor/ruby-signature/lib/ruby/signature/test/type_check.rb +0 -256
- data/vendor/ruby-signature/lib/ruby/signature/type_name.rb +0 -72
- data/vendor/ruby-signature/lib/ruby/signature/types.rb +0 -932
- data/vendor/ruby-signature/lib/ruby/signature/variance_calculator.rb +0 -140
- data/vendor/ruby-signature/lib/ruby/signature/vendorer.rb +0 -49
- data/vendor/ruby-signature/lib/ruby/signature/version.rb +0 -5
- data/vendor/ruby-signature/lib/ruby/signature/writer.rb +0 -271
- data/vendor/ruby-signature/ruby-signature.gemspec +0 -45
- data/vendor/ruby-signature/stdlib/abbrev/abbrev.rbs +0 -3
- data/vendor/ruby-signature/stdlib/base64/base64.rbs +0 -15
- data/vendor/ruby-signature/stdlib/builtin/array.rbs +0 -1997
- data/vendor/ruby-signature/stdlib/builtin/basic_object.rbs +0 -280
- data/vendor/ruby-signature/stdlib/builtin/binding.rbs +0 -177
- data/vendor/ruby-signature/stdlib/builtin/builtin.rbs +0 -35
- data/vendor/ruby-signature/stdlib/builtin/class.rbs +0 -145
- data/vendor/ruby-signature/stdlib/builtin/comparable.rbs +0 -116
- data/vendor/ruby-signature/stdlib/builtin/complex.rbs +0 -400
- data/vendor/ruby-signature/stdlib/builtin/constants.rbs +0 -37
- data/vendor/ruby-signature/stdlib/builtin/data.rbs +0 -5
- data/vendor/ruby-signature/stdlib/builtin/deprecated.rbs +0 -2
- data/vendor/ruby-signature/stdlib/builtin/dir.rbs +0 -419
- data/vendor/ruby-signature/stdlib/builtin/encoding.rbs +0 -606
- data/vendor/ruby-signature/stdlib/builtin/enumerable.rbs +0 -404
- data/vendor/ruby-signature/stdlib/builtin/enumerator.rbs +0 -260
- data/vendor/ruby-signature/stdlib/builtin/errno.rbs +0 -781
- data/vendor/ruby-signature/stdlib/builtin/errors.rbs +0 -582
- data/vendor/ruby-signature/stdlib/builtin/exception.rbs +0 -193
- data/vendor/ruby-signature/stdlib/builtin/false_class.rbs +0 -40
- data/vendor/ruby-signature/stdlib/builtin/fiber.rbs +0 -68
- data/vendor/ruby-signature/stdlib/builtin/fiber_error.rbs +0 -12
- data/vendor/ruby-signature/stdlib/builtin/file.rbs +0 -476
- data/vendor/ruby-signature/stdlib/builtin/file_test.rbs +0 -59
- data/vendor/ruby-signature/stdlib/builtin/float.rbs +0 -696
- data/vendor/ruby-signature/stdlib/builtin/gc.rbs +0 -121
- data/vendor/ruby-signature/stdlib/builtin/hash.rbs +0 -1029
- data/vendor/ruby-signature/stdlib/builtin/integer.rbs +0 -710
- data/vendor/ruby-signature/stdlib/builtin/io.rbs +0 -683
- data/vendor/ruby-signature/stdlib/builtin/kernel.rbs +0 -574
- data/vendor/ruby-signature/stdlib/builtin/marshal.rbs +0 -135
- data/vendor/ruby-signature/stdlib/builtin/match_data.rbs +0 -141
- data/vendor/ruby-signature/stdlib/builtin/math.rbs +0 -66
- data/vendor/ruby-signature/stdlib/builtin/method.rbs +0 -182
- data/vendor/ruby-signature/stdlib/builtin/module.rbs +0 -248
- data/vendor/ruby-signature/stdlib/builtin/nil_class.rbs +0 -82
- data/vendor/ruby-signature/stdlib/builtin/numeric.rbs +0 -409
- data/vendor/ruby-signature/stdlib/builtin/object.rbs +0 -824
- data/vendor/ruby-signature/stdlib/builtin/proc.rbs +0 -426
- data/vendor/ruby-signature/stdlib/builtin/process.rbs +0 -354
- data/vendor/ruby-signature/stdlib/builtin/random.rbs +0 -93
- data/vendor/ruby-signature/stdlib/builtin/range.rbs +0 -226
- data/vendor/ruby-signature/stdlib/builtin/rational.rbs +0 -424
- data/vendor/ruby-signature/stdlib/builtin/rb_config.rbs +0 -10
- data/vendor/ruby-signature/stdlib/builtin/regexp.rbs +0 -131
- data/vendor/ruby-signature/stdlib/builtin/ruby_vm.rbs +0 -14
- data/vendor/ruby-signature/stdlib/builtin/signal.rbs +0 -55
- data/vendor/ruby-signature/stdlib/builtin/string.rbs +0 -770
- data/vendor/ruby-signature/stdlib/builtin/string_io.rbs +0 -13
- data/vendor/ruby-signature/stdlib/builtin/struct.rbs +0 -40
- data/vendor/ruby-signature/stdlib/builtin/symbol.rbs +0 -230
- data/vendor/ruby-signature/stdlib/builtin/thread.rbs +0 -1112
- data/vendor/ruby-signature/stdlib/builtin/thread_group.rbs +0 -23
- data/vendor/ruby-signature/stdlib/builtin/time.rbs +0 -739
- data/vendor/ruby-signature/stdlib/builtin/trace_point.rbs +0 -91
- data/vendor/ruby-signature/stdlib/builtin/true_class.rbs +0 -46
- data/vendor/ruby-signature/stdlib/builtin/unbound_method.rbs +0 -159
- data/vendor/ruby-signature/stdlib/builtin/warning.rbs +0 -17
- data/vendor/ruby-signature/stdlib/erb/erb.rbs +0 -18
- data/vendor/ruby-signature/stdlib/find/find.rbs +0 -44
- data/vendor/ruby-signature/stdlib/pathname/pathname.rbs +0 -21
- data/vendor/ruby-signature/stdlib/prime/integer-extension.rbs +0 -23
- data/vendor/ruby-signature/stdlib/prime/prime.rbs +0 -188
- data/vendor/ruby-signature/stdlib/securerandom/securerandom.rbs +0 -9
- data/vendor/ruby-signature/stdlib/set/set.rbs +0 -77
- data/vendor/ruby-signature/stdlib/tmpdir/tmpdir.rbs +0 -53
@@ -0,0 +1,148 @@
|
|
1
|
+
module Steep
|
2
|
+
module Server
|
3
|
+
class SignatureWorker < BaseWorker
|
4
|
+
attr_reader :queue
|
5
|
+
attr_reader :last_target_validated_at
|
6
|
+
|
7
|
+
def initialize(project:, reader:, writer:, queue: Queue.new)
|
8
|
+
super(project: project, reader: reader, writer: writer)
|
9
|
+
|
10
|
+
@queue = queue
|
11
|
+
@last_target_validated_at = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def validate_signature_if_required(request)
|
15
|
+
path = source_path(URI.parse(request[:params][:textDocument][:uri]))
|
16
|
+
|
17
|
+
project.targets.each do |target|
|
18
|
+
if target.signature_file?(path)
|
19
|
+
enqueue_target target: target, timestamp: Time.now
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def enqueue_target(target:, timestamp:)
|
25
|
+
Steep.logger.debug "queueing target #{target.name}@#{timestamp}"
|
26
|
+
last_target_validated_at[target] = timestamp
|
27
|
+
queue << [target, timestamp]
|
28
|
+
end
|
29
|
+
|
30
|
+
def handle_request(request)
|
31
|
+
case request[:method]
|
32
|
+
when "initialize"
|
33
|
+
# Don't respond to initialize request, but start type checking.
|
34
|
+
project.targets.each do |target|
|
35
|
+
enqueue_target(target: target, timestamp: Time.now)
|
36
|
+
end
|
37
|
+
when "textDocument/didChange"
|
38
|
+
update_source(request)
|
39
|
+
validate_signature_if_required(request)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def validate_signature(target, timestamp:)
|
44
|
+
Steep.logger.info "Starting signature validation: #{target.name} (#{timestamp})..."
|
45
|
+
|
46
|
+
target.type_check(target_sources: [], validate_signatures: true)
|
47
|
+
|
48
|
+
Steep.logger.info "Finished signature validation: #{target.name} (#{timestamp})"
|
49
|
+
|
50
|
+
diagnostics = case status = target.status
|
51
|
+
when Project::Target::SignatureSyntaxErrorStatus
|
52
|
+
target.signature_files.each.with_object({}) do |(path, file), hash|
|
53
|
+
if file.status.is_a?(Project::SignatureFile::ParseErrorStatus)
|
54
|
+
location = case error = file.status.error
|
55
|
+
when RBS::Parser::SyntaxError
|
56
|
+
if error.error_value.is_a?(String)
|
57
|
+
buf = RBS::Buffer.new(name: path, content: file.content)
|
58
|
+
RBS::Location.new(buffer: buf, start_pos: buf.content.size, end_pos: buf.content.size)
|
59
|
+
else
|
60
|
+
error.error_value.location
|
61
|
+
end
|
62
|
+
when RBS::Parser::SemanticsError
|
63
|
+
error.location
|
64
|
+
else
|
65
|
+
raise
|
66
|
+
end
|
67
|
+
|
68
|
+
hash[path] =
|
69
|
+
[
|
70
|
+
LSP::Interface::Diagnostic.new(
|
71
|
+
message: file.status.error.message,
|
72
|
+
severity: LSP::Constant::DiagnosticSeverity::ERROR,
|
73
|
+
range: LSP::Interface::Range.new(
|
74
|
+
start: LSP::Interface::Position.new(
|
75
|
+
line: location.start_line - 1,
|
76
|
+
character: location.start_column,
|
77
|
+
),
|
78
|
+
end: LSP::Interface::Position.new(
|
79
|
+
line: location.end_line - 1,
|
80
|
+
character: location.end_column
|
81
|
+
)
|
82
|
+
)
|
83
|
+
)
|
84
|
+
]
|
85
|
+
else
|
86
|
+
hash[path] = []
|
87
|
+
end
|
88
|
+
end
|
89
|
+
when Project::Target::SignatureValidationErrorStatus
|
90
|
+
error_hash = status.errors.group_by {|error| error.location.buffer.name }
|
91
|
+
|
92
|
+
target.signature_files.each_key.with_object({}) do |path, hash|
|
93
|
+
errors = error_hash[path] || []
|
94
|
+
hash[path] = errors.map do |error|
|
95
|
+
LSP::Interface::Diagnostic.new(
|
96
|
+
message: StringIO.new.tap {|io| error.puts(io) }.string.split(/\t/, 2).last,
|
97
|
+
severity: LSP::Constant::DiagnosticSeverity::ERROR,
|
98
|
+
range: LSP::Interface::Range.new(
|
99
|
+
start: LSP::Interface::Position.new(
|
100
|
+
line: error.location.start_line - 1,
|
101
|
+
character: error.location.start_column,
|
102
|
+
),
|
103
|
+
end: LSP::Interface::Position.new(
|
104
|
+
line: error.location.end_line - 1,
|
105
|
+
character: error.location.end_column
|
106
|
+
)
|
107
|
+
)
|
108
|
+
)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
when Project::Target::TypeCheckStatus
|
112
|
+
target.signature_files.each_key.with_object({}) do |path, hash|
|
113
|
+
hash[path] = []
|
114
|
+
end
|
115
|
+
else
|
116
|
+
Steep.logger.info "Unexpected target status: #{status.class}"
|
117
|
+
end
|
118
|
+
|
119
|
+
diagnostics.each do |path, diags|
|
120
|
+
writer.write(
|
121
|
+
method: :"textDocument/publishDiagnostics",
|
122
|
+
params: LSP::Interface::PublishDiagnosticsParams.new(
|
123
|
+
uri: URI.parse(project.absolute_path(path).to_s).tap {|uri| uri.scheme = "file"},
|
124
|
+
diagnostics: diags
|
125
|
+
)
|
126
|
+
)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def active_job?(target, timestamp)
|
131
|
+
if last_target_validated_at[target] == timestamp
|
132
|
+
sleep 0.1
|
133
|
+
last_target_validated_at[target] == timestamp
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def handle_job(job)
|
138
|
+
target, timestamp = job
|
139
|
+
|
140
|
+
if active_job?(target, timestamp)
|
141
|
+
validate_signature(target, timestamp: timestamp)
|
142
|
+
else
|
143
|
+
Steep.logger.info "Skipping signature validation: #{target.name}, queued timestamp=#{timestamp}, latest timestamp=#{last_target_validated_at[target]}"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Steep
|
2
|
+
module Server
|
3
|
+
module Utils
|
4
|
+
LSP = LanguageServer::Protocol
|
5
|
+
|
6
|
+
def source_path(uri)
|
7
|
+
project.relative_path(Pathname(uri.path))
|
8
|
+
end
|
9
|
+
|
10
|
+
def update_source(request)
|
11
|
+
path = source_path(URI.parse(request[:params][:textDocument][:uri]))
|
12
|
+
text = request[:params][:contentChanges][0][:text]
|
13
|
+
version = request[:params][:textDocument][:version]
|
14
|
+
|
15
|
+
Steep.logger.debug "Updateing source: path=#{path}, version=#{version}, size=#{text.bytesize}"
|
16
|
+
|
17
|
+
project.targets.each do |target|
|
18
|
+
case
|
19
|
+
when target.source_file?(path)
|
20
|
+
target.update_source path, text
|
21
|
+
when target.possible_source_file?(path)
|
22
|
+
target.add_source path, text
|
23
|
+
when target.signature_file?(path)
|
24
|
+
target.update_signature path, text
|
25
|
+
when target.possible_signature_file?(path)
|
26
|
+
target.add_signature path, text
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
if block_given?
|
31
|
+
yield path, version
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Steep
|
2
|
+
module Server
|
3
|
+
class WorkerProcess
|
4
|
+
attr_reader :reader
|
5
|
+
attr_reader :writer
|
6
|
+
attr_reader :stderr
|
7
|
+
|
8
|
+
attr_reader :wait_thread
|
9
|
+
|
10
|
+
def initialize(reader:, writer:, stderr:, wait_thread:)
|
11
|
+
@reader = reader
|
12
|
+
@writer = writer
|
13
|
+
@stderr = stderr
|
14
|
+
@wait_thread = wait_thread
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.spawn_worker(type, name:, steepfile:)
|
18
|
+
log_level = %w(debug info warn error fatal unknown)[Steep.logger.level]
|
19
|
+
command = case type
|
20
|
+
when :code
|
21
|
+
["steep", "worker", "--code", "--name=#{name}", "--log-level=#{log_level}", "--steepfile=#{steepfile}"]
|
22
|
+
when :signature
|
23
|
+
["steep", "worker", "--signature", "--name=#{name}", "--log-level=#{log_level}", "--steepfile=#{steepfile}"]
|
24
|
+
when :interaction
|
25
|
+
["steep", "worker", "--interaction", "--name=#{name}", "--log-level=#{log_level}", "--steepfile=#{steepfile}"]
|
26
|
+
else
|
27
|
+
raise
|
28
|
+
end
|
29
|
+
|
30
|
+
stdin, stdout, thread = Open3.popen2(*command, pgroup: true)
|
31
|
+
stderr = nil
|
32
|
+
|
33
|
+
writer = LanguageServer::Protocol::Transport::Io::Writer.new(stdin)
|
34
|
+
reader = LanguageServer::Protocol::Transport::Io::Reader.new(stdout)
|
35
|
+
|
36
|
+
new(reader: reader, writer: writer, stderr: stderr, wait_thread: thread)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.spawn_code_workers(steepfile:, count: [Etc.nprocessors-3, 1].max)
|
40
|
+
count.times.map do |i|
|
41
|
+
spawn_worker(:code, name: "code@#{i}", steepfile: steepfile)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def <<(message)
|
46
|
+
writer.write(message)
|
47
|
+
end
|
48
|
+
|
49
|
+
def read(&block)
|
50
|
+
reader.read(&block)
|
51
|
+
end
|
52
|
+
|
53
|
+
def shutdown
|
54
|
+
self << { method: :shutdown, params: nil }
|
55
|
+
self << { method: :exit, params: nil }
|
56
|
+
|
57
|
+
writer.io.close()
|
58
|
+
@wait_thread.join()
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Steep
|
2
2
|
module Signature
|
3
3
|
class Validator
|
4
|
-
Location =
|
5
|
-
Declarations =
|
4
|
+
Location = RBS::Location
|
5
|
+
Declarations = RBS::AST::Declarations
|
6
6
|
|
7
7
|
attr_reader :checker
|
8
8
|
|
@@ -51,19 +51,19 @@ module Steep
|
|
51
51
|
case decl
|
52
52
|
when Declarations::Class
|
53
53
|
rescue_validation_errors do
|
54
|
-
Steep.logger.
|
54
|
+
Steep.logger.debug "#{Location.to_string decl.location}:\tValidating class definition `#{name}`..."
|
55
55
|
builder.build_instance(decl.name.absolute!).each_type do |type|
|
56
|
-
env.validate type, namespace:
|
56
|
+
env.validate type, namespace: RBS::Namespace.root
|
57
57
|
end
|
58
58
|
builder.build_singleton(decl.name.absolute!).each_type do |type|
|
59
|
-
env.validate type, namespace:
|
59
|
+
env.validate type, namespace: RBS::Namespace.root
|
60
60
|
end
|
61
61
|
end
|
62
62
|
when Declarations::Interface
|
63
63
|
rescue_validation_errors do
|
64
|
-
Steep.logger.
|
64
|
+
Steep.logger.debug "#{Location.to_string decl.location}:\tValidating interface `#{name}`..."
|
65
65
|
builder.build_interface(decl.name.absolute!, decl).each_type do |type|
|
66
|
-
env.validate type, namespace:
|
66
|
+
env.validate type, namespace: RBS::Namespace.root
|
67
67
|
end
|
68
68
|
end
|
69
69
|
end
|
@@ -78,7 +78,7 @@ module Steep
|
|
78
78
|
def validate_const
|
79
79
|
env.each_constant do |name, decl|
|
80
80
|
rescue_validation_errors do
|
81
|
-
Steep.logger.
|
81
|
+
Steep.logger.debug "#{Location.to_string decl.location}:\tValidating constant `#{name}`..."
|
82
82
|
env.validate(decl.type, namespace: name.namespace)
|
83
83
|
end
|
84
84
|
end
|
@@ -87,8 +87,8 @@ module Steep
|
|
87
87
|
def validate_global
|
88
88
|
env.each_global do |name, decl|
|
89
89
|
rescue_validation_errors do
|
90
|
-
Steep.logger.
|
91
|
-
env.validate(decl.type, namespace:
|
90
|
+
Steep.logger.debug "#{Location.to_string decl.location}:\tValidating global `#{name}`..."
|
91
|
+
env.validate(decl.type, namespace: RBS::Namespace.root)
|
92
92
|
end
|
93
93
|
end
|
94
94
|
end
|
@@ -96,7 +96,7 @@ module Steep
|
|
96
96
|
def validate_alias
|
97
97
|
env.each_alias do |name, decl|
|
98
98
|
rescue_validation_errors do
|
99
|
-
Steep.logger.
|
99
|
+
Steep.logger.debug "#{Location.to_string decl.location}:\tValidating alias `#{name}`..."
|
100
100
|
env.validate(decl.type, namespace: name.namespace)
|
101
101
|
end
|
102
102
|
end
|
@@ -104,14 +104,14 @@ module Steep
|
|
104
104
|
|
105
105
|
def rescue_validation_errors
|
106
106
|
yield
|
107
|
-
rescue
|
107
|
+
rescue RBS::InvalidTypeApplicationError => exn
|
108
108
|
@errors << Errors::InvalidTypeApplicationError.new(
|
109
109
|
name: factory.type_name(exn.type_name),
|
110
110
|
args: exn.args.map {|ty| factory.type(ty) },
|
111
111
|
params: exn.params.each.map(&:name),
|
112
112
|
location: exn.location
|
113
113
|
)
|
114
|
-
rescue
|
114
|
+
rescue RBS::NoTypeFoundError => exn
|
115
115
|
@errors << Errors::UnknownTypeNameError.new(
|
116
116
|
name: factory.type_name(exn.type_name),
|
117
117
|
location: exn.location
|
data/lib/steep/source.rb
CHANGED
@@ -1,5 +1,38 @@
|
|
1
1
|
module Steep
|
2
2
|
class TypeConstruction
|
3
|
+
class Pair
|
4
|
+
attr_reader :type
|
5
|
+
attr_reader :constr
|
6
|
+
|
7
|
+
def initialize(type:, constr:)
|
8
|
+
@type = type
|
9
|
+
@constr = constr
|
10
|
+
end
|
11
|
+
|
12
|
+
def with(type: self.type, constr: self.constr)
|
13
|
+
self.class.new(
|
14
|
+
type: type,
|
15
|
+
constr: constr
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def +(other)
|
20
|
+
if type.is_a?(AST::Types::Bot)
|
21
|
+
other.with(type: type)
|
22
|
+
else
|
23
|
+
other
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def context
|
28
|
+
constr.context
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_ary
|
32
|
+
[type, constr, context]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
3
36
|
attr_reader :checker
|
4
37
|
attr_reader :source
|
5
38
|
attr_reader :annotations
|
@@ -50,6 +83,36 @@ module Steep
|
|
50
83
|
)
|
51
84
|
end
|
52
85
|
|
86
|
+
def with_updated_context(lvar_env: self.context.lvar_env)
|
87
|
+
if lvar_env != self.context.lvar_env
|
88
|
+
with(context: self.context.with(lvar_env: lvar_env))
|
89
|
+
else
|
90
|
+
self
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def with(annotations: self.annotations, context: self.context, typing: self.typing)
|
95
|
+
if context != self.context || typing != self.typing
|
96
|
+
self.class.new(
|
97
|
+
checker: checker,
|
98
|
+
source: source,
|
99
|
+
annotations: annotations,
|
100
|
+
typing: typing,
|
101
|
+
context: context
|
102
|
+
)
|
103
|
+
else
|
104
|
+
self
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def update_context()
|
109
|
+
with(context: yield(self.context))
|
110
|
+
end
|
111
|
+
|
112
|
+
def update_lvar_env
|
113
|
+
with_updated_context(lvar_env: yield(context.lvar_env))
|
114
|
+
end
|
115
|
+
|
53
116
|
def check_relation(sub_type:, super_type:, constraints: Subtyping::Constraints.empty)
|
54
117
|
checker.check(Subtyping::Relation.new(sub_type: sub_type, super_type: super_type), self_type: self_type, constraints: constraints)
|
55
118
|
end
|
@@ -100,7 +163,7 @@ module Steep
|
|
100
163
|
else
|
101
164
|
method_type.block.type
|
102
165
|
end
|
103
|
-
var_types[block_arg.children[0]
|
166
|
+
var_types[block_arg.children[0]] = block_type
|
104
167
|
end
|
105
168
|
end
|
106
169
|
|
@@ -123,12 +186,6 @@ module Steep
|
|
123
186
|
super_method: super_method
|
124
187
|
)
|
125
188
|
|
126
|
-
if var_types
|
127
|
-
var_types.each do |name, type|
|
128
|
-
type_env.set(lvar: name, type: type)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
189
|
if definition
|
133
190
|
definition.instance_variables.each do |name, decl|
|
134
191
|
type_env.set(ivar: name, type: checker.factory.type(decl.type))
|
@@ -136,12 +193,27 @@ module Steep
|
|
136
193
|
end
|
137
194
|
|
138
195
|
type_env = type_env.with_annotations(
|
139
|
-
lvar_types: annots.lvar_types,
|
140
196
|
ivar_types: annots.ivar_types,
|
141
197
|
const_types: annots.const_types,
|
142
198
|
self_type: annots.self_type || self_type
|
143
199
|
)
|
144
200
|
|
201
|
+
lvar_env = TypeInference::LocalVariableTypeEnv.empty(
|
202
|
+
subtyping: checker,
|
203
|
+
self_type: annots.self_type || self_type
|
204
|
+
)
|
205
|
+
|
206
|
+
if var_types
|
207
|
+
lvar_env = lvar_env.update(
|
208
|
+
assigned_types: var_types.each.with_object({}) {|(var, type), hash|
|
209
|
+
arg_node = args.find {|arg| arg.children[0] == var }
|
210
|
+
hash[var.name] = TypeInference::LocalVariableTypeEnv::Entry.new(type: type, nodes: [arg_node].compact)
|
211
|
+
}
|
212
|
+
)
|
213
|
+
end
|
214
|
+
|
215
|
+
lvar_env = lvar_env.annotate(annots)
|
216
|
+
|
145
217
|
self.class.new(
|
146
218
|
checker: checker,
|
147
219
|
source: source,
|
@@ -152,7 +224,8 @@ module Steep
|
|
152
224
|
block_context: nil,
|
153
225
|
break_context: nil,
|
154
226
|
self_type: annots.self_type || self_type,
|
155
|
-
type_env: type_env
|
227
|
+
type_env: type_env,
|
228
|
+
lvar_env: lvar_env
|
156
229
|
),
|
157
230
|
typing: typing,
|
158
231
|
)
|
@@ -162,6 +235,9 @@ module Steep
|
|
162
235
|
new_module_name = Names::Module.from_node(node.children.first) or raise "Unexpected module name: #{node.children.first}"
|
163
236
|
new_namespace = nested_namespace_for_module(new_module_name)
|
164
237
|
|
238
|
+
const_context = [new_namespace] + self.module_context.const_env.context
|
239
|
+
module_const_env = TypeInference::ConstantEnv.new(factory: checker.factory, context: const_context)
|
240
|
+
|
165
241
|
annots = source.annotations(block: node, factory: checker.factory, current_module: new_namespace)
|
166
242
|
module_type = AST::Builtin::Module.instance_type
|
167
243
|
|
@@ -219,13 +295,6 @@ module Steep
|
|
219
295
|
module_type = annots.module_type
|
220
296
|
end
|
221
297
|
|
222
|
-
const_context = if new_namespace.empty?
|
223
|
-
nil
|
224
|
-
else
|
225
|
-
Names::Module.new(name: new_namespace.path.last, namespace: new_namespace.parent)
|
226
|
-
end
|
227
|
-
module_const_env = TypeInference::ConstantEnv.new(factory: checker.factory, context: const_context)
|
228
|
-
|
229
298
|
module_context_ = TypeInference::Context::ModuleContext.new(
|
230
299
|
instance_type: instance_type,
|
231
300
|
module_type: annots.self_type || module_type,
|
@@ -242,6 +311,11 @@ module Steep
|
|
242
311
|
const_env: module_const_env,
|
243
312
|
signatures: checker.factory.env)
|
244
313
|
|
314
|
+
lvar_env = TypeInference::LocalVariableTypeEnv.empty(
|
315
|
+
subtyping: checker,
|
316
|
+
self_type: module_context_.module_type
|
317
|
+
).annotate(annots)
|
318
|
+
|
245
319
|
self.class.new(
|
246
320
|
checker: checker,
|
247
321
|
source: source,
|
@@ -253,7 +327,8 @@ module Steep
|
|
253
327
|
break_context: nil,
|
254
328
|
module_context: module_context_,
|
255
329
|
self_type: module_context_.module_type,
|
256
|
-
type_env: module_type_env
|
330
|
+
type_env: module_type_env,
|
331
|
+
lvar_env: lvar_env
|
257
332
|
)
|
258
333
|
)
|
259
334
|
end
|
@@ -318,11 +393,7 @@ module Steep
|
|
318
393
|
module_type = annots.module_type
|
319
394
|
end
|
320
395
|
|
321
|
-
const_context =
|
322
|
-
nil
|
323
|
-
else
|
324
|
-
Names::Module.new(name: new_namespace.path.last, namespace: new_namespace.parent)
|
325
|
-
end
|
396
|
+
const_context = [new_namespace] + self.module_context.const_env.context
|
326
397
|
class_const_env = TypeInference::ConstantEnv.new(factory: checker.factory, context: const_context)
|
327
398
|
|
328
399
|
module_context = TypeInference::Context::ModuleContext.new(
|
@@ -341,51 +412,90 @@ module Steep
|
|
341
412
|
const_env: class_const_env,
|
342
413
|
signatures: checker.factory.env)
|
343
414
|
|
415
|
+
lvar_env = TypeInference::LocalVariableTypeEnv.empty(
|
416
|
+
subtyping: checker,
|
417
|
+
self_type: module_context.module_type
|
418
|
+
).annotate(annots)
|
419
|
+
|
420
|
+
class_body_context = TypeInference::Context.new(
|
421
|
+
method_context: nil,
|
422
|
+
block_context: nil,
|
423
|
+
module_context: module_context,
|
424
|
+
break_context: nil,
|
425
|
+
self_type: module_context.module_type,
|
426
|
+
type_env: class_type_env,
|
427
|
+
lvar_env: lvar_env
|
428
|
+
)
|
344
429
|
|
345
430
|
self.class.new(
|
346
431
|
checker: checker,
|
347
432
|
source: source,
|
348
433
|
annotations: annots,
|
349
434
|
typing: typing,
|
350
|
-
context:
|
351
|
-
method_context: nil,
|
352
|
-
block_context: nil,
|
353
|
-
module_context: module_context,
|
354
|
-
break_context: nil,
|
355
|
-
self_type: module_context.module_type,
|
356
|
-
type_env: class_type_env
|
357
|
-
)
|
435
|
+
context: class_body_context
|
358
436
|
)
|
359
437
|
end
|
360
438
|
|
361
439
|
def for_branch(node, truthy_vars: Set.new, type_case_override: nil, break_context: context.break_context)
|
362
440
|
annots = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
363
441
|
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
442
|
+
lvar_env = context.lvar_env
|
443
|
+
|
444
|
+
unless truthy_vars.empty?
|
445
|
+
lvar_env = lvar_env.yield_self do |env|
|
446
|
+
decls = env.declared_types.each.with_object({}) do |(name, entry), hash|
|
447
|
+
if truthy_vars.include?(name)
|
448
|
+
hash[name] = entry.update(type: unwrap(entry.type))
|
449
|
+
else
|
450
|
+
hash[name] = entry
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
assignments = env.assigned_types.each.with_object({}) do |(name, entry), hash|
|
455
|
+
if truthy_vars.include?(name)
|
456
|
+
hash[name] = entry.update(type: unwrap(entry.type))
|
457
|
+
else
|
458
|
+
hash[name] = entry
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
env.update(declared_types: decls, assigned_types: assignments)
|
369
463
|
end
|
370
464
|
end
|
371
465
|
|
372
|
-
|
373
|
-
|
466
|
+
if type_case_override
|
467
|
+
lvar_env = type_case_override.inject(lvar_env) do |lvar_env, (name, type)|
|
468
|
+
lvar_env.assign!(name, node: node, type: type) do |declared_type, assigned_type, result|
|
469
|
+
relation = Subtyping::Relation.new(sub_type: assigned_type, super_type: declared_type)
|
470
|
+
typing.add_error(
|
471
|
+
Errors::IncompatibleTypeCase.new(
|
472
|
+
node: node,
|
473
|
+
var_name: name,
|
474
|
+
relation: relation,
|
475
|
+
result: result
|
476
|
+
)
|
477
|
+
)
|
478
|
+
end
|
479
|
+
end
|
374
480
|
end
|
375
481
|
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
482
|
+
lvar_env = lvar_env.annotate(annots) do |var, outer_type, inner_type, result|
|
483
|
+
relation = Subtyping::Relation.new(sub_type: inner_type, super_type: outer_type)
|
484
|
+
typing.add_error(
|
485
|
+
Errors::IncompatibleAnnotation.new(node: node,
|
380
486
|
var_name: var,
|
381
487
|
relation: relation,
|
382
488
|
result: result)
|
383
|
-
|
384
|
-
|
489
|
+
)
|
490
|
+
end
|
491
|
+
|
492
|
+
type_env = context.type_env
|
493
|
+
|
494
|
+
if type_case_override
|
495
|
+
type_env = type_env.with_annotations(self_type: self_type)
|
385
496
|
end
|
386
497
|
|
387
498
|
type_env = type_env.with_annotations(
|
388
|
-
lvar_types: annots.lvar_types,
|
389
499
|
ivar_types: annots.ivar_types,
|
390
500
|
const_types: annots.const_types,
|
391
501
|
gvar_types: {},
|
@@ -399,19 +509,18 @@ module Steep
|
|
399
509
|
)
|
400
510
|
end
|
401
511
|
|
402
|
-
|
512
|
+
update_context {|context|
|
513
|
+
context.with(type_env: type_env,
|
514
|
+
break_context: break_context,
|
515
|
+
lvar_env: lvar_env)
|
516
|
+
}
|
403
517
|
end
|
404
518
|
|
405
|
-
|
519
|
+
def add_typing(node, type:, constr: self)
|
520
|
+
raise if constr.typing != self.typing
|
406
521
|
|
407
|
-
|
408
|
-
|
409
|
-
checker: checker,
|
410
|
-
source: source,
|
411
|
-
annotations: annotations.equal?(NOTHING) ? self.annotations : annotations,
|
412
|
-
typing: typing,
|
413
|
-
context: context.equal?(NOTHING) ? self.context : context
|
414
|
-
)
|
522
|
+
typing.add_typing(node, type, nil)
|
523
|
+
Pair.new(type: type, constr: constr)
|
415
524
|
end
|
416
525
|
|
417
526
|
def synthesize(node, hint: nil)
|
@@ -420,43 +529,63 @@ module Steep
|
|
420
529
|
case node.type
|
421
530
|
when :begin, :kwbegin
|
422
531
|
yield_self do
|
532
|
+
end_pos = node.loc.expression.end_pos
|
533
|
+
|
423
534
|
*mid_nodes, last_node = each_child_node(node).to_a
|
424
|
-
mid_nodes.each do |child|
|
425
|
-
synthesize(child)
|
426
|
-
end
|
427
535
|
if last_node
|
428
|
-
|
536
|
+
pair = mid_nodes.inject(Pair.new(type: AST::Builtin.nil_type, constr: self)) do |pair, node|
|
537
|
+
pair.constr.synthesize(node).yield_self {|p| pair + p }.tap do |new_pair|
|
538
|
+
if new_pair.constr.context != pair.constr.context
|
539
|
+
# update context
|
540
|
+
range = node.loc.expression.end_pos..end_pos
|
541
|
+
typing.add_context(range, context: new_pair.constr.context)
|
542
|
+
end
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
p = pair.constr.synthesize(last_node, hint: hint)
|
547
|
+
last_pair = pair + p
|
548
|
+
last_pair.constr.add_typing(node, type: last_pair.type, constr: last_pair.constr)
|
429
549
|
else
|
430
|
-
type
|
550
|
+
add_typing(node, type: AST::Builtin.nil_type)
|
431
551
|
end
|
432
|
-
|
433
|
-
typing.add_typing(node, type, context)
|
434
552
|
end
|
435
553
|
|
436
554
|
when :lvasgn
|
437
555
|
yield_self do
|
438
|
-
var = node.children
|
439
|
-
|
556
|
+
var, rhs = node.children
|
557
|
+
name = var.name
|
440
558
|
|
441
|
-
case
|
559
|
+
case name
|
442
560
|
when :_, :__any__
|
443
|
-
synthesize(rhs, hint: AST::Builtin.any_type)
|
444
|
-
|
561
|
+
synthesize(rhs, hint: AST::Builtin.any_type).yield_self do |pair|
|
562
|
+
add_typing(node, type: AST::Builtin.any_type, constr: pair.constr)
|
563
|
+
end
|
445
564
|
when :__skip__
|
446
|
-
|
565
|
+
add_typing(node, type: AST::Builtin.any_type)
|
447
566
|
else
|
448
|
-
|
567
|
+
rhs_result = synthesize(rhs, hint: hint || context.lvar_env.declared_types[name]&.type)
|
568
|
+
constr = rhs_result.constr.update_lvar_env do |lvar_env|
|
569
|
+
lvar_env.assign(name, node: node, type: rhs_result.type) do |declared_type, actual_type, result|
|
570
|
+
typing.add_error(Errors::IncompatibleAssignment.new(node: node,
|
571
|
+
lhs_type: declared_type,
|
572
|
+
rhs_type: actual_type,
|
573
|
+
result: result))
|
574
|
+
end
|
575
|
+
end
|
576
|
+
|
577
|
+
add_typing(node, type: rhs_result.type, constr: constr)
|
449
578
|
end
|
450
579
|
end
|
451
580
|
|
452
581
|
when :lvar
|
453
582
|
yield_self do
|
454
583
|
var = node.children[0]
|
455
|
-
type =
|
456
|
-
|
584
|
+
if (type = context.lvar_env[var.name])
|
585
|
+
add_typing node, type: type
|
586
|
+
else
|
587
|
+
fallback_to_any(node)
|
457
588
|
end
|
458
|
-
|
459
|
-
typing.add_typing node, type, context
|
460
589
|
end
|
461
590
|
|
462
591
|
when :ivasgn
|
@@ -471,7 +600,7 @@ module Steep
|
|
471
600
|
type = type_env.get(ivar: name) do
|
472
601
|
fallback_to_any node
|
473
602
|
end
|
474
|
-
|
603
|
+
add_typing(node, type: type)
|
475
604
|
end
|
476
605
|
|
477
606
|
when :send
|
@@ -484,7 +613,7 @@ module Steep
|
|
484
613
|
module_type
|
485
614
|
end
|
486
615
|
|
487
|
-
|
616
|
+
add_typing(node, type: type)
|
488
617
|
else
|
489
618
|
type_send(node, send_node: node, block_params: nil, block_body: nil)
|
490
619
|
end
|
@@ -492,83 +621,58 @@ module Steep
|
|
492
621
|
|
493
622
|
when :csend
|
494
623
|
yield_self do
|
495
|
-
|
624
|
+
pair = if self_class?(node)
|
496
625
|
module_type = expand_alias(module_context.module_type)
|
497
626
|
type = if module_type.is_a?(AST::Types::Name::Class)
|
498
627
|
AST::Types::Name::Class.new(name: module_type.name, constructor: method_context.constructor)
|
499
628
|
else
|
500
629
|
module_type
|
501
630
|
end
|
502
|
-
|
631
|
+
add_typing(node, type: type)
|
503
632
|
else
|
504
633
|
type_send(node, send_node: node, block_params: nil, block_body: nil, unwrap: true)
|
505
634
|
end
|
506
635
|
|
507
|
-
|
636
|
+
lvar_env = context.lvar_env.join(pair.context.lvar_env, context.lvar_env)
|
637
|
+
add_typing(node,
|
638
|
+
type: union_type(pair.type, AST::Builtin.nil_type),
|
639
|
+
constr: pair.constr.with_updated_context(lvar_env: lvar_env))
|
508
640
|
end
|
509
641
|
|
510
642
|
when :match_with_lvasgn
|
511
643
|
each_child_node(node) do |child|
|
512
644
|
synthesize(child)
|
513
645
|
end
|
514
|
-
|
646
|
+
add_typing(node, type: AST::Builtin.any_type)
|
515
647
|
|
516
648
|
when :op_asgn
|
517
649
|
yield_self do
|
518
650
|
lhs, op, rhs = node.children
|
519
651
|
|
520
|
-
|
652
|
+
case lhs.type
|
653
|
+
when :lvasgn
|
654
|
+
var_node = lhs.updated(:lvar)
|
655
|
+
send_node = rhs.updated(:send, [var_node, op, rhs])
|
656
|
+
new_node = node.updated(:lvasgn, [lhs.children[0], send_node])
|
521
657
|
|
522
|
-
|
523
|
-
when :lvasgn
|
524
|
-
type_env.get(lvar: lhs.children.first.name) do
|
525
|
-
break
|
526
|
-
end
|
527
|
-
when :ivasgn
|
528
|
-
type_env.get(ivar: lhs.children.first) do
|
529
|
-
break
|
530
|
-
end
|
531
|
-
else
|
532
|
-
Steep.logger.error("Unexpected op_asgn lhs: #{lhs.type}")
|
533
|
-
nil
|
534
|
-
end
|
658
|
+
type, constr = synthesize(new_node, hint: hint)
|
535
659
|
|
536
|
-
|
537
|
-
when lhs_type == AST::Builtin.any_type
|
538
|
-
typing.add_typing(node, lhs_type, context)
|
539
|
-
when !lhs_type
|
540
|
-
fallback_to_any(node)
|
541
|
-
else
|
542
|
-
lhs_interface = checker.factory.interface(lhs_type, private: false)
|
543
|
-
op_method = lhs_interface.methods[op]
|
660
|
+
constr.add_typing(node, type: type)
|
544
661
|
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
method_name: op,
|
550
|
-
method: op_method,
|
551
|
-
args: args,
|
552
|
-
block_params: nil,
|
553
|
-
block_body: nil,
|
554
|
-
topdown_hint: true)
|
662
|
+
when :ivasgn
|
663
|
+
var_node = lhs.updated(:ivar)
|
664
|
+
send_node = rhs.updated(:send, [var_node, op, rhs])
|
665
|
+
new_node = node.updated(:ivasgn, [lhs.children[0], send_node])
|
555
666
|
|
556
|
-
|
557
|
-
if result.failure?
|
558
|
-
typing.add_error(
|
559
|
-
Errors::IncompatibleAssignment.new(
|
560
|
-
node: node,
|
561
|
-
lhs_type: lhs_type,
|
562
|
-
rhs_type: return_type,
|
563
|
-
result: result
|
564
|
-
)
|
565
|
-
)
|
566
|
-
end
|
567
|
-
else
|
568
|
-
typing.add_error Errors::NoMethod.new(node: node, method: op, type: expand_self(lhs_type))
|
569
|
-
end
|
667
|
+
type, constr = synthesize(new_node, hint: hint)
|
570
668
|
|
571
|
-
|
669
|
+
constr.add_typing(node, type: type)
|
670
|
+
|
671
|
+
else
|
672
|
+
Steep.logger.error("Unexpected op_asgn lhs: #{lhs.type}")
|
673
|
+
|
674
|
+
_, constr = synthesize(rhs)
|
675
|
+
constr.add_typing(node, type: AST::Builtin.any_type)
|
572
676
|
end
|
573
677
|
end
|
574
678
|
|
@@ -597,7 +701,7 @@ module Steep
|
|
597
701
|
block_body: nil,
|
598
702
|
topdown_hint: true)
|
599
703
|
|
600
|
-
|
704
|
+
add_typing node, type: return_type
|
601
705
|
else
|
602
706
|
fallback_to_any node do
|
603
707
|
Errors::UnexpectedSuper.new(node: node, method: method_context.name)
|
@@ -619,49 +723,64 @@ module Steep
|
|
619
723
|
end
|
620
724
|
|
621
725
|
when :def
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
new.check(node.children[2], return_type) do |_, actual_type, result|
|
636
|
-
typing.add_error(Errors::MethodBodyTypeMismatch.new(node: node,
|
637
|
-
expected: new.method_context&.return_type,
|
638
|
-
actual: actual_type,
|
639
|
-
result: result))
|
640
|
-
end
|
641
|
-
else
|
642
|
-
new.synthesize(node.children[2])
|
726
|
+
yield_self do
|
727
|
+
name, args_node, body_node = node.children
|
728
|
+
|
729
|
+
new = for_new_method(name,
|
730
|
+
node,
|
731
|
+
args: args_node.children,
|
732
|
+
self_type: module_context&.instance_type,
|
733
|
+
definition: module_context&.instance_definition)
|
734
|
+
new.typing.add_context_for_node(node, context: new.context)
|
735
|
+
new.typing.add_context_for_body(node, context: new.context)
|
736
|
+
|
737
|
+
each_child_node(args_node) do |arg|
|
738
|
+
new.synthesize(arg)
|
643
739
|
end
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
740
|
+
|
741
|
+
body_pair = if body_node
|
742
|
+
return_type = expand_alias(new.method_context&.return_type)
|
743
|
+
if return_type && !return_type.is_a?(AST::Types::Void)
|
744
|
+
new.check(body_node, return_type) do |_, actual_type, result|
|
745
|
+
typing.add_error(Errors::MethodBodyTypeMismatch.new(node: node,
|
746
|
+
expected: new.method_context&.return_type,
|
747
|
+
actual: actual_type,
|
748
|
+
result: result))
|
749
|
+
end
|
750
|
+
else
|
751
|
+
new.synthesize(body_node)
|
752
|
+
end
|
753
|
+
else
|
754
|
+
return_type = expand_alias(new.method_context&.return_type)
|
755
|
+
if return_type && !return_type.is_a?(AST::Types::Void)
|
756
|
+
result = check_relation(sub_type: AST::Builtin.nil_type, super_type: return_type)
|
757
|
+
if result.failure?
|
758
|
+
typing.add_error(Errors::MethodBodyTypeMismatch.new(node: node,
|
759
|
+
expected: new.method_context&.return_type,
|
760
|
+
actual: AST::Builtin.nil_type,
|
761
|
+
result: result))
|
762
|
+
end
|
763
|
+
end
|
764
|
+
|
765
|
+
Pair.new(type: AST::Builtin.nil_type, constr: new)
|
766
|
+
end
|
767
|
+
|
768
|
+
if body_node
|
769
|
+
begin_pos = body_node.loc.expression.end_pos
|
770
|
+
end_pos = node.loc.end.begin_pos
|
771
|
+
|
772
|
+
typing.add_context(begin_pos..end_pos, context: body_pair.context)
|
654
773
|
end
|
655
|
-
end
|
656
774
|
|
657
|
-
|
658
|
-
|
659
|
-
|
775
|
+
if module_context
|
776
|
+
module_context.defined_instance_methods << node.children[0]
|
777
|
+
end
|
660
778
|
|
661
|
-
|
779
|
+
add_typing(node, type: AST::Builtin::Symbol.instance_type)
|
780
|
+
end
|
662
781
|
|
663
782
|
when :defs
|
664
|
-
synthesize(node.children[0]).tap do |self_type|
|
783
|
+
synthesize(node.children[0]).type.tap do |self_type|
|
665
784
|
self_type = expand_self(self_type)
|
666
785
|
definition = case self_type
|
667
786
|
when AST::Types::Name::Instance
|
@@ -677,6 +796,8 @@ module Steep
|
|
677
796
|
args: node.children[2].children,
|
678
797
|
self_type: self_type,
|
679
798
|
definition: definition)
|
799
|
+
new.typing.add_context_for_node(node, context: new.context)
|
800
|
+
new.typing.add_context_for_body(node, context: new.context)
|
680
801
|
|
681
802
|
each_child_node(node.children[2]) do |arg|
|
682
803
|
new.synthesize(arg)
|
@@ -703,13 +824,20 @@ module Steep
|
|
703
824
|
end
|
704
825
|
end
|
705
826
|
|
706
|
-
|
827
|
+
add_typing(node, type: AST::Builtin::Symbol.instance_type)
|
707
828
|
|
708
829
|
when :return
|
709
830
|
yield_self do
|
710
831
|
if node.children.size > 0
|
832
|
+
method_return_type = expand_alias(method_context&.return_type)
|
833
|
+
|
711
834
|
return_types = node.children.map do |value|
|
712
|
-
synthesize(value
|
835
|
+
synthesize(value,
|
836
|
+
hint: if method_return_type.is_a?(AST::Types::Void)
|
837
|
+
nil
|
838
|
+
else
|
839
|
+
method_return_type
|
840
|
+
end).type
|
713
841
|
end
|
714
842
|
|
715
843
|
value_type = if return_types.size == 1
|
@@ -718,9 +846,9 @@ module Steep
|
|
718
846
|
AST::Builtin::Array.instance_type(union_type(*return_types))
|
719
847
|
end
|
720
848
|
|
721
|
-
if
|
722
|
-
unless
|
723
|
-
result = check_relation(sub_type: value_type, super_type:
|
849
|
+
if method_return_type
|
850
|
+
unless method_return_type.is_a?(AST::Types::Void)
|
851
|
+
result = check_relation(sub_type: value_type, super_type: method_return_type)
|
724
852
|
|
725
853
|
if result.failure?
|
726
854
|
typing.add_error(Errors::ReturnTypeMismatch.new(node: node,
|
@@ -732,7 +860,7 @@ module Steep
|
|
732
860
|
end
|
733
861
|
end
|
734
862
|
|
735
|
-
|
863
|
+
add_typing(node, type: AST::Builtin.bottom_type)
|
736
864
|
end
|
737
865
|
|
738
866
|
when :break
|
@@ -758,7 +886,7 @@ module Steep
|
|
758
886
|
typing.add_error Errors::UnexpectedJump.new(node: node)
|
759
887
|
end
|
760
888
|
|
761
|
-
|
889
|
+
add_typing(node, type: AST::Builtin.bottom_type)
|
762
890
|
|
763
891
|
when :next
|
764
892
|
value = node.children[0]
|
@@ -783,77 +911,99 @@ module Steep
|
|
783
911
|
typing.add_error Errors::UnexpectedJump.new(node: node)
|
784
912
|
end
|
785
913
|
|
786
|
-
|
914
|
+
add_typing(node, type: AST::Builtin.bottom_type)
|
787
915
|
|
788
916
|
when :retry
|
789
917
|
unless break_context
|
790
918
|
typing.add_error Errors::UnexpectedJump.new(node: node)
|
791
919
|
end
|
792
|
-
|
920
|
+
add_typing(node, type: AST::Builtin.bottom_type)
|
793
921
|
|
794
922
|
when :arg, :kwarg, :procarg0
|
795
923
|
yield_self do
|
796
924
|
var = node.children[0]
|
797
|
-
type =
|
798
|
-
|
925
|
+
type = context.lvar_env[var.name]
|
926
|
+
unless type
|
927
|
+
type = AST::Builtin.any_type
|
928
|
+
Steep.logger.error { "Unknown arg type: #{node}" }
|
799
929
|
end
|
800
|
-
|
930
|
+
add_typing(node, type: type)
|
801
931
|
end
|
802
932
|
|
803
933
|
when :optarg, :kwoptarg
|
804
934
|
yield_self do
|
805
935
|
var = node.children[0]
|
806
936
|
rhs = node.children[1]
|
807
|
-
|
937
|
+
|
938
|
+
type = context.lvar_env[var.name]
|
939
|
+
|
940
|
+
node_type, constr = synthesize(rhs, hint: type)
|
941
|
+
|
942
|
+
constr_ = constr.update_lvar_env do |env|
|
943
|
+
env.assign(var.name, node: node, type: node_type) do |declared_type, type, result|
|
944
|
+
typing.add_error(
|
945
|
+
Errors::IncompatibleAssignment.new(node: node,
|
946
|
+
lhs_type: declared_type,
|
947
|
+
rhs_type: type,
|
948
|
+
result: result)
|
949
|
+
)
|
950
|
+
end
|
951
|
+
end
|
952
|
+
|
953
|
+
add_typing(node, type: constr_.context.lvar_env[var.name], constr: constr_)
|
808
954
|
end
|
809
955
|
|
810
956
|
when :restarg
|
811
957
|
yield_self do
|
812
958
|
var = node.children[0]
|
813
|
-
type =
|
959
|
+
type = context.lvar_env[var.name]
|
960
|
+
unless type
|
961
|
+
Steep.logger.error { "Unknown variable: #{node}" }
|
814
962
|
typing.add_error Errors::FallbackAny.new(node: node)
|
815
|
-
AST::Builtin::Array.instance_type(AST::Builtin.any_type)
|
963
|
+
type = AST::Builtin::Array.instance_type(AST::Builtin.any_type)
|
816
964
|
end
|
817
965
|
|
818
|
-
|
966
|
+
add_typing(node, type: type)
|
819
967
|
end
|
820
968
|
|
821
969
|
when :kwrestarg
|
822
970
|
yield_self do
|
823
971
|
var = node.children[0]
|
824
|
-
type =
|
972
|
+
type = context.lvar_env[var.name]
|
973
|
+
unless type
|
974
|
+
Steep.logger.error { "Unknown variable: #{node}" }
|
825
975
|
typing.add_error Errors::FallbackAny.new(node: node)
|
826
|
-
AST::Builtin::Hash.instance_type(AST::Builtin::Symbol.instance_type, AST::Builtin.any_type)
|
976
|
+
type = AST::Builtin::Hash.instance_type(AST::Builtin::Symbol.instance_type, AST::Builtin.any_type)
|
827
977
|
end
|
828
978
|
|
829
|
-
|
979
|
+
add_typing(node, type: type)
|
830
980
|
end
|
831
981
|
|
832
982
|
when :float
|
833
|
-
|
983
|
+
add_typing(node, type: AST::Builtin::Float.instance_type)
|
834
984
|
|
835
985
|
when :nil
|
836
|
-
|
986
|
+
add_typing(node, type: AST::Builtin.nil_type)
|
837
987
|
|
838
988
|
when :int
|
839
989
|
yield_self do
|
840
|
-
literal_type = expand_alias(hint) {|hint_| test_literal_type(node.children[0], hint_)}
|
990
|
+
literal_type = expand_alias(hint) {|hint_| test_literal_type(node.children[0], hint_) }
|
841
991
|
|
842
992
|
if literal_type
|
843
|
-
|
993
|
+
add_typing(node, type: literal_type)
|
844
994
|
else
|
845
|
-
|
995
|
+
add_typing(node, type: AST::Builtin::Integer.instance_type)
|
846
996
|
end
|
847
997
|
end
|
848
998
|
|
849
999
|
when :sym
|
850
1000
|
yield_self do
|
851
|
-
literal_type = expand_alias(hint) {|
|
1001
|
+
literal_type = expand_alias(hint) {|hint| test_literal_type(node.children[0], hint) }
|
852
1002
|
|
853
1003
|
if literal_type
|
854
|
-
|
1004
|
+
add_typing(node, type: literal_type)
|
855
1005
|
else
|
856
|
-
|
1006
|
+
add_typing(node, type: AST::Builtin::Symbol.instance_type)
|
857
1007
|
end
|
858
1008
|
end
|
859
1009
|
|
@@ -862,14 +1012,14 @@ module Steep
|
|
862
1012
|
literal_type = expand_alias(hint) {|hint_| test_literal_type(node.children[0], hint_)}
|
863
1013
|
|
864
1014
|
if literal_type
|
865
|
-
|
1015
|
+
add_typing(node, type: literal_type)
|
866
1016
|
else
|
867
|
-
|
1017
|
+
add_typing(node, type: AST::Builtin::String.instance_type)
|
868
1018
|
end
|
869
1019
|
end
|
870
1020
|
|
871
1021
|
when :true, :false
|
872
|
-
|
1022
|
+
add_typing(node, type: AST::Types::Boolean.new)
|
873
1023
|
|
874
1024
|
when :hash
|
875
1025
|
yield_self do
|
@@ -887,14 +1037,14 @@ module Steep
|
|
887
1037
|
case child.type
|
888
1038
|
when :pair
|
889
1039
|
key, value = child.children
|
890
|
-
key_types << synthesize(key).yield_self do |type|
|
1040
|
+
key_types << synthesize(key).type.yield_self do |type|
|
891
1041
|
select_super_type(type, key_hint)
|
892
1042
|
end
|
893
|
-
value_types << synthesize(value).yield_self do |type|
|
1043
|
+
value_types << synthesize(value).type.yield_self do |type|
|
894
1044
|
select_super_type(type, value_hint)
|
895
1045
|
end
|
896
1046
|
when :kwsplat
|
897
|
-
expand_alias(synthesize(child.children[0])) do |splat_type, original_type|
|
1047
|
+
expand_alias(synthesize(child.children[0]).type) do |splat_type, original_type|
|
898
1048
|
if AST::Builtin::Hash.instance_type?(splat_type)
|
899
1049
|
key_types << splat_type.args[0]
|
900
1050
|
value_types << splat_type.args[1]
|
@@ -916,7 +1066,7 @@ module Steep
|
|
916
1066
|
typing.add_error Errors::FallbackAny.new(node: node)
|
917
1067
|
end
|
918
1068
|
|
919
|
-
|
1069
|
+
add_typing(node, type: AST::Builtin::Hash.instance_type(key_type, value_type))
|
920
1070
|
end
|
921
1071
|
|
922
1072
|
when :dstr, :xstr
|
@@ -924,18 +1074,21 @@ module Steep
|
|
924
1074
|
synthesize(child)
|
925
1075
|
end
|
926
1076
|
|
927
|
-
|
1077
|
+
add_typing(node, type: AST::Builtin::String.instance_type)
|
928
1078
|
|
929
1079
|
when :dsym
|
930
1080
|
each_child_node(node) do |child|
|
931
1081
|
synthesize(child)
|
932
1082
|
end
|
933
1083
|
|
934
|
-
|
1084
|
+
add_typing(node, type: AST::Builtin::Symbol.instance_type)
|
935
1085
|
|
936
1086
|
when :class
|
937
1087
|
yield_self do
|
938
1088
|
for_class(node).tap do |constructor|
|
1089
|
+
constructor.typing.add_context_for_node(node, context: constructor.context)
|
1090
|
+
constructor.typing.add_context_for_body(node, context: constructor.context)
|
1091
|
+
|
939
1092
|
constructor.synthesize(node.children[2]) if node.children[2]
|
940
1093
|
|
941
1094
|
if constructor.module_context&.implement_name && !namespace_module?(node)
|
@@ -943,12 +1096,15 @@ module Steep
|
|
943
1096
|
end
|
944
1097
|
end
|
945
1098
|
|
946
|
-
|
1099
|
+
add_typing(node, type: AST::Builtin.nil_type)
|
947
1100
|
end
|
948
1101
|
|
949
1102
|
when :module
|
950
1103
|
yield_self do
|
951
1104
|
for_module(node).yield_self do |constructor|
|
1105
|
+
constructor.typing.add_context_for_node(node, context: constructor.context)
|
1106
|
+
constructor.typing.add_context_for_body(node, context: constructor.context)
|
1107
|
+
|
952
1108
|
constructor.synthesize(node.children[1]) if node.children[1]
|
953
1109
|
|
954
1110
|
if constructor.module_context&.implement_name && !namespace_module?(node)
|
@@ -956,19 +1112,20 @@ module Steep
|
|
956
1112
|
end
|
957
1113
|
end
|
958
1114
|
|
959
|
-
|
1115
|
+
add_typing(node, type: AST::Builtin.nil_type)
|
960
1116
|
end
|
961
1117
|
|
962
1118
|
when :self
|
963
|
-
|
1119
|
+
add_typing node, type: AST::Types::Self.new
|
964
1120
|
|
965
1121
|
when :const
|
966
1122
|
const_name = Names::Module.from_node(node)
|
1123
|
+
|
967
1124
|
if const_name
|
968
1125
|
type = type_env.get(const: const_name) do
|
969
1126
|
fallback_to_any node
|
970
1127
|
end
|
971
|
-
|
1128
|
+
add_typing node, type: type
|
972
1129
|
else
|
973
1130
|
fallback_to_any node
|
974
1131
|
end
|
@@ -977,7 +1134,8 @@ module Steep
|
|
977
1134
|
yield_self do
|
978
1135
|
const_name = Names::Module.from_node(node)
|
979
1136
|
if const_name
|
980
|
-
|
1137
|
+
const_type = type_env.get(const: const_name) {}
|
1138
|
+
value_type = synthesize(node.children.last, hint: const_type).type
|
981
1139
|
type = type_env.assign(const: const_name, type: value_type, self_type: self_type) do |error|
|
982
1140
|
case error
|
983
1141
|
when Subtyping::Result::Failure
|
@@ -991,9 +1149,9 @@ module Steep
|
|
991
1149
|
end
|
992
1150
|
end
|
993
1151
|
|
994
|
-
|
1152
|
+
add_typing(node, type: type)
|
995
1153
|
else
|
996
|
-
synthesize(node.children.last)
|
1154
|
+
synthesize(node.children.last).type
|
997
1155
|
fallback_to_any(node)
|
998
1156
|
end
|
999
1157
|
end
|
@@ -1013,7 +1171,7 @@ module Steep
|
|
1013
1171
|
end
|
1014
1172
|
end
|
1015
1173
|
|
1016
|
-
|
1174
|
+
add_typing(node, type: block_type.type.return_type)
|
1017
1175
|
else
|
1018
1176
|
typing.add_error(Errors::UnexpectedYield.new(node: node))
|
1019
1177
|
fallback_to_any node
|
@@ -1027,16 +1185,9 @@ module Steep
|
|
1027
1185
|
if method_context&.method
|
1028
1186
|
if method_context.super_method
|
1029
1187
|
types = method_context.super_method.method_types.map {|method_type|
|
1030
|
-
|
1031
|
-
when Ruby::Signature::MethodType
|
1032
|
-
checker.factory.method_type(method_type, self_type: self_type).return_type
|
1033
|
-
when :any
|
1034
|
-
AST::Builtin.any_type
|
1035
|
-
else
|
1036
|
-
raise "Unexpected method_type: #{method_type.inspect}"
|
1037
|
-
end
|
1188
|
+
checker.factory.method_type(method_type, self_type: self_type).return_type
|
1038
1189
|
}
|
1039
|
-
|
1190
|
+
add_typing(node, type: union_type(*types))
|
1040
1191
|
else
|
1041
1192
|
typing.add_error(Errors::UnexpectedSuper.new(node: node, method: method_context.name))
|
1042
1193
|
fallback_to_any node
|
@@ -1058,7 +1209,7 @@ module Steep
|
|
1058
1209
|
end
|
1059
1210
|
end
|
1060
1211
|
|
1061
|
-
|
1212
|
+
add_typing(node, type: array_type || AST::Builtin::Array.instance_type(AST::Builtin.any_type))
|
1062
1213
|
else
|
1063
1214
|
is_tuple = nil
|
1064
1215
|
|
@@ -1068,7 +1219,7 @@ module Steep
|
|
1068
1219
|
is_tuple &&= node.children.size >= hint.types.size
|
1069
1220
|
is_tuple &&= hint.types.map.with_index do |child_type, index|
|
1070
1221
|
child_node = node.children[index]
|
1071
|
-
[synthesize(child_node, hint: child_type), child_type]
|
1222
|
+
[synthesize(child_node, hint: child_type).type, child_type]
|
1072
1223
|
end.all? do |node_type, hint_type|
|
1073
1224
|
result = check_relation(sub_type: node_type, super_type: hint_type)
|
1074
1225
|
result.success?
|
@@ -1085,7 +1236,7 @@ module Steep
|
|
1085
1236
|
element_types = node.children.flat_map do |e|
|
1086
1237
|
if e.type == :splat
|
1087
1238
|
Steep.logger.info "Typing of splat in array is incompatible with Ruby; it does not use #to_a method"
|
1088
|
-
synthesize(e.children.first).yield_self do |type|
|
1239
|
+
synthesize(e.children.first).type.yield_self do |type|
|
1089
1240
|
expand_alias(type) do |ty|
|
1090
1241
|
case ty
|
1091
1242
|
when AST::Types::Union
|
@@ -1105,155 +1256,237 @@ module Steep
|
|
1105
1256
|
end
|
1106
1257
|
end
|
1107
1258
|
else
|
1108
|
-
[select_super_type(synthesize(e), element_hint)]
|
1259
|
+
[select_super_type(synthesize(e).type, element_hint)]
|
1109
1260
|
end
|
1110
1261
|
end
|
1111
1262
|
array_type = AST::Builtin::Array.instance_type(AST::Types::Union.build(types: element_types))
|
1112
1263
|
end
|
1113
1264
|
|
1114
|
-
|
1265
|
+
add_typing(node, type: array_type)
|
1115
1266
|
end
|
1116
1267
|
end
|
1117
1268
|
|
1118
1269
|
when :and
|
1119
1270
|
yield_self do
|
1120
1271
|
left, right = node.children
|
1121
|
-
|
1272
|
+
logic = TypeInference::Logic.new(subtyping: checker)
|
1273
|
+
truthy, falsey = logic.nodes(node: left)
|
1122
1274
|
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
end
|
1275
|
+
left_type, constr = synthesize(left)
|
1276
|
+
truthy_env, falsey_env = logic.environments(truthy_vars: truthy.vars,
|
1277
|
+
falsey_vars: falsey.vars,
|
1278
|
+
lvar_env: constr.context.lvar_env)
|
1128
1279
|
|
1129
|
-
|
1130
|
-
const_env: nil)])
|
1280
|
+
right_type, constr = constr.update_lvar_env { truthy_env }.for_branch(right).synthesize(right)
|
1131
1281
|
|
1132
|
-
if left_type.is_a?(AST::Types::Boolean)
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1282
|
+
type = if left_type.is_a?(AST::Types::Boolean)
|
1283
|
+
union_type(left_type, right_type)
|
1284
|
+
else
|
1285
|
+
union_type(right_type, AST::Builtin.nil_type)
|
1286
|
+
end
|
1287
|
+
|
1288
|
+
add_typing(node,
|
1289
|
+
type: type,
|
1290
|
+
constr: constr.update_lvar_env do
|
1291
|
+
if right_type.is_a?(AST::Types::Bot)
|
1292
|
+
falsey_env
|
1293
|
+
else
|
1294
|
+
context.lvar_env.join(falsey_env, constr.context.lvar_env)
|
1295
|
+
end
|
1296
|
+
end)
|
1137
1297
|
end
|
1138
1298
|
|
1139
1299
|
when :or
|
1140
1300
|
yield_self do
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1301
|
+
left, right = node.children
|
1302
|
+
logic = TypeInference::Logic.new(subtyping: checker)
|
1303
|
+
truthy, falsey = logic.nodes(node: left)
|
1304
|
+
|
1305
|
+
left_type, constr = synthesize(left, hint: hint)
|
1306
|
+
truthy_env, falsey_env = logic.environments(truthy_vars: truthy.vars,
|
1307
|
+
falsey_vars: falsey.vars,
|
1308
|
+
lvar_env: constr.context.lvar_env)
|
1309
|
+
left_type_t, _ = logic.partition_union(left_type)
|
1310
|
+
|
1311
|
+
right_type, constr = constr.update_lvar_env { falsey_env }.for_branch(right).synthesize(right, hint: left_type_t)
|
1312
|
+
|
1313
|
+
type = union_type(left_type_t, right_type)
|
1314
|
+
|
1315
|
+
add_typing(node,
|
1316
|
+
type: type,
|
1317
|
+
constr: constr.update_lvar_env do
|
1318
|
+
if right_type.is_a?(AST::Types::Bot)
|
1319
|
+
truthy_env
|
1320
|
+
else
|
1321
|
+
context.lvar_env.join(truthy_env, constr.context.lvar_env)
|
1322
|
+
end
|
1323
|
+
end)
|
1146
1324
|
end
|
1147
1325
|
|
1148
1326
|
when :if
|
1149
1327
|
cond, true_clause, false_clause = node.children
|
1150
|
-
synthesize cond
|
1151
1328
|
|
1152
|
-
|
1329
|
+
cond_type, constr = synthesize(cond)
|
1330
|
+
logic = TypeInference::Logic.new(subtyping: checker)
|
1331
|
+
|
1332
|
+
truthys, falseys = logic.nodes(node: cond)
|
1333
|
+
truthy_env, falsey_env = logic.environments(truthy_vars: truthys.vars,
|
1334
|
+
falsey_vars: falseys.vars,
|
1335
|
+
lvar_env: constr.context.lvar_env)
|
1153
1336
|
|
1154
1337
|
if true_clause
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1338
|
+
true_pair = constr
|
1339
|
+
.update_lvar_env { truthy_env }
|
1340
|
+
.for_branch(true_clause)
|
1341
|
+
.tap {|constr| typing.add_context_for_node(true_clause, context: constr.context) }
|
1342
|
+
.synthesize(true_clause, hint: hint)
|
1159
1343
|
end
|
1344
|
+
|
1160
1345
|
if false_clause
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1346
|
+
false_pair = constr
|
1347
|
+
.update_lvar_env { falsey_env }
|
1348
|
+
.for_branch(false_clause)
|
1349
|
+
.tap {|constr| typing.add_context_for_node(false_clause, context: constr.context) }
|
1350
|
+
.synthesize(false_clause, hint: hint)
|
1351
|
+
end
|
1352
|
+
|
1353
|
+
constr = constr.update_lvar_env do |env|
|
1354
|
+
envs = []
|
1355
|
+
|
1356
|
+
if true_pair
|
1357
|
+
unless true_pair.type.is_a?(AST::Types::Bot)
|
1358
|
+
envs << true_pair.context.lvar_env
|
1359
|
+
end
|
1360
|
+
else
|
1361
|
+
envs << truthy_env
|
1362
|
+
end
|
1363
|
+
|
1364
|
+
if false_pair
|
1365
|
+
unless false_pair.type.is_a?(AST::Types::Bot)
|
1366
|
+
envs << false_pair.context.lvar_env
|
1367
|
+
end
|
1368
|
+
else
|
1369
|
+
envs << falsey_env
|
1164
1370
|
end
|
1371
|
+
|
1372
|
+
env.join(*envs)
|
1165
1373
|
end
|
1166
1374
|
|
1167
|
-
|
1168
|
-
|
1375
|
+
add_typing(node,
|
1376
|
+
type: union_type(true_pair&.type || AST::Builtin.nil_type,
|
1377
|
+
false_pair&.type || AST::Builtin.nil_type),
|
1378
|
+
constr: constr)
|
1169
1379
|
|
1170
1380
|
when :case
|
1171
1381
|
yield_self do
|
1172
|
-
cond, *whens = node.children
|
1382
|
+
cond, *whens, els = node.children
|
1383
|
+
|
1384
|
+
constr = self
|
1173
1385
|
|
1174
1386
|
if cond
|
1175
|
-
cond_type =
|
1387
|
+
cond_type, constr = synthesize(cond)
|
1388
|
+
cond_type = expand_alias(cond_type)
|
1176
1389
|
if cond_type.is_a?(AST::Types::Union)
|
1177
1390
|
var_names = TypeConstruction.value_variables(cond)
|
1178
1391
|
var_types = cond_type.types.dup
|
1179
1392
|
end
|
1180
1393
|
end
|
1181
1394
|
|
1182
|
-
|
1183
|
-
if clause&.type == :when
|
1184
|
-
test_types = clause.children.take(clause.children.size - 1).map do |child|
|
1185
|
-
expand_alias(synthesize(child, hint: hint))
|
1186
|
-
end
|
1395
|
+
branch_pairs = []
|
1187
1396
|
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1397
|
+
whens.each do |clause|
|
1398
|
+
*tests, body = clause.children
|
1399
|
+
|
1400
|
+
test_types = []
|
1401
|
+
clause_constr = constr
|
1402
|
+
|
1403
|
+
tests.each do |test|
|
1404
|
+
type, clause_constr = synthesize(test)
|
1405
|
+
test_types << expand_alias(type)
|
1406
|
+
end
|
1407
|
+
|
1408
|
+
if body
|
1409
|
+
if var_names && var_types && test_types.all? {|ty| ty.is_a?(AST::Types::Name::Class) }
|
1410
|
+
var_types_in_body = test_types.flat_map do |test_type|
|
1411
|
+
filtered_types = var_types.select do |var_type|
|
1412
|
+
var_type.is_a?(AST::Types::Name::Base) && var_type.name == test_type.name
|
1413
|
+
end
|
1414
|
+
if filtered_types.empty?
|
1415
|
+
to_instance_type(test_type)
|
1416
|
+
else
|
1417
|
+
filtered_types
|
1206
1418
|
end
|
1207
|
-
else
|
1208
|
-
type_case_override = nil
|
1209
1419
|
end
|
1210
1420
|
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1421
|
+
var_types.reject! do |type|
|
1422
|
+
var_types_in_body.any? do |test_type|
|
1423
|
+
type.is_a?(AST::Types::Name::Base) && test_type.name == type.name
|
1424
|
+
end
|
1425
|
+
end
|
1426
|
+
|
1427
|
+
var_type_in_body = union_type(*var_types_in_body)
|
1428
|
+
type_case_override = var_names.each.with_object({}) do |var_name, hash|
|
1429
|
+
hash[var_name] = var_type_in_body
|
1214
1430
|
end
|
1431
|
+
|
1432
|
+
branch_pairs << clause_constr
|
1433
|
+
.for_branch(body, type_case_override: type_case_override)
|
1434
|
+
.synthesize(body, hint: hint)
|
1215
1435
|
else
|
1216
|
-
|
1436
|
+
branch_pairs << clause_constr.synthesize(body, hint: hint)
|
1217
1437
|
end
|
1218
1438
|
else
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
type_case_override = var_names.each.with_object({}) do |var_name, hash|
|
1223
|
-
hash[var_name] = union_type(*var_types)
|
1224
|
-
end
|
1225
|
-
var_types.clear
|
1226
|
-
else
|
1227
|
-
typing.add_error Errors::ElseOnExhaustiveCase.new(node: node, type: cond_type)
|
1228
|
-
type_case_override = var_names.each.with_object({}) do |var_name, hash|
|
1229
|
-
hash[var_name] = AST::Builtin.any_type
|
1230
|
-
end
|
1231
|
-
end
|
1232
|
-
end
|
1439
|
+
branch_pairs << Pair.new(type: AST::Builtin.nil_type, constr: clause_constr)
|
1440
|
+
end
|
1441
|
+
end
|
1233
1442
|
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1443
|
+
if els
|
1444
|
+
if var_names && var_types
|
1445
|
+
if var_types.empty?
|
1446
|
+
typing.add_error Errors::ElseOnExhaustiveCase.new(node: node, type: cond_type)
|
1238
1447
|
end
|
1448
|
+
|
1449
|
+
else_override = var_names.each.with_object({}) do |var_name, hash|
|
1450
|
+
hash[var_name] = unless var_types.empty?
|
1451
|
+
union_type(*var_types)
|
1452
|
+
else
|
1453
|
+
AST::Builtin.any_type
|
1454
|
+
end
|
1455
|
+
end
|
1456
|
+
branch_pairs << constr
|
1457
|
+
.for_branch(els, type_case_override: else_override)
|
1458
|
+
.synthesize(els, hint: hint)
|
1459
|
+
else
|
1460
|
+
branch_pairs << constr.synthesize(els, hint: hint)
|
1239
1461
|
end
|
1240
1462
|
end
|
1241
1463
|
|
1242
|
-
types =
|
1243
|
-
|
1464
|
+
types = branch_pairs.map(&:type)
|
1465
|
+
constrs = branch_pairs.map(&:constr)
|
1244
1466
|
|
1245
|
-
unless var_types&.empty? ||
|
1467
|
+
unless var_types&.empty? || els
|
1246
1468
|
types.push AST::Builtin.nil_type
|
1247
1469
|
end
|
1248
1470
|
|
1249
|
-
|
1250
|
-
|
1471
|
+
constr = constr.update_lvar_env do |env|
|
1472
|
+
env.join(*constrs.map {|c| c.context.lvar_env })
|
1473
|
+
end
|
1474
|
+
|
1475
|
+
add_typing(node, type: union_type(*types), constr: constr)
|
1251
1476
|
end
|
1252
1477
|
|
1253
1478
|
when :rescue
|
1254
1479
|
yield_self do
|
1255
1480
|
body, *resbodies, else_node = node.children
|
1256
|
-
|
1481
|
+
body_pair = synthesize(body) if body
|
1482
|
+
|
1483
|
+
body_constr = if body_pair
|
1484
|
+
self.update_lvar_env do |env|
|
1485
|
+
env.join(env, body_pair.context.lvar_env)
|
1486
|
+
end
|
1487
|
+
else
|
1488
|
+
self
|
1489
|
+
end
|
1257
1490
|
|
1258
1491
|
resbody_pairs = resbodies.map do |resbody|
|
1259
1492
|
exn_classes, assignment, body = resbody.children
|
@@ -1261,7 +1494,7 @@ module Steep
|
|
1261
1494
|
if exn_classes
|
1262
1495
|
case exn_classes.type
|
1263
1496
|
when :array
|
1264
|
-
exn_types = exn_classes.children.map {|child| synthesize(child)}
|
1497
|
+
exn_types = exn_classes.children.map {|child| synthesize(child).type }
|
1265
1498
|
else
|
1266
1499
|
Steep.logger.error "Unexpected exception list: #{exn_classes.type}"
|
1267
1500
|
end
|
@@ -1294,27 +1527,28 @@ module Steep
|
|
1294
1527
|
type_override[var_name] = AST::Builtin.any_type
|
1295
1528
|
end
|
1296
1529
|
|
1297
|
-
resbody_construction = for_branch(resbody, type_case_override: type_override)
|
1530
|
+
resbody_construction = body_constr.for_branch(resbody, type_case_override: type_override)
|
1298
1531
|
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
|
1304
|
-
[type, resbody_construction.type_env]
|
1532
|
+
if body
|
1533
|
+
resbody_construction.synthesize(body)
|
1534
|
+
else
|
1535
|
+
Pair.new(constr: body_constr, type: AST::Builtin.nil_type)
|
1536
|
+
end
|
1305
1537
|
end
|
1306
|
-
|
1538
|
+
|
1539
|
+
resbody_types = resbody_pairs.map(&:type)
|
1540
|
+
resbody_envs = resbody_pairs.map {|pair| pair.context.lvar_env }
|
1307
1541
|
|
1308
1542
|
if else_node
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1543
|
+
else_pair = (body_pair&.constr || self).for_branch(else_node).synthesize(else_node)
|
1544
|
+
add_typing(node,
|
1545
|
+
type: union_type(*[else_pair.type, *resbody_types].compact),
|
1546
|
+
constr: update_lvar_env {|env| env.join(*resbody_envs, env) })
|
1547
|
+
else
|
1548
|
+
add_typing(node,
|
1549
|
+
type: union_type(*[body_pair&.type, *resbody_types].compact),
|
1550
|
+
constr: update_lvar_env {|env| env.join(*resbody_envs, (body_pair&.constr || self).context.lvar_env) })
|
1312
1551
|
end
|
1313
|
-
|
1314
|
-
type_env.join!([*resbody_envs, else_env].compact)
|
1315
|
-
|
1316
|
-
types = [body_type, *resbody_types, else_type].compact
|
1317
|
-
typing.add_typing(node, union_type(*types), context)
|
1318
1552
|
end
|
1319
1553
|
|
1320
1554
|
when :resbody
|
@@ -1322,66 +1556,105 @@ module Steep
|
|
1322
1556
|
klasses, asgn, body = node.children
|
1323
1557
|
synthesize(klasses) if klasses
|
1324
1558
|
synthesize(asgn) if asgn
|
1325
|
-
body_type = synthesize(body) if body
|
1326
|
-
|
1559
|
+
body_type = synthesize(body).type if body
|
1560
|
+
add_typing(node, type: body_type)
|
1327
1561
|
end
|
1328
1562
|
|
1329
1563
|
when :ensure
|
1330
1564
|
yield_self do
|
1331
1565
|
body, ensure_body = node.children
|
1332
|
-
body_type = synthesize(body) if body
|
1566
|
+
body_type = synthesize(body).type if body
|
1333
1567
|
synthesize(ensure_body) if ensure_body
|
1334
|
-
|
1568
|
+
add_typing(node, type: union_type(body_type))
|
1335
1569
|
end
|
1336
1570
|
|
1337
1571
|
when :masgn
|
1338
1572
|
type_masgn(node)
|
1339
1573
|
|
1340
|
-
when :while, :
|
1574
|
+
when :while, :until
|
1341
1575
|
yield_self do
|
1342
1576
|
cond, body = node.children
|
1577
|
+
_, constr = synthesize(cond)
|
1343
1578
|
|
1344
|
-
|
1345
|
-
|
1579
|
+
logic = TypeInference::Logic.new(subtyping: checker)
|
1580
|
+
truthy, falsey = logic.nodes(node: cond)
|
1581
|
+
|
1582
|
+
case node.type
|
1583
|
+
when :while
|
1584
|
+
body_env, exit_env = logic.environments(truthy_vars: truthy.vars, falsey_vars: falsey.vars, lvar_env: constr.context.lvar_env)
|
1585
|
+
when :until
|
1586
|
+
exit_env, body_env = logic.environments(truthy_vars: truthy.vars, falsey_vars: falsey.vars, lvar_env: constr.context.lvar_env)
|
1587
|
+
end
|
1346
1588
|
|
1347
1589
|
if body
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1590
|
+
_, body_constr = constr
|
1591
|
+
.update_lvar_env { body_env.pin_assignments }
|
1592
|
+
.for_branch(body,
|
1593
|
+
break_context: TypeInference::Context::BreakContext.new(
|
1594
|
+
break_type: nil,
|
1595
|
+
next_type: nil
|
1596
|
+
))
|
1597
|
+
.tap {|constr| typing.add_context_for_node(body, context: constr.context) }
|
1598
|
+
.synthesize(body)
|
1599
|
+
|
1600
|
+
constr = constr.update_lvar_env {|env| env.join(exit_env, body_constr.context.lvar_env) }
|
1601
|
+
else
|
1602
|
+
constr = constr.update_lvar_env { exit_env }
|
1356
1603
|
end
|
1357
1604
|
|
1358
|
-
|
1605
|
+
add_typing(node, type: AST::Builtin.nil_type, constr: constr)
|
1606
|
+
end
|
1607
|
+
|
1608
|
+
when :while_post, :until_post
|
1609
|
+
yield_self do
|
1610
|
+
cond, body = node.children
|
1611
|
+
|
1612
|
+
cond_pair = synthesize(cond)
|
1613
|
+
|
1614
|
+
if body
|
1615
|
+
for_loop = cond_pair.constr
|
1616
|
+
.update_lvar_env {|env| env.pin_assignments }
|
1617
|
+
.for_branch(body,
|
1618
|
+
break_context: TypeInference::Context::BreakContext.new(
|
1619
|
+
break_type: nil,
|
1620
|
+
next_type: nil
|
1621
|
+
))
|
1622
|
+
|
1623
|
+
typing.add_context_for_node(body, context: for_loop.context)
|
1624
|
+
body_pair = for_loop.synthesize(body)
|
1625
|
+
|
1626
|
+
constr = cond_pair.constr.update_lvar_env {|env| env.join(env, body_pair.context.lvar_env) }
|
1627
|
+
|
1628
|
+
add_typing(node, type: AST::Builtin.nil_type, constr: constr)
|
1629
|
+
else
|
1630
|
+
add_typing(node, type: AST::Builtin.nil_type, constr: cond_pair.constr)
|
1631
|
+
end
|
1359
1632
|
end
|
1360
1633
|
|
1361
1634
|
when :irange, :erange
|
1362
|
-
types = node.children.map {|n| synthesize(n)}
|
1635
|
+
types = node.children.map {|n| synthesize(n).type }
|
1363
1636
|
type = AST::Builtin::Range.instance_type(union_type(*types))
|
1364
|
-
|
1637
|
+
add_typing(node, type: type)
|
1365
1638
|
|
1366
1639
|
when :regexp
|
1367
1640
|
each_child_node(node) do |child|
|
1368
1641
|
synthesize(child)
|
1369
1642
|
end
|
1370
1643
|
|
1371
|
-
|
1644
|
+
add_typing(node, type: AST::Builtin::Regexp.instance_type)
|
1372
1645
|
|
1373
1646
|
when :regopt
|
1374
1647
|
# ignore
|
1375
|
-
|
1648
|
+
add_typing(node, type: AST::Builtin.any_type)
|
1376
1649
|
|
1377
1650
|
when :nth_ref, :back_ref
|
1378
|
-
|
1651
|
+
add_typing(node, type: AST::Builtin::String.instance_type)
|
1379
1652
|
|
1380
1653
|
when :or_asgn, :and_asgn
|
1381
1654
|
yield_self do
|
1382
1655
|
_, rhs = node.children
|
1383
|
-
rhs_type = synthesize(rhs)
|
1384
|
-
|
1656
|
+
rhs_type = synthesize(rhs).type
|
1657
|
+
add_typing(node, type: rhs_type)
|
1385
1658
|
end
|
1386
1659
|
|
1387
1660
|
when :defined?
|
@@ -1389,7 +1662,7 @@ module Steep
|
|
1389
1662
|
synthesize(child)
|
1390
1663
|
end
|
1391
1664
|
|
1392
|
-
|
1665
|
+
add_typing(node, type: AST::Builtin.any_type)
|
1393
1666
|
|
1394
1667
|
when :gvasgn
|
1395
1668
|
yield_self do
|
@@ -1415,7 +1688,7 @@ module Steep
|
|
1415
1688
|
typing.add_error Errors::FallbackAny.new(node: node)
|
1416
1689
|
end
|
1417
1690
|
|
1418
|
-
|
1691
|
+
add_typing(node, type: type)
|
1419
1692
|
end
|
1420
1693
|
|
1421
1694
|
when :block_pass
|
@@ -1443,9 +1716,9 @@ module Steep
|
|
1443
1716
|
end
|
1444
1717
|
end
|
1445
1718
|
|
1446
|
-
type ||= synthesize(node.children[0], hint: hint)
|
1719
|
+
type ||= synthesize(node.children[0], hint: hint).type
|
1447
1720
|
|
1448
|
-
|
1721
|
+
add_typing node, type: type
|
1449
1722
|
end
|
1450
1723
|
|
1451
1724
|
when :blockarg
|
@@ -1454,7 +1727,7 @@ module Steep
|
|
1454
1727
|
synthesize(child)
|
1455
1728
|
end
|
1456
1729
|
|
1457
|
-
|
1730
|
+
add_typing node, type: AST::Builtin.any_type
|
1458
1731
|
end
|
1459
1732
|
|
1460
1733
|
when :splat, :sclass, :alias
|
@@ -1465,55 +1738,35 @@ module Steep
|
|
1465
1738
|
synthesize(child)
|
1466
1739
|
end
|
1467
1740
|
|
1468
|
-
|
1741
|
+
add_typing node, type: AST::Builtin.any_type
|
1469
1742
|
end
|
1470
1743
|
|
1471
1744
|
else
|
1472
1745
|
raise "Unexpected node: #{node.inspect}, #{node.location.expression}"
|
1746
|
+
end.tap do |pair|
|
1747
|
+
unless pair.is_a?(Pair) && !pair.type.is_a?(Pair)
|
1748
|
+
# Steep.logger.error { "result = #{pair.inspect}" }
|
1749
|
+
# Steep.logger.error { "node = #{node.type}" }
|
1750
|
+
raise "#synthesize should return an instance of Pair: #{pair.class}"
|
1751
|
+
end
|
1473
1752
|
end
|
1474
1753
|
end
|
1475
1754
|
end
|
1476
1755
|
|
1477
1756
|
def check(node, type, constraints: Subtyping::Constraints.empty)
|
1478
|
-
|
1757
|
+
pair = synthesize(node, hint: type)
|
1479
1758
|
|
1480
|
-
result = check_relation(sub_type:
|
1759
|
+
result = check_relation(sub_type: pair.type, super_type: type, constraints: constraints)
|
1481
1760
|
if result.failure?
|
1482
|
-
yield(type,
|
1483
|
-
|
1484
|
-
end
|
1485
|
-
|
1486
|
-
def type_assignment(var, rhs, node, hint: nil)
|
1487
|
-
if rhs
|
1488
|
-
expand_alias(synthesize(rhs, hint: type_env.lvar_types[var.name] || hint)) do |rhs_type|
|
1489
|
-
node_type = assign_type_to_variable(var, rhs_type, node)
|
1490
|
-
typing.add_typing(node, node_type, context)
|
1491
|
-
end
|
1761
|
+
yield(type, pair.type, result)
|
1762
|
+
pair.with(type: type)
|
1492
1763
|
else
|
1493
|
-
|
1494
|
-
lhs_type = variable_type(var)
|
1495
|
-
|
1496
|
-
if lhs_type
|
1497
|
-
typing.add_typing(node, lhs_type, context)
|
1498
|
-
else
|
1499
|
-
fallback_to_any node
|
1500
|
-
end
|
1501
|
-
end
|
1502
|
-
end
|
1503
|
-
|
1504
|
-
def assign_type_to_variable(var, type, node)
|
1505
|
-
name = var.name
|
1506
|
-
type_env.assign(lvar: name, type: type, self_type: self_type) do |result|
|
1507
|
-
var_type = type_env.get(lvar: name)
|
1508
|
-
typing.add_error(Errors::IncompatibleAssignment.new(node: node,
|
1509
|
-
lhs_type: var_type,
|
1510
|
-
rhs_type: type,
|
1511
|
-
result: result))
|
1764
|
+
pair
|
1512
1765
|
end
|
1513
1766
|
end
|
1514
1767
|
|
1515
1768
|
def type_ivasgn(name, rhs, node)
|
1516
|
-
rhs_type = synthesize(rhs, hint: type_env.get(ivar: name) { fallback_to_any(node) })
|
1769
|
+
rhs_type = synthesize(rhs, hint: type_env.get(ivar: name) { fallback_to_any(node) }).type
|
1517
1770
|
ivar_type = type_env.assign(ivar: name, type: rhs_type, self_type: self_type) do |error|
|
1518
1771
|
case error
|
1519
1772
|
when Subtyping::Result::Failure
|
@@ -1526,102 +1779,111 @@ module Steep
|
|
1526
1779
|
fallback_to_any node
|
1527
1780
|
end
|
1528
1781
|
end
|
1529
|
-
|
1782
|
+
add_typing(node, type: ivar_type)
|
1530
1783
|
end
|
1531
1784
|
|
1532
1785
|
def type_masgn(node)
|
1533
1786
|
lhs, rhs = node.children
|
1534
|
-
|
1535
|
-
rhs_type = expand_alias(
|
1787
|
+
rhs_pair = synthesize(rhs)
|
1788
|
+
rhs_type = expand_alias(rhs_pair.type)
|
1536
1789
|
|
1537
|
-
|
1538
|
-
when rhs.type == :array && lhs.children.all? {|a| a.type == :lvasgn || a.type == :ivasgn} && lhs.children.size == rhs.children.size
|
1539
|
-
pairs = lhs.children.zip(rhs.children)
|
1540
|
-
pairs.each do |(l, r)|
|
1541
|
-
case
|
1542
|
-
when l.type == :lvasgn
|
1543
|
-
type_assignment(l.children.first, r, l)
|
1544
|
-
when l.type == :ivasgn
|
1545
|
-
type_ivasgn(l.children.first, r, l)
|
1546
|
-
end
|
1547
|
-
end
|
1790
|
+
constr = rhs_pair.constr
|
1548
1791
|
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1571
|
-
|
1572
|
-
|
1792
|
+
if lhs.children.all? {|a| a.type == :lvasgn || a.type == :ivasgn}
|
1793
|
+
case
|
1794
|
+
when rhs.type == :array && lhs.children.size == rhs.children.size
|
1795
|
+
# a, @b = x, y
|
1796
|
+
|
1797
|
+
constr = lhs.children.zip(rhs.children).inject(constr) do |ctr, (lhs, rhs)|
|
1798
|
+
case lhs.type
|
1799
|
+
when :lvasgn
|
1800
|
+
name = lhs.children[0].name
|
1801
|
+
type = typing.type_of(node: rhs)
|
1802
|
+
env = ctr.context.lvar_env.assign(name, node: node, type: type) do |declared_type, type, result|
|
1803
|
+
typing.add_error(
|
1804
|
+
Errors::IncompatibleAssignment.new(node: lhs,
|
1805
|
+
lhs_type: declared_type,
|
1806
|
+
rhs_type: type,
|
1807
|
+
result: result)
|
1808
|
+
)
|
1809
|
+
end
|
1810
|
+
add_typing(lhs,
|
1811
|
+
type: type,
|
1812
|
+
constr: ctr.with_updated_context(lvar_env: env))
|
1813
|
+
when :ivasgn
|
1814
|
+
type_ivasgn(lhs.children.first, rhs, lhs)
|
1815
|
+
constr
|
1573
1816
|
end
|
1574
1817
|
end
|
1575
|
-
end
|
1576
1818
|
|
1577
|
-
|
1819
|
+
add_typing(node, type: rhs_type, constr: constr)
|
1578
1820
|
|
1579
|
-
|
1580
|
-
|
1821
|
+
when rhs_type.is_a?(AST::Types::Tuple)
|
1822
|
+
# a, @b = tuple
|
1581
1823
|
|
1582
|
-
|
1583
|
-
|
1824
|
+
constr = lhs.children.zip(rhs_type.types).inject(constr) do |ctr, (lhs, type)|
|
1825
|
+
ty = type || AST::Builtin.nil_type
|
1584
1826
|
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1590
|
-
|
1591
|
-
|
1827
|
+
case lhs.type
|
1828
|
+
when :lvasgn
|
1829
|
+
name = lhs.children[0].name
|
1830
|
+
env = ctr.context.lvar_env.assign(name, node: node, type: ty) do |declared_type, type, result|
|
1831
|
+
typing.add_error(
|
1832
|
+
Errors::IncompatibleAssignment.new(node: lhs,
|
1833
|
+
lhs_type: declared_type,
|
1834
|
+
rhs_type: type,
|
1835
|
+
result: result)
|
1836
|
+
)
|
1837
|
+
end
|
1838
|
+
add_typing(lhs,
|
1839
|
+
type: ty,
|
1840
|
+
constr: ctr.with_updated_context(lvar_env: env)).constr
|
1841
|
+
when :ivasgn
|
1842
|
+
ivar = lhs.children[0]
|
1843
|
+
|
1844
|
+
type_env.assign(ivar: ivar, type: ty, self_type: self_type) do |error|
|
1592
1845
|
case error
|
1593
1846
|
when Subtyping::Result::Failure
|
1594
|
-
|
1595
|
-
typing.add_error(Errors::IncompatibleAssignment.new(node:
|
1596
|
-
lhs_type:
|
1597
|
-
rhs_type:
|
1847
|
+
ivar_type = type_env.get(ivar: ivar)
|
1848
|
+
typing.add_error(Errors::IncompatibleAssignment.new(node: lhs,
|
1849
|
+
lhs_type: ivar_type,
|
1850
|
+
rhs_type: ty,
|
1598
1851
|
result: error))
|
1599
1852
|
when nil
|
1600
1853
|
fallback_to_any node
|
1601
1854
|
end
|
1602
1855
|
end
|
1856
|
+
|
1857
|
+
ctr
|
1603
1858
|
end
|
1604
1859
|
end
|
1605
|
-
end
|
1606
1860
|
|
1607
|
-
|
1861
|
+
add_typing(node, type: rhs_type, constr: constr)
|
1608
1862
|
|
1609
|
-
|
1610
|
-
|
1863
|
+
when AST::Builtin::Array.instance_type?(rhs_type)
|
1864
|
+
element_type = AST::Types::Union.build(types: [rhs_type.args.first, AST::Builtin.nil_type])
|
1611
1865
|
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1866
|
+
constr = lhs.children.inject(constr) do |ctr, assignment|
|
1867
|
+
case assignment.type
|
1868
|
+
when :lvasgn
|
1869
|
+
name = assignment.children[0].name
|
1870
|
+
env = ctr.context.lvar_env.assign(name, node: node, type: element_type) do |declared_type, type, result|
|
1871
|
+
typing.add_error(
|
1872
|
+
Errors::IncompatibleAssignment.new(node: assignment,
|
1873
|
+
lhs_type: declared_type,
|
1874
|
+
rhs_type: type,
|
1875
|
+
result: result)
|
1876
|
+
)
|
1877
|
+
end
|
1878
|
+
|
1879
|
+
add_typing(assignment,
|
1880
|
+
type: element_type,
|
1881
|
+
constr: ctr.with_updated_context(lvar_env: env)).constr
|
1615
1882
|
|
1616
|
-
|
1883
|
+
when :ivasgn
|
1884
|
+
ivar = assignment.children[0]
|
1617
1885
|
|
1618
|
-
|
1619
|
-
case assignment.type
|
1620
|
-
when :lvasgn
|
1621
|
-
assign_type_to_variable(assignment.children.first, element_type, assignment)
|
1622
|
-
when :ivasgn
|
1623
|
-
assignment.children.first.yield_self do |ivar|
|
1624
|
-
type_env.assign(ivar: ivar, type: element_type) do |error|
|
1886
|
+
type_env.assign(ivar: ivar, type: element_type, self_type: self_type) do |error|
|
1625
1887
|
case error
|
1626
1888
|
when Subtyping::Result::Failure
|
1627
1889
|
type = type_env.get(ivar: ivar)
|
@@ -1633,14 +1895,22 @@ module Steep
|
|
1633
1895
|
fallback_to_any node
|
1634
1896
|
end
|
1635
1897
|
end
|
1898
|
+
|
1899
|
+
ctr
|
1636
1900
|
end
|
1637
1901
|
end
|
1638
|
-
end
|
1639
1902
|
|
1640
|
-
|
1903
|
+
add_typing node, type: rhs_type, constr: constr
|
1904
|
+
|
1905
|
+
when rhs_type.is_a?(AST::Types::Any)
|
1906
|
+
fallback_to_any(node)
|
1641
1907
|
|
1908
|
+
else
|
1909
|
+
Steep.logger.error("Unsupported masgn: #{rhs.type} (#{rhs_type})")
|
1910
|
+
fallback_to_any(node)
|
1911
|
+
end
|
1642
1912
|
else
|
1643
|
-
Steep.logger.error("Unsupported masgn
|
1913
|
+
Steep.logger.error("Unsupported masgn left hand side")
|
1644
1914
|
fallback_to_any(node)
|
1645
1915
|
end
|
1646
1916
|
end
|
@@ -1655,7 +1925,8 @@ module Steep
|
|
1655
1925
|
return_hint = type_hint.return_type
|
1656
1926
|
end
|
1657
1927
|
|
1658
|
-
|
1928
|
+
block_pair = type_block(node: node,
|
1929
|
+
block_param_hint: params_hint,
|
1659
1930
|
block_type_hint: return_hint,
|
1660
1931
|
node_type_hint: nil,
|
1661
1932
|
block_params: params,
|
@@ -1663,12 +1934,12 @@ module Steep
|
|
1663
1934
|
block_annotations: block_annotations,
|
1664
1935
|
topdown_hint: true)
|
1665
1936
|
|
1666
|
-
|
1937
|
+
add_typing node, type: block_pair.type
|
1667
1938
|
end
|
1668
1939
|
|
1669
1940
|
def type_send(node, send_node:, block_params:, block_body:, unwrap: false)
|
1670
1941
|
receiver, method_name, *arguments = send_node.children
|
1671
|
-
receiver_type = receiver ? synthesize(receiver) : AST::Types::Self.new
|
1942
|
+
receiver_type = receiver ? synthesize(receiver).type : AST::Types::Self.new
|
1672
1943
|
|
1673
1944
|
if unwrap
|
1674
1945
|
receiver_type = unwrap(receiver_type)
|
@@ -1676,70 +1947,70 @@ module Steep
|
|
1676
1947
|
|
1677
1948
|
receiver_type = expand_alias(receiver_type)
|
1678
1949
|
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1950
|
+
pair = case receiver_type
|
1951
|
+
when AST::Types::Any
|
1952
|
+
add_typing node, type: AST::Builtin.any_type
|
1953
|
+
|
1954
|
+
when nil
|
1955
|
+
fallback_to_any node
|
1956
|
+
|
1957
|
+
when AST::Types::Void, AST::Types::Bot, AST::Types::Top
|
1958
|
+
fallback_to_any node do
|
1959
|
+
Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
1960
|
+
end
|
1961
|
+
|
1962
|
+
else
|
1963
|
+
case expanded_receiver_type = expand_self(receiver_type)
|
1964
|
+
when AST::Types::Self
|
1965
|
+
Steep.logger.error "`self` type cannot be resolved to concrete type"
|
1966
|
+
fallback_to_any node do
|
1967
|
+
Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
1968
|
+
end
|
1969
|
+
else
|
1970
|
+
begin
|
1971
|
+
interface = checker.factory.interface(receiver_type,
|
1972
|
+
private: !receiver,
|
1973
|
+
self_type: expanded_receiver_type)
|
1974
|
+
|
1975
|
+
method = interface.methods[method_name]
|
1976
|
+
|
1977
|
+
if method
|
1978
|
+
args = TypeInference::SendArgs.from_nodes(arguments)
|
1979
|
+
return_type, constr, _ = type_method_call(node,
|
1980
|
+
method: method,
|
1981
|
+
method_name: method_name,
|
1982
|
+
args: args,
|
1983
|
+
block_params: block_params,
|
1984
|
+
block_body: block_body,
|
1985
|
+
receiver_type: receiver_type,
|
1986
|
+
topdown_hint: true)
|
1987
|
+
|
1988
|
+
add_typing node, type: return_type, constr: constr
|
1989
|
+
else
|
1990
|
+
fallback_to_any node do
|
1991
|
+
Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
|
1992
|
+
end
|
1993
|
+
end
|
1994
|
+
rescue => exn
|
1995
|
+
$stderr.puts exn.inspect
|
1996
|
+
exn.backtrace.each do |t|
|
1997
|
+
$stderr.puts t
|
1998
|
+
end
|
1728
1999
|
|
1729
|
-
|
1730
|
-
|
1731
|
-
|
1732
|
-
|
1733
|
-
|
1734
|
-
|
2000
|
+
fallback_to_any node do
|
2001
|
+
Errors::NoMethod.new(node: node, method: method_name, type: expanded_receiver_type)
|
2002
|
+
end
|
2003
|
+
end
|
2004
|
+
end
|
2005
|
+
end
|
1735
2006
|
|
1736
|
-
case
|
2007
|
+
case pair.type
|
1737
2008
|
when nil, Errors::Base
|
1738
2009
|
arguments.each do |arg|
|
1739
2010
|
unless typing.has_type?(arg)
|
1740
2011
|
if arg.type == :splat
|
1741
|
-
type = synthesize(arg.children[0])
|
1742
|
-
|
2012
|
+
type = synthesize(arg.children[0]).type
|
2013
|
+
add_typing(arg, type: AST::Builtin::Array.instance_type(type))
|
1743
2014
|
else
|
1744
2015
|
synthesize(arg)
|
1745
2016
|
end
|
@@ -1752,16 +2023,18 @@ module Steep
|
|
1752
2023
|
params = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
|
1753
2024
|
pairs = params.each.map {|param| [param, AST::Builtin.any_type]}
|
1754
2025
|
|
1755
|
-
for_block, _ = for_block(block_annotations: block_annotations,
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
2026
|
+
for_block, _ = constr.for_block(block_annotations: block_annotations,
|
2027
|
+
param_pairs: pairs,
|
2028
|
+
method_return_type: AST::Builtin.any_type,
|
2029
|
+
typing: typing)
|
2030
|
+
|
2031
|
+
for_block.typing.add_context_for_body(node, context: for_block.context)
|
1759
2032
|
|
1760
2033
|
for_block.synthesize(block_body)
|
1761
2034
|
end
|
1762
2035
|
end
|
1763
2036
|
else
|
1764
|
-
|
2037
|
+
pair
|
1765
2038
|
end
|
1766
2039
|
end
|
1767
2040
|
|
@@ -1782,6 +2055,8 @@ module Steep
|
|
1782
2055
|
)
|
1783
2056
|
end
|
1784
2057
|
|
2058
|
+
lvar_env = context.lvar_env.pin_assignments.annotate(block_annotations)
|
2059
|
+
|
1785
2060
|
return_type = if block_annotations.break_type
|
1786
2061
|
union_type(method_return_type, block_annotations.break_type)
|
1787
2062
|
else
|
@@ -1809,7 +2084,8 @@ module Steep
|
|
1809
2084
|
module_context: module_context,
|
1810
2085
|
break_context: break_context,
|
1811
2086
|
self_type: block_annotations.self_type || self_type,
|
1812
|
-
type_env: block_type_env
|
2087
|
+
type_env: block_type_env,
|
2088
|
+
lvar_env: lvar_env
|
1813
2089
|
)
|
1814
2090
|
), return_type]
|
1815
2091
|
end
|
@@ -1823,70 +2099,72 @@ module Steep
|
|
1823
2099
|
end
|
1824
2100
|
|
1825
2101
|
def type_method_call(node, method_name:, receiver_type:, method:, args:, block_params:, block_body:, topdown_hint:)
|
2102
|
+
node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
|
2103
|
+
|
1826
2104
|
case
|
1827
2105
|
when method.union?
|
1828
2106
|
yield_self do
|
1829
2107
|
results = method.types.map do |method|
|
1830
|
-
typing.new_child do |child_typing|
|
1831
|
-
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1841
|
-
|
1842
|
-
|
1843
|
-
|
1844
|
-
|
1845
|
-
|
1846
|
-
|
1847
|
-
if (type, typing, error = results.find {|_, _, error| error })
|
1848
|
-
typing.save!
|
1849
|
-
[type, error]
|
2108
|
+
typing.new_child(node_range) do |child_typing|
|
2109
|
+
with_new_typing(child_typing).type_method_call(node,
|
2110
|
+
method_name: method_name,
|
2111
|
+
receiver_type: receiver_type,
|
2112
|
+
method: method,
|
2113
|
+
args: args,
|
2114
|
+
block_params: block_params,
|
2115
|
+
block_body: block_body,
|
2116
|
+
topdown_hint: false)
|
2117
|
+
end
|
2118
|
+
end
|
2119
|
+
|
2120
|
+
if (type, constr, error = results.find {|_, _, error| error })
|
2121
|
+
constr.typing.save!
|
2122
|
+
[type,
|
2123
|
+
update_lvar_env { constr.context.lvar_env },
|
2124
|
+
error]
|
1850
2125
|
else
|
1851
|
-
|
1852
|
-
|
2126
|
+
types = results.map(&:first)
|
2127
|
+
|
2128
|
+
_, constr, _ = results.first
|
2129
|
+
constr.typing.save!
|
1853
2130
|
|
1854
|
-
[union_type(*
|
2131
|
+
[union_type(*types),
|
2132
|
+
update_lvar_env { constr.context.lvar_env },
|
2133
|
+
nil]
|
1855
2134
|
end
|
1856
2135
|
end
|
1857
2136
|
|
1858
2137
|
when method.intersection?
|
1859
2138
|
yield_self do
|
1860
2139
|
results = method.types.map do |method|
|
1861
|
-
typing.new_child do |child_typing|
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
|
1866
|
-
|
1867
|
-
|
1868
|
-
|
1869
|
-
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
1873
|
-
|
1874
|
-
]
|
1875
|
-
end
|
1876
|
-
end
|
1877
|
-
|
1878
|
-
successes = results.select {|_, _, error| !error }
|
2140
|
+
typing.new_child(node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }) do |child_typing|
|
2141
|
+
with_new_typing(child_typing).type_method_call(node,
|
2142
|
+
method_name: method_name,
|
2143
|
+
receiver_type: receiver_type,
|
2144
|
+
method: method,
|
2145
|
+
args: args,
|
2146
|
+
block_params: block_params,
|
2147
|
+
block_body: block_body,
|
2148
|
+
topdown_hint: false)
|
2149
|
+
end
|
2150
|
+
end
|
2151
|
+
|
2152
|
+
successes = results.reject {|_, _, error| error }
|
1879
2153
|
unless successes.empty?
|
1880
|
-
types = successes.map
|
1881
|
-
|
1882
|
-
typing.save!
|
2154
|
+
types = successes.map(&:first)
|
2155
|
+
constr = successes[0][1]
|
2156
|
+
constr.typing.save!
|
1883
2157
|
|
1884
|
-
[AST::Types::Intersection.build(types: types),
|
2158
|
+
[AST::Types::Intersection.build(types: types),
|
2159
|
+
update_lvar_env { constr.context.lvar_env },
|
2160
|
+
nil]
|
1885
2161
|
else
|
1886
|
-
type,
|
1887
|
-
typing.save!
|
2162
|
+
type, constr, error = results.first
|
2163
|
+
constr.typing.save!
|
1888
2164
|
|
1889
|
-
[type,
|
2165
|
+
[type,
|
2166
|
+
update_lvar_env { constr.context.lvar_env },
|
2167
|
+
error]
|
1890
2168
|
end
|
1891
2169
|
end
|
1892
2170
|
|
@@ -1894,55 +2172,40 @@ module Steep
|
|
1894
2172
|
yield_self do
|
1895
2173
|
results = method.types.flat_map do |method_type|
|
1896
2174
|
Steep.logger.tagged method_type.to_s do
|
1897
|
-
|
1898
|
-
|
1899
|
-
|
1900
|
-
|
1901
|
-
|
1902
|
-
|
1903
|
-
|
1904
|
-
|
1905
|
-
|
1906
|
-
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
1912
|
-
topdown_hint: topdown_hint
|
1913
|
-
)
|
1914
|
-
|
1915
|
-
[result, child_typing, method_type]
|
1916
|
-
end
|
1917
|
-
end
|
1918
|
-
when :any
|
1919
|
-
typing.new_child do |child_typing|
|
1920
|
-
this = self.with_new_typing(child_typing)
|
1921
|
-
|
1922
|
-
args.args.each do |arg|
|
1923
|
-
this.synthesize(arg)
|
1924
|
-
end
|
2175
|
+
zips = args.zips(method_type.params, method_type.block&.type)
|
2176
|
+
|
2177
|
+
zips.map do |arg_pairs|
|
2178
|
+
typing.new_child(node_range) do |child_typing|
|
2179
|
+
ret = self.with_new_typing(child_typing).try_method_type(
|
2180
|
+
node,
|
2181
|
+
receiver_type: receiver_type,
|
2182
|
+
method_type: method_type,
|
2183
|
+
args: args,
|
2184
|
+
arg_pairs: arg_pairs,
|
2185
|
+
block_params: block_params,
|
2186
|
+
block_body: block_body,
|
2187
|
+
child_typing: child_typing,
|
2188
|
+
topdown_hint: topdown_hint
|
2189
|
+
)
|
1925
2190
|
|
1926
|
-
|
1927
|
-
this.synthesize(block_body)
|
1928
|
-
end
|
2191
|
+
raise unless ret.is_a?(Array) && ret[1].is_a?(TypeConstruction)
|
1929
2192
|
|
1930
|
-
|
2193
|
+
result, constr = ret
|
1931
2194
|
|
1932
|
-
[
|
2195
|
+
[result, constr, method_type]
|
1933
2196
|
end
|
1934
2197
|
end
|
1935
2198
|
end
|
1936
2199
|
end
|
1937
2200
|
|
1938
2201
|
unless results.empty?
|
1939
|
-
result,
|
2202
|
+
result, constr, method_type = results.find {|result, _, _| !result.is_a?(Errors::Base) } || results.last
|
1940
2203
|
else
|
1941
2204
|
method_type = method.types.last
|
2205
|
+
constr = self.with_new_typing(typing.new_child(node_range))
|
1942
2206
|
result = Errors::IncompatibleArguments.new(node: node, receiver_type: receiver_type, method_type: method_type)
|
1943
|
-
call_typing = typing.new_child
|
1944
2207
|
end
|
1945
|
-
|
2208
|
+
constr.typing.save!
|
1946
2209
|
|
1947
2210
|
case result
|
1948
2211
|
when Errors::Base
|
@@ -1962,9 +2225,13 @@ module Steep
|
|
1962
2225
|
type = AST::Builtin.any_type
|
1963
2226
|
end
|
1964
2227
|
|
1965
|
-
[type,
|
2228
|
+
[type,
|
2229
|
+
update_lvar_env { constr.context.lvar_env },
|
2230
|
+
result]
|
1966
2231
|
else # Type
|
1967
|
-
[result,
|
2232
|
+
[result,
|
2233
|
+
update_lvar_env { constr.context.lvar_env },
|
2234
|
+
nil]
|
1968
2235
|
end
|
1969
2236
|
end
|
1970
2237
|
end
|
@@ -1977,7 +2244,7 @@ module Steep
|
|
1977
2244
|
when :hash
|
1978
2245
|
keyword_hash_type = AST::Builtin::Hash.instance_type(AST::Builtin::Symbol.instance_type,
|
1979
2246
|
AST::Builtin.any_type)
|
1980
|
-
|
2247
|
+
add_typing node, type: keyword_hash_type
|
1981
2248
|
|
1982
2249
|
given_keys = Set.new()
|
1983
2250
|
|
@@ -2001,7 +2268,7 @@ module Steep
|
|
2001
2268
|
params.rest_keywords
|
2002
2269
|
end
|
2003
2270
|
|
2004
|
-
|
2271
|
+
add_typing key_node, type: AST::Builtin::Symbol.instance_type
|
2005
2272
|
|
2006
2273
|
given_keys << key_symbol
|
2007
2274
|
|
@@ -2083,7 +2350,7 @@ module Steep
|
|
2083
2350
|
hash_type = AST::Types::Record.new(elements: hash_elements)
|
2084
2351
|
end
|
2085
2352
|
|
2086
|
-
node_type = synthesize(node, hint: hash_type)
|
2353
|
+
node_type = synthesize(node, hint: hash_type).type
|
2087
2354
|
|
2088
2355
|
check_relation(sub_type: node_type, super_type: hash_type).else do
|
2089
2356
|
return Errors::ArgumentTypeMismatch.new(
|
@@ -2111,6 +2378,8 @@ module Steep
|
|
2111
2378
|
context: context
|
2112
2379
|
)
|
2113
2380
|
|
2381
|
+
constr = construction
|
2382
|
+
|
2114
2383
|
method_type.instantiate(instantiation).yield_self do |method_type|
|
2115
2384
|
constraints = Subtyping::Constraints.new(unknowns: fresh_types.map(&:name))
|
2116
2385
|
variance = Subtyping::VariableVariance.from_method_type(method_type)
|
@@ -2120,23 +2389,20 @@ module Steep
|
|
2120
2389
|
case pair
|
2121
2390
|
when Array
|
2122
2391
|
(arg_node, param_type) = pair
|
2123
|
-
|
2124
2392
|
param_type = param_type.subst(instantiation)
|
2125
2393
|
|
2126
|
-
arg_type = if arg_node.type == :splat
|
2127
|
-
|
2128
|
-
|
2129
|
-
|
2130
|
-
|
2131
|
-
end
|
2394
|
+
arg_type, constr = if arg_node.type == :splat
|
2395
|
+
constr.synthesize(arg_node.children[0])
|
2396
|
+
else
|
2397
|
+
constr.synthesize(arg_node, hint: topdown_hint ? param_type : nil)
|
2398
|
+
end
|
2132
2399
|
|
2133
2400
|
check_relation(sub_type: arg_type, super_type: param_type, constraints: constraints).else do |result|
|
2134
|
-
return Errors::ArgumentTypeMismatch.new(
|
2135
|
-
|
2136
|
-
|
2137
|
-
|
2138
|
-
|
2139
|
-
)
|
2401
|
+
return [Errors::ArgumentTypeMismatch.new(node: arg_node,
|
2402
|
+
receiver_type: receiver_type,
|
2403
|
+
expected: param_type,
|
2404
|
+
actual: arg_type),
|
2405
|
+
constr]
|
2140
2406
|
end
|
2141
2407
|
else
|
2142
2408
|
# keyword
|
@@ -2146,7 +2412,7 @@ module Steep
|
|
2146
2412
|
constraints: constraints)
|
2147
2413
|
|
2148
2414
|
if result.is_a?(Errors::Base)
|
2149
|
-
return result
|
2415
|
+
return [result, constr]
|
2150
2416
|
end
|
2151
2417
|
end
|
2152
2418
|
end
|
@@ -2161,10 +2427,9 @@ module Steep
|
|
2161
2427
|
check_relation(sub_type: AST::Types::Proc.new(params: block_param_hint, return_type: AST::Types::Any.new),
|
2162
2428
|
super_type: method_type.block.type,
|
2163
2429
|
constraints: constraints).else do |result|
|
2164
|
-
return Errors::IncompatibleBlockParameters.new(
|
2165
|
-
|
2166
|
-
|
2167
|
-
)
|
2430
|
+
return [Errors::IncompatibleBlockParameters.new(node: node,
|
2431
|
+
method_type: method_type),
|
2432
|
+
constr]
|
2168
2433
|
end
|
2169
2434
|
end
|
2170
2435
|
|
@@ -2175,50 +2440,53 @@ module Steep
|
|
2175
2440
|
|
2176
2441
|
begin
|
2177
2442
|
method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: occurence.params)).yield_self do |method_type|
|
2178
|
-
|
2179
|
-
|
2180
|
-
|
2181
|
-
|
2182
|
-
|
2183
|
-
|
2184
|
-
|
2185
|
-
|
2186
|
-
|
2443
|
+
type, _ = constr.type_block(node: node,
|
2444
|
+
block_param_hint: method_type.block.type.params,
|
2445
|
+
block_type_hint: method_type.block.type.return_type,
|
2446
|
+
node_type_hint: method_type.return_type,
|
2447
|
+
block_params: block_params_,
|
2448
|
+
block_body: block_body,
|
2449
|
+
block_annotations: block_annotations,
|
2450
|
+
topdown_hint: topdown_hint)
|
2451
|
+
|
2452
|
+
result = check_relation(sub_type: type.return_type,
|
2187
2453
|
super_type: method_type.block.type.return_type,
|
2188
2454
|
constraints: constraints)
|
2189
2455
|
|
2190
2456
|
case result
|
2191
2457
|
when Subtyping::Result::Success
|
2192
2458
|
method_type.return_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: fresh_vars)).yield_self do |ret_type|
|
2193
|
-
if block_annotations.break_type
|
2194
|
-
|
2195
|
-
|
2196
|
-
|
2197
|
-
|
2459
|
+
ty = if block_annotations.break_type
|
2460
|
+
AST::Types::Union.new(types: [block_annotations.break_type, ret_type])
|
2461
|
+
else
|
2462
|
+
ret_type
|
2463
|
+
end
|
2464
|
+
[ty, constr]
|
2198
2465
|
end
|
2199
2466
|
|
2200
2467
|
when Subtyping::Result::Failure
|
2201
|
-
Errors::BlockTypeMismatch.new(node: node,
|
2202
|
-
|
2203
|
-
|
2204
|
-
|
2468
|
+
[Errors::BlockTypeMismatch.new(node: node,
|
2469
|
+
expected: method_type.block.type,
|
2470
|
+
actual: type,
|
2471
|
+
result: result),
|
2472
|
+
constr]
|
2205
2473
|
end
|
2206
2474
|
end
|
2207
2475
|
|
2208
2476
|
rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
|
2209
|
-
Errors::UnsatisfiableConstraint.new(node: node,
|
2210
|
-
|
2211
|
-
|
2212
|
-
|
2213
|
-
|
2214
|
-
|
2477
|
+
[Errors::UnsatisfiableConstraint.new(node: node,
|
2478
|
+
method_type: method_type,
|
2479
|
+
var: exn.var,
|
2480
|
+
sub_type: exn.sub_type,
|
2481
|
+
super_type: exn.super_type,
|
2482
|
+
result: exn.result),
|
2483
|
+
constr]
|
2215
2484
|
end
|
2216
2485
|
|
2217
2486
|
when method_type.block && args.block_pass_arg
|
2218
2487
|
begin
|
2219
2488
|
method_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: occurence.params)).yield_self do |method_type|
|
2220
|
-
block_type = synthesize(args.block_pass_arg,
|
2221
|
-
hint: topdown_hint ? method_type.block.type : nil)
|
2489
|
+
block_type, constr = constr.synthesize(args.block_pass_arg, hint: topdown_hint ? method_type.block.type : nil)
|
2222
2490
|
result = check_relation(
|
2223
2491
|
sub_type: block_type,
|
2224
2492
|
super_type: method_type.block.yield_self {|expected_block|
|
@@ -2233,40 +2501,58 @@ module Steep
|
|
2233
2501
|
|
2234
2502
|
case result
|
2235
2503
|
when Subtyping::Result::Success
|
2236
|
-
|
2504
|
+
[
|
2505
|
+
method_type.return_type.subst(constraints.solution(checker, self_type: self_type, variance: variance, variables: fresh_vars)),
|
2506
|
+
constr
|
2507
|
+
]
|
2237
2508
|
|
2238
2509
|
when Subtyping::Result::Failure
|
2239
|
-
|
2240
|
-
|
2241
|
-
|
2242
|
-
|
2510
|
+
[
|
2511
|
+
Errors::BlockTypeMismatch.new(node: node,
|
2512
|
+
expected: method_type.block.type,
|
2513
|
+
actual: block_type,
|
2514
|
+
result: result),
|
2515
|
+
constr
|
2516
|
+
]
|
2243
2517
|
end
|
2244
2518
|
end
|
2245
2519
|
|
2246
2520
|
rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
|
2247
|
-
|
2248
|
-
|
2249
|
-
|
2250
|
-
|
2251
|
-
|
2252
|
-
|
2521
|
+
[
|
2522
|
+
Errors::UnsatisfiableConstraint.new(node: node,
|
2523
|
+
method_type: method_type,
|
2524
|
+
var: exn.var,
|
2525
|
+
sub_type: exn.sub_type,
|
2526
|
+
super_type: exn.super_type,
|
2527
|
+
result: exn.result),
|
2528
|
+
constr
|
2529
|
+
]
|
2253
2530
|
end
|
2254
2531
|
|
2255
2532
|
when (!method_type.block || method_type.block.optional?) && !block_params && !block_body && !args.block_pass_arg
|
2256
2533
|
# OK, without block
|
2257
|
-
|
2534
|
+
[
|
2535
|
+
method_type.subst(constraints.solution(checker, variance: variance, variables: fresh_vars, self_type: self_type)).return_type,
|
2536
|
+
constr
|
2537
|
+
]
|
2258
2538
|
|
2259
2539
|
when !method_type.block && (block_params || args.block_pass_arg)
|
2260
|
-
|
2261
|
-
|
2262
|
-
|
2263
|
-
|
2540
|
+
[
|
2541
|
+
Errors::UnexpectedBlockGiven.new(
|
2542
|
+
node: node,
|
2543
|
+
method_type: method_type
|
2544
|
+
),
|
2545
|
+
constr
|
2546
|
+
]
|
2264
2547
|
|
2265
2548
|
when method_type.block && !method_type.block.optional? && !block_params && !block_body && !args.block_pass_arg
|
2266
|
-
|
2267
|
-
|
2268
|
-
|
2269
|
-
|
2549
|
+
[
|
2550
|
+
Errors::RequiredBlockMissing.new(
|
2551
|
+
node: node,
|
2552
|
+
method_type: method_type
|
2553
|
+
),
|
2554
|
+
constr
|
2555
|
+
]
|
2270
2556
|
|
2271
2557
|
else
|
2272
2558
|
raise "Unexpected case condition"
|
@@ -2274,7 +2560,7 @@ module Steep
|
|
2274
2560
|
end
|
2275
2561
|
end
|
2276
2562
|
|
2277
|
-
def type_block(block_param_hint:, block_type_hint:, node_type_hint:, block_params:, block_body:, block_annotations:, topdown_hint:)
|
2563
|
+
def type_block(node:, block_param_hint:, block_type_hint:, node_type_hint:, block_params:, block_body:, block_annotations:, topdown_hint:)
|
2278
2564
|
block_param_pairs = block_param_hint && block_params.zip(block_param_hint)
|
2279
2565
|
|
2280
2566
|
param_types_hash = {}
|
@@ -2290,15 +2576,12 @@ module Steep
|
|
2290
2576
|
end
|
2291
2577
|
end
|
2292
2578
|
|
2293
|
-
|
2294
|
-
param_types_hash.each do |name, type|
|
2295
|
-
|
2296
|
-
end
|
2297
|
-
|
2298
|
-
block_annotations.lvar_types.each do |name, type|
|
2299
|
-
env.set(lvar: name, type: type)
|
2579
|
+
lvar_env = context.lvar_env.pin_assignments.yield_self do |env|
|
2580
|
+
decls = param_types_hash.each.with_object({}) do |(name, type), hash|
|
2581
|
+
hash[name] = TypeInference::LocalVariableTypeEnv::Entry.new(type: type)
|
2300
2582
|
end
|
2301
|
-
|
2583
|
+
env.update(declared_types: env.declared_types.merge(decls))
|
2584
|
+
end.annotate(block_annotations)
|
2302
2585
|
|
2303
2586
|
break_type = if block_annotations.break_type
|
2304
2587
|
union_type(node_type_hint, block_annotations.break_type)
|
@@ -2327,33 +2610,38 @@ module Steep
|
|
2327
2610
|
module_context: module_context,
|
2328
2611
|
break_context: break_context,
|
2329
2612
|
self_type: block_annotations.self_type || self_type,
|
2330
|
-
type_env:
|
2613
|
+
type_env: type_env.dup,
|
2614
|
+
lvar_env: lvar_env
|
2331
2615
|
)
|
2332
2616
|
)
|
2333
2617
|
|
2618
|
+
for_block_body.typing.add_context_for_body(node, context: for_block_body.context)
|
2619
|
+
|
2334
2620
|
if block_body
|
2335
|
-
|
2336
|
-
|
2337
|
-
|
2338
|
-
|
2339
|
-
|
2340
|
-
|
2621
|
+
body_pair = if (body_type = block_context.body_type)
|
2622
|
+
for_block_body.check(block_body, body_type) do |expected, actual, result|
|
2623
|
+
typing.add_error Errors::BlockTypeMismatch.new(node: block_body,
|
2624
|
+
expected: expected,
|
2625
|
+
actual: actual,
|
2626
|
+
result: result)
|
2341
2627
|
|
2342
|
-
end
|
2343
|
-
body_type
|
2344
|
-
else
|
2345
|
-
for_block_body.synthesize(block_body, hint: topdown_hint ? block_type_hint : nil)
|
2346
2628
|
end
|
2629
|
+
else
|
2630
|
+
for_block_body.synthesize(block_body, hint: topdown_hint ? block_type_hint : nil)
|
2631
|
+
end
|
2632
|
+
|
2633
|
+
range = block_body.loc.expression.end_pos..node.loc.end.begin_pos
|
2634
|
+
typing.add_context(range, context: body_pair.context)
|
2347
2635
|
else
|
2348
|
-
|
2636
|
+
body_pair = Pair.new(type: AST::Builtin.nil_type, constr: for_block_body)
|
2349
2637
|
end
|
2350
2638
|
|
2351
|
-
|
2352
|
-
|
2353
|
-
|
2354
|
-
|
2355
|
-
|
2356
|
-
|
2639
|
+
body_pair.with(
|
2640
|
+
type: AST::Types::Proc.new(
|
2641
|
+
params: block_param_hint || block_params.params_type,
|
2642
|
+
return_type: body_pair.type
|
2643
|
+
)
|
2644
|
+
)
|
2357
2645
|
end
|
2358
2646
|
|
2359
2647
|
def each_child_node(node)
|
@@ -2435,10 +2723,10 @@ module Steep
|
|
2435
2723
|
end
|
2436
2724
|
|
2437
2725
|
def nested_namespace_for_module(module_name)
|
2438
|
-
if module_name.relative?
|
2439
|
-
current_namespace.append(module_name.name)
|
2726
|
+
if module_name.relative?
|
2727
|
+
(current_namespace + module_name.namespace).append(module_name.name)
|
2440
2728
|
else
|
2441
|
-
|
2729
|
+
module_name
|
2442
2730
|
end
|
2443
2731
|
end
|
2444
2732
|
|
@@ -2457,6 +2745,7 @@ module Steep
|
|
2457
2745
|
end
|
2458
2746
|
|
2459
2747
|
def union_type(*types)
|
2748
|
+
raise if types.empty?
|
2460
2749
|
AST::Types::Union.build(types: types)
|
2461
2750
|
end
|
2462
2751
|
|
@@ -2545,7 +2834,7 @@ module Steep
|
|
2545
2834
|
typing.add_error Errors::FallbackAny.new(node: node)
|
2546
2835
|
end
|
2547
2836
|
|
2548
|
-
|
2837
|
+
add_typing node, type: AST::Builtin.any_type
|
2549
2838
|
end
|
2550
2839
|
|
2551
2840
|
def self_class?(node)
|
@@ -2591,21 +2880,6 @@ module Steep
|
|
2591
2880
|
end
|
2592
2881
|
end
|
2593
2882
|
|
2594
|
-
def self.truthy_variables(node)
|
2595
|
-
case node&.type
|
2596
|
-
when :lvar
|
2597
|
-
Set.new([node.children.first.name])
|
2598
|
-
when :lvasgn
|
2599
|
-
Set.new([node.children.first.name]) + truthy_variables(node.children[1])
|
2600
|
-
when :and
|
2601
|
-
truthy_variables(node.children[0]) + truthy_variables(node.children[1])
|
2602
|
-
when :begin
|
2603
|
-
truthy_variables(node.children.last)
|
2604
|
-
else
|
2605
|
-
Set.new()
|
2606
|
-
end
|
2607
|
-
end
|
2608
|
-
|
2609
2883
|
def self.value_variables(node)
|
2610
2884
|
case node&.type
|
2611
2885
|
when :lvar
|
@@ -2685,7 +2959,7 @@ module Steep
|
|
2685
2959
|
def try_hash_type(node, hint)
|
2686
2960
|
case hint
|
2687
2961
|
when AST::Types::Record
|
2688
|
-
typing.new_child do |child_typing|
|
2962
|
+
typing.new_child(node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }) do |child_typing|
|
2689
2963
|
new_construction = with_new_typing(child_typing)
|
2690
2964
|
elements = {}
|
2691
2965
|
|
@@ -2702,7 +2976,7 @@ module Steep
|
|
2702
2976
|
end
|
2703
2977
|
|
2704
2978
|
value_hint = hint.elements[key_value]
|
2705
|
-
value_type = new_construction.synthesize(value, hint: value_hint)
|
2979
|
+
value_type = new_construction.synthesize(value, hint: value_hint).type
|
2706
2980
|
|
2707
2981
|
if value_hint
|
2708
2982
|
if check_relation(sub_type: value_type, super_type: value_hint).success?
|
@@ -2719,12 +2993,15 @@ module Steep
|
|
2719
2993
|
child_typing.save!
|
2720
2994
|
|
2721
2995
|
hash = AST::Types::Record.new(elements: elements)
|
2722
|
-
|
2996
|
+
add_typing(node, type: hash)
|
2723
2997
|
end
|
2724
2998
|
when AST::Types::Union
|
2725
|
-
hint.types.
|
2726
|
-
try_hash_type(node, type)
|
2999
|
+
hint.types.each do |type|
|
3000
|
+
if pair = try_hash_type(node, type)
|
3001
|
+
return pair
|
3002
|
+
end
|
2727
3003
|
end
|
3004
|
+
nil
|
2728
3005
|
end
|
2729
3006
|
end
|
2730
3007
|
end
|