Class: TreeHaver::CitrusGrammarFinder
- Inherits:
-
Object
- Object
- TreeHaver::CitrusGrammarFinder
- Defined in:
- lib/tree_haver/citrus_grammar_finder.rb
Overview
Utility for finding and registering Citrus grammar gems.
CitrusGrammarFinder provides language-agnostic discovery of Citrus grammar gems. Given a language name and gem information, it attempts to load the grammar and register it with tree_haver.
Unlike tree-sitter grammars (which are .so files), Citrus grammars are Ruby modules that respond to .parse(source). This class handles the discovery and registration of these grammars.
Instance Attribute Summary collapse
-
#gem_name ⇒ String
readonly
The gem name to require.
-
#grammar_const ⇒ String
readonly
The constant path to the grammar (e.g., “TomlRB::Document”).
-
#language_name ⇒ Symbol
readonly
The language identifier.
-
#require_path ⇒ String?
readonly
Custom require path (defaults to gem_name with dashes to slashes).
Instance Method Summary collapse
-
#available? ⇒ Boolean
Check if the Citrus grammar is available.
-
#grammar_module ⇒ Module?
Get the resolved grammar module.
-
#initialize(language:, gem_name:, grammar_const:, require_path: nil) ⇒ CitrusGrammarFinder
constructor
Initialize a Citrus grammar finder.
-
#not_found_message ⇒ String
Get a human-readable error message when grammar is not found.
-
#register!(raise_on_missing: false) ⇒ Boolean
Register this Citrus grammar with TreeHaver.
-
#search_info ⇒ Hash
Get debug information about the search.
Constructor Details
#initialize(language:, gem_name:, grammar_const:, require_path: nil) ⇒ CitrusGrammarFinder
Initialize a Citrus grammar finder
50 51 52 53 54 55 56 57 58 |
# File 'lib/tree_haver/citrus_grammar_finder.rb', line 50 def initialize(language:, gem_name:, grammar_const:, require_path: nil) @language_name = language.to_sym @gem_name = gem_name @grammar_const = grammar_const @require_path = require_path || gem_name.tr("-", "/") @load_attempted = false @available = false @grammar_module = nil end |
Instance Attribute Details
#gem_name ⇒ String (readonly)
Returns the gem name to require.
36 37 38 |
# File 'lib/tree_haver/citrus_grammar_finder.rb', line 36 def gem_name @gem_name end |
#grammar_const ⇒ String (readonly)
Returns the constant path to the grammar (e.g., “TomlRB::Document”).
39 40 41 |
# File 'lib/tree_haver/citrus_grammar_finder.rb', line 39 def grammar_const @grammar_const end |
#language_name ⇒ Symbol (readonly)
Returns the language identifier.
33 34 35 |
# File 'lib/tree_haver/citrus_grammar_finder.rb', line 33 def language_name @language_name end |
#require_path ⇒ String? (readonly)
Returns custom require path (defaults to gem_name with dashes to slashes).
42 43 44 |
# File 'lib/tree_haver/citrus_grammar_finder.rb', line 42 def require_path @require_path end |
Instance Method Details
#available? ⇒ Boolean
Check if the Citrus grammar is available
Attempts to require the gem and resolve the grammar constant. Result is cached after first call.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/tree_haver/citrus_grammar_finder.rb', line 66 def available? return @available if @load_attempted @load_attempted = true begin # Try to require the gem require @require_path # Try to resolve the constant @grammar_module = resolve_constant(@grammar_const) # Verify it responds to parse unless @grammar_module.respond_to?(:parse) warn("#{@grammar_const} doesn't respond to :parse") @available = false return false end @available = true rescue LoadError => e # Always show LoadError for debugging warn("CitrusGrammarFinder: Failed to load '#{@require_path}': #{e.class}: #{e.message}") @available = false rescue NameError => e # Always show NameError for debugging warn("CitrusGrammarFinder: Failed to resolve '#{@grammar_const}': #{e.class}: #{e.message}") @available = false rescue => e # Catch any other errors warn("CitrusGrammarFinder: Unexpected error: #{e.class}: #{e.message}") warn(e.backtrace.first(3).join("\n")) if ENV["TREE_HAVER_DEBUG"] @available = false end @available end |
#grammar_module ⇒ Module?
Get the resolved grammar module
106 107 108 109 |
# File 'lib/tree_haver/citrus_grammar_finder.rb', line 106 def grammar_module available? # Ensure we've tried to load @grammar_module end |
#not_found_message ⇒ String
Get a human-readable error message when grammar is not found
152 153 154 155 |
# File 'lib/tree_haver/citrus_grammar_finder.rb', line 152 def "Citrus grammar for #{@language_name} not found. " \ "Install #{@gem_name} gem: gem install #{@gem_name}" end |
#register!(raise_on_missing: false) ⇒ Boolean
Register this Citrus grammar with TreeHaver
After registration, the language can be used via:
TreeHaver::Language.{language_name}
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/tree_haver/citrus_grammar_finder.rb', line 119 def register!(raise_on_missing: false) unless available? if raise_on_missing raise NotAvailable, end return false end TreeHaver.register_language( @language_name, grammar_module: @grammar_module, gem_name: @gem_name, ) true end |
#search_info ⇒ Hash
Get debug information about the search
138 139 140 141 142 143 144 145 146 147 |
# File 'lib/tree_haver/citrus_grammar_finder.rb', line 138 def search_info { language: @language_name, gem_name: @gem_name, grammar_const: @grammar_const, require_path: @require_path, available: available?, grammar_module: @grammar_module&.name, } end |