Class: RBS::EnvironmentLoader
- Inherits:
-
Object
- Object
- RBS::EnvironmentLoader
- Includes:
- FileFinder
- Defined in:
- sig/environment_loader.rbs,
lib/rbs/environment_loader.rb
Overview
EnvironmentLoader is an object to load RBS files from filesystem.
Set up your configuration through repository and #add method.
# Set up the repository to load library RBSs from.
repo = RBS::Repository.default
repo.add(Pathname("vendor/rbs/gem-rbs"))
repo.add(Pathname("vendor/rbs/internal-rbs"))
loader = RBS::EnvironmentLoader.new(repository: repo)
# Add libraries to load RBS files.
loader.add(library: "minitest")
loader.add(library: "rbs", version: "1.0.0")
# Add dirs to load RBS files from.
loader.add(path: Pathname("sig"))
# Load RBSs into an environment.
environment = RBS::Environment.new()
loader.load(env: environment)
Defined Under Namespace
Classes: Library, UnknownLibraryError
Constant Summary collapse
- DEFAULT_CORE_ROOT =
Pathname(_ = __dir__) + "../../core"
Instance Attribute Summary collapse
-
#core_root ⇒ Pathname?
readonly
Returns the value of attribute core_root.
-
#dirs ⇒ Array[Pathname]
readonly
Returns the value of attribute dirs.
-
#libs ⇒ Set[Library]
readonly
Returns the value of attribute libs.
-
#repository ⇒ Repository
readonly
Returns the value of attribute repository.
Class Method Summary collapse
-
.gem_sig_path(name, version) ⇒ [Gem::Specification, Pathname]?
Returns a pair of spec and path for a gem with RBS.
Instance Method Summary collapse
-
#add(path: nil, library: nil, version: nil, resolve_dependencies: true) ⇒ Object
Add a path or library to load RBSs from.
-
#add_collection(lockfile) ⇒ void
Add repository path and libraries via rbs_collection.lock.yaml.
- #each_dir {|arg0, arg1| ... } ⇒ void
- #each_signature {|arg0, arg1, arg2, arg3, arg4| ... } ⇒ void
-
#has_library?(library:, version:) ⇒ Boolean
This is helper function to test if RBS for a library is available or not.
-
#initialize(core_root: DEFAULT_CORE_ROOT, repository: Repository.new) ⇒ EnvironmentLoader
constructor
Accepts two optional keyword arguments.
-
#load(env:) ⇒ Array[[AST::Declarations::t, Pathname, source]]
Add all declarations to environment.
- #resolve_dependencies(library:, version:) ⇒ void
Methods included from FileFinder
Constructor Details
#initialize(core_root: DEFAULT_CORE_ROOT, repository: Repository.new) ⇒ EnvironmentLoader
Accepts two optional keyword arguments.
core_root is the path to the directory with RBSs for core classes.
The default value is the core library included in RBS gem. (EnvironmentLoader::DEFAULT_CORE_ROOT)
Passing nil means it skips loading core class definitions.
repository is the repository for library classes.
The default value is repository only with stdlib classes. (Repository.new)
69 70 71 72 73 74 75 |
# File 'sig/environment_loader.rbs', line 69 def initialize(core_root: DEFAULT_CORE_ROOT, repository: Repository.new) @core_root = core_root @repository = repository @libs = Set.new @dirs = [] end |
Instance Attribute Details
#core_root ⇒ Pathname? (readonly)
Returns the value of attribute core_root.
20 21 22 |
# File 'lib/rbs/environment_loader.rb', line 20 def core_root @core_root end |
#dirs ⇒ Array[Pathname] (readonly)
Returns the value of attribute dirs.
24 25 26 |
# File 'lib/rbs/environment_loader.rb', line 24 def dirs @dirs end |
#libs ⇒ Set[Library] (readonly)
Returns the value of attribute libs.
23 24 25 |
# File 'lib/rbs/environment_loader.rb', line 23 def libs @libs end |
#repository ⇒ Repository (readonly)
Returns the value of attribute repository.
21 22 23 |
# File 'lib/rbs/environment_loader.rb', line 21 def repository @repository end |
Class Method Details
.gem_sig_path(name, version) ⇒ [Gem::Specification, Pathname]?
Returns a pair of spec and path for a gem with RBS. Returns nil if the gem is not installed, or the gem doesn't provide RBS.
105 106 107 108 109 110 111 112 113 114 115 |
# File 'sig/environment_loader.rbs', line 105 def self.gem_sig_path(name, version) requirements = [] #: Array[String] requirements << version if version spec = Gem::Specification.find_by_name(name, *requirements) path = Pathname(spec.gem_dir) + "sig" if path.directory? [spec, path] end rescue Gem::MissingSpecError nil end |
Instance Method Details
#add(path:) ⇒ void #add(library:, version:, resolve_dependencies:) ⇒ void
Add a path or library to load RBSs from.
path can be a file or a directory.
All .rbs files from the given directory will be loaded.
Specifying a file will load the file regardless the extension of the file is.
library can be a name of a gem.
Specifying nil to version will load any version available.
It first tries to load RBS files from gem with specified version.
If RBS files cannot be found in the gem, it tries to load RBSs from repository.
82 83 84 85 86 87 88 89 90 91 |
# File 'sig/environment_loader.rbs', line 82 def add(path: nil, library: nil, version: nil, resolve_dependencies: true) case when path dirs << path when library if libs.add?(Library.new(name: library, version: version)) && resolve_dependencies resolve_dependencies(library: library, version: version) end end end |
#add_collection(lockfile) ⇒ void
This method returns an undefined value.
Add repository path and libraries via rbs_collection.lock.yaml.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'sig/environment_loader.rbs', line 88 def add_collection(lockfile) lockfile.check_rbs_availability! repository.add(lockfile.fullpath) lockfile.gems.each_value do |gem| name = gem[:name] locked_version = gem[:version] if (source = gem[:source]).is_a?(Collection::Sources::Rubygems) # allow loading different version of a gem unless source.has?(name, locked_version) if (spec, _ = self.class.gem_sig_path(name, nil)) RBS.logger.warn { "Loading type definition from gem `#{name}-#{spec.version}` because locked version `#{locked_version}` is unavailable. Try `rbs collection update` to fix the (potential) issue." } locked_version = spec.version.to_s end end end add(library: gem[:name], version: locked_version, resolve_dependencies: false) end end |
#each_dir {|arg0, arg1| ... } ⇒ void
This method returns an undefined value.
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/rbs/environment_loader.rb', line 125 def each_dir if root = core_root yield :core, root end libs.each do |lib| unless has_library?(version: lib.version, library: lib.name) raise UnknownLibraryError.new(lib: lib) end case when from_gem = self.class.gem_sig_path(lib.name, lib.version) yield lib, from_gem[1] when from_repo = repository.lookup(lib.name, lib.version) yield lib, from_repo end end dirs.each do |dir| yield dir, dir end end |
#each_signature {|arg0, arg1, arg2, arg3, arg4| ... } ⇒ void
This method returns an undefined value.
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/rbs/environment_loader.rb', line 148 def each_signature files = Set[] each_dir do |source, dir| skip_hidden = !source.is_a?(Pathname) FileFinder.each_file(dir, skip_hidden: skip_hidden) do |path| next if files.include?(path) files << path buffer = Buffer.new(name: path, content: path.read(encoding: "UTF-8")) _, dirs, decls = Parser.parse_signature(buffer) yield source, path, buffer, decls, dirs end end end |
#has_library?(library:, version:) ⇒ Boolean
This is helper function to test if RBS for a library is available or not.
92 93 94 95 96 97 98 |
# File 'sig/environment_loader.rbs', line 92 def has_library?(library:, version:) if self.class.gem_sig_path(library, version) || repository.lookup(library, version) true else false end end |
#load(env:) ⇒ Array[[AST::Declarations::t, Pathname, source]]
Add all declarations to environment.
Raises UnknownLibraryError if RBS cannot be loaded from a library.
Returns an array of tuples of the declaration, path to the file, and the source.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'sig/environment_loader.rbs', line 100 def load(env:) # @type var loaded: Array[[AST::Declarations::t, Pathname, source]] loaded = [] # For migrating stringio to stdlib if @core_root && libs.none? { |lib| lib.name == 'stringio' } add(library: 'stringio', version: nil) end each_signature do |source, path, buffer, decls, dirs| decls.each do |decl| loaded << [decl, path, source] end env.add_source(Source::RBS.new(buffer, dirs, decls)) end loaded end |
#resolve_dependencies(library:, version:) ⇒ void
This method returns an undefined value.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/rbs/environment_loader.rb', line 59 def resolve_dependencies(library:, version:) [Collection::Sources::Rubygems.instance, Collection::Sources::Stdlib.instance].each do |source| next unless source.has?(library, version) unless version version = source.versions(library).last or raise end source.dependencies_of(library, version)&.each do |dep| add(library: dep['name'], version: nil) end return end end |