Module: TreeHaver::LanguageRegistry Private
- Defined in:
- lib/tree_haver/language_registry.rb
Overview
This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.
Thread-safe language registrations and cache for loaded Language handles
The LanguageRegistry provides two main functions:
- Registrations: Store mappings from language names to backend-specific configurations
- Cache: Memoize loaded Language objects to avoid repeated dlopen calls
The registry supports multiple backends for the same language, allowing runtime switching, benchmarking, and fallback scenarios.
Supported Backend Types
The registry is extensible and supports any backend type. Common types include:
:tree_sitter- Native tree-sitter grammars (.so files):citrus- Citrus PEG parser grammars (pure Ruby):prism- Ruby's Prism parser (Ruby source only):psych- Ruby's Psych parser (YAML only):commonmarker- Commonmarker gem (Markdown):markly- Markly gem (Markdown/GFM):rbs- RBS gem (RBS type signatures) - registered externally by rbs-merge
External gems can register their own backend types using the same API.
Registration structure:
registrations = {
toml: {
tree_sitter: { path: "/path/to/lib.so", symbol: "tree_sitter_toml" },
citrus: { grammar_module: TomlRB::Document, gem_name: "toml-rb" }
},
ruby: {
prism: { backend_module: TreeHaver::Backends::Prism }
},
yaml: {
psych: { backend_module: TreeHaver::Backends::Psych }
},
markdown: {
commonmarker: { backend_module: TreeHaver::Backends::Commonmarker },
markly: { backend_module: TreeHaver::Backends::Markly }
},
rbs: {
rbs: { backend_module: Rbs::Merge::Backends::RbsBackend } # External
}
}
TreeHaver::LanguageRegistry.register(:toml, :tree_sitter,
path: "/path/to/lib.so", symbol: "tree_sitter_toml")
TreeHaver::LanguageRegistry.register(:toml, :citrus,
grammar_module: TomlRB::Document, gem_name: "toml-rb")
TreeHaver::LanguageRegistry.register(:rbs, :rbs,
backend_module: Rbs::Merge::Backends::RbsBackend,
gem_name: "rbs")
Class Method Summary collapse
-
.clear ⇒ void
private
Clear all registrations and cache.
-
.clear_cache! ⇒ void
private
Clear the language cache.
-
.fetch(key) ⇒ Object
private
Fetch a cached language by key or compute and store it.
-
.register(name, backend_type, **config) ⇒ void
private
Register a language for a specific backend.
-
.registered(name, backend_type = nil) ⇒ Hash{Symbol => Hash}, ...
private
Fetch registration entries for a language.
- .with_registration(name, backend_type, **config) ⇒ Object private
Class Method Details
.clear ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Clear all registrations and cache
Removes all language registrations and cached Language objects. Primarily used in tests to reset state between test cases.
213 214 215 216 217 218 219 |
# File 'lib/tree_haver/language_registry.rb', line 213 def clear @mutex.synchronize do @registrations.clear @cache.clear end nil end |
.clear_cache! ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Clear the language cache
Removes all cached Language objects. The next call to fetch for any key will recompute the value. Does not clear registrations.
200 201 202 203 |
# File 'lib/tree_haver/language_registry.rb', line 200 def clear_cache! @mutex.synchronize { @cache.clear } nil end |
.fetch(key) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Fetch a cached language by key or compute and store it
This method provides thread-safe memoization for loaded Language objects. If the key exists in the cache, the cached value is returned immediately. Otherwise, the block is called to compute the value, which is then cached.
183 184 185 186 187 188 189 190 |
# File 'lib/tree_haver/language_registry.rb', line 183 def fetch(key) @mutex.synchronize do return @cache[key] if @cache.key?(key) value = yield @cache[key] = value end end |
.register(name, backend_type, **config) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Register a language for a specific backend
Stores backend-specific configuration for a language. Multiple backends can be registered for the same language without conflict.
100 101 102 103 104 105 106 107 108 109 |
# File 'lib/tree_haver/language_registry.rb', line 100 def register(name, backend_type, **config) key = name.to_sym backend_key = backend_type.to_sym @mutex.synchronize do @registrations[key] ||= {} @registrations[key][backend_key] = config.compact end nil end |
.registered(name, backend_type = nil) ⇒ Hash{Symbol => Hash}, ...
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Fetch registration entries for a language
Returns all backend-specific configurations for a language.
157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/tree_haver/language_registry.rb', line 157 def registered(name, backend_type = nil) @mutex.synchronize do lang_config = @registrations[name.to_sym] return unless lang_config if backend_type lang_config[backend_type.to_sym] else lang_config end end end |
.with_registration(name, backend_type, **config) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/tree_haver/language_registry.rb', line 111 def with_registration(name, backend_type, **config) key = name.to_sym backend_key = backend_type.to_sym original = nil had_language = false had_backend = false @mutex.synchronize do had_language = @registrations.key?(key) had_backend = @registrations.fetch(key, {}).key?(backend_key) original = @registrations.fetch(key, {})[backend_key]&.dup @registrations[key] ||= {} @registrations[key][backend_key] = config.compact @cache.clear end yield ensure @mutex.synchronize do if had_backend @registrations[key][backend_key] = original elsif had_language @registrations[key].delete(backend_key) else @registrations.delete(key) end @cache.clear end end |