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
@@ -47,8 +47,9 @@ module RBS
47
47
  when path
48
48
  dirs << path
49
49
  when library
50
- if library == 'rubygems'
51
- RBS.logger.warn '`rubygems` has been moved to core library, so it is always loaded. Remove explicit loading `rubygems`'
50
+ case library
51
+ when 'rubygems', 'set'
52
+ RBS.logger.warn "`#{library}` has been moved to core library, so it is always loaded. Remove explicit loading `#{library}`"
52
53
  return
53
54
  end
54
55
 
@@ -95,9 +96,11 @@ module RBS
95
96
  # @type var loaded: Array[[AST::Declarations::t, Pathname, source]]
96
97
  loaded = []
97
98
 
98
- each_decl do |decl, buf, source, path|
99
- env << decl
100
- loaded << [decl, path, source]
99
+ each_signature do |source, path, buffer, decls, dirs|
100
+ decls.each do |decl|
101
+ loaded << [decl, path, source]
102
+ end
103
+ env.add_signature(buffer: buffer, directives: dirs, decls: decls)
101
104
  end
102
105
 
103
106
  loaded
@@ -148,7 +151,7 @@ module RBS
148
151
  end
149
152
  end
150
153
 
151
- def each_decl
154
+ def each_signature
152
155
  files = Set[]
153
156
 
154
157
  each_dir do |source, dir|
@@ -160,9 +163,9 @@ module RBS
160
163
  files << path
161
164
  buffer = Buffer.new(name: path.to_s, content: path.read(encoding: "UTF-8"))
162
165
 
163
- Parser.parse_signature(buffer).each do |decl|
164
- yield decl, buffer, source, path
165
- end
166
+ _, dirs, decls = Parser.parse_signature(buffer)
167
+
168
+ yield source, path, buffer, decls, dirs
166
169
  end
167
170
  end
168
171
  end
@@ -36,7 +36,7 @@ module RBS
36
36
  env.interface_decls.each_key do |type_name|
37
37
  yield TypeNameNode.new(type_name: type_name)
38
38
  end
39
- env.alias_decls.each_key do |type_name|
39
+ env.type_alias_decls.each_key do |type_name|
40
40
  yield TypeNameNode.new(type_name: type_name)
41
41
  end
42
42
  end
data/lib/rbs/errors.rb CHANGED
@@ -20,7 +20,25 @@ module RBS
20
20
  class LoadingError < BaseError; end
21
21
  class DefinitionError < BaseError; end
22
22
 
23
+ module DetailedMessageable
24
+ def detailed_message(highlight: false, **)
25
+ indent = " " * location.start_column
26
+ marker = "^" * (location.end_column - location.start_column)
27
+
28
+ io = StringIO.new
29
+ io.puts super
30
+ io.puts
31
+ io.print "\e[1m" if highlight
32
+ io.puts " #{location.buffer.lines[location.end_line - 1]}"
33
+ io.puts " #{indent}#{marker}"
34
+ io.print "\e[m" if highlight
35
+ io.string
36
+ end
37
+ end
38
+
23
39
  class ParsingError < BaseError
40
+ include DetailedMessageable
41
+
24
42
  attr_reader :location
25
43
  attr_reader :error_message
26
44
  attr_reader :token_type
@@ -119,19 +137,7 @@ module RBS
119
137
  end
120
138
 
121
139
  def self.check!(type_name, env:, location:)
122
- dic = case
123
- when type_name.class?
124
- env.class_decls
125
- when type_name.alias?
126
- env.alias_decls
127
- when type_name.interface?
128
- env.interface_decls
129
- else
130
- raise
131
- end
132
-
133
- dic.key?(type_name) or raise new(type_name: type_name, location: location)
134
-
140
+ env.type_name?(type_name) or raise new(type_name: type_name, location: location)
135
141
  type_name
136
142
  end
137
143
  end
