rbs 3.2.2 → 3.3.0.pre.1

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 (125) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/comments.yml +1 -1
  3. data/.github/workflows/ruby.yml +7 -2
  4. data/CHANGELOG.md +85 -0
  5. data/Gemfile.lock +14 -14
  6. data/README.md +11 -2
  7. data/Rakefile +10 -7
  8. data/Steepfile +7 -7
  9. data/core/basic_object.rbs +7 -7
  10. data/core/binding.rbs +3 -3
  11. data/core/builtin.rbs +171 -5
  12. data/core/constants.rbs +17 -17
  13. data/core/dir.rbs +3 -3
  14. data/core/encoding.rbs +434 -628
  15. data/core/enumerator.rbs +37 -0
  16. data/core/exception.rbs +11 -11
  17. data/core/false_class.rbs +5 -11
  18. data/core/fiber.rbs +3 -3
  19. data/core/file_test.rbs +28 -26
  20. data/core/kernel.rbs +900 -21
  21. data/core/marshal.rbs +24 -14
  22. data/core/match_data.rbs +8 -8
  23. data/core/math.rbs +57 -53
  24. data/core/method.rbs +3 -1
  25. data/core/module.rbs +38 -36
  26. data/core/nil_class.rbs +7 -13
  27. data/core/object.rbs +3 -966
  28. data/core/process.rbs +3 -3
  29. data/core/ractor.rbs +2 -2
  30. data/core/rb_config.rbs +64 -43
  31. data/core/regexp.rbs +3 -3
  32. data/core/signal.rbs +10 -4
  33. data/core/struct.rbs +1 -1
  34. data/core/thread.rbs +7 -7
  35. data/core/thread_group.rbs +9 -9
  36. data/core/true_class.rbs +5 -11
  37. data/core/unbound_method.rbs +56 -7
  38. data/core/warning.rbs +33 -0
  39. data/docs/collection.md +56 -6
  40. data/docs/data_and_struct.md +57 -0
  41. data/docs/stdlib.md +61 -2
  42. data/docs/syntax.md +123 -2
  43. data/ext/rbs_extension/lexer.c +624 -569
  44. data/ext/rbs_extension/lexer.h +1 -0
  45. data/ext/rbs_extension/lexer.re +1 -0
  46. data/ext/rbs_extension/lexstate.c +1 -0
  47. data/ext/rbs_extension/parser.c +6 -0
  48. data/goodcheck.yml +2 -2
  49. data/lib/rbs/annotate/formatter.rb +13 -3
  50. data/lib/rbs/annotate/rdoc_source.rb +10 -1
  51. data/lib/rbs/cli/colored_io.rb +48 -0
  52. data/lib/rbs/cli/diff.rb +80 -0
  53. data/lib/rbs/cli.rb +151 -16
  54. data/lib/rbs/collection/config/lockfile.rb +0 -25
  55. data/lib/rbs/collection/config/lockfile_generator.rb +0 -6
  56. data/lib/rbs/collection/installer.rb +1 -1
  57. data/lib/rbs/collection/sources/git.rb +6 -4
  58. data/lib/rbs/collection/sources/local.rb +7 -5
  59. data/lib/rbs/diff.rb +104 -0
  60. data/lib/rbs/environment.rb +1 -1
  61. data/lib/rbs/method_type.rb +23 -0
  62. data/lib/rbs/prototype/rb.rb +2 -9
  63. data/lib/rbs/prototype/runtime/helpers.rb +59 -0
  64. data/lib/rbs/prototype/runtime/value_object_generator.rb +236 -0
  65. data/lib/rbs/prototype/runtime.rb +234 -150
  66. data/lib/rbs/sorter.rb +144 -117
  67. data/lib/rbs/test/guaranteed.rb +31 -0
  68. data/lib/rbs/test/type_check.rb +4 -4
  69. data/lib/rbs/test.rb +3 -0
  70. data/lib/rbs/types.rb +184 -3
  71. data/lib/rbs/version.rb +1 -1
  72. data/lib/rbs/writer.rb +4 -4
  73. data/lib/rbs.rb +1 -0
  74. data/rbs.gemspec +1 -0
  75. data/sig/annotate/formatter.rbs +2 -2
  76. data/sig/annotate/rdoc_annotater.rbs +1 -1
  77. data/sig/cli/colored_io.rbs +15 -0
  78. data/sig/cli/diff.rbs +21 -0
  79. data/sig/cli.rbs +2 -0
  80. data/sig/collection/config/lockfile.rbs +0 -6
  81. data/sig/diff.rbs +23 -0
  82. data/sig/errors.rbs +1 -5
  83. data/sig/method_types.rbs +6 -0
  84. data/sig/prototype/runtime.rbs +108 -0
  85. data/sig/rdoc/rbs.rbs +4 -0
  86. data/sig/shims/bundler.rbs +5 -0
  87. data/sig/sorter.rbs +23 -5
  88. data/sig/types.rbs +29 -0
  89. data/stdlib/benchmark/0/benchmark.rbs +1 -1
  90. data/stdlib/cgi/0/core.rbs +2 -2
  91. data/stdlib/did_you_mean/0/did_you_mean.rbs +2 -2
  92. data/stdlib/digest/0/digest.rbs +1 -1
  93. data/stdlib/fileutils/0/fileutils.rbs +1 -1
  94. data/stdlib/forwardable/0/forwardable.rbs +4 -4
  95. data/stdlib/io-console/0/io-console.rbs +1 -1
  96. data/stdlib/json/0/json.rbs +37 -0
  97. data/stdlib/logger/0/logger.rbs +2 -2
  98. data/stdlib/net-http/0/manifest.yaml +1 -1
  99. data/stdlib/net-http/0/net-http.rbs +16 -63
  100. data/stdlib/net-protocol/0/manifest.yaml +2 -0
  101. data/stdlib/net-protocol/0/net-protocol.rbs +56 -0
  102. data/stdlib/openssl/0/openssl.rbs +1 -1
  103. data/stdlib/pp/0/manifest.yaml +2 -0
  104. data/stdlib/pp/0/pp.rbs +301 -0
  105. data/stdlib/{yaml → psych}/0/dbm.rbs +3 -3
  106. data/stdlib/psych/0/manifest.yaml +3 -0
  107. data/stdlib/psych/0/psych.rbs +391 -0
  108. data/stdlib/{yaml → psych}/0/store.rbs +2 -2
  109. data/stdlib/rdoc/0/code_object.rbs +55 -0
  110. data/stdlib/rdoc/0/comment.rbs +60 -0
  111. data/stdlib/rdoc/0/context.rbs +153 -0
  112. data/stdlib/rdoc/0/markup.rbs +119 -0
  113. data/stdlib/rdoc/0/parser.rbs +56 -0
  114. data/stdlib/rdoc/0/rdoc.rbs +0 -372
  115. data/stdlib/rdoc/0/ri.rbs +17 -0
  116. data/stdlib/rdoc/0/store.rbs +48 -0
  117. data/stdlib/rdoc/0/top_level.rbs +97 -0
  118. data/stdlib/socket/0/basic_socket.rbs +1 -1
  119. data/stdlib/socket/0/socket.rbs +1 -1
  120. data/stdlib/uri/0/common.rbs +1 -1
  121. data/stdlib/yaml/0/manifest.yaml +1 -2
  122. data/stdlib/yaml/0/yaml.rbs +1 -199
  123. metadata +46 -9
  124. data/sig/shims/pp.rbs +0 -3
  125. data/sig/shims.rbs +0 -47
