rbs 1.7.1 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,115 @@
1
+ module RBS
2
+ class TypeAliasRegularity
3
+ class Diagnostic
4
+ attr_reader :type_name, :nonregular_type
5
+
6
+ def initialize(type_name:, nonregular_type:)
7
+ @type_name = type_name
8
+ @nonregular_type = nonregular_type
9
+ end
10
+ end
11
+
12
+ attr_reader :env, :builder, :diagnostics
13
+
14
+ def initialize(env:)
15
+ @env = env
16
+ @builder = DefinitionBuilder.new(env: env)
17
+ @diagnostics = {}
18
+ end
19
+
20
+ def validate
21
+ diagnostics.clear
22
+
23
+ each_mutual_alias_defs do |names|
24
+ # Find the first generic type alias in strongly connected component.
25
+ # This is to skip the regularity check when the alias is not generic.
26
+ names.each do |name|
27
+ # @type break: nil
28
+ if type = build_alias_type(name)
29
+ # Running validation only once from the first generic type is enough, because they are mutual recursive definition.
30
+ validate_alias_type(type, names, {})
31
+ break
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ def validate_alias_type(alias_type, names, types)
38
+ if names.include?(alias_type.name)
39
+ if ex_type = types[alias_type.name]
40
+ unless compatible_args?(ex_type.args, alias_type.args)
41
+ diagnostics[alias_type.name] ||=
42
+ Diagnostic.new(type_name: alias_type.name, nonregular_type: alias_type)
43
+ end
44
+
45
+ return
46
+ else
47
+ types[alias_type.name] = alias_type
48
+ end
49
+
50
+ expanded = builder.expand_alias2(alias_type.name, alias_type.args)
51
+ each_alias_type(expanded) do |at|
52
+ validate_alias_type(at, names, types)
53
+ end
54
+ end
55
+ end
56
+
57
+ def build_alias_type(name)
58
+ entry = env.alias_decls[name] or raise "Unknown alias name: #{name}"
59
+ unless entry.decl.type_params.empty?
60
+ as = entry.decl.type_params.each.map {|param| Types::Variable.new(name: param.name, location: nil) }
61
+ Types::Alias.new(name: name, args: as, location: nil)
62
+ end
63
+ end
64
+
65
+ def compatible_args?(args1, args2)
66
+ if args1.size == args2.size
67
+ args1.zip(args2).all? do |t1, t2|
68
+ t1.is_a?(Types::Bases::Any) ||
69
+ t2.is_a?(Types::Bases::Any) ||
70
+ t1 == t2
71
+ end
72
+ end
73
+ end
74
+
75
+ def nonregular?(type_name)
76
+ diagnostics[type_name]
77
+ end
78
+
79
+ def each_mutual_alias_defs(&block)
80
+ # @type var each_node: TSort::_EachNode[TypeName]
81
+ each_node = __skip__ = -> (&block) do
82
+ env.alias_decls.each_value do |decl|
83
+ block[decl.name]
84
+ end
85
+ end
86
+ # @type var each_child: TSort::_EachChild[TypeName]
87
+ each_child = __skip__ = -> (name, &block) do
88
+ type = builder.expand_alias1(name)
89
+ each_alias_type(type) do |ty|
90
+ block[ty.name]
91
+ end
92
+ end
93
+
94
+ TSort.each_strongly_connected_component(each_node, each_child) do |names|
95
+ yield Set.new(names)
96
+ end
97
+ end
98
+
99
+ def each_alias_type(type, &block)
100
+ if type.is_a?(RBS::Types::Alias)
101
+ yield type
102
+ end
103
+
104
+ type.each_type do |ty|
105
+ each_alias_type(ty, &block)
106
+ end
107
+ end
108
+
109
+ def self.validate(env:)
110
+ self.new(env: env).tap do |validator|
111
+ validator.validate()
112
+ end
113
+ end
114
+ end
115
+ end
data/lib/rbs/types.rb CHANGED
@@ -295,39 +295,27 @@ module RBS
295
295
 
296
296
  class Alias
297
297
  attr_reader :location
298
- attr_reader :name
299
298
 
300
- def initialize(name:, location:)
299
+ include Application
300
+
301
+ def initialize(name:, args:, location:)
301
302
  @name = name
303
+ @args = args
302
304
  @location = location