@@ -148,7 +154,7 @@ module RBS
148
154
  end
149
155
 
150
156
  def self.check!(type_name, env:, location:)
151
- if decl = env.class_decls[type_name]
157
+ if env.module_name?(type_name)
152
158
  return
153
159
  end
154
160
 
@@ -166,7 +172,7 @@ module RBS
166
172
  end
167
173
 
168
174
  def self.check!(super_decl, env:)
169
- return if env.class_decls[super_decl.name].is_a?(Environment::ClassEntry)
175
+ return if env.class_decl?(super_decl.name) || env.class_alias?(super_decl.name)
170
176
 
171
177
  raise new(super_decl)
172
178
  end
@@ -186,16 +192,7 @@ module RBS
186
192
  def self.check!(self_type, env:)
187
193
  type_name = self_type.name
188
194
 
189
- dic = case
190
- when type_name.class?
191
- env.class_decls
192
- when type_name.interface?
193
- env.interface_decls
194
- else
195
- raise
196
- end
197
-
198
- dic.key?(type_name) or raise new(type_name: type_name, location: self_type.location)
195
+ (env.module_name?(type_name) || env.interface_name?(type_name)) or raise new(type_name: type_name, location: self_type.location)
199
196
  end
200
197
  end
201
198
 
@@ -215,16 +212,7 @@ module RBS
215
212
  end
216
213
 
217
214
  def self.check!(type_name, env:, member:)
218
- dic = case
219
- when type_name.class?
220
- env.class_decls
221
- when type_name.interface?
222
- env.interface_decls
223
- else
224
- raise
225
- end
226
-
227
- dic.key?(type_name) or raise new(type_name: type_name, member: member)
215
+ (env.module_name?(type_name) || env.interface_name?(type_name)) or raise new(type_name: type_name, member: member)
228
216
  end
229
217
  end
230
218
 
@@ -416,8 +404,7 @@ module RBS
416
404
  end
417
405
 
418
406
  def self.check!(type_name:, env:, member:)
419
- case env.class_decls[member.name]
420
- when Environment::ClassEntry
407
+ if env.class_decl?(member.name)
421
408
  raise new(type_name: type_name, member: member)
422
409
  end
423
410
  end
@@ -478,4 +465,32 @@ module RBS
478
465
  super "#{Location.to_string(location)}: Cyclic type parameter bound is prohibited"
479
466
  end
480
467
  end
468
+
469
+ class InconsistentClassModuleAliasError < BaseError
470
+ attr_reader :alias_entry
471
+
472
+ def initialize(entry)
473
+ @alias_entry = entry
474
+
475
+ expected_kind, actual_kind =
476
+ case entry
477
+ when Environment::ModuleAliasEntry
478
+ ["module", "class"]
479
+ when Environment::ClassAliasEntry
480
+ ["class", "module"]
481
+ end
482
+
483
+ super "#{Location.to_string(entry.decl.location&.[](:old_name))}: A #{expected_kind} `#{entry.decl.new_name}` cannot be an alias of a #{actual_kind} `#{entry.decl.old_name}`"
484
+ end
485
+ end
486
+
487
+ class CyclicClassAliasDefinitionError < BaseError
488
+ attr_reader :alias_entry
489
+
490
+ def initialize(entry)
491
+ @alias_entry = entry
492
+
493
+ super "#{Location.to_string(entry.decl.location&.[](:old_name))}: A #{alias_entry.decl.new_name} is a cyclic definition"
494
+ end
495
+ end
481
496
  end
data/lib/rbs/locator.rb CHANGED
@@ -2,21 +2,24 @@
2
2
 
3
3
  module RBS
4
4
  class Locator
5
- attr_reader :decls
5
+ attr_reader :decls, :dirs, :buffer
6
6
 
7
- def initialize(decls:)
7
+ def initialize(buffer:, dirs:, decls:)
8
+ @buffer = buffer
9
+ @dirs = dirs
8
10
  @decls = decls