data/lib/rbs/diff.rb ADDED
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ class Diff
5
+ def initialize(type_name:, library_options:, after_path: [], before_path: [])
6
+ @type_name = type_name
7
+ @library_options = library_options
8
+ @after_path = after_path
9
+ @before_path = before_path
10
+ end
11
+
12
+ def each_diff(&block)
13
+ return to_enum(:each_diff) unless block
14
+
15
+ before_instance_methods, before_singleton_methods, before_constant_decls = build_methods(@before_path)
16
+ after_instance_methods, after_singleton_methods, after_constant_decls = build_methods(@after_path)
17
+
18
+ each_diff_methods(:instance, before_instance_methods, after_instance_methods, &block)
19
+ each_diff_methods(:singleton, before_singleton_methods, after_singleton_methods, &block)
20
+
21
+ each_diff_constants(before_constant_decls, after_constant_decls, &block)
22
+ end
23
+
24
+ private
25
+
26
+ def each_diff_methods(kind, before_methods, after_methods)
27
+ all_keys = before_methods.keys.to_set + after_methods.keys.to_set
28
+ all_keys.each do |key|
29
+ before = definition_method_to_s(key, kind, before_methods[key]) or next
30
+ after = definition_method_to_s(key, kind, after_methods[key]) or next
31
+ next if before == after
32
+
33
+ yield before, after
34
+ end
35
+ end
36
+
37
+ def each_diff_constants(before_constant_decls, after_constant_decls)
38
+ all_keys = before_constant_decls.keys.to_set + after_constant_decls.keys.to_set
39
+ all_keys.each do |key|
40
+ before = constant_to_s(key, before_constant_decls[key]) or next
41
+ after = constant_to_s(key, after_constant_decls[key]) or next
42
+ next if before == after
43
+
44
+ yield before, after
45
+ end
46
+ end
47
+
48
+ def build_methods(path)
49
+ env = build_env(path)
50
+ builder = build_builder(env)
51
+
52
+ instance_methods = begin
53
+ builder.build_instance(@type_name).methods
54
+ rescue => e
55
+ RBS.logger.warn("#{path}: #{e.message}")
56
+ {}
57
+ end
58
+ singleton_methods = begin
59
+ builder.build_singleton(@type_name).methods
60
+ rescue => e
61
+ RBS.logger.warn("#{path}: #{e.message}")
62
+ {}
63
+ end
64
+ type_name_to_s = @type_name.to_s
65
+ constant_decls = env.constant_decls.select { |key| key.to_s.start_with?(type_name_to_s) }
66
+
67
+ [ instance_methods, singleton_methods, constant_decls ]
68
+ end
69
+
70
+ def build_env(path)
71
+ loader = @library_options.loader()
72
+ path&.each do |dir|
73
+ loader.add(path: Pathname(dir))
74
+ end
75
+ Environment.from_loader(loader)
76
+ end
77
+
78
+ def build_builder(env)
79
+ DefinitionBuilder.new(env: env.resolve_type_names)
80
+ end
81
+
82
+ def definition_method_to_s(key, kind, definition_method)
83
+ if definition_method
84
+ prefix = kind == :instance ? "" : "self."
85
+
86
+ if definition_method.alias_of
87
+ "alias #{prefix}#{key} #{prefix}#{definition_method.alias_of.defs.first.member.name}"
88
+ else
89
+ "def #{prefix}#{key}: #{definition_method.method_types.join(" | ")}"
90
+ end
91
+ else
92
+ +"-"
93
+ end
94
+ end
95
+
96
+ def constant_to_s(key, constant)
97
+ if constant
98
+ "#{key}: #{constant.decl.type}"
99
+ else
100
+ +"-"
101
+ end
102
+ end
103
+ end
104
+ end
@@ -441,7 +441,7 @@ module RBS
441
441
 