303
305
  end
304
306
 
305
- def ==(other)
306
- other.is_a?(Alias) && other.name == name
307
- end
308
-
309
- alias eql? ==
310
-
311
- def hash
312
- self.class.hash ^ name.hash
313
- end
314
-
315
- include NoFreeVariables
316
- include NoSubst
317
-
318
307
  def to_json(state = _ = nil)
319
- { class: :alias, name: name, location: location }.to_json(state)
308
+ { class: :alias, name: name, args: args, location: location }.to_json(state)
320
309
  end
321
310
 
322
- def to_s(level = 0)
323
- name.to_s
311
+ def sub(s)
312
+ Alias.new(name: name, args: args.map {|ty| ty.sub(s) }, location: location)
324
313
  end
325
314
 
326
- include EmptyEachType
327
-
328
- def map_type_name
315
+ def map_type_name(&block)
329
316
  Alias.new(
330
317
  name: yield(name, location, self),
318
+ args: args.map {|arg| arg.map_type_name(&block) },
331
319
  location: location
332
320
  )
333
321
  end
@@ -433,7 +421,7 @@ module RBS
433
421
  return "{ }" if self.fields.empty?
434
422
 
435
423
  fields = self.fields.map do |key, type|
436
- if key.is_a?(Symbol) && key.match?(/\A[A-Za-z_][A-Za-z_]*\z/) && !Parser::KEYWORDS.include?(key)
424
+ if key.is_a?(Symbol) && key.match?(/\A[A-Za-z_][A-Za-z_]*\z/)
437
425
  "#{key}: #{type}"
438
426
  else
439
427
  "#{key.inspect} => #{type}"
data/lib/rbs/validator.rb CHANGED
@@ -2,10 +2,12 @@ module RBS
2
2
  class Validator
3
3
  attr_reader :env
4
4
  attr_reader :resolver
5
+ attr_reader :definition_builder
5
6
 
6
7
  def initialize(env:, resolver:)
7
8
  @env = env
8
9
  @resolver = resolver
10
+ @definition_builder = DefinitionBuilder.new(env: env)
9
11
  end
10
12
 
11
13
  def absolute_type(type, context:)
@@ -17,8 +19,8 @@ module RBS
17
19
  # Validates presence of the relative type, and application arity match.
18
20
  def validate_type(type, context:)
19
21
  case type
20
- when Types::ClassInstance, Types::Interface
21
- # @type var type: Types::ClassInstance | Types::Interface
22
+ when Types::ClassInstance, Types::Interface, Types::Alias
23
+ # @type var type: Types::ClassInstance | Types::Interface | Types::Alias
22
24
  if type.name.namespace.relative?
23
25
  type = _ = absolute_type(type, context: context) do |_|
24
26
  NoTypeFoundError.check!(type.name.absolute!, env: env, location: type.location)
@@ -30,6 +32,8 @@ module RBS
30
32
  env.class_decls[type.name]&.type_params
31
33
  when Types::Interface
32
34
  env.interface_decls[type.name]&.decl&.type_params
35
+ when Types::Alias
36
+ env.alias_decls[type.name]&.decl&.type_params
33
37
  end
34
38
 
35
39
  unless type_params
@@ -43,8 +47,8 @@ module RBS
43
47
  location: type.location
44
48
  )
45
49
 
46
- when Types::Alias, Types::ClassSingleton
47
- # @type var type: Types::Alias | Types::ClassSingleton
50
+ when Types::ClassSingleton
51
+ # @type var type: Types::ClassSingleton
48
52
  type = _ = absolute_type(type, context: context) { type.name.absolute! }
49
53
  NoTypeFoundError.check!(type.name, env: env, location: type.location)
50
54
  end
@@ -55,11 +59,40 @@ module RBS
55
59
  end
56
60
 
57
61
  def validate_type_alias(entry:)
58
- @type_alias_dependency ||= TypeAliasDependency.new(env: env)
59
- if @type_alias_dependency.circular_definition?(entry.decl.name)
62
+ type_name = entry.decl.name
63
+
64
+ if type_alias_dependency.circular_definition?(type_name)
60
65
  location = entry.decl.location or raise
