steep 1.0.2 → 1.1.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +5 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +22 -3
- data/Gemfile +6 -3
- data/Gemfile.lock +12 -16
- data/Gemfile.steep +3 -0
- data/Gemfile.steep.lock +49 -0
- data/Rakefile +5 -0
- data/Steepfile +6 -1
- data/bin/setup +2 -0
- data/bin/steep +19 -0
- data/lib/steep/ast/types/factory.rb +1 -1
- data/lib/steep/diagnostic/ruby.rb +49 -3
- data/lib/steep/diagnostic/signature.rb +18 -0
- data/lib/steep/drivers/watch.rb +3 -1
- data/lib/steep/method_name.rb +9 -3
- data/lib/steep/node_helper.rb +49 -0
- data/lib/steep/services/completion_provider.rb +22 -15
- data/lib/steep/services/hover_provider/ruby.rb +30 -12
- data/lib/steep/services/type_check_service.rb +12 -12
- data/lib/steep/shims/symbol_start_with.rb +18 -0
- data/lib/steep/signature/validator.rb +19 -0
- data/lib/steep/subtyping/constraints.rb +43 -14
- data/lib/steep/type_construction.rb +666 -746
- data/lib/steep/type_inference/constant_env.rb +0 -2
- data/lib/steep/type_inference/context.rb +23 -17
- data/lib/steep/type_inference/logic_type_interpreter.rb +210 -119
- data/lib/steep/type_inference/method_call.rb +80 -6
- data/lib/steep/type_inference/multiple_assignment.rb +189 -0
- data/lib/steep/type_inference/type_env.rb +271 -120
- data/lib/steep/type_inference/type_env_builder.rb +138 -0
- data/lib/steep/typing.rb +2 -0
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +4 -3
- data/rbs_collection.steep.lock.yaml +112 -0
- data/rbs_collection.steep.yaml +19 -0
- data/sample/sig/conference.rbs +8 -0
- data/sig/shims/parser/source/map.rbs +146 -0
- data/sig/shims/parser/source/range.rbs +237 -0
- data/sig/shims/parser.rbs +17 -0
- data/sig/steep/ast/annotation/collection.rbs +75 -0
- data/sig/steep/ast/annotation.rbs +126 -0
- data/sig/steep/ast/builtin.rbs +69 -0
- data/sig/steep/ast/type_params.rbs +11 -0
- data/sig/steep/ast/types/any.rbs +29 -0
- data/sig/steep/ast/types/boolean.rbs +31 -0
- data/sig/steep/ast/types/bot.rbs +29 -0
- data/sig/steep/ast/types/class.rbs +29 -0
- data/sig/steep/ast/types/factory.rbs +76 -0
- data/sig/steep/ast/types/helper.rbs +19 -0
- data/sig/steep/ast/types/instance.rbs +29 -0
- data/sig/steep/ast/types/intersection.rbs +35 -0
- data/sig/steep/ast/types/literal.rbs +33 -0
- data/sig/steep/ast/types/logic.rbs +78 -0
- data/sig/steep/ast/types/name.rbs +71 -0
- data/sig/steep/ast/types/nil.rbs +31 -0
- data/sig/steep/ast/types/proc.rbs +46 -0
- data/sig/steep/ast/types/record.rbs +38 -0
- data/sig/steep/ast/types/self.rbs +29 -0
- data/sig/steep/ast/types/top.rbs +29 -0
- data/sig/steep/ast/types/tuple.rbs +34 -0
- data/sig/steep/ast/types/union.rbs +38 -0
- data/sig/steep/ast/types/var.rbs +37 -0
- data/sig/steep/ast/types/void.rbs +29 -0
- data/sig/steep/ast/types.rbs +37 -0
- data/sig/steep/diagnostic/deprecated/unknown_constant_assigned.rbs +15 -0
- data/sig/steep/diagnostic/helper.rbs +9 -0
- data/sig/steep/diagnostic/lsp_formatter.rbs +29 -0
- data/sig/steep/diagnostic/ruby.rbs +494 -0
- data/sig/steep/diagnostic/signature.rbs +215 -0
- data/sig/steep/interface/block.rbs +35 -0
- data/sig/steep/interface/function.rbs +253 -0
- data/sig/steep/interface/interface.rbs +23 -0
- data/sig/steep/interface/method_type.rbs +55 -0
- data/sig/steep/interface/substitution.rbs +53 -0
- data/sig/steep/interface/type_param.rbs +35 -0
- data/sig/steep/method_name.rbs +26 -0
- data/sig/steep/module_helper.rbs +7 -0
- data/sig/steep/node_helper.rbs +11 -0
- data/sig/steep/project/dsl.rbs +94 -0
- data/sig/steep/project/options.rbs +15 -0
- data/sig/steep/project/pattern.rbs +25 -0
- data/sig/steep/project/target.rbs +25 -0
- data/sig/steep/project.rbs +19 -0
- data/sig/steep/services/completion_provider.rbs +123 -0
- data/sig/steep/services/content_change.rbs +35 -0
- data/sig/steep/services/file_loader.rbs +13 -0
- data/sig/steep/services/goto_service.rbs +45 -0
- data/sig/steep/services/hover_provider/rbs.rbs +21 -0
- data/sig/steep/services/hover_provider/ruby.rbs +109 -0
- data/sig/steep/services/hover_provider/singleton_methods.rbs +11 -0
- data/sig/steep/services/path_assignment.rbs +21 -0
- data/sig/steep/services/signature_service.rbs +91 -0
- data/sig/steep/services/stats_calculator.rbs +17 -0
- data/sig/steep/services/type_check_service.rbs +93 -0
- data/sig/steep/source.rbs +55 -0
- data/sig/steep/subtyping/cache.rbs +17 -0
- data/sig/steep/subtyping/check.rbs +93 -0
- data/sig/steep/subtyping/constraints.rbs +111 -0
- data/sig/steep/subtyping/relation.rbs +51 -0
- data/sig/steep/subtyping/result.rbs +157 -0
- data/sig/steep/subtyping/variable_variance.rbs +23 -0
- data/sig/steep/type_construction.rbs +285 -0
- data/sig/steep/type_inference/block_params.rbs +52 -0
- data/sig/steep/type_inference/constant_env.rbs +27 -0
- data/sig/steep/type_inference/context.rbs +137 -0
- data/sig/steep/type_inference/logic_type_interpreter.rbs +72 -0
- data/sig/steep/type_inference/method_call.rbs +124 -0
- data/sig/steep/type_inference/method_params.rbs +104 -0
- data/sig/steep/type_inference/multiple_assignment.rbs +76 -0
- data/sig/steep/type_inference/type_env.rbs +158 -0
- data/sig/steep/type_inference/type_env_builder.rbs +77 -0
- data/sig/steep/typing.rbs +68 -0
- data/sig/steep.rbs +31 -0
- data/smoke/class/f.rb +1 -0
- data/smoke/class/test_expectations.yml +2 -2
- data/smoke/diagnostics/test_expectations.yml +4 -2
- metadata +90 -6
- data/lib/steep/type_inference/local_variable_type_env.rb +0 -249
- data/lib/steep/type_inference/logic.rb +0 -161
@@ -2,22 +2,36 @@ module Steep
|
|
2
2
|
module Services
|
3
3
|
module HoverProvider
|
4
4
|
class Ruby
|
5
|
-
TypeContent = Struct.new(:node, :type, :location, keyword_init: true)
|
6
|
-
VariableContent = Struct.new(:node, :name, :type, :location, keyword_init: true)
|
7
|
-
MethodCallContent = Struct.new(:node, :method_call, :location, keyword_init: true)
|
8
|
-
DefinitionContent = Struct.new(:node, :method_name, :method_type, :definition, :location, keyword_init: true)
|
9
|
-
ConstantContent = Struct.new(:location, :full_name, :type, :decl, keyword_init: true) do
|
5
|
+
TypeContent = _ = Struct.new(:node, :type, :location, keyword_init: true)
|
6
|
+
VariableContent = _ = Struct.new(:node, :name, :type, :location, keyword_init: true)
|
7
|
+
MethodCallContent = _ = Struct.new(:node, :method_call, :location, keyword_init: true)
|
8
|
+
DefinitionContent = _ = Struct.new(:node, :method_name, :method_type, :definition, :location, keyword_init: true)
|
9
|
+
ConstantContent = _ = Struct.new(:location, :full_name, :type, :decl, keyword_init: true) do
|
10
|
+
# @implements ConstantContent
|
11
|
+
|
10
12
|
def comments
|
11
13
|
case
|
12
|
-
when
|
13
|
-
decl.decls.
|
14
|
-
when
|
14
|
+
when decl = class_decl
|
15
|
+
decl.decls.map {|d| d.decl.comment }
|
16
|
+
when decl = constant_decl
|
15
17
|
[decl.decl.comment]
|
16
18
|
else
|
17
|
-
|
19
|
+
raise
|
18
20
|
end.compact
|
19
21
|
end
|
20
22
|
|
23
|
+
def class_decl
|
24
|
+
if (decl = decl()).is_a?(::RBS::Environment::MultiEntry)
|
25
|
+
decl
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def constant_decl
|
30
|
+
if (decl = decl()).is_a?(::RBS::Environment::SingleEntry)
|
31
|
+
decl
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
21
35
|
def constant?
|
22
36
|
decl.is_a?(::RBS::Environment::SingleEntry)
|
23
37
|
end
|
@@ -49,6 +63,8 @@ module Steep
|
|
49
63
|
else
|
50
64
|
methods[singleton_method]
|
51
65
|
end
|
66
|
+
else
|
67
|
+
raise "One of the instance_method or singleton_method is required"
|
52
68
|
end
|
53
69
|
end
|
54
70
|
|
@@ -72,6 +88,8 @@ module Steep
|
|
72
88
|
InstanceMethodName.new(type_name: defined_in, method_name: method_name)
|
73
89
|
when builder.build_singleton(defined_in).methods.key?(method_name)
|
74
90
|
SingletonMethodName.new(type_name: defined_in, method_name: method_name)
|
91
|
+
else
|
92
|
+
raise
|
75
93
|
end
|
76
94
|
else
|
77
95
|
InstanceMethodName.new(type_name: defined_in, method_name: method_name)
|
@@ -83,19 +101,19 @@ module Steep
|
|
83
101
|
typing = typecheck(target, path: path, content: file.content, line: line, column: column) or return
|
84
102
|
node, *parents = typing.source.find_nodes(line: line, column: column)
|
85
103
|
|
86
|
-
if node
|
104
|
+
if node && parents
|
87
105
|
case node.type
|
88
106
|
when :lvar
|
89
107
|
var_name = node.children[0]
|
90
108
|
context = typing.context_at(line: line, column: column)
|
91
|
-
var_type = context.
|
109
|
+
var_type = context.type_env[var_name] || AST::Types::Any.new(location: nil)
|
92
110
|
|
93
111
|
return VariableContent.new(node: node, name: var_name, type: var_type, location: node.location.name)
|
94
112
|
|
95
113
|
when :lvasgn
|
96
114
|
var_name, rhs = node.children
|
97
115
|
context = typing.context_at(line: line, column: column)
|
98
|
-
type = context.
|
116
|
+
type = context.type_env[var_name] || typing.type_of(node: node)
|
99
117
|
|
100
118
|
return VariableContent.new(node: node, name: var_name, type: type, location: node.location.name)
|
101
119
|
|
@@ -342,21 +342,22 @@ module Steep
|
|
342
342
|
|
343
343
|
def self.type_check(source:, subtyping:)
|
344
344
|
annotations = source.annotations(block: source.node, factory: subtyping.factory, context: nil)
|
345
|
+
|
346
|
+
definition = subtyping.factory.definition_builder.build_instance(AST::Builtin::Object.module_name)
|
347
|
+
|
345
348
|
const_env = TypeInference::ConstantEnv.new(
|
346
349
|
factory: subtyping.factory,
|
347
350
|
context: nil,
|
348
351
|
resolver: RBS::Resolver::ConstantResolver.new(builder: subtyping.factory.definition_builder)
|
349
352
|
)
|
350
|
-
type_env = TypeInference::TypeEnv.
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
class_type: AST::Builtin::Object.module_type
|
359
|
-
).annotate(annotations)
|
353
|
+
type_env = TypeInference::TypeEnv.new(const_env)
|
354
|
+
type_env = TypeInference::TypeEnvBuilder.new(
|
355
|
+
TypeInference::TypeEnvBuilder::Command::ImportConstantAnnotations.new(annotations),
|
356
|
+
TypeInference::TypeEnvBuilder::Command::ImportGlobalDeclarations.new(subtyping.factory),
|
357
|
+
TypeInference::TypeEnvBuilder::Command::ImportInstanceVariableDefinition.new(definition, subtyping.factory),
|
358
|
+
TypeInference::TypeEnvBuilder::Command::ImportInstanceVariableAnnotations.new(annotations),
|
359
|
+
TypeInference::TypeEnvBuilder::Command::ImportLocalVariableAnnotations.new(annotations)
|
360
|
+
).build(type_env)
|
360
361
|
|
361
362
|
context = TypeInference::Context.new(
|
362
363
|
block_context: nil,
|
@@ -364,7 +365,7 @@ module Steep
|
|
364
365
|
instance_type: AST::Builtin::Object.instance_type,
|
365
366
|
module_type: AST::Builtin::Object.module_type,
|
366
367
|
implement_name: nil,
|
367
|
-
|
368
|
+
nesting: nil,
|
368
369
|
class_name: AST::Builtin::Object.module_name,
|
369
370
|
instance_definition: subtyping.factory.definition_builder.build_instance(AST::Builtin::Object.module_name),
|
370
371
|
module_definition: subtyping.factory.definition_builder.build_singleton(AST::Builtin::Object.module_name)
|
@@ -373,7 +374,6 @@ module Steep
|
|
373
374
|
break_context: nil,
|
374
375
|
self_type: AST::Builtin::Object.instance_type,
|
375
376
|
type_env: type_env,
|
376
|
-
lvar_env: lvar_env,
|
377
377
|
call_context: TypeInference::MethodCall::TopLevelContext.new,
|
378
378
|
variable_context: TypeInference::Context::TypeVariableContext.empty
|
379
379
|
)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Steep runs on Ruby 2.6 and it needs a shim of `Symbol#start_with?`
|
2
|
+
|
3
|
+
module Shims
|
4
|
+
module SymbolStartWith
|
5
|
+
def start_with?(*args)
|
6
|
+
to_s.start_with?(*args)
|
7
|
+
end
|
8
|
+
|
9
|
+
def end_with?(*args)
|
10
|
+
to_s.end_with?(*args)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
unless Symbol.method_defined?(:start_with?)
|
15
|
+
Symbol.include(SymbolStartWith)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -324,6 +324,25 @@ module Steep
|
|
324
324
|
end
|
325
325
|
end
|
326
326
|
|
327
|
+
definition.class_variables.each do |name, var|
|
328
|
+
if var.declared_in == definition.type_name
|
329
|
+
if (parent = var.parent_variable) && var.declared_in != parent.declared_in
|
330
|
+
class_var = definition.entry.decls.flat_map {|decl| decl.decl.members }.find do |member|
|
331
|
+
member.is_a?(RBS::AST::Members::ClassVariable) && member.name == name
|
332
|
+
end
|
333
|
+
|
334
|
+
if class_var
|
335
|
+
@errors << Diagnostic::Signature::ClassVariableDuplicationError.new(
|
336
|
+
class_name: definition.type_name,
|
337
|
+
other_class_name: parent.declared_in,
|
338
|
+
variable_name: name,
|
339
|
+
location: class_var.location[:name]
|
340
|
+
)
|
341
|
+
end
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
327
346
|
ancestors = builder.ancestor_builder.one_singleton_ancestors(name)
|
328
347
|
mixin_constraints(definition, ancestors.extended_modules, immediate_self_types: ancestors.self_types).each do |relation, ancestor|
|
329
348
|
checker.check(
|
@@ -124,10 +124,10 @@ module Steep
|
|
124
124
|
skips << type if skip
|
125
125
|
end
|
126
126
|
|
127
|
-
super_fvs = supers.
|
127
|
+
super_fvs = supers.each_with_object(Set.new) do |type, fvs|
|
128
128
|
fvs.merge(type.free_variables)
|
129
129
|
end
|
130
|
-
sub_fvs = subs.
|
130
|
+
sub_fvs = subs.each_with_object(Set.new) do |type, fvs|
|
131
131
|
fvs.merge(type.free_variables)
|
132
132
|
end
|
133
133
|
|
@@ -169,6 +169,18 @@ module Steep
|
|
169
169
|
else
|
170
170
|
type
|
171
171
|
end
|
172
|
+
when AST::Types::Tuple
|
173
|
+
AST::Types::Tuple.new(
|
174
|
+
types: type.types.map {|ty| eliminate_variable(ty, to: AST::Builtin.any_type) },
|
175
|
+
location: type.location
|
176
|
+
)
|
177
|
+
when AST::Types::Record
|
178
|
+
AST::Types::Record.new(
|
179
|
+
elements: type.elements.transform_values {|ty| eliminate_variable(ty, to: AST::Builtin.any_type) },
|
180
|
+
location: type.location
|
181
|
+
)
|
182
|
+
when AST::Types::Proc
|
183
|
+
type.map_type {|ty| eliminate_variable(ty, to: AST::Builtin.any_type) }
|
172
184
|
else
|
173
185
|
type
|
174
186
|
end
|
@@ -193,34 +205,36 @@ module Steep
|
|
193
205
|
end
|
194
206
|
|
195
207
|
def upper_bound(var, skip: false)
|
196
|
-
|
197
|
-
|
208
|
+
if skip
|
209
|
+
upper_bound = upper_bound_types(var)
|
210
|
+
else
|
211
|
+
_, upper_bound, _ = dictionary[var]
|
212
|
+
end
|
198
213
|
|
199
214
|
case upper_bound.size
|
200
215
|
when 0
|
201
216
|
AST::Types::Top.new
|
202
217
|
when 1
|
203
|
-
upper_bound.first
|
218
|
+
upper_bound.first || raise
|
204
219
|
else
|
205
220
|
AST::Types::Intersection.build(types: upper_bound.to_a)
|
206
221
|
end
|
207
222
|
end
|
208
223
|
|
209
224
|
def lower_bound(var, skip: false)
|
210
|
-
lower_bound
|
211
|
-
lower_bound -= skips if skip
|
225
|
+
lower_bound = lower_bound_types(var)
|
212
226
|
|
213
227
|
case lower_bound.size
|
214
228
|
when 0
|
215
229
|
AST::Types::Bot.new
|
216
230
|
when 1
|
217
|
-
lower_bound.first
|
231
|
+
lower_bound.first || raise
|
218
232
|
else
|
219
233
|
AST::Types::Union.build(types: lower_bound.to_a)
|
220
234
|
end
|
221
235
|
end
|
222
236
|
|
223
|
-
Context = Struct.new(:variance, :self_type, :instance_type, :class_type, keyword_init: true)
|
237
|
+
Context = _ = Struct.new(:variance, :self_type, :instance_type, :class_type, keyword_init: true)
|
224
238
|
|
225
239
|
def solution(checker, variance: nil, variables:, self_type: nil, instance_type: nil, class_type: nil, context: nil)
|
226
240
|
if context
|
@@ -288,16 +302,13 @@ module Steep
|
|
288
302
|
end
|
289
303
|
|
290
304
|
def has_constraint?(var)
|
291
|
-
|
292
|
-
lower -= skips
|
293
|
-
upper -= skips
|
294
|
-
!lower.empty? || !upper.empty?
|
305
|
+
!upper_bound_types(var).empty? || !lower_bound_types(var).empty?
|
295
306
|
end
|
296
307
|
|
297
308
|
def each
|
298
309
|
if block_given?
|
299
310
|
dictionary.each_key do |var|
|
300
|
-
yield var, lower_bound(var), upper_bound(var)
|
311
|
+
yield [var, lower_bound(var), upper_bound(var)]
|
301
312
|
end
|
302
313
|
else
|
303
314
|
enum_for :each
|
@@ -311,6 +322,24 @@ module Steep
|
|
311
322
|
|
312
323
|
"#{unknowns.to_a.join(",")}/#{vars.to_a.join(",")} |- { #{strings.join(", ")} }"
|
313
324
|
end
|
325
|
+
|
326
|
+
def lower_bound_types(var_name)
|
327
|
+
lower, _, _ = dictionary[var_name]
|
328
|
+
lower
|
329
|
+
end
|
330
|
+
|
331
|
+
def upper_bound_types(var_name)
|
332
|
+
_, upper, skips = dictionary[var_name]
|
333
|
+
|
334
|
+
case
|
335
|
+
when upper.empty?
|
336
|
+
skips
|
337
|
+
when skips.empty?
|
338
|
+
upper
|
339
|
+
else
|
340
|
+
upper - skips
|
341
|
+
end
|
342
|
+
end
|
314
343
|
end
|
315
344
|
end
|
316
345
|
end
|