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