steep 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -50,8 +50,9 @@ module Steep
50
50
  attr_reader :const_env
51
51
  attr_reader :implement_name
52
52
  attr_reader :current_namespace
53
+ attr_reader :class_name
53
54
 
54
- def initialize(instance_type:, module_type:, implement_name:, current_namespace:, const_env:)
55
+ def initialize(instance_type:, module_type:, implement_name:, current_namespace:, const_env:, class_name:)
55
56
  @instance_type = instance_type
56
57
  @module_type = module_type
57
58
  @defined_instance_methods = Set.new
@@ -59,6 +60,7 @@ module Steep
59
60
  @implement_name = implement_name
60
61
  @current_namespace = current_namespace
61
62
  @const_env = const_env
63
+ @class_name = class_name
62
64
  end
63
65
 
64
66
  def const_context
@@ -344,7 +346,8 @@ module Steep
344
346
  module_type: annots.self_type || module_type,
345
347
  implement_name: implement_module_name,
346
348
  current_namespace: new_namespace,
347
- const_env: module_const_env
349
+ const_env: module_const_env,
350
+ class_name: absolute_name(new_module_name)
348
351
  )
349
352
 
350
353
  module_type_env = TypeInference::TypeEnv.build(annotations: annots,
@@ -368,6 +371,7 @@ module Steep
368
371
 
369
372
  def for_class(node)
370
373
  new_class_name = Names::Module.from_node(node.children.first) or raise "Unexpected class name: #{node.children.first}"
374
+ super_class_name = node.children[1] && Names::Module.from_node(node.children[1])
371
375
  new_namespace = nested_namespace_for_module(new_class_name)
372
376
 
373
377
  annots = source.annotations(block: node, builder: checker.builder, current_module: new_namespace)
@@ -384,16 +388,26 @@ module Steep
384
388
  end
385
389
  end
386
390
  else
387
- absolute_name(new_class_name).yield_self do |absolute_name|
388
- if checker.builder.signatures.class_name?(absolute_name)
389
- signature = checker.builder.signatures.find_class(absolute_name)
390
- AST::Annotation::Implements::Module.new(name: absolute_name,
391
- args: signature.params&.variables || [])
392
- end
391
+ name = nil
392
+ name ||= absolute_name(new_class_name).yield_self do |absolute_name|
393
+ absolute_name if checker.builder.signatures.class_name?(absolute_name)
394
+ end
395
+ name ||= super_class_name && absolute_name(super_class_name).yield_self do |absolute_name|
396
+ absolute_name if checker.builder.signatures.class_name?(absolute_name)
397
+ end
398
+
399
+ if name
400
+ signature = checker.builder.signatures.find_class(name)
401
+ AST::Annotation::Implements::Module.new(name: name,
402
+ args: signature.params&.variables || [])
393
403
  end
394
404
  end
395
405
  end
396
406
 
407
+ if annots.implement_module_annotation
408
+ new_class_name = implement_module_name.name
409
+ end
410
+
397
411
  if implement_module_name
398
412
  class_name = implement_module_name.name
399
413
  class_args = implement_module_name.args.map {|x| AST::Types::Var.new(name: x) }
@@ -416,7 +430,8 @@ module Steep
416
430
  module_type: annots.self_type || annots.module_type || module_type,
417
431
  implement_name: implement_module_name,
418
432
  current_namespace: new_namespace,
419
- const_env: class_const_env
433
+ const_env: class_const_env,
434
+ class_name: absolute_name(new_class_name)
420
435
  )
421
436
 
422
437
  class_type_env = TypeInference::TypeEnv.build(
@@ -702,7 +717,7 @@ module Steep
702
717
  if send_node.type == :lambda
703
718
  type_lambda(node, block_params: params, block_body: body, type_hint: hint)
704
719
  else
705
- type_send(node, send_node: send_node, block_params: params, block_body: body)
720
+ type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend)
706
721
  end
707
722
  end
708
723
 
@@ -1151,11 +1166,12 @@ module Steep
1151
1166
  expand_alias(hint) do |hint|
