rbs 3.3.0.pre.2 → 3.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/Gemfile.lock +2 -2
- data/README.md +47 -0
- data/Steepfile +1 -2
- data/lib/rbs/cli.rb +7 -1
- data/lib/rbs/collection/config/lockfile_generator.rb +1 -1
- data/lib/rbs/collection.rb +0 -1
- data/lib/rbs/diff.rb +36 -18
- data/lib/rbs/prototype/runtime/value_object_generator.rb +3 -1
- data/lib/rbs/resolver/constant_resolver.rb +1 -1
- data/lib/rbs/types.rb +5 -1
- data/lib/rbs/version.rb +1 -1
- data/sig/diff.rbs +4 -1
- data/sig/prototype/runtime.rbs +19 -3
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5578e86c15b544b7609720ca682e2d27015777e0a337b31cf2e5635ad8f055bc
|
4
|
+
data.tar.gz: e29e44859fca53e8698b4eeade30b7b9d9e0f4d17766d9d2195d24b53dc20ecb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df94b11063185c3728d4590a6ca9bc46a5efd707956956f1a46cacb1c06f80e4fc4d1d92180700f6411b2a4903406f0ca328a726019895c1fdcd74deea3e3647
|
7
|
+
data.tar.gz: 534f7db84014b9c7030862248115cc6f263de3d7cd0d3e3349a416052c2ee0764b35925756362c0d0adc5da0330f2937c6ca0544be666b8dad8b86d5e117e36e
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,29 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 3.3.1 (2023-11-21)
|
6
|
+
|
7
|
+
### Library changes
|
8
|
+
|
9
|
+
* Allow to use RBS in symlinked tree ([#1624](https://github.com/ruby/rbs/pull/1624))
|
10
|
+
* Should escape if param name include not simple-word ([#1618](https://github.com/ruby/rbs/pull/1618))
|
11
|
+
|
12
|
+
#### rbs collection
|
13
|
+
|
14
|
+
* Load Bundler lazily ([#1612](https://github.com/ruby/rbs/pull/1612))
|
15
|
+
|
16
|
+
### Miscellaneous
|
17
|
+
|
18
|
+
* Stop using `bundle` command ([#1619](https://github.com/ruby/rbs/pull/1619))
|
19
|
+
|
20
|
+
## 3.3.0 (2023-11-09)
|
21
|
+
|
22
|
+
### Library changes
|
23
|
+
|
24
|
+
* Stop exiting with error when syntax error detected during validation ([#1603](https://github.com/ruby/rbs/pull/1603))
|
25
|
+
* [rbs diff] Load dependencies from manifest.yaml ([#1602](https://github.com/ruby/rbs/pull/1602))
|
26
|
+
* [rbs diff] Resolve constants name ([#1601](https://github.com/ruby/rbs/pull/1601))
|
27
|
+
|
5
28
|
## 3.3.0.pre.2 (2023-11-02)
|
6
29
|
|
7
30
|
### Signature updates
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rbs (3.3.
|
4
|
+
rbs (3.3.1)
|
5
5
|
abbrev
|
6
6
|
|
7
7
|
PATH
|
@@ -83,7 +83,7 @@ GEM
|
|
83
83
|
stackprof (0.2.25)
|
84
84
|
stringio (3.0.7)
|
85
85
|
strong_json (2.1.2)
|
86
|
-
tempfile (0.
|
86
|
+
tempfile (0.2.0)
|
87
87
|
test-unit (3.6.1)
|
88
88
|
power_assert
|
89
89
|
timeout (0.4.0)
|
data/README.md
CHANGED
@@ -77,6 +77,53 @@ $ rbs methods ::Object
|
|
77
77
|
$ rbs method Object then
|
78
78
|
```
|
79
79
|
|
80
|
+
An end user of `rbs` will probably find `rbs prototype` the most useful. This command generates boilerplate signature declarations for ruby files. For example, say you have written the below ruby script.
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
# person.rb
|
84
|
+
class Person
|
85
|
+
attr_reader :name
|
86
|
+
attr_reader :contacts
|
87
|
+
|
88
|
+
def initialize(name:)
|
89
|
+
@name = name
|
90
|
+
@contacts = []
|
91
|
+
end
|
92
|
+
|
93
|
+
def speak
|
94
|
+
"I'm #{@name} and I love Ruby!"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
```
|
98
|
+
|
99
|
+
Running prototype on the above will automatically generate
|
100
|
+
|
101
|
+
```
|
102
|
+
$ rbs prototype rb person.rb
|
103
|
+
class Person
|
104
|
+
@name: untyped
|
105
|
+
|
106
|
+
@contacts: untyped
|
107
|
+
|
108
|
+
attr_reader name: untyped
|
109
|
+
|
110
|
+
attr_reader contacts: untyped
|
111
|
+
|
112
|
+
def initialize: (name: untyped) -> void
|
113
|
+
|
114
|
+
def speak: () -> ::String
|
115
|
+
end
|
116
|
+
```
|
117
|
+
|
118
|
+
It prints signatures for all methods, classes, instance variables, and constants.
|
119
|
+
This is only a starting point, and you should edit the output to match your signature more accurately.
|
120
|
+
|
121
|
+
`rbs prototpe` offers three options.
|
122
|
+
|
123
|
+
- `rb` generates from just the available Ruby code
|
124
|
+
- `rbi` generates from Sorbet RBI
|
125
|
+
- `runtime` generates from runtime API
|
126
|
+
|
80
127
|
## Library
|
81
128
|
|
82
129
|
There are two important concepts, _environment_ and _definition_.
|
data/Steepfile
CHANGED
@@ -8,8 +8,7 @@ target :lib do
|
|
8
8
|
"lib/rbs/test.rb"
|
9
9
|
)
|
10
10
|
|
11
|
-
library "pathname", "json", "logger", "monitor", "tsort", "uri", 'dbm', 'pstore', 'singleton', 'shellwords', 'fileutils', 'find', 'digest', 'abbrev', 'prettyprint'
|
12
|
-
signature 'stdlib/yaml/0'
|
11
|
+
library "pathname", "json", "logger", "monitor", "tsort", "uri", 'dbm', 'pstore', 'singleton', 'shellwords', 'fileutils', 'find', 'digest', 'abbrev', 'prettyprint', 'yaml'
|
13
12
|
signature "stdlib/strscan/0/"
|
14
13
|
signature "stdlib/optparse/0/"
|
15
14
|
signature "stdlib/rdoc/0/"
|
data/lib/rbs/cli.rb
CHANGED
@@ -445,6 +445,7 @@ EOU
|
|
445
445
|
|
446
446
|
def run_validate(args, options)
|
447
447
|
stdout = stdout()
|
448
|
+
exit_error = false
|
448
449
|
|
449
450
|
OptionParser.new do |opts|
|
450
451
|
opts.banner = <<EOU
|
@@ -460,6 +461,9 @@ EOU
|
|
460
461
|
opts.on("--silent") do
|
461
462
|
stdout = StringIO.new
|
462
463
|
end
|
464
|
+
opts.on("--[no-]exit-error-on-syntax-error", "exit(1) if syntax error is detected") {|bool|
|
465
|
+
exit_error = bool
|
466
|
+
}
|
463
467
|
end.parse!(args)
|
464
468
|
|
465
469
|
loader = options.loader()
|
@@ -632,7 +636,7 @@ EOU
|
|
632
636
|
syntax_errors.each do |message|
|
633
637
|
self.stdout.puts message
|
634
638
|
end
|
635
|
-
exit
|
639
|
+
exit 1 if exit_error
|
636
640
|
end
|
637
641
|
end
|
638
642
|
|
@@ -1242,6 +1246,8 @@ EOB
|
|
1242
1246
|
end
|
1243
1247
|
|
1244
1248
|
def run_collection(args, options)
|
1249
|
+
require 'bundler'
|
1250
|
+
|
1245
1251
|
opts = collection_options(args)
|
1246
1252
|
params = {}
|
1247
1253
|
opts.order args.drop(1), into: params
|
@@ -83,7 +83,7 @@ module RBS
|
|
83
83
|
private def validate_gemfile_lock_path!(lock:, gemfile_lock_path:)
|
84
84
|
return unless lock
|
85
85
|
return unless lock.gemfile_lock_fullpath
|
86
|
-
unless lock.gemfile_lock_fullpath == gemfile_lock_path
|
86
|
+
unless File.realpath(lock.gemfile_lock_fullpath) == File.realpath(gemfile_lock_path)
|
87
87
|
raise GemfileLockMismatchError.new(expected: lock.gemfile_lock_fullpath, actual: gemfile_lock_path)
|
88
88
|
end
|
89
89
|
end
|
data/lib/rbs/collection.rb
CHANGED
data/lib/rbs/diff.rb
CHANGED
@@ -12,13 +12,13 @@ module RBS
|
|
12
12
|
def each_diff(&block)
|
13
13
|
return to_enum(:each_diff) unless block
|
14
14
|
|
15
|
-
before_instance_methods, before_singleton_methods,
|
16
|
-
after_instance_methods, after_singleton_methods,
|
15
|
+
before_instance_methods, before_singleton_methods, before_constant_children = build_methods(@before_path)
|
16
|
+
after_instance_methods, after_singleton_methods, after_constant_children = build_methods(@after_path)
|
17
17
|
|
18
18
|
each_diff_methods(:instance, before_instance_methods, after_instance_methods, &block)
|
19
19
|
each_diff_methods(:singleton, before_singleton_methods, after_singleton_methods, &block)
|
20
20
|
|
21
|
-
each_diff_constants(
|
21
|
+
each_diff_constants(before_constant_children, after_constant_children, &block)
|
22
22
|
end
|
23
23
|
|
24
24
|
private
|
@@ -34,11 +34,11 @@ module RBS
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
def each_diff_constants(
|
38
|
-
all_keys =
|
37
|
+
def each_diff_constants(before_constant_children, after_constant_children)
|
38
|
+
all_keys = before_constant_children.keys.to_set + after_constant_children.keys.to_set
|
39
39
|
all_keys.each do |key|
|
40
|
-
before = constant_to_s(
|
41
|
-
after = constant_to_s(
|
40
|
+
before = constant_to_s(before_constant_children[key]) or next
|
41
|
+
after = constant_to_s(after_constant_children[key]) or next
|
42
42
|
next if before == after
|
43
43
|
|
44
44
|
yield before, after
|
@@ -52,25 +52,42 @@ module RBS
|
|
52
52
|
instance_methods = begin
|
53
53
|
builder.build_instance(@type_name).methods
|
54
54
|
rescue => e
|
55
|
-
RBS.logger.warn("#{path}: #{e.message}")
|
56
|
-
{}
|
55
|
+
RBS.logger.warn("#{path}: (#{e.class}) #{e.message}")
|
56
|
+
{} #: Hash[Symbol, Definition::Method]
|
57
57
|
end
|
58
58
|
singleton_methods = begin
|
59
59
|
builder.build_singleton(@type_name).methods
|
60
60
|
rescue => e
|
61
|
-
RBS.logger.warn("#{path}: #{e.message}")
|
62
|
-
{}
|
61
|
+
RBS.logger.warn("#{path}: (#{e.class}) #{e.message}")
|
62
|
+
{} #: Hash[Symbol, Definition::Method]
|
63
63
|
end
|
64
|
-
type_name_to_s = @type_name.to_s
|
65
|
-
constant_decls = env.constant_decls.select { |key| key.to_s.start_with?(type_name_to_s) }
|
66
64
|
|
67
|
-
|
65
|
+
constant_children = begin
|
66
|
+
constant_resolver = RBS::Resolver::ConstantResolver.new(builder: builder)
|
67
|
+
constant_resolver.children(@type_name)
|
68
|
+
rescue => e
|
69
|
+
RBS.logger.warn("#{path}: (#{e.class}) #{e.message}")
|
70
|
+
{} #: Hash[Symbol, Constant]
|
71
|
+
end
|
72
|
+
|
73
|
+
[ instance_methods, singleton_methods, constant_children ]
|
68
74
|
end
|
69
75
|
|
70
76
|
def build_env(path)
|
71
77
|
loader = @library_options.loader()
|
72
78
|
path&.each do |dir|
|
73
|
-
|
79
|
+
dir_pathname = Pathname(dir)
|
80
|
+
loader.add(path: dir_pathname)
|
81
|
+
|
82
|
+
manifest_pathname = dir_pathname / 'manifest.yaml'
|
83
|
+
if manifest_pathname.exist?
|
84
|
+
manifest = YAML.safe_load(manifest_pathname.read)
|
85
|
+
if manifest['dependencies']
|
86
|
+
manifest['dependencies'].each do |dependency|
|
87
|
+
loader.add(library: dependency['name'], version: nil)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
74
91
|
end
|
75
92
|
Environment.from_loader(loader)
|
76
93
|
end
|
@@ -84,7 +101,8 @@ module RBS
|
|
84
101
|
prefix = kind == :instance ? "" : "self."
|
85
102
|
|
86
103
|
if definition_method.alias_of
|
87
|
-
|
104
|
+
first_def = definition_method.alias_of.defs.first #: Definition::Method::TypeDef
|
105
|
+
"alias #{prefix}#{key} #{prefix}#{first_def.member.name}"
|
88
106
|
else
|
89
107
|
"def #{prefix}#{key}: #{definition_method.method_types.join(" | ")}"
|
90
108
|
end
|
@@ -93,9 +111,9 @@ module RBS
|
|
93
111
|
end
|
94
112
|
end
|
95
113
|
|
96
|
-
def constant_to_s(
|
114
|
+
def constant_to_s(constant)
|
97
115
|
if constant
|
98
|
-
"#{
|
116
|
+
"#{constant.name.name}: #{constant.type}"
|
99
117
|
else
|
100
118
|
+"-"
|
101
119
|
end
|
@@ -33,7 +33,9 @@ module RBS
|
|
33
33
|
# def self.members: () -> [ :foo, :bar ]
|
34
34
|
# def members: () -> [ :foo, :bar ]
|
35
35
|
def build_s_members
|
36
|
-
|
36
|
+
(
|
37
|
+
[:singleton, :instance] #: Array[AST::Members::MethodDefinition::kind]
|
38
|
+
).map do |kind|
|
37
39
|
AST::Members::MethodDefinition.new(
|
38
40
|
name: :members,
|
39
41
|
overloads: [
|
data/lib/rbs/types.rb
CHANGED
data/lib/rbs/version.rb
CHANGED
data/sig/diff.rbs
CHANGED
@@ -15,9 +15,12 @@ module RBS
|
|
15
15
|
def each_diff: () { (String before, String after) -> void } -> void
|
16
16
|
|
17
17
|
private def each_diff_by: (Symbol kind, Hash[::Symbol, Definition::Method] before_methods, Hash[::Symbol, Definition::Method] after_methods) { (String before, String after) -> void } -> void
|
18
|
-
private def build_methods: (Array[String] path) -> [ Hash[::Symbol, Definition::Method], Hash[::Symbol, Definition::Method] ]
|
18
|
+
private def build_methods: (Array[String] path) -> [ Hash[::Symbol, Definition::Method], Hash[::Symbol, Definition::Method] , Hash[Symbol, Constant]]
|
19
19
|
private def build_env: (Array[String] path) -> Environment
|
20
20
|
private def build_builder: (Environment env) -> DefinitionBuilder
|
21
21
|
private def definition_method_to_s: (Symbol key, Symbol kind, Definition::Method definition_method) -> String?
|
22
|
+
private def each_diff_methods: (Symbol kind, Hash[Symbol, Definition::Method], Hash[Symbol, Definition::Method]) { (String before, String after) -> void } -> void
|
23
|
+
private def each_diff_constants: (Hash[Symbol, Constant] before_constants, Hash[Symbol, Constant] after_constants) { (String before, String after) -> void } -> void
|
24
|
+
private def constant_to_s: (Constant?) -> String
|
22
25
|
end
|
23
26
|
end
|
data/sig/prototype/runtime.rbs
CHANGED
@@ -2,12 +2,17 @@ module RBS
|
|
2
2
|
module Prototype
|
3
3
|
class Runtime
|
4
4
|
module Reflection
|
5
|
+
self.@object_class: UnboundMethod
|
5
6
|
def self.object_class: (Module value) -> Class
|
6
7
|
|
8
|
+
self.@constants_of: UnboundMethod
|
7
9
|
def self.constants_of: (Module mod, ?bool inherit) -> Array[Symbol]
|
8
10
|
end
|
9
11
|
|
10
12
|
module Helpers
|
13
|
+
@module_name_method: UnboundMethod
|
14
|
+
@untyped: Types::Bases::Any
|
15
|
+
|
11
16
|
private
|
12
17
|
|
13
18
|
def const_name: (Module const) -> String?
|
@@ -19,12 +24,15 @@ module RBS
|
|
19
24
|
|
20
25
|
def to_type_name: (String name, ?full_name: bool) -> TypeName
|
21
26
|
|
22
|
-
def untyped: () ->
|
27
|
+
def untyped: () -> Types::Bases::Any
|
23
28
|
end
|
24
29
|
|
25
30
|
class ValueObjectBase
|
26
31
|
include Helpers
|
27
32
|
|
33
|
+
# @target_class stores the singleton object of `Data` or `Struct` subclass
|
34
|
+
@target_class: untyped
|
35
|
+
|
28
36
|
def build_decl: () -> AST::Declarations::Class
|
29
37
|
|
30
38
|
private
|
@@ -33,6 +41,10 @@ module RBS
|
|
33
41
|
|
34
42
|
def build_s_members: () -> Array[AST::Members::MethodDefinition]
|
35
43
|
|
44
|
+
def build_super_class: () -> AST::Declarations::Class::Super
|
45
|
+
|
46
|
+
def add_decl_members: (AST::Declarations::Class) -> void
|
47
|
+
|
36
48
|
def initialize: (Class target_class) -> void
|
37
49
|
end
|
38
50
|
|
@@ -77,9 +89,9 @@ module RBS
|
|
77
89
|
|
78
90
|
def skip_mixin?: (type_name: TypeName, module_name: TypeName, mixin_class: mixin_class) -> bool
|
79
91
|
|
80
|
-
def skip_singleton_method?: (module_name: TypeName,
|
92
|
+
def skip_singleton_method?: (module_name: TypeName, method: UnboundMethod, accessibility: Definition::accessibility) -> bool
|
81
93
|
|
82
|
-
def skip_instance_method?: (module_name: TypeName,
|
94
|
+
def skip_instance_method?: (module_name: TypeName, method: UnboundMethod, accessibility: Definition::accessibility) -> bool
|
83
95
|
|
84
96
|
def skip_constant?: (module_name: String, name: Symbol) -> bool
|
85
97
|
|
@@ -147,6 +159,8 @@ module RBS
|
|
147
159
|
|
148
160
|
def generate_module: (Module mod) -> void
|
149
161
|
|
162
|
+
def generate_mixin: (Module mod, AST::Declarations::Class | AST::Declarations::Module, TypeName, TypeName) -> void
|
163
|
+
|
150
164
|
# Generate/find outer module declarations
|
151
165
|
# This is broken down into another method to comply with `DRY`
|
152
166
|
# This generates/finds declarations in nested form & returns the last array of declarations
|
@@ -158,6 +172,8 @@ module RBS
|
|
158
172
|
|
159
173
|
def block_from_ast_of: (UnboundMethod method) -> Types::Block?
|
160
174
|
|
175
|
+
def block_from_body: (RubyVM::AbstractSyntaxTree::Node) -> Types::Block?
|
176
|
+
|
161
177
|
def can_alias?: (Module, UnboundMethod) -> bool
|
162
178
|
|
163
179
|
def type_params: (Module) -> Array[AST::TypeParam]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.3.
|
4
|
+
version: 3.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Soutaro Matsumoto
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-11-
|
11
|
+
date: 2023-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: abbrev
|
@@ -505,9 +505,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
505
505
|
version: '3.0'
|
506
506
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
507
507
|
requirements:
|
508
|
-
- - "
|
508
|
+
- - ">="
|
509
509
|
- !ruby/object:Gem::Version
|
510
|
-
version:
|
510
|
+
version: '0'
|
511
511
|
requirements: []
|
512
512
|
rubygems_version: 3.4.10
|
513
513
|
signing_key:
|