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