Class: TypeGuessr::MCP::StandaloneRuntime
- Inherits:
-
Object
- Object
- TypeGuessr::MCP::StandaloneRuntime
- Defined in:
- lib/type_guessr/mcp/standalone_runtime.rb
Overview
Standalone runtime that mirrors RuntimeAdapter’s query interface without depending on ruby-lsp’s GlobalState.
Provides type inference, method signature lookup, and method search for use by the MCP server. All public query methods are thread-safe.
Instance Method Summary collapse
-
#build_member_index! ⇒ Object
Delegate member_index build to code_index.
-
#finalize_index! ⇒ Object
Finalize location index after all files are indexed.
-
#index_parsed_file(file_path, prism_result) ⇒ Object
Index a pre-parsed file into the IR graph.
-
#initialize(converter:, location_index:, signature_registry:, method_registry:, ivar_registry:, cvar_registry:, resolver:, signature_builder:, code_index:) ⇒ StandaloneRuntime
constructor
A new instance of StandaloneRuntime.
-
#method_signature(class_name, method_name) ⇒ Hash
Get method signature for a class#method.
-
#method_signatures(methods) ⇒ Array<Hash>
Get signatures for multiple methods in one call.
-
#method_source(class_name, method_name) ⇒ Hash
Get source code for a single method.
-
#method_sources(methods) ⇒ Array<Hash>
Get source code for multiple methods in one call.
-
#preload_signatures! ⇒ Object
Preload RBS signatures for inference.
-
#refresh_member_index!(file_uri) ⇒ Object
Delegate member_index refresh to code_index.
-
#remove_indexed_file(file_path) ⇒ Object
Remove all indexed data for a file.
-
#search_methods(query, include_signatures: false) ⇒ Array<Hash>
Search for methods matching a query pattern.
Constructor Details
#initialize(converter:, location_index:, signature_registry:, method_registry:, ivar_registry:, cvar_registry:, resolver:, signature_builder:, code_index:) ⇒ StandaloneRuntime
Returns a new instance of StandaloneRuntime.
20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/type_guessr/mcp/standalone_runtime.rb', line 20 def initialize(converter:, location_index:, signature_registry:, method_registry:, ivar_registry:, cvar_registry:, resolver:, signature_builder:, code_index:) @converter = converter @location_index = location_index @signature_registry = signature_registry @method_registry = method_registry @ivar_registry = ivar_registry @cvar_registry = cvar_registry @resolver = resolver @signature_builder = signature_builder @code_index = code_index @mutex = Mutex.new end |
Instance Method Details
#build_member_index! ⇒ Object
Delegate member_index build to code_index
70 71 72 |
# File 'lib/type_guessr/mcp/standalone_runtime.rb', line 70 def build_member_index! @code_index.build_member_index! end |
#finalize_index! ⇒ Object
Finalize location index after all files are indexed
81 82 83 |
# File 'lib/type_guessr/mcp/standalone_runtime.rb', line 81 def finalize_index! @mutex.synchronize { @location_index.finalize! } end |
#index_parsed_file(file_path, prism_result) ⇒ Object
Index a pre-parsed file into the IR graph
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/type_guessr/mcp/standalone_runtime.rb', line 37 def index_parsed_file(file_path, prism_result) return unless prism_result.value @mutex.synchronize do @location_index.remove_file(file_path) @method_registry.remove_file(file_path) @resolver.clear_cache context = Core::Converter::PrismConverter::Context.new( file_path: file_path, location_index: @location_index, method_registry: @method_registry, ivar_registry: @ivar_registry, cvar_registry: @cvar_registry ) prism_result.value.statements&.body&.each do |stmt| @converter.convert(stmt, context) end end end |
#method_signature(class_name, method_name) ⇒ Hash
Get method signature for a class#method
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/type_guessr/mcp/standalone_runtime.rb', line 94 def method_signature(class_name, method_name) def_node = @mutex.synchronize { @method_registry.lookup(class_name, method_name) } unless def_node entry = @signature_registry.lookup(class_name, method_name) if entry.is_a?(Core::Registry::SignatureRegistry::MethodEntry) return { source: "rbs", signatures: entry.signature_strings, class_name: class_name, method_name: method_name } end if entry.is_a?(Core::Registry::SignatureRegistry::GemMethodEntry) return { source: "gem_cache", signatures: entry.signature_strings, class_name: class_name, method_name: method_name } end return { error: "Method not found: #{class_name}##{method_name}", class_name: class_name, method_name: method_name } end sig = @mutex.synchronize { @signature_builder.build_from_def_node(def_node) } { source: "project", signature: sig.to_s, class_name: class_name, method_name: method_name } rescue StandardError => e { error: e., class_name: class_name, method_name: method_name } end |
#method_signatures(methods) ⇒ Array<Hash>
Get signatures for multiple methods in one call
136 137 138 139 140 |
# File 'lib/type_guessr/mcp/standalone_runtime.rb', line 136 def method_signatures(methods) methods.map do |entry| method_signature(entry[:class_name], entry[:method_name]) end end |
#method_source(class_name, method_name) ⇒ Hash
Get source code for a single method
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/type_guessr/mcp/standalone_runtime.rb', line 146 def method_source(class_name, method_name) def_node = @mutex.synchronize { @method_registry.lookup(class_name, method_name) } unless def_node return { error: "Method not found: #{class_name}##{method_name}", class_name: class_name, method_name: method_name } end file_path = @mutex.synchronize { @method_registry.source_file_for(class_name, method_name) } unless file_path return { error: "Source file not found: #{class_name}##{method_name}", class_name: class_name, method_name: method_name } end source = File.read(file_path) prism_result = Prism.parse(source) node_context = RubyLsp::RubyDocument.locate( prism_result.value, def_node.loc, code_units_cache: prism_result.code_units_cache(Encoding::UTF_8) ) prism_def = node_context.node.is_a?(Prism::DefNode) ? node_context.node : node_context.parent { class_name: class_name, method_name: method_name, source: prism_def.slice, file_path: file_path, line: prism_def.location.start_line } rescue StandardError => e { error: e., class_name: class_name, method_name: method_name } end |
#method_sources(methods) ⇒ Array<Hash>
Get source code for multiple methods in one call
181 182 183 184 185 |
# File 'lib/type_guessr/mcp/standalone_runtime.rb', line 181 def method_sources(methods) methods.map do |entry| method_source(entry[:class_name], entry[:method_name]) end end |
#preload_signatures! ⇒ Object
Preload RBS signatures for inference
86 87 88 |
# File 'lib/type_guessr/mcp/standalone_runtime.rb', line 86 def preload_signatures! @signature_registry.preload end |
#refresh_member_index!(file_uri) ⇒ Object
Delegate member_index refresh to code_index
76 77 78 |
# File 'lib/type_guessr/mcp/standalone_runtime.rb', line 76 def refresh_member_index!(file_uri) @code_index.refresh_member_index!(file_uri) end |
#remove_indexed_file(file_path) ⇒ Object
Remove all indexed data for a file
61 62 63 64 65 66 67 |
# File 'lib/type_guessr/mcp/standalone_runtime.rb', line 61 def remove_indexed_file(file_path) @mutex.synchronize do @location_index.remove_file(file_path) @method_registry.remove_file(file_path) @resolver.clear_cache end end |
#search_methods(query, include_signatures: false) ⇒ Array<Hash>
Search for methods matching a query pattern
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/type_guessr/mcp/standalone_runtime.rb', line 191 def search_methods(query, include_signatures: false) @mutex.synchronize do results = @method_registry.search(query) results.map do |class_name, method_name, def_node| entry = { class_name: class_name, method_name: method_name, full_name: "#{class_name}##{method_name}", location: def_node.loc ? { offset: def_node.loc } : nil } if include_signatures sig = @signature_builder.build_from_def_node(def_node) entry[:signature] = sig.to_s end entry end end rescue StandardError => e { error: e. } end |