steep 0.23.0 → 0.29.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 +46 -0
- data/bin/smoke_runner.rb +3 -4
- data/lib/steep.rb +4 -3
- data/lib/steep/annotation_parser.rb +2 -4
- data/lib/steep/ast/builtin.rb +11 -21
- data/lib/steep/ast/types.rb +5 -3
- data/lib/steep/ast/types/any.rb +1 -3
- data/lib/steep/ast/types/boolean.rb +1 -3
- data/lib/steep/ast/types/bot.rb +1 -3
- data/lib/steep/ast/types/class.rb +2 -2
- data/lib/steep/ast/types/factory.rb +249 -89
- data/lib/steep/ast/types/helper.rb +6 -0
- data/lib/steep/ast/types/instance.rb +2 -2
- data/lib/steep/ast/types/intersection.rb +20 -13
- data/lib/steep/ast/types/literal.rb +1 -3
- data/lib/steep/ast/types/logic.rb +63 -0
- data/lib/steep/ast/types/name.rb +15 -67
- data/lib/steep/ast/types/nil.rb +1 -3
- data/lib/steep/ast/types/proc.rb +5 -2
- data/lib/steep/ast/types/record.rb +9 -4
- data/lib/steep/ast/types/self.rb +1 -1
- data/lib/steep/ast/types/top.rb +1 -3
- data/lib/steep/ast/types/tuple.rb +5 -3
- data/lib/steep/ast/types/union.rb +16 -9
- data/lib/steep/ast/types/var.rb +2 -2
- data/lib/steep/ast/types/void.rb +1 -3
- data/lib/steep/drivers/check.rb +4 -0
- data/lib/steep/errors.rb +14 -0
- data/lib/steep/interface/interface.rb +5 -62
- data/lib/steep/interface/method_type.rb +394 -93
- data/lib/steep/interface/substitution.rb +48 -6
- data/lib/steep/module_helper.rb +25 -0
- data/lib/steep/project/completion_provider.rb +48 -51
- data/lib/steep/project/file.rb +3 -3
- data/lib/steep/project/hover_content.rb +4 -6
- data/lib/steep/project/target.rb +5 -2
- data/lib/steep/server/base_worker.rb +5 -3
- data/lib/steep/server/code_worker.rb +2 -0
- data/lib/steep/server/master.rb +10 -1
- data/lib/steep/signature/validator.rb +3 -3
- data/lib/steep/source.rb +4 -3
- data/lib/steep/subtyping/check.rb +46 -59
- data/lib/steep/subtyping/constraints.rb +8 -0
- data/lib/steep/type_construction.rb +771 -513
- data/lib/steep/type_inference/block_params.rb +5 -0
- data/lib/steep/type_inference/constant_env.rb +3 -6
- data/lib/steep/type_inference/context.rb +8 -0
- data/lib/steep/type_inference/context_array.rb +4 -3
- data/lib/steep/type_inference/logic.rb +31 -0
- data/lib/steep/type_inference/logic_type_interpreter.rb +219 -0
- data/lib/steep/type_inference/type_env.rb +2 -2
- data/lib/steep/typing.rb +7 -0
- data/lib/steep/version.rb +1 -1
- data/smoke/alias/a.rb +1 -1
- data/smoke/case/a.rb +1 -1
- data/smoke/hash/d.rb +1 -1
- data/smoke/if/a.rb +1 -1
- data/smoke/module/a.rb +1 -1
- data/smoke/rescue/a.rb +4 -13
- data/smoke/type_case/a.rb +0 -7
- data/steep.gemspec +2 -2
- metadata +10 -10
- data/lib/steep/ast/method_type.rb +0 -126
- data/lib/steep/ast/namespace.rb +0 -80
- data/lib/steep/names.rb +0 -86
@@ -26,7 +26,32 @@ module Steep
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.empty
|
29
|
-
new(dictionary: {},
|
29
|
+
new(dictionary: {},
|
30
|
+
instance_type: INSTANCE_TYPE,
|
31
|
+
module_type: CLASS_TYPE,
|
32
|
+
self_type: SELF_TYPE)
|
33
|
+
end
|
34
|
+
|
35
|
+
def empty?
|
36
|
+
dictionary.empty? &&
|
37
|
+
instance_type.is_a?(AST::Types::Instance) &&
|
38
|
+
module_type.is_a?(AST::Types::Class) &&
|
39
|
+
self_type.is_a?(AST::Types::Self)
|
40
|
+
end
|
41
|
+
|
42
|
+
INSTANCE_TYPE = AST::Types::Instance.new
|
43
|
+
CLASS_TYPE = AST::Types::Class.new
|
44
|
+
SELF_TYPE = AST::Types::Self.new
|
45
|
+
|
46
|
+
def domain
|
47
|
+
set = Set.new
|
48
|
+
|
49
|
+
set.merge(dictionary.keys)
|
50
|
+
set << INSTANCE_TYPE unless instance_type.is_a?(AST::Types::Instance)
|
51
|
+
set << CLASS_TYPE unless instance_type.is_a?(AST::Types::Class)
|
52
|
+
set << SELF_TYPE unless instance_type.is_a?(AST::Types::Self)
|
53
|
+
|
54
|
+
set
|
30
55
|
end
|
31
56
|
|
32
57
|
def to_s
|
@@ -65,22 +90,39 @@ module Steep
|
|
65
90
|
|
66
91
|
def except(vars)
|
67
92
|
self.class.new(
|
68
|
-
dictionary: dictionary
|
93
|
+
dictionary: dictionary,
|
69
94
|
instance_type: instance_type,
|
70
95
|
module_type: module_type,
|
71
96
|
self_type: self_type
|
72
|
-
)
|
97
|
+
).except!(vars)
|
73
98
|
end
|
74
99
|
|
75
|
-
def
|
100
|
+
def except!(vars)
|
101
|
+
vars.each do |var|
|
102
|
+
dictionary.delete(var)
|
103
|
+
end
|
104
|
+
|
105
|
+
self
|
106
|
+
end
|
107
|
+
|
108
|
+
def merge!(s, overwrite: false)
|
76
109
|
dictionary.transform_values! {|ty| ty.subst(s) }
|
77
110
|
dictionary.merge!(s.dictionary) do |key, a, b|
|
78
111
|
if a == b
|
79
112
|
a
|
80
113
|
else
|
81
|
-
|
114
|
+
if overwrite
|
115
|
+
b
|
116
|
+
else
|
117
|
+
raise "Duplicated key on merge!: #{key}, #{a}, #{b} (#{self})"
|
118
|
+
end
|
82
119
|
end
|
83
120
|
end
|
121
|
+
|
122
|
+
@instance_type = instance_type.subst(s)
|
123
|
+
@module_type = module_type.subst(s)
|
124
|
+
@self_type = self_type.subst(s)
|
125
|
+
|
84
126
|
self
|
85
127
|
end
|
86
128
|
|
@@ -92,7 +134,7 @@ module Steep
|
|
92
134
|
end
|
93
135
|
|
94
136
|
def add!(v, ty)
|
95
|
-
merge!(Substitution.new(dictionary: { v => ty }, instance_type:
|
137
|
+
merge!(Substitution.new(dictionary: { v => ty }, instance_type: instance_type, module_type: module_type, self_type: self_type))
|
96
138
|
end
|
97
139
|
end
|
98
140
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Steep
|
2
|
+
module ModuleHelper
|
3
|
+
def module_name_from_node(node)
|
4
|
+
case node.type
|
5
|
+
when :const, :casgn
|
6
|
+
namespace = namespace_from_node(node.children[0]) or return
|
7
|
+
name = node.children[1]
|
8
|
+
RBS::TypeName.new(name: name, namespace: namespace)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def namespace_from_node(node)
|
13
|
+
case node&.type
|
14
|
+
when nil
|
15
|
+
RBS::Namespace.empty
|
16
|
+
when :cbase
|
17
|
+
RBS::Namespace.root
|
18
|
+
when :const
|
19
|
+
namespace_from_node(node.children[0])&.yield_self do |parent|
|
20
|
+
parent.append(node.children[1])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -10,13 +10,9 @@ module Steep
|
|
10
10
|
|
11
11
|
InstanceVariableItem = Struct.new(:identifier, :range, :type, keyword_init: true)
|
12
12
|
LocalVariableItem = Struct.new(:identifier, :range, :type, keyword_init: true)
|
13
|
-
MethodNameItem = Struct.new(:identifier, :range, :
|
14
|
-
def method_type
|
15
|
-
def_type.type
|
16
|
-
end
|
17
|
-
|
13
|
+
MethodNameItem = Struct.new(:identifier, :range, :method_def, :method_type, :inherited_method, keyword_init: true) do
|
18
14
|
def comment
|
19
|
-
|
15
|
+
method_def&.comment
|
20
16
|
end
|
21
17
|
end
|
22
18
|
|
@@ -90,7 +86,9 @@ module Steep
|
|
90
86
|
end
|
91
87
|
|
92
88
|
def at_end?(pos, of:)
|
93
|
-
|
89
|
+
if of
|
90
|
+
of.last_line == pos.line && of.last_column == pos.column
|
91
|
+
end
|
94
92
|
end
|
95
93
|
|
96
94
|
def range_for(position, prefix: "")
|
@@ -194,21 +192,25 @@ module Steep
|
|
194
192
|
return [] unless node
|
195
193
|
|
196
194
|
if at_end?(shift_pos, of: node.loc)
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
195
|
+
begin
|
196
|
+
context = typing.context_at(line: position.line, column: position.column)
|
197
|
+
receiver_type = case (type = typing.type_of(node: node))
|
198
|
+
when AST::Types::Self
|
199
|
+
context.self_type
|
200
|
+
else
|
201
|
+
type
|
202
|
+
end
|
203
|
+
|
204
|
+
items = []
|
205
|
+
method_items_for_receiver_type(receiver_type,
|
206
|
+
include_private: false,
|
207
|
+
prefix: "",
|
208
|
+
position: position,
|
209
|
+
items: items)
|
210
|
+
items
|
211
|
+
rescue Typing::UnknownNodeError
|
212
|
+
[]
|
213
|
+
end
|
212
214
|
else
|
213
215
|
[]
|
214
216
|
end
|
@@ -230,37 +232,27 @@ module Steep
|
|
230
232
|
|
231
233
|
def method_items_for_receiver_type(type, include_private:, prefix:, position:, items:)
|
232
234
|
range = range_for(position, prefix: prefix)
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
if include_private || method.public?
|
250
|
-
if name.to_s.start_with?(prefix)
|
251
|
-
if word_name?(name.to_s)
|
252
|
-
method.defs.each do |def_type|
|
253
|
-
items << MethodNameItem.new(identifier: name,
|
254
|
-
range: range,
|
255
|
-
definition: method,
|
256
|
-
def_type: def_type,
|
257
|
-
inherited_method: inherited_method?(method, definition))
|
258
|
-
end
|
259
|
-
end
|
235
|
+
interface = subtyping.factory.interface(type, self_type: type, private: include_private)
|
236
|
+
|
237
|
+
interface.methods.each do |name, method_entry|
|
238
|
+
next if disallowed_method?(name)
|
239
|
+
|
240
|
+
if name.to_s.start_with?(prefix)
|
241
|
+
if word_name?(name.to_s)
|
242
|
+
method_entry.method_types.each do |method_type|
|
243
|
+
items << MethodNameItem.new(
|
244
|
+
identifier: name,
|
245
|
+
range: range,
|
246
|
+
method_def: method_type.method_def,
|
247
|
+
method_type: method_type.method_def&.type || subtyping.factory.method_type_1(method_type, self_type: type),
|
248
|
+
inherited_method: inherited_method?(method_type.method_def, type)
|
249
|
+
)
|
260
250
|
end
|
261
251
|
end
|
262
252
|
end
|
263
253
|
end
|
254
|
+
rescue
|
255
|
+
# nop
|
264
256
|
end
|
265
257
|
|
266
258
|
def word_name?(name)
|
@@ -304,8 +296,13 @@ module Steep
|
|
304
296
|
index
|
305
297
|
end
|
306
298
|
|
307
|
-
def inherited_method?(
|
308
|
-
|
299
|
+
def inherited_method?(method_def, type)
|
300
|
+
case type
|
301
|
+
when AST::Types::Name::Instance, AST::Types::Name::Singleton, AST::Types::Name::Interface
|
302
|
+
method_def.implemented_in != type.name
|
303
|
+
else
|
304
|
+
false
|
305
|
+
end
|
309
306
|
end
|
310
307
|
|
311
308
|
def disallowed_method?(name)
|
data/lib/steep/project/file.rb
CHANGED
@@ -41,8 +41,8 @@ module Steep
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def self.type_check(source, subtyping:)
|
44
|
-
annotations = source.annotations(block: source.node, factory: subtyping.factory, current_module:
|
45
|
-
const_env = TypeInference::ConstantEnv.new(factory: subtyping.factory, context: [
|
44
|
+
annotations = source.annotations(block: source.node, factory: subtyping.factory, current_module: RBS::Namespace.root)
|
45
|
+
const_env = TypeInference::ConstantEnv.new(factory: subtyping.factory, context: [RBS::Namespace.root])
|
46
46
|
type_env = TypeInference::TypeEnv.build(annotations: annotations,
|
47
47
|
subtyping: subtyping,
|
48
48
|
const_env: const_env,
|
@@ -58,7 +58,7 @@ module Steep
|
|
58
58
|
instance_type: nil,
|
59
59
|
module_type: nil,
|
60
60
|
implement_name: nil,
|
61
|
-
current_namespace:
|
61
|
+
current_namespace: RBS::Namespace.root,
|
62
62
|
const_env: const_env,
|
63
63
|
class_name: nil
|
64
64
|
),
|
@@ -21,9 +21,7 @@ module Steep
|
|
21
21
|
@project = project
|
22
22
|
end
|
23
23
|
|
24
|
-
def method_definition_for(factory,
|
25
|
-
type_name = factory.type_name_1(module_name)
|
26
|
-
|
24
|
+
def method_definition_for(factory, type_name, singleton_method: nil, instance_method: nil)
|
27
25
|
case
|
28
26
|
when instance_method
|
29
27
|
factory.definition_builder.build_instance(type_name).methods[instance_method]
|
@@ -86,16 +84,16 @@ module Steep
|
|
86
84
|
when AST::Types::Name::Instance
|
87
85
|
method_definition = method_definition_for(factory, receiver_type.name, instance_method: method_name)
|
88
86
|
if method_definition&.defined_in
|
89
|
-
owner_name =
|
87
|
+
owner_name = method_definition.defined_in
|
90
88
|
[
|
91
89
|
InstanceMethodName.new(owner_name, method_name),
|
92
90
|
method_definition
|
93
91
|
]
|
94
92
|
end
|
95
|
-
when AST::Types::Name::
|
93
|
+
when AST::Types::Name::Singleton
|
96
94
|
method_definition = method_definition_for(factory, receiver_type.name, singleton_method: method_name)
|
97
95
|
if method_definition&.defined_in
|
98
|
-
owner_name =
|
96
|
+
owner_name = method_definition.defined_in
|
99
97
|
[
|
100
98
|
SingletonMethodName.new(owner_name, method_name),
|
101
99
|
method_definition
|
data/lib/steep/project/target.rb
CHANGED
@@ -172,6 +172,7 @@ module Steep
|
|
172
172
|
timestamp: Time.now
|
173
173
|
)
|
174
174
|
rescue => exn
|
175
|
+
Steep.log_error exn
|
175
176
|
@status = SignatureOtherErrorStatus.new(error: exn, timestamp: Time.now)
|
176
177
|
end
|
177
178
|
end
|
@@ -194,8 +195,10 @@ module Steep
|
|
194
195
|
type_check_sources = []
|
195
196
|
|
196
197
|
target_sources.each do |file|
|
197
|
-
|
198
|
-
|
198
|
+
Steep.logger.tagged("path=#{file.path}") do
|
199
|
+
if file.type_check(check, timestamp)
|
200
|
+
type_check_sources << file
|
201
|
+
end
|
199
202
|
end
|
200
203
|
end
|
201
204
|
|
@@ -12,6 +12,7 @@ module Steep
|
|
12
12
|
@project = project
|
13
13
|
@reader = reader
|
14
14
|
@writer = writer
|
15
|
+
@shutdown = false
|
15
16
|
end
|
16
17
|
|
17
18
|
def handle_request(request)
|
@@ -28,7 +29,7 @@ module Steep
|
|
28
29
|
Steep.logger.formatter.push_tags(*tags)
|
29
30
|
Steep.logger.tagged "background" do
|
30
31
|
while job = queue.pop
|
31
|
-
handle_job(job)
|
32
|
+
handle_job(job) unless @shutdown
|
32
33
|
end
|
33
34
|
end
|
34
35
|
end
|
@@ -38,11 +39,12 @@ module Steep
|
|
38
39
|
reader.read do |request|
|
39
40
|
case request[:method]
|
40
41
|
when "shutdown"
|
41
|
-
|
42
|
+
@shutdown = true
|
43
|
+
writer.write(id: request[:id], result: nil)
|
42
44
|
when "exit"
|
43
45
|
break
|
44
46
|
else
|
45
|
-
handle_request(request)
|
47
|
+
handle_request(request) unless @shutdown
|
46
48
|
end
|
47
49
|
end
|
48
50
|
ensure
|
data/lib/steep/server/master.rb
CHANGED
@@ -23,6 +23,7 @@ module Steep
|
|
23
23
|
@signature_worker = signature_worker
|
24
24
|
@code_workers = code_workers
|
25
25
|
@worker_to_paths = {}
|
26
|
+
@shutdown_request_id = nil
|
26
27
|
end
|
27
28
|
|
28
29
|
def start
|
@@ -59,7 +60,14 @@ module Steep
|
|
59
60
|
end
|
60
61
|
|
61
62
|
while job = queue.pop
|
62
|
-
|
63
|
+
if @shutdown_request_id
|
64
|
+
if job[:id] == @shutdown_request_id
|
65
|
+
writer.write(job)
|
66
|
+
break
|
67
|
+
end
|
68
|
+
else
|
69
|
+
writer.write(job)
|
70
|
+
end
|
63
71
|
end
|
64
72
|
|
65
73
|
writer.io.close
|
@@ -154,6 +162,7 @@ module Steep
|
|
154
162
|
|
155
163
|
when "shutdown"
|
156
164
|
queue << { id: id, result: nil }
|
165
|
+
@shutdown_request_id = id
|
157
166
|
|
158
167
|
when "exit"
|
159
168
|
queue << nil
|
@@ -130,19 +130,19 @@ module Steep
|
|
130
130
|
yield
|
131
131
|
rescue RBS::InvalidTypeApplicationError => exn
|
132
132
|
@errors << Errors::InvalidTypeApplicationError.new(
|
133
|
-
name:
|
133
|
+
name: exn.type_name,
|
134
134
|
args: exn.args.map {|ty| factory.type(ty) },
|
135
135
|
params: exn.params,
|
136
136
|
location: exn.location
|
137
137
|
)
|
138
138
|
rescue RBS::NoTypeFoundError, RBS::NoSuperclassFoundError, RBS::NoMixinFoundError => exn
|
139
139
|
@errors << Errors::UnknownTypeNameError.new(
|
140
|
-
name:
|
140
|
+
name: exn.type_name,
|
141
141
|
location: exn.location
|
142
142
|
)
|
143
143
|
rescue RBS::InvalidOverloadMethodError => exn
|
144
144
|
@errors << Errors::InvalidMethodOverloadError.new(
|
145
|
-
class_name:
|
145
|
+
class_name: exn.type_name,
|
146
146
|
method_name: exn.method_name,
|
147
147
|
location: exn.members[0].location
|
148
148
|
)
|
data/lib/steep/source.rb
CHANGED
@@ -38,7 +38,7 @@ module Steep
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def self.parser
|
41
|
-
::Parser::
|
41
|
+
::Parser::Ruby27.new(Builder.new).tap do |parser|
|
42
42
|
parser.diagnostics.all_errors_are_fatal = true
|
43
43
|
parser.diagnostics.ignore_warnings = true
|
44
44
|
end
|
@@ -60,7 +60,7 @@ module Steep
|
|
60
60
|
_, comments, _ = yield_self do
|
61
61
|
buffer = ::Parser::Source::Buffer.new(path.to_s)
|
62
62
|
buffer.source = source_code
|
63
|
-
parser = ::Parser::
|
63
|
+
parser = ::Parser::Ruby27.new
|
64
64
|
|
65
65
|
parser.tokenize(buffer)
|
66
66
|
end
|
@@ -79,6 +79,7 @@ module Steep
|
|
79
79
|
end
|
80
80
|
|
81
81
|
mapping = {}
|
82
|
+
|
82
83
|
construct_mapping(node: node, annotations: annotations, mapping: mapping)
|
83
84
|
|
84
85
|
annotations.each do |annot|
|
@@ -185,7 +186,7 @@ module Steep
|
|
185
186
|
construct_mapping(node: node.children[0], annotations: annotations, mapping: mapping, line_range: nil)
|
186
187
|
end
|
187
188
|
|
188
|
-
if node.
|
189
|
+
if node.children.last
|
189
190
|
else_node = node.children.last
|
190
191
|
else_start = node.loc.else.last_line
|
191
192
|
else_end = node.loc.end.line
|