steep 0.33.0 → 0.38.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 +28 -0
- data/lib/steep.rb +9 -0
- data/lib/steep/annotation_parser.rb +1 -1
- data/lib/steep/ast/types/factory.rb +167 -102
- data/lib/steep/ast/types/logic.rb +20 -1
- data/lib/steep/ast/types/proc.rb +32 -20
- 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 +38 -15
- data/lib/steep/index/rbs_index.rb +334 -0
- data/lib/steep/index/signature_symbol_provider.rb +154 -0
- data/lib/steep/index/source_index.rb +100 -0
- data/lib/steep/interface/block.rb +79 -0
- data/lib/steep/interface/function.rb +770 -0
- data/lib/steep/interface/method_type.rb +41 -832
- 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/master.rb +5 -1
- data/lib/steep/server/signature_worker.rb +63 -6
- data/lib/steep/subtyping/check.rb +70 -32
- data/lib/steep/subtyping/variable_occurrence.rb +4 -2
- data/lib/steep/subtyping/variable_variance.rb +2 -2
- data/lib/steep/type_construction.rb +780 -495
- data/lib/steep/type_inference/block_params.rb +1 -1
- data/lib/steep/type_inference/constant_env.rb +5 -1
- data/lib/steep/type_inference/context.rb +7 -3
- data/lib/steep/type_inference/local_variable_type_env.rb +10 -1
- data/lib/steep/type_inference/logic_type_interpreter.rb +3 -0
- data/lib/steep/type_inference/method_call.rb +116 -0
- data/lib/steep/typing.rb +46 -10
- data/lib/steep/version.rb +1 -1
- data/smoke/regression/range.rb +5 -0
- data/smoke/tsort/Steepfile +6 -0
- data/smoke/tsort/a.rb +15 -0
- data/steep.gemspec +1 -1
- metadata +17 -6
@@ -15,9 +15,13 @@ module Steep
|
|
15
15
|
@table = RBS::ConstantTable.new(builder: factory.definition_builder)
|
16
16
|
end
|
17
17
|
|
18
|
+
def lookup_constant(name)
|
19
|
+
table.resolve_constant_reference(name, context: context)
|
20
|
+
end
|
21
|
+
|
18
22
|
def lookup(name)
|
19
23
|
cache[name] ||= begin
|
20
|
-
constant =
|
24
|
+
constant = lookup_constant(name)
|
21
25
|
|
22
26
|
if constant
|
23
27
|
factory.type(constant.type)
|
@@ -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,8 +20,10 @@ module Steep
|
|
20
20
|
attr_reader :should_update
|
21
21
|
attr_reader :contexts
|
22
22
|
attr_reader :root_context
|
23
|
+
attr_reader :method_calls
|
24
|
+
attr_reader :source_index
|
23
25
|
|
24
|
-
def initialize(source:, root_context:, parent: nil, parent_last_update: parent&.last_update, contexts: nil)
|
26
|
+
def initialize(source:, root_context:, parent: nil, parent_last_update: parent&.last_update, contexts: nil, source_index: nil)
|
25
27
|
@source = source
|
26
28
|
|
27
29
|
@parent = parent
|
@@ -33,6 +35,9 @@ module Steep
|
|
33
35
|
@typing = {}.compare_by_identity
|
34
36
|
@root_context = root_context
|
35
37
|
@contexts = contexts || TypeInference::ContextArray.from_source(source: source)
|
38
|
+
@method_calls = {}.compare_by_identity
|
39
|
+
|
40
|
+
@source_index = source_index || Index::SourceIndex.new(source: source)
|
36
41
|
end
|
37
42
|
|
38
43
|
def add_error(error)
|
@@ -46,6 +51,12 @@ module Steep
|
|
46
51
|
type
|
47
52
|
end
|
48
53
|
|
54
|
+
def add_call(node, call)
|
55
|
+
method_calls[node] = call
|
56
|
+
|
57
|
+
call
|
58
|
+
end
|
59
|
+
|
49
60
|
def add_context(range, context:)
|
50
61
|
contexts.insert_context(range, context: context)
|
51
62
|
@last_update += 1
|
@@ -69,6 +80,20 @@ module Steep
|
|
69
80
|
end
|
70
81
|
end
|
71
82
|
|
83
|
+
def call_of(node:)
|
84
|
+
call = method_calls[node]
|
85
|
+
|
86
|
+
if call
|
87
|
+
call
|
88
|
+
else
|
89
|
+
if parent
|
90
|
+
parent.call_of(node: node)
|
91
|
+
else
|
92
|
+
raise UnknownNodeError.new(:call, node: node)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
72
97
|
def add_context_for_node(node, context:)
|
73
98
|
begin_pos = node.loc.expression.begin_pos
|
74
99
|
end_pos = node.loc.expression.end_pos
|
@@ -76,6 +101,18 @@ module Steep
|
|
76
101
|
add_context(begin_pos..end_pos, context: context)
|
77
102
|
end
|
78
103
|
|
104
|
+
def block_range(node)
|
105
|
+
send_node, args_node, _ = node.children
|
106
|
+
begin_pos = if send_node.type != :lambda && args_node.loc.expression
|
107
|
+
args_node.loc.expression.end_pos
|
108
|
+
else
|
109
|
+
node.loc.begin.end_pos
|
110
|
+
end
|
111
|
+
end_pos = node.loc.end.begin_pos
|
112
|
+
|
113
|
+
begin_pos..end_pos
|
114
|
+
end
|
115
|
+
|
79
116
|
def add_context_for_body(node, context:)
|
80
117
|
case node.type
|
81
118
|
when :class
|
@@ -117,14 +154,8 @@ module Steep
|
|
117
154
|
add_context(body_begin_pos..body_end_pos, context: context)
|
118
155
|
|
119
156
|
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)
|
157
|
+
range = block_range(node)
|
158
|
+
add_context(range, context: context)
|
128
159
|
|
129
160
|
when :for
|
130
161
|
_, collection, _ = node.children
|
@@ -167,7 +198,8 @@ module Steep
|
|
167
198
|
child = self.class.new(source: source,
|
168
199
|
parent: self,
|
169
200
|
root_context: root_context,
|
170
|
-
contexts: TypeInference::ContextArray.new(buffer: contexts.buffer, range: range, context: nil)
|
201
|
+
contexts: TypeInference::ContextArray.new(buffer: contexts.buffer, range: range, context: nil),
|
202
|
+
source_index: source_index.new_child)
|
171
203
|
@should_update = true
|
172
204
|
|
173
205
|
if block_given?
|
@@ -191,9 +223,13 @@ module Steep
|
|
191
223
|
|
192
224
|
parent.contexts.merge(contexts)
|
193
225
|
|
226
|
+
parent.method_calls.merge!(method_calls)
|
227
|
+
|
194
228
|
errors.each do |error|
|
195
229
|
parent.add_error error
|
196
230
|
end
|
231
|
+
|
232
|
+
parent.source_index.merge!(source_index)
|
197
233
|
end
|
198
234
|
end
|
199
235
|
end
|
data/lib/steep/version.rb
CHANGED
data/smoke/tsort/a.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# ALLOW FAILURE
|
2
|
+
|
3
|
+
require "tsort"
|
4
|
+
|
5
|
+
# @type var g: Hash[Integer, Array[Integer]]
|
6
|
+
g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
|
7
|
+
|
8
|
+
# @type var each_node: ^() { (Integer) -> void } -> void
|
9
|
+
each_node = -> (&b) { g.each_key(&b) }
|
10
|
+
# @type var each_child: ^(Integer) { (Integer) -> void } -> void
|
11
|
+
each_child = -> (n, &b) { g[n].each(&b) }
|
12
|
+
|
13
|
+
# @type var xs: Array[String]
|
14
|
+
# !expects IncompatibleAssignment: lhs_type=::Array[::String], rhs_type=::Array[::Integer]
|
15
|
+
xs = TSort.tsort(each_node, each_child)
|
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", "
|
37
|
+
spec.add_runtime_dependency "rbs", ">= 0.20.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.38.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-10
|
11
|
+
date: 2020-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -104,16 +104,16 @@ dependencies:
|
|
104
104
|
name: rbs
|
105
105
|
requirement: !ruby/object:Gem::Requirement
|
106
106
|
requirements:
|
107
|
-
- - "
|
107
|
+
- - ">="
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
version: 0.
|
109
|
+
version: 0.20.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.20.0
|
117
117
|
description: Gradual Typing for Ruby
|
118
118
|
email:
|
119
119
|
- matsumoto@soutaro.com
|
@@ -170,6 +170,7 @@ files:
|
|
170
170
|
- lib/steep/drivers/langserver.rb
|
171
171
|
- lib/steep/drivers/print_project.rb
|
172
172
|
- lib/steep/drivers/signature_error_printer.rb
|
173
|
+
- lib/steep/drivers/stats.rb
|
173
174
|
- lib/steep/drivers/trace_printer.rb
|
174
175
|
- lib/steep/drivers/utils/driver_helper.rb
|
175
176
|
- lib/steep/drivers/validate.rb
|
@@ -177,10 +178,16 @@ files:
|
|
177
178
|
- lib/steep/drivers/watch.rb
|
178
179
|
- lib/steep/drivers/worker.rb
|
179
180
|
- lib/steep/errors.rb
|
181
|
+
- lib/steep/index/rbs_index.rb
|
182
|
+
- lib/steep/index/signature_symbol_provider.rb
|
183
|
+
- lib/steep/index/source_index.rb
|
184
|
+
- lib/steep/interface/block.rb
|
185
|
+
- lib/steep/interface/function.rb
|
180
186
|
- lib/steep/interface/interface.rb
|
181
187
|
- lib/steep/interface/method.rb
|
182
188
|
- lib/steep/interface/method_type.rb
|
183
189
|
- lib/steep/interface/substitution.rb
|
190
|
+
- lib/steep/method_name.rb
|
184
191
|
- lib/steep/module_helper.rb
|
185
192
|
- lib/steep/project.rb
|
186
193
|
- lib/steep/project/completion_provider.rb
|
@@ -217,6 +224,7 @@ files:
|
|
217
224
|
- lib/steep/type_inference/local_variable_type_env.rb
|
218
225
|
- lib/steep/type_inference/logic.rb
|
219
226
|
- lib/steep/type_inference/logic_type_interpreter.rb
|
227
|
+
- lib/steep/type_inference/method_call.rb
|
220
228
|
- lib/steep/type_inference/send_args.rb
|
221
229
|
- lib/steep/type_inference/type_env.rb
|
222
230
|
- lib/steep/typing.rb
|
@@ -334,6 +342,7 @@ files:
|
|
334
342
|
- smoke/regression/hash.rb
|
335
343
|
- smoke/regression/poly_new.rb
|
336
344
|
- smoke/regression/poly_new.rbs
|
345
|
+
- smoke/regression/range.rb
|
337
346
|
- smoke/regression/set_divide.rb
|
338
347
|
- smoke/rescue/Steepfile
|
339
348
|
- smoke/rescue/a.rb
|
@@ -351,6 +360,8 @@ files:
|
|
351
360
|
- smoke/toplevel/Steepfile
|
352
361
|
- smoke/toplevel/a.rb
|
353
362
|
- smoke/toplevel/a.rbs
|
363
|
+
- smoke/tsort/Steepfile
|
364
|
+
- smoke/tsort/a.rb
|
354
365
|
- smoke/type_case/Steepfile
|
355
366
|
- smoke/type_case/a.rb
|
356
367
|
- smoke/yield/Steepfile
|