rbs 3.2.2 → 3.3.0.pre.1

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