61
- raise RecursiveTypeAliasError.new(alias_names: [entry.decl.name], location: location)
66
+ raise RecursiveTypeAliasError.new(alias_names: [type_name], location: location)
67
+ end
68
+
69
+ if diagnostic = type_alias_regularity.nonregular?(type_name)
70
+ location = entry.decl.location or raise
71
+ raise NonregularTypeAliasError.new(diagnostic: diagnostic, location: location)
72
+ end
73
+
74
+ unless entry.decl.type_params.empty?
75
+ calculator = VarianceCalculator.new(builder: definition_builder)
76
+ result = calculator.in_type_alias(name: type_name)
77
+ if set = result.incompatible?(entry.decl.type_params)
78
+ set.each do |param_name|
79
+ param = entry.decl.type_params[param_name] or raise
80
+ raise InvalidVarianceAnnotationError.new(
81
+ type_name: type_name,
82
+ param: param,
83
+ location: entry.decl.type.location
84
+ )
85
+ end
86
+ end
62
87
  end
63
88
  end
89
+
90
+ def type_alias_dependency
91
+ @type_alias_dependency ||= TypeAliasDependency.new(env: env)
92
+ end
93
+
94
+ def type_alias_regularity
95
+ @type_alias_regularity ||= TypeAliasRegularity.validate(env: env)
96
+ end
64
97
  end
65
98
  end
@@ -54,6 +54,21 @@ module RBS
54
54
  false
55
55
  end
56
56
  end
57
+
58
+ def incompatible?(params)
59
+ # @type set: Hash[Symbol]
60
+ set = Set[]
61
+
62
+ params.each do |param|
63
+ unless compatible?(param.name, with_annotation: param.variance)
64
+ set << param.name
65
+ end
66
+ end
67
+
68
+ unless set.empty?
69
+ set
70
+ end
71
+ end
57
72
  end
58
73
 
59
74
  attr_reader :builder
@@ -69,19 +84,12 @@ module RBS
69
84
  def in_method_type(method_type:, variables:)
70
85
  result = Result.new(variables: variables)
71
86
 
72
- method_type.type.each_param do |param|
73
- type(param.type, result: result, context: :contravariant)
74
- end
87
+ function(method_type.type, result: result, context: :covariant)
75
88
 
76
89
  if block = method_type.block
77
- block.type.each_param do |param|
78
- type(param.type, result: result, context: :covariant)
79
- end
80
- type(block.type.return_type, result: result, context: :contravariant)
90
+ function(block.type, result: result, context: :contravariant)
81
91
  end
82
92
 
83
- type(method_type.type.return_type, result: result, context: :covariant)
84
-
85
93
  result
86
94
  end
87
95
 
@@ -97,6 +105,14 @@ module RBS
97
105
  end
98
106
  end
99
107
 
108
+ def in_type_alias(name:)
109
+ decl = env.alias_decls[name].decl or raise
110
+ variables = decl.type_params.each.map(&:name)
111
+ Result.new(variables: variables).tap do |result|
112
+ type(decl.type, result: result, context: :covariant)
113
+ end
114
+ end
115
+
100
116
  def type(type, result:, context:)
101
117
  case type
102
118
  when Types::Variable
@@ -110,7 +126,7 @@ module RBS
110
126
  result.invariant(type.name)
111
127
  end
112
128
  end
113
- when Types::ClassInstance, Types::Interface
129
+ when Types::ClassInstance, Types::Interface, Types::Alias
114
130
  NoTypeFoundError.check!(type.name,
115
131
  env: env,
116
132
  location: type.location)
@@ -120,6 +136,8 @@ module RBS
120
136
  env.class_decls[type.name].type_params
121
137
  when Types::Interface
122
138
  env.interface_decls[type.name].decl.type_params
139
+ when Types::Alias
140
+ env.alias_decls[type.name].decl.type_params
123
141
  end
124
142
 
125
143
  type.args.each.with_index do |ty, i|
@@ -130,26 +148,36 @@ module RBS
130
148
  when :covariant
131
149
  type(ty, result: result, context: context)
132
150
  when :contravariant
133
- # @type var con: variance
134
- con = case context
135
- when :invariant
136
- :invariant
137
- when :covariant
138
- :contravariant
139
- when :contravariant
140
- :covariant
141
- else
142
- raise
143
- end
144
- type(ty, result: result, context: con)
151
+ type(ty, result: result, context: negate(context))
145
152
  end
