rbs 3.2.2 → 3.3.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|