rbs 1.3.3 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +10 -0
- data/CHANGELOG.md +69 -0
- data/Gemfile +2 -0
- data/Rakefile +4 -0
- data/Steepfile +9 -1
- data/core/array.rbs +8 -7
- data/core/builtin.rbs +1 -1
- data/core/enumerable.rbs +11 -10
- data/core/enumerator.rbs +2 -2
- data/core/exception.rbs +1 -0
- data/core/false_class.rbs +4 -4
- data/core/file.rbs +3 -1
- data/core/float.rbs +1 -1
- data/core/global_variables.rbs +180 -0
- data/core/hash.rbs +7 -7
- data/core/integer.rbs +1 -2
- data/core/io/wait.rbs +37 -0
- data/core/io.rbs +11 -5
- data/core/kernel.rbs +25 -2
- data/core/object.rbs +1 -1
- data/core/ractor.rbs +779 -0
- data/core/range.rbs +11 -9
- data/core/string_io.rbs +3 -5
- data/core/true_class.rbs +4 -4
- data/docs/collection.md +116 -0
- data/lib/rbs/builtin_names.rb +1 -0
- data/lib/rbs/cli.rb +94 -2
- data/lib/rbs/collection/cleaner.rb +29 -0
- data/lib/rbs/collection/config/lockfile_generator.rb +95 -0
- data/lib/rbs/collection/config.rb +85 -0
- data/lib/rbs/collection/installer.rb +27 -0
- data/lib/rbs/collection/sources/git.rb +147 -0
- data/lib/rbs/collection/sources/rubygems.rb +40 -0
- data/lib/rbs/collection/sources/stdlib.rb +38 -0
- data/lib/rbs/collection/sources.rb +22 -0
- data/lib/rbs/collection.rb +13 -0
- data/lib/rbs/environment_loader.rb +12 -0
- data/lib/rbs/errors.rb +18 -0
- data/lib/rbs/parser.rb +1 -1
- data/lib/rbs/parser.y +1 -1
- data/lib/rbs/prototype/rb.rb +8 -1
- data/lib/rbs/prototype/runtime.rb +1 -1
- data/lib/rbs/repository.rb +13 -7
- data/lib/rbs/type_alias_dependency.rb +88 -0
- data/lib/rbs/validator.rb +8 -0
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs.rb +2 -0
- data/sig/builtin_names.rbs +1 -0
- data/sig/cli.rbs +5 -0
- data/sig/collection/cleaner.rbs +13 -0
- data/sig/collection/collections.rbs +112 -0
- data/sig/collection/config.rbs +69 -0
- data/sig/collection/installer.rbs +15 -0
- data/sig/collection.rbs +4 -0
- data/sig/environment_loader.rbs +3 -0
- data/sig/errors.rbs +9 -0
- data/sig/polyfill.rbs +12 -3
- data/sig/repository.rbs +4 -0
- data/sig/type_alias_dependency.rbs +22 -0
- data/sig/validator.rbs +2 -0
- data/stdlib/digest/0/digest.rbs +418 -0
- data/stdlib/objspace/0/objspace.rbs +406 -0
- data/stdlib/openssl/0/openssl.rbs +3711 -0
- data/stdlib/pathname/0/pathname.rbs +2 -2
- data/stdlib/rubygems/0/rubygems.rbs +1 -1
- data/stdlib/securerandom/0/securerandom.rbs +3 -1
- data/stdlib/tempfile/0/tempfile.rbs +270 -0
- data/stdlib/uri/0/generic.rbs +3 -3
- data/steep/Gemfile.lock +10 -10
- metadata +28 -3
data/lib/rbs/prototype/rb.rb
CHANGED
@@ -319,9 +319,16 @@ module RBS
|
|
319
319
|
const_to_name(node.children[0])
|
320
320
|
end
|
321
321
|
|
322
|
+
value_node = node.children.last
|
323
|
+
type = if value_node.nil?
|
324
|
+
# Give up type prediction when node is MASGN.
|
325
|
+
Types::Bases::Any.new(location: nil)
|
326
|
+
else
|
327
|
+
node_type(value_node)
|
328
|
+
end
|
322
329
|
decls << AST::Declarations::Constant.new(
|
323
330
|
name: const_name,
|
324
|
-
type:
|
331
|
+
type: type,
|
325
332
|
location: nil,
|
326
333
|
comment: comments[node.first_lineno - 1]
|
327
334
|
)
|
@@ -87,7 +87,7 @@ module RBS
|
|
87
87
|
unless const_name(mix)
|
88
88
|
RBS.logger.warn("Skipping anonymous module #{mix} included in #{mod}")
|
89
89
|
else
|
90
|
-
module_name = module_full_name = to_type_name(const_name(mix))
|
90
|
+
module_name = module_full_name = to_type_name(const_name(mix), full_name: true)
|
91
91
|
if module_full_name.namespace == type_name.namespace
|
92
92
|
module_name = TypeName.new(name: module_full_name.name, namespace: Namespace.empty)
|
93
93
|
end
|
data/lib/rbs/repository.rb
CHANGED
@@ -55,13 +55,8 @@ module RBS
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def find_best_version(version)
|
58
|
-
|
59
|
-
|
60
|
-
if v = version_names.reverse.bsearch {|v| v <= version ? true : false }
|
61
|
-
versions[v]
|
62
|
-
else
|
63
|
-
oldest_version
|
64
|
-
end
|
58
|
+
best_version = Repository.find_best_version(version, version_names)
|
59
|
+
versions[best_version]
|
65
60
|
end
|
66
61
|
|
67
62
|
def empty?
|
@@ -89,6 +84,17 @@ module RBS
|
|
89
84
|
end
|
90
85
|
end
|
91
86
|
|
87
|
+
def self.find_best_version(version, candidates)
|
88
|
+
candidates = candidates.sort
|
89
|
+
return candidates.last || raise unless version
|
90
|
+
|
91
|
+
if v = candidates.reverse.bsearch {|v| v <= version ? true : false }
|
92
|
+
v
|
93
|
+
else
|
94
|
+
candidates.first or raise
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
92
98
|
def add(dir)
|
93
99
|
dirs << dir
|
94
100
|
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module RBS
|
2
|
+
class TypeAliasDependency
|
3
|
+
attr_reader :env
|
4
|
+
|
5
|
+
# Direct dependencies corresponds to a directed graph
|
6
|
+
# with vertices as types and directions based on assignment of types
|
7
|
+
attr_reader :direct_dependencies
|
8
|
+
# A hash which stores the transitive closure
|
9
|
+
# of the directed graph
|
10
|
+
attr_reader :dependencies
|
11
|
+
|
12
|
+
def initialize(env:)
|
13
|
+
@env = env
|
14
|
+
end
|
15
|
+
|
16
|
+
# Check if an alias type definition is circular & prohibited
|
17
|
+
def circular_definition?(alias_name)
|
18
|
+
# Construct transitive closure, if not constructed already
|
19
|
+
transitive_closure() unless @dependencies
|
20
|
+
|
21
|
+
# Check for recursive type alias
|
22
|
+
@dependencies[alias_name][alias_name]
|
23
|
+
end
|
24
|
+
|
25
|
+
def build_dependencies
|
26
|
+
return if @direct_dependencies
|
27
|
+
|
28
|
+
# Initialize hash(a directed graph)
|
29
|
+
@direct_dependencies = {}
|
30
|
+
# Initialize dependencies as an empty hash
|
31
|
+
@dependencies = {}
|
32
|
+
# Iterate over alias declarations inserted into environment
|
33
|
+
env.alias_decls.each do |name, entry|
|
34
|
+
# Construct a directed graph by recursively extracting type aliases
|
35
|
+
@direct_dependencies[name] = direct_dependency(entry.decl.type)
|
36
|
+
# Initialize dependencies with an empty hash
|
37
|
+
@dependencies[name] = {}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def transitive_closure
|
42
|
+
# Construct a graph of direct dependencies
|
43
|
+
build_dependencies()
|
44
|
+
# Construct transitive closure by using DFS(recursive technique)
|
45
|
+
@direct_dependencies.each_key do |name|
|
46
|
+
dependency(name, name)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# Constructs directed graph recursively
|
53
|
+
def direct_dependency(type, result = Set[])
|
54
|
+
case type
|
55
|
+
when RBS::Types::Union, RBS::Types::Intersection, RBS::Types::Optional
|
56
|
+
# Iterate over nested types & extract type aliases recursively
|
57
|
+
type.each_type do |nested_type|
|
58
|
+
direct_dependency(nested_type, result)
|
59
|
+
end
|
60
|
+
when RBS::Types::Alias
|
61
|
+
# Append type name if the type is an alias
|
62
|
+
result << type.name
|
63
|
+
end
|
64
|
+
|
65
|
+
result
|
66
|
+
end
|
67
|
+
|
68
|
+
# Recursive function to construct transitive closure
|
69
|
+
def dependency(start, vertex, nested = nil)
|
70
|
+
if (start == vertex)
|
71
|
+
if (@direct_dependencies[start].include?(vertex) || nested)
|
72
|
+
# Mark a vertex as connected to itself
|
73
|
+
# if it is connected as an edge || a path(traverse multiple edges)
|
74
|
+
@dependencies[start][vertex] = true
|
75
|
+
end
|
76
|
+
else
|
77
|
+
# Mark a pair of vertices as connected while recursively performing DFS
|
78
|
+
@dependencies[start][vertex] = true
|
79
|
+
end
|
80
|
+
|
81
|
+
# Iterate over the direct dependencies of the vertex
|
82
|
+
@direct_dependencies[vertex]&.each do |type_name|
|
83
|
+
# Invoke the function unless it is already checked
|
84
|
+
dependency(start, type_name, start == type_name) unless @dependencies[start][type_name]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/rbs/validator.rb
CHANGED
@@ -53,5 +53,13 @@ module RBS
|
|
53
53
|
validate_type(type, context: context)
|
54
54
|
end
|
55
55
|
end
|
56
|
+
|
57
|
+
def validate_type_alias(entry:)
|
58
|
+
@type_alias_dependency ||= TypeAliasDependency.new(env: env)
|
59
|
+
if @type_alias_dependency.circular_definition?(entry.decl.name)
|
60
|
+
location = entry.decl.location or raise
|
61
|
+
raise RecursiveTypeAliasError.new(alias_names: [entry.decl.name], location: location)
|
62
|
+
end
|
63
|
+
end
|
56
64
|
end
|
57
65
|
end
|
data/lib/rbs/version.rb
CHANGED
data/lib/rbs.rb
CHANGED
data/sig/builtin_names.rbs
CHANGED
data/sig/cli.rbs
CHANGED
@@ -2,6 +2,7 @@ module RBS
|
|
2
2
|
class CLI
|
3
3
|
class LibraryOptions
|
4
4
|
attr_accessor core_root: Pathname?
|
5
|
+
attr_accessor config_path: Pathname?
|
5
6
|
|
6
7
|
attr_reader libs: Array[String]
|
7
8
|
attr_reader dirs: Array[String]
|
@@ -63,6 +64,10 @@ module RBS
|
|
63
64
|
|
64
65
|
def run_test: (Array[String], LibraryOptions) -> void
|
65
66
|
|
67
|
+
def run_collection: (Array[String], LibraryOptions) -> void
|
68
|
+
|
66
69
|
def test_opt: (LibraryOptions) -> String?
|
70
|
+
|
71
|
+
def collection_options: (Array[String]) -> OptionParser
|
67
72
|
end
|
68
73
|
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module RBS
|
2
|
+
module Collection
|
3
|
+
module Sources
|
4
|
+
def self.from_config_entry: (source_entry) -> _Source
|
5
|
+
|
6
|
+
interface _Source
|
7
|
+
def has?: (Config::gem_entry) -> boolish
|
8
|
+
def versions: (Config::gem_entry) -> Array[String]
|
9
|
+
def install: (dest: Pathname, config_entry: Config::gem_entry, stdout: CLI::_IO) -> void
|
10
|
+
def to_lockfile: () -> source_entry
|
11
|
+
end
|
12
|
+
|
13
|
+
type source_entry = Git::source_entry
|
14
|
+
| Stdlib::source_entry
|
15
|
+
| Rubygems::source_entry
|
16
|
+
|
17
|
+
class Git
|
18
|
+
METADATA_FILENAME: String
|
19
|
+
|
20
|
+
type source_entry = {
|
21
|
+
'type' => 'git',
|
22
|
+
'name' => String,
|
23
|
+
'remote' => String,
|
24
|
+
'revision' => String,
|
25
|
+
'repo_dir' => String?,
|
26
|
+
}
|
27
|
+
|
28
|
+
class CommandError < StandardError
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_reader name: String
|
32
|
+
attr_reader remote: String
|
33
|
+
attr_reader repo_dir: String
|
34
|
+
|
35
|
+
def initialize: (name: String, revision: String, remote: String, repo_dir: String?) -> untyped
|
36
|
+
|
37
|
+
def has?: (Config::gem_entry) -> bool
|
38
|
+
|
39
|
+
def versions: (Config::gem_entry) -> Array[String]
|
40
|
+
|
41
|
+
def install: (dest: Pathname, config_entry: Config::gem_entry, stdout: CLI::_IO) -> void
|
42
|
+
|
43
|
+
def to_lockfile: () -> source_entry
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def _install: (dest: Pathname , config_entry: Config::gem_entry) -> void
|
48
|
+
|
49
|
+
def setup!: (revision: String) -> void
|
50
|
+
|
51
|
+
def need_to_fetch?: (String revision ) -> bool
|
52
|
+
|
53
|
+
def git_dir: () -> Pathname
|
54
|
+
|
55
|
+
def gem_repo_dir: () -> Pathname
|
56
|
+
|
57
|
+
def with_revision: [T] () { () -> T } -> T
|
58
|
+
|
59
|
+
def resolved_revision: () -> String
|
60
|
+
|
61
|
+
def resolve_revision: () -> String
|
62
|
+
|
63
|
+
def git: (*String cmd) -> String
|
64
|
+
|
65
|
+
def sh!: (*String cmd) -> String
|
66
|
+
|
67
|
+
def format_config_entry: (Config::gem_entry) -> String
|
68
|
+
end
|
69
|
+
|
70
|
+
# signatures that are bundled in rbs gem under the stdlib/ directory
|
71
|
+
class Stdlib
|
72
|
+
type source_entry = {
|
73
|
+
'type' => 'stdlib',
|
74
|
+
}
|
75
|
+
|
76
|
+
# polyfill of singleton module
|
77
|
+
def self.instance: () -> instance
|
78
|
+
|
79
|
+
def has?: (Config::gem_entry) -> bool
|
80
|
+
|
81
|
+
def versions: (Config::gem_entry) -> Array[String]
|
82
|
+
|
83
|
+
def install: (dest: Pathname, config_entry: Config::gem_entry, stdout: CLI::_IO) -> void
|
84
|
+
|
85
|
+
def to_lockfile: () -> source_entry
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def gem_dir: (Config::gem_entry) -> Pathname
|
90
|
+
end
|
91
|
+
|
92
|
+
# sig/ directory
|
93
|
+
class Rubygems
|
94
|
+
type source_entry = {
|
95
|
+
'type' => 'rubygems',
|
96
|
+
}
|
97
|
+
|
98
|
+
# polyfill of singleton module
|
99
|
+
def self.instance: () -> instance
|
100
|
+
|
101
|
+
def has?: (Config::gem_entry) -> boolish
|
102
|
+
def versions: (Config::gem_entry) -> Array[String]
|
103
|
+
def install: (dest: Pathname, config_entry: Config::gem_entry, stdout: CLI::_IO) -> void
|
104
|
+
def to_lockfile: () -> source_entry
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def gem_sig_path: (Config::gem_entry) -> [Gem::Specification, Pathname]?
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module RBS
|
2
|
+
module Collection
|
3
|
+
# This class represent the configration file.
|
4
|
+
class Config
|
5
|
+
class LockfileGenerator
|
6
|
+
attr_reader config: Config
|
7
|
+
attr_reader lock: Config?
|
8
|
+
attr_reader lock_path: Pathname
|
9
|
+
attr_reader gemfile_lock: Bundler::LockfileParser
|
10
|
+
|
11
|
+
def self.generate: (config_path: Pathname, gemfile_lock_path: Pathname, ?with_lockfile: boolish) -> Config
|
12
|
+
|
13
|
+
def initialize: (config_path: Pathname, gemfile_lock_path: Pathname, with_lockfile: boolish) -> void
|
14
|
+
|
15
|
+
def generate: () -> Config
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def assign_gem: (gem_name: String, version: String?) -> void
|
20
|
+
|
21
|
+
def upsert_gem: (gem_entry? old, gem_entry new) -> void
|
22
|
+
|
23
|
+
def gemfile_lock_gems: () { (untyped) -> void } -> void
|
24
|
+
|
25
|
+
def remove_ignored_gems!: () -> void
|
26
|
+
|
27
|
+
def find_source: (gem_name: String) -> untyped
|
28
|
+
|
29
|
+
def find_best_version: (version: String?, versions: Array[String]) -> Gem::Version
|
30
|
+
end
|
31
|
+
|
32
|
+
PATH: Pathname
|
33
|
+
|
34
|
+
type gem_entry = {
|
35
|
+
'name' => String,
|
36
|
+
'version' => String?,
|
37
|
+
'ignore' => boolish,
|
38
|
+
'source' => Sources::source_entry?
|
39
|
+
}
|
40
|
+
|
41
|
+
@config_path: Pathname
|
42
|
+
|
43
|
+
def self.generate_lockfile: (config_path: Pathname, gemfile_lock_path: Pathname, ?with_lockfile: boolish) -> Config
|
44
|
+
|
45
|
+
def self.from_path: (Pathname path) -> Config
|
46
|
+
|
47
|
+
def self.lockfile_of: (Pathname config_path) -> Config?
|
48
|
+
|
49
|
+
def self.to_lockfile_path: (Pathname config_path) -> Pathname
|
50
|
+
|
51
|
+
# config_path is necessary to resolve relative repo_path
|
52
|
+
def initialize: (untyped data, config_path: Pathname) -> void
|
53
|
+
|
54
|
+
def add_gem: (untyped gem) -> untyped
|
55
|
+
|
56
|
+
def gem: (String gem_name) -> untyped
|
57
|
+
|
58
|
+
def repo_path: () -> Pathname
|
59
|
+
|
60
|
+
def sources: () -> Array[Sources::_Source]
|
61
|
+
|
62
|
+
def dump_to: (Pathname) -> void
|
63
|
+
|
64
|
+
def gems: () -> Array[untyped]
|
65
|
+
|
66
|
+
def check_rbs_availability!: () -> void
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module RBS
|
2
|
+
module Collection
|
3
|
+
class Installer
|
4
|
+
attr_reader lockfile: Config
|
5
|
+
attr_reader stdout: CLI::_IO
|
6
|
+
|
7
|
+
def initialize: (lockfile_path: Pathname, ?stdout: CLI::_IO) -> void
|
8
|
+
def install_from_lockfile: () -> void
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def source_for: (Config::gem_entry) -> Sources::_Source
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/sig/collection.rbs
ADDED
data/sig/environment_loader.rbs
CHANGED
@@ -78,6 +78,9 @@ module RBS
|
|
78
78
|
def add: (path: Pathname) -> void
|
79
79
|
| (library: String, version: String?) -> void
|
80
80
|
|
81
|
+
# Add repository path and libraries via rbs_collection.lock.yaml.
|
82
|
+
def add_collection: (Collection::Config collection_config) -> void
|
83
|
+
|
81
84
|
# This is helper function to test if RBS for a library is available or not.
|
82
85
|
#
|
83
86
|
def has_library?: (library: String, version: String?) -> bool
|
data/sig/errors.rbs
CHANGED
@@ -196,4 +196,13 @@ module RBS
|
|
196
196
|
|
197
197
|
def mixin_name: () -> String
|
198
198
|
end
|
199
|
+
|
200
|
+
class RecursiveTypeAliasError < LoadingError
|
201
|
+
attr_reader alias_names: Array[TypeName]
|
202
|
+
attr_reader location: Location
|
203
|
+
|
204
|
+
def initialize: (alias_names: Array[TypeName], location: Location) -> void
|
205
|
+
|
206
|
+
def name: () -> String
|
207
|
+
end
|
199
208
|
end
|