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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +95 -3
  3. data/core/array.rbs +3 -3
  4. data/core/builtin.rbs +4 -0
  5. data/core/enumerable.rbs +3 -3
  6. data/core/thread.rbs +1 -1
  7. data/docs/collection.md +23 -1
  8. data/docs/syntax.md +117 -61
  9. data/ext/rbs_extension/constants.c +2 -6
  10. data/ext/rbs_extension/constants.h +1 -2
  11. data/ext/rbs_extension/parser.c +221 -185
  12. data/ext/rbs_extension/parserstate.c +6 -2
  13. data/ext/rbs_extension/parserstate.h +10 -0
  14. data/ext/rbs_extension/ruby_objs.c +17 -17
  15. data/ext/rbs_extension/ruby_objs.h +3 -4
  16. data/lib/rbs/ast/declarations.rb +6 -99
  17. data/lib/rbs/ast/type_param.rb +134 -0
  18. data/lib/rbs/cli.rb +33 -5
  19. data/lib/rbs/collection/config/lockfile_generator.rb +26 -18
  20. data/lib/rbs/collection/sources/git.rb +18 -7
  21. data/lib/rbs/collection/sources/rubygems.rb +7 -0
  22. data/lib/rbs/collection/sources/stdlib.rb +6 -0
  23. data/lib/rbs/definition.rb +9 -0
  24. data/lib/rbs/definition_builder.rb +78 -16
  25. data/lib/rbs/environment.rb +32 -8
  26. data/lib/rbs/environment_loader.rb +0 -2
  27. data/lib/rbs/environment_walker.rb +4 -1
  28. data/lib/rbs/errors.rb +31 -6
  29. data/lib/rbs/location_aux.rb +2 -0
  30. data/lib/rbs/method_type.rb +29 -6
  31. data/lib/rbs/prototype/rb.rb +3 -3
  32. data/lib/rbs/prototype/rbi.rb +8 -6
  33. data/lib/rbs/prototype/runtime.rb +4 -4
  34. data/lib/rbs/type_alias_regularity.rb +115 -0
  35. data/lib/rbs/types.rb +100 -23
  36. data/lib/rbs/validator.rb +99 -15
  37. data/lib/rbs/variance_calculator.rb +60 -31
  38. data/lib/rbs/version.rb +1 -1
  39. data/lib/rbs/writer.rb +2 -14
  40. data/lib/rbs.rb +2 -0
  41. data/schema/decls.json +19 -46
  42. data/schema/methodType.json +1 -1
  43. data/schema/typeParam.json +36 -0
  44. data/schema/types.json +8 -2
  45. data/sig/collection/collections.rbs +13 -2
  46. data/sig/collection/config.rbs +2 -2
  47. data/sig/declarations.rbs +15 -62
  48. data/sig/definition.rbs +11 -1
  49. data/sig/definition_builder.rbs +37 -1
  50. data/sig/environment.rbs +7 -1
  51. data/sig/environment_walker.rbs +26 -0
  52. data/sig/errors.rbs +28 -3
  53. data/sig/location.rbs +3 -1
  54. data/sig/locator.rbs +1 -1
  55. data/sig/method_types.rbs +25 -4
  56. data/sig/type_alias_regularity.rbs +92 -0
  57. data/sig/type_param.rbs +74 -0
  58. data/sig/types.rbs +37 -8
  59. data/sig/validator.rbs +38 -2
  60. data/sig/variance_calculator.rbs +50 -0
  61. data/sig/writer.rbs +1 -1
  62. data/stdlib/bigdecimal-math/0/manifest.yaml +2 -0
  63. data/stdlib/csv/0/manifest.yaml +2 -0
  64. data/stdlib/date/0/date.rbs +2 -2
  65. data/stdlib/logger/0/manifest.yaml +2 -0
  66. data/stdlib/net-http/0/manifest.yaml +2 -0
  67. data/stdlib/openssl/0/manifest.yaml +2 -0
  68. data/stdlib/prime/0/manifest.yaml +2 -0
  69. data/stdlib/resolv/0/manifest.yaml +3 -0
  70. data/stdlib/set/0/set.rbs +3 -3
  71. data/stdlib/uri/0/common.rbs +10 -5
  72. data/stdlib/uri/0/ftp.rbs +10 -0
  73. data/stdlib/uri/0/mailto.rbs +5 -0
  74. data/stdlib/uri/0/ws.rbs +10 -0
  75. data/stdlib/uri/0/wss.rbs +7 -0
  76. data/stdlib/yaml/0/manifest.yaml +3 -0
  77. data/steep/Gemfile.lock +10 -10
  78. metadata +21 -5
  79. data/lib/ruby/signature.rb +0 -7
@@ -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.each_key do |name|
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.each_key do |name|
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.expand_alias(name).tap do |type|
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
- assign_gem(gem_name: gem['name'], version: gem['version'])
23
+ @gem_queue.push({ name: gem['name'], version: gem['version'] })
23
24
  end
24
25
 
25
26
  gemfile_lock_gems do |spec|
26
- assign_gem(gem_name: spec.name, version: spec.version)
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(gem_name:, version:)
35
- locked = lock&.gem(gem_name)
36
- specified = config.gem(gem_name)
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
- if locked
42
- # If rbs_collection.lock.yaml contain the gem, use it.
43
- upsert_gem specified, locked
44
- else
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' => gem_name }))
51
- # @type var new_content: RBS::Collection::Config::gem_entry
52
- new_content = {
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
- upsert_gem specified, new_content
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(gem_name:)
87
+ private def find_source(name:)
80
88
  sources = config.sources
81
89
 
82
- sources.find { |c| c.has?({ 'name' => gem_name, 'revision' => nil } ) }
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
- dir = base.join('rbs', Digest::SHA256.hexdigest(remote))
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
- (__skip__ = Open3.capture3(*cmd, chdir: git_dir)).then do |out, err, status|
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',
@@ -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.each.map(&:name)
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
- renamed_method_params = method_type.type_params.map do |name|
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(method_type.type_params, Types::Variable.build(renamed_method_params))
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
- method_params = class_params + method_type.type_params
405
- sub = Substitution.build([], [])
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.skip_validation
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
- entry = env.alias_decls[type_name] or raise "Unknown name for expand_alias: #{type_name}"
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.type
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