rbs 0.2.0

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 (132) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ruby.yml +28 -0
  3. data/.gitignore +12 -0
  4. data/.rubocop.yml +15 -0
  5. data/BSDL +22 -0
  6. data/CHANGELOG.md +9 -0
  7. data/COPYING +56 -0
  8. data/Gemfile +6 -0
  9. data/README.md +93 -0
  10. data/Rakefile +142 -0
  11. data/bin/annotate-with-rdoc +157 -0
  12. data/bin/console +14 -0
  13. data/bin/query-rdoc +103 -0
  14. data/bin/setup +10 -0
  15. data/bin/sort +89 -0
  16. data/bin/test_runner.rb +16 -0
  17. data/docs/CONTRIBUTING.md +97 -0
  18. data/docs/sigs.md +148 -0
  19. data/docs/stdlib.md +152 -0
  20. data/docs/syntax.md +528 -0
  21. data/exe/rbs +7 -0
  22. data/lib/rbs.rb +64 -0
  23. data/lib/rbs/ast/annotation.rb +27 -0
  24. data/lib/rbs/ast/comment.rb +27 -0
  25. data/lib/rbs/ast/declarations.rb +395 -0
  26. data/lib/rbs/ast/members.rb +362 -0
  27. data/lib/rbs/buffer.rb +50 -0
  28. data/lib/rbs/builtin_names.rb +55 -0
  29. data/lib/rbs/cli.rb +558 -0
  30. data/lib/rbs/constant.rb +26 -0
  31. data/lib/rbs/constant_table.rb +150 -0
  32. data/lib/rbs/definition.rb +170 -0
  33. data/lib/rbs/definition_builder.rb +919 -0
  34. data/lib/rbs/environment.rb +281 -0
  35. data/lib/rbs/environment_loader.rb +136 -0
  36. data/lib/rbs/environment_walker.rb +124 -0
  37. data/lib/rbs/errors.rb +187 -0
  38. data/lib/rbs/location.rb +102 -0
  39. data/lib/rbs/method_type.rb +123 -0
  40. data/lib/rbs/namespace.rb +91 -0
  41. data/lib/rbs/parser.y +1344 -0
  42. data/lib/rbs/prototype/rb.rb +553 -0
  43. data/lib/rbs/prototype/rbi.rb +587 -0
  44. data/lib/rbs/prototype/runtime.rb +381 -0
  45. data/lib/rbs/substitution.rb +46 -0
  46. data/lib/rbs/test.rb +26 -0
  47. data/lib/rbs/test/errors.rb +61 -0
  48. data/lib/rbs/test/hook.rb +294 -0
  49. data/lib/rbs/test/setup.rb +58 -0
  50. data/lib/rbs/test/spy.rb +325 -0
  51. data/lib/rbs/test/test_helper.rb +183 -0
  52. data/lib/rbs/test/type_check.rb +254 -0
  53. data/lib/rbs/type_name.rb +70 -0
  54. data/lib/rbs/types.rb +936 -0
  55. data/lib/rbs/variance_calculator.rb +138 -0
  56. data/lib/rbs/vendorer.rb +47 -0
  57. data/lib/rbs/version.rb +3 -0
  58. data/lib/rbs/writer.rb +269 -0
  59. data/lib/ruby/signature.rb +7 -0
  60. data/rbs.gemspec +46 -0
  61. data/stdlib/abbrev/abbrev.rbs +60 -0
  62. data/stdlib/base64/base64.rbs +71 -0
  63. data/stdlib/benchmark/benchmark.rbs +372 -0
  64. data/stdlib/builtin/array.rbs +1997 -0
  65. data/stdlib/builtin/basic_object.rbs +280 -0
  66. data/stdlib/builtin/binding.rbs +177 -0
  67. data/stdlib/builtin/builtin.rbs +45 -0
  68. data/stdlib/builtin/class.rbs +145 -0
  69. data/stdlib/builtin/comparable.rbs +116 -0
  70. data/stdlib/builtin/complex.rbs +400 -0
  71. data/stdlib/builtin/constants.rbs +37 -0
  72. data/stdlib/builtin/data.rbs +5 -0
  73. data/stdlib/builtin/deprecated.rbs +2 -0
  74. data/stdlib/builtin/dir.rbs +413 -0
  75. data/stdlib/builtin/encoding.rbs +607 -0
  76. data/stdlib/builtin/enumerable.rbs +404 -0
  77. data/stdlib/builtin/enumerator.rbs +260 -0
  78. data/stdlib/builtin/errno.rbs +781 -0
  79. data/stdlib/builtin/errors.rbs +582 -0
  80. data/stdlib/builtin/exception.rbs +194 -0
  81. data/stdlib/builtin/false_class.rbs +40 -0
  82. data/stdlib/builtin/fiber.rbs +68 -0
  83. data/stdlib/builtin/fiber_error.rbs +12 -0
  84. data/stdlib/builtin/file.rbs +1076 -0
  85. data/stdlib/builtin/file_test.rbs +59 -0
  86. data/stdlib/builtin/float.rbs +696 -0
  87. data/stdlib/builtin/gc.rbs +243 -0
  88. data/stdlib/builtin/hash.rbs +1029 -0
  89. data/stdlib/builtin/integer.rbs +707 -0
  90. data/stdlib/builtin/io.rbs +683 -0
  91. data/stdlib/builtin/kernel.rbs +576 -0
  92. data/stdlib/builtin/marshal.rbs +161 -0
  93. data/stdlib/builtin/match_data.rbs +271 -0
  94. data/stdlib/builtin/math.rbs +369 -0
  95. data/stdlib/builtin/method.rbs +185 -0
  96. data/stdlib/builtin/module.rbs +1104 -0
  97. data/stdlib/builtin/nil_class.rbs +82 -0
  98. data/stdlib/builtin/numeric.rbs +409 -0
  99. data/stdlib/builtin/object.rbs +824 -0
  100. data/stdlib/builtin/proc.rbs +429 -0
  101. data/stdlib/builtin/process.rbs +1227 -0
  102. data/stdlib/builtin/random.rbs +267 -0
  103. data/stdlib/builtin/range.rbs +226 -0
  104. data/stdlib/builtin/rational.rbs +424 -0
  105. data/stdlib/builtin/rb_config.rbs +57 -0
  106. data/stdlib/builtin/regexp.rbs +1083 -0
  107. data/stdlib/builtin/ruby_vm.rbs +14 -0
  108. data/stdlib/builtin/signal.rbs +55 -0
  109. data/stdlib/builtin/string.rbs +1901 -0
  110. data/stdlib/builtin/string_io.rbs +284 -0
  111. data/stdlib/builtin/struct.rbs +40 -0
  112. data/stdlib/builtin/symbol.rbs +228 -0
  113. data/stdlib/builtin/thread.rbs +1108 -0
  114. data/stdlib/builtin/thread_group.rbs +23 -0
  115. data/stdlib/builtin/time.rbs +1047 -0
  116. data/stdlib/builtin/trace_point.rbs +290 -0
  117. data/stdlib/builtin/true_class.rbs +46 -0
  118. data/stdlib/builtin/unbound_method.rbs +153 -0
  119. data/stdlib/builtin/warning.rbs +17 -0
  120. data/stdlib/coverage/coverage.rbs +62 -0
  121. data/stdlib/csv/csv.rbs +773 -0
  122. data/stdlib/erb/erb.rbs +392 -0
  123. data/stdlib/find/find.rbs +40 -0
  124. data/stdlib/ipaddr/ipaddr.rbs +247 -0
  125. data/stdlib/json/json.rbs +335 -0
  126. data/stdlib/pathname/pathname.rbs +1093 -0
  127. data/stdlib/prime/integer-extension.rbs +23 -0
  128. data/stdlib/prime/prime.rbs +188 -0
  129. data/stdlib/securerandom/securerandom.rbs +9 -0
  130. data/stdlib/set/set.rbs +301 -0
  131. data/stdlib/tmpdir/tmpdir.rbs +53 -0
  132. metadata +292 -0
