rbs 1.7.0 → 2.0.0.pre1
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/CHANGELOG.md +95 -3
- data/core/array.rbs +3 -3
- data/core/builtin.rbs +4 -0
- data/core/enumerable.rbs +3 -3
- data/core/thread.rbs +1 -1
- data/docs/collection.md +23 -1
- data/docs/syntax.md +117 -61
- data/ext/rbs_extension/constants.c +2 -6
- data/ext/rbs_extension/constants.h +1 -2
- data/ext/rbs_extension/parser.c +221 -185
- data/ext/rbs_extension/parserstate.c +6 -2
- data/ext/rbs_extension/parserstate.h +10 -0
- data/ext/rbs_extension/ruby_objs.c +17 -17
- data/ext/rbs_extension/ruby_objs.h +3 -4
- data/lib/rbs/ast/declarations.rb +6 -99
- data/lib/rbs/ast/type_param.rb +134 -0
- data/lib/rbs/cli.rb +33 -5
- data/lib/rbs/collection/config/lockfile_generator.rb +26 -18
- data/lib/rbs/collection/sources/git.rb +18 -7
- data/lib/rbs/collection/sources/rubygems.rb +7 -0
- data/lib/rbs/collection/sources/stdlib.rb +6 -0
- data/lib/rbs/definition.rb +9 -0
- data/lib/rbs/definition_builder.rb +78 -16
- data/lib/rbs/environment.rb +32 -8
- data/lib/rbs/environment_loader.rb +0 -2
- data/lib/rbs/environment_walker.rb +4 -1
- data/lib/rbs/errors.rb +31 -6
- data/lib/rbs/location_aux.rb +2 -0
- data/lib/rbs/method_type.rb +29 -6
- data/lib/rbs/prototype/rb.rb +3 -3
- data/lib/rbs/prototype/rbi.rb +8 -6
- data/lib/rbs/prototype/runtime.rb +4 -4
- data/lib/rbs/type_alias_regularity.rb +115 -0
- data/lib/rbs/types.rb +100 -23
- data/lib/rbs/validator.rb +99 -15
- data/lib/rbs/variance_calculator.rb +60 -31
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +2 -14
- data/lib/rbs.rb +2 -0
- data/schema/decls.json +19 -46
- data/schema/methodType.json +1 -1
- data/schema/typeParam.json +36 -0
- data/schema/types.json +8 -2
- data/sig/collection/collections.rbs +13 -2
- data/sig/collection/config.rbs +2 -2
- data/sig/declarations.rbs +15 -62
- data/sig/definition.rbs +11 -1
- data/sig/definition_builder.rbs +37 -1
- data/sig/environment.rbs +7 -1
- data/sig/environment_walker.rbs +26 -0
- data/sig/errors.rbs +28 -3
- data/sig/location.rbs +3 -1
- data/sig/locator.rbs +1 -1
- data/sig/method_types.rbs +25 -4
- data/sig/type_alias_regularity.rbs +92 -0
- data/sig/type_param.rbs +74 -0
- data/sig/types.rbs +37 -8
- data/sig/validator.rbs +38 -2
- data/sig/variance_calculator.rbs +50 -0
- data/sig/writer.rbs +1 -1
- data/stdlib/bigdecimal-math/0/manifest.yaml +2 -0
- data/stdlib/csv/0/manifest.yaml +2 -0
- data/stdlib/date/0/date.rbs +2 -2
- data/stdlib/logger/0/manifest.yaml +2 -0
- data/stdlib/net-http/0/manifest.yaml +2 -0
- data/stdlib/openssl/0/manifest.yaml +2 -0
- data/stdlib/prime/0/manifest.yaml +2 -0
- data/stdlib/resolv/0/manifest.yaml +3 -0
- data/stdlib/set/0/set.rbs +3 -3
- data/stdlib/uri/0/common.rbs +10 -5
- data/stdlib/uri/0/ftp.rbs +10 -0
- data/stdlib/uri/0/mailto.rbs +5 -0
- data/stdlib/uri/0/ws.rbs +10 -0
- data/stdlib/uri/0/wss.rbs +7 -0
- data/stdlib/yaml/0/manifest.yaml +3 -0
- data/steep/Gemfile.lock +10 -10
- metadata +21 -5
- data/lib/ruby/signature.rb +0 -7
data/lib/rbs/environment.rb
CHANGED
@@ -39,22 +39,29 @@ module RBS
|
|
39
39
|
|
40
40
|
def validate_type_params
|
41
41
|
unless decls.empty?
|
42
|
+
# @type var hd_decl: MultiEntry::D[module_decl]
|
43
|
+
# @type var tl_decls: Array[MultiEntry::D[module_decl]]
|
42
44
|
hd_decl, *tl_decls = decls
|
43
45
|
raise unless hd_decl
|
44
46
|
|
45
47
|
hd_params = hd_decl.decl.type_params
|
46
|
-
hd_names = hd_params.params.map(&:name)
|
47
48
|
|
48
49
|
tl_decls.each do |tl_decl|
|
49
50
|
tl_params = tl_decl.decl.type_params
|
50
51
|
|
51
|
-
unless hd_params
|
52
|
+
unless compatible_params?(hd_params, tl_params)
|
52
53
|
raise GenericParameterMismatchError.new(name: name, decl: tl_decl.decl)
|
53
54
|
end
|
54
55
|
end
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
59
|
+
def compatible_params?(ps1, ps2)
|
60
|
+
if ps1.size == ps2.size
|
61
|
+
ps1 == AST::TypeParam.rename(ps2, new_names: ps1.map(&:name))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
58
65
|
def type_params
|
59
66
|
primary.decl.type_params
|
60
67
|
end
|
@@ -240,17 +247,19 @@ module RBS
|
|
240
247
|
array.unshift(head + decl.name.to_namespace)
|
241
248
|
end
|
242
249
|
|
250
|
+
outer_context = context.drop(1)
|
251
|
+
|
243
252
|
case decl
|
244
253
|
when AST::Declarations::Class
|
245
254
|
outer_ = outer + [decl]
|
246
255
|
prefix_ = prefix + decl.name.to_namespace
|
247
256
|
AST::Declarations::Class.new(
|
248
257
|
name: decl.name.with_prefix(prefix),
|
249
|
-
type_params: decl.type_params,
|
258
|
+
type_params: resolve_type_params(resolver, decl.type_params, context: context),
|
250
259
|
super_class: decl.super_class&.yield_self do |super_class|
|
251
260
|
AST::Declarations::Class::Super.new(
|
252
|
-
name: absolute_type_name(resolver, super_class.name, context:
|
253
|
-
args: super_class.args.map {|type| absolute_type(resolver, type, context:
|
261
|
+
name: absolute_type_name(resolver, super_class.name, context: outer_context),
|
262
|
+
args: super_class.args.map {|type| absolute_type(resolver, type, context: outer_context) },
|
254
263
|
location: super_class.location
|
255
264
|
)
|
256
265
|
end,
|
@@ -278,7 +287,7 @@ module RBS
|
|
278
287
|
prefix_ = prefix + decl.name.to_namespace
|
279
288
|
AST::Declarations::Module.new(
|
280
289
|
name: decl.name.with_prefix(prefix),
|
281
|
-
type_params: decl.type_params,
|
290
|
+
type_params: resolve_type_params(resolver, decl.type_params, context: context),
|
282
291
|
self_types: decl.self_types.map do |module_self|
|
283
292
|
AST::Declarations::Module::Self.new(
|
284
293
|
name: absolute_type_name(resolver, module_self.name, context: context),
|
@@ -308,7 +317,7 @@ module RBS
|
|
308
317
|
when AST::Declarations::Interface
|
309
318
|
AST::Declarations::Interface.new(
|
310
319
|
name: decl.name.with_prefix(prefix),
|
311
|
-
type_params: decl.type_params,
|
320
|
+
type_params: resolve_type_params(resolver, decl.type_params, context: context),
|
312
321
|
members: decl.members.map do |member|
|
313
322
|
resolve_member(resolver, member, context: context)
|
314
323
|
end,
|
@@ -319,6 +328,7 @@ module RBS
|
|
319
328
|
when AST::Declarations::Alias
|
320
329
|
AST::Declarations::Alias.new(
|
321
330
|
name: decl.name.with_prefix(prefix),
|
331
|
+
type_params: resolve_type_params(resolver, decl.type_params, context: context),
|
322
332
|
type: absolute_type(resolver, decl.type, context: context),
|
323
333
|
location: decl.location,
|
324
334
|
annotations: decl.annotations,
|
@@ -342,7 +352,7 @@ module RBS
|
|
342
352
|
name: member.name,
|
343
353
|
kind: member.kind,
|
344
354
|
types: member.types.map do |type|
|
345
|
-
|
355
|
+
resolve_method_type(resolver, type, context: context)
|
346
356
|
end,
|
347
357
|
comment: member.comment,
|
348
358
|
overload: member.overload?,
|
@@ -429,6 +439,20 @@ module RBS
|
|
429
439
|
end
|
430
440
|
end
|
431
441
|
|
442
|
+
def resolve_method_type(resolver, type, context:)
|
443
|
+
type.map_type do |ty|
|
444
|
+
absolute_type(resolver, ty, context: context)
|
445
|
+
end.map_type_bound do |bound|
|
446
|
+
_ = absolute_type(resolver, bound, context: context)
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
def resolve_type_params(resolver, params, context:)
|
451
|
+
params.map do |param|
|
452
|
+
param.map_type {|type| _ = absolute_type(resolver, type, context: context) }
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
432
456
|
def absolute_type_name(resolver, type_name, context:)
|
433
457
|
resolver.resolve(type_name, context: context) || type_name
|
434
458
|
end
|
@@ -57,7 +57,7 @@ module RBS
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
when name.alias?
|
60
|
-
each_type_node builder.
|
60
|
+
each_type_node builder.expand_alias1(name), &block
|
61
61
|
else
|
62
62
|
raise "Unexpected TypeNameNode with type_name=#{name}"
|
63
63
|
end
|
@@ -126,6 +126,9 @@ module RBS
|
|
126
126
|
end
|
127
127
|
when RBS::Types::Alias
|
128
128
|
yield TypeNameNode.new(type_name: type.name)
|
129
|
+
type.args.each do |ty|
|
130
|
+
each_type_node(ty, &block)
|
131
|
+
end
|
129
132
|
when RBS::Types::Union, RBS::Types::Intersection, RBS::Types::Tuple
|
130
133
|
type.types.each do |ty|
|
131
134
|
each_type_node ty, &block
|
data/lib/rbs/errors.rb
CHANGED
@@ -14,11 +14,11 @@ module RBS
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
class
|
18
|
-
class LoadingError <
|
19
|
-
class DefinitionError <
|
17
|
+
class BaseError < StandardError; end
|
18
|
+
class LoadingError < BaseError; end
|
19
|
+
class DefinitionError < BaseError; end
|
20
20
|
|
21
|
-
class ParsingError <
|
21
|
+
class ParsingError < BaseError
|
22
22
|
attr_reader :location
|
23
23
|
attr_reader :error_message
|
24
24
|
attr_reader :token_type
|
@@ -105,7 +105,7 @@ module RBS
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
|
-
class NoTypeFoundError <
|
108
|
+
class NoTypeFoundError < BaseError
|
109
109
|
attr_reader :type_name
|
110
110
|
attr_reader :location
|
111
111
|
|
@@ -416,7 +416,7 @@ module RBS
|
|
416
416
|
end
|
417
417
|
end
|
418
418
|
|
419
|
-
class RecursiveTypeAliasError <
|
419
|
+
class RecursiveTypeAliasError < BaseError
|
420
420
|
attr_reader :alias_names
|
421
421
|
attr_reader :location
|
422
422
|
|
@@ -431,4 +431,29 @@ module RBS
|
|
431
431
|
@alias_names.map(&:name).join(', ')
|
432
432
|
end
|
433
433
|
end
|
434
|
+
|
435
|
+
class NonregularTypeAliasError < BaseError
|
436
|
+
attr_reader :diagnostic
|
437
|
+
attr_reader :location
|
438
|
+
|
439
|
+
def initialize(diagnostic:, location:)
|
440
|
+
@diagnostic = diagnostic
|
441
|
+
@location = location
|
442
|
+
|
443
|
+
super "#{Location.to_string location}: Nonregular generic type alias is prohibited: #{diagnostic.type_name}, #{diagnostic.nonregular_type}"
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
class CyclicTypeParameterBound < BaseError
|
448
|
+
attr_reader :params, :type_name, :method_name, :location
|
449
|
+
|
450
|
+
def initialize(type_name:, method_name:, params:, location:)
|
451
|
+
@type_name = type_name
|
452
|
+
@method_name = method_name
|
453
|
+
@params = params
|
454
|
+
@location = location
|
455
|
+
|
456
|
+
super "#{Location.to_string(location)}: Cyclic type parameter bound is prohibited"
|
457
|
+
end
|
458
|
+
end
|
434
459
|
end
|
data/lib/rbs/location_aux.rb
CHANGED
data/lib/rbs/method_type.rb
CHANGED
@@ -29,11 +29,18 @@ module RBS
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def sub(s)
|
32
|
-
s.without(*
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
32
|
+
sub = s.without(*type_param_names)
|
33
|
+
|
34
|
+
self.class.new(
|
35
|
+
type_params: type_params.map do |param|
|
36
|
+
param.map_type do |bound|
|
37
|
+
bound.map_type {|ty| ty.sub(sub) }
|
38
|
+
end
|
39
|
+
end,
|
40
|
+
type: type.sub(sub),
|
41
|
+
block: block&.sub(sub),
|
42
|
+
location: location
|
43
|
+
)
|
37
44
|
end
|
38
45
|
|
39
46
|
def update(type_params: self.type_params, type: self.type, block: self.block, location: self.location)
|
@@ -48,7 +55,7 @@ module RBS
|
|
48
55
|
def free_variables(set = Set.new)
|
49
56
|
type.free_variables(set)
|
50
57
|
block&.type&.free_variables(set)
|
51
|
-
set.subtract(
|
58
|
+
set.subtract(type_param_names)
|
52
59
|
end
|
53
60
|
|
54
61
|
def map_type(&block)
|
@@ -62,6 +69,18 @@ module RBS
|
|
62
69
|
)
|
63
70
|
end
|
64
71
|
|
72
|
+
def map_type_bound(&block)
|
73
|
+
if type_params.empty?
|
74
|
+
self
|
75
|
+
else
|
76
|
+
self.update(
|
77
|
+
type_params: type_params.map {|param|
|
78
|
+
param.map_type(&block)
|
79
|
+
}
|
80
|
+
)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
65
84
|
def each_type(&block)
|
66
85
|
if block
|
67
86
|
type.each_type(&block)
|
@@ -89,5 +108,9 @@ module RBS
|
|
89
108
|
"[#{type_params.join(", ")}] #{s}"
|
90
109
|
end
|
91
110
|
end
|
111
|
+
|
112
|
+
def type_param_names
|
113
|
+
type_params.map(&:name)
|
114
|
+
end
|
92
115
|
end
|
93
116
|
end
|
data/lib/rbs/prototype/rb.rb
CHANGED
@@ -49,7 +49,7 @@ module RBS
|
|
49
49
|
annotations: [],
|
50
50
|
comment: nil,
|
51
51
|
location: nil,
|
52
|
-
type_params:
|
52
|
+
type_params: []
|
53
53
|
)
|
54
54
|
decls << top
|
55
55
|
end
|
@@ -88,7 +88,7 @@ module RBS
|
|
88
88
|
kls = AST::Declarations::Class.new(
|
89
89
|
name: const_to_name(class_name),
|
90
90
|
super_class: super_class && AST::Declarations::Class::Super.new(name: const_to_name(super_class), args: [], location: nil),
|
91
|
-
type_params:
|
91
|
+
type_params: [],
|
92
92
|
members: [],
|
93
93
|
annotations: [],
|
94
94
|
location: nil,
|
@@ -108,7 +108,7 @@ module RBS
|
|
108
108
|
|
109
109
|
mod = AST::Declarations::Module.new(
|
110
110
|
name: const_to_name(module_name),
|
111
|
-
type_params:
|
111
|
+
type_params: [],
|
112
112
|
self_types: [],
|
113
113
|
members: [],
|
114
114
|
annotations: [],
|
data/lib/rbs/prototype/rbi.rb
CHANGED
@@ -48,7 +48,7 @@ module RBS
|
|
48
48
|
modules.push AST::Declarations::Class.new(
|
49
49
|
name: nested_name(name),
|
50
50
|
super_class: super_class && AST::Declarations::Class::Super.new(name: const_to_name(super_class), args: [], location: nil),
|
51
|
-
type_params:
|
51
|
+
type_params: [],
|
52
52
|
members: [],
|
53
53
|
annotations: [],
|
54
54
|
location: nil,
|
@@ -65,7 +65,7 @@ module RBS
|
|
65
65
|
def push_module(name, comment:)
|
66
66
|
modules.push AST::Declarations::Module.new(
|
67
67
|
name: nested_name(name),
|
68
|
-
type_params:
|
68
|
+
type_params: [],
|
69
69
|
members: [],
|
70
70
|
annotations: [],
|
71
71
|
location: nil,
|
@@ -212,10 +212,12 @@ module RBS
|
|
212
212
|
end
|
213
213
|
end
|
214
214
|
|
215
|
-
current_module.type_params.
|
216
|
-
|
217
|
-
|
218
|
-
|
215
|
+
current_module.type_params << AST::TypeParam.new(
|
216
|
+
name: node.children[0],
|
217
|
+
variance: variance || :invariant,
|
218
|
+
location: nil,
|
219
|
+
upper_bound: nil
|
220
|
+
)
|
219
221
|
end
|
220
222
|
else
|
221
223
|
name = node.children[0].yield_self do |n|
|
@@ -371,7 +371,7 @@ module RBS
|
|
371
371
|
unless decl
|
372
372
|
decl = AST::Declarations::Class.new(
|
373
373
|
name: to_type_name(only_name(mod)),
|
374
|
-
type_params:
|
374
|
+
type_params: [],
|
375
375
|
super_class: generate_super_class(mod),
|
376
376
|
members: [],
|
377
377
|
annotations: [],
|
@@ -425,7 +425,7 @@ module RBS
|
|
425
425
|
unless decl
|
426
426
|
decl = AST::Declarations::Module.new(
|
427
427
|
name: to_type_name(only_name(mod)),
|
428
|
-
type_params:
|
428
|
+
type_params: [],
|
429
429
|
self_types: [],
|
430
430
|
members: [],
|
431
431
|
annotations: [],
|
@@ -479,7 +479,7 @@ module RBS
|
|
479
479
|
if outer_module.is_a?(Class)
|
480
480
|
outer_decl = AST::Declarations::Class.new(
|
481
481
|
name: to_type_name(outer_module_name),
|
482
|
-
type_params:
|
482
|
+
type_params: [],
|
483
483
|
super_class: generate_super_class(outer_module),
|
484
484
|
members: [],
|
485
485
|
annotations: [],
|
@@ -489,7 +489,7 @@ module RBS
|
|
489
489
|
else
|
490
490
|
outer_decl = AST::Declarations::Module.new(
|
491
491
|
name: to_type_name(outer_module_name),
|
492
|
-
type_params:
|
492
|
+
type_params: [],
|
493
493
|
self_types: [],
|
494
494
|
members: [],
|
495
495
|
annotations: [],
|
@@ -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
@@ -26,6 +26,14 @@ module RBS
|
|
26
26
|
enum_for :each_type
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
def map_type(&block)
|
31
|
+
if block
|
32
|
+
_ = self
|
33
|
+
else
|
34
|
+
enum_for(:map_type)
|
35
|
+
end
|
36
|
+
end
|
29
37
|
end
|
30
38
|
|
31
39
|
module Bases
|
@@ -261,6 +269,18 @@ module RBS
|
|
261
269
|
location: location
|
262
270
|
)
|
263
271
|
end
|
272
|
+
|
273
|
+
def map_type(&block)
|
274
|
+
if block
|
275
|
+
Interface.new(
|
276
|
+
name: name,
|
277
|
+
args: args.map {|type| yield type },
|
278
|
+
location: location
|
279
|
+
)
|
280
|
+
else
|
281
|
+
enum_for(:map_type)
|
282
|
+
end
|
283
|
+
end
|
264
284
|
end
|
265
285
|
|
266
286
|
class ClassInstance
|
@@ -291,46 +311,58 @@ module RBS
|
|
291
311
|
location: location
|
292
312
|
)
|
293
313
|
end
|
314
|
+
|
315
|
+
def map_type(&block)
|
316
|
+
if block
|
317
|
+
ClassInstance.new(
|
318
|
+
name: name,
|
319
|
+
args: args.map {|type| yield type },
|
320
|
+
location: location
|
321
|
+
)
|
322
|
+
else
|
323
|
+
enum_for :map_type
|
324
|
+
end
|
325
|
+
end
|
294
326
|
end
|
295
327
|
|
296
328
|
class Alias
|
297
329
|
attr_reader :location
|
298
|
-
attr_reader :name
|
299
330
|
|
300
|
-
|
331
|
+
include Application
|
332
|
+
|
333
|
+
def initialize(name:, args:, location:)
|
301
334
|
@name = name
|
335
|
+
@args = args
|
302
336
|
@location = location
|
303
337
|
end
|
304
338
|
|
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
339
|
def to_json(state = _ = nil)
|
319
|
-
{ class: :alias, name: name, location: location }.to_json(state)
|
340
|
+
{ class: :alias, name: name, args: args, location: location }.to_json(state)
|
320
341
|
end
|
321
342
|
|
322
|
-
def
|
323
|
-
name.
|
343
|
+
def sub(s)
|
344
|
+
Alias.new(name: name, args: args.map {|ty| ty.sub(s) }, location: location)
|
324
345
|
end
|
325
346
|
|
326
|
-
|
327
|
-
|
328
|
-
def map_type_name
|
347
|
+
def map_type_name(&block)
|
329
348
|
Alias.new(
|
330
349
|
name: yield(name, location, self),
|
350
|
+
args: args.map {|arg| arg.map_type_name(&block) },
|
331
351
|
location: location
|
332
352
|
)
|
333
353
|
end
|
354
|
+
|
355
|
+
def map_type(&block)
|
356
|
+
if block
|
357
|
+
Alias.new(
|
358
|
+
name: name,
|
359
|
+
args: args.map {|type| yield type },
|
360
|
+
location: location
|
361
|
+
)
|
362
|
+
else
|
363
|
+
enum_for :map_type
|
364
|
+
end
|
365
|
+
end
|
334
366
|
end
|
335
367
|
|
336
368
|
class Tuple
|
@@ -391,6 +423,17 @@ module RBS
|
|
391
423
|
location: location
|
392
424
|
)
|
393
425
|
end
|
426
|
+
|
427
|
+
def map_type(&block)
|
428
|
+
if block
|
429
|
+
Tuple.new(
|
430
|
+
types: types.map {|type| yield type },
|
431
|
+
location: location
|
432
|
+
)
|
433
|
+
else
|
434
|
+
enum_for :map_type
|
435
|
+
end
|
436
|
+
end
|
394
437
|
end
|
395
438
|
|
396
439
|
class Record
|
@@ -433,7 +476,7 @@ module RBS
|
|
433
476
|
return "{ }" if self.fields.empty?
|
434
477
|
|
435
478
|
fields = self.fields.map do |key, type|
|
436
|
-
if key.is_a?(Symbol) && key.match?(/\A[A-Za-z_][A-Za-z_]*\z/)
|
479
|
+
if key.is_a?(Symbol) && key.match?(/\A[A-Za-z_][A-Za-z_]*\z/)
|
437
480
|
"#{key}: #{type}"
|
438
481
|
else
|
439
482
|
"#{key.inspect} => #{type}"
|
@@ -456,6 +499,17 @@ module RBS
|
|
456
499
|
location: location
|
457
500
|
)
|
458
501
|
end
|
502
|
+
|
503
|
+
def map_type(&block)
|
504
|
+
if block
|
505
|
+
Record.new(
|
506
|
+
fields: fields.transform_values {|type| yield type },
|
507
|
+
location: location
|
508
|
+
)
|
509
|
+
else
|
510
|
+
enum_for :map_type
|
511
|
+
end
|
512
|
+
end
|
459
513
|
end
|
460
514
|
|
461
515
|
class Optional
|
@@ -515,6 +569,17 @@ module RBS
|
|
515
569
|
location: location
|
516
570
|
)
|
517
571
|
end
|
572
|
+
|
573
|
+
def map_type(&block)
|
574
|
+
if block
|
575
|
+
Optional.new(
|
576
|
+
type: yield(type),
|
577
|
+
location: location
|
578
|
+
)
|
579
|
+
else
|
580
|
+
enum_for :map_type
|
581
|
+
end
|
582
|
+
end
|
518
583
|
end
|
519
584
|
|
520
585
|
class Union
|
@@ -690,7 +755,7 @@ module RBS
|
|
690
755
|
|
691
756
|
def to_s
|
692
757
|
if name
|
693
|
-
if Parser::KEYWORDS.include?(name)
|
758
|
+
if Parser::KEYWORDS.include?(name.to_s)
|
694
759
|
"#{type} `#{name}`"
|
695
760
|
else
|
696
761
|
"#{type} #{name}"
|
@@ -1058,6 +1123,18 @@ module RBS
|
|
1058
1123
|
location: location
|
1059
1124
|
)
|
1060
1125
|
end
|
1126
|
+
|
1127
|
+
def map_type(&block)
|
1128
|
+
if block
|
1129
|
+
Proc.new(
|
1130
|
+
type: type.map_type(&block),
|
1131
|
+
block: self.block&.map_type(&block),
|
1132
|
+
location: location
|
1133
|
+
)
|
1134
|
+
else
|
1135
|
+
enum_for :map_type
|
1136
|
+
end
|
1137
|
+
end
|
1061
1138
|
end
|
1062
1139
|
|
1063
1140
|
class Literal
|