9
11
  end
10
12
 
11
- def buffer
12
- decls[0].location&.buffer or raise
13
- end
14
-
15
13
  def find(line:, column:)
16
14
  pos = buffer.loc_to_pos([line, column])
17
15
 
16
+ dirs.each do |dir|
17
+ array = [] #: Array[component]
18
+ find_in_directive(pos, dir, array) and return array
19
+ end
20
+
18
21
  decls.each do |decl|
19
- array = []
22
+ array = [] #: Array[component]
20
23
  find_in_decl(pos, decl: decl, array: array) and return array
21
24
  end
22
25
 
@@ -36,6 +39,22 @@ module RBS
36
39
  end
37
40
  end
38
41
 
42
+ def find_in_directive(pos, dir, array)
43
+ if test_loc(pos, location: dir.location)
44
+ array.unshift(dir)
45
+
46
+ dir.clauses.each do |clause|
47
+ if test_loc(pos, location: clause.location)
48
+ array.unshift(clause)
49
+ find_in_loc(pos, location: clause.location, array: array)
50
+ return true
51
+ end
52
+ end
53
+ end
54
+
55
+ false
56
+ end
57
+
39
58
  def find_in_decl(pos, decl:, array:)
40
59
  if test_loc(pos, location: decl.location)
41
60
  array.unshift(decl)
@@ -95,7 +114,7 @@ module RBS
95
114
  when AST::Declarations::Constant, AST::Declarations::Global
96
115
  find_in_type(pos, array: array, type: decl.type) and return true
97
116
 
98
- when AST::Declarations::Alias
117
+ when AST::Declarations::TypeAlias
99
118
  find_in_type(pos, array: array, type: decl.type) and return true
100
119
  end
101
120
 
@@ -2,19 +2,21 @@
2
2
 
3
3
  module RBS
4
4
  class Parser
5
- def self.parse_type(source, line: nil, column: nil, range: nil, variables: [])
5
+ def self.parse_type(source, range: 0..., variables: [])
6
6
  buf = buffer(source)
7
- _parse_type(buf, range&.begin || 0, range&.end || buf.last_position, variables, range.nil?)
7
+ _parse_type(buf, range.begin || 0, range.end || buf.last_position, variables)
8
8
  end
9
9
 
10
- def self.parse_method_type(source, line: nil, column: nil, range: nil, variables: [])
10
+ def self.parse_method_type(source, range: 0..., variables: [])
11
11
  buf = buffer(source)
12
- _parse_method_type(buf, range&.begin || 0, range&.end || buf.last_position, variables, range.nil?)
12
+ _parse_method_type(buf, range.begin || 0, range.end || buf.last_position, variables)
13
13
  end
14
14
 
15
- def self.parse_signature(source, line: nil, column: nil)
15
+ def self.parse_signature(source)
16
16
  buf = buffer(source)
17
- _parse_signature(buf, buf.last_position)
17
+ dirs, decls = _parse_signature(buf, buf.last_position)
18
+
19
+ [buf, dirs, decls]
18
20
  end
19
21
 
20
22
  def self.buffer(source)
@@ -18,20 +18,33 @@ module RBS
18
18
  end
19
19
 
20
20
  environment.class_decls.each do |name, entry|
21
+ constant = constant_of_module(name, entry)
22
+
21
23
  unless name.namespace.empty?
22
24
  parent = name.namespace.to_type_name
23
-
24
25
  table = children_table[parent] or raise
25
- constant = constant_of_module(name, entry)
26
26
  else
27
27
  table = toplevel
28
- constant = constant_of_module(name, entry)
29
28
  end
30
29
 
31
30
  table[name.name] = constant
32
31
  constants_table[name] = constant
33
32
  end
34
33
 