146
153
  end
147
- when Types::Tuple, Types::Record, Types::Union, Types::Intersection
148
- # Covariant types
154
+ when Types::Proc
155
+ function(type.type, result: result, context: context)
156
+ else
149
157
  type.each_type do |ty|
150
158
  type(ty, result: result, context: context)
151
159
  end
152
160
  end
153
161
  end
162
+
163
+ def function(type, result:, context:)
164
+ type.each_param do |param|
165
+ type(param.type, result: result, context: negate(context))
166
+ end
167
+ type(type.return_type, result: result, context: context)
168
+ end
169
+
170
+ def negate(variance)
171
+ case variance
172
+ when :invariant
173
+ :invariant
174
+ when :covariant
175
+ :contravariant
176
+ when :contravariant
177
+ :covariant
178
+ else
179
+ raise
180
+ end
181
+ end
154
182
  end
155
183
  end
data/lib/rbs/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RBS
2
- VERSION = "1.7.1"
2
+ VERSION = "1.8.0"
3
3
  end
data/lib/rbs/writer.rb CHANGED
@@ -119,7 +119,7 @@ module RBS
119
119
  when AST::Declarations::Alias
120
120
  write_comment decl.comment
121
121
  write_annotation decl.annotations
122
- puts "type #{decl.name} = #{decl.type}"
122
+ puts "type #{name_and_params(decl.name, decl.type_params)} = #{decl.type}"
123
123
 
124
124
  when AST::Declarations::Interface
125
125
  write_comment decl.comment
data/lib/rbs.rb CHANGED
@@ -45,6 +45,7 @@ require "rbs/repository"
45
45
  require "rbs/ancestor_graph"
46
46
  require "rbs/locator"
47
47
  require "rbs/type_alias_dependency"
48
+ require "rbs/type_alias_regularity"
48
49
  require "rbs/collection"
49
50
 
50
51
  require "rbs_extension"
data/schema/decls.json CHANGED
@@ -12,6 +12,18 @@
12
12
  "name": {
13
13
  "type": "string"
14
14
  },
15
+ "type_params": {
16
+ "type": "object",
17
+ "properties": {
18
+ "params": {
19
+ "type": "array",
20
+ "items": {
21
+ "$ref": "#/definitions/moduleTypeParam"
22
+ }
23
+ }
24
+ },
25
+ "required": ["params"]
26
+ },
15
27
  "type": {
16
28
  "$ref": "types.json"
17
29
  },
@@ -28,7 +40,7 @@
28
40
  "$ref": "comment.json"
29
41
  }
30
42
  },
31
- "required": ["declaration", "name", "type", "annotations", "location", "comment"]
43
+ "required": ["declaration", "name", "type_params", "type", "annotations", "location", "comment"]
32
44
  },
33
45
  "constant": {
34
46
  "title": "Constant declaration: `VERSION: String`, ...",
data/schema/types.json CHANGED
@@ -106,7 +106,7 @@
106
106
  "required": ["class", "name", "args", "location"]
107
107
  },
