rbs 3.0.4 → 3.1.1
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 +4 -4
- data/CHANGELOG.md +56 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +23 -21
- data/Steepfile +1 -1
- data/core/file.rbs +104 -0
- data/core/gc.rbs +0 -7
- data/core/io/buffer.rbs +1 -3
- data/core/module.rbs +4 -4
- data/core/object.rbs +2 -2
- data/core/process.rbs +3 -0
- data/core/rubygems/rubygems.rbs +0 -9
- data/core/string.rbs +4 -2
- data/ext/rbs_extension/parser.c +15 -11
- data/lib/rbs/cli.rb +107 -13
- data/lib/rbs/collection/config/lockfile_generator.rb +38 -32
- data/lib/rbs/definition_builder.rb +6 -9
- data/lib/rbs/environment.rb +2 -2
- data/lib/rbs/environment_loader.rb +3 -23
- data/lib/rbs/errors.rb +59 -2
- data/lib/rbs/file_finder.rb +31 -0
- data/lib/rbs/parser_aux.rb +4 -4
- data/lib/rbs/prototype/rb.rb +2 -1
- data/lib/rbs/subtractor.rb +184 -0
- data/lib/rbs/vendorer.rb +3 -3
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +12 -0
- data/lib/rbs.rb +2 -0
- data/lib/rdoc/discover.rb +1 -1
- data/sig/cli.rbs +2 -0
- data/sig/collection/config/lockfile_generator.rbs +3 -1
- data/sig/environment_loader.rbs +17 -15
- data/sig/file_finder.rbs +6 -0
- data/sig/manifest.yaml +1 -0
- data/sig/parser.rbs +26 -8
- data/sig/repository.rbs +7 -5
- data/sig/shims/bundler.rbs +2 -0
- data/sig/shims/rubygems.rbs +4 -0
- data/sig/subtractor.rbs +33 -0
- data/sig/types.rbs +10 -6
- metadata +7 -3
data/lib/rbs/cli.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
require "open3"
|
4
4
|
require "optparse"
|
5
5
|
require "shellwords"
|
6
|
+
require "abbrev"
|
7
|
+
require "stringio"
|
6
8
|
|
7
9
|
module RBS
|
8
10
|
class CLI
|
@@ -88,7 +90,7 @@ module RBS
|
|
88
90
|
@stderr = stderr
|
89
91
|
end
|
90
92
|
|
91
|
-
COMMANDS = [:ast, :annotate, :list, :ancestors, :methods, :method, :validate, :constant, :paths, :prototype, :vendor, :parse, :test, :collection]
|
93
|
+
COMMANDS = [:ast, :annotate, :list, :ancestors, :methods, :method, :validate, :constant, :paths, :prototype, :vendor, :parse, :test, :collection, :subtract]
|
92
94
|
|
93
95
|
def parse_logging_options(opts)
|
94
96
|
opts.on("--log-level LEVEL", "Specify log level (defaults to `warn`)") do |level|
|
@@ -450,7 +452,6 @@ Examples:
|
|
450
452
|
EOU
|
451
453
|
|
452
454
|
opts.on("--silent") do
|
453
|
-
require "stringio"
|
454
455
|
@stdout = StringIO.new
|
455
456
|
end
|
456
457
|
end.parse!(args)
|
@@ -920,6 +921,10 @@ Options:
|
|
920
921
|
end
|
921
922
|
|
922
923
|
def run_parse(args, options)
|
924
|
+
parse_method = :parse_signature
|
925
|
+
# @type var e_code: String?
|
926
|
+
e_code = nil
|
927
|
+
|
923
928
|
OptionParser.new do |opts|
|
924
929
|
opts.banner = <<-EOB
|
925
930
|
Usage: rbs parse [files...]
|
@@ -929,22 +934,35 @@ Parse given RBS files and print syntax errors.
|
|
929
934
|
Examples:
|
930
935
|
|
931
936
|
$ rbs parse sig/app/models.rbs sig/app/controllers.rbs
|
937
|
+
|
938
|
+
Options:
|
932
939
|
EOB
|
933
|
-
end.parse!(args)
|
934
940
|
|
935
|
-
|
941
|
+
opts.on('-e CODE', 'One line RBS script to parse') { |e| e_code = e }
|
942
|
+
opts.on('--type', 'Parse code as a type') { |e| parse_method = :parse_type }
|
943
|
+
opts.on('--method-type', 'Parse code as a method type') { |e| parse_method = :parse_method_type }
|
944
|
+
end.parse!(args)
|
936
945
|
|
937
946
|
syntax_error = false
|
938
|
-
args.
|
947
|
+
bufs = args.flat_map do |path|
|
939
948
|
path = Pathname(path)
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
949
|
+
FileFinder.each_file(path, skip_hidden: false, immediate: true).map do |file_path|
|
950
|
+
Buffer.new(content: file_path.read, name: file_path)
|
951
|
+
end
|
952
|
+
end
|
953
|
+
bufs << Buffer.new(content: e_code, name: '-e') if e_code
|
954
|
+
|
955
|
+
bufs.each do |buf|
|
956
|
+
RBS.logger.info "Parsing #{buf.name}..."
|
957
|
+
case parse_method
|
958
|
+
when :parse_signature
|
959
|
+
Parser.parse_signature(buf)
|
960
|
+
else
|
961
|
+
Parser.public_send(parse_method, buf, require_eof: true)
|
947
962
|
end
|
963
|
+
rescue RBS::ParsingError => ex
|
964
|
+
stdout.puts ex.message
|
965
|
+
syntax_error = true
|
948
966
|
end
|
949
967
|
|
950
968
|
exit 1 if syntax_error
|
@@ -1078,7 +1096,8 @@ EOB
|
|
1078
1096
|
config_path = options.config_path or raise
|
1079
1097
|
lock_path = Collection::Config.to_lockfile_path(config_path)
|
1080
1098
|
|
1081
|
-
|
1099
|
+
subcommand = Abbrev.abbrev(['install', 'update', 'help'])[args[0]] || args[0]
|
1100
|
+
case subcommand
|
1082
1101
|
when 'install'
|
1083
1102
|
unless params[:frozen]
|
1084
1103
|
Collection::Config.generate_lockfile(config_path: config_path, definition: Bundler.definition)
|
@@ -1154,5 +1173,80 @@ EOB
|
|
1154
1173
|
opts.on('--frozen') if args[0] == 'install'
|
1155
1174
|
end
|
1156
1175
|
end
|
1176
|
+
|
1177
|
+
def run_subtract(args, _)
|
1178
|
+
write_to_file = false
|
1179
|
+
# @type var subtrahend_paths: Array[String]
|
1180
|
+
subtrahend_paths = []
|
1181
|
+
|
1182
|
+
opts = OptionParser.new do |opts|
|
1183
|
+
opts.banner = <<~HELP
|
1184
|
+
Usage:
|
1185
|
+
rbs subtract [options...] minuend.rbs [minuend2.rbs, ...] subtrahend.rbs
|
1186
|
+
rbs subtract [options...] minuend.rbs [minuend2.rbs, ...] --subtrahend subtrahend_1.rbs --subtrahend subtrahend_2.rbs
|
1187
|
+
|
1188
|
+
Remove duplications between RBS files.
|
1189
|
+
|
1190
|
+
Examples:
|
1191
|
+
|
1192
|
+
# Generate RBS files from the codebase.
|
1193
|
+
$ rbs prototype rb lib/ > generated.rbs
|
1194
|
+
|
1195
|
+
# Write more descrictive types by hand.
|
1196
|
+
$ $EDITOR handwritten.rbs
|
1197
|
+
|
1198
|
+
# Remove hand-written method definitions from generated.rbs.
|
1199
|
+
$ rbs subtract --write generated.rbs handwritten.rbs
|
1200
|
+
|
1201
|
+
Options:
|
1202
|
+
HELP
|
1203
|
+
opts.on('-w', '--write', 'Overwrite files directry') { write_to_file = true }
|
1204
|
+
opts.on('--subtrahend=PATH', '') { |path| subtrahend_paths << path }
|
1205
|
+
opts.parse!(args)
|
1206
|
+
end
|
1207
|
+
|
1208
|
+
if subtrahend_paths.empty?
|
1209
|
+
*minuend_paths, subtrahend_path = args
|
1210
|
+
unless subtrahend_path
|
1211
|
+
stdout.puts opts.help
|
1212
|
+
exit 1
|
1213
|
+
end
|
1214
|
+
subtrahend_paths << subtrahend_path
|
1215
|
+
else
|
1216
|
+
minuend_paths = args
|
1217
|
+
end
|
1218
|
+
|
1219
|
+
if minuend_paths.empty?
|
1220
|
+
stdout.puts opts.help
|
1221
|
+
exit 1
|
1222
|
+
end
|
1223
|
+
|
1224
|
+
subtrahend = Environment.new.tap do |env|
|
1225
|
+
loader = EnvironmentLoader.new(core_root: nil)
|
1226
|
+
subtrahend_paths.each do |path|
|
1227
|
+
loader.add(path: Pathname(path))
|
1228
|
+
end
|
1229
|
+
loader.load(env: env)
|
1230
|
+
end
|
1231
|
+
|
1232
|
+
minuend_paths.each do |minuend_path|
|
1233
|
+
FileFinder.each_file(Pathname(minuend_path), immediate: true, skip_hidden: true) do |rbs_path|
|
1234
|
+
buf = Buffer.new(name: rbs_path, content: rbs_path.read)
|
1235
|
+
_, dirs, decls = Parser.parse_signature(buf)
|
1236
|
+
subtracted = Subtractor.new(decls, subtrahend).call
|
1237
|
+
|
1238
|
+
io = StringIO.new
|
1239
|
+
w = Writer.new(out: io)
|
1240
|
+
w.write(dirs)
|
1241
|
+
w.write(subtracted)
|
1242
|
+
|
1243
|
+
if write_to_file
|
1244
|
+
rbs_path.write(io.string)
|
1245
|
+
else
|
1246
|
+
stdout.puts(io.string)
|
1247
|
+
end
|
1248
|
+
end
|
1249
|
+
end
|
1250
|
+
end
|
1157
1251
|
end
|
1158
1252
|
end
|
@@ -76,7 +76,7 @@ module RBS
|
|
76
76
|
end
|
77
77
|
|
78
78
|
if spec = gem_hash[dep.name]
|
79
|
-
assign_gem(name: dep.name, version: spec.version, ignored_gems: ignored_gems, src_data: nil)
|
79
|
+
assign_gem(name: dep.name, version: spec.version, ignored_gems: ignored_gems, src_data: nil, skip: dep.source.is_a?(Bundler::Source::Gemspec))
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
@@ -91,50 +91,56 @@ module RBS
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
-
private def assign_gem(name:, version:, src_data:, ignored_gems:)
|
94
|
+
private def assign_gem(name:, version:, src_data:, ignored_gems:, skip: false)
|
95
95
|
return if ignored_gems.include?(name)
|
96
96
|
return if lockfile.gems.key?(name)
|
97
97
|
|
98
|
-
|
98
|
+
unless skip
|
99
|
+
# @type var locked: Lockfile::library?
|
99
100
|
|
100
|
-
|
101
|
-
|
102
|
-
|
101
|
+
if existing_lockfile
|
102
|
+
locked = existing_lockfile.gems[name]
|
103
|
+
end
|
103
104
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
105
|
+
# If rbs_collection.lock.yaml contain the gem, use it.
|
106
|
+
# Else find the gem from gem_collection.
|
107
|
+
unless locked
|
108
|
+
source =
|
109
|
+
if src_data
|
110
|
+
Sources.from_config_entry(src_data, base_directory: config.config_path.dirname)
|
111
|
+
else
|
112
|
+
find_source(name: name)
|
113
|
+
end
|
114
|
+
|
115
|
+
if source
|
116
|
+
installed_version = version
|
117
|
+
best_version = find_best_version(version: installed_version, versions: source.versions(name))
|
118
|
+
|
119
|
+
locked = {
|
120
|
+
name: name,
|
121
|
+
version: best_version.to_s,
|
122
|
+
source: source,
|
123
|
+
}
|
112
124
|
end
|
113
|
-
|
114
|
-
if source
|
115
|
-
installed_version = version
|
116
|
-
best_version = find_best_version(version: installed_version, versions: source.versions(name))
|
117
|
-
|
118
|
-
locked = {
|
119
|
-
name: name,
|
120
|
-
version: best_version.to_s,
|
121
|
-
source: source,
|
122
|
-
}
|
123
125
|
end
|
124
|
-
end
|
125
126
|
|
126
|
-
|
127
|
-
|
127
|
+
if locked
|
128
|
+
lockfile.gems[name] = locked
|
128
129
|
|
129
|
-
|
130
|
-
|
130
|
+
locked[:source].dependencies_of(locked[:name], locked[:version])&.each do |dep|
|
131
|
+
assign_stdlib(name: dep["name"], from_gem: name)
|
132
|
+
end
|
131
133
|
end
|
132
134
|
end
|
133
135
|
|
134
|
-
gem_hash
|
135
|
-
|
136
|
-
|
136
|
+
if spec = gem_hash.fetch(name, nil)
|
137
|
+
spec.dependencies.each do |dep|
|
138
|
+
if dep_spec = gem_hash[dep.name]
|
139
|
+
assign_gem(name: dep.name, version: dep_spec.version, src_data: nil, ignored_gems: ignored_gems)
|
140
|
+
end
|
137
141
|
end
|
142
|
+
else
|
143
|
+
RBS.logger.warn "Cannot find `#{name}` gem. Using incorrect Bundler context? (#{definition.lockfile})"
|
138
144
|
end
|
139
145
|
end
|
140
146
|
|
@@ -239,14 +239,6 @@ module RBS
|
|
239
239
|
definition.class_variables.merge!(defn.class_variables)
|
240
240
|
end
|
241
241
|
|
242
|
-
all_interfaces = one_ancestors.each_extended_interface.flat_map do |interface|
|
243
|
-
other_interfaces = ancestor_builder.interface_ancestors(interface.name).ancestors #: Array[Definition::Ancestor::Instance]
|
244
|
-
other_interfaces = other_interfaces.select {|ancestor| ancestor.source }
|
245
|
-
[interface, *other_interfaces]
|
246
|
-
end
|
247
|
-
interface_methods = interface_methods(all_interfaces)
|
248
|
-
import_methods(definition, type_name, methods, interface_methods, Substitution.new)
|
249
|
-
|
250
242
|
one_ancestors.each_extended_module do |mod|
|
251
243
|
mod.args.each do |arg|
|
252
244
|
validate_type_presence(arg)
|
@@ -256,7 +248,12 @@ module RBS
|
|
256
248
|
define_instance(definition, mod.name, subst)
|
257
249
|
end
|
258
250
|
|
259
|
-
|
251
|
+
all_interfaces = one_ancestors.each_extended_interface.flat_map do |interface|
|
252
|
+
other_interfaces = ancestor_builder.interface_ancestors(interface.name).ancestors #: Array[Definition::Ancestor::Instance]
|
253
|
+
other_interfaces = other_interfaces.select {|ancestor| ancestor.source }
|
254
|
+
[interface, *other_interfaces]
|
255
|
+
end
|
256
|
+
interface_methods = interface_methods(all_interfaces)
|
260
257
|
import_methods(definition, type_name, methods, interface_methods, Substitution.new)
|
261
258
|
|
262
259
|
entry.decls.each do |d|
|
data/lib/rbs/environment.rb
CHANGED
@@ -365,7 +365,7 @@ module RBS
|
|
365
365
|
name = decl.name.with_prefix(namespace)
|
366
366
|
|
367
367
|
if interface_entry = interface_decls[name]
|
368
|
-
DuplicatedDeclarationError.new(name, decl, interface_entry.decl)
|
368
|
+
raise DuplicatedDeclarationError.new(name, decl, interface_entry.decl)
|
369
369
|
end
|
370
370
|
|
371
371
|
interface_decls[name] = InterfaceEntry.new(name: name, decl: decl, outer: outer)
|
@@ -374,7 +374,7 @@ module RBS
|
|
374
374
|
name = decl.name.with_prefix(namespace)
|
375
375
|
|
376
376
|
if entry = type_alias_decls[name]
|
377
|
-
DuplicatedDeclarationError.new(name, decl, entry.decl)
|
377
|
+
raise DuplicatedDeclarationError.new(name, decl, entry.decl)
|
378
378
|
end
|
379
379
|
|
380
380
|
type_alias_decls[name] = TypeAliasEntry.new(name: name, decl: decl, outer: outer)
|
@@ -12,6 +12,8 @@ module RBS
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
+
include FileFinder
|
16
|
+
|
15
17
|
Library = _ = Struct.new(:name, :version, keyword_init: true)
|
16
18
|
|
17
19
|
attr_reader :core_root
|
@@ -129,35 +131,13 @@ module RBS
|
|
129
131
|
end
|
130
132
|
end
|
131
133
|
|
132
|
-
def each_file(path, immediate:, skip_hidden:, &block)
|
133
|
-
case
|
134
|
-
when path.file?
|
135
|
-
if path.extname == ".rbs" || immediate
|
136
|
-
yield path
|
137
|
-
end
|
138
|
-
|
139
|
-
when path.directory?
|
140
|
-
if path.basename.to_s.start_with?("_")
|
141
|
-
if skip_hidden
|
142
|
-
unless immediate
|
143
|
-
return
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
path.children.sort.each do |child|
|
149
|
-
each_file(child, immediate: false, skip_hidden: skip_hidden, &block)
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
134
|
def each_signature
|
155
135
|
files = Set[]
|
156
136
|
|
157
137
|
each_dir do |source, dir|
|
158
138
|
skip_hidden = !source.is_a?(Pathname)
|
159
139
|
|
160
|
-
each_file(dir, skip_hidden: skip_hidden, immediate: true) do |path|
|
140
|
+
FileFinder.each_file(dir, skip_hidden: skip_hidden, immediate: true) do |path|
|
161
141
|
next if files.include?(path)
|
162
142
|
|
163
143
|
files << path
|
data/lib/rbs/errors.rb
CHANGED
@@ -22,11 +22,16 @@ module RBS
|
|
22
22
|
|
23
23
|
module DetailedMessageable
|
24
24
|
def detailed_message(highlight: false, **)
|
25
|
+
msg = super
|
26
|
+
|
27
|
+
# Support only one line
|
28
|
+
return msg unless location.start_line == location.end_line
|
29
|
+
|
25
30
|
indent = " " * location.start_column
|
26
31
|
marker = "^" * (location.end_column - location.start_column)
|
27
32
|
|
28
33
|
io = StringIO.new
|
29
|
-
io.puts
|
34
|
+
io.puts msg
|
30
35
|
io.puts
|
31
36
|
io.print "\e[1m" if highlight
|
32
37
|
io.puts " #{location.buffer.lines[location.end_line - 1]}"
|
@@ -125,7 +130,9 @@ module RBS
|
|
125
130
|
end
|
126
131
|
end
|
127
132
|
|
128
|
-
class NoTypeFoundError <
|
133
|
+
class NoTypeFoundError < DefinitionError
|
134
|
+
include DetailedMessageable
|
135
|
+
|
129
136
|
attr_reader :type_name
|
130
137
|
attr_reader :location
|
131
138
|
|
@@ -163,6 +170,8 @@ module RBS
|
|
163
170
|
end
|
164
171
|
|
165
172
|
class InheritModuleError < DefinitionError
|
173
|
+
include DetailedMessageable
|
174
|
+
|
166
175
|
attr_reader :super_decl
|
167
176
|
|
168
177
|
def initialize(super_decl)
|
@@ -171,6 +180,10 @@ module RBS
|
|
171
180
|
super "#{Location.to_string(super_decl.location)}: Cannot inherit a module: #{super_decl.name}"
|
172
181
|
end
|
173
182
|
|
183
|
+
def location
|
184
|
+
@super_decl.location
|
185
|
+
end
|
186
|
+
|
174
187
|
def self.check!(super_decl, env:)
|
175
188
|
return if env.class_decl?(super_decl.name) || env.class_alias?(super_decl.name)
|
176
189
|
|
@@ -179,6 +192,8 @@ module RBS
|
|
179
192
|
end
|
180
193
|
|
181
194
|
class NoSelfTypeFoundError < DefinitionError
|
195
|
+
include DetailedMessageable
|
196
|
+
|
182
197
|
attr_reader :type_name
|
183
198
|
attr_reader :location
|
184
199
|
|
@@ -197,6 +212,8 @@ module RBS
|
|
197
212
|
end
|
198
213
|
|
199
214
|
class NoMixinFoundError < DefinitionError
|
215
|
+
include DetailedMessageable
|
216
|
+
|
200
217
|
attr_reader :type_name
|
201
218
|
attr_reader :member
|
202
219
|
|
@@ -217,6 +234,8 @@ module RBS
|
|
217
234
|
end
|
218
235
|
|
219
236
|
class DuplicatedMethodDefinitionError < DefinitionError
|
237
|
+
include DetailedMessageable
|
238
|
+
|
220
239
|
attr_reader :type
|
221
240
|
attr_reader :method_name
|
222
241
|
attr_reader :members
|
@@ -256,6 +275,8 @@ module RBS
|
|
256
275
|
end
|
257
276
|
|
258
277
|
class DuplicatedInterfaceMethodDefinitionError < DefinitionError
|
278
|
+
include DetailedMessageable
|
279
|
+
|
259
280
|
attr_reader :type
|
260
281
|
attr_reader :method_name
|
261
282
|
attr_reader :member
|
@@ -268,6 +289,10 @@ module RBS
|
|
268
289
|
super "#{member.location}: Duplicated method definition: #{qualified_method_name}"
|
269
290
|
end
|
270
291
|
|
292
|
+
def location
|
293
|
+
member.location
|
294
|
+
end
|
295
|
+
|
271
296
|
def qualified_method_name
|
272
297
|
case type
|
273
298
|
when Types::ClassSingleton
|
@@ -283,6 +308,8 @@ module RBS
|
|
283
308
|
end
|
284
309
|
|
285
310
|
class UnknownMethodAliasError < DefinitionError
|
311
|
+
include DetailedMessageable
|
312
|
+
|
286
313
|
attr_reader :type_name
|
287
314
|
attr_reader :original_name
|
288
315
|
attr_reader :aliased_name
|
@@ -310,6 +337,8 @@ module RBS
|
|
310
337
|
end
|
311
338
|
|
312
339
|
class InvalidOverloadMethodError < DefinitionError
|
340
|
+
include DetailedMessageable
|
341
|
+
|
313
342
|
attr_reader :type_name
|
314
343
|
attr_reader :method_name
|
315
344
|
attr_reader :kind
|
@@ -330,6 +359,10 @@ module RBS
|
|
330
359
|
|
331
360
|
super "#{Location.to_string members[0].location}: Invalid method overloading: #{type_name}#{delimiter}#{method_name}"
|
332
361
|
end
|
362
|
+
|
363
|
+
def location
|
364
|
+
members[0].location
|
365
|
+
end
|
333
366
|
end
|
334
367
|
|
335
368
|
class GenericParameterMismatchError < LoadingError
|
@@ -357,6 +390,8 @@ module RBS
|
|
357
390
|
end
|
358
391
|
|
359
392
|
class InvalidVarianceAnnotationError < DefinitionError
|
393
|
+
include DetailedMessageable
|
394
|
+
|
360
395
|
attr_reader :type_name
|
361
396
|
attr_reader :param
|
362
397
|
attr_reader :location
|
@@ -371,6 +406,8 @@ module RBS
|
|
371
406
|
end
|
372
407
|
|
373
408
|
class RecursiveAliasDefinitionError < DefinitionError
|
409
|
+
include DetailedMessageable
|
410
|
+
|
374
411
|
attr_reader :type
|
375
412
|
attr_reader :defs
|
376
413
|
|
@@ -389,6 +426,8 @@ module RBS
|
|
389
426
|
end
|
390
427
|
|
391
428
|
class MixinClassError < DefinitionError
|
429
|
+
include DetailedMessageable
|
430
|
+
|
392
431
|
attr_reader :type_name
|
393
432
|
attr_reader :member
|
394
433
|
|
@@ -426,6 +465,8 @@ module RBS
|
|
426
465
|
end
|
427
466
|
|
428
467
|
class RecursiveTypeAliasError < BaseError
|
468
|
+
include DetailedMessageable
|
469
|
+
|
429
470
|
attr_reader :alias_names
|
430
471
|
attr_reader :location
|
431
472
|
|
@@ -442,6 +483,8 @@ module RBS
|
|
442
483
|
end
|
443
484
|
|
444
485
|
class NonregularTypeAliasError < BaseError
|
486
|
+
include DetailedMessageable
|
487
|
+
|
445
488
|
attr_reader :diagnostic
|
446
489
|
attr_reader :location
|
447
490
|
|
@@ -454,6 +497,8 @@ module RBS
|
|
454
497
|
end
|
455
498
|
|
456
499
|
class CyclicTypeParameterBound < BaseError
|
500
|
+
include DetailedMessageable
|
501
|
+
|
457
502
|
attr_reader :params, :type_name, :method_name, :location
|
458
503
|
|
459
504
|
def initialize(type_name:, method_name:, params:, location:)
|
@@ -467,6 +512,8 @@ module RBS
|
|
467
512
|
end
|
468
513
|
|
469
514
|
class InconsistentClassModuleAliasError < BaseError
|
515
|
+
include DetailedMessageable
|
516
|
+
|
470
517
|
attr_reader :alias_entry
|
471
518
|
|
472
519
|
def initialize(entry)
|
@@ -482,9 +529,15 @@ module RBS
|
|
482
529
|
|
483
530
|
super "#{Location.to_string(entry.decl.location&.[](:old_name))}: A #{expected_kind} `#{entry.decl.new_name}` cannot be an alias of a #{actual_kind} `#{entry.decl.old_name}`"
|
484
531
|
end
|
532
|
+
|
533
|
+
def location
|
534
|
+
@alias_entry.decl.location
|
535
|
+
end
|
485
536
|
end
|
486
537
|
|
487
538
|
class CyclicClassAliasDefinitionError < BaseError
|
539
|
+
include DetailedMessageable
|
540
|
+
|
488
541
|
attr_reader :alias_entry
|
489
542
|
|
490
543
|
def initialize(entry)
|
@@ -492,5 +545,9 @@ module RBS
|
|
492
545
|
|
493
546
|
super "#{Location.to_string(entry.decl.location&.[](:old_name))}: A #{alias_entry.decl.new_name} is a cyclic definition"
|
494
547
|
end
|
548
|
+
|
549
|
+
def location
|
550
|
+
@alias_entry.decl.location
|
551
|
+
end
|
495
552
|
end
|
496
553
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBS
|
4
|
+
module FileFinder
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def self.each_file(path, immediate:, skip_hidden:, &block)
|
8
|
+
return enum_for(__method__, path, immediate: immediate, skip_hidden: skip_hidden) unless block
|
9
|
+
|
10
|
+
case
|
11
|
+
when path.file?
|
12
|
+
if path.extname == ".rbs" || immediate
|
13
|
+
yield path
|
14
|
+
end
|
15
|
+
|
16
|
+
when path.directory?
|
17
|
+
if path.basename.to_s.start_with?("_")
|
18
|
+
if skip_hidden
|
19
|
+
unless immediate
|
20
|
+
return
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
path.children.sort.each do |child|
|
26
|
+
each_file(child, immediate: false, skip_hidden: skip_hidden, &block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/rbs/parser_aux.rb
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
|
3
3
|
module RBS
|
4
4
|
class Parser
|
5
|
-
def self.parse_type(source, range: 0..., variables: [])
|
5
|
+
def self.parse_type(source, range: 0..., variables: [], require_eof: false)
|
6
6
|
buf = buffer(source)
|
7
|
-
_parse_type(buf, range.begin || 0, range.end || buf.last_position, variables)
|
7
|
+
_parse_type(buf, range.begin || 0, range.end || buf.last_position, variables, require_eof)
|
8
8
|
end
|
9
9
|
|
10
|
-
def self.parse_method_type(source, range: 0..., variables: [])
|
10
|
+
def self.parse_method_type(source, range: 0..., variables: [], require_eof: false)
|
11
11
|
buf = buffer(source)
|
12
|
-
_parse_method_type(buf, range.begin || 0, range.end || buf.last_position, variables)
|
12
|
+
_parse_method_type(buf, range.begin || 0, range.end || buf.last_position, variables, require_eof)
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.parse_signature(source)
|
data/lib/rbs/prototype/rb.rb
CHANGED
@@ -215,7 +215,8 @@ module RBS
|
|
215
215
|
when :include
|
216
216
|
args.each do |arg|
|
217
217
|
if (name = const_to_name(arg, context: context))
|
218
|
-
|
218
|
+
klass = context.singleton ? AST::Members::Extend : AST::Members::Include
|
219
|
+
decls << klass.new(
|
219
220
|
name: name,
|
220
221
|
args: [],
|
221
222
|
annotations: [],
|