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.
- checksums.yaml +7 -0
- data/.github/workflows/ruby.yml +28 -0
- data/.gitignore +12 -0
- data/.rubocop.yml +15 -0
- data/BSDL +22 -0
- data/CHANGELOG.md +9 -0
- data/COPYING +56 -0
- data/Gemfile +6 -0
- data/README.md +93 -0
- data/Rakefile +142 -0
- data/bin/annotate-with-rdoc +157 -0
- data/bin/console +14 -0
- data/bin/query-rdoc +103 -0
- data/bin/setup +10 -0
- data/bin/sort +89 -0
- data/bin/test_runner.rb +16 -0
- data/docs/CONTRIBUTING.md +97 -0
- data/docs/sigs.md +148 -0
- data/docs/stdlib.md +152 -0
- data/docs/syntax.md +528 -0
- data/exe/rbs +7 -0
- data/lib/rbs.rb +64 -0
- data/lib/rbs/ast/annotation.rb +27 -0
- data/lib/rbs/ast/comment.rb +27 -0
- data/lib/rbs/ast/declarations.rb +395 -0
- data/lib/rbs/ast/members.rb +362 -0
- data/lib/rbs/buffer.rb +50 -0
- data/lib/rbs/builtin_names.rb +55 -0
- data/lib/rbs/cli.rb +558 -0
- data/lib/rbs/constant.rb +26 -0
- data/lib/rbs/constant_table.rb +150 -0
- data/lib/rbs/definition.rb +170 -0
- data/lib/rbs/definition_builder.rb +919 -0
- data/lib/rbs/environment.rb +281 -0
- data/lib/rbs/environment_loader.rb +136 -0
- data/lib/rbs/environment_walker.rb +124 -0
- data/lib/rbs/errors.rb +187 -0
- data/lib/rbs/location.rb +102 -0
- data/lib/rbs/method_type.rb +123 -0
- data/lib/rbs/namespace.rb +91 -0
- data/lib/rbs/parser.y +1344 -0
- data/lib/rbs/prototype/rb.rb +553 -0
- data/lib/rbs/prototype/rbi.rb +587 -0
- data/lib/rbs/prototype/runtime.rb +381 -0
- data/lib/rbs/substitution.rb +46 -0
- data/lib/rbs/test.rb +26 -0
- data/lib/rbs/test/errors.rb +61 -0
- data/lib/rbs/test/hook.rb +294 -0
- data/lib/rbs/test/setup.rb +58 -0
- data/lib/rbs/test/spy.rb +325 -0
- data/lib/rbs/test/test_helper.rb +183 -0
- data/lib/rbs/test/type_check.rb +254 -0
- data/lib/rbs/type_name.rb +70 -0
- data/lib/rbs/types.rb +936 -0
- data/lib/rbs/variance_calculator.rb +138 -0
- data/lib/rbs/vendorer.rb +47 -0
- data/lib/rbs/version.rb +3 -0
- data/lib/rbs/writer.rb +269 -0
- data/lib/ruby/signature.rb +7 -0
- data/rbs.gemspec +46 -0
- data/stdlib/abbrev/abbrev.rbs +60 -0
- data/stdlib/base64/base64.rbs +71 -0
- data/stdlib/benchmark/benchmark.rbs +372 -0
- data/stdlib/builtin/array.rbs +1997 -0
- data/stdlib/builtin/basic_object.rbs +280 -0
- data/stdlib/builtin/binding.rbs +177 -0
- data/stdlib/builtin/builtin.rbs +45 -0
- data/stdlib/builtin/class.rbs +145 -0
- data/stdlib/builtin/comparable.rbs +116 -0
- data/stdlib/builtin/complex.rbs +400 -0
- data/stdlib/builtin/constants.rbs +37 -0
- data/stdlib/builtin/data.rbs +5 -0
- data/stdlib/builtin/deprecated.rbs +2 -0
- data/stdlib/builtin/dir.rbs +413 -0
- data/stdlib/builtin/encoding.rbs +607 -0
- data/stdlib/builtin/enumerable.rbs +404 -0
- data/stdlib/builtin/enumerator.rbs +260 -0
- data/stdlib/builtin/errno.rbs +781 -0
- data/stdlib/builtin/errors.rbs +582 -0
- data/stdlib/builtin/exception.rbs +194 -0
- data/stdlib/builtin/false_class.rbs +40 -0
- data/stdlib/builtin/fiber.rbs +68 -0
- data/stdlib/builtin/fiber_error.rbs +12 -0
- data/stdlib/builtin/file.rbs +1076 -0
- data/stdlib/builtin/file_test.rbs +59 -0
- data/stdlib/builtin/float.rbs +696 -0
- data/stdlib/builtin/gc.rbs +243 -0
- data/stdlib/builtin/hash.rbs +1029 -0
- data/stdlib/builtin/integer.rbs +707 -0
- data/stdlib/builtin/io.rbs +683 -0
- data/stdlib/builtin/kernel.rbs +576 -0
- data/stdlib/builtin/marshal.rbs +161 -0
- data/stdlib/builtin/match_data.rbs +271 -0
- data/stdlib/builtin/math.rbs +369 -0
- data/stdlib/builtin/method.rbs +185 -0
- data/stdlib/builtin/module.rbs +1104 -0
- data/stdlib/builtin/nil_class.rbs +82 -0
- data/stdlib/builtin/numeric.rbs +409 -0
- data/stdlib/builtin/object.rbs +824 -0
- data/stdlib/builtin/proc.rbs +429 -0
- data/stdlib/builtin/process.rbs +1227 -0
- data/stdlib/builtin/random.rbs +267 -0
- data/stdlib/builtin/range.rbs +226 -0
- data/stdlib/builtin/rational.rbs +424 -0
- data/stdlib/builtin/rb_config.rbs +57 -0
- data/stdlib/builtin/regexp.rbs +1083 -0
- data/stdlib/builtin/ruby_vm.rbs +14 -0
- data/stdlib/builtin/signal.rbs +55 -0
- data/stdlib/builtin/string.rbs +1901 -0
- data/stdlib/builtin/string_io.rbs +284 -0
- data/stdlib/builtin/struct.rbs +40 -0
- data/stdlib/builtin/symbol.rbs +228 -0
- data/stdlib/builtin/thread.rbs +1108 -0
- data/stdlib/builtin/thread_group.rbs +23 -0
- data/stdlib/builtin/time.rbs +1047 -0
- data/stdlib/builtin/trace_point.rbs +290 -0
- data/stdlib/builtin/true_class.rbs +46 -0
- data/stdlib/builtin/unbound_method.rbs +153 -0
- data/stdlib/builtin/warning.rbs +17 -0
- data/stdlib/coverage/coverage.rbs +62 -0
- data/stdlib/csv/csv.rbs +773 -0
- data/stdlib/erb/erb.rbs +392 -0
- data/stdlib/find/find.rbs +40 -0
- data/stdlib/ipaddr/ipaddr.rbs +247 -0
- data/stdlib/json/json.rbs +335 -0
- data/stdlib/pathname/pathname.rbs +1093 -0
- data/stdlib/prime/integer-extension.rbs +23 -0
- data/stdlib/prime/prime.rbs +188 -0
- data/stdlib/securerandom/securerandom.rbs +9 -0
- data/stdlib/set/set.rbs +301 -0
- data/stdlib/tmpdir/tmpdir.rbs +53 -0
- metadata +292 -0
data/lib/rbs/errors.rb
ADDED
|
@@ -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
|
data/lib/rbs/location.rb
ADDED
|
@@ -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
|