steep 0.18.0 → 0.23.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/.github/workflows/ruby.yml +5 -1
- data/CHANGELOG.md +28 -1
- data/Gemfile +7 -0
- data/bin/steep-prof +16 -0
- data/lib/steep/ast/types/factory.rb +16 -13
- data/lib/steep/ast/types/literal.rb +4 -0
- data/lib/steep/project/completion_provider.rb +24 -8
- data/lib/steep/project/dsl.rb +7 -1
- data/lib/steep/project/file.rb +7 -0
- data/lib/steep/project/hover_content.rb +9 -3
- data/lib/steep/project/options.rb +7 -0
- data/lib/steep/project/target.rb +43 -23
- data/lib/steep/server/interaction_worker.rb +5 -5
- data/lib/steep/server/signature_worker.rb +4 -0
- data/lib/steep/signature/errors.rb +28 -0
- data/lib/steep/signature/validator.rb +57 -27
- data/lib/steep/subtyping/check.rb +214 -43
- data/lib/steep/type_construction.rb +184 -75
- data/lib/steep/type_inference/type_env.rb +2 -2
- data/lib/steep/typing.rb +6 -0
- data/lib/steep/version.rb +1 -1
- data/smoke/class/a.rbs +1 -2
- data/smoke/class/f.rb +3 -1
- data/smoke/extension/a.rbs +3 -2
- data/smoke/extension/e.rbs +2 -3
- data/smoke/interface/a.rbs +6 -6
- data/steep.gemspec +1 -8
- metadata +8 -97
@@ -37,7 +37,6 @@ module Steep
|
|
37
37
|
attr_reader :source
|
38
38
|
attr_reader :annotations
|
39
39
|
attr_reader :typing
|
40
|
-
attr_reader :type_env
|
41
40
|
|
42
41
|
attr_reader :context
|
43
42
|
|
@@ -169,7 +168,7 @@ module Steep
|
|
169
168
|
|
170
169
|
super_method = if definition
|
171
170
|
if (this_method = definition.methods[method_name])
|
172
|
-
if module_context&.class_name == checker.factory.type_name(this_method.defined_in
|
171
|
+
if module_context&.class_name == checker.factory.type_name(this_method.defined_in)
|
173
172
|
this_method.super_method
|
174
173
|
else
|
175
174
|
this_method
|
@@ -231,6 +230,39 @@ module Steep
|
|
231
230
|
)
|
232
231
|
end
|
233
232
|
|
233
|
+
def implement_module(module_name:, super_name: nil, annotations:)
|
234
|
+
if (annotation = annotations.implement_module_annotation)
|
235
|
+
absolute_name(annotation.name.name).yield_self do |absolute_name|
|
236
|
+
if checker.factory.class_name?(absolute_name) || checker.factory.module_name?(absolute_name)
|
237
|
+
AST::Annotation::Implements::Module.new(
|
238
|
+
name: absolute_name,
|
239
|
+
args: annotation.name.args
|
240
|
+
)
|
241
|
+
else
|
242
|
+
Steep.logger.error "Unknown class name given to @implements: #{annotation.name.name}"
|
243
|
+
nil
|
244
|
+
end
|
245
|
+
end
|
246
|
+
else
|
247
|
+
name = nil
|
248
|
+
name ||= absolute_name(module_name).yield_self do |absolute_name|
|
249
|
+
absolute_name if checker.factory.class_name?(absolute_name) || checker.factory.module_name?(absolute_name)
|
250
|
+
end
|
251
|
+
name ||= super_name && absolute_name(super_name).yield_self do |absolute_name|
|
252
|
+
absolute_name if checker.factory.class_name?(absolute_name) || checker.factory.module_name?(absolute_name)
|
253
|
+
end
|
254
|
+
|
255
|
+
if name
|
256
|
+
absolute_name_ = checker.factory.type_name_1(name)
|
257
|
+
entry = checker.factory.env.class_decls[absolute_name_]
|
258
|
+
AST::Annotation::Implements::Module.new(
|
259
|
+
name: name,
|
260
|
+
args: entry.type_params.each.map(&:name)
|
261
|
+
)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
234
266
|
def for_module(node)
|
235
267
|
new_module_name = Names::Module.from_node(node.children.first) or raise "Unexpected module name: #{node.children.first}"
|
236
268
|
new_namespace = nested_namespace_for_module(new_module_name)
|
@@ -241,35 +273,14 @@ module Steep
|
|
241
273
|
annots = source.annotations(block: node, factory: checker.factory, current_module: new_namespace)
|
242
274
|
module_type = AST::Builtin::Module.instance_type
|
243
275
|
|
244
|
-
implement_module_name =
|
245
|
-
if (annotation = annots.implement_module_annotation)
|
246
|
-
absolute_name(annotation.name.name).yield_self do |absolute_name|
|
247
|
-
if checker.factory.module_name?(absolute_name)
|
248
|
-
AST::Annotation::Implements::Module.new(name: absolute_name,
|
249
|
-
args: annotation.name.args)
|
250
|
-
else
|
251
|
-
Steep.logger.error "Unknown module name given to @implements: #{annotation.name.name}"
|
252
|
-
nil
|
253
|
-
end
|
254
|
-
end
|
255
|
-
else
|
256
|
-
absolute_name(new_module_name).yield_self do |absolute_name|
|
257
|
-
if checker.factory.module_name?(absolute_name)
|
258
|
-
absolute_name_ = checker.factory.type_name_1(absolute_name)
|
259
|
-
decl = checker.factory.env.find_class(absolute_name_)
|
260
|
-
AST::Annotation::Implements::Module.new(name: absolute_name,
|
261
|
-
args: decl.type_params.each.map(&:name))
|
262
|
-
end
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|
276
|
+
implement_module_name = implement_module(module_name: new_module_name, annotations: annots)
|
266
277
|
|
267
278
|
if implement_module_name
|
268
279
|
module_name = implement_module_name.name
|
269
280
|
module_args = implement_module_name.args.map {|x| AST::Types::Var.new(name: x)}
|
270
281
|
|
271
282
|
type_name_ = checker.factory.type_name_1(implement_module_name.name)
|
272
|
-
|
283
|
+
module_entry = checker.factory.definition_builder.env.class_decls[type_name_]
|
273
284
|
instance_def = checker.factory.definition_builder.build_instance(type_name_)
|
274
285
|
module_def = checker.factory.definition_builder.build_singleton(type_name_)
|
275
286
|
|
@@ -277,9 +288,22 @@ module Steep
|
|
277
288
|
types: [
|
278
289
|
AST::Types::Name::Instance.new(name: module_name, args: module_args),
|
279
290
|
AST::Builtin::Object.instance_type,
|
280
|
-
|
281
|
-
|
282
|
-
|
291
|
+
*module_entry.self_types.map {|module_self|
|
292
|
+
type = case
|
293
|
+
when module_self.name.interface?
|
294
|
+
RBS::Types::Interface.new(
|
295
|
+
name: module_self.name,
|
296
|
+
args: module_self.args,
|
297
|
+
location: module_self.location
|
298
|
+
)
|
299
|
+
when module_self.name.class?
|
300
|
+
RBS::Types::ClassInstance.new(
|
301
|
+
name: module_self.name,
|
302
|
+
args: module_self.args,
|
303
|
+
location: module_self.location
|
304
|
+
)
|
305
|
+
end
|
306
|
+
checker.factory.type(type)
|
283
307
|
}
|
284
308
|
].compact
|
285
309
|
)
|
@@ -340,34 +364,7 @@ module Steep
|
|
340
364
|
|
341
365
|
annots = source.annotations(block: node, factory: checker.factory, current_module: new_namespace)
|
342
366
|
|
343
|
-
implement_module_name =
|
344
|
-
if (annotation = annots.implement_module_annotation)
|
345
|
-
absolute_name(annotation.name.name).yield_self do |absolute_name|
|
346
|
-
if checker.factory.class_name?(absolute_name)
|
347
|
-
AST::Annotation::Implements::Module.new(name: absolute_name,
|
348
|
-
args: annotation.name.args)
|
349
|
-
else
|
350
|
-
Steep.logger.error "Unknown class name given to @implements: #{annotation.name.name}"
|
351
|
-
nil
|
352
|
-
end
|
353
|
-
end
|
354
|
-
else
|
355
|
-
name = nil
|
356
|
-
name ||= absolute_name(new_class_name).yield_self do |absolute_name|
|
357
|
-
absolute_name if checker.factory.class_name?(absolute_name)
|
358
|
-
end
|
359
|
-
name ||= super_class_name && absolute_name(super_class_name).yield_self do |absolute_name|
|
360
|
-
absolute_name if checker.factory.class_name?(absolute_name)
|
361
|
-
end
|
362
|
-
|
363
|
-
if name
|
364
|
-
absolute_name_ = checker.factory.type_name_1(name)
|
365
|
-
decl = checker.factory.env.find_class(absolute_name_)
|
366
|
-
AST::Annotation::Implements::Module.new(name: name,
|
367
|
-
args: decl.type_params.each.map(&:name))
|
368
|
-
end
|
369
|
-
end
|
370
|
-
end
|
367
|
+
implement_module_name = implement_module(module_name: new_class_name, super_name: super_class_name, annotations: annots)
|
371
368
|
|
372
369
|
if annots.implement_module_annotation
|
373
370
|
new_class_name = implement_module_name.name
|
@@ -436,6 +433,83 @@ module Steep
|
|
436
433
|
)
|
437
434
|
end
|
438
435
|
|
436
|
+
def for_sclass(node, type)
|
437
|
+
annots = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
438
|
+
|
439
|
+
instance_type = if type.is_a?(AST::Types::Self)
|
440
|
+
context.self_type
|
441
|
+
else
|
442
|
+
type
|
443
|
+
end
|
444
|
+
|
445
|
+
module_type = case instance_type
|
446
|
+
when AST::Types::Name::Class
|
447
|
+
AST::Builtin::Class.instance_type
|
448
|
+
when AST::Types::Name::Module
|
449
|
+
AST::Builtin::Module.instance_type
|
450
|
+
when AST::Types::Name::Instance
|
451
|
+
instance_type.to_class(constructor: nil)
|
452
|
+
else
|
453
|
+
raise "Unexpected type for sclass node: #{type}"
|
454
|
+
end
|
455
|
+
|
456
|
+
instance_definition = case instance_type
|
457
|
+
when AST::Types::Name::Class, AST::Types::Name::Module
|
458
|
+
type_name = checker.factory.type_name_1(instance_type.name)
|
459
|
+
checker.factory.definition_builder.build_singleton(type_name)
|
460
|
+
when AST::Types::Name::Instance
|
461
|
+
type_name = checker.factory.type_name_1(instance_type.name)
|
462
|
+
checker.factory.definition_builder.build_instance(type_name)
|
463
|
+
end
|
464
|
+
|
465
|
+
module_definition = case module_type
|
466
|
+
when AST::Types::Name::Class, AST::Types::Name::Module
|
467
|
+
type_name = checker.factory.type_name_1(instance_type.name)
|
468
|
+
checker.factory.definition_builder.build_singleton(type_name)
|
469
|
+
else
|
470
|
+
nil
|
471
|
+
end
|
472
|
+
|
473
|
+
module_context = TypeInference::Context::ModuleContext.new(
|
474
|
+
instance_type: annots.instance_type || instance_type,
|
475
|
+
module_type: annots.self_type || annots.module_type || module_type,
|
476
|
+
implement_name: nil,
|
477
|
+
current_namespace: current_namespace,
|
478
|
+
const_env: self.module_context.const_env,
|
479
|
+
class_name: self.module_context.class_name,
|
480
|
+
module_definition: module_definition,
|
481
|
+
instance_definition: instance_definition
|
482
|
+
)
|
483
|
+
|
484
|
+
type_env = TypeInference::TypeEnv.build(annotations: annots,
|
485
|
+
subtyping: checker,
|
486
|
+
const_env: self.module_context.const_env,
|
487
|
+
signatures: checker.factory.env)
|
488
|
+
|
489
|
+
lvar_env = TypeInference::LocalVariableTypeEnv.empty(
|
490
|
+
subtyping: checker,
|
491
|
+
self_type: module_context.module_type
|
492
|
+
).annotate(annots)
|
493
|
+
|
494
|
+
body_context = TypeInference::Context.new(
|
495
|
+
method_context: nil,
|
496
|
+
block_context: nil,
|
497
|
+
module_context: module_context,
|
498
|
+
break_context: nil,
|
499
|
+
self_type: module_context.module_type,
|
500
|
+
type_env: type_env,
|
501
|
+
lvar_env: lvar_env
|
502
|
+
)
|
503
|
+
|
504
|
+
self.class.new(
|
505
|
+
checker: checker,
|
506
|
+
source: source,
|
507
|
+
annotations: annots,
|
508
|
+
typing: typing,
|
509
|
+
context: body_context
|
510
|
+
)
|
511
|
+
end
|
512
|
+
|
439
513
|
def for_branch(node, truthy_vars: Set.new, type_case_override: nil, break_context: context.break_context)
|
440
514
|
annots = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
441
515
|
|
@@ -564,7 +638,9 @@ module Steep
|
|
564
638
|
when :__skip__
|
565
639
|
add_typing(node, type: AST::Builtin.any_type)
|
566
640
|
else
|
567
|
-
|
641
|
+
hint ||= context.lvar_env.declared_types[name]&.type
|
642
|
+
rhs_result = synthesize(rhs, hint: hint)
|
643
|
+
|
568
644
|
constr = rhs_result.constr.update_lvar_env do |lvar_env|
|
569
645
|
lvar_env.assign(name, node: node, type: rhs_result.type) do |declared_type, actual_type, result|
|
570
646
|
typing.add_error(Errors::IncompatibleAssignment.new(node: node,
|
@@ -987,7 +1063,7 @@ module Steep
|
|
987
1063
|
|
988
1064
|
when :int
|
989
1065
|
yield_self do
|
990
|
-
literal_type =
|
1066
|
+
literal_type = test_literal_type(node.children[0], hint)
|
991
1067
|
|
992
1068
|
if literal_type
|
993
1069
|
add_typing(node, type: literal_type)
|
@@ -998,7 +1074,7 @@ module Steep
|
|
998
1074
|
|
999
1075
|
when :sym
|
1000
1076
|
yield_self do
|
1001
|
-
literal_type =
|
1077
|
+
literal_type = test_literal_type(node.children[0], hint)
|
1002
1078
|
|
1003
1079
|
if literal_type
|
1004
1080
|
add_typing(node, type: literal_type)
|
@@ -1009,7 +1085,7 @@ module Steep
|
|
1009
1085
|
|
1010
1086
|
when :str
|
1011
1087
|
yield_self do
|
1012
|
-
literal_type =
|
1088
|
+
literal_type = test_literal_type(node.children[0], hint)
|
1013
1089
|
|
1014
1090
|
if literal_type
|
1015
1091
|
add_typing(node, type: literal_type)
|
@@ -1019,7 +1095,13 @@ module Steep
|
|
1019
1095
|
end
|
1020
1096
|
|
1021
1097
|
when :true, :false
|
1022
|
-
|
1098
|
+
ty = node.type == :true ? AST::Types::Literal.new(value: true) : AST::Types::Literal.new(value: false)
|
1099
|
+
|
1100
|
+
if hint && check_relation(sub_type: ty, super_type: hint).success?
|
1101
|
+
add_typing(node, type: hint)
|
1102
|
+
else
|
1103
|
+
add_typing(node, type: AST::Types::Boolean.new)
|
1104
|
+
end
|
1023
1105
|
|
1024
1106
|
when :hash
|
1025
1107
|
yield_self do
|
@@ -1115,6 +1197,25 @@ module Steep
|
|
1115
1197
|
add_typing(node, type: AST::Builtin.nil_type)
|
1116
1198
|
end
|
1117
1199
|
|
1200
|
+
when :sclass
|
1201
|
+
yield_self do
|
1202
|
+
type, constr = synthesize(node.children[0])
|
1203
|
+
constructor = constr.for_sclass(node, type)
|
1204
|
+
|
1205
|
+
constructor.typing.add_context_for_node(node, context: constructor.context)
|
1206
|
+
constructor.typing.add_context_for_body(node, context: constructor.context)
|
1207
|
+
|
1208
|
+
constructor.synthesize(node.children[1]) if node.children[1]
|
1209
|
+
|
1210
|
+
if constructor.module_context.instance_definition && module_context.module_definition
|
1211
|
+
if constructor.module_context.instance_definition.type_name == module_context.module_definition.type_name
|
1212
|
+
module_context.defined_module_methods.merge(constructor.module_context.defined_instance_methods)
|
1213
|
+
end
|
1214
|
+
end
|
1215
|
+
|
1216
|
+
add_typing(node, type: AST::Builtin.nil_type)
|
1217
|
+
end
|
1218
|
+
|
1118
1219
|
when :self
|
1119
1220
|
add_typing node, type: AST::Types::Self.new
|
1120
1221
|
|
@@ -1992,9 +2093,11 @@ module Steep
|
|
1992
2093
|
end
|
1993
2094
|
end
|
1994
2095
|
rescue => exn
|
1995
|
-
|
1996
|
-
|
1997
|
-
|
2096
|
+
case exn
|
2097
|
+
when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
|
2098
|
+
# ignore known RBS errors.
|
2099
|
+
else
|
2100
|
+
Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
|
1998
2101
|
end
|
1999
2102
|
|
2000
2103
|
fallback_to_any node do
|
@@ -2750,13 +2853,18 @@ module Steep
|
|
2750
2853
|
end
|
2751
2854
|
|
2752
2855
|
def validate_method_definitions(node, module_name)
|
2856
|
+
module_name_1 = checker.factory.type_name_1(module_name.name)
|
2857
|
+
member_decl_count = checker.factory.env.class_decls[module_name_1].decls.count {|d| d.decl.each_member.count > 0 }
|
2858
|
+
|
2859
|
+
return unless member_decl_count == 1
|
2860
|
+
|
2753
2861
|
expected_instance_method_names = (module_context.instance_definition&.methods || {}).each.with_object(Set[]) do |(name, method), set|
|
2754
|
-
if method.implemented_in == module_context.instance_definition.
|
2862
|
+
if method.implemented_in == module_context.instance_definition.type_name
|
2755
2863
|
set << name
|
2756
2864
|
end
|
2757
2865
|
end
|
2758
2866
|
expected_module_method_names = (module_context.module_definition&.methods || {}).each.with_object(Set[]) do |(name, method), set|
|
2759
|
-
if method.implemented_in == module_context.module_definition.
|
2867
|
+
if method.implemented_in == module_context.module_definition.type_name
|
2760
2868
|
set << name
|
2761
2869
|
end
|
2762
2870
|
end
|
@@ -2915,14 +3023,15 @@ module Steep
|
|
2915
3023
|
end
|
2916
3024
|
|
2917
3025
|
def test_literal_type(literal, hint)
|
2918
|
-
|
2919
|
-
|
2920
|
-
|
2921
|
-
|
2922
|
-
|
2923
|
-
|
2924
|
-
|
2925
|
-
|
3026
|
+
if hint
|
3027
|
+
case hint
|
3028
|
+
when AST::Types::Any
|
3029
|
+
nil
|
3030
|
+
else
|
3031
|
+
literal_type = AST::Types::Literal.new(value: literal, location: nil)
|
3032
|
+
if check_relation(sub_type: literal_type, super_type: hint).success?
|
3033
|
+
hint
|
3034
|
+
end
|
2926
3035
|
end
|
2927
3036
|
end
|
2928
3037
|
end
|
@@ -2948,7 +3057,7 @@ module Steep
|
|
2948
3057
|
def to_instance_type(type, args: nil)
|
2949
3058
|
args = args || case type
|
2950
3059
|
when AST::Types::Name::Class, AST::Types::Name::Module
|
2951
|
-
checker.factory.env.
|
3060
|
+
checker.factory.env.class_decls[checker.factory.type_name_1(type.name)].type_params.each.map { AST::Builtin.any_type }
|
2952
3061
|
else
|
2953
3062
|
raise "unexpected type to to_instance_type: #{type}"
|
2954
3063
|
end
|
@@ -31,8 +31,8 @@ module Steep
|
|
31
31
|
annotations.const_types.each do |name, type|
|
32
32
|
env.set(const: name, type: type)
|
33
33
|
end
|
34
|
-
signatures.
|
35
|
-
type =
|
34
|
+
signatures.global_decls.each do |name, entry|
|
35
|
+
type = entry.decl.type
|
36
36
|
env.set(gvar: name, type: subtyping.factory.type(type))
|
37
37
|
end
|
38
38
|
end
|
data/lib/steep/typing.rb
CHANGED
@@ -95,6 +95,12 @@ module Steep
|
|
95
95
|
end_pos = node.loc.end.begin_pos
|
96
96
|
add_context(begin_pos..end_pos, context: context)
|
97
97
|
|
98
|
+
when :sclass
|
99
|
+
name_node = node.children[0]
|
100
|
+
begin_pos = name_node.loc.expression.end_pos
|
101
|
+
end_pos = node.loc.end.begin_pos
|
102
|
+
add_context(begin_pos..end_pos, context: context)
|
103
|
+
|
98
104
|
when :def, :defs
|
99
105
|
args_node = case node.type
|
100
106
|
when :def
|
data/lib/steep/version.rb
CHANGED
data/smoke/class/a.rbs
CHANGED
data/smoke/class/f.rb
CHANGED
data/smoke/extension/a.rbs
CHANGED