steep 0.31.0 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/lib/steep.rb +3 -2
- data/lib/steep/annotation_parser.rb +1 -1
- data/lib/steep/ast/types/factory.rb +66 -60
- data/lib/steep/cli.rb +15 -2
- data/lib/steep/drivers/print_project.rb +11 -0
- data/lib/steep/drivers/stats.rb +85 -0
- data/lib/steep/drivers/vendor.rb +1 -20
- data/lib/steep/errors.rb +19 -15
- data/lib/steep/interface/method_type.rb +12 -23
- data/lib/steep/method_name.rb +28 -0
- data/lib/steep/project/completion_provider.rb +24 -15
- data/lib/steep/project/dsl.rb +13 -17
- data/lib/steep/project/options.rb +4 -4
- data/lib/steep/project/source_file.rb +2 -1
- data/lib/steep/project/target.rb +19 -10
- data/lib/steep/server/interaction_worker.rb +1 -1
- data/lib/steep/server/utils.rb +1 -1
- data/lib/steep/source.rb +3 -3
- data/lib/steep/subtyping/check.rb +30 -16
- data/lib/steep/subtyping/variable_occurrence.rb +2 -0
- data/lib/steep/type_construction.rb +585 -416
- data/lib/steep/type_inference/context.rb +7 -3
- data/lib/steep/type_inference/context_array.rb +1 -1
- data/lib/steep/type_inference/local_variable_type_env.rb +10 -1
- data/lib/steep/type_inference/logic_type_interpreter.rb +6 -0
- data/lib/steep/type_inference/method_call.rb +116 -0
- data/lib/steep/typing.rb +38 -8
- data/lib/steep/version.rb +1 -1
- data/smoke/regression/fun.rb +8 -0
- data/smoke/regression/fun.rbs +4 -0
- data/smoke/regression/range.rb +5 -0
- data/steep.gemspec +1 -1
- metadata +10 -6
- data/lib/steep/ast/buffer.rb +0 -51
- data/lib/steep/ast/location.rb +0 -86
@@ -80,6 +80,7 @@ module Steep
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
+
attr_reader :call_context
|
83
84
|
attr_reader :method_context
|
84
85
|
attr_reader :block_context
|
85
86
|
attr_reader :break_context
|
@@ -88,7 +89,7 @@ module Steep
|
|
88
89
|
attr_reader :type_env
|
89
90
|
attr_reader :lvar_env
|
90
91
|
|
91
|
-
def initialize(method_context:, block_context:, break_context:, module_context:, self_type:, type_env:, lvar_env:)
|
92
|
+
def initialize(method_context:, block_context:, break_context:, module_context:, self_type:, type_env:, lvar_env:, call_context:)
|
92
93
|
@method_context = method_context
|
93
94
|
@block_context = block_context
|
94
95
|
@break_context = break_context
|
@@ -96,6 +97,7 @@ module Steep
|
|
96
97
|
@self_type = self_type
|
97
98
|
@type_env = type_env
|
98
99
|
@lvar_env = lvar_env
|
100
|
+
@call_context = call_context
|
99
101
|
end
|
100
102
|
|
101
103
|
def with(method_context: self.method_context,
|
@@ -104,7 +106,8 @@ module Steep
|
|
104
106
|
module_context: self.module_context,
|
105
107
|
self_type: self.self_type,
|
106
108
|
type_env: self.type_env,
|
107
|
-
lvar_env: self.lvar_env
|
109
|
+
lvar_env: self.lvar_env,
|
110
|
+
call_context: self.call_context)
|
108
111
|
self.class.new(
|
109
112
|
method_context: method_context,
|
110
113
|
block_context: block_context,
|
@@ -112,7 +115,8 @@ module Steep
|
|
112
115
|
module_context: module_context,
|
113
116
|
self_type: self_type,
|
114
117
|
type_env: type_env,
|
115
|
-
lvar_env: lvar_env
|
118
|
+
lvar_env: lvar_env,
|
119
|
+
call_context: call_context
|
116
120
|
)
|
117
121
|
end
|
118
122
|
end
|
@@ -114,7 +114,9 @@ module Steep
|
|
114
114
|
relation = Subtyping::Relation.new(sub_type: inner_type, super_type: outer_type)
|
115
115
|
constraints = Subtyping::Constraints.new(unknowns: Set.new)
|
116
116
|
subtyping.check(relation, constraints: constraints, self_type: self_type).else do |result|
|
117
|
-
|
117
|
+
if block_given?
|
118
|
+
yield var, outer_type, inner_type, result
|
119
|
+
end
|
118
120
|
end
|
119
121
|
end
|
120
122
|
end
|
@@ -147,6 +149,13 @@ module Steep
|
|
147
149
|
)
|
148
150
|
end
|
149
151
|
|
152
|
+
def subst(s)
|
153
|
+
update(
|
154
|
+
declared_types: declared_types.transform_values {|e| e.update(type: e.type.subst(s)) },
|
155
|
+
assigned_types: assigned_types.transform_values {|e| e.update(type: e.type.subst(s)) }
|
156
|
+
)
|
157
|
+
end
|
158
|
+
|
150
159
|
def each
|
151
160
|
if block_given?
|
152
161
|
vars.each do |var|
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module Steep
|
2
|
+
module TypeInference
|
3
|
+
class MethodCall
|
4
|
+
class MethodDecl
|
5
|
+
attr_reader :method_name
|
6
|
+
attr_reader :method_def
|
7
|
+
|
8
|
+
def initialize(method_name:, method_def:)
|
9
|
+
@method_name = method_name
|
10
|
+
@method_def = method_def
|
11
|
+
end
|
12
|
+
|
13
|
+
def hash
|
14
|
+
method_name.hash
|
15
|
+
# RBS::MethodType doesn't have #hash
|
16
|
+
end
|
17
|
+
|
18
|
+
def ==(other)
|
19
|
+
other.is_a?(MethodDecl) && other.method_name == method_name && other.method_def == method_def
|
20
|
+
end
|
21
|
+
|
22
|
+
alias eql? ==
|
23
|
+
|
24
|
+
def method_type
|
25
|
+
method_def.type
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
MethodContext = Struct.new(:method_name, keyword_init: true) do
|
30
|
+
def to_s
|
31
|
+
"@#{method_name}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
ModuleContext = Struct.new(:type_name, keyword_init: true) do
|
36
|
+
def to_s
|
37
|
+
"@#{type_name}@"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
TopLevelContext = Class.new() do
|
42
|
+
def to_s
|
43
|
+
"@<main>"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
UnknownContext = Class.new() do
|
48
|
+
def to_s
|
49
|
+
"@<unknown>"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
class Base
|
55
|
+
attr_reader :node
|
56
|
+
attr_reader :context
|
57
|
+
attr_reader :method_name
|
58
|
+
attr_reader :return_type
|
59
|
+
attr_reader :receiver_type
|
60
|
+
|
61
|
+
def initialize(node:, context:, method_name:, receiver_type:, return_type:)
|
62
|
+
@node = node
|
63
|
+
@context = context
|
64
|
+
@method_name = method_name
|
65
|
+
@receiver_type = receiver_type
|
66
|
+
@return_type = return_type
|
67
|
+
end
|
68
|
+
|
69
|
+
def with_return_type(new_type)
|
70
|
+
dup.tap do |copy|
|
71
|
+
copy.instance_eval do
|
72
|
+
@return_type = new_type
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class Typed < Base
|
79
|
+
attr_reader :actual_method_type
|
80
|
+
attr_reader :method_decls
|
81
|
+
|
82
|
+
def initialize(node:, context:, method_name:, receiver_type:, actual_method_type:, method_decls:, return_type: actual_method_type.return_type)
|
83
|
+
super(node: node, context: context, method_name: method_name, receiver_type: receiver_type, return_type: return_type)
|
84
|
+
@actual_method_type = actual_method_type
|
85
|
+
@method_decls = method_decls
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
class Untyped < Base
|
90
|
+
def initialize(node:, context:, method_name:)
|
91
|
+
super(node: node, context: context, method_name: method_name, receiver_type: AST::Types::Any.new, return_type: AST::Types::Any.new)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class NoMethodError < Base
|
96
|
+
attr_reader :error
|
97
|
+
|
98
|
+
def initialize(node:, context:, method_name:, receiver_type:, error:)
|
99
|
+
super(node: node, context: context, method_name: method_name, receiver_type: receiver_type, return_type: AST::Types::Any.new)
|
100
|
+
@error = error
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class Error < Base
|
105
|
+
attr_reader :errors
|
106
|
+
attr_reader :method_decls
|
107
|
+
|
108
|
+
def initialize(node:, context:, method_name:, receiver_type:, errors:, method_decls: Set[], return_type: AST::Types::Any.new)
|
109
|
+
super(node: node, context: context, method_name: method_name, receiver_type: receiver_type, return_type: return_type)
|
110
|
+
@method_decls = method_decls
|
111
|
+
@errors = errors
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/lib/steep/typing.rb
CHANGED
@@ -20,6 +20,7 @@ module Steep
|
|
20
20
|
attr_reader :should_update
|
21
21
|
attr_reader :contexts
|
22
22
|
attr_reader :root_context
|
23
|
+
attr_reader :method_calls
|
23
24
|
|
24
25
|
def initialize(source:, root_context:, parent: nil, parent_last_update: parent&.last_update, contexts: nil)
|
25
26
|
@source = source
|
@@ -33,6 +34,7 @@ module Steep
|
|
33
34
|
@typing = {}.compare_by_identity
|
34
35
|
@root_context = root_context
|
35
36
|
@contexts = contexts || TypeInference::ContextArray.from_source(source: source)
|
37
|
+
@method_calls = {}.compare_by_identity
|
36
38
|
end
|
37
39
|
|
38
40
|
def add_error(error)
|
@@ -46,6 +48,12 @@ module Steep
|
|
46
48
|
type
|
47
49
|
end
|
48
50
|
|
51
|
+
def add_call(node, call)
|
52
|
+
method_calls[node] = call
|
53
|
+
|
54
|
+
call
|
55
|
+
end
|
56
|
+
|
49
57
|
def add_context(range, context:)
|
50
58
|
contexts.insert_context(range, context: context)
|
51
59
|
@last_update += 1
|
@@ -69,6 +77,20 @@ module Steep
|
|
69
77
|
end
|
70
78
|
end
|
71
79
|
|
80
|
+
def call_of(node:)
|
81
|
+
call = method_calls[node]
|
82
|
+
|
83
|
+
if call
|
84
|
+
call
|
85
|
+
else
|
86
|
+
if parent
|
87
|
+
parent.call_of(node: node)
|
88
|
+
else
|
89
|
+
raise UnknownNodeError.new(:call, node: node)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
72
94
|
def add_context_for_node(node, context:)
|
73
95
|
begin_pos = node.loc.expression.begin_pos
|
74
96
|
end_pos = node.loc.expression.end_pos
|
@@ -76,6 +98,18 @@ module Steep
|
|
76
98
|
add_context(begin_pos..end_pos, context: context)
|
77
99
|
end
|
78
100
|
|
101
|
+
def block_range(node)
|
102
|
+
send_node, args_node, _ = node.children
|
103
|
+
begin_pos = if send_node.type != :lambda && args_node.loc.expression
|
104
|
+
args_node.loc.expression.end_pos
|
105
|
+
else
|
106
|
+
node.loc.begin.end_pos
|
107
|
+
end
|
108
|
+
end_pos = node.loc.end.begin_pos
|
109
|
+
|
110
|
+
begin_pos..end_pos
|
111
|
+
end
|
112
|
+
|
79
113
|
def add_context_for_body(node, context:)
|
80
114
|
case node.type
|
81
115
|
when :class
|
@@ -117,14 +151,8 @@ module Steep
|
|
117
151
|
add_context(body_begin_pos..body_end_pos, context: context)
|
118
152
|
|
119
153
|
when :block
|
120
|
-
|
121
|
-
|
122
|
-
args_node.loc.expression.end_pos
|
123
|
-
else
|
124
|
-
node.loc.begin.end_pos
|
125
|
-
end
|
126
|
-
end_pos = node.loc.end.begin_pos
|
127
|
-
add_context(begin_pos..end_pos, context: context)
|
154
|
+
range = block_range(node)
|
155
|
+
add_context(range, context: context)
|
128
156
|
|
129
157
|
when :for
|
130
158
|
_, collection, _ = node.children
|
@@ -191,6 +219,8 @@ module Steep
|
|
191
219
|
|
192
220
|
parent.contexts.merge(contexts)
|
193
221
|
|
222
|
+
parent.method_calls.merge!(method_calls)
|
223
|
+
|
194
224
|
errors.each do |error|
|
195
225
|
parent.add_error error
|
196
226
|
end
|
data/lib/steep/version.rb
CHANGED
data/steep.gemspec
CHANGED
@@ -34,5 +34,5 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.add_runtime_dependency "rainbow", ">= 2.2.2", "< 4.0"
|
35
35
|
spec.add_runtime_dependency "listen", "~> 3.0"
|
36
36
|
spec.add_runtime_dependency "language_server-protocol", "~> 3.15.0.1"
|
37
|
-
spec.add_runtime_dependency "rbs", "~> 0.
|
37
|
+
spec.add_runtime_dependency "rbs", "~> 0.17.0"
|
38
38
|
end
|
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: 0.
|
4
|
+
version: 0.35.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Soutaro Matsumoto
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -106,14 +106,14 @@ dependencies:
|
|
106
106
|
requirements:
|
107
107
|
- - "~>"
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
version: 0.
|
109
|
+
version: 0.17.0
|
110
110
|
type: :runtime
|
111
111
|
prerelease: false
|
112
112
|
version_requirements: !ruby/object:Gem::Requirement
|
113
113
|
requirements:
|
114
114
|
- - "~>"
|
115
115
|
- !ruby/object:Gem::Version
|
116
|
-
version: 0.
|
116
|
+
version: 0.17.0
|
117
117
|
description: Gradual Typing for Ruby
|
118
118
|
email:
|
119
119
|
- matsumoto@soutaro.com
|
@@ -140,9 +140,7 @@ files:
|
|
140
140
|
- lib/steep/annotation_parser.rb
|
141
141
|
- lib/steep/ast/annotation.rb
|
142
142
|
- lib/steep/ast/annotation/collection.rb
|
143
|
-
- lib/steep/ast/buffer.rb
|
144
143
|
- lib/steep/ast/builtin.rb
|
145
|
-
- lib/steep/ast/location.rb
|
146
144
|
- lib/steep/ast/type_params.rb
|
147
145
|
- lib/steep/ast/types.rb
|
148
146
|
- lib/steep/ast/types/any.rb
|
@@ -172,6 +170,7 @@ files:
|
|
172
170
|
- lib/steep/drivers/langserver.rb
|
173
171
|
- lib/steep/drivers/print_project.rb
|
174
172
|
- lib/steep/drivers/signature_error_printer.rb
|
173
|
+
- lib/steep/drivers/stats.rb
|
175
174
|
- lib/steep/drivers/trace_printer.rb
|
176
175
|
- lib/steep/drivers/utils/driver_helper.rb
|
177
176
|
- lib/steep/drivers/validate.rb
|
@@ -183,6 +182,7 @@ files:
|
|
183
182
|
- lib/steep/interface/method.rb
|
184
183
|
- lib/steep/interface/method_type.rb
|
185
184
|
- lib/steep/interface/substitution.rb
|
185
|
+
- lib/steep/method_name.rb
|
186
186
|
- lib/steep/module_helper.rb
|
187
187
|
- lib/steep/project.rb
|
188
188
|
- lib/steep/project/completion_provider.rb
|
@@ -219,6 +219,7 @@ files:
|
|
219
219
|
- lib/steep/type_inference/local_variable_type_env.rb
|
220
220
|
- lib/steep/type_inference/logic.rb
|
221
221
|
- lib/steep/type_inference/logic_type_interpreter.rb
|
222
|
+
- lib/steep/type_inference/method_call.rb
|
222
223
|
- lib/steep/type_inference/send_args.rb
|
223
224
|
- lib/steep/type_inference/type_env.rb
|
224
225
|
- lib/steep/typing.rb
|
@@ -331,9 +332,12 @@ files:
|
|
331
332
|
- smoke/regexp/b.rb
|
332
333
|
- smoke/regression/Steepfile
|
333
334
|
- smoke/regression/array.rb
|
335
|
+
- smoke/regression/fun.rb
|
336
|
+
- smoke/regression/fun.rbs
|
334
337
|
- smoke/regression/hash.rb
|
335
338
|
- smoke/regression/poly_new.rb
|
336
339
|
- smoke/regression/poly_new.rbs
|
340
|
+
- smoke/regression/range.rb
|
337
341
|
- smoke/regression/set_divide.rb
|
338
342
|
- smoke/rescue/Steepfile
|
339
343
|
- smoke/rescue/a.rb
|
data/lib/steep/ast/buffer.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
module Steep
|
2
|
-
module AST
|
3
|
-
class Buffer
|
4
|
-
attr_reader :name
|
5
|
-
attr_reader :content
|
6
|
-
attr_reader :lines
|
7
|
-
attr_reader :ranges
|
8
|
-
|
9
|
-
def initialize(name:, content:)
|
10
|
-
@name = name
|
11
|
-
@content = content
|
12
|
-
|
13
|
-
@lines = content.split(/\n/, -1)
|
14
|
-
|
15
|
-
@ranges = []
|
16
|
-
offset = 0
|
17
|
-
lines.each.with_index do |line, index|
|
18
|
-
if index == lines.size - 1
|
19
|
-
ranges << (offset..offset)
|
20
|
-
else
|
21
|
-
size = line.size
|
22
|
-
range = offset..(offset+size)
|
23
|
-
ranges << range
|
24
|
-
offset += size+1
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def pos_to_loc(pos)
|
30
|
-
index = ranges.bsearch_index do |range|
|
31
|
-
pos <= range.end
|
32
|
-
end
|
33
|
-
|
34
|
-
if index
|
35
|
-
[index + 1, pos - ranges[index].begin]
|
36
|
-
else
|
37
|
-
[1, pos]
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def loc_to_pos(loc)
|
42
|
-
line, column = loc
|
43
|
-
ranges[line - 1].begin + column
|
44
|
-
end
|
45
|
-
|
46
|
-
def source(range)
|
47
|
-
content[range]
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|