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,187 @@
1
+ module RBS
2
+ class InvalidTypeApplicationError < StandardError
3
+ attr_reader :type_name
4
+ attr_reader :args
5
+ attr_reader :params
6
+ attr_reader :location
7
+
8
+ def initialize(type_name:, args:, params:, location:)
9
+ @type_name = type_name
10
+ @args = args
11
+ @params = params
12
+ @location = location
13
+ super "#{Location.to_string location}: #{type_name} expects parameters [#{params.each.map(&:name).join(", ")}], but given args [#{args.join(", ")}]"
14
+ end
15
+
16
+ def self.check!(type_name:, args:, params:, location:)
17
+ unless args.size == params.size
18
+ raise new(type_name: type_name, args: args, params: params, location: location)
19
+ end
20
+ end
21
+ end
22
+
23
+ class InvalidExtensionParameterError < StandardError
24
+ attr_reader :type_name
25
+ attr_reader :extension_name
26
+ attr_reader :location
27
+ attr_reader :extension_params
28
+ attr_reader :class_params
29
+
30
+ def initialize(type_name:, extension_name:, extension_params:, class_params:, location:)
31
+ @type_name = type_name
32
+ @extension_name = extension_name
33
+ @extension_params = extension_params
34
+ @class_params = class_params
35
+ @location = location
36
+
37
+ super "#{Location.to_string location}: Expected #{class_params.size} parameters to #{type_name} (#{extension_name}) but has #{extension_params.size} parameters"
38
+ end
39
+
40
+ def self.check!(type_name:, extension_name:, extension_params:, class_params:, location:)
41
+ unless extension_params.size == class_params.size
42
+ raise new(type_name: type_name,
43
+ extension_name: extension_name,
44
+ extension_params: extension_params,
45
+ class_params: class_params,
46
+ location: location)
47
+ end
48
+ end
49
+ end
50
+
51
+ class RecursiveAncestorError < StandardError
52
+ attr_reader :ancestors
53
+ attr_reader :location
54
+
55
+ def initialize(ancestors:, location:)
56
+ last = case last = ancestors.last
57
+ when Definition::Ancestor::Singleton
58
+ "singleton(#{last.name})"
59
+ when Definition::Ancestor::Instance
60
+ if last.args.empty?
61
+ last.name.to_s
62
+ else
63
+ "#{last.name}[#{last.args.join(", ")}]"
64
+ end
65
+ end
66
+
67
+ super "#{Location.to_string location}: Detected recursive ancestors: #{last}"
68
+ end
69
+
70
+ def self.check!(self_ancestor, ancestors:, location:)
71
+ case self_ancestor
72
+ when Definition::Ancestor::Instance
73
+ if ancestors.any? {|a| a.is_a?(Definition::Ancestor::Instance) && a.name == self_ancestor.name }
74
+ raise new(ancestors: ancestors + [self_ancestor], location: location)
75
+ end
76
+ when Definition::Ancestor::Singleton
77
+ if ancestors.include?(self_ancestor)
78
+ raise new(ancestors: ancestors + [self_ancestor], location: location)
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ class NoTypeFoundError < StandardError
85
+ attr_reader :type_name
86
+ attr_reader :location
87
+
88
+ def initialize(type_name:, location:)
89
+ @type_name = type_name
90
+ @location = location
91
+
92
+ super "#{Location.to_string location}: Could not find #{type_name}"
93
+ end
94
+
95
+ def self.check!(type_name, env:, location:)
96
+ env.find_type_decl(type_name) or
97
+ raise new(type_name: type_name, location: location)
98
+
99
+ type_name
100
+ end
101
+ end
102
+
103
+ class DuplicatedMethodDefinitionError < StandardError
104
+ attr_reader :decl
105
+ attr_reader :location
106
+
107
+ def initialize(decl:, name:, location:)
108
+ decl_str = case decl
109
+ when AST::Declarations::Interface, AST::Declarations::Class, AST::Declarations::Module
110
+ decl.name.to_s
111
+ when AST::Declarations::Extension
112
+ "#{decl.name} (#{decl.extension_name})"
113
+ end
114
+
115
+ super "#{Location.to_string location}: #{decl_str} has duplicated method definition: #{name}"
116
+ end
117
+
118
+ def self.check!(decl:, methods:, name:, location:)
119
+ if methods.key?(name)
120
+ raise new(decl: decl, name: name, location: location)
121
+ end
122
+ end
123
+ end
124
+
125
+ class UnknownMethodAliasError < StandardError
126
+ attr_reader :original_name
127
+ attr_reader :aliased_name
128
+ attr_reader :location
129
+
130
+ def initialize(original_name:, aliased_name:, location:)
131
+ @original_name = original_name
132
+ @aliased_name = aliased_name
133
+ @location = location
134
+
135
+ super "#{Location.to_string location}: Unknown method alias name: #{original_name} => #{aliased_name}"
136
+ end
137
+
138
+ def self.check!(methods:, original_name:, aliased_name:, location:)
139
+ unless methods.key?(original_name)
140
+ raise new(original_name: original_name, aliased_name: aliased_name, location: location)
141
+ end
142
+ end
143
+ end
144
+
145
+ class DuplicatedDeclarationError < StandardError
146
+ attr_reader :name
147
+ attr_reader :decls
148
+
149
+ def initialize(name, *decls)
150
+ @name = name
151
+ @decls = decls
152
+
153
+ super "#{Location.to_string decls.last.location}: Duplicated declaration: #{name}"
154
+ end
155
+ end
156
+
157
+ class InvalidVarianceAnnotationError < StandardError
158
+ MethodTypeError = Struct.new(:method_name, :method_type, :param, keyword_init: true)
159
+ InheritanceError = Struct.new(:super_class, :param, keyword_init: true)
160
+ MixinError = Struct.new(:include_member, :param, keyword_init: true)
161
+
162
+ attr_reader :decl
163
+ attr_reader :errors
164
+
165
+ def initialize(decl:, errors:)
166
+ @decl = decl
167
+ @errors = errors
168
+
169
+ message = [
170
+ "#{Location.to_string decl.location}: Invalid variance annotation: #{decl.name}"
171
+ ]
172
+
173
+ errors.each do |error|
174
+ case error
175
+ when MethodTypeError
176
+ message << " MethodTypeError (#{error.param.name}): on `#{error.method_name}` #{error.method_type.to_s} (#{error.method_type.location&.start_line})"
177
+ when InheritanceError
178
+ message << " InheritanceError: #{error.super_class}"
179
+ when MixinError
180
+ message << " MixinError: #{error.include_member.name} (#{error.include_member.location&.start_line})"
181
+ end
182
+ end
183
+
184
+ super message.join("\n")
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,102 @@
1
+ module RBS
2
+ class Location
3
+ attr_reader :buffer
4
+ attr_reader :start_pos
5
+ attr_reader :end_pos
6
+
7
+ def initialize(buffer:, start_pos:, end_pos:)
8
+ @buffer = buffer
9
+ @start_pos = start_pos
10
+ @end_pos = end_pos
11
+ end
12
+
13
+ def inspect
14
+ "#<#{self.class}:#{self.__id__} @buffer=#{buffer.name}, @pos=#{start_pos}...#{end_pos}, source='#{source.lines.first}', start_line=#{start_line}, start_column=#{start_column}>"
15
+ end
16
+
17
+ def name
18
+ buffer.name
19
+ end
20
+
21
+ def start_line
22
+ start_loc[0]
23
+ end
24
+
25
+ def start_column
26
+ start_loc[1]
27
+ end
28
+
29
+ def end_line
30
+ end_loc[0]
31
+ end
32
+
33
+ def end_column
34
+ end_loc[1]
35
+ end
36
+
37
+ def start_loc
38
+ @start_loc ||= buffer.pos_to_loc(start_pos)
39
+ end
40
+
41
+ def end_loc
42
+ @end_loc ||= buffer.pos_to_loc(end_pos)
43
+ end
44
+
45
+ def source
46
+ @source ||= buffer.content[start_pos...end_pos]
47
+ end
48
+
49
+ def to_s
50
+ "#{name || "-"}:#{start_line}:#{start_column}...#{end_line}:#{end_column}"
51
+ end
52
+
53
+ def self.to_string(location, default: "*:*:*...*:*")
54
+ location&.to_s || default
55
+ end
56
+
57
+ def ==(other)
58
+ other.is_a?(Location) &&
59
+ other.buffer == buffer &&
60
+ other.start_pos == start_pos &&
61
+ other.end_pos == end_pos
62
+ end
63
+
64
+ def +(other)
65
+ if other
66
+ raise "Invalid concat: buffer=#{buffer.name}, other.buffer=#{other.buffer.name}" unless other.buffer == buffer
67
+
68
+ self.class.new(buffer: buffer,
69
+ start_pos: start_pos,
70
+ end_pos: other.end_pos)
71
+ else
72
+ self
73
+ end
74
+ end
75
+
76
+ def self.concat(*locations)
77
+ locations.inject {|l1, l2| l1 + l2 }
78
+ end
79
+
80
+ def pred?(loc)
81
+ loc.is_a?(Location) &&
82
+ loc.name == name &&
83
+ loc.start_pos == end_pos
84
+ end
85
+
86
+ def to_json(*args)
87
+ {
88
+ start: {
89
+ line: start_line,
90
+ column: start_column
91
+ },
92
+ end: {
93
+ line: end_line,
94
+ column: end_column
95
+ },
96
+ buffer: {
97
+ name: name&.to_s
98
+ }
99
+ }.to_json(*args)
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,123 @@
1
+ module RBS
2
+ class MethodType
3
+ class Block
4
+ attr_reader :type
5
+ attr_reader :required
6
+
7
+ def initialize(type:, required:)
8
+ @type = type
9
+ @required = required
10
+ end
11
+
12
+ def ==(other)
13
+ other.is_a?(Block) &&
14
+ other.type == type &&
15
+ other.required == required
16
+ end
17
+
18
+ def to_json(*a)
19
+ {
20
+ type: type,
21
+ required: required
22
+ }.to_json(*a)
23
+ end
24
+
25
+ def sub(s)
26
+ self.class.new(
27
+ type: type.sub(s),
28
+ required: required
29
+ )
30
+ end
31
+ end
32
+
33
+ attr_reader :type_params
34
+ attr_reader :type
35
+ attr_reader :block
36
+ attr_reader :location
37
+
38
+ def initialize(type_params:, type:, block:, location:)
39
+ @type_params = type_params
40
+ @type = type
41
+ @block = block
42
+ @location = location
43
+ end
44
+
45
+ def ==(other)
46
+ other.is_a?(MethodType) &&
47
+ other.type_params == type_params &&
48
+ other.type == type &&
49
+ other.block == block
50
+ end
51
+
52
+ def to_json(*a)
53
+ {
54
+ type_params: type_params,
55
+ type: type,
56
+ block: block,
57
+ location: location
58
+ }.to_json(*a)
59
+ end
60
+
61
+ def sub(s)
62
+ s.without(*type_params).yield_self do |sub|
63
+ map_type do |ty|
64
+ ty.sub(sub)
65
+ end
66
+ end
67
+ end
68
+
69
+ def update(type_params: self.type_params, type: self.type, block: self.block, location: self.location)
70
+ self.class.new(
71
+ type_params: type_params,
72
+ type: type,
73
+ block: block,
74
+ location: location
75
+ )
76
+ end
77
+
78
+ def free_variables(set = Set.new)
79
+ type.free_variables(set)
80
+ block&.type&.free_variables(set)
81
+ set.subtract(type_params)
82
+ end
83
+
84
+ def map_type(&block)
85
+ self.class.new(
86
+ type_params: type_params,
87
+ type: type.map_type(&block),
88
+ block: self.block&.yield_self do |b|
89
+ Block.new(type: b.type.map_type(&block), required: b.required)
90
+ end,
91
+ location: location
92
+ )
93
+ end
94
+
95
+ def each_type(&block)
96
+ if block_given?
97
+ type.each_type(&block)
98
+ self.block&.yield_self do |b|
99
+ b.type.each_type(&block)
100
+ end
101
+ else
102
+ enum_for :each_type
103
+ end
104
+ end
105
+
106
+ def to_s
107
+ s = case
108
+ when block && block.required
109
+ "(#{type.param_to_s}) { (#{block.type.param_to_s}) -> #{block.type.return_to_s} } -> #{type.return_to_s}"
110
+ when block
111
+ "(#{type.param_to_s}) ?{ (#{block.type.param_to_s}) -> #{block.type.return_to_s} } -> #{type.return_to_s}"
112
+ else
113
+ "(#{type.param_to_s}) -> #{type.return_to_s}"
114
+ end
115
+
116
+ if type_params.empty?
117
+ s
118
+ else
119
+ "[#{type_params.join(", ")}] #{s}"
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,91 @@
1
+ module RBS
2
+ class Namespace
3
+ attr_reader :path
4
+
5
+ def initialize(path:, absolute:)
6
+ @path = path
7
+ @absolute = absolute
8
+ end
9
+
10
+ def self.empty
11
+ new(path: [], absolute: false)
12
+ end
13
+
14
+ def self.root
15
+ new(path: [], absolute: true)
16
+ end
17
+
18
+ def +(other)
19
+ if other.absolute?
20
+ other
21
+ else
22
+ self.class.new(path: path + other.path, absolute: absolute?)
23
+ end
24
+ end
25
+
26
+ def append(component)
27
+ self.class.new(path: path + [component], absolute: absolute?)
28
+ end
29
+
30
+ def parent
31
+ raise "Parent with empty namespace" if empty?
32
+ self.class.new(path: path.take(path.size - 1), absolute: absolute?)
33
+ end
34
+
35
+ def absolute?
36
+ @absolute
37
+ end
38
+
39
+ def relative?
40
+ !absolute?
41
+ end
42
+
43
+ def absolute!
44
+ self.class.new(path: path, absolute: true)
45
+ end
46
+
47
+ def relative!
48
+ self.class.new(path: path, absolute: false)
49
+ end
50
+
51
+ def empty?
52
+ path.empty?
53
+ end
54
+
55
+ def ==(other)
56
+ other.is_a?(Namespace) && other.path == path && other.absolute? == absolute?
57
+ end
58
+
59
+ alias eql? ==
60
+
61
+ def hash
62
+ self.class.hash ^ path.hash ^ absolute?.hash
63
+ end
64
+
65
+ def split
66
+ [parent, path.last]
67
+ end
68
+
69
+ def to_s
70
+ if empty?
71
+ absolute? ? "::" : ""
72
+ else
73
+ s = path.join("::")
74
+ absolute? ? "::#{s}::" : "#{s}::"
75
+ end
76
+ end
77
+
78
+ def to_type_name
79
+ parent, name = split
80
+ TypeName.new(name: name, namespace: parent)
81
+ end
82
+
83
+ def self.parse(string)
84
+ if string.start_with?("::")
85
+ new(path: string.split("::").drop(1).map(&:to_sym), absolute: true)
86
+ else
87
+ new(path: string.split("::").map(&:to_sym), absolute: false)
88
+ end
89
+ end
90
+ end
91
+ end