34
+ environment.class_alias_decls.each do |name, entry|
35
+ normalized_entry = environment.normalized_module_class_entry(name) or next
36
+ constant = constant_of_module(name, normalized_entry)
37
+
38
+ # Insert class/module aliases into `children_table` and `toplevel` table
39
+ unless name.namespace.empty?
40
+ normalized_parent = environment.normalize_module_name?(name.namespace.to_type_name) or raise
41
+ table = children_table[normalized_parent] or raise
42
+ table[name.name] = constant
43
+ else
44
+ toplevel[name.name] = constant
45
+ end
46
+ end
47
+
35
48
  environment.constant_decls.each do |name, entry|
36
49
  unless name.namespace.empty?
37
50
  parent = name.namespace.to_type_name
@@ -97,6 +110,8 @@ module RBS
97
110
  end
98
111
 
99
112
  def children(module_name)
113
+ module_name = builder.env.normalize_module_name(module_name)
114
+
100
115
  unless child_constants_cache.key?(module_name)
101
116
  load_child_constants(module_name)
102
117
  end
@@ -113,6 +128,7 @@ module RBS
113
128
  else
114
129
  constants_from_ancestors(BuiltinNames::Object.name, constants: consts)
115
130
  end
131
+
116
132
  constants_from_context(context, constants: consts) or return
117
133
  constants_itself(context, constants: consts)
118
134
 
@@ -151,7 +167,7 @@ module RBS
151
167
  constants_from_context(parent, constants: constants) or return false
152
168
 
153
169
  if last
154
- consts = table.children(last) or return false
170
+ consts = table.children(builder.env.normalize_module_name(last)) or return false
155
171
  constants.merge!(consts)
156
172
  end
157
173
  end
@@ -160,14 +176,14 @@ module RBS
160
176
  end
161
177
 
162
178
  def constants_from_ancestors(module_name, constants:)
163
- entry = builder.env.class_decls[module_name]
179
+ entry = builder.env.normalized_module_class_entry(module_name) or raise
164
180
 
165
- if entry.is_a?(Environment::ModuleEntry)
181
+ if entry.is_a?(Environment::ClassEntry) || entry.is_a?(Environment::ModuleEntry)
166
182
  constants.merge!(table.children(BuiltinNames::Object.name) || raise)
167
183
  constants.merge!(table.toplevel)
168
184
  end
169
185
 
170
- builder.ancestor_builder.instance_ancestors(module_name).ancestors.reverse_each do |ancestor|
186
+ builder.ancestor_builder.instance_ancestors(entry.name).ancestors.reverse_each do |ancestor|
171
187
  if ancestor.is_a?(Definition::Ancestor::Instance)
172
188
  case ancestor.source
173
189
  when AST::Members::Include, :super, nil
@@ -12,7 +12,8 @@ module RBS
12
12
 
13
13
  all_names.merge(env.class_decls.keys)
14
14
  all_names.merge(env.interface_decls.keys)
15
- all_names.merge(env.alias_decls.keys)
15
+ all_names.merge(env.type_alias_decls.keys)
16
+ all_names.merge(env.class_alias_decls.keys)
16
17
  end
17
18
 
18
19
  def try_cache(query)
data/lib/rbs/sorter.rb CHANGED
@@ -15,7 +15,7 @@ module RBS
15
15
  stdout.puts "Opening #{path}..."
16
16
 
17
17
  buffer = Buffer.new(name: path, content: path.read)
18
- sigs = Parser.parse_signature(buffer)
18
+ _, _, sigs = Parser.parse_signature(buffer)
19
19
 
20
20
  sigs.each do |m|
21
21
  sort_decl! m
@@ -30,11 +30,11 @@ module RBS
30
30
 
31
31
  def group(member)
32
32
  case member
33
- when Declarations::Alias
33
+ when Declarations::TypeAlias
34
34
  -3
35
35
  when Declarations::Constant
36
36
  -2
37
- when Declarations::Class, Declarations::Module
37
+ when Declarations::Class, Declarations::Module, Declarations::Interface
38
38
  -1
