execute method
Execute the tool with the given input.
Implementation
@override
Future<ToolResult> execute(Map<String, dynamic> input) async {
final parsed = LspToolInput.fromJson(input);
final absolutePath = _expandPath(parsed.filePath);
// Wait for initialization.
final manager = _manager;
if (manager == null) {
return ToolResult.success(
'LSP server manager not initialized. This may indicate a startup issue.',
metadata: LspToolOutput(
operation: parsed.operation.name,
result: 'LSP server manager not initialized.',
filePath: parsed.filePath,
).toJson(),
);
}
if (manager.initStatus == LspInitStatus.pending) {
await manager.waitForInitialization();
}
try {
// Ensure file is open.
if (!manager.isFileOpen(absolutePath)) {
final file = File(absolutePath);
final stat = await file.stat();
if (stat.size > maxLspFileSizeBytes) {
final sizeMb = (stat.size / 1000000).ceil();
return ToolResult.success(
'File too large for LSP analysis (${sizeMb}MB exceeds 10MB limit)',
metadata: LspToolOutput(
operation: parsed.operation.name,
result:
'File too large for LSP analysis (${sizeMb}MB exceeds 10MB limit)',
filePath: parsed.filePath,
).toJson(),
);
}
final content = await file.readAsString();
await manager.openFile(absolutePath, content);
}
// Build params.
final uri = Uri.file(absolutePath).toString();
final position = parsed.lspPosition;
final method = parsed.operation.method;
final params = _buildParams(parsed.operation, uri, position);
// Send request.
var result = await manager.sendRequest(absolutePath, method, params);
if (result == null) {
final ext = absolutePath.split('.').last;
return ToolResult.success(
'No LSP server available for file type: .$ext',
metadata: LspToolOutput(
operation: parsed.operation.name,
result: 'No LSP server available for file type: .$ext',
filePath: parsed.filePath,
).toJson(),
);
}
// For call hierarchy, do the two-step process.
if (parsed.operation == LspOperation.incomingCalls ||
parsed.operation == LspOperation.outgoingCalls) {
if (result is! List || result.isEmpty) {
return ToolResult.success(
'No call hierarchy item found at this position',
metadata: LspToolOutput(
operation: parsed.operation.name,
result: 'No call hierarchy item found at this position',
filePath: parsed.filePath,
resultCount: 0,
fileCount: 0,
).toJson(),
);
}
final callMethod = parsed.operation == LspOperation.incomingCalls
? 'callHierarchy/incomingCalls'
: 'callHierarchy/outgoingCalls';
result = await manager.sendRequest(absolutePath, callMethod, {
'item': result[0],
});
}
// Format result string.
final formatted = _formatResult(parsed.operation, result);
return ToolResult.success(
formatted,
metadata: LspToolOutput(
operation: parsed.operation.name,
result: formatted,
filePath: parsed.filePath,
).toJson(),
);
} catch (e) {
final errorMsg = 'Error performing ${parsed.operation.name}: $e';
return ToolResult.success(
errorMsg,
metadata: LspToolOutput(
operation: parsed.operation.name,
result: errorMsg,
filePath: parsed.filePath,
).toJson(),
);
}
}