steep 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby-windows.yml +34 -0
- data/.github/workflows/ruby.yml +2 -2
- data/CHANGELOG.md +32 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +5 -5
- data/lib/steep/ast/builtin.rb +2 -2
- data/lib/steep/ast/types/factory.rb +6 -2
- data/lib/steep/ast/types/proc.rb +2 -0
- data/lib/steep/cli.rb +3 -1
- data/lib/steep/diagnostic/ruby.rb +1 -1
- data/lib/steep/drivers/check.rb +3 -3
- data/lib/steep/path_helper.rb +22 -0
- data/lib/steep/project.rb +3 -15
- data/lib/steep/server/base_worker.rb +1 -0
- data/lib/steep/server/change_buffer.rb +1 -1
- data/lib/steep/server/interaction_worker.rb +3 -5
- data/lib/steep/server/master.rb +61 -45
- data/lib/steep/server/type_check_worker.rb +10 -25
- data/lib/steep/services/completion_provider.rb +3 -3
- data/lib/steep/services/goto_service.rb +2 -4
- data/lib/steep/services/hover_provider/rbs.rb +1 -1
- data/lib/steep/services/stats_calculator.rb +0 -1
- data/lib/steep/services/type_check_service.rb +3 -0
- data/lib/steep/source.rb +1 -1
- data/lib/steep/subtyping/check.rb +0 -3
- data/lib/steep/type_construction.rb +63 -26
- data/lib/steep/type_inference/logic_type_interpreter.rb +6 -4
- data/lib/steep/type_inference/send_args.rb +1 -2
- data/lib/steep/type_inference/type_env.rb +6 -0
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +3 -2
- data/smoke/regression/lambda.rb +3 -0
- data/smoke/regression/test_expectations.yml +12 -0
- data/steep.gemspec +1 -1
- metadata +7 -5
- data/lib/steep/subtyping/variable_occurrence.rb +0 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d153db54fad9f22a3b38fe9a1a2539c11d50b6efc34cea1cba69b2849c69c1e
|
4
|
+
data.tar.gz: 98dfeb1b9a044c6ef30d880d5deda10fb97143e82807743c9f06c4e7aeff6663
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c7b1f95050bf14a7fbf1c521318648c3d99fd6750fff30c79d1bb84a55582dc4f74da0aec91f7ddfc7736c2a571caa99bc462865b42c1335659a6a1e44fe684
|
7
|
+
data.tar.gz: 7708ef12ea5754f432a2c71e347400ebd24cbcab9e69fab21783c1be00c000b3420c8f88db1f83bb2ed58a525a3a6f34f044ea421c2be8f53becf64dfbc7fdda
|
@@ -0,0 +1,34 @@
|
|
1
|
+
name: Run test on Windows
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
pull_request: {}
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
strategy:
|
12
|
+
matrix:
|
13
|
+
ruby_version:
|
14
|
+
- "2.7"
|
15
|
+
- "3.0"
|
16
|
+
- "3.1"
|
17
|
+
task:
|
18
|
+
- test
|
19
|
+
# - test:output Ignored because the order of diagnostics changes somehow
|
20
|
+
- build
|
21
|
+
runs-on: windows-latest
|
22
|
+
steps:
|
23
|
+
- uses: actions/checkout@v3
|
24
|
+
- uses: ruby/setup-ruby@v1
|
25
|
+
with:
|
26
|
+
ruby-version: ${{ matrix.ruby_version }}
|
27
|
+
- name: Run test
|
28
|
+
run: |
|
29
|
+
git config --global --add safe.directory /__w/steep/steep
|
30
|
+
ruby -v
|
31
|
+
gem install bundler
|
32
|
+
bundle install --jobs 4 --retry 3
|
33
|
+
bin/setup
|
34
|
+
bundle exec rake ${{matrix.task}}
|
data/.github/workflows/ruby.yml
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
name:
|
1
|
+
name: Run test on container
|
2
2
|
|
3
3
|
on:
|
4
4
|
push:
|
@@ -8,7 +8,6 @@ on:
|
|
8
8
|
|
9
9
|
jobs:
|
10
10
|
test:
|
11
|
-
runs-on: "ubuntu-latest"
|
12
11
|
strategy:
|
13
12
|
matrix:
|
14
13
|
container_tag:
|
@@ -20,6 +19,7 @@ jobs:
|
|
20
19
|
- test
|
21
20
|
- test:output
|
22
21
|
- build
|
22
|
+
runs-on: ubuntu-latest
|
23
23
|
container:
|
24
24
|
image: rubylang/ruby:${{ matrix.container_tag }}
|
25
25
|
steps:
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,38 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 1.0.1 (2022-06-16)
|
6
|
+
|
7
|
+
This is the first patch release for Steep 1.0.
|
8
|
+
However, this release includes one non-trivial type system update, [\#570](https://github.com/soutaro/steep/pull/570), which adds a special typing rule for `Hash#compact` like `Array#compact`.
|
9
|
+
The change will make type checking more permissive and precise, so no new error won't be reported with the fix.
|
10
|
+
|
11
|
+
### Type checker
|
12
|
+
|
13
|
+
* Support shorthand hash for Ruby 3.1 ([\#567](https://github.com/soutaro/steep/pull/567))
|
14
|
+
* Fix super and zsuper with block ([\#568](https://github.com/soutaro/steep/pull/568))
|
15
|
+
* Apply logic-type evaluation only if the node is `:send` ([\#569](https://github.com/soutaro/steep/pull/569))
|
16
|
+
* Add support for `Hash#compact` ([\#570](https://github.com/soutaro/steep/pull/570))
|
17
|
+
* Use given `const_env` when making a new `ModuleContext` ([\#575](https://github.com/soutaro/steep/pull/575))
|
18
|
+
* Graceful, hopefully, error handling with undefined outer module ([\#576](https://github.com/soutaro/steep/pull/576))
|
19
|
+
* Type check anonymous block forwarding ([\#577](https://github.com/soutaro/steep/pull/577))
|
20
|
+
* Incompatible default value is a type error ([\#578](https://github.com/soutaro/steep/pull/578))
|
21
|
+
* Load `ChildrenLevel` helper in `AST::Types::Proc` ([\#584](https://github.com/soutaro/steep/pull/584))
|
22
|
+
* Type check `gvar` and `gvasgn` in methods([\#579](https://github.com/soutaro/steep/pull/579))
|
23
|
+
* Avoid `UnexpectedError` when assigning untyped singleton class ([\#586](https://github.com/soutaro/steep/pull/586))
|
24
|
+
|
25
|
+
### Tool
|
26
|
+
|
27
|
+
* Improve Windows support ([\#561](https://github.com/soutaro/steep/pull/561), [\#573](https://github.com/soutaro/steep/pull/573))
|
28
|
+
* Test if `.ruby-version` exists before `rvm do` in binstub ([\#558](https://github.com/soutaro/steep/pull/558))
|
29
|
+
* Fix typo ([\#564](https://github.com/soutaro/steep/pull/564))
|
30
|
+
* Ignore `untitled:` URIs in LSP ([\#580](https://github.com/soutaro/steep/pull/580))
|
31
|
+
|
32
|
+
### Miscellaneous
|
33
|
+
|
34
|
+
* Fix test name ([\#565](https://github.com/soutaro/steep/pull/565), [\#566](https://github.com/soutaro/steep/pull/566), [\#585](https://github.com/soutaro/steep/pull/585))
|
35
|
+
* Remove some unused code except tests ([\#587](https://github.com/soutaro/steep/pull/587))
|
36
|
+
|
5
37
|
## 1.0.0 (2022-05-20)
|
6
38
|
|
7
39
|
* Add special typing rule for `Array#compact` ([\#555](https://github.com/soutaro/steep/pull/555))
|
data/Gemfile
CHANGED
@@ -7,7 +7,7 @@ gem "with_steep_types", path: "test/gems/with_steep_types"
|
|
7
7
|
gem "without_steep_types", path: "test/gems/without_steep_types"
|
8
8
|
|
9
9
|
gem "rake"
|
10
|
-
gem "minitest", "~> 5.
|
10
|
+
gem "minitest", "~> 5.16"
|
11
11
|
gem "minitest-hooks"
|
12
12
|
group :stackprof, optional: true do
|
13
13
|
gem "stackprof"
|
data/Gemfile.lock
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
steep (1.0.
|
4
|
+
steep (1.0.1)
|
5
5
|
activesupport (>= 5.1)
|
6
6
|
language_server-protocol (>= 3.15, < 4.0)
|
7
7
|
listen (~> 3.0)
|
8
8
|
parallel (>= 1.0.0)
|
9
|
-
parser (>= 3.
|
9
|
+
parser (>= 3.1)
|
10
10
|
rainbow (>= 2.2.2, < 4.0)
|
11
11
|
rbs (>= 2.3.2)
|
12
12
|
terminal-table (>= 2, < 4)
|
@@ -38,7 +38,7 @@ GEM
|
|
38
38
|
listen (3.7.1)
|
39
39
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
40
40
|
rb-inotify (~> 0.9, >= 0.9.10)
|
41
|
-
minitest (5.
|
41
|
+
minitest (5.16.1)
|
42
42
|
minitest-hooks (1.5.0)
|
43
43
|
minitest (> 5.3)
|
44
44
|
minitest-slow_test (0.2.0)
|
@@ -51,7 +51,7 @@ GEM
|
|
51
51
|
rb-fsevent (0.11.1)
|
52
52
|
rb-inotify (0.10.1)
|
53
53
|
ffi (~> 1.0)
|
54
|
-
rbs (2.
|
54
|
+
rbs (2.5.1)
|
55
55
|
stackprof (0.2.19)
|
56
56
|
terminal-table (3.0.2)
|
57
57
|
unicode-display_width (>= 1.1.1, < 3)
|
@@ -63,7 +63,7 @@ PLATFORMS
|
|
63
63
|
ruby
|
64
64
|
|
65
65
|
DEPENDENCIES
|
66
|
-
minitest (~> 5.
|
66
|
+
minitest (~> 5.16)
|
67
67
|
minitest-hooks
|
68
68
|
minitest-slow_test
|
69
69
|
rake
|
data/lib/steep/ast/builtin.rb
CHANGED
@@ -16,7 +16,7 @@ module Steep
|
|
16
16
|
args << Builtin.any_type
|
17
17
|
end
|
18
18
|
end
|
19
|
-
arity == args.size or raise "
|
19
|
+
arity == args.size or raise "Malformed instance type: name=#{module_name}, args=#{args}"
|
20
20
|
|
21
21
|
Types::Name::Instance.new(name: module_name, args: args)
|
22
22
|
end
|
@@ -28,7 +28,7 @@ module Steep
|
|
28
28
|
def instance_type?(type, args: nil)
|
29
29
|
if type.is_a?(Types::Name::Instance)
|
30
30
|
if args
|
31
|
-
arity == args.size or raise "
|
31
|
+
arity == args.size or raise "Malformed instance type: name=#{module_name}, args=#{args}"
|
32
32
|
type.name == module_name && type.args == args
|
33
33
|
else
|
34
34
|
type.name == module_name && type.args.size == arity
|
@@ -9,6 +9,12 @@ module Steep
|
|
9
9
|
|
10
10
|
attr_reader :type_interface_cache
|
11
11
|
|
12
|
+
def inspect
|
13
|
+
s = "#<%s:%#018x " % [self.class, object_id]
|
14
|
+
s << "@definition_builder=#<%s:%#018x>" % [definition_builder.class, definition_builder.object_id]
|
15
|
+
s + ">"
|
16
|
+
end
|
17
|
+
|
12
18
|
def initialize(builder:)
|
13
19
|
@definition_builder = builder
|
14
20
|
|
@@ -282,8 +288,6 @@ module Steep
|
|
282
288
|
fvs = self_type.free_variables()
|
283
289
|
|
284
290
|
type_params = []
|
285
|
-
alpha_vars = []
|
286
|
-
alpha_types = []
|
287
291
|
|
288
292
|
conflicting_names = method_type.type_params.each.with_object([]) do |param, names|
|
289
293
|
names << params.name if fvs.include?(param.name)
|
data/lib/steep/ast/types/proc.rb
CHANGED
data/lib/steep/cli.rb
CHANGED
@@ -271,7 +271,9 @@ if type "rbenv" > /dev/null 2>&1; then
|
|
271
271
|
STEEP="rbenv exec ${STEEP}"
|
272
272
|
else
|
273
273
|
if type "rvm" > /dev/null 2>&1; then
|
274
|
-
|
274
|
+
if [ -e ${ROOT_DIR}/.ruby-version ]; then
|
275
|
+
STEEP="rvm ${ROOT_DIR} do ${STEEP}"
|
276
|
+
fi
|
275
277
|
fi
|
276
278
|
fi
|
277
279
|
|
@@ -296,7 +296,7 @@ module Steep
|
|
296
296
|
attr_reader :method_type
|
297
297
|
|
298
298
|
def initialize(node:, method_type:)
|
299
|
-
super(node: node, location: node.loc.selector)
|
299
|
+
super(node: node, location: (node.type == :super || node.type == :zsuper) ? node.loc.keyword : node.loc.selector)
|
300
300
|
@method_type = method_type
|
301
301
|
end
|
302
302
|
|
data/lib/steep/drivers/check.rb
CHANGED
@@ -139,7 +139,7 @@ module Steep
|
|
139
139
|
missing_count = 0
|
140
140
|
|
141
141
|
ns = notifications.each.with_object({}) do |notification, hash|
|
142
|
-
path = project.relative_path(
|
142
|
+
path = project.relative_path(Steep::PathHelper.to_pathname(notification[:uri]))
|
143
143
|
hash[path] = notification[:diagnostics]
|
144
144
|
end
|
145
145
|
|
@@ -186,7 +186,7 @@ module Steep
|
|
186
186
|
end
|
187
187
|
|
188
188
|
ns = notifications.each.with_object({}) do |notification, hash|
|
189
|
-
path = project.relative_path(
|
189
|
+
path = project.relative_path(Steep::PathHelper.to_pathname(notification[:uri]))
|
190
190
|
hash[path] = notification[:diagnostics]
|
191
191
|
end
|
192
192
|
|
@@ -215,7 +215,7 @@ module Steep
|
|
215
215
|
total = errors.sum {|notification| notification[:diagnostics].size }
|
216
216
|
|
217
217
|
errors.each do |notification|
|
218
|
-
path =
|
218
|
+
path = Steep::PathHelper.to_pathname(notification[:uri])
|
219
219
|
buffer = RBS::Buffer.new(name: project.relative_path(path), content: path.read)
|
220
220
|
printer = DiagnosticPrinter.new(buffer: buffer, stdout: stdout)
|
221
221
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Steep
|
2
|
+
module PathHelper
|
3
|
+
module_function
|
4
|
+
|
5
|
+
def to_pathname(uri, dosish: Gem.win_platform?)
|
6
|
+
uri = URI.parse(uri)
|
7
|
+
if uri.scheme == "file"
|
8
|
+
path = uri.path
|
9
|
+
path.sub!(%r{^/([a-zA-Z])(:|%3A)//?}i, '\1:/') if dosish
|
10
|
+
Pathname(path)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_uri(path, dosish: Gem.win_platform?)
|
15
|
+
str_path = path.to_s
|
16
|
+
if dosish
|
17
|
+
str_path.insert(0, "/") if str_path[0] != "/"
|
18
|
+
end
|
19
|
+
URI::File.build(path: str_path)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/steep/project.rb
CHANGED
@@ -16,22 +16,10 @@ module Steep
|
|
16
16
|
steepfile_path.parent
|
17
17
|
end
|
18
18
|
|
19
|
-
def relative_path(
|
20
|
-
path = if Gem.win_platform?
|
21
|
-
path_str = URI.decode_www_form_component(
|
22
|
-
orig_path.to_s.delete_prefix("/")
|
23
|
-
)
|
24
|
-
unless path_str.start_with?(%r{[a-z]:/}i)
|
25
|
-
# FIXME: Sometimes drive letter is missing, taking from base_dir
|
26
|
-
path_str = base_dir.to_s.split("/")[0] + "/" + path_str
|
27
|
-
end
|
28
|
-
Pathname.new(
|
29
|
-
path_str
|
30
|
-
)
|
31
|
-
else
|
32
|
-
orig_path
|
33
|
-
end
|
19
|
+
def relative_path(path)
|
34
20
|
path.relative_path_from(base_dir)
|
21
|
+
rescue ArgumentError
|
22
|
+
path
|
35
23
|
end
|
36
24
|
|
37
25
|
def absolute_path(path)
|
@@ -40,7 +40,7 @@ module Steep
|
|
40
40
|
|
41
41
|
def collect_changes(request)
|
42
42
|
push_buffer do |changes|
|
43
|
-
path = project.relative_path(
|
43
|
+
path = project.relative_path(Steep::PathHelper.to_pathname(request[:params][:textDocument][:uri]))
|
44
44
|
version = request[:params][:textDocument][:version]
|
45
45
|
Steep.logger.info { "Updating source: path=#{path}, version=#{version}..." }
|
46
46
|
|
@@ -53,8 +53,7 @@ module Steep
|
|
53
53
|
when "textDocument/hover"
|
54
54
|
id = request[:id]
|
55
55
|
|
56
|
-
|
57
|
-
path = project.relative_path(Pathname(uri.path))
|
56
|
+
path = project.relative_path(Steep::PathHelper.to_pathname(request[:params][:textDocument][:uri]))
|
58
57
|
line = request[:params][:position][:line]+1
|
59
58
|
column = request[:params][:position][:character]
|
60
59
|
|
@@ -64,8 +63,7 @@ module Steep
|
|
64
63
|
id = request[:id]
|
65
64
|
|
66
65
|
params = request[:params]
|
67
|
-
|
68
|
-
path = project.relative_path(Pathname(uri.path))
|
66
|
+
path = project.relative_path(Steep::PathHelper.to_pathname(params[:textDocument][:uri]))
|
69
67
|
line, column = params[:position].yield_self {|hash| [hash[:line]+1, hash[:character]] }
|
70
68
|
trigger = params.dig(:context, :triggerCharacter)
|
71
69
|
|
@@ -144,7 +142,7 @@ module Steep
|
|
144
142
|
decls = sig_service.files[relative_path].decls
|
145
143
|
locator = RBS::Locator.new(decls: decls)
|
146
144
|
|
147
|
-
|
145
|
+
_hd, tail = locator.find2(line: job.line, column: job.column)
|
148
146
|
|
149
147
|
namespace = []
|
150
148
|
tail.each do |t|
|
data/lib/steep/server/master.rb
CHANGED
@@ -21,9 +21,7 @@ module Steep
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def uri(path)
|
24
|
-
|
25
|
-
uri.scheme = "file"
|
26
|
-
end
|
24
|
+
Steep::PathHelper.to_uri(path)
|
27
25
|
end
|
28
26
|
|
29
27
|
def as_json(assignment:)
|
@@ -41,7 +39,7 @@ module Steep
|
|
41
39
|
end
|
42
40
|
|
43
41
|
def percentage
|
44
|
-
checked_paths.size * 100 /
|
42
|
+
checked_paths.size * 100 / all_paths.size
|
45
43
|
end
|
46
44
|
|
47
45
|
def all_paths
|
@@ -50,12 +48,7 @@ module Steep
|
|
50
48
|
|
51
49
|
def checking_path?(path)
|
52
50
|
[library_paths, signature_paths, code_paths].any? do |paths|
|
53
|
-
|
54
|
-
# FIXME: Sometimes drive letter is missing, so comparing without drive letter.
|
55
|
-
paths.any? {|p| p.to_s.split("/", 2)[1] == path.to_s.split("/", 2)[1]}
|
56
|
-
else
|
57
|
-
paths.include?(path)
|
58
|
-
end
|
51
|
+
paths.include?(path)
|
59
52
|
end
|
60
53
|
end
|
61
54
|
|
@@ -463,7 +456,7 @@ module Steep
|
|
463
456
|
end
|
464
457
|
|
465
458
|
def pathname(uri)
|
466
|
-
|
459
|
+
Steep::PathHelper.to_pathname(uri)
|
467
460
|
end
|
468
461
|
|
469
462
|
def work_done_progress_supported?
|
@@ -524,40 +517,54 @@ module Steep
|
|
524
517
|
end
|
525
518
|
|
526
519
|
when "textDocument/didChange"
|
527
|
-
|
528
|
-
|
529
|
-
|
520
|
+
if path = pathname(message[:params][:textDocument][:uri])
|
521
|
+
broadcast_notification(message)
|
522
|
+
controller.push_changes(path)
|
523
|
+
end
|
530
524
|
|
531
525
|
when "textDocument/didSave"
|
532
|
-
if
|
533
|
-
if
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
526
|
+
if path = pathname(message[:params][:textDocument][:uri])
|
527
|
+
if typecheck_automatically
|
528
|
+
if request = controller.make_request(last_request: current_type_check_request)
|
529
|
+
start_type_check(
|
530
|
+
request,
|
531
|
+
last_request: current_type_check_request,
|
532
|
+
start_progress: request.total > 10
|
533
|
+
)
|
534
|
+
end
|
539
535
|
end
|
540
536
|
end
|
541
537
|
|
542
538
|
when "textDocument/didOpen"
|
543
|
-
path = pathname(message[:params][:textDocument][:uri])
|
544
|
-
|
539
|
+
if path = pathname(message[:params][:textDocument][:uri])
|
540
|
+
controller.update_priority(open: path)
|
541
|
+
end
|
545
542
|
|
546
543
|
when "textDocument/didClose"
|
547
|
-
path = pathname(message[:params][:textDocument][:uri])
|
548
|
-
|
544
|
+
if path = pathname(message[:params][:textDocument][:uri])
|
545
|
+
controller.update_priority(close: path)
|
546
|
+
end
|
549
547
|
|
550
548
|
when "textDocument/hover", "textDocument/completion"
|
551
549
|
if interaction_worker
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
550
|
+
if path = pathname(message[:params][:textDocument][:uri])
|
551
|
+
result_controller << send_request(method: message[:method], params: message[:params], worker: interaction_worker) do |handler|
|
552
|
+
handler.on_completion do |response|
|
553
|
+
job_queue << SendMessageJob.to_client(
|
554
|
+
message: {
|
555
|
+
id: message[:id],
|
556
|
+
result: response[:result]
|
557
|
+
}
|
558
|
+
)
|
559
|
+
end
|
560
560
|
end
|
561
|
+
else
|
562
|
+
job_queue << SendMessageJob.to_client(
|
563
|
+
message: {
|
564
|
+
id: message[:id],
|
565
|
+
result: nil
|
566
|
+
}
|
567
|
+
)
|
561
568
|
end
|
562
569
|
end
|
563
570
|
|
@@ -594,20 +601,29 @@ module Steep
|
|
594
601
|
end
|
595
602
|
|
596
603
|
when "textDocument/definition", "textDocument/implementation"
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
604
|
+
if path = pathname(message[:params][:textDocument][:uri])
|
605
|
+
result_controller << group_request do |group|
|
606
|
+
typecheck_workers.each do |worker|
|
607
|
+
group << send_request(method: message[:method], params: message[:params], worker: worker)
|
608
|
+
end
|
601
609
|
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
+
group.on_completion do |handlers|
|
611
|
+
links = handlers.flat_map(&:result)
|
612
|
+
job_queue << SendMessageJob.to_client(
|
613
|
+
message: {
|
614
|
+
id: message[:id],
|
615
|
+
result: links
|
616
|
+
}
|
617
|
+
)
|
618
|
+
end
|
610
619
|
end
|
620
|
+
else
|
621
|
+
job_queue << SendMessageJob.to_client(
|
622
|
+
message: {
|
623
|
+
id: message[:id],
|
624
|
+
result: []
|
625
|
+
}
|
626
|
+
)
|
611
627
|
end
|
612
628
|
|
613
629
|
when "$/typecheck"
|
@@ -86,10 +86,10 @@ module Steep
|
|
86
86
|
queue << StartTypeCheckJob.new(guid: guid, changes: changes)
|
87
87
|
end
|
88
88
|
|
89
|
-
priority_paths = Set.new(params[:priority_uris].map {|uri|
|
90
|
-
library_paths = params[:library_uris].map {|uri|
|
91
|
-
signature_paths = params[:signature_uris].map {|uri|
|
92
|
-
code_paths = params[:code_uris].map {|uri|
|
89
|
+
priority_paths = Set.new(params[:priority_uris].map {|uri| Steep::PathHelper.to_pathname(uri) })
|
90
|
+
library_paths = params[:library_uris].map {|uri| Steep::PathHelper.to_pathname(uri) }
|
91
|
+
signature_paths = params[:signature_uris].map {|uri| Steep::PathHelper.to_pathname(uri) }
|
92
|
+
code_paths = params[:code_uris].map {|uri| Steep::PathHelper.to_pathname(uri) }
|
93
93
|
|
94
94
|
library_paths.each do |path|
|
95
95
|
if priority_paths.include?(path)
|
@@ -135,21 +135,6 @@ module Steep
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def handle_job(job)
|
138
|
-
job_path = if job.respond_to?(:path)
|
139
|
-
if Gem.win_platform?
|
140
|
-
# FIXME: Sometimes drive letter is missing, using base_dir
|
141
|
-
if job.path.to_s.start_with?(%r{/[a-z](:|%3A)/}i)
|
142
|
-
job.path.to_s
|
143
|
-
else
|
144
|
-
"/#{project.base_dir.to_s.split("/").first}/#{job.path}"
|
145
|
-
end
|
146
|
-
else
|
147
|
-
job.path.to_s
|
148
|
-
end
|
149
|
-
else
|
150
|
-
nil
|
151
|
-
end
|
152
|
-
|
153
138
|
case job
|
154
139
|
when StartTypeCheckJob
|
155
140
|
Steep.logger.info { "Processing StartTypeCheckJob for guid=#{job.guid}" }
|
@@ -164,7 +149,7 @@ module Steep
|
|
164
149
|
writer.write(
|
165
150
|
method: :"textDocument/publishDiagnostics",
|
166
151
|
params: LSP::Interface::PublishDiagnosticsParams.new(
|
167
|
-
uri:
|
152
|
+
uri: Steep::PathHelper.to_uri(job.path),
|
168
153
|
diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq
|
169
154
|
)
|
170
155
|
)
|
@@ -182,7 +167,7 @@ module Steep
|
|
182
167
|
writer.write(
|
183
168
|
method: :"textDocument/publishDiagnostics",
|
184
169
|
params: LSP::Interface::PublishDiagnosticsParams.new(
|
185
|
-
uri:
|
170
|
+
uri: Steep::PathHelper.to_uri(job.path),
|
186
171
|
diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq.compact
|
187
172
|
)
|
188
173
|
)
|
@@ -201,7 +186,7 @@ module Steep
|
|
201
186
|
writer.write(
|
202
187
|
method: :"textDocument/publishDiagnostics",
|
203
188
|
params: LSP::Interface::PublishDiagnosticsParams.new(
|
204
|
-
uri:
|
189
|
+
uri: Steep::PathHelper.to_uri(job.path),
|
205
190
|
diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq.compact
|
206
191
|
)
|
207
192
|
)
|
@@ -251,7 +236,7 @@ module Steep
|
|
251
236
|
location: symbol.location.yield_self do |location|
|
252
237
|
path = Pathname(location.buffer.name)
|
253
238
|
{
|
254
|
-
uri:
|
239
|
+
uri: Steep::PathHelper.to_uri(project.absolute_path(path)),
|
255
240
|
range: {
|
256
241
|
start: { line: location.start_line - 1, character: location.start_column },
|
257
242
|
end: { line: location.end_line - 1, character: location.end_column }
|
@@ -279,7 +264,7 @@ module Steep
|
|
279
264
|
end
|
280
265
|
|
281
266
|
def goto(job)
|
282
|
-
path =
|
267
|
+
path = Steep::PathHelper.to_pathname(job.params[:textDocument][:uri])
|
283
268
|
line = job.params[:position][:line] + 1
|
284
269
|
column = job.params[:position][:character]
|
285
270
|
|
@@ -306,7 +291,7 @@ module Steep
|
|
306
291
|
path = project.absolute_path(path)
|
307
292
|
|
308
293
|
{
|
309
|
-
uri:
|
294
|
+
uri: Steep::PathHelper.to_uri(path.to_s).to_s,
|
310
295
|
range: loc.as_lsp_range
|
311
296
|
}
|
312
297
|
end
|
@@ -157,7 +157,7 @@ module Steep
|
|
157
157
|
end
|
158
158
|
|
159
159
|
def items_for_trigger(position:)
|
160
|
-
node, *
|
160
|
+
node, *_parents = source.find_nodes(line: position.line, column: position.column)
|
161
161
|
node ||= source.node
|
162
162
|
|
163
163
|
return [] unless node
|
@@ -265,7 +265,7 @@ module Steep
|
|
265
265
|
def items_for_dot(position:)
|
266
266
|
# foo. ←
|
267
267
|
shift_pos = position-1
|
268
|
-
node, *
|
268
|
+
node, *_parents = source.find_nodes(line: shift_pos.line, column: shift_pos.column)
|
269
269
|
node ||= source.node
|
270
270
|
|
271
271
|
return [] unless node
|
@@ -355,7 +355,7 @@ module Steep
|
|
355
355
|
end
|
356
356
|
end
|
357
357
|
end
|
358
|
-
rescue RuntimeError =>
|
358
|
+
rescue RuntimeError => _exn
|
359
359
|
# nop
|
360
360
|
end
|
361
361
|
|
@@ -35,7 +35,7 @@ module Steep
|
|
35
35
|
def implementation(path:, line:, column:)
|
36
36
|
locations = []
|
37
37
|
|
38
|
-
relative_path = project.relative_path(path)
|
38
|
+
# relative_path = project.relative_path(path)
|
39
39
|
|
40
40
|
queries = query_at(path: path, line: line, column: column)
|
41
41
|
queries.uniq!
|
@@ -57,8 +57,6 @@ module Steep
|
|
57
57
|
def definition(path:, line:, column:)
|
58
58
|
locations = []
|
59
59
|
|
60
|
-
relative_path = project.relative_path(path)
|
61
|
-
|
62
60
|
queries = query_at(path: path, line: line, column: column)
|
63
61
|
queries.uniq!
|
64
62
|
|
@@ -108,7 +106,7 @@ module Steep
|
|
108
106
|
case
|
109
107
|
when target = type_check.source_file?(relative_path)
|
110
108
|
source = type_check.source_files[relative_path]
|
111
|
-
typing,
|
109
|
+
typing, _signature = type_check_path(target: target, path: relative_path, content: source.content, line: line, column: column)
|
112
110
|
if typing
|
113
111
|
node, *parents = typing.source.find_nodes(line: line, column: column)
|
114
112
|
|
@@ -335,6 +335,9 @@ module Steep
|
|
335
335
|
SourceFile.with_syntax_error(path: path, content: text, error: error)
|
336
336
|
rescue EncodingError => exn
|
337
337
|
SourceFile.no_data(path: path, content: "")
|
338
|
+
rescue RuntimeError => exn
|
339
|
+
Steep.log_error(exn)
|
340
|
+
SourceFile.no_data(path: path, content: text)
|
338
341
|
end
|
339
342
|
|
340
343
|
def self.type_check(source:, subtyping:)
|
data/lib/steep/source.rb
CHANGED
@@ -421,9 +421,6 @@ module Steep
|
|
421
421
|
when relation.sub_type.is_a?(AST::Types::Proc) && relation.super_type.is_a?(AST::Types::Proc)
|
422
422
|
name = :__proc__
|
423
423
|
|
424
|
-
sub_type = relation.sub_type
|
425
|
-
super_type = relation.super_type
|
426
|
-
|
427
424
|
All(relation) do |result|
|
428
425
|
result.add(relation.map {|p| p.type }) do |rel|
|
429
426
|
check_function(name, rel)
|
@@ -131,11 +131,13 @@ module Steep
|
|
131
131
|
|
132
132
|
def for_new_method(method_name, node, args:, self_type:, definition:)
|
133
133
|
annots = source.annotations(block: node, factory: checker.factory, context: nesting)
|
134
|
-
type_env = TypeInference::TypeEnv.
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
134
|
+
type_env = TypeInference::TypeEnv.build(
|
135
|
+
annotations: annots,
|
136
|
+
subtyping: checker,
|
137
|
+
const_env: module_context&.const_env || self.type_env.const_env,
|
138
|
+
signatures: checker.factory.env
|
139
|
+
)
|
140
|
+
type_env.merge_const_types(self.type_env)
|
139
141
|
|
140
142
|
definition_method_type = if definition
|
141
143
|
definition.methods[method_name]&.yield_self do |method|
|
@@ -320,7 +322,7 @@ module Steep
|
|
320
322
|
instance_type: nil,
|
321
323
|
module_type: nil,
|
322
324
|
implement_name: nil,
|
323
|
-
const_env:
|
325
|
+
const_env: const_env,
|
324
326
|
class_name: self.module_context.class_name,
|
325
327
|
module_definition: nil,
|
326
328
|
instance_definition: nil
|
@@ -1355,24 +1357,23 @@ module Steep
|
|
1355
1357
|
rhs = node.children[1]
|
1356
1358
|
|
1357
1359
|
var_type = context.lvar_env[var]
|
1358
|
-
node_type, constr = synthesize(rhs, hint: var_type)
|
1359
|
-
|
1360
|
-
type = AST::Types::Union.build(types: [var_type, node_type])
|
1361
1360
|
|
1362
|
-
|
1363
|
-
|
1361
|
+
if var_type
|
1362
|
+
type, constr = check(rhs, var_type) do |expected_type, actual_type, result|
|
1364
1363
|
typing.add_error(
|
1365
1364
|
Diagnostic::Ruby::IncompatibleAssignment.new(
|
1366
1365
|
node: node,
|
1367
|
-
lhs_type:
|
1368
|
-
rhs_type:
|
1366
|
+
lhs_type: expected_type,
|
1367
|
+
rhs_type: actual_type,
|
1369
1368
|
result: result
|
1370
1369
|
)
|
1371
1370
|
)
|
1372
1371
|
end
|
1372
|
+
else
|
1373
|
+
type, constr = synthesize(rhs)
|
1373
1374
|
end
|
1374
1375
|
|
1375
|
-
add_typing(node, type: type
|
1376
|
+
constr.add_typing(node, type: type)
|
1376
1377
|
end
|
1377
1378
|
|
1378
1379
|
when :restarg
|
@@ -1578,8 +1579,7 @@ module Steep
|
|
1578
1579
|
message: "sclass receiver must be instance type or singleton type, but type given `#{type}`"
|
1579
1580
|
)
|
1580
1581
|
)
|
1581
|
-
constr.add_typing(node, type: AST::Builtin.nil_type)
|
1582
|
-
return
|
1582
|
+
return constr.add_typing(node, type: AST::Builtin.nil_type)
|
1583
1583
|
end
|
1584
1584
|
|
1585
1585
|
constructor.typing.add_context_for_node(node, context: constructor.context)
|
@@ -2299,7 +2299,8 @@ module Steep
|
|
2299
2299
|
yield_self do
|
2300
2300
|
value = node.children[0]
|
2301
2301
|
|
2302
|
-
|
2302
|
+
case
|
2303
|
+
when hint.is_a?(AST::Types::Proc) && value && value.type == :sym
|
2303
2304
|
if hint.one_arg?
|
2304
2305
|
# Assumes Symbol#to_proc implementation
|
2305
2306
|
param_type = hint.type.params.required[0]
|
@@ -2333,9 +2334,18 @@ module Steep
|
|
2333
2334
|
else
|
2334
2335
|
Steep.logger.error "Passing multiple args through Symbol#to_proc is not supported yet"
|
2335
2336
|
end
|
2337
|
+
when value == nil
|
2338
|
+
type = AST::Types::Proc.new(
|
2339
|
+
type: method_context.method_type.block.type,
|
2340
|
+
location: nil,
|
2341
|
+
block: nil
|
2342
|
+
)
|
2343
|
+
if method_context.method_type.block.optional?
|
2344
|
+
type = AST::Types::Union.build(types: [type, AST::Builtin.nil_type])
|
2345
|
+
end
|
2336
2346
|
end
|
2337
2347
|
|
2338
|
-
type ||= synthesize(
|
2348
|
+
type ||= synthesize(value, hint: hint).type
|
2339
2349
|
|
2340
2350
|
add_typing node, type: type
|
2341
2351
|
end
|
@@ -2827,13 +2837,6 @@ module Steep
|
|
2827
2837
|
|
2828
2838
|
block_constr.typing.add_context_for_body(node, context: block_constr.context)
|
2829
2839
|
|
2830
|
-
default_proc_function =
|
2831
|
-
Interface::Function.new(
|
2832
|
-
params: Interface::Function::Params.empty,
|
2833
|
-
return_type: AST::Builtin.any_type,
|
2834
|
-
location: nil
|
2835
|
-
)
|
2836
|
-
|
2837
2840
|
params.params.each do |param|
|
2838
2841
|
_, block_constr = block_constr.synthesize(param.node, hint: param.type)
|
2839
2842
|
end
|
@@ -3093,6 +3096,15 @@ module Steep
|
|
3093
3096
|
private: private,
|
3094
3097
|
self_type: AST::Types::Self.new)
|
3095
3098
|
|
3099
|
+
if send_node.type == :super || send_node.type == :zsuper
|
3100
|
+
method_name = method_context.name
|
3101
|
+
unless method_context.super_method
|
3102
|
+
return fallback_to_any(send_node) do
|
3103
|
+
Diagnostic::Ruby::UnexpectedSuper.new(node: send_node, method: method_name)
|
3104
|
+
end
|
3105
|
+
end
|
3106
|
+
end
|
3107
|
+
|
3096
3108
|
constr.type_send_interface(node,
|
3097
3109
|
interface: interface,
|
3098
3110
|
receiver: receiver,
|
@@ -3144,6 +3156,9 @@ module Steep
|
|
3144
3156
|
array_compact: Set[
|
3145
3157
|
MethodName("::Array#compact"),
|
3146
3158
|
MethodName("::Enumerable#compact")
|
3159
|
+
],
|
3160
|
+
hash_compact: Set[
|
3161
|
+
MethodName("::Hash#compact")
|
3147
3162
|
]
|
3148
3163
|
}
|
3149
3164
|
|
@@ -3170,6 +3185,29 @@ module Steep
|
|
3170
3185
|
method_decls: decls
|
3171
3186
|
)
|
3172
3187
|
|
3188
|
+
return [call, constr]
|
3189
|
+
end
|
3190
|
+
end
|
3191
|
+
when decl = decls.find {|decl| SPECIAL_METHOD_NAMES[:hash_compact].include?(decl.method_name) }
|
3192
|
+
if arguments.empty? && !block_params
|
3193
|
+
# compact
|
3194
|
+
return_type = method_type.type.return_type
|
3195
|
+
if AST::Builtin::Hash.instance_type?(return_type)
|
3196
|
+
key = return_type.args[0]
|
3197
|
+
value = return_type.args[1]
|
3198
|
+
type = AST::Builtin::Hash.instance_type(key, unwrap(value))
|
3199
|
+
|
3200
|
+
_, constr = add_typing(node, type: type)
|
3201
|
+
call = TypeInference::MethodCall::Special.new(
|
3202
|
+
node: node,
|
3203
|
+
context: constr.context.method_context,
|
3204
|
+
method_name: decl.method_name,
|
3205
|
+
receiver_type: receiver_type,
|
3206
|
+
actual_method_type: method_type.with(type: method_type.type.with(return_type: type)),
|
3207
|
+
return_type: type,
|
3208
|
+
method_decls: decls
|
3209
|
+
)
|
3210
|
+
|
3173
3211
|
return [call, constr]
|
3174
3212
|
end
|
3175
3213
|
end
|
@@ -3309,7 +3347,6 @@ module Steep
|
|
3309
3347
|
method_type = method_type.instantiate(instantiation)
|
3310
3348
|
|
3311
3349
|
variance = Subtyping::VariableVariance.from_method_type(method_type)
|
3312
|
-
occurence = Subtyping::VariableOccurence.from_method_type(method_type)
|
3313
3350
|
constraints = Subtyping::Constraints.new(unknowns: type_params.map(&:name))
|
3314
3351
|
ccontext = Subtyping::Constraints::Context.new(
|
3315
3352
|
self_type: self_type,
|
@@ -132,9 +132,12 @@ module Steep
|
|
132
132
|
end
|
133
133
|
end
|
134
134
|
when AST::Types::Logic::Not
|
135
|
-
|
136
|
-
|
137
|
-
|
135
|
+
case value_node.type
|
136
|
+
when :send
|
137
|
+
receiver, * = value_node.children
|
138
|
+
receiver_type = typing.type_of(node: receiver)
|
139
|
+
falsy_env, truthy_env = eval(env: env, type: receiver_type, node: receiver)
|
140
|
+
end
|
138
141
|
end
|
139
142
|
else
|
140
143
|
_, vars = decompose_value(node)
|
@@ -195,7 +198,6 @@ module Steep
|
|
195
198
|
|
196
199
|
[truthy_types, falsy_types]
|
197
200
|
else
|
198
|
-
value_type = typing.type_of(node: value_node)
|
199
201
|
types = [arg_type]
|
200
202
|
|
201
203
|
case value_node.type
|
@@ -528,7 +528,6 @@ module Steep
|
|
528
528
|
def each
|
529
529
|
if block_given?
|
530
530
|
errors = []
|
531
|
-
positional_count = 0
|
532
531
|
|
533
532
|
positional_arg.tap do |args|
|
534
533
|
while (value, args = args.next())
|
@@ -615,7 +614,7 @@ module Steep
|
|
615
614
|
end
|
616
615
|
end
|
617
616
|
|
618
|
-
pass = block_pass_arg
|
617
|
+
# pass = block_pass_arg
|
619
618
|
# if pass.node
|
620
619
|
# yield pass
|
621
620
|
# end
|
data/lib/steep/version.rb
CHANGED
data/lib/steep.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require "steep/version"
|
2
2
|
|
3
3
|
require "pathname"
|
4
|
-
require "parser/
|
4
|
+
require "parser/ruby31"
|
5
5
|
require "active_support"
|
6
6
|
require "active_support/core_ext/object/try"
|
7
7
|
require "active_support/core_ext/string/inflections"
|
@@ -21,6 +21,8 @@ require "terminal-table"
|
|
21
21
|
|
22
22
|
require "rbs"
|
23
23
|
|
24
|
+
require "steep/path_helper"
|
25
|
+
|
24
26
|
require "steep/shims/filter_map"
|
25
27
|
|
26
28
|
require "steep/equatable"
|
@@ -65,7 +67,6 @@ require "steep/subtyping/cache"
|
|
65
67
|
require "steep/subtyping/relation"
|
66
68
|
require "steep/subtyping/constraints"
|
67
69
|
require "steep/subtyping/variable_variance"
|
68
|
-
require "steep/subtyping/variable_occurrence"
|
69
70
|
|
70
71
|
require "steep/diagnostic/helper"
|
71
72
|
require "steep/diagnostic/ruby"
|
@@ -40,6 +40,18 @@
|
|
40
40
|
| (::Numeric) -> ::Time
|
41
41
|
| (::Time) -> ::Float
|
42
42
|
code: Ruby::UnresolvedOverloading
|
43
|
+
- file: lambda.rb
|
44
|
+
diagnostics:
|
45
|
+
- range:
|
46
|
+
start:
|
47
|
+
line: 1
|
48
|
+
character: 7
|
49
|
+
end:
|
50
|
+
line: 1
|
51
|
+
character: 10
|
52
|
+
severity: ERROR
|
53
|
+
message: 'Cannot find the declaration of module: `Mod`'
|
54
|
+
code: Ruby::UnknownConstant
|
43
55
|
- file: set_divide.rb
|
44
56
|
diagnostics:
|
45
57
|
- range:
|
data/steep.gemspec
CHANGED
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
|
|
28
28
|
|
29
29
|
spec.required_ruby_version = '>= 2.6.0'
|
30
30
|
|
31
|
-
spec.add_runtime_dependency "parser", ">= 3.
|
31
|
+
spec.add_runtime_dependency "parser", ">= 3.1"
|
32
32
|
spec.add_runtime_dependency "activesupport", ">= 5.1"
|
33
33
|
spec.add_runtime_dependency "rainbow", ">= 2.2.2", "< 4.0"
|
34
34
|
spec.add_runtime_dependency "listen", "~> 3.0"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: steep
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Soutaro Matsumoto
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '3.
|
19
|
+
version: '3.1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '3.
|
26
|
+
version: '3.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -149,6 +149,7 @@ extensions: []
|
|
149
149
|
extra_rdoc_files: []
|
150
150
|
files:
|
151
151
|
- ".github/dependabot.yml"
|
152
|
+
- ".github/workflows/ruby-windows.yml"
|
152
153
|
- ".github/workflows/ruby.yml"
|
153
154
|
- ".gitignore"
|
154
155
|
- ".gitmodules"
|
@@ -224,6 +225,7 @@ files:
|
|
224
225
|
- lib/steep/interface/type_param.rb
|
225
226
|
- lib/steep/method_name.rb
|
226
227
|
- lib/steep/module_helper.rb
|
228
|
+
- lib/steep/path_helper.rb
|
227
229
|
- lib/steep/project.rb
|
228
230
|
- lib/steep/project/dsl.rb
|
229
231
|
- lib/steep/project/options.rb
|
@@ -256,7 +258,6 @@ files:
|
|
256
258
|
- lib/steep/subtyping/constraints.rb
|
257
259
|
- lib/steep/subtyping/relation.rb
|
258
260
|
- lib/steep/subtyping/result.rb
|
259
|
-
- lib/steep/subtyping/variable_occurrence.rb
|
260
261
|
- lib/steep/subtyping/variable_variance.rb
|
261
262
|
- lib/steep/type_construction.rb
|
262
263
|
- lib/steep/type_inference/block_params.rb
|
@@ -481,6 +482,7 @@ files:
|
|
481
482
|
- smoke/regression/issue_332.rbs
|
482
483
|
- smoke/regression/issue_372.rb
|
483
484
|
- smoke/regression/issue_372.rbs
|
485
|
+
- smoke/regression/lambda.rb
|
484
486
|
- smoke/regression/masgn.rb
|
485
487
|
- smoke/regression/poly_new.rb
|
486
488
|
- smoke/regression/poly_new.rbs
|
@@ -1,51 +0,0 @@
|
|
1
|
-
module Steep
|
2
|
-
module Subtyping
|
3
|
-
class VariableOccurence
|
4
|
-
attr_reader :params
|
5
|
-
attr_reader :returns
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
@params = Set.new
|
9
|
-
@returns = Set.new
|
10
|
-
end
|
11
|
-
|
12
|
-
def add_method_type(method_type)
|
13
|
-
method_type.type.params.each_type do |type|
|
14
|
-
each_var(type) do |var|
|
15
|
-
params << var
|
16
|
-
end
|
17
|
-
end
|
18
|
-
each_var(method_type.type.return_type) do |var|
|
19
|
-
returns << var
|
20
|
-
end
|
21
|
-
|
22
|
-
method_type.block&.yield_self do |block|
|
23
|
-
block.type.params.each_type do |type|
|
24
|
-
each_var(type) do |var|
|
25
|
-
params << var
|
26
|
-
end
|
27
|
-
end
|
28
|
-
each_var(block.type.return_type) do |var|
|
29
|
-
returns << var
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
params.subtract(returns)
|
34
|
-
end
|
35
|
-
|
36
|
-
def each_var(type, &block)
|
37
|
-
type.free_variables.each(&block)
|
38
|
-
end
|
39
|
-
|
40
|
-
def strictly_return?(var)
|
41
|
-
!params.member?(var) && returns.member?(var)
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.from_method_type(method_type)
|
45
|
-
self.new.tap do |occurence|
|
46
|
-
occurence.add_method_type(method_type)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|