39
39
  when Members::Include
40
40
  0.0
@@ -100,9 +100,9 @@ module RBS
100
100
  member.new_name.to_s
101
101
  when Declarations::Constant
102
102
  member.name.to_s
103
- when Declarations::Alias
103
+ when Declarations::TypeAlias
104
104
  member.name.to_s
105
- when Declarations::Class, Declarations::Module
105
+ when Declarations::Class, Declarations::Module, Declarations::Interface
106
106
  member.name.to_s
107
107
  else
108
108
  raise
@@ -67,7 +67,7 @@ TracePoint.trace :end do |tp|
67
67
 
68
68
  if class_name
69
69
  if filter.any? {|f| match(to_absolute_typename(f).to_s, class_name.to_s) } && skips.none? {|f| match(f, class_name.to_s) }
70
- if env.class_decls.key?(class_name)
70
+ if env.module_name?(class_name)
71
71
  logger.info "Setting up hooks for #{class_name}"
72
72
  tester.install!(tp.self, sample_size: sample_size, unchecked_classes: unchecked_classes)
73
73
  end
@@ -32,7 +32,7 @@ module RBS
32
32
  # Initialize dependencies as an empty hash
33
33
  @dependencies = {}
34
34
  # Iterate over alias declarations inserted into environment
35
- env.alias_decls.each do |name, entry|
35
+ env.type_alias_decls.each do |name, entry|
36
36
  # Construct a directed graph by recursively extracting type aliases
37
37
  @direct_dependencies[name] = direct_dependency(entry.decl.type)
38
38
  # Initialize dependencies with an empty hash
@@ -57,7 +57,7 @@ module RBS
57
57
  end
58
58
 
59
59
  def build_alias_type(name)
60
- entry = env.alias_decls[name] or return
60
+ entry = env.type_alias_decls[name] or return
61
61
  unless entry.decl.type_params.empty?
62
62
  as = entry.decl.type_params.each.map {|param| Types::Variable.new(name: param.name, location: nil) }
63
63
  Types::Alias.new(name: name, args: as, location: nil)
@@ -81,13 +81,13 @@ module RBS
81
81
  def each_mutual_alias_defs(&block)
82
82
  # @type var each_node: TSort::_EachNode[TypeName]
83
83
  each_node = __skip__ = -> (&block) do
84
- env.alias_decls.each_value do |decl|
84
+ env.type_alias_decls.each_value do |decl|
85
85
  block[decl.name]
86
86
  end
87
87
  end
88
88
  # @type var each_child: TSort::_EachChild[TypeName]
89
89
  each_child = __skip__ = -> (name, &block) do
90
- if env.alias_decls.key?(name)
90
+ if env.type_alias_decls.key?(name)
91
91
  type = builder.expand_alias1(name)
92
92
  each_alias_type(type) do |ty|
93
93
  block[ty.name]
data/lib/rbs/validator.rb CHANGED
@@ -33,11 +33,12 @@ module RBS
33
33
 
34
34
  type_params = case type
35
35
  when Types::ClassInstance
36
- env.class_decls[type.name].type_params
36
+ entry = env.normalized_module_class_entry(type.name) or raise
37
+ entry.type_params
37
38
  when Types::Interface
38
39
  env.interface_decls[type.name].decl.type_params
39
40
  when Types::Alias
40
- env.alias_decls[type.name].decl.type_params
41
+ env.type_alias_decls[type.name].decl.type_params
41
42
  end
42
43
 