108
108
  "alias": {
109
- "title": "Type alias: `u`, `ty`, `json`, ...",
109
+ "title": "Type alias: `u`, `ty`, `json`, `list[Integer]`, ...",
110
110
  "type": "object",
111
111
  "properties": {
112
112
  "class": {
@@ -116,11 +116,17 @@
116
116
  "name": {
117
117
  "type": "string"
118
118
  },
119
+ "args": {
120
+ "type": "array",
121
+ "items": {
122
+ "$ref": "#"
123
+ }
124
+ },
119
125
  "location": {
120
126
  "$ref": "location.json"
121
127
  }
122
128
  },
123
- "required": ["class", "name", "location"]
129
+ "required": ["class", "name", "args", "location"]
124
130
  },
125
131
  "tuple": {
126
132
  "title": "Tuple type: `[Foo, bar]`, ...",
data/sig/declarations.rbs CHANGED
@@ -217,19 +217,22 @@ module RBS
217
217
  end
218
218
 
219
219
  class Alias < Base
220
- # type loc = Location
221
- # ^^^^ keyword
222
- # ^^^ name
223
- # ^ eq
224
- type loc = Location[:keyword | :name | :eq, bot]
220
+ # type loc[T] = Location[T, bot]
221
+ # ^^^^ keyword
222
+ # ^^^ name
223
+ # ^^^ type_params
224
+ # ^ eq
225
+ #
226
+ type loc = Location[:keyword | :name | :eq, :type_params]
225
227
 
226
228
  attr_reader name: TypeName
229
+ attr_reader type_params: ModuleTypeParams
227
230
  attr_reader type: Types::t
228
231
  attr_reader annotations: Array[Annotation]
229
232
  attr_reader location: loc?
230
233
  attr_reader comment: Comment?
231
234
 
232
- def initialize: (name: TypeName, type: Types::t, annotations: Array[Annotation], location: loc?, comment: Comment?) -> void
235
+ def initialize: (name: TypeName, type_params: ModuleTypeParams, type: Types::t, annotations: Array[Annotation], location: loc?, comment: Comment?) -> void
233
236
 
234
237
  include _HashEqual
235
238
  include _ToJson
@@ -43,8 +43,37 @@ module RBS
43
43
 
44
44
  def define_methods: (Definition, interface_methods: Hash[Symbol, Definition::Method], methods: MethodBuilder::Methods, super_interface_method: bool) -> void
45
45
 
46
+ # Expand a type alias of given name without type arguments.
47
+ # Raises an error if the type alias requires arguments.
48
+ #
49
+ # Assume `type foo[T] = [T, T]`:
50
+ #
51
+ # ```
52
+ # expand_alias("::foo") # => error
53
+ # ```
54
+ #
46
55
  def expand_alias: (TypeName) -> Types::t
47
56
 
57
+ # Expand a type alias of given name with arguments of `untyped`.
58
+ #
59
+ # Assume `type foo[T] = [T, T]`:
60
+ #
61
+ # ```
62
+ # expand_alias1("::foo") # => [untyped, untyped]
63
+ # ```
64
+ #
65
+ def expand_alias1: (TypeName) -> Types::t
66
+
67
+ # Expand a type alias of given name with `args`.
68
+ #
69
+ # Assume `type foo[T] = [T, T]`:
70
+ #
71
+ # ```
72
+ # expand_alias2("::foo", ["::Integer"]) # => [::Integer, ::Integer]
73
+ # ```
74
+ #
75
+ def expand_alias2: (TypeName, Array[Types::t] args) -> Types::t
76
+
48
77
  def update: (env: Environment, ancestor_builder: AncestorBuilder, except: _Each[TypeName]) -> DefinitionBuilder
49
78
  end
50
79
  end
@@ -1,4 +1,28 @@
1
1
  module RBS
2
+ # EnvironmentWalker provides topological sort of class/module definitions.
3
+ #
4
+ # If a method, attribute, or ancestor in a class definition have a reference to another class, it is dependency.
5
+ #
6
+ # ```rb
7
+ # walker = EnvironmentWalker.new(env: env)
8
+ #
9
+ # walker.each_strongly_connected_component do |scc|
10
+ # # Yields an array of strongly connected components.
11
+ # end
12
+ # ```
13
+ #
14
+ # The `#only_ancestors!` method limits the dependency only to ancestors.
15
+ # Only super classes and included modules are dependencies with the option.
16
+ # This is useful to calculate the dependencies of class hierarchy.
17
+ #
18
+ # ```rb
19
+ # walker = EnvironmentWalker.new(env: env).only_ancestors!
20
+ #
21
+ # walker.each_strongly_connected_component do |scc|
22
+ # # Yields an array of strongly connected components.
23
+ # end
24
+ # ```
25
+ #
2
26
  class EnvironmentWalker
3
27
  class InstanceNode
4
28
  attr_reader type_name: TypeName
@@ -32,6 +56,8 @@ module RBS
32
56
 
33
57
  def tsort_each_child: (node) { (node) -> void } -> void
34
58
 
59
+ private
60
+
35
61
  def each_type_name: (Types::t) { (TypeName) -> void } -> void
36
62
 
37
63
  def each_type_node: (Types::t) { (node) -> void } -> void
data/sig/errors.rbs CHANGED
@@ -220,4 +220,14 @@ module RBS
220
220
 
221
221
  def name: () -> String
222
222
  end
223
+
224
+ class NonregularTypeAliasError < LoadingError
225
+ # Diagnostic reported from `TypeAliasRegularity`.
226
+ attr_reader diagnostic: TypeAliasRegularity::Diagnostic
227
+
228
+ # Location of the definition.
229
+ attr_reader location: Location[untyped, untyped]?
230
+
231
+ def initialize: (diagnostic: TypeAliasRegularity::Diagnostic, location: Location[untyped, untyped]?) -> void
232
+ end
223
233
  end
@@ -0,0 +1,92 @@
1
+ module RBS
2
+ # `TypeAliasRegularity` validates if a type alias is regular or not.
3
+ #
4
+ # Generic and recursive type alias cannot be polymorphic in their definitions.
5
+ #
6
+ # ```rbs
7
+ # type foo[T] = Integer
8
+ # | foo[T]? # Allowed. The type argument of `foo` doesn't change.
9
+ #
10
+ # type bar[T] = Integer
11
+ # | foo[T]
12
+ # | foo[Array[T]] # Allowed. There are two type arguments `T` and `Array[T]` of `foo`, but it's not definition of `foo`.
13
+ #
14
+ # type baz[T] = Integer
15
+ # | baz[Array[T]] # Error. Recursive definition of `baz` has different type argument from the definition.
16
+ # ```
17
+ #
18
+ # The `#nonregular?` method can be used to test if given type name is regular or not.
19
+ #
20
+ # ```rb
21
+ # validator = RBS::TypeAliasRegularity.validate(env: env)
22
+ #
23
+ # validator.nonregular?(TypeName("::foo")) # => nil
24
+ # validator.nonregular?(TypeName("::bar")) # => nil
25
+ # validator.nonregular?(TypeName("::baz")) # => TypeAliasRegularity::Diagnostic
26
+ # ```
27
+ #
28
+ # A special case is when the type argument is `untyped`.
29
+ #
30
+ # ```rbs
31
+ # type foo[T] = Integer | foo[untyped] # This is allowed.
32
+ # ```
33
+ #
34
+ class TypeAliasRegularity
35
+ attr_reader env: Environment
36
+
37
+ attr_reader builder: DefinitionBuilder
38
+
39
+ attr_reader diagnostics: Hash[TypeName, Diagnostic]
40
+
41
+ # `Diagnostic` represents an non-regular type alias declaration error.
42
+ # It consists of the name of the alias type and a type on which the nonregularity is detected.
43
+ #
44
+ # ```rbs
45
+ # type t[T] = Integer | t[T?]
46
+ # ```
47
+ #
48
+ # The type `t` is nonregular because it contains `t[T?]` on it's right hand side.
49
+ #
50
+ # ```
51
+ # diagnostic = validator.nonregular?(TypeName("::t"))
52
+ # diagnostic.type_name # => TypeName("::t")
53
+ # diagnostic.nonregular_type # => t[T?]
54
+ # ```
55
+ #
56
+ class Diagnostic
57
+ attr_reader type_name: TypeName
58
+
59
+ attr_reader nonregular_type: Types::Alias
60
+
61
+ def initialize: (type_name: TypeName, nonregular_type: Types::Alias) -> void
62
+ end
63
+
64
+ # Returns new instance which already run `#validate`.
65
+ #
66
+ def self.validate: (env: Environment) -> TypeAliasRegularity
67
+
68
+ def initialize: (env: Environment) -> void
69
+
70
+ # Returns `Diagnostic` instance if the alias type is nonregular.
71
+ # Regurns `nil` if the alias type is regular.
72
+ #
73
+ def nonregular?: (TypeName) -> Diagnostic?
74
+
75
+ def validate: () -> void
76
+
77
+ private
78
+
79
+ def validate_alias_type: (Types::Alias, Set[TypeName], Hash[TypeName, Types::Alias]) -> void
80
+
81
+ # Returns alias type for given type name, if the alias is generic.
82
+ # Returns nil if the type alias is not generic.
83
+ #
84
+ def build_alias_type: (TypeName) -> Types::Alias?
85
+
86
+ def compatible_args?: (Array[Types::t], Array[Types::t]) -> boolish
87
+
88
+ def each_alias_type: (Types::t) { (Types::Alias) -> void } -> void
89
+
90
+ def each_mutual_alias_defs: () { (Set[TypeName]) -> void } -> void
91
+ end
92
+ end