rbs 3.0.0.dev.1 → 3.0.0.dev.3

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 (165) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/comments.yml +2 -1
  3. data/.github/workflows/ruby.yml +4 -3
  4. data/CHANGELOG.md +28 -0
  5. data/Gemfile.lock +12 -12
  6. data/README.md +1 -0
  7. data/Rakefile +77 -3
  8. data/Steepfile +1 -1
  9. data/core/array.rbs +574 -424
  10. data/core/basic_object.rbs +11 -39
  11. data/core/binding.rbs +1 -1
  12. data/core/builtin.rbs +9 -1
  13. data/core/class.rbs +37 -0
  14. data/core/comparable.rbs +7 -18
  15. data/core/complex.rbs +2 -2
  16. data/core/data.rbs +419 -0
  17. data/core/dir.rbs +52 -104
  18. data/core/encoding.rbs +22 -181
  19. data/core/enumerable.rbs +212 -175
  20. data/core/enumerator/product.rbs +96 -0
  21. data/core/enumerator.rbs +57 -8
  22. data/core/errors.rbs +8 -2
  23. data/core/exception.rbs +41 -0
  24. data/core/fiber.rbs +95 -12
  25. data/core/file.rbs +840 -275
  26. data/core/file_test.rbs +34 -19
  27. data/core/float.rbs +40 -96
  28. data/core/gc.rbs +15 -3
  29. data/core/hash.rbs +114 -176
  30. data/core/integer.rbs +85 -145
  31. data/core/io/buffer.rbs +187 -60
  32. data/core/io/wait.rbs +28 -16
  33. data/core/io.rbs +1859 -1389
  34. data/core/kernel.rbs +525 -961
  35. data/core/match_data.rbs +306 -142
  36. data/core/math.rbs +506 -234
  37. data/core/method.rbs +0 -24
  38. data/core/module.rbs +111 -18
  39. data/core/nil_class.rbs +2 -0
  40. data/core/numeric.rbs +76 -144
  41. data/core/object.rbs +88 -212
  42. data/core/proc.rbs +17 -5
  43. data/core/process.rbs +22 -5
  44. data/core/ractor.rbs +1 -1
  45. data/core/random.rbs +20 -3
  46. data/core/range.rbs +91 -89
  47. data/core/rational.rbs +2 -3
  48. data/core/rbs/unnamed/argf.rbs +177 -120
  49. data/core/rbs/unnamed/env_class.rbs +89 -163
  50. data/core/rbs/unnamed/random.rbs +36 -12
  51. data/core/refinement.rbs +8 -0
  52. data/core/regexp.rbs +462 -272
  53. data/core/ruby_vm.rbs +210 -0
  54. data/{stdlib/set/0 → core}/set.rbs +43 -47
  55. data/core/string.rbs +1403 -1332
  56. data/core/string_io.rbs +191 -107
  57. data/core/struct.rbs +67 -63
  58. data/core/symbol.rbs +187 -201
  59. data/core/thread.rbs +40 -35
  60. data/core/time.rbs +902 -826
  61. data/core/trace_point.rbs +55 -6
  62. data/core/unbound_method.rbs +48 -24
  63. data/docs/collection.md +4 -0
  64. data/docs/syntax.md +55 -0
  65. data/ext/rbs_extension/constants.c +16 -2
  66. data/ext/rbs_extension/constants.h +8 -1
  67. data/ext/rbs_extension/extconf.rb +1 -1
  68. data/ext/rbs_extension/lexer.c +834 -777
  69. data/ext/rbs_extension/lexer.h +3 -1
  70. data/ext/rbs_extension/lexer.re +3 -1
  71. data/ext/rbs_extension/lexstate.c +4 -2
  72. data/ext/rbs_extension/parser.c +262 -43
  73. data/ext/rbs_extension/ruby_objs.c +56 -2
  74. data/ext/rbs_extension/ruby_objs.h +7 -1
  75. data/lib/rbs/annotate/rdoc_annotator.rb +1 -1
  76. data/lib/rbs/ast/declarations.rb +49 -2
  77. data/lib/rbs/ast/directives.rb +39 -0
  78. data/lib/rbs/cli.rb +38 -19
  79. data/lib/rbs/collection/cleaner.rb +8 -1
  80. data/lib/rbs/collection/config/lockfile.rb +3 -1
  81. data/lib/rbs/collection/config/lockfile_generator.rb +37 -30
  82. data/lib/rbs/collection/config.rb +3 -3
  83. data/lib/rbs/collection/sources/git.rb +10 -3
  84. data/lib/rbs/collection/sources/local.rb +79 -0
  85. data/lib/rbs/collection/sources.rb +8 -1
  86. data/lib/rbs/definition_builder/ancestor_builder.rb +24 -8
  87. data/lib/rbs/definition_builder.rb +8 -8
  88. data/lib/rbs/environment/use_map.rb +77 -0
  89. data/lib/rbs/environment.rb +358 -88
  90. data/lib/rbs/environment_loader.rb +12 -9
  91. data/lib/rbs/environment_walker.rb +1 -1
  92. data/lib/rbs/errors.rb +52 -37
  93. data/lib/rbs/locator.rb +27 -8
  94. data/lib/rbs/parser_aux.rb +8 -6
  95. data/lib/rbs/resolver/constant_resolver.rb +23 -7
  96. data/lib/rbs/resolver/type_name_resolver.rb +2 -1
  97. data/lib/rbs/sorter.rb +5 -5
  98. data/lib/rbs/test/setup.rb +1 -1
  99. data/lib/rbs/type_alias_dependency.rb +1 -1
  100. data/lib/rbs/type_alias_regularity.rb +3 -3
  101. data/lib/rbs/validator.rb +23 -2
  102. data/lib/rbs/variance_calculator.rb +2 -2
  103. data/lib/rbs/version.rb +1 -1
  104. data/lib/rbs/writer.rb +28 -2
  105. data/lib/rbs.rb +2 -2
  106. data/lib/rdoc_plugin/parser.rb +2 -2
  107. data/rbs.gemspec +1 -1
  108. data/sig/ancestor_graph.rbs +22 -2
  109. data/sig/collection/config/lockfile_generator.rbs +8 -10
  110. data/sig/collection/config.rbs +1 -1
  111. data/sig/collection/sources.rbs +44 -9
  112. data/sig/constant.rbs +1 -1
  113. data/sig/declarations.rbs +36 -3
  114. data/sig/definition.rbs +1 -1
  115. data/sig/definition_builder.rbs +0 -1
  116. data/sig/directives.rbs +61 -0
  117. data/sig/environment.rbs +150 -29
  118. data/sig/environment_loader.rbs +1 -1
  119. data/sig/errors.rbs +22 -1
  120. data/sig/locator.rbs +14 -2
  121. data/sig/parser.rbs +8 -15
  122. data/sig/resolver/constant_resolver.rbs +1 -2
  123. data/sig/shims/{abstract_syntax_tree.rbs → _abstract_syntax_tree.rbs} +0 -0
  124. data/sig/shims/bundler.rbs +18 -0
  125. data/sig/shims/rubygems.rbs +6 -0
  126. data/sig/use_map.rbs +35 -0
  127. data/sig/validator.rbs +12 -5
  128. data/sig/writer.rbs +4 -2
  129. data/stdlib/bigdecimal/0/big_decimal.rbs +16 -13
  130. data/stdlib/cgi/0/core.rbs +16 -0
  131. data/stdlib/coverage/0/coverage.rbs +50 -8
  132. data/stdlib/csv/0/csv.rbs +1 -1
  133. data/stdlib/date/0/date.rbs +856 -726
  134. data/stdlib/date/0/date_time.rbs +83 -210
  135. data/stdlib/erb/0/erb.rbs +13 -36
  136. data/stdlib/etc/0/etc.rbs +127 -20
  137. data/stdlib/fileutils/0/fileutils.rbs +1290 -381
  138. data/stdlib/logger/0/logger.rbs +466 -316
  139. data/stdlib/net-http/0/net-http.rbs +2211 -534
  140. data/stdlib/nkf/0/nkf.rbs +5 -5
  141. data/stdlib/objspace/0/objspace.rbs +31 -14
  142. data/stdlib/openssl/0/openssl.rbs +11 -7
  143. data/stdlib/optparse/0/optparse.rbs +20 -17
  144. data/stdlib/pathname/0/pathname.rbs +21 -4
  145. data/stdlib/pstore/0/pstore.rbs +378 -154
  146. data/stdlib/pty/0/pty.rbs +24 -8
  147. data/stdlib/ripper/0/ripper.rbs +1650 -0
  148. data/stdlib/socket/0/addrinfo.rbs +9 -15
  149. data/stdlib/socket/0/socket.rbs +36 -3
  150. data/stdlib/strscan/0/string_scanner.rbs +7 -5
  151. data/stdlib/tempfile/0/tempfile.rbs +104 -44
  152. data/stdlib/time/0/time.rbs +2 -2
  153. data/stdlib/uri/0/file.rbs +5 -0
  154. data/stdlib/uri/0/generic.rbs +2 -2
  155. data/stdlib/yaml/0/yaml.rbs +2 -2
  156. data/stdlib/zlib/0/zlib.rbs +1 -1
  157. metadata +13 -13
  158. data/core/deprecated.rbs +0 -9
  159. data/lib/rbs/constant_table.rb +0 -167
  160. data/lib/rbs/type_name_resolver.rb +0 -67
  161. data/sig/constant_table.rbs +0 -30
  162. data/sig/shims/ripper.rbs +0 -8
  163. data/sig/type_name_resolver.rbs +0 -26
  164. data/steep/Gemfile +0 -3
  165. data/steep/Gemfile.lock +0 -61
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ module AST
5
+ module Directives
6
+ class Base
7
+ end
8
+
9
+ class Use < Base
10
+ class SingleClause
11
+ attr_reader :type_name, :new_name, :location
12
+
13
+ def initialize(type_name:, new_name:, location:)
14
+ @type_name = type_name
15
+ @new_name = new_name
16
+ @location = location
17
+ end
18
+ end
19
+
20
+ class WildcardClause
21
+ attr_reader :namespace, :location
22
+
23
+ def initialize(namespace:, location:)
24
+ @location = location
25
+ @namespace = namespace
26
+ end
27
+ end
28
+
29
+ attr_reader :clauses, :location
30
+
31
+ def initialize(clauses:, location:)
32
+ @clauses = clauses
33
+ @location = location
34
+ end
35
+ end
36
+
37
+ end
38
+ end
39
+ end
data/lib/rbs/cli.rb CHANGED
@@ -438,15 +438,15 @@ EOU
438
438
  env = Environment.from_loader(loader).resolve_type_names
