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

Sign up to get free protection for your applications and to get access to all the features.
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