steep 0.33.0 → 0.34.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/steep.rb +3 -0
- data/lib/steep/annotation_parser.rb +1 -1
- data/lib/steep/ast/types/factory.rb +63 -57
- data/lib/steep/cli.rb +14 -1
- data/lib/steep/drivers/stats.rb +85 -0
- 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/source_file.rb +2 -1
- data/lib/steep/server/interaction_worker.rb +1 -1
- data/lib/steep/subtyping/variable_occurrence.rb +2 -0
- data/lib/steep/type_construction.rb +577 -415
- 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/method_call.rb +116 -0
- data/lib/steep/typing.rb +38 -8
- data/lib/steep/version.rb +1 -1
- data/smoke/regression/range.rb +5 -0
- data/steep.gemspec +1 -1
- metadata +8 -4
@@ -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.14.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.34.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-10-27 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.14.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.14.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
|
@@ -181,6 +182,7 @@ files:
|
|
181
182
|
- lib/steep/interface/method.rb
|
182
183
|
- lib/steep/interface/method_type.rb
|
183
184
|
- lib/steep/interface/substitution.rb
|
185
|
+
- lib/steep/method_name.rb
|
184
186
|
- lib/steep/module_helper.rb
|
185
187
|
- lib/steep/project.rb
|
186
188
|
- lib/steep/project/completion_provider.rb
|
@@ -217,6 +219,7 @@ files:
|
|
217
219
|
- lib/steep/type_inference/local_variable_type_env.rb
|
218
220
|
- lib/steep/type_inference/logic.rb
|
219
221
|
- lib/steep/type_inference/logic_type_interpreter.rb
|
222
|
+
- lib/steep/type_inference/method_call.rb
|
220
223
|
- lib/steep/type_inference/send_args.rb
|
221
224
|
- lib/steep/type_inference/type_env.rb
|
222
225
|
- lib/steep/typing.rb
|
@@ -334,6 +337,7 @@ files:
|
|
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
|