rbs 1.8.1 → 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 +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: [],
|