steep 0.13.0 → 0.16.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.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
|