feat: Enhance symbol search with co-location boosting and receiver type support
Improves search accuracy by boosting results when multiple query symbols appear in the same file, addressing cases where common names like "run" return too many results. Adds Go method receiver type extraction to qualified names for better searchability (e.g., "scrapeLoop.run"). Optimizes database queries with two-pass approach to handle distinctive vs common symbol names efficiently.
This commit is contained in:
@@ -27,4 +27,16 @@ export const goExtractor: LanguageExtractor = {
|
||||
}
|
||||
return sig;
|
||||
},
|
||||
getReceiverType: (node, source) => {
|
||||
// Go method_declaration has a "receiver" field: func (sl *scrapeLoop) run(...)
|
||||
// The receiver is a parameter_list containing a parameter_declaration
|
||||
// with a type that may be a pointer_type (*scrapeLoop) or plain type (scrapeLoop)
|
||||
const receiver = getChildByField(node, 'receiver');
|
||||
if (!receiver) return undefined;
|
||||
// Find the type identifier inside the receiver
|
||||
const text = getNodeText(receiver, source);
|
||||
// Extract type name from patterns like "(sl *Type)", "(sl Type)", "(*Type)", "(Type)"
|
||||
const match = text.match(/\*?\s*([A-Za-z_][A-Za-z0-9_]*)\s*\)/);
|
||||
return match?.[1];
|
||||
},
|
||||
};
|
||||
|
||||
@@ -163,4 +163,11 @@ export interface LanguageExtractor {
|
||||
* Returns info about each declared variable, allowing the core to create nodes.
|
||||
*/
|
||||
extractVariables?: (node: SyntaxNode, source: string) => VariableInfo[];
|
||||
|
||||
/**
|
||||
* Extract receiver/owner type name from a method declaration.
|
||||
* Used by Go to get the struct receiver (e.g., "scrapeLoop" from "func (sl *scrapeLoop) run()").
|
||||
* When present, the receiver type is included in the qualified name for better searchability.
|
||||
*/
|
||||
getReceiverType?: (node: SyntaxNode, source: string) => string | undefined;
|
||||
}
|
||||
|
||||
@@ -505,13 +505,21 @@ export class TreeSitterExtractor {
|
||||
const isAsync = this.extractor.isAsync?.(node);
|
||||
const isStatic = this.extractor.isStatic?.(node);
|
||||
|
||||
const methodNode = this.createNode('method', name, node, {
|
||||
// For languages with receiver types (Go), include receiver in qualified name
|
||||
// so FTS can match "scrapeLoop.run" → qualified_name "...::scrapeLoop::run"
|
||||
const receiverType = this.extractor.getReceiverType?.(node, this.source);
|
||||
const extraProps: Partial<Node> = {
|
||||
docstring,
|
||||
signature,
|
||||
visibility,
|
||||
isAsync,
|
||||
isStatic,
|
||||
});
|
||||
};
|
||||
if (receiverType) {
|
||||
extraProps.qualifiedName = `${this.filePath}::${receiverType}::${name}`;
|
||||
}
|
||||
|
||||
const methodNode = this.createNode('method', name, node, extraProps);
|
||||
if (!methodNode) return;
|
||||
|
||||
// Extract type annotations (parameter types and return type)
|
||||
|
||||
Reference in New Issue
Block a user