442
442
  when AST::Declarations::Global
443
443
  if entry = global_decls[decl.name]
444
- raise DuplicatedDeclarationError.new(name, decl, entry.decl)
444
+ raise DuplicatedDeclarationError.new(decl.name, decl, entry.decl)
445
445
  end
446
446
 
447
447
  global_decls[decl.name] = GlobalEntry.new(name: decl.name, decl: decl, outer: outer)
@@ -86,6 +86,9 @@ module RBS
86
86
  type.each_type(&block)
87
87
  self.block&.yield_self do |b|
88
88
  b.type.each_type(&block)
89
+ if b.self_type
90
+ yield b.self_type
91
+ end
89
92
  end
90
93
  else
91
94
  enum_for :each_type
@@ -114,5 +117,25 @@ module RBS
114
117
  def type_param_names
115
118
  type_params.map(&:name)
116
119
  end
120
+
121
+ def has_self_type?
122
+ each_type.any? {|type| type.has_self_type? }
123
+ end
124
+
125
+ def has_classish_type?
126
+ each_type.any? {|type| type.has_classish_type? }
127
+ end
128
+
129
+ def with_nonreturn_void?
130
+ if type.with_nonreturn_void?
131
+ true
132
+ else
133
+ if block = block()
134
+ block.type.with_nonreturn_void? || block.self_type&.with_nonreturn_void? || false
135
+ else
136
+ false
137
+ end
138
+ end
139
+ end
117
140
  end
