rbs 1.8.1 → 2.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +51 -4
- data/docs/collection.md +23 -1
- data/docs/syntax.md +94 -41
- data/ext/rbs_extension/constants.c +2 -6
- data/ext/rbs_extension/constants.h +1 -2
- data/ext/rbs_extension/parser.c +212 -178
- data/ext/rbs_extension/parserstate.c +6 -2
- data/ext/rbs_extension/parserstate.h +10 -0
- data/ext/rbs_extension/ruby_objs.c +9 -11
- data/ext/rbs_extension/ruby_objs.h +1 -2
- data/lib/rbs/ast/declarations.rb +0 -97
- data/lib/rbs/ast/type_param.rb +134 -0
- data/lib/rbs/cli.rb +32 -4
- data/lib/rbs/collection/config/lockfile_generator.rb +26 -18
- data/lib/rbs/collection/sources/git.rb +9 -0
- 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 +20 -14
- data/lib/rbs/environment.rb +32 -9
- data/lib/rbs/environment_loader.rb +0 -2
- data/lib/rbs/errors.rb +20 -7
- 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/types.rb +89 -0
- data/lib/rbs/validator.rb +56 -1
- data/lib/rbs/variance_calculator.rb +9 -8
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +1 -13
- data/lib/rbs.rb +1 -0
- data/schema/decls.json +16 -55
- data/schema/methodType.json +1 -1
- data/schema/typeParam.json +36 -0
- data/sig/collection/collections.rbs +9 -0
- data/sig/collection/config.rbs +2 -2
- data/sig/declarations.rbs +8 -58
- data/sig/definition.rbs +11 -1
- data/sig/definition_builder.rbs +1 -1
- data/sig/environment.rbs +7 -1
- data/sig/errors.rbs +19 -4
- data/sig/location.rbs +3 -1
- data/sig/locator.rbs +1 -1
- data/sig/method_types.rbs +25 -4
- data/sig/type_param.rbs +74 -0
- data/sig/types.rbs +27 -1
- data/sig/validator.rbs +31 -2
- data/sig/variance_calculator.rbs +1 -1
- 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/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/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
- metadata +19 -4
@@ -0,0 +1,134 @@
|
|
1
|
+
module RBS
|
2
|
+
module AST
|
3
|
+
class TypeParam
|
4
|
+
attr_reader :name, :variance, :location, :upper_bound
|
5
|
+
|
6
|
+
def initialize(name:, variance:, upper_bound:, location:)
|
7
|
+
@name = name
|
8
|
+
@variance = variance
|
9
|
+
@upper_bound = upper_bound
|
10
|
+
@location = location
|
11
|
+
@unchecked = false
|
12
|
+
end
|
13
|
+
|
14
|
+
def unchecked!(value = true)
|
15
|
+
@unchecked = value ? true : false
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def unchecked?
|
20
|
+
@unchecked
|
21
|
+
end
|
22
|
+
|
23
|
+
def ==(other)
|
24
|
+
other.is_a?(TypeParam) &&
|
25
|
+
other.name == name &&
|
26
|
+
other.variance == variance &&
|
27
|
+
other.upper_bound == upper_bound &&
|
28
|
+
other.unchecked? == unchecked?
|
29
|
+
end
|
30
|
+
|
31
|
+
alias eql? ==
|
32
|
+
|
33
|
+
def hash
|
34
|
+
self.class.hash ^ name.hash ^ variance.hash ^ upper_bound.hash ^ unchecked?.hash
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_json(state = JSON::State.new)
|
38
|
+
{
|
39
|
+
name: name,
|
40
|
+
variance: variance,
|
41
|
+
unchecked: unchecked?,
|
42
|
+
location: location,
|
43
|
+
upper_bound: upper_bound
|
44
|
+
}.to_json(state)
|
45
|
+
end
|
46
|
+
|
47
|
+
def rename(name)
|
48
|
+
TypeParam.new(
|
49
|
+
name: name,
|
50
|
+
variance: variance,
|
51
|
+
upper_bound: upper_bound,
|
52
|
+
location: location
|
53
|
+
).unchecked!(unchecked?)
|
54
|
+
end
|
55
|
+
|
56
|
+
def map_type(&block)
|
57
|
+
if b = upper_bound
|
58
|
+
_upper_bound = yield(b)
|
59
|
+
end
|
60
|
+
|
61
|
+
TypeParam.new(
|
62
|
+
name: name,
|
63
|
+
variance: variance,
|
64
|
+
upper_bound: _upper_bound,
|
65
|
+
location: location
|
66
|
+
).unchecked!(unchecked?)
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.resolve_variables(params)
|
70
|
+
return if params.empty?
|
71
|
+
|
72
|
+
vars = Set.new(params.map(&:name))
|
73
|
+
|
74
|
+
params.map! do |param|
|
75
|
+
param.map_type {|bound| _ = subst_var(vars, bound) }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.subst_var(vars, type)
|
80
|
+
case type
|
81
|
+
when Types::ClassInstance
|
82
|
+
namespace = type.name.namespace
|
83
|
+
if namespace.relative? && namespace.empty? && vars.member?(type.name.name)
|
84
|
+
return Types::Variable.new(name: type.name.name, location: type.location)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
type.map_type {|t| subst_var(vars, t) }
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.rename(params, new_names:)
|
92
|
+
raise unless params.size == new_names.size
|
93
|
+
|
94
|
+
subst = Substitution.build(new_names, Types::Variable.build(new_names))
|
95
|
+
|
96
|
+
params.map.with_index do |param, index|
|
97
|
+
new_name = new_names[index]
|
98
|
+
|
99
|
+
TypeParam.new(
|
100
|
+
name: new_name,
|
101
|
+
variance: param.variance,
|
102
|
+
upper_bound: param.upper_bound&.map_type {|type| type.sub(subst) },
|
103
|
+
location: param.location
|
104
|
+
).unchecked!(param.unchecked?)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def to_s
|
109
|
+
s = ""
|
110
|
+
|
111
|
+
if unchecked?
|
112
|
+
s << "unchecked "
|
113
|
+
end
|
114
|
+
|
115
|
+
case variance
|
116
|
+
when :invariant
|
117
|
+
# nop
|
118
|
+
when :covariant
|
119
|
+
s << "out "
|
120
|
+
when :contravariant
|
121
|
+
s << "in "
|
122
|
+
end
|
123
|
+
|
124
|
+
s << name.to_s
|
125
|
+
|
126
|
+
if type = upper_bound
|
127
|
+
s << " < #{type}"
|
128
|
+
end
|
129
|
+
|
130
|
+
s
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/lib/rbs/cli.rb
CHANGED
@@ -430,7 +430,7 @@ EOU
|
|
430
430
|
builder = DefinitionBuilder.new(env: env)
|
431
431
|
validator = Validator.new(env: env, resolver: TypeNameResolver.from_env(env))
|
432
432
|
|
433
|
-
env.class_decls.
|
433
|
+
env.class_decls.each do |name, decl|
|
434
434
|
stdout.puts "Validating class/module definition: `#{name}`..."
|
435
435
|
builder.build_instance(name).each_type do |type|
|
436
436
|
validator.validate_type type, context: [Namespace.root]
|
@@ -438,13 +438,43 @@ EOU
|
|
438
438
|
builder.build_singleton(name).each_type do |type|
|
439
439
|
validator.validate_type type, context: [Namespace.root]
|
440
440
|
end
|
441
|
+
|
442
|
+
d = decl.primary.decl
|
443
|
+
|
444
|
+
validator.validate_type_params(
|
445
|
+
d.type_params,
|
446
|
+
type_name: name,
|
447
|
+
location: d.location&.aref(:type_params)
|
448
|
+
)
|
449
|
+
|
450
|
+
decl.decls.each do |d|
|
451
|
+
d.decl.each_member do |member|
|
452
|
+
case member
|
453
|
+
when AST::Members::MethodDefinition
|
454
|
+
validator.validate_method_definition(member, type_name: name)
|
455
|
+
end
|
456
|
+
end
|
457
|
+
end
|
441
458
|
end
|
442
459
|
|
443
|
-
env.interface_decls.
|
460
|
+
env.interface_decls.each do |name, decl|
|
444
461
|
stdout.puts "Validating interface: `#{name}`..."
|
445
462
|
builder.build_interface(name).each_type do |type|
|
446
463
|
validator.validate_type type, context: [Namespace.root]
|
447
464
|
end
|
465
|
+
|
466
|
+
validator.validate_type_params(
|
467
|
+
decl.decl.type_params,
|
468
|
+
type_name: name,
|
469
|
+
location: decl.decl.location&.aref(:type_params)
|
470
|
+
)
|
471
|
+
|
472
|
+
decl.decl.members.each do |member|
|
473
|
+
case member
|
474
|
+
when AST::Members::MethodDefinition
|
475
|
+
validator.validate_method_definition(member, type_name: name)
|
476
|
+
end
|
477
|
+
end
|
448
478
|
end
|
449
479
|
|
450
480
|
env.constant_decls.each do |name, const|
|
@@ -836,8 +866,6 @@ EOB
|
|
836
866
|
end
|
837
867
|
|
838
868
|
def run_collection(args, options)
|
839
|
-
warn "warning: rbs collection is experimental, and the behavior may change until RBS v2.0"
|
840
|
-
|
841
869
|
opts = collection_options(args)
|
842
870
|
params = {}
|
843
871
|
opts.order args.drop(1), into: params
|
@@ -15,15 +15,20 @@ module RBS
|
|
15
15
|
@lock_path = Config.to_lockfile_path(config_path)
|
16
16
|
@lock = Config.from_path(lock_path) if lock_path.exist? && with_lockfile
|
17
17
|
@gemfile_lock = Bundler::LockfileParser.new(gemfile_lock_path.read)
|
18
|
+
@gem_queue = []
|
18
19
|
end
|
19
20
|
|
20
21
|
def generate
|
21
22
|
config.gems.each do |gem|
|
22
|
-
|
23
|
+
@gem_queue.push({ name: gem['name'], version: gem['version'] })
|
23
24
|
end
|
24
25
|
|
25
26
|
gemfile_lock_gems do |spec|
|
26
|
-
|
27
|
+
@gem_queue.push({ name: spec.name, version: spec.version })
|
28
|
+
end
|
29
|
+
|
30
|
+
while gem = @gem_queue.shift
|
31
|
+
assign_gem(**gem)
|
27
32
|
end
|
28
33
|
remove_ignored_gems!
|
29
34
|
|
@@ -31,30 +36,33 @@ module RBS
|
|
31
36
|
config
|
32
37
|
end
|
33
38
|
|
34
|
-
private def assign_gem(
|
35
|
-
locked = lock&.gem(
|
36
|
-
specified = config.gem(
|
39
|
+
private def assign_gem(name:, version:)
|
40
|
+
locked = lock&.gem(name)
|
41
|
+
specified = config.gem(name)
|
37
42
|
|
38
43
|
return if specified&.dig('ignore')
|
39
44
|
return if specified&.dig('source') # skip if the source is already filled
|
40
45
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
# Find the gem from gem_collection.
|
46
|
-
source = find_source(gem_name: gem_name)
|
46
|
+
# If rbs_collection.lock.yaml contain the gem, use it.
|
47
|
+
# Else find the gem from gem_collection.
|
48
|
+
unless locked
|
49
|
+
source = find_source(name: name)
|
47
50
|
return unless source
|
48
51
|
|
49
52
|
installed_version = version
|
50
|
-
best_version = find_best_version(version: installed_version, versions: source.versions({ 'name' =>
|
51
|
-
|
52
|
-
|
53
|
-
'name' => gem_name,
|
53
|
+
best_version = find_best_version(version: installed_version, versions: source.versions({ 'name' => name }))
|
54
|
+
locked = {
|
55
|
+
'name' => name,
|
54
56
|
'version' => best_version.to_s,
|
55
57
|
'source' => source.to_lockfile,
|
56
58
|
}
|
57
|
-
|
59
|
+
end
|
60
|
+
|
61
|
+
upsert_gem specified, locked
|
62
|
+
source = Sources.from_config_entry(locked['source'])
|
63
|
+
manifest = source.manifest_of(locked) or return
|
64
|
+
manifest['dependencies']&.each do |dep|
|
65
|
+
@gem_queue.push({ name: dep['name'], version: nil} )
|
58
66
|
end
|
59
67
|
end
|
60
68
|
|
@@ -76,10 +84,10 @@ module RBS
|
|
76
84
|
end
|
77
85
|
end
|
78
86
|
|
79
|
-
private def find_source(
|
87
|
+
private def find_source(name:)
|
80
88
|
sources = config.sources
|
81
89
|
|
82
|
-
sources.find { |c| c.has?({ 'name' =>
|
90
|
+
sources.find { |c| c.has?({ 'name' => name, 'revision' => nil } ) }
|
83
91
|
end
|
84
92
|
|
85
93
|
private def find_best_version(version:, versions:)
|
@@ -50,6 +50,15 @@ module RBS
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
+
def manifest_of(config_entry)
|
54
|
+
gem_name = config_entry['name']
|
55
|
+
version = config_entry['version'] or raise
|
56
|
+
gem_dir = gem_repo_dir.join(gem_name, version)
|
57
|
+
|
58
|
+
manifest_path = gem_dir.join('manifest.yaml')
|
59
|
+
YAML.safe_load(manifest_path.read) if manifest_path.exist?
|
60
|
+
end
|
61
|
+
|
53
62
|
private def _install(dest:, config_entry:)
|
54
63
|
gem_name = config_entry['name']
|
55
64
|
version = config_entry['version'] or raise
|
@@ -25,6 +25,13 @@ module RBS
|
|
25
25
|
stdout.puts "Using #{name}:#{version} (#{from})"
|
26
26
|
end
|
27
27
|
|
28
|
+
def manifest_of(config_entry)
|
29
|
+
_, sig_path = gem_sig_path(config_entry)
|
30
|
+
sig_path or raise
|
31
|
+
manifest_path = sig_path.join('manifest.yaml')
|
32
|
+
YAML.safe_load(manifest_path.read) if manifest_path.exist?
|
33
|
+
end
|
34
|
+
|
28
35
|
def to_lockfile
|
29
36
|
{
|
30
37
|
'type' => 'rubygems',
|
@@ -23,6 +23,12 @@ module RBS
|
|
23
23
|
stdout.puts "Using #{name}:#{version} (#{from})"
|
24
24
|
end
|
25
25
|
|
26
|
+
def manifest_of(config_entry)
|
27
|
+
version = config_entry['version'] or raise
|
28
|
+
manifest_path = gem_dir(config_entry).join(version, 'manifest.yaml')
|
29
|
+
YAML.safe_load(manifest_path.read) if manifest_path.exist?
|
30
|
+
end
|
31
|
+
|
26
32
|
def to_lockfile
|
27
33
|
{
|
28
34
|
'type' => 'stdlib',
|
data/lib/rbs/definition.rb
CHANGED
@@ -155,6 +155,15 @@ module RBS
|
|
155
155
|
)
|
156
156
|
end
|
157
157
|
|
158
|
+
def map_type_bound(&block)
|
159
|
+
self.class.new(
|
160
|
+
super_method: super_method&.map_type_bound(&block),
|
161
|
+
defs: defs.map {|defn| defn.update(type: defn.type.map_type_bound(&block)) },
|
162
|
+
accessibility: @accessibility,
|
163
|
+
alias_of: alias_of
|
164
|
+
)
|
165
|
+
end
|
166
|
+
|
158
167
|
def map_method_type(&block)
|
159
168
|
self.class.new(
|
160
169
|
super_method: super_method,
|
@@ -385,7 +385,7 @@ module RBS
|
|
385
385
|
initialize = instance.methods[:initialize]
|
386
386
|
|
387
387
|
if initialize
|
388
|
-
class_params = entry.type_params
|
388
|
+
class_params = entry.type_params
|
389
389
|
|
390
390
|
# Inject a virtual _typed new_.
|
391
391
|
initialize_defs = initialize.defs
|
@@ -394,28 +394,34 @@ module RBS
|
|
394
394
|
defs: initialize_defs.map do |initialize_def|
|
395
395
|
method_type = initialize_def.type
|
396
396
|
|
397
|
-
class_type_param_vars = Set.new(class_params)
|
398
|
-
method_type_param_vars = Set.new(method_type.type_params)
|
397
|
+
class_type_param_vars = Set.new(class_params.map(&:name))
|
398
|
+
method_type_param_vars = Set.new(method_type.type_params.map(&:name))
|
399
399
|
|
400
400
|
if class_type_param_vars.intersect?(method_type_param_vars)
|
401
|
-
|
402
|
-
if class_type_param_vars.include?(name)
|
403
|
-
Types::Variable.fresh(name).name
|
401
|
+
new_method_param_names = method_type.type_params.map do |method_param|
|
402
|
+
if class_type_param_vars.include?(method_param.name)
|
403
|
+
Types::Variable.fresh(method_param.name).name
|
404
404
|
else
|
405
|
-
name
|
405
|
+
method_param.name
|
406
406
|
end
|
407
407
|
end
|
408
|
-
method_params = class_params + renamed_method_params
|
409
408
|
|
410
|
-
sub = Substitution.build(
|
409
|
+
sub = Substitution.build(
|
410
|
+
method_type.type_params.map(&:name),
|
411
|
+
Types::Variable.build(new_method_param_names)
|
412
|
+
)
|
413
|
+
|
414
|
+
method_params = class_params + AST::TypeParam.rename(method_type.type_params, new_names: new_method_param_names)
|
415
|
+
method_type = method_type
|
416
|
+
.update(type_params: [])
|
417
|
+
.sub(sub)
|
418
|
+
.update(type_params: method_params)
|
411
419
|
else
|
412
|
-
|
413
|
-
|
420
|
+
method_type = method_type
|
421
|
+
.update(type_params: class_params + method_type.type_params)
|
414
422
|
end
|
415
423
|
|
416
|
-
method_type = method_type.map_type {|ty| ty.sub(sub) }
|
417
424
|
method_type = method_type.update(
|
418
|
-
type_params: method_params,
|
419
425
|
type: method_type.type.with_return_type(
|
420
426
|
Types::ClassInstance.new(
|
421
427
|
name: type_name,
|
@@ -446,7 +452,7 @@ module RBS
|
|
446
452
|
|
447
453
|
def validate_params_with(type_params, result:)
|
448
454
|
type_params.each do |param|
|
449
|
-
unless param.
|
455
|
+
unless param.unchecked?
|
450
456
|
unless result.compatible?(param.name, with_annotation: param.variance)
|
451
457
|
yield param
|
452
458
|
end
|
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,7 +328,7 @@ module RBS
|
|
319
328
|
when AST::Declarations::Alias
|
320
329
|
AST::Declarations::Alias.new(
|
321
330
|
name: decl.name.with_prefix(prefix),
|
322
|
-
type_params: decl.type_params,
|
331
|
+
type_params: resolve_type_params(resolver, decl.type_params, context: context),
|
323
332
|
type: absolute_type(resolver, decl.type, context: context),
|
324
333
|
location: decl.location,
|
325
334
|
annotations: decl.annotations,
|
@@ -343,7 +352,7 @@ module RBS
|
|
343
352
|
name: member.name,
|
344
353
|
kind: member.kind,
|
345
354
|
types: member.types.map do |type|
|
346
|
-
|
355
|
+
resolve_method_type(resolver, type, context: context)
|
347
356
|
end,
|
348
357
|
comment: member.comment,
|
349
358
|
overload: member.overload?,
|
@@ -430,6 +439,20 @@ module RBS
|
|
430
439
|
end
|
431
440
|
end
|
432
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
|
+
|
433
456
|
def absolute_type_name(resolver, type_name, context:)
|
434
457
|
resolver.resolve(type_name, context: context) || type_name
|
435
458
|
end
|
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
|
|
@@ -432,7 +432,7 @@ module RBS
|
|
432
432
|
end
|
433
433
|
end
|
434
434
|
|
435
|
-
class NonregularTypeAliasError <
|
435
|
+
class NonregularTypeAliasError < BaseError
|
436
436
|
attr_reader :diagnostic
|
437
437
|
attr_reader :location
|
438
438
|
|
@@ -443,4 +443,17 @@ module RBS
|
|
443
443
|
super "#{Location.to_string location}: Nonregular generic type alias is prohibited: #{diagnostic.type_name}, #{diagnostic.nonregular_type}"
|
444
444
|
end
|
445
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
|
446
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: [],
|