43
44
  InvalidTypeApplicationError.check!(
@@ -147,6 +148,26 @@ module RBS
147
148
  end
148
149
  end
149
150
 
151
+ def validate_class_alias(entry:)
152
+ case env.normalize_module_name?(entry.decl.new_name)
153
+ when nil
154
+ raise NoTypeFoundError.new(type_name: entry.decl.old_name, location: entry.decl.location&.[](:old_name))
155
+ when false
156
+ raise CyclicClassAliasDefinitionError.new(entry)
157
+ end
158
+
159
+ case entry
160
+ when Environment::ClassAliasEntry
161
+ unless env.class_entry(entry.decl.old_name)
162
+ raise InconsistentClassModuleAliasError.new(entry)
163
+ end
164
+ when Environment::ModuleAliasEntry
165
+ unless env.module_entry(entry.decl.old_name)
166
+ raise InconsistentClassModuleAliasError.new(entry)
167
+ end
168
+ end
169
+ end
170
+
150
171
  def type_alias_dependency
151
172
  @type_alias_dependency ||= TypeAliasDependency.new(env: env)
152
173
  end
@@ -108,7 +108,7 @@ module RBS
108
108
  end
109
109
 
110
110
  def in_type_alias(name:)
111
- decl = env.alias_decls[name].decl or raise
111
+ decl = env.type_alias_decls[name].decl or raise
112
112
  variables = decl.type_params.each.map(&:name)
113
113
  Result.new(variables: variables).tap do |result|
114
114
  type(decl.type, result: result, context: :covariant)
@@ -139,7 +139,7 @@ module RBS
139
139
  when Types::Interface
140
140
  env.interface_decls[type.name].decl.type_params
141
141
  when Types::Alias
142
- env.alias_decls[type.name].decl.type_params
142
+ env.type_alias_decls[type.name].decl.type_params
143
143
  end
144
144
 
145
145
  type.args.each.with_index do |ty, i|
data/lib/rbs/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RBS
4
- VERSION = "3.0.0.dev.1"
4
+ VERSION = "3.0.0.dev.3"
5
5
  end
data/lib/rbs/writer.rb CHANGED
@@ -76,7 +76,16 @@ module RBS
76
76
  end
77
77
  end
78
78
 
79
- def write(decls)
79
+ def write(contents)
80
+ dirs = contents.select {|c| c.is_a?(AST::Directives::Base) } #: Array[AST::Directives::t]
81
+ decls = contents.select {|c| c.is_a?(AST::Declarations::Base) } #: Array[AST::Declarations::t]
82
+
83
+ dirs.each do |dir|
84
+ write_directive(dir)
85
+ end
86
+
87
+ puts unless dirs.empty?
88
+
80
89
  [nil, *decls].each_cons(2) do |prev, decl|
81
90
  raise unless decl
82
91
 
@@ -85,6 +94,23 @@ module RBS
85
94
  end
86
95
  end
87
96
 
97
+ def write_directive(dir)
98
+ clauses = dir.clauses.map do |clause|
99
+ case clause
100
+ when AST::Directives::Use::SingleClause
101
+ if clause.new_name
102
+ "#{clause.type_name} as #{clause.new_name}"
103
+ else
104
+ "#{clause.type_name}"
105
+ end
106
+ when AST::Directives::Use::WildcardClause
107
+ "#{clause.namespace}*"
108
+ end
109
+ end
110
+
111
+ puts "use #{clauses.join(", ")}"
112
+ end
113
+
88
114
  def write_decl(decl)
89
115
  case decl
90
116
  when AST::Declarations::Class
@@ -134,7 +160,7 @@ module RBS
134
160
  write_comment decl.comment
135
161
  puts "#{decl.name}: #{decl.type}"
136
162
 
137
- when AST::Declarations::Alias
163
+ when AST::Declarations::TypeAlias
138
164
  write_comment decl.comment
139
165
  write_annotation decl.annotations
140
166
  write_loc_source(decl) {
data/lib/rbs.rb CHANGED
@@ -17,10 +17,12 @@ require "rbs/type_name"
17
17
  require "rbs/types"
18
18
  require "rbs/method_type"
19
19
  require "rbs/ast/type_param"
20
+ require "rbs/ast/directives"
20
21
  require "rbs/ast/declarations"
21
22
  require "rbs/ast/members"
22
23
  require "rbs/ast/annotation"
23
24
  require "rbs/environment"
25
+ require "rbs/environment/use_map"
24
26
  require "rbs/environment_loader"
25
27
  require "rbs/builtin_names"
26
28
  require "rbs/definition"
@@ -32,7 +34,6 @@ require "rbs/substitution"
32
34
  require "rbs/constant"
33
35
  require "rbs/resolver/constant_resolver"
34
36
  require "rbs/resolver/type_name_resolver"
35
- require "rbs/constant_table"
36
37
  require "rbs/ast/comment"
37
38
  require "rbs/writer"
38
39
  require "rbs/prototype/helpers"
@@ -40,7 +41,6 @@ require "rbs/prototype/rbi"
40
41
  require "rbs/prototype/rb"
41
42
  require "rbs/prototype/runtime"
42
43
  require "rbs/prototype/node_usage"
43
- require "rbs/type_name_resolver"
44
44
  require "rbs/environment_walker"
45
45
  require "rbs/vendorer"
46
46
  require "rbs/validator"
@@ -14,8 +14,8 @@ module RBS
14
14
  end
15
15
 
16
16
  def scan
17
- ast = ::RBS::Parser.parse_signature(@content)
18
- ast.each do |decl|
17
+ _, _, decls = ::RBS::Parser.parse_signature(@content)
18
+ decls.each do |decl|
19
19
  parse_member(decl: decl, context: @top_level)
20
20
  end
21
21
  @top_level
data/rbs.gemspec CHANGED
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
28
28
  # Specify which files should be added to the gem when it is released.
29
29
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
30
30
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
31
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|bin)/}) }
31
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|bin|steep)/}) }
32
32
  end