1152
1167
  is_tuple = hint.is_a?(AST::Types::Tuple)
1153
1168
  is_tuple &&= node.children.all? {|child| child.type != :splat }
1154
- is_tuple &&= node.children.map.with_index do |child, index|
1155
- synthesize(child, hint: hint.types[index])
1156
- end.yield_self do |types|
1157
- tuple = AST::Types::Tuple.new(types: types)
1158
- relation = Subtyping::Relation.new(sub_type: tuple, super_type: hint)
1169
+ is_tuple &&= node.children.size >= hint.types.size
1170
+ is_tuple &&= hint.types.map.with_index do |child_type, index|
1171
+ child_node = node.children[index]
1172
+ [synthesize(child_node, hint: child_type), child_type]
1173
+ end.all? do |node_type, hint_type|
1174
+ relation = Subtyping::Relation.new(sub_type: node_type, super_type: hint_type)
1159
1175
  result = checker.check(relation, constraints: Subtyping::Constraints.empty)
1160
1176
  result.success?
1161
1177
  end
@@ -1224,7 +1240,9 @@ module Steep
1224
1240
 
1225
1241
  when :or
1226
1242
  yield_self do
1227
- t1, t2 = each_child_node(node).map {|child| synthesize(child) }
1243
+ c1, c2 = node.children
1244
+ t1 = synthesize(c1, hint: hint)
1245
+ t2 = synthesize(c2, hint: unwrap(t1))
1228
1246
  type = union_type(unwrap(t1), t2)
1229
1247
  typing.add_typing(node, type)
1230
1248
  end
@@ -1272,7 +1290,7 @@ module Steep
1272
1290
  if (body = clause.children.last)
1273
1291
  if var_names && var_types && test_types.all? {|type| type.is_a?(AST::Types::Name::Class) }
1274
1292
  var_types_in_body = test_types.flat_map {|test_type|
1275
- filtered_types = var_types.select {|var_type| var_type.name == test_type.name }
1293
+ filtered_types = var_types.select {|var_type| var_type.is_a?(AST::Types::Name::Base) && var_type.name == test_type.name }
1276
1294
  if filtered_types.empty?
1277
1295
  to_instance_type(test_type)
1278
1296
  else
@@ -1281,7 +1299,7 @@ module Steep
1281
1299
  }
1282
1300
  var_types.reject! {|type|
1283
1301
  var_types_in_body.any? {|test_type|
1284
- test_type.name == type.name
1302
+ type.is_a?(AST::Types::Name::Base) && test_type.name == type.name
1285
1303
  }
1286
1304
  }
1287
1305
 
@@ -1761,7 +1779,7 @@ module Steep
1761
1779
  receiver_type = unwrap(receiver_type)
1762
1780
  end
1763
1781
 
1764
- return_type = case receiver_type
1782
+ return_type = case expand_alias(receiver_type)
1765
1783
  when AST::Types::Any
1766
1784
  typing.add_typing node, AST::Builtin.any_type
1767
1785
 
@@ -2041,7 +2059,7 @@ module Steep
2041
2059
  )
2042
2060
  else
