rbs 0.2.0

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