@@ -0,0 +1,138 @@
1
+ module RBS
2
+ class VarianceCalculator
3
+ class Result
4
+ attr_reader :result
5
+
6
+ def initialize(variables:)
7
+ @result = {}
8
+ variables.each do |x|
9
+ result[x] = :unused
10
+ end
11
+ end
12
+
13
+ def covariant(x)
14
+ case result[x]
15
+ when :unused
16
+ result[x] = :covariant
17
+ when :contravariant
18
+ result[x] = :invariant
19
+ end
20
+ end
21
+
22
+ def contravariant(x)
23
+ case result[x]
24
+ when :unused
25
+ result[x] = :contravariant
26
+ when :covariant
27
+ result[x] = :invariant
28
+ end
29
+ end
30
+
31
+ def invariant(x)
32
+ result[x] = :invariant
33
+ end
34
+
35
+ def each(&block)
36
+ result.each(&block)
37
+ end
38
+
39
+ def include?(name)
40
+ result.key?(name)
41
+ end
42
+
43
+ def compatible?(var, with_annotation:)
44
+ variance = result[var]
45
+
46
+ case
47
+ when variance == :unused
48
+ true
49
+ when with_annotation == :invariant
50
+ true
51
+ when variance == with_annotation
52
+ true
53
+ else
54
+ false
55
+ end
56
+ end
57
+ end
58
+
59
+ attr_reader :builder
60
+
61
+ def initialize(builder:)
62
+ @builder = builder
63
+ end
64
+
65
+ def env
66
+ builder.env
67
+ end
68
+
69
+ def in_method_type(method_type:, variables:)
70
+ result = Result.new(variables: variables)
71
+
72
+ method_type.type.each_param do |param|
73
+ type(param.type, result: result, context: :contravariant)
74
+ end
75
+
76
+ if method_type.block
77
+ method_type.block.type.each_param do |param|
78
+ type(param.type, result: result, context: :covariant)
79
+ end
80
+ type(method_type.block.type.return_type, result: result, context: :contravariant)
81
+ end
82
+
83
+ type(method_type.type.return_type, result: result, context: :covariant)
84
+
85
+ result
86
+ end
87
+
88
+ def in_inherit(name:, args:, variables:)
89
+ type = Types::ClassInstance.new(name: name, args: args, location: nil)
90
+
91
+ Result.new(variables: variables).tap do |result|
92
+ type(type, result: result, context: :covariant)
93
+ end
94
+ end
95
+
96
+ def type(type, result:, context:)
97
+ case type
98
+ when Types::Variable
99
+ if result.include?(type.name)
100
+ case context
101
+ when :covariant
102
+ result.covariant(type.name)
103
+ when :contravariant
104
+ result.contravariant(type.name)
105
+ when :invariant
106
+ result.invariant(type.name)
107
+ end
108
+ end
109
+ when Types::ClassInstance, Types::Interface
110
+ decl = env.find_class(type.name)
111
+ type.args.each.with_index do |ty, i|
112
+ var = decl.type_params.params[i]
113
+ case var.variance
114
+ when :invariant
115
+ type(ty, result: result, context: :invariant)
116
+ when :covariant
117
+ type(ty, result: result, context: context)
118
+ when :contravariant
119
+ con = case context
120
+ when :invariant
121
+ :invariant
122
+ when :covariant
123
+ :contravariant
124
+ when :contravariant
125
+ :covariant
126
+ end
127
+ type(ty, result: result, context: con)
128
+ end
129
+ end
130
+ when Types::Tuple, Types::Record, Types::Union, Types::Intersection
131
+ # Covariant types
132
+ type.each_type do |ty|
133
+ type(ty, result: result, context: context)
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,47 @@
1
+ module RBS
2
+ class Vendorer
3
+ attr_reader :vendor_dir
4
+
5
+ def initialize(vendor_dir:)
6
+ @vendor_dir = vendor_dir
7
+ end
8
+
9
+ def ensure_dir
10
+ unless vendor_dir.directory?
11
+ vendor_dir.mkpath
12
+ end
13
+
14
+ yield
15
+ end
16
+
17
+ def clean!
18
+ ensure_dir do
19
+ RBS.logger.info "Cleaning vendor root: #{vendor_dir}..."
20
+ vendor_dir.rmtree
21
+ end
22
+ end
23
+
24
+ def stdlib!()
25
+ ensure_dir do
26
+ RBS.logger.info "Vendoring stdlib: #{EnvironmentLoader::STDLIB_ROOT} => #{vendor_dir + "stdlib"}..."
27
+ FileUtils.copy_entry EnvironmentLoader::STDLIB_ROOT, vendor_dir + "stdlib"
28
+ end
29
+ end
30
+
31
+ def gem!(name, version)
32
+ ensure_dir do
33
+ sig_path = EnvironmentLoader.gem_sig_path(name, version)
34
+ RBS.logger.debug "Checking gem signature path: name=#{name}, version=#{version}, path=#{sig_path}"
35
+
36
+ if sig_path&.directory?
37
+ gems_dir = vendor_dir + "gems"
38
+ gems_dir.mkpath unless gems_dir.directory?
39
+
40
+ gem_dir = gems_dir + name
41
+ RBS.logger.info "Vendoring gem(#{name}:#{version}): #{sig_path} => #{gem_dir}..."
42
+ FileUtils.copy_entry sig_path, gem_dir
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,3 @@
1
+ module RBS
2
+ VERSION = "0.2.0"
3
+ end
@@ -0,0 +1,269 @@
1
+ module RBS
2
+ class Writer
3
+ attr_reader :out
4
+
5
+ def initialize(out:)
6
+ @out = out
7
+ end
8
+
9
+ def write_annotation(annotations, level:)
10
+ prefix = " " * level
11
+
12
+ annotations.each do |annotation|
13
+ string = annotation.string
14
+ case
15
+ when string !~ /\}/
16
+ out.puts "#{prefix}%a{#{string}}"
17
+ when string !~ /\)/
18
+ out.puts "#{prefix}%a(#{string})"
19
+ when string !~ /\]/
20
+ out.puts "#{prefix}%a[#{string}]"
21
+ when string !~ /\>/
22
+ out.puts "#{prefix}%a<#{string}>"
23
+ when string !~ /\|/
24
+ out.puts "#{prefix}%a|#{string}|"
25
+ end
26
+ end
27
+ end
28
+
29
+ def write_comment(comment, level:)
30
+ if comment
31
+ prefix = " " * level
32
+ comment.string.lines.each do |line|
33
+ line = " #{line}" unless line.chomp.empty?
34
+ out.puts "#{prefix}##{line}"
35
+ end
36
+ end
37
+ end
38
+
39
+ def write(decls)
40
+ [nil, *decls].each_cons(2) do |prev, decl|
41
+ preserve_empty_line(prev, decl)
42
+ write_decl decl
43
+ end
44
+ end
45
+
46
+ def write_decl(decl)
47
+ case decl
48
+ when AST::Declarations::Class
49
+ super_class = if decl.super_class
50
+ " < #{name_and_args(decl.super_class.name, decl.super_class.args)}"
51
+ end
52
+ write_comment decl.comment, level: 0
53
+ write_annotation decl.annotations, level: 0
54
+ out.puts "class #{name_and_params(decl.name, decl.type_params)}#{super_class}"
55
+
56
+ [nil, *decl.members].each_cons(2) do |prev, member|
57
+ preserve_empty_line prev, member
58
+ write_member member
59
+ end
60
+
61
+ out.puts "end"
62
+
63
+ when AST::Declarations::Module
64
+ self_type = if decl.self_type
65
+ " : #{decl.self_type}"
66
+ end
67
+
68
+ write_comment decl.comment, level: 0
69
+ write_annotation decl.annotations, level: 0
70
+ out.puts "module #{name_and_params(decl.name, decl.type_params)}#{self_type}"
71
+ decl.members.each.with_index do |member, index|
72
+ if index > 0
73
+ out.puts
74
+ end
75
+ write_member member
76
+ end
77
+ out.puts "end"
78
+ when AST::Declarations::Constant
79
+ write_comment decl.comment, level: 0
80
+ out.puts "#{decl.name}: #{decl.type}"
81
+
82
+ when AST::Declarations::Global
83
+ write_comment decl.comment, level: 0
84
+ out.puts "#{decl.name}: #{decl.type}"
85
+
86
+ when AST::Declarations::Alias
87
+ write_comment decl.comment, level: 0
88
+ write_annotation decl.annotations, level: 0
89
+ out.puts "type #{decl.name} = #{decl.type}"
90
+
91
+ when AST::Declarations::Interface
92
+ write_comment decl.comment, level: 0
93
+ write_annotation decl.annotations, level: 0
94
+ out.puts "interface #{name_and_params(decl.name, decl.type_params)}"
95
+ decl.members.each.with_index do |member, index|
96
+ if index > 0
97
+ out.puts
98
+ end
99
+ write_member member
100
+ end
101
+ out.puts "end"
102
+
103
+ when AST::Declarations::Extension
104
+ write_comment decl.comment, level: 0
105
+ write_annotation decl.annotations, level: 0
106
+ out.puts "extension #{name_and_args(decl.name, decl.type_params)} (#{decl.extension_name})"
107
+ decl.members.each.with_index do |member, index|
108
+ if index > 0
109
+ out.puts
110
+ end
111
+ write_member member
112
+ end
113
+ out.puts "end"
114
+ end
115
+ end
116
+
117
+ def name_and_params(name, params)
118
+ if params.empty?
119
+ "#{name}"
120
+ else
121
+ ps = params.each.map do |param|
122
+ s = ""
123
+ if param.skip_validation
124
+ s << "unchecked "
125
+ end
126
+ case param.variance
127
+ when :invariant
128
+ # nop
129
+ when :covariant
130
+ s << "out "
131
+ when :contravariant
132
+ s << "in "
133
+ end
134
+ s + param.name.to_s
135
+ end
136
+
137
+ "#{name}[#{ps.join(", ")}]"
138
+ end
139
+ end
140
+
141
+ def name_and_args(name, args)
142
+ if name && args
143
+ if args.empty?
144
+ "#{name}"
145
+ else
146
+ "#{name}[#{args.join(", ")}]"
147
+ end
148
+ end
149
+ end
150
+
151
+ def write_member(member)
152
+ case member
153
+ when AST::Members::Include
154
+ write_comment member.comment, level: 2
155
+ write_annotation member.annotations, level: 2
156
+ out.puts " include #{name_and_args(member.name, member.args)}"
157
+ when AST::Members::Extend
158
+ write_comment member.comment, level: 2
159
+ write_annotation member.annotations, level: 2
160
+ out.puts " extend #{name_and_args(member.name, member.args)}"
161
+ when AST::Members::Prepend
162
+ write_comment member.comment, level: 2
163
+ write_annotation member.annotations, level: 2
164
+ out.puts " prepend #{name_and_args(member.name, member.args)}"
165
+ when AST::Members::AttrAccessor
166
+ write_comment member.comment, level: 2
167
+ write_annotation member.annotations, level: 2
168
+ out.puts " #{attribute(:accessor, member)}"
169
+ when AST::Members::AttrReader
170
+ write_comment member.comment, level: 2
171
+ write_annotation member.annotations, level: 2
172
+ out.puts " #{attribute(:reader, member)}"
173
+ when AST::Members::AttrWriter
174
+ write_comment member.comment, level: 2
175
+ write_annotation member.annotations, level: 2
176
+ out.puts " #{attribute(:writer, member)}"
177
+ when AST::Members::Public
178
+ out.puts " public"
179
+ when AST::Members::Private
180
+ out.puts " private"
181
+ when AST::Members::Alias
182
+ write_comment member.comment, level: 2
183
+ write_annotation member.annotations, level: 2
184
+ new_name = member.singleton? ? "self.#{member.new_name}" : member.new_name
185
+ old_name = member.singleton? ? "self.#{member.old_name}" : member.old_name
186
+ out.puts " alias #{new_name} #{old_name}"
187
+ when AST::Members::InstanceVariable
188
+ write_comment member.comment, level: 2
189
+ out.puts " #{member.name}: #{member.type}"
190
+ when AST::Members::ClassInstanceVariable
191
+ write_comment member.comment, level: 2
192
+ out.puts " self.#{member.name}: #{member.type}"
193
+ when AST::Members::ClassVariable
194
+ write_comment member.comment, level: 2
195
+ out.puts " #{member.name}: #{member.type}"
196
+ when AST::Members::MethodDefinition
197
+ write_comment member.comment, level: 2
198
+ write_annotation member.annotations, level: 2
199
+ write_def member
200
+ end
201
+ end
202
+
203
+ def method_name(name)
204
+ s = name.to_s
205
+
206
+ if /\A#{Parser::KEYWORDS_RE}\z/.match?(s)
207
+ "`#{s}`"
208
+ else
209
+ s
210
+ end
211
+ end
212
+
213
+ def write_def(member)
214
+ name = case member.kind
215
+ when :instance
216
+ "#{method_name(member.name)}"
217
+ when :singleton_instance
218
+ "self?.#{method_name(member.name)}"
219
+ when :singleton
220
+ "self.#{method_name(member.name)}"
221
+ end
222
+
223
+ attrs = member.attributes.empty? ? "" : member.attributes.join(" ") + " "
224
+ prefix = " #{attrs}def #{name}:"
225
+ padding = " " * (prefix.size-1)
226
+
227
+ out.print prefix
228
+
229
+ member.types.each.with_index do |type, index|
230
+ if index > 0
231
+ out.print padding
232
+ out.print "|"
233
+ end
234
+ out.puts " #{type}"
235
+ end
236
+ end
237
+
238
+ def attribute(kind, attr)
239
+ var = case attr.ivar_name
240
+ when nil
241
+ ""
242
+ when false
243
+ "()"
244
+ else
245
+ "(#{attr.ivar_name})"
246
+ end
247
+ "attr_#{kind} #{attr.name}#{var}: #{attr.type}"
248
+ end
249
+
250
+ def preserve_empty_line(prev, decl)
251
+ return unless prev
252
+
253
+ decl = decl.comment if decl.respond_to?(:comment) && decl.comment
254
+
255
+ # When the signature is not constructed by the parser,
256
+ # it always inserts an empty line.
257
+ if !prev.location || !decl.location
258
+ out.puts
259
+ return
260
+ end
261
+
262
+ prev_end_line = prev.location.end_line
263
+ start_line = decl.location.start_line
264
+ if start_line - prev_end_line > 1
265
+ out.puts
266
+ end
267
+ end
268
+ end
269
+ end