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/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
|