33
33
  spec.extensions = %w{ext/rbs_extension/extconf.rb}
34
34
 
@@ -1,4 +1,22 @@
1
1
  module RBS
2
+ # AncestorGraph is a utility class that helps iterating through ancestors and decendants of a class/module
3
+ #
4
+ # ```ruby
5
+ # graph = AncestorGraph.new(env: env, ancestor_builder: ancestor_builder)
6
+ #
7
+ # graph.each_parent(AncestorGraph::InstanceNode.new(type_name: TypeName("::Object")))
8
+ # graph.each_ancestor(AncestorGraph::InstanceNode.new(type_name: TypeName("::Object")))
9
+ #
10
+ # graph.each_child(AncestorGraph::InstanceNode.new(type_name: TypeName("::Object")))
11
+ # graph.each_descendant(AncestorGraph::InstanceNode.new(type_name: TypeName("::Object")))
12
+ # ```
13
+ #
14
+ # Note that the class works for class/module declarations.
15
+ # All of the *alias* classes/modules are ignored.
16
+ #
17
+ # * Alias classes/modules doesn't count as a parent nor child
18
+ # * Passing alias classes/modules to the method doesn't yield anything
19
+ #
2
20
  class AncestorGraph
3
21
  class InstanceNode
4
22
  attr_reader type_name: TypeName
@@ -19,8 +37,6 @@ module RBS
19
37
 
20
38
  def initialize: (env: Environment, ?ancestor_builder: DefinitionBuilder::AncestorBuilder) -> void
21
39
 
22
- def build: () -> void
23
-
24
40
  def each_parent: (node) { (node) -> void } -> void
25
41
  | (node) -> Enumerator[node, void]
26
42
 
@@ -33,6 +49,10 @@ module RBS
33
49
  def each_descendant: (node, ?yielded: Set[node]) { (node) -> void } -> void
34
50
  | (node) -> Enumerator[node, void]
35
51
 
52
+ private
53
+
54
+ def build: () -> void
55
+
36
56
  def build_ancestors: (node, DefinitionBuilder::AncestorBuilder::OneAncestors) -> void
37
57
 
38
58
  def register: (parent: node, child: node) -> void