steep 0.9.0 → 0.10.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.
@@ -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