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
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
module RBS
|
|
2
|
+
class Environment
|
|
3
|
+
attr_reader :buffers
|
|
4
|
+
attr_reader :declarations
|
|
5
|
+
|
|
6
|
+
attr_reader :name_to_decl
|
|
7
|
+
attr_reader :name_to_extensions
|
|
8
|
+
attr_reader :name_to_constant
|
|
9
|
+
attr_reader :name_to_global
|
|
10
|
+
attr_reader :name_to_alias
|
|
11
|
+
|
|
12
|
+
def initialize
|
|
13
|
+
@buffers = []
|
|
14
|
+
@declarations = []
|
|
15
|
+
|
|
16
|
+
@name_to_decl = {}
|
|
17
|
+
@name_to_extensions = {}
|
|
18
|
+
@name_to_constant = {}
|
|
19
|
+
@name_to_global = {}
|
|
20
|
+
@name_to_alias = {}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def initialize_copy(other)
|
|
24
|
+
@buffers = other.buffers.dup
|
|
25
|
+
@declarations = other.declarations.dup
|
|
26
|
+
|
|
27
|
+
@name_to_decl = other.name_to_decl.dup
|
|
28
|
+
@name_to_extensions = other.name_to_extensions.dup
|
|
29
|
+
@name_to_constant = other.name_to_constant.dup
|
|
30
|
+
@name_to_global = other.name_to_global.dup
|
|
31
|
+
@name_to_alias = other.name_to_alias.dup
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def cache_name(cache, name:, decl:)
|
|
35
|
+
if cache.key?(name)
|
|
36
|
+
raise DuplicatedDeclarationError.new(name, decl, cache[name])
|
|
37
|
+
end
|
|
38
|
+
cache[name] = decl
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def <<(decl)
|
|
42
|
+
declarations << decl
|
|
43
|
+
case decl
|
|
44
|
+
when AST::Declarations::Class, AST::Declarations::Module, AST::Declarations::Interface
|
|
45
|
+
cache_name name_to_decl, name: decl.name.absolute!, decl: decl
|
|
46
|
+
when AST::Declarations::Extension
|
|
47
|
+
yield_self do
|
|
48
|
+
name = decl.name.absolute!
|
|
49
|
+
exts = name_to_extensions.fetch(name) do
|
|
50
|
+
name_to_extensions[name] = []
|
|
51
|
+
end
|
|
52
|
+
exts << decl
|
|
53
|
+
end
|
|
54
|
+
when AST::Declarations::Alias
|
|
55
|
+
cache_name name_to_alias, name: decl.name.absolute!, decl: decl
|
|
56
|
+
when AST::Declarations::Constant
|
|
57
|
+
cache_name name_to_constant, name: decl.name.absolute!, decl: decl
|
|
58
|
+
when AST::Declarations::Global
|
|
59
|
+
cache_name name_to_global, name: decl.name, decl: decl
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def find_class(type_name)
|
|
64
|
+
name_to_decl[type_name]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def each_decl
|
|
68
|
+
if block_given?
|
|
69
|
+
name_to_decl.each do |name, decl|
|
|
70
|
+
yield name, decl
|
|
71
|
+
end
|
|
72
|
+
else
|
|
73
|
+
enum_for :each_decl
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def each_constant
|
|
78
|
+
if block_given?
|
|
79
|
+
name_to_constant.each do |name, decl|
|
|
80
|
+
yield name, decl
|
|
81
|
+
end
|
|
82
|
+
else
|
|
83
|
+
enum_for :each_constant
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def each_global
|
|
88
|
+
if block_given?
|
|
89
|
+
name_to_global.each do |name, global|
|
|
90
|
+
yield name, global
|
|
91
|
+
end
|
|
92
|
+
else
|
|
93
|
+
enum_for :each_global
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def each_alias(&block)
|
|
98
|
+
if block_given?
|
|
99
|
+
name_to_alias.each(&block)
|
|
100
|
+
else
|
|
101
|
+
enum_for :each_alias
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def each_class_name(&block)
|
|
106
|
+
each_decl.select {|name,| class?(name) }.each(&block)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def class?(type_name)
|
|
110
|
+
find_class(type_name)&.yield_self do |decl|
|
|
111
|
+
decl.is_a?(AST::Declarations::Class) || decl.is_a?(AST::Declarations::Module)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def find_type_decl(type_name)
|
|
116
|
+
name_to_decl[type_name]
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def find_extensions(type_name)
|
|
120
|
+
name_to_extensions[type_name] || []
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def find_alias(type_name)
|
|
124
|
+
name_to_alias[type_name]
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def each_extension(type_name, &block)
|
|
128
|
+
if block_given?
|
|
129
|
+
(name_to_extensions[type_name] || []).each(&block)
|
|
130
|
+
else
|
|
131
|
+
enum_for :each_extension, type_name
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def absolute_type_name_in(environment, name:, namespace:)
|
|
136
|
+
raise "Namespace should be absolute: #{namespace}" unless namespace.absolute?
|
|
137
|
+
|
|
138
|
+
if name.absolute?
|
|
139
|
+
name if environment.key?(name)
|
|
140
|
+
else
|
|
141
|
+
absolute_name = name.with_prefix(namespace)
|
|
142
|
+
|
|
143
|
+
if environment.key?(absolute_name)
|
|
144
|
+
absolute_name
|
|
145
|
+
else
|
|
146
|
+
if namespace.empty?
|
|
147
|
+
nil
|
|
148
|
+
else
|
|
149
|
+
parent = namespace.parent
|
|
150
|
+
absolute_type_name_in environment, name: name, namespace: parent
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def absolute_class_name(name, namespace:)
|
|
157
|
+
raise "Class name expected: #{name}" unless name.class?
|
|
158
|
+
absolute_type_name_in name_to_decl, name: name, namespace: namespace
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def absolute_interface_name(name, namespace:)
|
|
162
|
+
raise "Interface name expected: #{name}" unless name.interface?
|
|
163
|
+
absolute_type_name_in name_to_decl, name: name, namespace: namespace
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def absolute_alias_name(name, namespace:)
|
|
167
|
+
raise "Alias name expected: #{name}" unless name.alias?
|
|
168
|
+
absolute_type_name_in name_to_alias, name: name, namespace: namespace
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def absolute_type_name(type_name, namespace:)
|
|
172
|
+
absolute_name = case
|
|
173
|
+
when type_name.class?
|
|
174
|
+
absolute_class_name(type_name, namespace: namespace)
|
|
175
|
+
when type_name.alias?
|
|
176
|
+
absolute_alias_name(type_name, namespace: namespace)
|
|
177
|
+
when type_name.interface?
|
|
178
|
+
absolute_interface_name(type_name, namespace: namespace)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
absolute_name || yield(type_name)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def absolute_name_or(name, type)
|
|
185
|
+
if name.absolute?
|
|
186
|
+
type
|
|
187
|
+
else
|
|
188
|
+
yield
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def absolute_type(type, namespace:, &block)
|
|
193
|
+
case type
|
|
194
|
+
when Types::ClassSingleton
|
|
195
|
+
absolute_name_or(type.name, type) do
|
|
196
|
+
absolute_name = absolute_type_name(type.name, namespace: namespace) { yield(type) }
|
|
197
|
+
Types::ClassSingleton.new(name: absolute_name, location: type.location)
|
|
198
|
+
end
|
|
199
|
+
when Types::ClassInstance
|
|
200
|
+
absolute_name = absolute_type_name(type.name, namespace: namespace) { yield(type) }
|
|
201
|
+
Types::ClassInstance.new(name: absolute_name,
|
|
202
|
+
args: type.args.map {|ty|
|
|
203
|
+
absolute_type(ty, namespace: namespace, &block)
|
|
204
|
+
},
|
|
205
|
+
location: type.location)
|
|
206
|
+
when Types::Interface
|
|
207
|
+
absolute_name = absolute_type_name(type.name, namespace: namespace) { yield(type) }
|
|
208
|
+
Types::Interface.new(name: absolute_name,
|
|
209
|
+
args: type.args.map {|ty|
|
|
210
|
+
absolute_type(ty, namespace: namespace, &block)
|
|
211
|
+
},
|
|
212
|
+
location: type.location)
|
|
213
|
+
when Types::Alias
|
|
214
|
+
absolute_name_or(type.name, type) do
|
|
215
|
+
absolute_name = absolute_type_name(type.name, namespace: namespace) { yield(type) }
|
|
216
|
+
Types::Alias.new(name: absolute_name, location: type.location)
|
|
217
|
+
end
|
|
218
|
+
when Types::Tuple
|
|
219
|
+
Types::Tuple.new(
|
|
220
|
+
types: type.types.map {|ty| absolute_type(ty, namespace: namespace, &block) },
|
|
221
|
+
location: type.location
|
|
222
|
+
)
|
|
223
|
+
when Types::Record
|
|
224
|
+
Types::Record.new(
|
|
225
|
+
fields: type.fields.transform_values {|ty| absolute_type(ty, namespace: namespace, &block) },
|
|
226
|
+
location: type.location
|
|
227
|
+
)
|
|
228
|
+
when Types::Union
|
|
229
|
+
Types::Union.new(
|
|
230
|
+
types: type.types.map {|ty| absolute_type(ty, namespace: namespace, &block) },
|
|
231
|
+
location: type.location
|
|
232
|
+
)
|
|
233
|
+
when Types::Intersection
|
|
234
|
+
Types::Intersection.new(
|
|
235
|
+
types: type.types.map {|ty| absolute_type(ty, namespace: namespace, &block) },
|
|
236
|
+
location: type.location
|
|
237
|
+
)
|
|
238
|
+
when Types::Optional
|
|
239
|
+
Types::Optional.new(
|
|
240
|
+
type: absolute_type(type.type, namespace: namespace, &block),
|
|
241
|
+
location: type.location
|
|
242
|
+
)
|
|
243
|
+
when Types::Proc
|
|
244
|
+
Types::Proc.new(
|
|
245
|
+
type: type.type.map_type {|ty| absolute_type(ty, namespace: namespace, &block) },
|
|
246
|
+
location: type.location
|
|
247
|
+
)
|
|
248
|
+
else
|
|
249
|
+
type
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
# Validates presence of the relative type, and application arity match.
|
|
254
|
+
def validate(type, namespace:)
|
|
255
|
+
case type
|
|
256
|
+
when Types::ClassInstance, Types::Interface
|
|
257
|
+
if type.name.namespace.relative?
|
|
258
|
+
type = absolute_type(type, namespace: namespace) do |type|
|
|
259
|
+
NoTypeFoundError.check!(type.name.absolute!, env: self, location: type.location)
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
decl = find_class(type.name)
|
|
264
|
+
unless decl
|
|
265
|
+
raise NoTypeFoundError.new(type_name: type.name, location: type.location)
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
InvalidTypeApplicationError.check!(
|
|
269
|
+
type_name: type.name,
|
|
270
|
+
args: type.args,
|
|
271
|
+
params: decl.type_params,
|
|
272
|
+
location: type.location
|
|
273
|
+
)
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
type.each_type do |type_|
|
|
277
|
+
validate(type_, namespace: namespace)
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
module RBS
|
|
2
|
+
class EnvironmentLoader
|
|
3
|
+
class UnknownLibraryNameError < StandardError
|
|
4
|
+
attr_reader :name
|
|
5
|
+
|
|
6
|
+
def initialize(name:)
|
|
7
|
+
@name = name
|
|
8
|
+
super "Cannot find a library or gem: `#{name}`"
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
LibraryPath = Struct.new(:name, :path, keyword_init: true)
|
|
13
|
+
GemPath = Struct.new(:name, :version, :path, keyword_init: true)
|
|
14
|
+
|
|
15
|
+
attr_reader :paths
|
|
16
|
+
attr_reader :stdlib_root
|
|
17
|
+
attr_reader :gem_vendor_path
|
|
18
|
+
|
|
19
|
+
STDLIB_ROOT = Pathname(__dir__) + "../../stdlib"
|
|
20
|
+
|
|
21
|
+
def self.gem_sig_path(name, version)
|
|
22
|
+
Pathname(Gem::Specification.find_by_name(name, version).gem_dir) + "sig"
|
|
23
|
+
rescue Gem::MissingSpecError
|
|
24
|
+
nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def initialize(stdlib_root: STDLIB_ROOT, gem_vendor_path: nil)
|
|
28
|
+
@stdlib_root = stdlib_root
|
|
29
|
+
@gem_vendor_path = gem_vendor_path
|
|
30
|
+
@paths = []
|
|
31
|
+
@no_builtin = false
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def add(path: nil, library: nil)
|
|
35
|
+
case
|
|
36
|
+
when path
|
|
37
|
+
@paths << path
|
|
38
|
+
when library
|
|
39
|
+
name, version = self.class.parse_library(library)
|
|
40
|
+
|
|
41
|
+
case
|
|
42
|
+
when !version && path = stdlib?(name)
|
|
43
|
+
@paths << LibraryPath.new(name: name, path: path)
|
|
44
|
+
when (path = gem?(name, version))
|
|
45
|
+
@paths << GemPath.new(name: name, version: version, path: path)
|
|
46
|
+
else
|
|
47
|
+
raise UnknownLibraryNameError.new(name: library)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def self.parse_library(lib)
|
|
53
|
+
lib.split(/:/)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def stdlib?(name)
|
|
57
|
+
if stdlib_root
|
|
58
|
+
path = stdlib_root + name
|
|
59
|
+
if path.directory?
|
|
60
|
+
path
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def gem?(name, version)
|
|
66
|
+
if gem_vendor_path
|
|
67
|
+
# Try vendored RBS first
|
|
68
|
+
gem_dir = gem_vendor_path + name
|
|
69
|
+
if gem_dir.directory?
|
|
70
|
+
return gem_dir
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Try ruby gem library
|
|
75
|
+
self.class.gem_sig_path(name, version)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def each_signature(path = nil, immediate: true, &block)
|
|
79
|
+
if block_given?
|
|
80
|
+
if path
|
|
81
|
+
case
|
|
82
|
+
when path.file?
|
|
83
|
+
if path.extname == ".rbs" || immediate
|
|
84
|
+
yield path
|
|
85
|
+
end
|
|
86
|
+
when path.directory?
|
|
87
|
+
path.children.each do |child|
|
|
88
|
+
each_signature child, immediate: false, &block
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
else
|
|
92
|
+
paths.each do |path|
|
|
93
|
+
case path
|
|
94
|
+
when Pathname
|
|
95
|
+
each_signature path, immediate: immediate, &block
|
|
96
|
+
when LibraryPath
|
|
97
|
+
each_signature path.path, immediate: immediate, &block
|
|
98
|
+
when GemPath
|
|
99
|
+
each_signature path.path, immediate: immediate, &block
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
else
|
|
104
|
+
enum_for :each_signature, path, immediate: immediate
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def no_builtin!
|
|
109
|
+
@no_builtin = true
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def no_builtin?
|
|
113
|
+
@no_builtin
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def load(env:)
|
|
117
|
+
signature_files = []
|
|
118
|
+
|
|
119
|
+
unless no_builtin?
|
|
120
|
+
signature_files.push(*each_signature(stdlib_root + "builtin"))
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
each_signature do |path|
|
|
124
|
+
signature_files.push path
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
signature_files.each do |file|
|
|
128
|
+
buffer = Buffer.new(name: file.to_s, content: file.read)
|
|
129
|
+
env.buffers.push(buffer)
|
|
130
|
+
Parser.parse_signature(buffer).each do |decl|
|
|
131
|
+
env << decl
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
module RBS
|
|
2
|
+
class EnvironmentWalker
|
|
3
|
+
attr_reader :env
|
|
4
|
+
|
|
5
|
+
def initialize(env:)
|
|
6
|
+
@env = env
|
|
7
|
+
@only_ancestors = nil
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def builder
|
|
11
|
+
@builder ||= DefinitionBuilder.new(env: env)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def only_ancestors!(only = true)
|
|
15
|
+
@only_ancestors = only
|
|
16
|
+
self
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def only_ancestors?
|
|
20
|
+
@only_ancestors
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
include TSort
|
|
24
|
+
|
|
25
|
+
def tsort_each_node(&block)
|
|
26
|
+
env.each_decl do |name|
|
|
27
|
+
yield name.absolute!
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
env.each_alias do |name, _|
|
|
31
|
+
yield name.absolute!
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def tsort_each_child(name, &block)
|
|
36
|
+
unless name.namespace.empty?
|
|
37
|
+
yield name.namespace.to_type_name
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
case
|
|
41
|
+
when name.class?, name.interface?
|
|
42
|
+
definitions = []
|
|
43
|
+
|
|
44
|
+
case
|
|
45
|
+
when name.class?
|
|
46
|
+
definitions << builder.build_instance(name)
|
|
47
|
+
definitions << builder.build_singleton(name)
|
|
48
|
+
when name.interface?
|
|
49
|
+
definitions << builder.build_interface(name, env.find_class(name))
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
definitions.each do |definition|
|
|
53
|
+
definition.ancestors.each do |ancestor|
|
|
54
|
+
yield ancestor.name
|
|
55
|
+
|
|
56
|
+
case ancestor
|
|
57
|
+
when Definition::Ancestor::Instance, Definition::Ancestor::ExtensionInstance
|
|
58
|
+
ancestor.args.each do |type|
|
|
59
|
+
each_type_name type, &block
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
unless only_ancestors?
|
|
65
|
+
definition.methods.each do |_, method|
|
|
66
|
+
method.method_types.each do |method_type|
|
|
67
|
+
method_type.type.each_type do |type|
|
|
68
|
+
each_type_name type, &block
|
|
69
|
+
end
|
|
70
|
+
method_type.block&.type&.each_type do |type|
|
|
71
|
+
each_type_name type, &block
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
when name.alias?
|
|
78
|
+
each_type_name builder.expand_alias(name), &block
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def each_type_name(type, &block)
|
|
83
|
+
case type
|
|
84
|
+
when RBS::Types::Bases::Any
|
|
85
|
+
when RBS::Types::Bases::Class
|
|
86
|
+
when RBS::Types::Bases::Instance
|
|
87
|
+
when RBS::Types::Bases::Self
|
|
88
|
+
when RBS::Types::Bases::Top
|
|
89
|
+
when RBS::Types::Bases::Bottom
|
|
90
|
+
when RBS::Types::Bases::Bool
|
|
91
|
+
when RBS::Types::Bases::Void
|
|
92
|
+
when RBS::Types::Bases::Nil
|
|
93
|
+
when RBS::Types::Variable
|
|
94
|
+
when RBS::Types::ClassSingleton
|
|
95
|
+
yield type.name
|
|
96
|
+
when RBS::Types::ClassInstance, RBS::Types::Interface
|
|
97
|
+
yield type.name
|
|
98
|
+
type.args.each do |ty|
|
|
99
|
+
each_type_name(ty, &block)
|
|
100
|
+
end
|
|
101
|
+
when RBS::Types::Alias
|
|
102
|
+
yield type.name
|
|
103
|
+
when RBS::Types::Union, RBS::Types::Intersection, RBS::Types::Tuple
|
|
104
|
+
type.types.each do |ty|
|
|
105
|
+
each_type_name ty, &block
|
|
106
|
+
end
|
|
107
|
+
when RBS::Types::Optional
|
|
108
|
+
each_type_name type.type, &block
|
|
109
|
+
when RBS::Types::Literal
|
|
110
|
+
# nop
|
|
111
|
+
when RBS::Types::Record
|
|
112
|
+
type.fields.each_value do |ty|
|
|
113
|
+
each_type_name ty, &block
|
|
114
|
+
end
|
|
115
|
+
when RBS::Types::Proc
|
|
116
|
+
type.each_type do |ty|
|
|
117
|
+
each_type_name ty, &block
|
|
118
|
+
end
|
|
119
|
+
else
|
|
120
|
+
raise "Unexpected type given: #{type}"
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|