steep 0.17.1 → 0.22.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.
@@ -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.name.absolute!)
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 = yield_self do
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
- module_decl = checker.factory.definition_builder.env.find_class(type_name_)
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
- module_decl.self_type&.yield_self {|ty|
281
- absolute_type = checker.factory.env.absolute_type(ty, namespace: module_decl.name.absolute!.namespace)
282
- checker.factory.type(absolute_type)
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 = yield_self do
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
 
@@ -565,6 +639,7 @@ module Steep
565
639
  add_typing(node, type: AST::Builtin.any_type)
566
640
  else
567
641
  rhs_result = synthesize(rhs, hint: hint || context.lvar_env.declared_types[name]&.type)
642
+
568
643
  constr = rhs_result.constr.update_lvar_env do |lvar_env|
569
644
  lvar_env.assign(name, node: node, type: rhs_result.type) do |declared_type, actual_type, result|
570
645
  typing.add_error(Errors::IncompatibleAssignment.new(node: node,
@@ -1019,7 +1094,13 @@ module Steep
1019
1094
  end
1020
1095
 
1021
1096
  when :true, :false
1022
- add_typing(node, type: AST::Types::Boolean.new)
1097
+ ty = node.type == :true ? AST::Types::Literal.new(value: true) : AST::Types::Literal.new(value: false)
1098
+
1099
+ if hint && check_relation(sub_type: ty, super_type: hint).success?
1100
+ add_typing(node, type: hint)
1101
+ else
1102
+ add_typing(node, type: AST::Types::Boolean.new)
1103
+ end
1023
1104
 
1024
1105
  when :hash
1025
1106
  yield_self do
@@ -1115,6 +1196,25 @@ module Steep
1115
1196
  add_typing(node, type: AST::Builtin.nil_type)
1116
1197
  end
1117
1198
 
1199
+ when :sclass
1200
+ yield_self do
1201
+ type, constr = synthesize(node.children[0])
1202
+ constructor = constr.for_sclass(node, type)
1203
+
1204
+ constructor.typing.add_context_for_node(node, context: constructor.context)
1205
+ constructor.typing.add_context_for_body(node, context: constructor.context)
1206
+
1207
+ constructor.synthesize(node.children[1]) if node.children[1]
1208
+
1209
+ if constructor.module_context.instance_definition && module_context.module_definition
1210
+ if constructor.module_context.instance_definition.type_name == module_context.module_definition.type_name
1211
+ module_context.defined_module_methods.merge(constructor.module_context.defined_instance_methods)
1212
+ end
1213
+ end
1214
+
1215
+ add_typing(node, type: AST::Builtin.nil_type)
1216
+ end
1217
+
1118
1218
  when :self
1119
1219
  add_typing node, type: AST::Types::Self.new
1120
1220
 
@@ -1992,9 +2092,11 @@ module Steep
1992
2092
  end
1993
2093
  end
1994
2094
  rescue => exn
1995
- $stderr.puts exn.inspect
1996
- exn.backtrace.each do |t|
1997
- $stderr.puts t
2095
+ case exn
2096
+ when RBS::NoTypeFoundError, RBS::NoMixinFoundError, RBS::NoSuperclassFoundError, RBS::InvalidTypeApplicationError
2097
+ # ignore known RBS errors.
2098
+ else
2099
+ Steep.log_error(exn, message: "Unexpected error in #type_send: #{exn.message} (#{exn.class})")
1998
2100
  end
1999
2101
 
2000
2102
  fallback_to_any node do
@@ -2750,13 +2852,18 @@ module Steep
2750
2852
  end
2751
2853
 
2752
2854
  def validate_method_definitions(node, module_name)
2855
+ module_name_1 = checker.factory.type_name_1(module_name.name)
2856
+ member_decl_count = checker.factory.env.class_decls[module_name_1].decls.count {|d| d.decl.each_member.count > 0 }
2857
+
2858
+ return unless member_decl_count == 1
2859
+
2753
2860
  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.declaration
2861
+ if method.implemented_in == module_context.instance_definition.type_name
2755
2862
  set << name
2756
2863
  end
2757
2864
  end
2758
2865
  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.declaration
2866
+ if method.implemented_in == module_context.module_definition.type_name
2760
2867
  set << name
2761
2868
  end
2762
2869
  end
@@ -2948,7 +3055,7 @@ module Steep
2948
3055
  def to_instance_type(type, args: nil)
2949
3056
  args = args || case type
2950
3057
  when AST::Types::Name::Class, AST::Types::Name::Module
2951
- checker.factory.env.find_class(checker.factory.type_name_1(type.name)).type_params.each.map { AST::Builtin.any_type }
3058
+ checker.factory.env.class_decls[checker.factory.type_name_1(type.name)].type_params.each.map { AST::Builtin.any_type }
2952
3059
  else
2953
3060
  raise "unexpected type to to_instance_type: #{type}"
2954
3061
  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.name_to_global.each do |name, global|
35
- type = signatures.absolute_type(global.type, namespace: RBS::Namespace.root) {|ty| ty.name.absolute! }
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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Steep
2
- VERSION = "0.17.1"
2
+ VERSION = "0.22.0"
3
3
  end
@@ -18,7 +18,6 @@ class D
18
18
  def foo: -> untyped
19
19
  end
20
20
 
21
- class E
22
- def initialize: () -> untyped
21
+ interface _E
23
22
  def foo: -> untyped
24
23
  end
@@ -1,8 +1,10 @@
1
- # @type var e: E
1
+ # @type var e: _E
2
2
  # @type var d: D
3
3
 
4
4
  e = (_ = nil)
5
5
  d = (_ = nil)
6
6
 
7
7
  e = d
8
+
9
+ # !expects IncompatibleAssignment: lhs_type=::D, rhs_type=::_E
8
10
  d = e
@@ -1,9 +1,10 @@
1
- extension Object (X)
1
+
2
+ class Object
2
3
  def try: [A] { (instance) -> A } -> A
3
4
  def f: -> Object
4
5
  end
5
6
 
6
- extension Kernel (X)
7
+ module Kernel
7
8
  def new_module_method: () -> void
8
9
  end
9
10
 
@@ -2,7 +2,6 @@ class NumberLike
2
2
  def to_number: -> Integer
3
3
  end
4
4
 
5
- extension Integer (NumberLike)
6
- def `+`: (NumberLike) -> NumberLike
7
- | super
5
+ class Integer
6
+ overload def `+`: (NumberLike) -> NumberLike
8
7
  end
@@ -1,12 +1,12 @@
1
1
  class A
2
2
  def foo: -> _Foo
3
3
  def hello: -> void
4
- end
5
4
 
6
- class A::Object
7
- def object?: -> bool
8
- end
5
+ class Object
6
+ def object?: -> bool
7
+ end
9
8
 
10
- interface A::_Foo
11
- def foo: -> Object
9
+ interface _Foo
10
+ def foo: -> Object
11
+ end
12
12
  end
@@ -28,18 +28,11 @@ Gem::Specification.new do |spec|
28
28
 
29
29
  spec.required_ruby_version = '>= 2.6.0'
30
30
 
31
- spec.add_development_dependency "bundler", ">= 1.13"
32
- spec.add_development_dependency "rake", "~> 13.0"
33
- spec.add_development_dependency "minitest", "~> 5.0"
34
- spec.add_development_dependency "racc", "~> 1.4"
35
- spec.add_development_dependency "minitest-reporters", "~> 1.4.2"
36
- spec.add_development_dependency "minitest-hooks", "~> 1.5.0"
37
-
38
31
  spec.add_runtime_dependency "parser", "~> 2.7.0"
39
32
  spec.add_runtime_dependency "ast_utils", "~> 0.3.0"
40
33
  spec.add_runtime_dependency "activesupport", ">= 5.1"
41
34
  spec.add_runtime_dependency "rainbow", ">= 2.2.2", "< 4.0"
42
35
  spec.add_runtime_dependency "listen", "~> 3.1"
43
36
  spec.add_runtime_dependency "language_server-protocol", "~> 3.14.0.2"
44
- spec.add_runtime_dependency "rbs", ">= 0.3.1", '< 0.5.0'
37
+ spec.add_runtime_dependency "rbs", "~> 0.9.0"
45
38
  end
metadata CHANGED
@@ -1,99 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: steep
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.1
4
+ version: 0.22.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-06-15 00:00:00.000000000 Z
11
+ date: 2020-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '1.13'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '1.13'
27
- - !ruby/object:Gem::Dependency
28
- name: rake
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '13.0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '13.0'
41
- - !ruby/object:Gem::Dependency
42
- name: minitest
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '5.0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '5.0'
55
- - !ruby/object:Gem::Dependency
56
- name: racc
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '1.4'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '1.4'
69
- - !ruby/object:Gem::Dependency
70
- name: minitest-reporters
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: 1.4.2
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: 1.4.2
83
- - !ruby/object:Gem::Dependency
84
- name: minitest-hooks
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: 1.5.0
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: 1.5.0
97
13
  - !ruby/object:Gem::Dependency
98
14
  name: parser
99
15
  requirement: !ruby/object:Gem::Requirement
@@ -188,22 +104,16 @@ dependencies:
188
104
  name: rbs
189
105
  requirement: !ruby/object:Gem::Requirement
190
106
  requirements:
191
- - - ">="
192
- - !ruby/object:Gem::Version
193
- version: 0.3.1
194
- - - "<"
107
+ - - "~>"
195
108
  - !ruby/object:Gem::Version
196
- version: 0.5.0
109
+ version: 0.9.0
197
110
  type: :runtime
198
111
  prerelease: false
199
112
  version_requirements: !ruby/object:Gem::Requirement
200
113
  requirements:
201
- - - ">="
202
- - !ruby/object:Gem::Version
203
- version: 0.3.1
204
- - - "<"
114
+ - - "~>"
205
115
  - !ruby/object:Gem::Version
206
- version: 0.5.0
116
+ version: 0.9.0
207
117
  description: Gradual Typing for Ruby
208
118
  email:
209
119
  - matsumoto@soutaro.com
@@ -224,6 +134,7 @@ files:
224
134
  - bin/console
225
135
  - bin/setup
226
136
  - bin/smoke_runner.rb
137
+ - bin/steep-prof
227
138
  - exe/steep
228
139
  - lib/steep.rb
229
140
  - lib/steep/annotation_parser.rb