2043
2061
  hash_elements = params.required_keywords.merge(
2044
- method_type.optional_keywords.transform_values do |type|
2062
+ method_type.params.optional_keywords.transform_values do |type|
2045
2063
  AST::Types::Union.build(types: [type, AST::Builtin.nil_type],
2046
2064
  location: method_type.location)
2047
2065
  end
@@ -2465,10 +2483,12 @@ module Steep
2465
2483
  when annotations.instance_dynamics.include?(method_name)
2466
2484
  # ok
2467
2485
  else
2468
- typing.add_error Errors::MethodDefinitionMissing.new(node: node,
2469
- module_name: module_name.name,
2470
- kind: :instance,
2471
- missing_method: method_name)
2486
+ if module_name.name == module_context&.class_name
2487
+ typing.add_error Errors::MethodDefinitionMissing.new(node: node,
2488
+ module_name: module_name.name,
2489
+ kind: :instance,
2490
+ missing_method: method_name)
2491
+ end
2472
2492
  end
2473
2493
  end
2474
2494
  expected_module_method_names.each do |method_name|
@@ -2478,10 +2498,12 @@ module Steep
2478
2498
  when annotations.module_dynamics.include?(method_name)
2479
2499
  # ok
2480
2500
  else
2481
- typing.add_error Errors::MethodDefinitionMissing.new(node: node,
2482
- module_name: module_name.name,
2483
- kind: :module,
2484
- missing_method: method_name)
2501
+ if module_name.name == module_context&.class_name
2502
+ typing.add_error Errors::MethodDefinitionMissing.new(node: node,
2503
+ module_name: module_name.name,
2504
+ kind: :module,
2505
+ missing_method: method_name)
2506
+ end
2485
2507
  end
2486
2508
  end
2487
2509
 
@@ -2659,7 +2681,8 @@ module Steep
2659
2681
  end
2660
2682
 
2661
2683
  def try_hash_type(node, hint)
2662
- if hint.is_a?(AST::Types::Record)
2684
+ case hint
2685
+ when AST::Types::Record
2663
2686
  typing.new_child do |child_typing|
2664
2687
  new_construction = with_new_typing(child_typing)
2665
2688
  elements = {}
@@ -2699,6 +2722,10 @@ module Steep
2699
2722
  hash = AST::Types::Record.new(elements: elements)
2700
2723
  typing.add_typing(node, hash)
2701
2724
  end
2725
+ when AST::Types::Union
2726
+ hint.types.find do |type|
2727
+ try_hash_type(node, type)
2728
+ end
2702
2729
  end
2703
2730
  end
2704
2731
  end
data/lib/steep/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Steep
2
- VERSION = "0.9.0"
2
+ VERSION = "0.10.0"
3
3
  end
data/lib/steep.rb CHANGED
@@ -7,6 +7,8 @@ require "active_support/core_ext/object/try"
7
7
  require "logger"
8
8
  require "active_support/tagged_logging"
9
9
  require "rainbow"
10
+ require "listen"
11
+ require 'pry'
10
12
 
11
13
  require "steep/ast/namespace"
12
14
  require "steep/names"
@@ -72,13 +74,17 @@ require "steep/type_inference/block_params"
72
74
  require "steep/type_inference/constant_env"
73
75
  require "steep/type_inference/type_env"
74
76
 
75
- require "steep/drivers/utils/validator"
77
+ require "steep/project"
78
+ require "steep/project/file"
79
+ require "steep/project/listener"
80
+ require "steep/project/options"
76
81
  require "steep/drivers/utils/each_signature"
77
82
  require "steep/drivers/check"
78
83
  require "steep/drivers/validate"
79
84
  require "steep/drivers/annotations"
80
85
  require "steep/drivers/scaffold"
81
86
  require "steep/drivers/print_interface"
87
+ require "steep/drivers/watch"
82
88
 
83
89
  if ENV["NO_COLOR"]
84
90
  Rainbow.enabled = false
data/sig/project.rbi ADDED
@@ -0,0 +1,106 @@
1
+ class Pathname
2
+ end
3
+
4
+ class Time
5
+ def self.now: -> instance
6
+ def < : (Time) -> bool
7
+ def >=: (Time) -> bool
8
+ end
9
+
10
+ type annotation = any
11
+
12
+ class Steep::Source
13
+ def self.parse: (String, path: String, labeling: any) -> instance
14
+ def annotations: (block: any, builder: any, current_module: any) -> Array<annotation>
15
+ def node: -> any
16
+ end
17
+
18
+ class Steep::Typing
19
+ attr_reader errors: Array<type_error>
20
+ attr_reader nodes: any
21
+ end
22
+
23
+ type type_error = any
24
+
25
+ class Steep::Project::Options
26
+ attr_accessor fallback_any_is_error: bool
27
+ attr_accessor allow_missing_definitions: bool
28
+ end
29
+
30
+ class Parser::SyntaxError
31
+ end
32
+
33
+ class Steep::Project::SourceFile
34
+ attr_reader options: Options
35
+ attr_reader path: Pathname
36
+ attr_accessor content: String
37
+ attr_reader content_updated_at: Time
38
+
39
+ attr_reader source: (Source | Parser::SyntaxError | nil)
40
+ attr_reader typing: Typing?
41
+ attr_reader last_type_checked_at: Time?
42
+
43
+ def initialize: (path: Pathname, options: Options) -> any
44
+ def requires_type_check?: -> bool
45
+ def invalidate: -> void
46
+ def parse: -> (Source | Parser::SyntaxError)
47
+ def errors: -> Array<type_error>?
48
+ def type_check: (any) -> void
49
+ end
50
+
51
+ class Steep::Project::SignatureFile
52
+ attr_reader path: Pathname
53
+ attr_accessor content: String
54
+ attr_reader content_updated_at: Time
55
+
56
+ def parse: -> Array<any>
57
+ end
58
+
59
+ interface Steep::Project::_Listener
60
+ def parse_signature: <'x> (project: Project, file: SignatureFile) { -> 'x } -> 'x
61
+ def parse_source: <'x> (project: Project, file: SourceFile) { -> 'x } -> 'x
62
+ def check: <'x> (project: Project) { -> 'x } -> 'x
63
+ def load_signature: <'x> (project: Project) { -> 'x } -> 'x
64
+ def validate_signature: <'x> (project: Project) { -> 'x } -> 'x
65
+ def type_check_source: <'x> (project: Project, file: SourceFile) { -> 'x } -> 'x
66
+ def clear_project: <'x> (project: Project) { -> 'x } -> 'x
67
+ end
68
+
69
+ class Steep::Project::SignatureLoaded
70
+ attr_reader check: any
71
+ attr_reader loaded_at: Time
72
+ attr_reader file_paths: Array<Pathname>
73
+
74
+ def initialize: (check: any, loaded_at: Time, file_paths: Array<Pathname>) -> any
75
+ end
76
+
77
+ class Steep::Project::SignatureHasSyntaxError
78
+ attr_reader errors: Hash<Pathname, any>
79
+ def initialize: (errors: Hash<Pathname, any>) -> any
80
+ end
81
+
82
+ class Steep::Project::SignatureHasError
83
+ attr_reader errors: Array<any>
84
+ def initialize: (errors: Array<any>) -> any
85
+ end
86
+
87
+ class Steep::Project
88
+ attr_reader listener: _Listener
89
+ attr_reader source_files: Hash<Pathname, SourceFile>
90
+ attr_reader signature_files: Hash<Pathname, SignatureFile>
91
+
92
+ attr_reader signature: (SignatureLoaded | SignatureHasError | SignatureHasSyntaxError | nil)
93
+
94
+ def initialize: (?_Listener?) -> any
95
+ def clear: -> void
96
+ def type_check: (?force_signatures: bool, ?force_sources: bool) -> void
97
+
98
+ def success?: -> bool
99
+ def has_type_error?: -> bool
100
+ def errors: -> Array<type_error>
101
+ def each_updated_source: (?force: bool) { (SourceFile) -> void } -> void
102
+ | (?force: bool) -> Enumerator<SourceFile, void>
103
+ def signature_updated?: -> bool
104
+ def reload_signature: -> void
105
+ def validate_signature: (any) -> Array<any>
106
+ end
data/smoke/hash/f.rb ADDED
@@ -0,0 +1,11 @@
1
+ # @type method commit: (Hash<Symbol, String?>) -> { repo: String, branch: String?, tag: String?, commit: String? }?
2
+ def commit(hash)
3
+ if repo = hash[:foo]
4
+ {
5
+ repo: repo,
6
+ branch: hash[:bar],
7
+ tag: hash[:baz],
8
+ commit: hash[:commit]
9
+ }
10
+ end
11
+ end
data/stdlib/builtin.rbi CHANGED
@@ -240,6 +240,9 @@ class Hash<'key, 'value>
240
240
  def key?: ('key) -> bool
241
241
  def merge: (Hash<'key, 'value>) -> Hash<'key, 'value>
242
242
  def delete: ('key) -> 'value?
243
+ def each_value: { ('value) -> void } -> self
244
+ | -> Enumerator<'valud, self>
245
+ def empty?: -> bool
243
246
 
244
247
  include Enumerable<['key, 'value], self>
245
248
  end
data/steep.gemspec CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.required_ruby_version = '>= 2.5.0'
26
26
 
27
- spec.add_development_dependency "bundler", "~> 1.13"
27
+ spec.add_development_dependency "bundler", ">= 1.13"
28
28
  spec.add_development_dependency "rake", "~> 10.0"
29
29
  spec.add_development_dependency "minitest", "~> 5.0"
30
30
  spec.add_development_dependency "racc", "~> 1.4"
@@ -33,4 +33,6 @@ Gem::Specification.new do |spec|
33
33
  spec.add_runtime_dependency "ast_utils", "~> 0.3.0"
34
34
  spec.add_runtime_dependency "activesupport", "~> 5.1"
35
35
  spec.add_runtime_dependency "rainbow", "~> 2.2.2", "< 4.0"
36
+ spec.add_runtime_dependency "listen", "~> 3.1"
37
+ spec.add_runtime_dependency "pry", "~> 0.12.2"
36
38
  end
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: steep
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.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: 2018-11-12 00:00:00.000000000 Z
11
+ date: 2019-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.13'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.13'
27
27
  - !ruby/object:Gem::Dependency
@@ -128,6 +128,34 @@ dependencies:
128
128
  - - "<"
129
129
  - !ruby/object:Gem::Version
130
130
  version: '4.0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: listen
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '3.1'
138
+ type: :runtime
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: '3.1'
145
+ - !ruby/object:Gem::Dependency
146
+ name: pry
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: 0.12.2
152
+ type: :runtime
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: 0.12.2
131
159
  description: Gradual Typing for Ruby
132
160
  email:
133
161
  - matsumoto@soutaro.com
@@ -189,8 +217,8 @@ files:
189
217
  - lib/steep/drivers/print_interface.rb
190
218
  - lib/steep/drivers/scaffold.rb
191
219
  - lib/steep/drivers/utils/each_signature.rb
192
- - lib/steep/drivers/utils/validator.rb
193
220
  - lib/steep/drivers/validate.rb
221
+ - lib/steep/drivers/watch.rb
194
222
  - lib/steep/errors.rb
195
223
  - lib/steep/interface/abstract.rb
196
224
  - lib/steep/interface/builder.rb
@@ -202,6 +230,10 @@ files:
202
230
  - lib/steep/names.rb
203
231
  - lib/steep/parser.rb
204
232
  - lib/steep/parser.y
233
+ - lib/steep/project.rb
234
+ - lib/steep/project/file.rb
235
+ - lib/steep/project/listener.rb
236
+ - lib/steep/project/options.rb
205
237
  - lib/steep/signature/errors.rb
206
238
  - lib/steep/source.rb
207
239
  - lib/steep/subtyping/check.rb
@@ -220,8 +252,7 @@ files:
220
252
  - lib/steep/typing.rb
221
253
  - lib/steep/version.rb
222
254
  - manual/annotations.md
223
- - sig/signature.rbi
224
- - sig/types.rbi
255
+ - sig/project.rbi
225
256
  - smoke/alias/a.rb
226
257
  - smoke/alias/a.rbi
227
258
  - smoke/alias/b.rb
@@ -268,6 +299,7 @@ files:
268
299
  - smoke/hash/d.rb
269
300
  - smoke/hash/e.rb
270
301
  - smoke/hash/e.rbi
302
+ - smoke/hash/f.rb
271
303
  - smoke/hello/hello.rb
272
304
  - smoke/hello/hello.rbi
273
305
  - smoke/if/a.rb
@@ -1,110 +0,0 @@
1
- module Steep
2
- module Drivers
3
- module Utils
4
- class Validator
5
- attr_reader :stdout
6
- attr_reader :stderr
7
- attr_reader :verbose
8
-
9
- def initialize(stdout:, stderr:, verbose:)
10
- @stdout = stdout
11
- @stderr = stderr
12
- @verbose = verbose
13
- end
14
-
15
- def run(env:, builder:, check:)
16
- result = true
17
-
18
- env.each do |sig|
19
- yield sig if block_given?
20
-
21
- case sig
22
- when AST::Signature::Interface
23
- yield_self do
24
- instance_interface = builder.build_interface(sig.name)
25
-
26
- args = instance_interface.params.map {|var| AST::Types::Var.fresh(var) }
27
- instance_type = AST::Types::Name::Interface.new(name: sig.name, args: args)
28
-
29
- instance_interface.instantiate(type: instance_type,
30
- args: args,
31
- instance_type: instance_type,
32
- module_type: nil).validate(check)
33
- end
34
-
35
- when AST::Signature::Module
36
- yield_self do
37
- instance_interface = builder.build_instance(sig.name)
38
- instance_args = instance_interface.params.map {|var| AST::Types::Var.fresh(var) }
39
-
40
- module_interface = builder.build_module(sig.name)
41
- module_args = module_interface.params.map {|var| AST::Types::Var.fresh(var) }
42
-
43
- instance_type = AST::Types::Name::Instance.new(name: sig.name, args: instance_args)
44
- module_type = AST::Types::Name::Module.new(name: sig.name)
45
-
46
- stdout.puts "👀 Validating instance methods..." if verbose
47
- instance_interface.instantiate(type: instance_type,
48
- args: instance_args,
49
- instance_type: instance_type,
50
- module_type: module_type).validate(check)
51
-
52
- stdout.puts "👀 Validating class methods..." if verbose
53
- module_interface.instantiate(type: module_type,
54
- args: module_args,
55
- instance_type: instance_type,
56
- module_type: module_type).validate(check)
57
- end
58
-
59
- when AST::Signature::Class
60
- yield_self do
61
- instance_interface = builder.build_instance(sig.name)
62
- instance_args = instance_interface.params.map {|var| AST::Types::Var.fresh(var) }
63
-
64
- module_interface = builder.build_class(sig.name, constructor: true)
65
- module_args = module_interface.params.map {|var| AST::Types::Var.fresh(var) }
66
-
67
- instance_type = AST::Types::Name::Instance.new(name: sig.name, args: instance_args)
68
- module_type = AST::Types::Name::Class.new(name: sig.name, constructor: true)
69
-
70
- stdout.puts "👀 Validating instance methods..." if verbose
71
- instance_interface.instantiate(type: instance_type,
72
- args: instance_args,
73
- instance_type: instance_type,
74
- module_type: module_type).validate(check)
75
-
76
- stdout.puts "👀 Validating class methods..." if verbose
77
- module_interface.instantiate(type: module_type,
78
- args: module_args,
79
- instance_type: instance_type,
80
- module_type: module_type).validate(check)
81
- end
82
- end
83
-
84
- rescue Interface::Instantiated::InvalidMethodOverrideError => exn
85
- result = false
86
- stdout.puts "😱 #{exn.message}"
87
- exn.result.trace.each do |s, t|
88
- case s
89
- when Interface::Method
90
- stdout.puts " #{s.name}(#{s.type_name}) <: #{t.name}(#{t.type_name})"
91
- when Interface::MethodType
92
- stdout.puts " #{s} <: #{t} (#{s.location&.name||"?"}:#{s.location&.start_line||"?"})"
93
- else
94
- stdout.puts " #{s} <: #{t}"
95
- end
96
- end
97
- stdout.puts " 🚨 #{exn.result.error.message}"
98
-
99
- rescue Interface::Instantiated::InvalidIvarOverrideError => exn
100
- result = false
101
- stdout.puts "😱 #{exn.message}"
102
-
103
- end
104
-
105
- result
106
- end
107
- end
108
- end
109
- end
110
- end