118
141
  end
@@ -89,8 +89,7 @@ module RBS
89
89
  body = "\n" if body.empty?
90
90
 
91
91
  comment = AST::Comment.new(string: body, location: nil)
92
- if (prev_comment = hash[line - 1])
93
- hash[line - 1] = nil
92
+ if prev_comment = hash.delete(line - 1)
94
93
  hash[line] = AST::Comment.new(string: prev_comment.string + comment.string,
95
94
  location: nil)
96
95
  else
@@ -362,13 +361,7 @@ module RBS
362
361
  end
363
362
 
364
363
  when :ITER
365
- method_name = node.children.first.children.first
366
- case method_name
367
- when :refine
368
- # ignore
369
- else
370
- process_children(node, decls: decls, comments: comments, context: context)
371
- end
364
+ # ignore
372
365
 
373
366
  when :CDECL
374
367
  const_name = case
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ module Prototype
5
+ class Runtime
6
+ module Helpers
7
+ private
8
+
9
+ # Returns the exact name & not compactly declared name
10
+ def only_name(mod)
11
+ # No nil check because this method is invoked after checking if the module exists
12
+ const_name!(mod).split(/::/).last or raise # (A::B::C) => C
13
+ end
14
+
15
+ def const_name!(const)
16
+ const_name(const) or raise
17
+ end
18
+
19
+ def const_name(const)
20
+ @module_name_method ||= Module.instance_method(:name)
21
+ name = @module_name_method.bind(const).call
22
+ return nil unless name
23
+
24
+ begin
25
+ deprecated, Warning[:deprecated] = Warning[:deprecated], false
26
+ Object.const_get(name)
27
+ rescue NameError
28
+ # Should generate const name if anonymous or internal module (e.g. NameError::message)
29
+ nil
30
+ else
31
+ name
32
+ ensure
33
+ Warning[:deprecated] = deprecated
34
+ end
35
+ end
36
+
37
+ def to_type_name(name, full_name: false)
38
+ *prefix, last = name.split(/::/)
39
+
40
+ last or raise
41
+
42
+ if full_name
43
+ if prefix.empty?
44
+ TypeName.new(name: last.to_sym, namespace: Namespace.empty)
45
+ else
46
+ TypeName.new(name: last.to_sym, namespace: Namespace.parse(prefix.join("::")))
47
+ end
48
+ else
49
+ TypeName.new(name: last.to_sym, namespace: Namespace.empty)
50
+ end
51
+ end
52
+
53
+ def untyped
54
+ @untyped ||= Types::Bases::Any.new(location: nil)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,236 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helpers'
4
+
5
+ module RBS
6
+ module Prototype
7
+ class Runtime
8
+ class ValueObjectBase
9
+ include Helpers
10
+
11
+ def initialize(target_class)
12
+ @target_class = target_class
13
+ end
14
+
15
+ def build_decl
16
+ decl = AST::Declarations::Class.new(
17
+ name: to_type_name(only_name(@target_class)),
18
+ type_params: [],
19
+ super_class: build_super_class,
20
+ members: [],
21
+ annotations: [],
22
+ location: nil,
23
+ comment: nil
24
+ )
25
+
26
+ add_decl_members(decl)
27
+
28
+ decl
29
+ end
30
+
31
+ private
32
+
33
+ # def self.members: () -> [ :foo, :bar ]
34
+ # def members: () -> [ :foo, :bar ]
35
+ def build_s_members
36
+ [:singleton, :instance].map do |kind|
37
+ AST::Members::MethodDefinition.new(
38
+ name: :members,
39
+ overloads: [
40
+ AST::Members::MethodDefinition::Overload.new(
41
+ annotations: [],
42
+ method_type: MethodType.new(
43
+ type: Types::Function.empty(
44
+ Types::Tuple.new(
45
+ types: @target_class.members.map do |member|
46
+ if member.to_s.ascii_only?
47
+ Types::Literal.new(literal: member, location: nil)
48
+ else
49
+ BuiltinNames::Symbol.instance_type
50
+ end
51
+ end,
52
+ location: nil
53
+ )
54
+ ),
55
+ type_params: [],
56
+ block: nil,
57
+ location: nil,
58
+ )
59
+ )
60
+ ],
61
+ kind: kind,
62
+ location: nil,
63
+ comment: nil,
64
+ annotations: [],
65
+ overloading: false,
66
+ visibility: nil
67
+ )
68
+ end
69
+ end
70
+
71
+ # attr_accessor foo: untyped
72
+ def build_member_accessors(ast_members_class)
73
+ @target_class.members.map do |member|
74
+ ast_members_class.new(
75
+ name: member,
76
+ ivar_name: nil,
77
+ type: untyped,
78
+ kind: :instance,
79
+ location: nil,
80
+ comment: nil,
81
+ annotations: []
82
+ )
83
+ end
84
+ end
85
+ end
86
+
87
+ class StructGenerator < ValueObjectBase
88
+ CAN_CALL_KEYWORD_INIT_P = Struct.new(:tmp).respond_to?(:keyword_init?)
89
+
90
+ def build_super_class
91
+ AST::Declarations::Class::Super.new(name: TypeName("::Struct"), args: [untyped], location: nil)
92
+ end
93
+
94
+ def add_decl_members(decl)
95
+ decl.members.concat build_s_new
96
+ decl.members.concat build_s_keyword_init_p
97
+ decl.members.concat build_s_members
98
+ decl.members.concat build_member_accessors(AST::Members::AttrAccessor)
99
+ end
100
+
101
+ # def self.new: (?untyped foo, ?untyped bar) -> instance
102
+ # | (?foo: untyped, ?bar: untyped) -> instance
103
+ def build_s_new
104
+ [:new, :[]].map do |name|
105
+ new_overloads = []
106
+
107
+ if CAN_CALL_KEYWORD_INIT_P ? (@target_class.keyword_init? == false || @target_class.keyword_init? == nil) : true
108
+ new_overloads << AST::Members::MethodDefinition::Overload.new(
109
+ annotations: [],
110
+ method_type: MethodType.new(
111
+ type: Types::Function.empty(Types::Bases::Instance.new(location: nil)).update(
112
+ optional_positionals: @target_class.members.map { |m| Types::Function::Param.new(name: m, type: untyped) },
113
+ ),
114
+ type_params: [],
115
+ block: nil,
116
+ location: nil,
117
+ )
118
+ )
119
+ end
120
+ if CAN_CALL_KEYWORD_INIT_P ? (@target_class.keyword_init? == true || @target_class.keyword_init? == nil) : true
121
+ new_overloads << AST::Members::MethodDefinition::Overload.new(
122
+ annotations: [],
123
+ method_type: MethodType.new(
124
+ type: Types::Function.empty(Types::Bases::Instance.new(location: nil)).update(
125
+ optional_keywords: @target_class.members.to_h { |m| [m, Types::Function::Param.new(name: nil, type: untyped)] },
126
+ ),
127
+ type_params: [],
128
+ block: nil,
129
+ location: nil,
130
+ )
131
+ )
132
+ end
133
+
134
+ AST::Members::MethodDefinition.new(
135
+ name: name,
136
+ overloads: new_overloads,
137
+ kind: :singleton,
138
+ location: nil,
139
+ comment: nil,
140
+ annotations: [],
141
+ overloading: false,
142
+ visibility: nil
143
+ )
144
+ end
145
+ end
146
+
147
+ # def self.keyword_init?: () -> bool?
148
+ def build_s_keyword_init_p
149
+ return [] unless CAN_CALL_KEYWORD_INIT_P
150
+
151
+ return_type = @target_class.keyword_init?.nil? \
152
+ ? Types::Bases::Nil.new(location: nil)
153
+ : Types::Literal.new(literal: @target_class.keyword_init?, location: nil)
154
+ type = Types::Function.empty(return_type)
155
+
156
+ [
157
+ AST::Members::MethodDefinition.new(
158
+ name: :keyword_init?,
159
+ overloads: [
160
+ AST::Members::MethodDefinition::Overload.new(
161
+ annotations: [],
162
+ method_type: MethodType.new(
163
+ type: type,
164
+ type_params: [],
165
+ block: nil,
166
+ location: nil,
167
+ )
168
+ )
169
+ ],
170
+ kind: :singleton,
171
+ location: nil,
172
+ comment: nil,
173
+ annotations: [],
174
+ overloading: false,
175
+ visibility: nil
176
+ )
177
+ ]
178
+ end
179
+ end
180
+
181
+ class DataGenerator < ValueObjectBase
182
+ def build_super_class
183
+ AST::Declarations::Class::Super.new(name: TypeName("::Data"), args: [], location: nil)
184
+ end
185
+
186
+ def add_decl_members(decl)
187
+ decl.members.concat build_s_new
188
+ decl.members.concat build_s_members
189
+ decl.members.concat build_member_accessors(AST::Members::AttrReader)
190
+ end
191
+
192
+ # def self.new: (untyped foo, untyped bar) -> instance
193
+ # | (foo: untyped, bar: untyped) -> instance
194
+ def build_s_new
195
+ [:new, :[]].map do |name|
196
+ new_overloads = []
197
+
198
+ new_overloads << AST::Members::MethodDefinition::Overload.new(
199
+ annotations: [],
200
+ method_type: MethodType.new(
201
+ type: Types::Function.empty(Types::Bases::Instance.new(location: nil)).update(
202
+ required_positionals: @target_class.members.map { |m| Types::Function::Param.new(name: m, type: untyped) },
203
+ ),
204
+ type_params: [],
205
+ block: nil,
206
+ location: nil,
207
+ )
208
+ )
209
+ new_overloads << AST::Members::MethodDefinition::Overload.new(
210
+ annotations: [],
211
+ method_type: MethodType.new(
212
+ type: Types::Function.empty(Types::Bases::Instance.new(location: nil)).update(
213
+ required_keywords: @target_class.members.to_h { |m| [m, Types::Function::Param.new(name: nil, type: untyped)] },
214
+ ),
215
+ type_params: [],
216
+ block: nil,
217
+ location: nil,
218
+ )
219
+ )
220
+
221
+ AST::Members::MethodDefinition.new(
222
+ name: name,
223
+ overloads: new_overloads,
224
+ kind: :singleton,
225
+ location: nil,
226
+ comment: nil,
227
+ annotations: [],
228
+ overloading: false,
229
+ visibility: nil
230
+ )
231
+ end
232
+ end
233
+ end
234
+ end
235
+ end
236
+ end