439
439
 
440
440
  builder = DefinitionBuilder.new(env: env)
441
- validator = Validator.new(env: env, resolver: TypeNameResolver.from_env(env))
441
+ validator = Validator.new(env: env, resolver: Resolver::TypeNameResolver.new(env))
442
442
 
443
443
  env.class_decls.each do |name, decl|
444
444
  stdout.puts "Validating class/module definition: `#{name}`..."
445
445
  builder.build_instance(name).each_type do |type|
446
- validator.validate_type type, context: [Namespace.root]
446
+ validator.validate_type type, context: nil
447
447
  end
448
448
  builder.build_singleton(name).each_type do |type|
449
- validator.validate_type type, context: [Namespace.root]
449
+ validator.validate_type type, context: nil
450
450
  end
451
451
 
452
452
  d = decl.primary.decl
@@ -467,10 +467,15 @@ EOU
467
467
  end
468
468
  end
469
469
 
470
+ env.class_alias_decls.each do |name, entry|
471
+ stdout.puts "Validating class/module alias definition: `#{name}`..."
472
+ validator.validate_class_alias(entry: entry)
473
+ end
474
+
470
475
  env.interface_decls.each do |name, decl|
471
476
  stdout.puts "Validating interface: `#{name}`..."
472
477
  builder.build_interface(name).each_type do |type|
