rbs 3.2.2 → 3.3.0.pre.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/.github/workflows/comments.yml +1 -1
- data/.github/workflows/ruby.yml +7 -2
- data/CHANGELOG.md +85 -0
- data/Gemfile.lock +14 -14
- data/README.md +11 -2
- data/Rakefile +10 -7
- data/Steepfile +7 -7
- data/core/basic_object.rbs +7 -7
- data/core/binding.rbs +3 -3
- data/core/builtin.rbs +171 -5
- data/core/constants.rbs +17 -17
- data/core/dir.rbs +3 -3
- data/core/encoding.rbs +434 -628
- data/core/enumerator.rbs +37 -0
- data/core/exception.rbs +11 -11
- data/core/false_class.rbs +5 -11
- data/core/fiber.rbs +3 -3
- data/core/file_test.rbs +28 -26
- data/core/kernel.rbs +900 -21
- data/core/marshal.rbs +24 -14
- data/core/match_data.rbs +8 -8
- data/core/math.rbs +57 -53
- data/core/method.rbs +3 -1
- data/core/module.rbs +38 -36
- data/core/nil_class.rbs +7 -13
- data/core/object.rbs +3 -966
- data/core/process.rbs +3 -3
- data/core/ractor.rbs +2 -2
- data/core/rb_config.rbs +64 -43
- data/core/regexp.rbs +3 -3
- data/core/signal.rbs +10 -4
- data/core/struct.rbs +1 -1
- data/core/thread.rbs +7 -7
- data/core/thread_group.rbs +9 -9
- data/core/true_class.rbs +5 -11
- data/core/unbound_method.rbs +56 -7
- data/core/warning.rbs +33 -0
- data/docs/collection.md +56 -6
- data/docs/data_and_struct.md +57 -0
- data/docs/stdlib.md +61 -2
- data/docs/syntax.md +123 -2
- data/ext/rbs_extension/lexer.c +624 -569
- data/ext/rbs_extension/lexer.h +1 -0
- data/ext/rbs_extension/lexer.re +1 -0
- data/ext/rbs_extension/lexstate.c +1 -0
- data/ext/rbs_extension/parser.c +6 -0
- data/goodcheck.yml +2 -2
- data/lib/rbs/annotate/formatter.rb +13 -3
- data/lib/rbs/annotate/rdoc_source.rb +10 -1
- data/lib/rbs/cli/colored_io.rb +48 -0
- data/lib/rbs/cli/diff.rb +80 -0
- data/lib/rbs/cli.rb +151 -16
- data/lib/rbs/collection/config/lockfile.rb +0 -25
- data/lib/rbs/collection/config/lockfile_generator.rb +0 -6
- data/lib/rbs/collection/installer.rb +1 -1
- data/lib/rbs/collection/sources/git.rb +6 -4
- data/lib/rbs/collection/sources/local.rb +7 -5
- data/lib/rbs/diff.rb +104 -0
- data/lib/rbs/environment.rb +1 -1
- data/lib/rbs/method_type.rb +23 -0
- data/lib/rbs/prototype/rb.rb +2 -9
- data/lib/rbs/prototype/runtime/helpers.rb +59 -0
- data/lib/rbs/prototype/runtime/value_object_generator.rb +236 -0
- data/lib/rbs/prototype/runtime.rb +234 -150
- data/lib/rbs/sorter.rb +144 -117
- data/lib/rbs/test/guaranteed.rb +31 -0
- data/lib/rbs/test/type_check.rb +4 -4
- data/lib/rbs/test.rb +3 -0
- data/lib/rbs/types.rb +184 -3
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +4 -4
- data/lib/rbs.rb +1 -0
- data/rbs.gemspec +1 -0
- data/sig/annotate/formatter.rbs +2 -2
- data/sig/annotate/rdoc_annotater.rbs +1 -1
- data/sig/cli/colored_io.rbs +15 -0
- data/sig/cli/diff.rbs +21 -0
- data/sig/cli.rbs +2 -0
- data/sig/collection/config/lockfile.rbs +0 -6
- data/sig/diff.rbs +23 -0
- data/sig/errors.rbs +1 -5
- data/sig/method_types.rbs +6 -0
- data/sig/prototype/runtime.rbs +108 -0
- data/sig/rdoc/rbs.rbs +4 -0
- data/sig/shims/bundler.rbs +5 -0
- data/sig/sorter.rbs +23 -5
- data/sig/types.rbs +29 -0
- data/stdlib/benchmark/0/benchmark.rbs +1 -1
- data/stdlib/cgi/0/core.rbs +2 -2
- data/stdlib/did_you_mean/0/did_you_mean.rbs +2 -2
- data/stdlib/digest/0/digest.rbs +1 -1
- data/stdlib/fileutils/0/fileutils.rbs +1 -1
- data/stdlib/forwardable/0/forwardable.rbs +4 -4
- data/stdlib/io-console/0/io-console.rbs +1 -1
- data/stdlib/json/0/json.rbs +37 -0
- data/stdlib/logger/0/logger.rbs +2 -2
- data/stdlib/net-http/0/manifest.yaml +1 -1
- data/stdlib/net-http/0/net-http.rbs +16 -63
- data/stdlib/net-protocol/0/manifest.yaml +2 -0
- data/stdlib/net-protocol/0/net-protocol.rbs +56 -0
- data/stdlib/openssl/0/openssl.rbs +1 -1
- data/stdlib/pp/0/manifest.yaml +2 -0
- data/stdlib/pp/0/pp.rbs +301 -0
- data/stdlib/{yaml → psych}/0/dbm.rbs +3 -3
- data/stdlib/psych/0/manifest.yaml +3 -0
- data/stdlib/psych/0/psych.rbs +391 -0
- data/stdlib/{yaml → psych}/0/store.rbs +2 -2
- data/stdlib/rdoc/0/code_object.rbs +55 -0
- data/stdlib/rdoc/0/comment.rbs +60 -0
- data/stdlib/rdoc/0/context.rbs +153 -0
- data/stdlib/rdoc/0/markup.rbs +119 -0
- data/stdlib/rdoc/0/parser.rbs +56 -0
- data/stdlib/rdoc/0/rdoc.rbs +0 -372
- data/stdlib/rdoc/0/ri.rbs +17 -0
- data/stdlib/rdoc/0/store.rbs +48 -0
- data/stdlib/rdoc/0/top_level.rbs +97 -0
- data/stdlib/socket/0/basic_socket.rbs +1 -1
- data/stdlib/socket/0/socket.rbs +1 -1
- data/stdlib/uri/0/common.rbs +1 -1
- data/stdlib/yaml/0/manifest.yaml +1 -2
- data/stdlib/yaml/0/yaml.rbs +1 -199
- metadata +46 -9
- data/sig/shims/pp.rbs +0 -3
- data/sig/shims.rbs +0 -47
data/ext/rbs_extension/lexer.h
CHANGED
data/ext/rbs_extension/lexer.re
CHANGED
|
@@ -95,6 +95,7 @@ start:
|
|
|
95
95
|
"void" { return next_token(state, kVOID); }
|
|
96
96
|
"use" { return next_token(state, kUSE); }
|
|
97
97
|
"as" { return next_token(state, kAS); }
|
|
98
|
+
"__todo__" { return next_token(state, k__TODO__); }
|
|
98
99
|
|
|
99
100
|
dqstring = ["] ("\\"[abefnrstv"\\] | [^"\\\x00])* ["];
|
|
100
101
|
sqstring = ['] ("\\"['\\] | [^'\x00])* ['];
|
data/ext/rbs_extension/parser.c
CHANGED
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
case kUNTYPED: \
|
|
40
40
|
case kUSE: \
|
|
41
41
|
case kAS: \
|
|
42
|
+
case k__TODO__: \
|
|
42
43
|
/* nop */
|
|
43
44
|
|
|
44
45
|
typedef struct {
|
|
@@ -898,6 +899,11 @@ static VALUE parse_simple(parserstate *state) {
|
|
|
898
899
|
return rbs_base_type(RBS_Types_Bases_Void, rbs_location_current_token(state));
|
|
899
900
|
case kUNTYPED:
|
|
900
901
|
return rbs_base_type(RBS_Types_Bases_Any, rbs_location_current_token(state));
|
|
902
|
+
case k__TODO__: {
|
|
903
|
+
VALUE type = rbs_base_type(RBS_Types_Bases_Any, rbs_location_current_token(state));
|
|
904
|
+
rb_funcall(type, rb_intern("todo!"), 0);
|
|
905
|
+
return type;
|
|
906
|
+
}
|
|
901
907
|
case tINTEGER: {
|
|
902
908
|
VALUE literal = rb_funcall(
|
|
903
909
|
string_of_loc(state, state->current_token.range.start, state->current_token.range.end),
|
data/goodcheck.yml
CHANGED
|
@@ -13,9 +13,9 @@ rules:
|
|
|
13
13
|
glob:
|
|
14
14
|
- "{core,stdlib}/**/*.rbs"
|
|
15
15
|
fail:
|
|
16
|
-
- "def `send`: (
|
|
16
|
+
- "def `send`: (interned arg0, *untyped arg1) -> untyped"
|
|
17
17
|
pass:
|
|
18
|
-
- "def `send`: (
|
|
18
|
+
- "def `send`: (interned, *untyped) -> untyped"
|
|
19
19
|
|
|
20
20
|
- id: rbs.prefer_boolish
|
|
21
21
|
pattern:
|
|
@@ -59,10 +59,20 @@ module RBS
|
|
|
59
59
|
|
|
60
60
|
def self.each_part(doc, &block)
|
|
61
61
|
if block
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
document =
|
|
63
|
+
case doc
|
|
64
|
+
when String
|
|
65
|
+
raise
|
|
66
|
+
when RDoc::Comment
|
|
67
|
+
document = doc.parse
|
|
68
|
+
when RDoc::Markup::Document
|
|
69
|
+
document = doc
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
if document.file
|
|
73
|
+
yield document
|
|
64
74
|
else
|
|
65
|
-
|
|
75
|
+
document.each do |d|
|
|
66
76
|
each_part(d, &block)
|
|
67
77
|
end
|
|
68
78
|
end
|
|
@@ -47,7 +47,16 @@ module RBS
|
|
|
47
47
|
def docs
|
|
48
48
|
if ds = yield
|
|
49
49
|
unless ds.empty?
|
|
50
|
-
ds.map
|
|
50
|
+
ds.map do |code_object|
|
|
51
|
+
case comment = code_object.comment
|
|
52
|
+
when String
|
|
53
|
+
raise
|
|
54
|
+
when RDoc::Comment
|
|
55
|
+
comment.parse
|
|
56
|
+
when RDoc::Markup::Document
|
|
57
|
+
comment
|
|
58
|
+
end
|
|
59
|
+
end
|
|
51
60
|
end
|
|
52
61
|
end
|
|
53
62
|
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RBS
|
|
4
|
+
class CLI
|
|
5
|
+
class ColoredIO
|
|
6
|
+
attr_reader :stdout
|
|
7
|
+
|
|
8
|
+
def initialize(stdout:)
|
|
9
|
+
@stdout = stdout
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def puts_red(string)
|
|
13
|
+
if can_display_colors?
|
|
14
|
+
puts "\e[31m#{string}\e[m"
|
|
15
|
+
else
|
|
16
|
+
puts string
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def puts_green(string)
|
|
21
|
+
if can_display_colors?
|
|
22
|
+
puts "\e[32m#{string}\e[m"
|
|
23
|
+
else
|
|
24
|
+
puts string
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def puts(...)
|
|
29
|
+
stdout.puts(...)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
# https://github.com/rubygems/rubygems/blob/ed65279100234a17d65d71fe26de5083984ac5b8/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb#L99-L109
|
|
35
|
+
def can_display_colors?
|
|
36
|
+
are_colors_supported? && !are_colors_disabled?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def are_colors_supported?
|
|
40
|
+
stdout.tty? && ENV["TERM"] != "dumb"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def are_colors_disabled?
|
|
44
|
+
!ENV['NO_COLOR'].nil? && !ENV.fetch('NO_COLOR', '').empty?
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
data/lib/rbs/cli/diff.rb
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RBS
|
|
4
|
+
class CLI
|
|
5
|
+
class Diff
|
|
6
|
+
def initialize(argv:, library_options:, stdout: $stdout, stderr: $stderr)
|
|
7
|
+
@format = nil
|
|
8
|
+
@stdout = stdout
|
|
9
|
+
@stderr = stderr
|
|
10
|
+
|
|
11
|
+
# @type var type_name: String?
|
|
12
|
+
type_name = nil
|
|
13
|
+
library_options = library_options
|
|
14
|
+
before_path = []
|
|
15
|
+
after_path = []
|
|
16
|
+
|
|
17
|
+
opt = OptionParser.new do |o|
|
|
18
|
+
o.banner = <<~HELP
|
|
19
|
+
[Experimental] This command is experimental. API and output compatibility is not guaranteed.
|
|
20
|
+
|
|
21
|
+
Usage:
|
|
22
|
+
rbs diff --format markdown --type-name Foo --before before_sig --after after_sig
|
|
23
|
+
|
|
24
|
+
Print diff for rbs environment dir
|
|
25
|
+
|
|
26
|
+
Examples:
|
|
27
|
+
|
|
28
|
+
# Diff dir1 and dir2 for Foo
|
|
29
|
+
$ rbs diff --format markdown --type-name Foo --before dir1 --after dir2
|
|
30
|
+
|
|
31
|
+
# Confirmation of methods related to Time class added by including stdlib/time
|
|
32
|
+
$ rbs diff --format diff --type-name Time --after stdlib/time
|
|
33
|
+
HELP
|
|
34
|
+
o.on("--format NAME") { |arg| @format = arg }
|
|
35
|
+
o.on("--type-name NAME") { |arg| type_name = arg }
|
|
36
|
+
o.on("--before DIR") { |arg| before_path << arg }
|
|
37
|
+
o.on("--after DIR") { |arg| after_path << arg }
|
|
38
|
+
end
|
|
39
|
+
opt.parse!(argv)
|
|
40
|
+
|
|
41
|
+
unless @format && type_name && ["markdown", "diff"].include?(@format)
|
|
42
|
+
@stderr.puts opt.banner
|
|
43
|
+
exit 1
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
@diff = RBS::Diff.new(
|
|
47
|
+
type_name: TypeName(type_name).absolute!,
|
|
48
|
+
library_options: library_options,
|
|
49
|
+
after_path: after_path,
|
|
50
|
+
before_path: before_path
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def run
|
|
55
|
+
public_send("run_#{@format}")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def run_diff
|
|
59
|
+
first = true
|
|
60
|
+
io = RBS::CLI::ColoredIO.new(stdout: @stdout)
|
|
61
|
+
@diff.each_diff do |before, after|
|
|
62
|
+
io.puts if !first
|
|
63
|
+
io.puts_red "- #{before}"
|
|
64
|
+
io.puts_green "+ #{after}"
|
|
65
|
+
first = false
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def run_markdown
|
|
70
|
+
@stdout.puts "| before | after |"
|
|
71
|
+
@stdout.puts "| --- | --- |"
|
|
72
|
+
@diff.each_diff do |before, after|
|
|
73
|
+
before.gsub!("|", "\\|")
|
|
74
|
+
after.gsub!("|", "\\|")
|
|
75
|
+
@stdout.puts "| `#{before}` | `#{after}` |"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
data/lib/rbs/cli.rb
CHANGED
|
@@ -8,6 +8,9 @@ require "stringio"
|
|
|
8
8
|
|
|
9
9
|
module RBS
|
|
10
10
|
class CLI
|
|
11
|
+
autoload :ColoredIO, 'rbs/cli/colored_io'
|
|
12
|
+
autoload :Diff, 'rbs/cli/diff'
|
|
13
|
+
|
|
11
14
|
class LibraryOptions
|
|
12
15
|
attr_accessor :core_root
|
|
13
16
|
attr_accessor :config_path
|
|
@@ -90,7 +93,7 @@ module RBS
|
|
|
90
93
|
@stderr = stderr
|
|
91
94
|
end
|
|
92
95
|
|
|
93
|
-
COMMANDS = [:ast, :annotate, :list, :ancestors, :methods, :method, :validate, :constant, :paths, :prototype, :vendor, :parse, :test, :collection, :subtract]
|
|
96
|
+
COMMANDS = [:ast, :annotate, :list, :ancestors, :methods, :method, :validate, :constant, :paths, :prototype, :vendor, :parse, :test, :collection, :subtract, :diff]
|
|
94
97
|
|
|
95
98
|
def parse_logging_options(opts)
|
|
96
99
|
opts.on("--log-level LEVEL", "Specify log level (defaults to `warn`)") do |level|
|
|
@@ -433,8 +436,9 @@ EOU
|
|
|
433
436
|
stdout.puts " accessibility: #{method.accessibility}"
|
|
434
437
|
stdout.puts " types:"
|
|
435
438
|
separator = " "
|
|
436
|
-
|
|
437
|
-
|
|
439
|
+
length_max = method.method_types.map { |type| type.to_s.length }.max or raise
|
|
440
|
+
method.method_types.each do |type|
|
|
441
|
+
stdout.puts format(" %s %-#{length_max}s at %s", separator, type, type.location)
|
|
438
442
|
separator = "|"
|
|
439
443
|
end
|
|
440
444
|
end
|
|
@@ -462,6 +466,30 @@ EOU
|
|
|
462
466
|
builder = DefinitionBuilder.new(env: env)
|
|
463
467
|
validator = Validator.new(env: env, resolver: Resolver::TypeNameResolver.new(env))
|
|
464
468
|
|
|
469
|
+
no_self_type_validator = ->(type) {
|
|
470
|
+
# @type var type: Types::t | MethodType
|
|
471
|
+
if type.has_self_type?
|
|
472
|
+
raise "#{type.location}: `self` type is not allowed in this context"
|
|
473
|
+
end
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
no_classish_type_validator = ->(type) {
|
|
477
|
+
# @type var type: Types::t | MethodType
|
|
478
|
+
if type.has_classish_type?
|
|
479
|
+
raise "#{type.location}: `instance` or `class` type is not allowed in this context"
|
|
480
|
+
end
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
void_type_context_validator = ->(type, allowed_here = false) {
|
|
484
|
+
# @type var type: Types::t | MethodType
|
|
485
|
+
if allowed_here
|
|
486
|
+
next if type.is_a?(Types::Bases::Void)
|
|
487
|
+
end
|
|
488
|
+
if type.with_nonreturn_void?
|
|
489
|
+
raise "#{type.location}: `void` type is only allowed in return type or generics parameter"
|
|
490
|
+
end
|
|
491
|
+
}
|
|
492
|
+
|
|
465
493
|
env.class_decls.each do |name, decl|
|
|
466
494
|
stdout.puts "Validating class/module definition: `#{name}`..."
|
|
467
495
|
builder.build_instance(name).each_type do |type|
|
|
@@ -471,6 +499,29 @@ EOU
|
|
|
471
499
|
validator.validate_type type, context: nil
|
|
472
500
|
end
|
|
473
501
|
|
|
502
|
+
case decl
|
|
503
|
+
when Environment::ClassEntry
|
|
504
|
+
decl.decls.each do |decl|
|
|
505
|
+
if super_class = decl.decl.super_class
|
|
506
|
+
super_class.args.each do |arg|
|
|
507
|
+
void_type_context_validator[arg, true]
|
|
508
|
+
no_self_type_validator[arg]
|
|
509
|
+
no_classish_type_validator[arg]
|
|
510
|
+
end
|
|
511
|
+
end
|
|
512
|
+
end
|
|
513
|
+
when Environment::ModuleEntry
|
|
514
|
+
decl.decls.each do |decl|
|
|
515
|
+
decl.decl.self_types.each do |self_type|
|
|
516
|
+
self_type.args.each do |arg|
|
|
517
|
+
void_type_context_validator[arg, true]
|
|
518
|
+
no_self_type_validator[arg]
|
|
519
|
+
no_classish_type_validator[arg]
|
|
520
|
+
end
|
|
521
|
+
end
|
|
522
|
+
end
|
|
523
|
+
end
|
|
524
|
+
|
|
474
525
|
d = decl.primary.decl
|
|
475
526
|
|
|
476
527
|
validator.validate_type_params(
|
|
@@ -479,11 +530,36 @@ EOU
|
|
|
479
530
|
location: d.location&.aref(:type_params)
|
|
480
531
|
)
|
|
481
532
|
|
|
533
|
+
d.type_params.each do |param|
|
|
534
|
+
if ub = param.upper_bound
|
|
535
|
+
void_type_context_validator[ub]
|
|
536
|
+
no_self_type_validator[ub]
|
|
537
|
+
no_classish_type_validator[ub]
|
|
538
|
+
end
|
|
539
|
+
end
|
|
540
|
+
|
|
482
541
|
decl.decls.each do |d|
|
|
483
542
|
d.decl.each_member do |member|
|
|
484
543
|
case member
|
|
485
544
|
when AST::Members::MethodDefinition
|
|
486
545
|
validator.validate_method_definition(member, type_name: name)
|
|
546
|
+
member.overloads.each do |ov|
|
|
547
|
+
void_type_context_validator[ov.method_type]
|
|
548
|
+
end
|
|
549
|
+
when AST::Members::Attribute
|
|
550
|
+
void_type_context_validator[member.type]
|
|
551
|
+
when AST::Members::Mixin
|
|
552
|
+
member.args.each do |arg|
|
|
553
|
+
no_self_type_validator[arg]
|
|
554
|
+
unless arg.is_a?(Types::Bases::Void)
|
|
555
|
+
void_type_context_validator[arg, true]
|
|
556
|
+
end
|
|
557
|
+
end
|
|
558
|
+
when AST::Members::Var
|
|
559
|
+
void_type_context_validator[member.type]
|
|
560
|
+
if member.is_a?(AST::Members::ClassVariable)
|
|
561
|
+
no_self_type_validator[member.type]
|
|
562
|
+
end
|
|
487
563
|
end
|
|
488
564
|
end
|
|
489
565
|
end
|
|
@@ -510,6 +586,10 @@ EOU
|
|
|
510
586
|
case member
|
|
511
587
|
when AST::Members::MethodDefinition
|
|
512
588
|
validator.validate_method_definition(member, type_name: name)
|
|
589
|
+
member.overloads.each do |ov|
|
|
590
|
+
void_type_context_validator[ov.method_type]
|
|
591
|
+
no_classish_type_validator[ov.method_type]
|
|
592
|
+
end
|
|
513
593
|
end
|
|
514
594
|
end
|
|
515
595
|
end
|
|
@@ -518,11 +598,17 @@ EOU
|
|
|
518
598
|
stdout.puts "Validating constant: `#{name}`..."
|
|
519
599
|
validator.validate_type const.decl.type, context: const.context
|
|
520
600
|
builder.ensure_namespace!(name.namespace, location: const.decl.location)
|
|
601
|
+
no_self_type_validator[const.decl.type]
|
|
602
|
+
no_classish_type_validator[const.decl.type]
|
|
603
|
+
void_type_context_validator[const.decl.type]
|
|
521
604
|
end
|
|
522
605
|
|
|
523
606
|
env.global_decls.each do |name, global|
|
|
524
607
|
stdout.puts "Validating global: `#{name}`..."
|
|
525
608
|
validator.validate_type global.decl.type, context: nil
|
|
609
|
+
no_self_type_validator[global.decl.type]
|
|
610
|
+
no_classish_type_validator[global.decl.type]
|
|
611
|
+
void_type_context_validator[global.decl.type]
|
|
526
612
|
end
|
|
527
613
|
|
|
528
614
|
env.type_alias_decls.each do |name, decl|
|
|
@@ -531,6 +617,9 @@ EOU
|
|
|
531
617
|
validator.validate_type type, context: nil
|
|
532
618
|
end
|
|
533
619
|
validator.validate_type_alias(entry: decl)
|
|
620
|
+
no_self_type_validator[decl.decl.type]
|
|
621
|
+
no_classish_type_validator[decl.decl.type]
|
|
622
|
+
void_type_context_validator[decl.decl.type]
|
|
534
623
|
end
|
|
535
624
|
end
|
|
536
625
|
|
|
@@ -644,8 +733,10 @@ EOU
|
|
|
644
733
|
require_libs = []
|
|
645
734
|
relative_libs = []
|
|
646
735
|
merge = false
|
|
736
|
+
todo = false
|
|
647
737
|
owners_included = []
|
|
648
738
|
outline = false
|
|
739
|
+
autoload = false
|
|
649
740
|
|
|
650
741
|
OptionParser.new do |opts|
|
|
651
742
|
opts.banner = <<EOU
|
|
@@ -671,26 +762,62 @@ EOU
|
|
|
671
762
|
opts.on("--merge", "Merge generated prototype RBS with existing RBS") do
|
|
672
763
|
merge = true
|
|
673
764
|
end
|
|
765
|
+
opts.on("--todo", "Generates only undefined methods compared to objects") do
|
|
766
|
+
Warning.warn("Geneating prototypes with `--todo` option is experimental\n", category: :experimental)
|
|
767
|
+
todo = true
|
|
768
|
+
end
|
|
674
769
|
opts.on("--method-owner CLASS", "Generate method prototypes if the owner of the method is [CLASS]") do |klass|
|
|
675
770
|
owners_included << klass
|
|
676
771
|
end
|
|
677
772
|
opts.on("--outline", "Generates only module/class/constant declaration (no method definition)") do
|
|
678
773
|
outline = true
|
|
679
774
|
end
|
|
775
|
+
opts.on("--autoload", "Load all autoload path") do
|
|
776
|
+
autoload = true
|
|
777
|
+
end
|
|
680
778
|
end.parse!(args)
|
|
681
779
|
|
|
682
780
|
loader = options.loader()
|
|
683
781
|
env = Environment.from_loader(loader).resolve_type_names
|
|
684
782
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
783
|
+
# @type var autoloader: ^() { () -> void } -> void
|
|
784
|
+
autoloader = ->(&block) {
|
|
785
|
+
if autoload
|
|
786
|
+
hook = Module.new do
|
|
787
|
+
def autoload(name, path)
|
|
788
|
+
super
|
|
789
|
+
end
|
|
790
|
+
end
|
|
791
|
+
::Module.prepend(hook)
|
|
792
|
+
::Kernel.prepend(hook)
|
|
793
|
+
|
|
794
|
+
arguments = []
|
|
795
|
+
TracePoint.new(:call) do |tp|
|
|
796
|
+
base = tp.self.kind_of?(Module) ? tp.self : Kernel
|
|
797
|
+
name = (tp.binding or raise).local_variable_get(:name)
|
|
798
|
+
arguments << [base, name]
|
|
799
|
+
end.enable(target: hook.instance_method(:autoload), &block)
|
|
800
|
+
|
|
801
|
+
arguments.each do |(base, name)|
|
|
802
|
+
begin
|
|
803
|
+
base.const_get(name)
|
|
804
|
+
rescue LoadError, StandardError
|
|
805
|
+
end
|
|
806
|
+
end
|
|
807
|
+
else
|
|
808
|
+
block.call
|
|
809
|
+
end
|
|
810
|
+
}
|
|
811
|
+
autoloader.call do
|
|
812
|
+
require_libs.each do |lib|
|
|
813
|
+
require(lib)
|
|
814
|
+
end
|
|
815
|
+
relative_libs.each do |lib|
|
|
816
|
+
eval("require_relative(lib)", binding, "rbs")
|
|
817
|
+
end
|
|
691
818
|
end
|
|
692
819
|
|
|
693
|
-
runtime = Prototype::Runtime.new(patterns: args, env: env, merge: merge, owners_included: owners_included)
|
|
820
|
+
runtime = Prototype::Runtime.new(patterns: args, env: env, merge: merge, todo: todo, owners_included: owners_included)
|
|
694
821
|
runtime.outline = outline
|
|
695
822
|
|
|
696
823
|
decls = runtime.decls
|
|
@@ -827,7 +954,12 @@ EOU
|
|
|
827
954
|
output_path = (output_dir + relative_path).sub_ext(".rbs")
|
|
828
955
|
|
|
829
956
|
parser = new_parser[]
|
|
830
|
-
|
|
957
|
+
begin
|
|
958
|
+
parser.parse file_path.read()
|
|
959
|
+
rescue SyntaxError
|
|
960
|
+
stdout.puts " ⚠️ Unable to parse due to SyntaxError: `#{file_path}`"
|
|
961
|
+
next
|
|
962
|
+
end
|
|
831
963
|
|
|
832
964
|
if output_path.file?
|
|
833
965
|
if force
|
|
@@ -1136,11 +1268,10 @@ EOB
|
|
|
1136
1268
|
# A directory to install the downloaded RBSs
|
|
1137
1269
|
path: .gem_rbs_collection
|
|
1138
1270
|
|
|
1139
|
-
gems:
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
ignore: true
|
|
1271
|
+
# gems:
|
|
1272
|
+
# # If you want to avoid installing rbs files for gems, you can specify them here.
|
|
1273
|
+
# - name: GEM_NAME
|
|
1274
|
+
# ignore: true
|
|
1144
1275
|
YAML
|
|
1145
1276
|
stdout.puts "created: #{config_path}"
|
|
1146
1277
|
when 'clean'
|
|
@@ -1259,5 +1390,9 @@ EOB
|
|
|
1259
1390
|
end
|
|
1260
1391
|
end
|
|
1261
1392
|
end
|
|
1393
|
+
|
|
1394
|
+
def run_diff(argv, library_options)
|
|
1395
|
+
Diff.new(argv: argv, library_options: library_options, stdout: stdout, stderr: stderr).run
|
|
1396
|
+
end
|
|
1262
1397
|
end
|
|
1263
1398
|
end
|
|
@@ -12,7 +12,6 @@ module RBS
|
|
|
12
12
|
@path = path
|
|
13
13
|
@gemfile_lock_path = gemfile_lock_path
|
|
14
14
|
|
|
15
|
-
@sources = {}
|
|
16
15
|
@gems = {}
|
|
17
16
|
end
|
|
18
17
|
|
|
@@ -26,27 +25,15 @@ module RBS
|
|
|
26
25
|
end
|
|
27
26
|
end
|
|
28
27
|
|
|
29
|
-
def each_source(&block)
|
|
30
|
-
if block
|
|
31
|
-
sources.each_value(&block)
|
|
32
|
-
yield Sources::Rubygems.instance
|
|
33
|
-
yield Sources::Stdlib.instance
|
|
34
|
-
else
|
|
35
|
-
enum_for :each_source
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
28
|
def to_lockfile
|
|
40
29
|
# @type var data: lockfile_data
|
|
41
30
|
|
|
42
31
|
data = {
|
|
43
|
-
"sources" => sources.each_value.sort_by {|s| s.name }.map {|source| source.to_lockfile },
|
|
44
32
|
"path" => path.to_s,
|
|
45
33
|
"gems" => gems.each_value.sort_by {|g| g[:name] }.map {|hash| library_data(hash) },
|
|
46
34
|
"gemfile_lock_path" => gemfile_lock_path.to_s
|
|
47
35
|
}
|
|
48
36
|
|
|
49
|
-
data.delete("sources") if sources.empty?
|
|
50
37
|
data.delete("gems") if gems.empty?
|
|
51
38
|
|
|
52
39
|
data
|
|
@@ -60,18 +47,6 @@ module RBS
|
|
|
60
47
|
|
|
61
48
|
lockfile = Lockfile.new(lockfile_path: lockfile_path, path: path, gemfile_lock_path: gemfile_lock_path)
|
|
62
49
|
|
|
63
|
-
if sources = data["sources"]
|
|
64
|
-
sources.each do |src|
|
|
65
|
-
git = Sources::Git.new(
|
|
66
|
-
name: src["name"],
|
|
67
|
-
revision: src["revision"],
|
|
68
|
-
remote: src["remote"],
|
|
69
|
-
repo_dir: src["repo_dir"]
|
|
70
|
-
)
|
|
71
|
-
lockfile.sources[git.name] = git
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
50
|
if gems = data["gems"]
|
|
76
51
|
gems.each do |gem|
|
|
77
52
|
src = gem["source"]
|
|
@@ -44,12 +44,6 @@ module RBS
|
|
|
44
44
|
path: config.repo_path_data,
|
|
45
45
|
gemfile_lock_path: definition.lockfile.relative_path_from(lockfile_dir)
|
|
46
46
|
)
|
|
47
|
-
config.sources.each do |source|
|
|
48
|
-
case source
|
|
49
|
-
when Sources::Git
|
|
50
|
-
lockfile.sources[source.name] = source
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
47
|
|
|
54
48
|
if with_lockfile && lockfile_path.file?
|
|
55
49
|
@existing_lockfile = Lockfile.from_lockfile(lockfile_path: lockfile_path, data: YAML.load_file(lockfile_path.to_s))
|
|
@@ -45,23 +45,25 @@ module RBS
|
|
|
45
45
|
|
|
46
46
|
gem_dir = dest.join(name, version)
|
|
47
47
|
|
|
48
|
+
colored_io = CLI::ColoredIO.new(stdout: stdout)
|
|
49
|
+
|
|
48
50
|
case
|
|
49
51
|
when gem_dir.symlink?
|
|
50
|
-
|
|
52
|
+
colored_io.puts_green("Updating to #{format_config_entry(name, version)} from a local source")
|
|
51
53
|
gem_dir.unlink
|
|
52
54
|
_install(dest: dest, name: name, version: version)
|
|
53
55
|
when gem_dir.directory?
|
|
54
56
|
prev = load_metadata(dir: gem_dir)
|
|
55
57
|
|
|
56
58
|
if prev == metadata_content(name: name, version: version)
|
|
57
|
-
|
|
59
|
+
colored_io.puts "Using #{format_config_entry(name, version)}"
|
|
58
60
|
else
|
|
59
|
-
|
|
61
|
+
colored_io.puts_green("Updating to #{format_config_entry(name, version)} from #{format_config_entry(prev["name"], prev["version"])}")
|
|
60
62
|
FileUtils.remove_entry_secure(gem_dir.to_s)
|
|
61
63
|
_install(dest: dest, name: name, version: version)
|
|
62
64
|
end
|
|
63
65
|
when !gem_dir.exist?
|
|
64
|
-
|
|
66
|
+
colored_io.puts_green("Installing #{format_config_entry(name, version)}")
|
|
65
67
|
_install(dest: dest, name: name, version: version)
|
|
66
68
|
else
|
|
67
69
|
raise
|
|
@@ -7,7 +7,7 @@ module RBS
|
|
|
7
7
|
include Base
|
|
8
8
|
|
|
9
9
|
attr_reader :path, :full_path
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
def initialize(path:, base_directory:)
|
|
12
12
|
# TODO: resolve relative path from dir of rbs_collection.yaml
|
|
13
13
|
@path = Pathname(path)
|
|
@@ -33,22 +33,24 @@ module RBS
|
|
|
33
33
|
from = @full_path.join(name, version)
|
|
34
34
|
gem_dir = dest.join(name, version)
|
|
35
35
|
|
|
36
|
+
colored_io = CLI::ColoredIO.new(stdout: stdout)
|
|
37
|
+
|
|
36
38
|
case
|
|
37
39
|
when gem_dir.symlink? && gem_dir.readlink == from
|
|
38
|
-
|
|
40
|
+
colored_io.puts "Using #{name}:#{version} (#{from})"
|
|
39
41
|
when gem_dir.symlink?
|
|
40
42
|
prev = gem_dir.readlink
|
|
41
43
|
gem_dir.unlink
|
|
42
44
|
_install(from, dest.join(name, version))
|
|
43
|
-
|
|
45
|
+
colored_io.puts_green("Updating #{name}:#{version} to #{from} from #{prev}")
|
|
44
46
|
when gem_dir.directory?
|
|
45
47
|
# TODO: Show version of git source
|
|
46
48
|
FileUtils.remove_entry_secure(gem_dir.to_s)
|
|
47
49
|
_install(from, dest.join(name, version))
|
|
48
|
-
|
|
50
|
+
colored_io.puts_green("Updating #{name}:#{version} from git source")
|
|
49
51
|
when !gem_dir.exist?
|
|
50
52
|
_install(from, dest.join(name, version))
|
|
51
|
-
|
|
53
|
+
colored_io.puts_green("Installing #{name}:#{version} (#{from})")
|
|
52
54
|
else
|
|
53
55
|
raise
|
|
54
56
|
end
|