rbs 1.7.0 → 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 +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/ast/declarations.rb
CHANGED
@@ -4,103 +4,6 @@ module RBS
|
|
4
4
|
class Base
|
5
5
|
end
|
6
6
|
|
7
|
-
class ModuleTypeParams
|
8
|
-
attr_reader :params
|
9
|
-
|
10
|
-
TypeParam = _ = Struct.new(:name, :variance, :skip_validation, :location, keyword_init: true) do
|
11
|
-
# @implements TypeParam
|
12
|
-
|
13
|
-
def to_json(state = _ = nil)
|
14
|
-
{
|
15
|
-
name: name,
|
16
|
-
variance: variance,
|
17
|
-
skip_validation: skip_validation,
|
18
|
-
}.to_json(state)
|
19
|
-
end
|
20
|
-
|
21
|
-
def ==(other)
|
22
|
-
other.is_a?(TypeParam) &&
|
23
|
-
other.name == name &&
|
24
|
-
other.variance == variance &&
|
25
|
-
other.skip_validation == skip_validation
|
26
|
-
end
|
27
|
-
|
28
|
-
alias eql? ==
|
29
|
-
|
30
|
-
def hash
|
31
|
-
self.class.hash ^ name.hash ^ variance.hash ^ skip_validation.hash
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def initialize()
|
36
|
-
@params = []
|
37
|
-
end
|
38
|
-
|
39
|
-
def add(param)
|
40
|
-
params << param
|
41
|
-
self
|
42
|
-
end
|
43
|
-
|
44
|
-
def ==(other)
|
45
|
-
other.is_a?(ModuleTypeParams) && other.params == params
|
46
|
-
end
|
47
|
-
|
48
|
-
alias eql? ==
|
49
|
-
|
50
|
-
def hash
|
51
|
-
params.hash
|
52
|
-
end
|
53
|
-
|
54
|
-
def [](name)
|
55
|
-
params.find {|p| p.name == name }
|
56
|
-
end
|
57
|
-
|
58
|
-
def to_json(state = _ = nil)
|
59
|
-
{
|
60
|
-
params: params
|
61
|
-
}.to_json(state)
|
62
|
-
end
|
63
|
-
|
64
|
-
def each(&block)
|
65
|
-
if block
|
66
|
-
params.each(&block)
|
67
|
-
else
|
68
|
-
params.each
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def self.empty
|
73
|
-
new
|
74
|
-
end
|
75
|
-
|
76
|
-
def variance(name)
|
77
|
-
var = self[name] or raise
|
78
|
-
var.variance
|
79
|
-
end
|
80
|
-
|
81
|
-
def skip_validation?(name)
|
82
|
-
var = self[name] or raise
|
83
|
-
var.skip_validation
|
84
|
-
end
|
85
|
-
|
86
|
-
def empty?
|
87
|
-
params.empty?
|
88
|
-
end
|
89
|
-
|
90
|
-
def size
|
91
|
-
params.size
|
92
|
-
end
|
93
|
-
|
94
|
-
def rename_to(names)
|
95
|
-
ModuleTypeParams.new().tap do |params|
|
96
|
-
names.each.with_index do |new_name, index|
|
97
|
-
param = self.params[index]
|
98
|
-
params.add(TypeParam.new(name: new_name, variance: param.variance, skip_validation: param.skip_validation, location: param.location))
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
7
|
module NestedDeclarationHelper
|
105
8
|
def each_member
|
106
9
|
if block_given?
|
@@ -362,13 +265,15 @@ module RBS
|
|
362
265
|
|
363
266
|
class Alias < Base
|
364
267
|
attr_reader :name
|
268
|
+
attr_reader :type_params
|
365
269
|
attr_reader :type
|
366
270
|
attr_reader :annotations
|
367
271
|
attr_reader :location
|
368
272
|
attr_reader :comment
|
369
273
|
|
370
|
-
def initialize(name:, type:, annotations:, location:, comment:)
|
274
|
+
def initialize(name:, type_params:, type:, annotations:, location:, comment:)
|
371
275
|
@name = name
|
276
|
+
@type_params = type_params
|
372
277
|
@type = type
|
373
278
|
@annotations = annotations
|
374
279
|
@location = location
|
@@ -378,19 +283,21 @@ module RBS
|
|
378
283
|
def ==(other)
|
379
284
|
other.is_a?(Alias) &&
|
380
285
|
other.name == name &&
|
286
|
+
other.type_params == type_params &&
|
381
287
|
other.type == type
|
382
288
|
end
|
383
289
|
|
384
290
|
alias eql? ==
|
385
291
|
|
386
292
|
def hash
|
387
|
-
self.class.hash ^ name.hash ^ type.hash
|
293
|
+
self.class.hash ^ name.hash ^ type_params.hash ^ type.hash
|
388
294
|
end
|
389
295
|
|
390
296
|
def to_json(state = _ = nil)
|
391
297
|
{
|
392
298
|
declaration: :alias,
|
393
299
|
name: name,
|
300
|
+
type_params: type_params,
|
394
301
|
type: type,
|
395
302
|
annotations: annotations,
|
396
303
|
location: location,
|
@@ -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|
|
@@ -460,7 +490,7 @@ EOU
|
|
460
490
|
|
461
491
|
env.alias_decls.each do |name, decl|
|
462
492
|
stdout.puts "Validating alias: `#{name}`..."
|
463
|
-
builder.
|
493
|
+
builder.expand_alias1(name).tap do |type|
|
464
494
|
validator.validate_type type, context: [Namespace.root]
|
465
495
|
end
|
466
496
|
validator.validate_type_alias(entry: decl)
|
@@ -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
|
@@ -104,9 +113,9 @@ module RBS
|
|
104
113
|
else
|
105
114
|
begin
|
106
115
|
# git v2.27.0 or greater
|
107
|
-
git 'clone', '--filter=blob:none', remote, git_dir.to_s
|
116
|
+
git 'clone', '--filter=blob:none', remote, git_dir.to_s, chdir: nil
|
108
117
|
rescue CommandError
|
109
|
-
git 'clone', remote, git_dir.to_s
|
118
|
+
git 'clone', remote, git_dir.to_s, chdir: nil
|
110
119
|
end
|
111
120
|
end
|
112
121
|
|
@@ -131,7 +140,8 @@ module RBS
|
|
131
140
|
private def git_dir
|
132
141
|
@git_dir ||= (
|
133
142
|
base = Pathname(ENV['XDG_CACHE_HOME'] || File.expand_path("~/.cache"))
|
134
|
-
|
143
|
+
cache_key = remote.start_with?('.') ? "#{remote}\0#{Dir.pwd}" : remote
|
144
|
+
dir = base.join('rbs', Digest::SHA256.hexdigest(cache_key))
|
135
145
|
dir.mkpath
|
136
146
|
dir
|
137
147
|
)
|
@@ -149,13 +159,14 @@ module RBS
|
|
149
159
|
git('rev-parse', 'HEAD').chomp
|
150
160
|
end
|
151
161
|
|
152
|
-
private def git(*cmd)
|
153
|
-
sh! 'git', *cmd
|
162
|
+
private def git(*cmd, **opt)
|
163
|
+
sh! 'git', *cmd, **opt
|
154
164
|
end
|
155
165
|
|
156
|
-
private def sh!(*cmd)
|
166
|
+
private def sh!(*cmd, **opt)
|
157
167
|
RBS.logger.debug "$ #{cmd.join(' ')}"
|
158
|
-
|
168
|
+
opt = { chdir: git_dir }.merge(opt).compact
|
169
|
+
(__skip__ = Open3.capture3(*cmd, **opt)).then do |out, err, status|
|
159
170
|
raise CommandError, "Unexpected status #{status.exitstatus}\n\n#{err}" unless status.success?
|
160
171
|
|
161
172
|
out
|
@@ -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,
|
@@ -291,6 +291,10 @@ module RBS
|
|
291
291
|
end
|
292
292
|
|
293
293
|
one_ancestors.each_extended_module do |mod|
|
294
|
+
mod.args.each do |arg|
|
295
|
+
validate_type_presence(arg)
|
296
|
+
end
|
297
|
+
|
294
298
|
mod_defn = build_instance(mod.name, no_self_types: true)
|
295
299
|
merge_definition(src: mod_defn,
|
296
300
|
dest: definition,
|
@@ -299,6 +303,10 @@ module RBS
|
|
299
303
|
|
300
304
|
interface_methods = {}
|
301
305
|
one_ancestors.each_extended_interface do |mod|
|
306
|
+
mod.args.each do |arg|
|
307
|
+
validate_type_presence(arg)
|
308
|
+
end
|
309
|
+
|
302
310
|
mod_defn = build_interface(mod.name)
|
303
311
|
subst = Substitution.build(mod_defn.type_params, mod.args)
|
304
312
|
|
@@ -377,7 +385,7 @@ module RBS
|
|
377
385
|
initialize = instance.methods[:initialize]
|
378
386
|
|
379
387
|
if initialize
|
380
|
-
class_params = entry.type_params
|
388
|
+
class_params = entry.type_params
|
381
389
|
|
382
390
|
# Inject a virtual _typed new_.
|
383
391
|
initialize_defs = initialize.defs
|
@@ -386,28 +394,34 @@ module RBS
|
|
386
394
|
defs: initialize_defs.map do |initialize_def|
|
387
395
|
method_type = initialize_def.type
|
388
396
|
|
389
|
-
class_type_param_vars = Set.new(class_params)
|
390
|
-
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))
|
391
399
|
|
392
400
|
if class_type_param_vars.intersect?(method_type_param_vars)
|
393
|
-
|
394
|
-
if class_type_param_vars.include?(name)
|
395
|
-
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
|
396
404
|
else
|
397
|
-
name
|
405
|
+
method_param.name
|
398
406
|
end
|
399
407
|
end
|
400
|
-
method_params = class_params + renamed_method_params
|
401
408
|
|
402
|
-
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)
|
403
419
|
else
|
404
|
-
|
405
|
-
|
420
|
+
method_type = method_type
|
421
|
+
.update(type_params: class_params + method_type.type_params)
|
406
422
|
end
|
407
423
|
|
408
|
-
method_type = method_type.map_type {|ty| ty.sub(sub) }
|
409
424
|
method_type = method_type.update(
|
410
|
-
type_params: method_params,
|
411
425
|
type: method_type.type.with_return_type(
|
412
426
|
Types::ClassInstance.new(
|
413
427
|
name: type_name,
|
@@ -438,7 +452,7 @@ module RBS
|
|
438
452
|
|
439
453
|
def validate_params_with(type_params, result:)
|
440
454
|
type_params.each do |param|
|
441
|
-
unless param.
|
455
|
+
unless param.unchecked?
|
442
456
|
unless result.compatible?(param.name, with_annotation: param.variance)
|
443
457
|
yield param
|
444
458
|
end
|
@@ -781,9 +795,36 @@ module RBS
|
|
781
795
|
end
|
782
796
|
|
783
797
|
def expand_alias(type_name)
|
784
|
-
|
798
|
+
expand_alias2(type_name, [])
|
799
|
+
end
|
800
|
+
|
801
|
+
def expand_alias1(type_name)
|
802
|
+
entry = env.alias_decls[type_name] or raise "Unknown alias name: #{type_name}"
|
803
|
+
as = entry.decl.type_params.each.map { Types::Bases::Any.new(location: nil) }
|
804
|
+
expand_alias2(type_name, as)
|
805
|
+
end
|
806
|
+
|
807
|
+
def expand_alias2(type_name, args)
|
808
|
+
entry = env.alias_decls[type_name] or raise "Unknown alias name: #{type_name}"
|
809
|
+
|
785
810
|
ensure_namespace!(type_name.namespace, location: entry.decl.location)
|
786
|
-
entry.decl.
|
811
|
+
params = entry.decl.type_params.each.map(&:name)
|
812
|
+
|
813
|
+
unless params.size == args.size
|
814
|
+
as = "[#{args.join(", ")}]" unless args.empty?
|
815
|
+
ps = "[#{params.join(", ")}]" unless params.empty?
|
816
|
+
|
817
|
+
raise "Invalid type application: type = #{type_name}#{as}, decl = #{type_name}#{ps}"
|
818
|
+
end
|
819
|
+
|
820
|
+
type = entry.decl.type
|
821
|
+
|
822
|
+
unless params.empty?
|
823
|
+
subst = Substitution.build(params, args)
|
824
|
+
type = type.sub(subst)
|
825
|
+
end
|
826
|
+
|
827
|
+
type
|
787
828
|
end
|
788
829
|
|
789
830
|
def update(env:, except:, ancestor_builder:)
|
@@ -804,5 +845,26 @@ module RBS
|
|
804
845
|
end
|
805
846
|
end
|
806
847
|
end
|
848
|
+
|
849
|
+
def validate_type_presence(type)
|
850
|
+
case type
|
851
|
+
when Types::ClassInstance, Types::ClassSingleton, Types::Interface, Types::Alias
|
852
|
+
validate_type_name(type.name, type.location)
|
853
|
+
end
|
854
|
+
|
855
|
+
type.each_type do |type|
|
856
|
+
validate_type_presence(type)
|
857
|
+
end
|
858
|
+
end
|
859
|
+
|
860
|
+
def validate_type_name(name, location)
|
861
|
+
name = name.absolute!
|
862
|
+
|
863
|
+
return if name.class? && env.class_decls.key?(name)
|
864
|
+
return if name.interface? && env.interface_decls.key?(name)
|
865
|
+
return if name.alias? && env.alias_decls.key?(name)
|
866
|
+
|
867
|
+
raise NoTypeFoundError.new(type_name: name, location: location)
|
868
|
+
end
|
807
869
|
end
|
808
870
|
end
|