473
- validator.validate_type type, context: [Namespace.root]
478
+ validator.validate_type type, context: nil
474
479
  end
475
480
 
476
481
  validator.validate_type_params(
@@ -495,13 +500,13 @@ EOU
495
500
 
496
501
  env.global_decls.each do |name, global|
497
502
  stdout.puts "Validating global: `#{name}`..."
498
- validator.validate_type global.decl.type, context: [Namespace.root]
503
+ validator.validate_type global.decl.type, context: nil
499
504
  end
500
505
 
501
- env.alias_decls.each do |name, decl|
506
+ env.type_alias_decls.each do |name, decl|
502
507
  stdout.puts "Validating alias: `#{name}`..."
503
508
  builder.expand_alias1(name).tap do |type|
504
- validator.validate_type type, context: [Namespace.root]
509
+ validator.validate_type type, context: nil
505
510
  end
506
511
  validator.validate_type_alias(entry: decl)
507
512
  end
@@ -537,14 +542,26 @@ EOU
537
542
  env = Environment.from_loader(loader).resolve_type_names
538
543
 
539
544
  builder = DefinitionBuilder.new(env: env)
540
- table = ConstantTable.new(builder: builder)
545
+ resolver = Resolver::ConstantResolver.new(builder: builder)
541
546
 
542
- namespace = context ? Namespace.parse(context).absolute! : Namespace.root
543
- stdout.puts "Context: #{namespace}"
544
- name = Namespace.parse(args[0]).to_type_name
545
- stdout.puts "Constant name: #{name}"
547
+ resolver_context = context ? [nil, TypeName(context).absolute!] : nil #: Resolver::context
548
+ stdout.puts "Context: #{context}"
549
+ const_name = TypeName(args[0])
550
+ stdout.puts "Constant name: #{const_name}"
546
551
 
547
- constant = table.resolve_constant_reference(name, context: namespace.ascend.to_a)
552
+ if const_name.absolute?
553
+ constant = resolver.table.constant(const_name)
554
+ else
555
+ head, *components = const_name.to_namespace.path
556
+ head or raise
557
+
558
+ constant = resolver.resolve(head, context: resolver_context)
559
+ constant = components.inject(constant) do |const, component|
560
+ if const
561
+ resolver.resolve_child(const.name, component)
562
+ end
563
+ end
564
+ end
548
565
 
549
566
  if constant
550
567
  stdout.puts " => #{constant.name}: #{constant.type}"
@@ -1043,15 +1060,12 @@ EOB
1043
1060
  case args[0]
1044
1061
  when 'install'
1045
1062
  unless params[:frozen]
1046
- gemfile_lock_path = Bundler.default_lockfile
1047
- Collection::Config.generate_lockfile(config_path: config_path, gemfile_lock_path: gemfile_lock_path)
1063
+ Collection::Config.generate_lockfile(config_path: config_path, definition: Bundler.definition)
1048
1064
  end
1049
1065
  Collection::Installer.new(lockfile_path: lock_path, stdout: stdout).install_from_lockfile
1050
1066
  when 'update'
1051
- gemfile_lock_path = Bundler.default_lockfile
1052
-
1053
1067
  # TODO: Be aware of argv to update only specified gem
1054
- Collection::Config.generate_lockfile(config_path: config_path, gemfile_lock_path: gemfile_lock_path, with_lockfile: false)
1068
+ Collection::Config.generate_lockfile(config_path: config_path, definition: Bundler.definition, with_lockfile: false)
1055
1069
  Collection::Installer.new(lockfile_path: lock_path, stdout: stdout).install_from_lockfile
1056
1070
  when 'init'
1057
1071
  if config_path.exist?
@@ -1062,11 +1076,16 @@ EOB
1062
1076
  config_path.write(<<~'YAML')
1063
1077
  # Download sources
1064
1078
  sources:
1065
- - name: ruby/gem_rbs_collection
1079
+ - type: git
1080
+ name: ruby/gem_rbs_collection
1066
1081
  remote: https://github.com/ruby/gem_rbs_collection.git
1067
1082
  revision: main
1068
1083
  repo_dir: gems
1069
1084
 
1085
+ # You can specify local directories as sources also.
1086
+ # - type: local
1087
+ # path: path/to/your/local/repository
1088
+
1070
1089
  # A directory to install the downloaded RBSs
1071
1090
  path: .gem_rbs_collection
1072
1091
 
@@ -16,7 +16,14 @@ module RBS
16
16
  version or raise
17
17
  next if needed? gem_name, version
18
18
 
19
- FileUtils.remove_entry_secure(dir.to_s)
19
+ case
20
+ when dir.symlink?
21
+ dir.unlink
22
+ when dir.directory?
23
+ FileUtils.remove_entry_secure(dir.to_s)
24
+ else
25
+ raise
26
+ end
20
27
  end
21
28
  end
22
29
 
@@ -75,7 +75,7 @@ module RBS
75
75
  if gems = data["gems"]
76
76
  gems.each do |gem|
77
77
  src = gem["source"]
78
- source = Sources.from_config_entry(src)
78
+ source = Sources.from_config_entry(src, base_directory: lockfile_path.dirname)
79
79
  lockfile.gems[gem["name"]] = {
80
80
  name: gem["name"],
81
81
  version: gem["version"],
@@ -106,6 +106,8 @@ module RBS
106
106
  meta_path = fullpath.join(gem[:name], gem[:version], Sources::Git::METADATA_FILENAME)
107
107
  raise CollectionNotAvailable unless meta_path.exist?
108
108
  raise CollectionNotAvailable unless library_data(gem) == YAML.load(meta_path.read)
109
+ when Sources::Local
110
+ raise CollectionNotAvailable unless fullpath.join(gem[:name], gem[:version]).symlink?
109
111
  end
110
112
  end
111
113
  end
@@ -20,15 +20,15 @@ module RBS
20
20
  end
21
21
  end
22
22
 
23
- attr_reader :config, :lockfile, :gemfile_lock, :existing_lockfile
23
+ attr_reader :config, :lockfile, :definition, :existing_lockfile, :gem_hash
24
24
 
25
- def self.generate(config:, gemfile_lock_path:, with_lockfile: true)
26
- generator = new(config: config, gemfile_lock_path: gemfile_lock_path, with_lockfile: with_lockfile)
25
+ def self.generate(config:, definition:, with_lockfile: true)
26
+ generator = new(config: config, definition: definition, with_lockfile: with_lockfile)
27
27
  generator.generate
28
28
  generator.lockfile
29
29
  end
30
30
 
31
- def initialize(config:, gemfile_lock_path:, with_lockfile:)
31
+ def initialize(config:, definition:, with_lockfile:)
32
32
  @config = config
33
33
 
34
34
  lockfile_path = Config.to_lockfile_path(config.config_path)
@@ -37,7 +37,7 @@ module RBS
37
37
  @lockfile = Lockfile.new(
38
38
  lockfile_path: lockfile_path,
39
39
  path: config.repo_path_data,
40
- gemfile_lock_path: gemfile_lock_path.relative_path_from(lockfile_dir)
40
+ gemfile_lock_path: definition.lockfile.relative_path_from(lockfile_dir)
41
41
  )
42
42
  config.sources.each do |source|
43
43
  case source
@@ -48,10 +48,13 @@ module RBS
48
48
 
49
49
  if with_lockfile && lockfile_path.file?
50
50
  @existing_lockfile = Lockfile.from_lockfile(lockfile_path: lockfile_path, data: YAML.load_file(lockfile_path.to_s))
51
- validate_gemfile_lock_path!(lock: @existing_lockfile, gemfile_lock_path: gemfile_lock_path)
51
+ validate_gemfile_lock_path!(lock: @existing_lockfile, gemfile_lock_path: definition.lockfile)
52
52
  end
53
53
 
54
- @gemfile_lock = Bundler::LockfileParser.new(gemfile_lock_path.read)
54
+ @definition = definition
55
+ @gem_hash = definition.locked_gems.specs.each.with_object({}) do |spec, hash| #$ Hash[String, Bundler::LazySpecification]
56
+ hash[spec.name] = spec
57
+ end
55
58
  end
56
59
 
57
60
  def generate
@@ -67,8 +70,13 @@ module RBS
67
70
  end
68
71
  end
69
72
 
70
- gemfile_lock_gems do |spec|
71
- assign_gem(name: spec.name, version: spec.version, ignored_gems: ignored_gems, src_data: nil)
73
+ definition.dependencies.each do |dep|
74
+ if dep.autorequire && dep.autorequire.empty?
75
+ next
76
+ end
77
+
78
+ spec = gem_hash[dep.name] or raise "Cannot find `#{dep.name}` in bundler context"
79
+ assign_gem(name: dep.name, version: spec.version, ignored_gems: ignored_gems, src_data: nil)
72
80
  end
73
81
 
74
82
  lockfile.lockfile_path.write(YAML.dump(lockfile.to_lockfile))
@@ -82,7 +90,7 @@ module RBS
82
90
  end
83
91
  end
84
92
 
85
- private def assign_gem(name:, version:, ignored_gems:, src_data:)
93
+ private def assign_gem(name:, version:, src_data:, ignored_gems:)
86
94
  return if ignored_gems.include?(name)
87
95
  return if lockfile.gems.key?(name)
88
96
 
@@ -97,29 +105,34 @@ module RBS
97
105
  unless locked
98
106
  source =
99
107
  if src_data
100
- Sources.from_config_entry(src_data)
108
+ Sources.from_config_entry(src_data, base_directory: config.config_path.dirname)
101
109
  else
102
110
  find_source(name: name)
103
111
  end
104
- return unless source
105
112
 
106
- installed_version = version
107
- best_version = find_best_version(version: installed_version, versions: source.versions(name))
113
+ if source
114
+ installed_version = version
115
+ best_version = find_best_version(version: installed_version, versions: source.versions(name))
108
116
 
109
- locked = {
110
- name: name,
111
- version: best_version.to_s,
112
- source: source,
113
- }
117
+ locked = {
118
+ name: name,
119
+ version: best_version.to_s,
120
+ source: source,
121
+ }
122
+ end
114
123
  end
115
124
 
116
- locked or raise
125
+ if locked
126
+ lockfile.gems[name] = locked
117
127
 
118
- lockfile.gems[name] = locked
119
- source = locked[:source]
128
+ locked[:source].dependencies_of(locked[:name], locked[:version])&.each do |dep|
129
+ assign_stdlib(name: dep["name"], from_gem: name)
130
+ end
131
+ end
120
132
 
121
- source.dependencies_of(locked[:name], locked[:version])&.each do |dep|
122
- assign_stdlib(name: dep["name"], from_gem: name)
133
+ gem_hash[name].dependencies.each do |dep|
134
+ spec = gem_hash[dep.name]
135
+ assign_gem(name: dep.name, version: spec.version, src_data: nil, ignored_gems: ignored_gems)
123
136
  end
124
137
  end
125
138
 
@@ -150,12 +163,6 @@ module RBS
150
163
  end
151
164
  end
152
165
 
153
- private def gemfile_lock_gems(&block)
154
- gemfile_lock.specs.each do |spec|
155
- yield spec
156
- end
157
- end
158
-
159
166
  private def find_source(name:)
160
167
  sources = config.sources
161
168
 
@@ -31,9 +31,9 @@ module RBS
31
31
 
32
32
  # Generate a rbs lockfile from Gemfile.lock to `config_path`.
33
33
  # If `with_lockfile` is true, it respects existing rbs lockfile.
34
- def self.generate_lockfile(config_path:, gemfile_lock_path:, with_lockfile: true)
34
+ def self.generate_lockfile(config_path:, definition:, with_lockfile: true)
35
35
  config = from_path(config_path)
36
- lockfile = LockfileGenerator.generate(config: config, gemfile_lock_path: gemfile_lock_path, with_lockfile: with_lockfile)
36
+ lockfile = LockfileGenerator.generate(config: config, definition: definition, with_lockfile: with_lockfile)
37
37
 
38
38
  [config, lockfile]
39
39
  end
@@ -66,7 +66,7 @@ module RBS
66
66
  def sources
67
67
  @sources ||= (
68
68
  @data['sources']
69
- .map { |c| Sources.from_config_entry(c) }
69
+ .map { |c| Sources.from_config_entry(c, base_directory: @config_path.dirname) }
70
70
  .push(Sources::Stdlib.instance)
71
71
  .push(Sources::Rubygems.instance)
72
72
  )
@@ -45,7 +45,12 @@ module RBS
45
45
 
46
46
  gem_dir = dest.join(name, version)
47
47
 
48
- if gem_dir.directory?
48
+ case
49
+ when gem_dir.symlink?
50
+ stdout.puts "Updating to #{format_config_entry(name, version)} from a local source"
51
+ gem_dir.unlink
52
+ _install(dest: dest, name: name, version: version)
53
+ when gem_dir.directory?
49
54
  prev = load_metadata(dir: gem_dir)
50
55
 
51
56
  if prev == metadata_content(name: name, version: version)
@@ -55,9 +60,11 @@ module RBS
55
60
  FileUtils.remove_entry_secure(gem_dir.to_s)
56
61
  _install(dest: dest, name: name, version: version)
57
62
  end
58
- else
63
+ when !gem_dir.exist?
59
64
  stdout.puts "Installing #{format_config_entry(name, version)}"
60
65
  _install(dest: dest, name: name, version: version)
66
+ else
67
+ raise
61
68
  end
62
69
  end
63
70
 
@@ -171,7 +178,7 @@ module RBS
171
178
  if commit_hash?
172
179
  revision
173
180
  else
174
- setup! { git('rev-parse', revision).chomp }
181
+ setup! { git('rev-parse', "refs/remotes/origin/#{revision}").chomp }
175
182
  end
176
183
  end
177
184
  end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ module Collection
5
+ module Sources
6
+ class Local
7
+ include Base
8
+
9
+ attr_reader :path, :full_path
10
+
11
+ def initialize(path:, base_directory:)
12
+ # TODO: resolve relative path from dir of rbs_collection.yaml
13
+ @path = Pathname(path)
14
+ @full_path = base_directory / path
15
+ end
16
+
17
+ def has?(name, version)
18
+ if version
19
+ @full_path.join(name, version).directory?
20
+ else
21
+ not versions(name).empty?
22
+ end
23
+ end
24
+
25
+ def versions(name)
26
+ @full_path.join(name).glob('*/').map { |path| path.basename.to_s }
27
+ end
28
+
29
+ # Create a symlink instead of copying file to refer files in @path.
30
+ # By avoiding copying RBS files, the users do not need re-run `rbs collection install`
31
+ # when the RBS files are updated.
32
+ def install(dest:, name:, version:, stdout:)
33
+ from = @full_path.join(name, version)
34
+ gem_dir = dest.join(name, version)
35
+
36
+ case
37
+ when gem_dir.symlink? && gem_dir.readlink == from
38
+ stdout.puts "Using #{name}:#{version} (#{from})"
39
+ when gem_dir.symlink?
40
+ prev = gem_dir.readlink
41
+ gem_dir.unlink
42
+ _install(from, dest.join(name, version))
43
+ stdout.puts "Updating #{name}:#{version} to #{from} from #{prev}"
44
+ when gem_dir.directory?
45
+ # TODO: Show version of git source
46
+ FileUtils.remove_entry_secure(gem_dir.to_s)
47
+ _install(from, dest.join(name, version))
48
+ stdout.puts "Updating #{name}:#{version} from git source"
49
+ when !gem_dir.exist?
50
+ _install(from, dest.join(name, version))
51
+ stdout.puts "Installing #{name}:#{version} (#{from})"
52
+ else
53
+ raise
54
+ end
55
+ end
56
+
57
+ private def _install(src, dst)
58
+ dst.dirname.mkpath
59
+ File.symlink(src, dst)
60
+ end
61
+
62
+ def manifest_of(name, version)
63
+ gem_dir = @full_path.join(name, version)
64
+ raise unless gem_dir.exist?
65
+
66
+ manifest_path = gem_dir.join('manifest.yaml')
67
+ YAML.safe_load(manifest_path.read) if manifest_path.exist?
68
+ end
69
+
70
+ def to_lockfile
71
+ {
72
+ 'type' => 'local',
73
+ 'path' => @path.to_s,
74
+ }
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -4,11 +4,12 @@ require_relative './sources/base'
4
4
  require_relative './sources/git'
5
5
  require_relative './sources/stdlib'
6
6
  require_relative './sources/rubygems'
7
+ require_relative './sources/local'
7
8
 
8
9
  module RBS
9
10
  module Collection
10
11
  module Sources
11
- def self.from_config_entry(source_entry)
12
+ def self.from_config_entry(source_entry, base_directory:)
12
13
  case source_entry['type']
13
14
  when 'git', nil # git source by default
14
15
  # @type var source_entry: Git::source_entry
@@ -18,6 +19,12 @@ module RBS
18
19
  remote: source_entry["remote"],
19
20
  repo_dir: source_entry["repo_dir"]
20
21
  )
22
+ when 'local'
23
+ # @type var source_entry: Local::source_entry
24
+ Local.new(
25
+ path: source_entry['path'],
26
+ base_directory: base_directory,
27
+ )
21
28
  when 'stdlib'
22
29
  Stdlib.instance
23
30
  when 'rubygems'
@@ -190,6 +190,8 @@ module RBS
190
190
  end
191
191
 
192
192
  def one_instance_ancestors(type_name)
193
+ type_name = env.normalize_module_name(type_name)
194
+
193
195
  as = one_instance_ancestors_cache[type_name] and return as
194
196
 
195
197
  entry = env.class_decls[type_name] or raise "Unknown name for one_instance_ancestors: #{type_name}"
@@ -210,6 +212,8 @@ module RBS
210
212
  super_args = []
211
213
  end
212
214
 
215
+ super_name = env.normalize_module_name(super_name)
216
+
213
217
  NoSuperclassFoundError.check!(super_name, env: env, location: primary.decl.location)
214
218
  if super_class
215
219
  InheritModuleError.check!(super_class, env: env)
@@ -236,7 +240,12 @@ module RBS
236
240
  else
237
241
  entry.self_types.each do |module_self|
238
242
  NoSelfTypeFoundError.check!(module_self, env: env)
239
- self_types.push Definition::Ancestor::Instance.new(name: module_self.name, args: module_self.args, source: module_self)
243
+
244
+ module_name = module_self.name
245
+ if module_name.class?
246
+ module_name = env.normalize_module_name(module_name)
247
+ end
248
+ self_types.push Definition::Ancestor::Instance.new(name: module_name, args: module_self.args, source: module_self)
240
249
  end
241
250
  end
242
251
  end
@@ -253,6 +262,7 @@ module RBS
253
262
  end
254
263
 
255
264
  def one_singleton_ancestors(type_name)
265
+ type_name = env.normalize_module_name(type_name)
256
266
  as = one_singleton_ancestors_cache[type_name] and return as
257
267
 
258
268
  entry = env.class_decls[type_name] or raise "Unknown name for one_singleton_ancestors: #{type_name}"
@@ -270,6 +280,8 @@ module RBS
270
280
  super_name = BuiltinNames::Object.name
271
281
  end
272
282
 
283
+ super_name = env.normalize_module_name(super_name)
284
+
273
285
  NoSuperclassFoundError.check!(super_name, env: env, location: primary.decl.location)
274
286
  if super_class
275
287
  InheritModuleError.check!(super_class, env: env)
@@ -328,16 +340,18 @@ module RBS
328
340
  when AST::Members::Include
329
341
  module_name = member.name
330
342
  module_args = member.args.map {|type| align_params ? type.sub(align_params) : type }
331
- ancestor = Definition::Ancestor::Instance.new(name: module_name, args: module_args, source: member)
332
343
 
333
344
  case
334
345
  when member.name.class? && included_modules
335
346
  MixinClassError.check!(type_name: type_name, env: env, member: member)
336
347
  NoMixinFoundError.check!(member.name, env: env, member: member)
337
- included_modules << ancestor
348
+
349
+ module_name = env.normalize_module_name(module_name)
350
+ included_modules << Definition::Ancestor::Instance.new(name: module_name, args: module_args, source: member)
338
351
  when member.name.interface? && included_interfaces
339
352
  NoMixinFoundError.check!(member.name, env: env, member: member)
340
- included_interfaces << ancestor
353
+
354
+ included_interfaces << Definition::Ancestor::Instance.new(name: module_name, args: module_args, source: member)
341
355
  end
342
356
 
343
357
  when AST::Members::Prepend
@@ -345,7 +359,7 @@ module RBS
345
359
  MixinClassError.check!(type_name: type_name, env: env, member: member)
346
360
  NoMixinFoundError.check!(member.name, env: env, member: member)
347
361
 
348
- module_name = member.name
362
+ module_name = env.normalize_module_name(member.name)
349
363
  module_args = member.args.map {|type| align_params ? type.sub(align_params) : type }
350
364
 
351
365
  prepended_modules << Definition::Ancestor::Instance.new(name: module_name, args: module_args, source: member)
@@ -354,16 +368,18 @@ module RBS
354
368
  when AST::Members::Extend
355
369
  module_name = member.name
356
370
  module_args = member.args
357
- ancestor = Definition::Ancestor::Instance.new(name: module_name, args: module_args, source: member)
358
371
 
359
372
  case
360
373
  when member.name.class? && extended_modules
361
374
  MixinClassError.check!(type_name: type_name, env: env, member: member)
362
375
  NoMixinFoundError.check!(member.name, env: env, member: member)
363
- extended_modules << ancestor
376
+
377
+ module_name = env.normalize_module_name(module_name)
378
+ extended_modules << Definition::Ancestor::Instance.new(name: module_name, args: module_args, source: member)
364
379
  when member.name.interface? && extended_interfaces
365
380
  NoMixinFoundError.check!(member.name, env: env, member: member)
366
- extended_interfaces << ancestor
381
+
382
+ extended_interfaces << Definition::Ancestor::Instance.new(name: module_name, args: module_args, source: member)
367
383
  end
368
384
  end
369
385
  end
@@ -3,7 +3,6 @@
3
3
  module RBS
4
4
  class DefinitionBuilder
5
5
  attr_reader :env
6
- attr_reader :type_name_resolver
7
6
  attr_reader :ancestor_builder
8
7
  attr_reader :method_builder
9
8
 
@@ -14,7 +13,6 @@ module RBS
14
13
 
15
14
  def initialize(env:, ancestor_builder: nil, method_builder: nil)
16
15
  @env = env
17
- @type_name_resolver = TypeNameResolver.from_env(env)
18
16
  @ancestor_builder = ancestor_builder || AncestorBuilder.new(env: env)
19
17
  @method_builder = method_builder || MethodBuilder.new(env: env)
20
18
 
@@ -72,7 +70,7 @@ module RBS
72
70
  entry = env.interface_decls[name] or raise "Unknown interface name: #{name}"
73
71
  entry.decl.type_params
74
72
  when name.alias?
75
- entry = env.alias_decls[name] or raise "Unknown alias name: #{name}"
73
+ entry = env.type_alias_decls[name] or raise "Unknown alias name: #{name}"
76
74
  entry.decl.type_params
77
75
  when name.class?
78
76
  entry = env.class_decls[name] or raise "Unknown module name: #{name}"
@@ -150,6 +148,8 @@ module RBS
150
148
  end
151
149
 
152
150
  def build_instance(type_name)
151
+ type_name = env.normalize_module_name(type_name)
152
+
153
153
  try_cache(type_name, cache: instance_cache) do
154
154
  entry = env.class_decls[type_name] or raise "Unknown name for build_instance: #{type_name}"
155
155
  ensure_namespace!(type_name.namespace, location: entry.decls[0].decl.location)
@@ -278,6 +278,8 @@ module RBS
278
278
  end
279
279
 
280
280
  def build_singleton(type_name)
281
+ type_name = env.normalize_module_name(type_name)
282
+
281
283
  try_cache type_name, cache: singleton_cache do
282
284
  entry = env.class_decls[type_name] or raise "Unknown name for build_singleton: #{type_name}"
283
285
  ensure_namespace!(type_name.namespace, location: entry.decls[0].decl.location)
@@ -743,13 +745,13 @@ module RBS
743
745
  end
744
746
 
745
747
  def expand_alias1(type_name)
746
- entry = env.alias_decls[type_name] or raise "Unknown alias name: #{type_name}"
748
+ entry = env.type_alias_decls[type_name] or raise "Unknown alias name: #{type_name}"
747
749
  as = entry.decl.type_params.each.map { Types::Bases::Any.new(location: nil) }
748
750
  expand_alias2(type_name, as)
749
751
  end
750
752
 
751
753
  def expand_alias2(type_name, args)
752
- entry = env.alias_decls[type_name] or raise "Unknown alias name: #{type_name}"
754
+ entry = env.type_alias_decls[type_name] or raise "Unknown alias name: #{type_name}"
753
755
 
754
756
  ensure_namespace!(type_name.namespace, location: entry.decl.location)
755
757
  params = entry.decl.type_params.each.map(&:name)
@@ -803,9 +805,7 @@ module RBS
803
805
  def validate_type_name(name, location)
804
806
  name = name.absolute!
805
807
 
806
- return if name.class? && env.class_decls.key?(name)
807
- return if name.interface? && env.interface_decls.key?(name)
808
- return if name.alias? && env.alias_decls.key?(name)
808
+ return if env.type_name?(name)
809
809
 
810
810
  raise NoTypeFoundError.new(type_name: name, location: location)
811
811
  end