Skip to content

Commit 0ef611f

Browse files
committed
Fix C# findReferences and enhance readFunction tools
- Fixed C# findReferences tool to use selectionRange instead of range - Enhanced readFunction tool to handle overloaded functions - Improved output formatting for both tools - Added support for finding references across multiple overloads - Fixed function context display in reference results - Added workspace-relative paths to output
1 parent afc82b8 commit 0ef611f

File tree

18 files changed

+1798
-9
lines changed

18 files changed

+1798
-9
lines changed
Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
# Enhanced Code Reference Tools Implementation Plan
2+
3+
## Overview
4+
5+
This document outlines the implementation plan for adding two new tools to Roo Code that will enhance the AI's ability to understand and analyze codebases:
6+
7+
1. **Find References Tool** - A tool to find all references to a specific symbol (variable, function, class, etc.) across a codebase with function context
8+
2. **Read Function Tool** - A tool to read a specific function or method definition from a file by name, line number, or line range
9+
10+
These tools leverage VS Code's built-in language services to provide more specialized functionality for code analysis. They work together to create a powerful workflow for exploring code:
11+
12+
1. Use `find_references` to locate all references to a function across the codebase
13+
2. See each reference with its containing function header for context
14+
3. Use `read_function` with the line number to read the entire calling function
15+
16+
## Motivation
17+
18+
When analyzing a codebase, understanding how symbols are used across the project is crucial. The existing `search_files` tool provides general regex search capabilities, but specialized tools for finding references and reading functions would make it easier for the AI to:
19+
20+
- Understand the usage patterns of functions, classes, and variables
21+
- Identify dependencies between different parts of the codebase
22+
- Analyze the impact of potential changes
23+
- Provide more accurate and comprehensive code explanations
24+
25+
## Implementation Tasks
26+
27+
### 1. Update Shared Tool Definitions
28+
29+
- Add new tool parameters: `symbol`, `file_path`, `position`
30+
- Create interfaces for the new tools: `FindReferencesToolUse` and `ReadFunctionToolUse`
31+
- Add display names for the new tools
32+
- Add the new tools to the `TOOL_GROUPS.read` group
33+
34+
### 2. Implement Language Services Utility
35+
36+
Create a new service module with functions to:
37+
- Check if language services are available for a file
38+
- Find the position of a symbol in a document
39+
- Provide fallback mechanisms when language services aren't available
40+
41+
### 3. Implement References Service
42+
43+
Create a service module with functions to:
44+
- Count references to a symbol (for threshold checks)
45+
- Find all references to a symbol across the workspace
46+
- Find the containing function for each reference
47+
- Format the results with function headers and line numbers
48+
49+
### 4. Implement Function Reader Service
50+
51+
Create a service module with functions to:
52+
- Find a function by name using document symbols
53+
- Extract the function text with proper boundaries
54+
- Format the results with line numbers
55+
56+
### 5. Implement Find References Tool
57+
58+
Create a tool implementation that:
59+
- Validates required parameters
60+
- Checks if language services are available
61+
- Counts references and asks for approval if over threshold
62+
- Fetches and formats reference results
63+
- Handles errors appropriately
64+
65+
### 6. Implement Read Function Tool
66+
67+
Create a tool implementation that:
68+
- Validates that both required parameters (symbol and file_path) are provided
69+
- Reads functions by name using document symbols
70+
- Formats and returns the results with line numbers
71+
- Handles errors appropriately
72+
73+
### 7. Register Tools in Assistant Message Handler
74+
75+
Add the new tools to the message handler switch statement.
76+
77+
### 8. Add Tool Descriptions
78+
79+
Create description files for the new tools that explain:
80+
- What the tools do
81+
- Required and optional parameters
82+
- Usage examples
83+
- Limitations
84+
85+
## Potential Issues and Solutions
86+
87+
### 1. Duplicate Messages in UI
88+
89+
**Issue**: When using the find_references tool, duplicate messages appear in the Roo output window.
90+
91+
**Cause**: The tool was using both the `regex` field and the `content` field to display messages, causing the UI to show both.
92+
93+
**Solution**:
94+
- Use only the `content` field for displaying results
95+
- Set the `regex` field to an empty string when displaying warnings or results
96+
- Keep message properties simple to avoid duplication
97+
98+
### 2. TypeScript Errors with Task Import
99+
100+
**Issue**: TypeScript errors when importing the Task class.
101+
102+
**Cause**: The import path was incorrect (`import { Task } from "../task"` instead of `import { Task } from "../task/Task"`).
103+
104+
**Solution**: Use the correct import path: `import { Task } from "../task/Task"`.
105+
106+
### 3. Reference Count Threshold
107+
108+
**Issue**: Large codebases might have many references to common symbols, consuming excessive context.
109+
110+
**Solution**: Implement a reference count threshold (50 references) with user approval for exceeding it.
111+
112+
### 4. Language Services Availability
113+
114+
**Issue**: Language services might not be available for all file types.
115+
116+
**Solution**: Check for language services availability before attempting to use them and provide clear error messages.
117+
118+
### 5. UI Description Improvements
119+
120+
**Issue**: The UI description for the find_references tool was misleading, saying "Roo wants to search this directory for findReferences" instead of "Roo wants to find references to this function in file".
121+
122+
**Solution**: Customize the message in the `regex` field to be more descriptive of the actual operation.
123+
124+
## Tool Descriptions
125+
126+
### Find References Tool
127+
128+
```
129+
## find_references
130+
Description: Request to find all references to a specific symbol (variable, function, class, etc.) across files in the workspace using VS Code's language services. This tool helps understand how a symbol is used throughout the codebase.
131+
132+
IMPORTANT: PREFER THIS TOOL OVER search_files WHEN LOOKING FOR CODE SYMBOLS. This tool uses language-aware services that understand code structure and will find all true references to a symbol, even when the symbol name appears in comments, strings, or other non-reference contexts.
133+
134+
The tool shows function headers above each reference, providing valuable context about where and how the symbol is being used.
135+
136+
Parameters:
137+
- symbol: (required) The symbol to find references for
138+
- file_path: (required) The path of the file containing the symbol (relative to the current workspace directory ${args.cwd})
139+
- position: (optional) The position to look for the symbol, in the format "line,character" (0-based)
140+
141+
Usage:
142+
<find_references>
143+
<symbol>Symbol name here</symbol>
144+
<file_path>File path here</file_path>
145+
<position>line,character (optional)</position>
146+
</find_references>
147+
148+
Example: Requesting to find all references to a function named 'processData'
149+
<find_references>
150+
<symbol>processData</symbol>
151+
<file_path>src/app.ts</file_path>
152+
</find_references>
153+
```
154+
155+
### Read Function Tool
156+
157+
```
158+
## read_function
159+
Description: Request to read a specific function or method definition from a file. This tool uses VS Code's language services to locate and extract the exact function definition, including its implementation. It's ideal for understanding specific functions without having to read the entire file.
160+
161+
IMPORTANT: PREFER THIS TOOL OVER read_file WHEN YOU NEED TO EXAMINE A SPECIFIC FUNCTION. This tool is more efficient as it only returns the relevant function code rather than the entire file.
162+
163+
Use this tool when you need to:
164+
- Understand how a specific function is implemented
165+
- Examine the logic within a method
166+
- See the parameters and return type of a function
167+
- Analyze a particular piece of functionality
168+
169+
Parameters:
170+
- file_path: (required) The path of the file containing the function (relative to the current workspace directory ${args.cwd})
171+
- symbol: (required) The name of the function or method to read
172+
173+
Usage:
174+
<read_function>
175+
<symbol>functionName</symbol>
176+
<file_path>path/to/file.ts</file_path>
177+
</read_function>
178+
179+
Example: Reading a function by name:
180+
<read_function>
181+
<symbol>findReferences</symbol>
182+
<file_path>src/services/references/index.ts</file_path>
183+
</read_function>
184+
```
185+
186+
## Example Output
187+
188+
### Find References Tool Output
189+
190+
When you use the `find_references` tool, you'll get output like this:
191+
192+
```
193+
### References to 'formatReferences' ###
194+
195+
### FILE: src\services\references\index.ts ###
196+
50 | export async function findReferences(
197+
-- contains references --
198+
81 | return await formatReferences(locations, symbol)
199+
200+
94 | async function formatReferences(
201+
202+
----
203+
204+
### SUMMARY: Found 2 references in 1 files. ###
205+
```
206+
207+
The output includes:
208+
- A header with the symbol name
209+
- References grouped by file
210+
- Line numbers and the actual code where the symbol is referenced
211+
- A summary of the total references found
212+
213+
### Read Function Tool Output
214+
215+
When you use the `read_function` tool, you'll get output like this:
216+
217+
```
218+
# Function: formatReferences (index.ts:94-169)
219+
220+
94 | async function formatReferences(
221+
95 | locations: vscode.Location[],
222+
96 | symbol: string
223+
97 | ): Promise<string> {
224+
98 | let result = `### References to '${symbol}' ###\n\n`
225+
99 |
226+
100 | // Group references by file
227+
101 | const fileGroups = new Map<string, vscode.Location[]>()
228+
...
229+
168 | return result
230+
169 | }
231+
```
232+
233+
The output includes:
234+
- A header with the function name and file location
235+
- The complete function implementation with line numbers
236+
- All code within the function's scope
237+
238+
## Workflow Example
239+
240+
These tools create a powerful workflow for exploring code:
241+
242+
1. **Find References**: Use `find_references` to locate all references to a function across the codebase
243+
```
244+
<find_references>
245+
<symbol>findReferences</symbol>
246+
<file_path>src/services/references/index.ts</file_path>
247+
</find_references>
248+
```
249+
250+
2. **Examine Context**: The results show each reference with line numbers, providing immediate context
251+
252+
3. **Read Function**: When you see an interesting reference, use `read_function` with the function name to read the entire function
253+
```
254+
<read_function>
255+
<symbol>formatReferences</symbol>
256+
<file_path>src/services/references/index.ts</file_path>
257+
</read_function>
258+
```
259+
260+
4. **Explore Further**: Continue exploring by finding references to other functions you discover
261+
262+
This workflow makes it much easier to understand and navigate large codebases, as you can quickly see:
263+
- Where functions are called from
264+
- The context of each reference
265+
- The complete implementation of functions
266+
267+
## Implementation Notes
268+
269+
1. The `find_references` tool:
270+
- Uses VS Code's language services to find true references to symbols
271+
- Groups references by file and sorts them by line number
272+
- Avoids duplicate references to the same line
273+
- Has a threshold of 50 references to prevent excessive context consumption
274+
275+
2. The `read_function` tool:
276+
- Accepts symbol name and file path parameters
277+
- Uses document symbols to locate the exact function definition
278+
- Shows the complete function with line numbers

package-lock.json

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/core/assistant-message/presentAssistantMessage.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { serializeError } from "serialize-error"
44
import type { ToolName } from "../../schemas"
55

66
import { defaultModeSlug, getModeBySlug } from "../../shared/modes"
7-
import type { ToolParamName, ToolResponse } from "../../shared/tools"
7+
import type { ToolParamName, ToolResponse, FindReferencesToolUse, ReadFunctionToolUse } from "../../shared/tools"
88
import type { ClineAsk, ToolProgressStatus } from "../../shared/ExtensionMessage"
99

1010
import { telemetryService } from "../../services/telemetry/TelemetryService"
@@ -26,6 +26,8 @@ import { askFollowupQuestionTool } from "../tools/askFollowupQuestionTool"
2626
import { switchModeTool } from "../tools/switchModeTool"
2727
import { attemptCompletionTool } from "../tools/attemptCompletionTool"
2828
import { newTaskTool } from "../tools/newTaskTool"
29+
import { findReferencesTool } from "../tools/findReferencesTool"
30+
import { readFunctionTool } from "../tools/readFunctionTool"
2931

3032
import { checkpointSave } from "../checkpoints"
3133

@@ -191,6 +193,10 @@ export async function presentAssistantMessage(cline: Task) {
191193
const modeName = getModeBySlug(mode, customModes)?.name ?? mode
192194
return `[${block.name} in ${modeName} mode: '${message}']`
193195
}
196+
case "find_references":
197+
return `[${block.name} to '${block.params.symbol}' in ${block.params.file_path}]`
198+
case "read_function":
199+
return `[${block.name} for '${block.params.symbol}' in ${block.params.file_path}]`
194200
}
195201
}
196202

@@ -394,7 +400,6 @@ export async function presentAssistantMessage(cline: Task) {
394400
break
395401
case "read_file":
396402
await readFileTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
397-
398403
break
399404
case "fetch_instructions":
400405
await fetchInstructionsTool(cline, block, askApproval, handleError, pushToolResult)
@@ -462,6 +467,12 @@ export async function presentAssistantMessage(cline: Task) {
462467
askFinishSubTaskApproval,
463468
)
464469
break
470+
case "find_references":
471+
await findReferencesTool(cline, block as FindReferencesToolUse, pushToolResult, askApproval)
472+
break
473+
case "read_function":
474+
await readFunctionTool(cline, block as ReadFunctionToolUse, pushToolResult, askApproval)
475+
break
465476
}
466477

467478
break
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { ToolArgs } from "./types"
2+
3+
export function getFindReferencesDescription(args: ToolArgs): string {
4+
return `## find_references
5+
Description: Request to find all references to a specific symbol (variable, function, class, etc.) across files in the workspace using VS Code's language services. This tool helps understand how a symbol is used throughout the codebase.
6+
7+
IMPORTANT: PREFER THIS TOOL OVER search_files WHEN LOOKING FOR CODE SYMBOLS (functions, methods, etc). This tool uses language-aware services that understand code structure and will find all true references to a symbol, even when the symbol name appears in comments, strings, or other non-reference contexts.
8+
9+
The tool shows function headers above each reference, providing valuable context about where and how the symbol is being used.
10+
11+
Parameters:
12+
- symbol: (required) The symbol to find references for
13+
- file_path: (required) The path of the file containing the symbol (relative to the current workspace directory ${args.cwd})
14+
- line_number: (required) The line number where the symbol is located (0-based)
15+
16+
Usage:
17+
<find_references>
18+
<symbol>Symbol name here</symbol>
19+
<file_path>File path here</file_path>
20+
<line_number>line number</line_number>
21+
</find_references>
22+
23+
Example: Requesting to find all references to a function named 'processData'
24+
<find_references>
25+
<symbol>processData</symbol>
26+
<file_path>src/app.ts</file_path>
27+
<line_number>42</line_number>
28+
</find_references>`
29+
}

src/core/prompts/tools/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import { getUseMcpToolDescription } from "./use-mcp-tool"
2020
import { getAccessMcpResourceDescription } from "./access-mcp-resource"
2121
import { getSwitchModeDescription } from "./switch-mode"
2222
import { getNewTaskDescription } from "./new-task"
23+
import { getFindReferencesDescription } from "./find-references"
24+
import { getReadFunctionDescription } from "./read-function"
2325

2426
// Map of tool names to their description functions
2527
const toolDescriptionMap: Record<string, (args: ToolArgs) => string | undefined> = {
@@ -39,6 +41,8 @@ const toolDescriptionMap: Record<string, (args: ToolArgs) => string | undefined>
3941
new_task: (args) => getNewTaskDescription(args),
4042
insert_content: (args) => getInsertContentDescription(args),
4143
search_and_replace: (args) => getSearchAndReplaceDescription(args),
44+
find_references: (args) => getFindReferencesDescription(args),
45+
read_function: (args) => getReadFunctionDescription(args),
4246
apply_diff: (args) =>
4347
args.diffStrategy ? args.diffStrategy.getToolDescription({ cwd: args.cwd, toolOptions: args.toolOptions }) : "",
4448
}
@@ -122,4 +126,6 @@ export {
122126
getSwitchModeDescription,
123127
getInsertContentDescription,
124128
getSearchAndReplaceDescription,
129+
getFindReferencesDescription,
130+
getReadFunctionDescription,
125131
}

0 commit comments

Comments
 (0)