Skip to content

Commit 485a140

Browse files
committed
Performance improvements
- Tested extensively with C, and Python - Using language agnostic apis provided by VS code sdk - Removed file parsing, as implementation needs to be as simple as possible - Updated README.md
1 parent cc5cc83 commit 485a140

File tree

3 files changed

+67
-114
lines changed

3 files changed

+67
-114
lines changed

.vscode/launch.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// A launch configuration that compiles the extension and then opens it inside a new window
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
{
6+
"version": "0.2.1", // Updated version
7+
"configurations": [
8+
{
9+
"name": "Run Extension",
10+
"type": "extensionHost",
11+
"request": "launch",
12+
"args": [
13+
"--extensionDevelopmentPath=${workspaceFolder}"
14+
],
15+
"outFiles": [
16+
"${workspaceFolder}/dist/**/*.js" // Ensure this path is correct
17+
],
18+
"preLaunchTask": "build" // Ensure this matches the label in tasks.json
19+
}
20+
]
21+
}

README.md

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,24 @@
22

33
## Introduction 👨‍🏫
44

5-
Thanks for checking out Code Visualizer! 🎉 This extension helps developers visualize their code by generating flowcharts that represent the call hierarchy of functions and methods in your codebase. It transforms the often complex structure of code into an easy-to-understand visual format, making it simpler to navigate large projects. 🗺️
5+
Thanks for checking out Code Visualizer! 🎉 This extension helps developers visualize their code by generating a flowchart that represents the call hierarchy of functions and methods in your codebase. It transforms the often complex structure of code into an easy-to-understand visual format, making it simpler to navigate large projects. 🗺️
66

77
## Features 🌟
8-
- **Flowchart Generation:** 📊 Right-click on any function or method, and select 'Generate Flowchart' to create a visual representation of its call hierarchy.
8+
- **Flowchart Generation:** 📊 Right-click on any function or method, and select 'Visualize' to create a visual representation of its call hierarchy.
99
- **Interactive Visuals:** 🖱️ Zoom in, zoom out, and interact with the flowchart to explore different parts of your code.
1010
- **Customizable Views:** 🎨 Tailor the flowchart to focus on specific function calls, and adjust the layout for better readability.
11+
- **Searchable:** 🔍 Search for any function or method in the flowchart to quickly navigate to it.
1112
- **Multi-Language Support:** 🌐 Currently supports C, C++, Python.
12-
* At least that's the goal of the project. Contributions are welcome! 🤝
13+
* At least that's the goal of this project. Contributions are welcome! 🤝
1314

1415
## How It Works 🛠️
1516

16-
1. Select a function in your code ✅
17-
2. Run the "Visualize" command 🏃‍♂️
18-
3. Watch as CodeFlow creates an interactive diagram of function calls 🎭
17+
1. Install the extension from the VS Code Marketplace.
18+
2. Right-click on any function or method, and select 'Visualize' to create a visual representation of its call hierarchy.
19+
3. Watch as the extension creates an interactive diagram of function calls 🎭
1920
4. Click on nodes to explore deeper into the call hierarchy 🕵️‍♂️
2021

21-
CodeFlow uses VS Code's built-in call hierarchy API, making it language-agnostic and powerful across various programming languages. 💪
22+
Code Visualizer uses VS Code's built-in call hierarchy API, making it language-agnostic and powerful across various programming languages. 💪
2223

2324
## Features 🚀
2425

@@ -28,7 +29,7 @@ CodeFlow uses VS Code's built-in call hierarchy API, making it language-agnostic
2829

2930
## How to Contribute 🤝
3031

31-
We're excited to welcome contributors to the CodeFlow project! Here's how you can get involved:
32+
We're excited to welcome contributors to the Code Visualizer project! Here's how you can get involved:
3233

3334
1. Fork the repository 🍴
3435
2. Clone your fork: `https://github.com/Ganjai-Labs/code-visualizer.git` 📥
@@ -37,26 +38,30 @@ We're excited to welcome contributors to the CodeFlow project! Here's how you ca
3738
5. Run tests: `npm test` 🧪
3839
6. Commit your changes: `git commit -m "Add some feature"` 💾
3940
7. Push to the branch: `git push origin your-feature-name` 🚀
40-
8. Submit a pull request 🙏
41+
8. Submit a pull request with the description of your changes 🙏
4142

4243
Before contributing, please read our [Contributing Guidelines](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md). 📚
4344

4445
## Features to be Implemented 🔮
4546

46-
We're always looking to improve CodeFlow. Here are some features we'd love to see:
47+
We're always looking to improve Code Visualizer. Here are some features we'd love to see:
4748

4849
1. Detect cycles in the generated diagrams, and highlight them in red 🔴
49-
2. Conditional highlighting of nodes based on certain conditions 🎨
50-
3. Export diagrams as images or SVGs 📸
50+
2. Draw multiple connections between nodes when a function is called multiple times 🔄
51+
52+
3. Export diagrams as images or SVGs. Currently, the generated diargams are html files that are not viewable outside of VS Code. 📸
5153
4. Integration with version control to show changes in call hierarchy over time 🕰️
5254
5. Performance optimizations for large codebases ⚡
5355
6. Enhanced filtering options for complex diagrams 🔍
5456

57+
### Moon shot 🌙
58+
59+
- Conditional highlighting of nodes based on certain conditions 🎨
60+
- Integration with LLMs to provide more context for the generated diagrams 🤖
61+
5562
Feel free to tackle any of these or propose your own ideas! 💡
5663

5764
## Get Started 🚀
5865

59-
Ready to dive in? Install CodeFlow from the VS Code Marketplace and start visualizing your code today! 🎊
60-
61-
Join us in making code comprehension a joyful experience. Happy coding! 😊👨‍💻👩‍💻
66+
Ready to dive in? Install Code Visualizer from the VS Code Marketplace and start visualizing your code today! 😊👨‍💻👩‍💻
6267

src/extension.ts

Lines changed: 26 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,13 @@ let nodePositions: Map<number, {x: number, y: number}> = new Map();
9696
function showFlowDiagram(data: {nodes: any[], edges: any[]}, context: vscode.ExtensionContext) {
9797
console.log('Creating or updating webview panel');
9898
if (panel) {
99-
console.log('Updating existing panel');
100-
panel.webview.postMessage({ command: 'updateDiagram', data: data, positions: Array.from(nodePositions.entries()) });
99+
console.log('Updating existing panel with data:', JSON.stringify(data));
100+
console.log('Current node positions:', Array.from(nodePositions.entries()));
101+
panel.webview.postMessage({
102+
command: 'updateDiagram',
103+
data: data,
104+
positions: Array.from(nodePositions.entries())
105+
});
101106
} else {
102107
console.log('Creating new panel');
103108
panel = vscode.window.createWebviewPanel(
@@ -144,111 +149,32 @@ function showFlowDiagram(data: {nodes: any[], edges: any[]}, context: vscode.Ext
144149

145150
// Modify visualizeNode to accept context
146151
async function visualizeNode(nodeId: number, context: vscode.ExtensionContext) {
147-
console.log(`Visualizing node with ID: ${nodeId}`);
148152
const node = globalData.nodes.find(n => n.id === nodeId);
149-
if (!node) {
150-
console.log('Node not found in globalData');
151-
return;
152-
}
153-
console.log(`Found node: ${JSON.stringify(node)}`);
154-
155-
// Check if this node has already been visualized
156-
if (node.visualized) {
157-
console.log('Node has already been visualized');
158-
vscode.window.showInformationMessage('This function has already been visualized.');
159-
return;
160-
}
153+
if (!node) return;
161154

162155
try {
163-
// Open all documents that contain the function with the same name
164-
const documents = await vscode.workspace.findFiles('**/*.{c,h}');
165-
let callHierarchyItems: vscode.CallHierarchyItem[] | undefined;
166-
167-
for (const docUri of documents) {
168-
const document = await vscode.workspace.openTextDocument(docUri);
169-
const text = document.getText();
170-
const functionRegex = new RegExp(`\\b${node.label}\\s*\\(`);
171-
const match = text.match(functionRegex);
172-
173-
if (match) {
174-
const position = document.positionAt(match.index!);
175-
callHierarchyItems = await vscode.commands.executeCommand<vscode.CallHierarchyItem[]>(
176-
'vscode.prepareCallHierarchy',
177-
document.uri,
178-
position
179-
);
180-
181-
if (callHierarchyItems && callHierarchyItems.length > 0) {
182-
break;
183-
}
184-
}
185-
}
156+
const document = await vscode.workspace.openTextDocument(vscode.Uri.file(node.file));
157+
// Instead of showing the document, let's just get the call hierarchy
158+
const position = new vscode.Position(node.line, node.character);
159+
160+
console.log(`Requesting call hierarchy for node ${nodeId} at ${node.file}:${position.line},${position.character}`);
161+
const callHierarchyItems = await vscode.commands.executeCommand<vscode.CallHierarchyItem[]>(
162+
'vscode.prepareCallHierarchy',
163+
document.uri,
164+
position
165+
);
186166

187167
if (callHierarchyItems && callHierarchyItems.length > 0) {
188-
console.log('Call hierarchy found, generating new flow diagram');
189-
190168
const incomingCalls = await vscode.commands.executeCommand<vscode.CallHierarchyIncomingCall[]>(
191169
'vscode.provideIncomingCalls',
192170
callHierarchyItems[0]
193171
);
194172

195173
const newData = await generateFlowDiagramFromCallHierarchy(callHierarchyItems[0], incomingCalls);
196-
console.log(`New data generated: ${JSON.stringify(newData)}`);
197174

198-
let hasNewConnections = false;
199-
200-
// Add new nodes to globalData or find existing ones
201-
for (const newNode of newData.nodes) {
202-
if (newNode.id !== 0) { // Skip the root node as it already exists
203-
const existingNode = globalData.nodes.find(n => n.label === newNode.label && n.file === newNode.file);
204-
if (!existingNode) {
205-
const newNodeId = nextNodeId++;
206-
globalData.nodes.push({
207-
...newNode,
208-
id: newNodeId,
209-
visualized: false
210-
});
211-
console.log(`Added new node: ${JSON.stringify(globalData.nodes[globalData.nodes.length - 1])}`);
212-
hasNewConnections = true;
213-
}
214-
}
215-
}
216-
217-
// Add or update edges in globalData
218-
for (const newEdge of newData.edges) {
219-
if (newEdge.to === 0) {
220-
// This edge connects to the visualized node
221-
const fromNode = globalData.nodes.find(n => n.label === newData.nodes[newEdge.from].label && n.file === newData.nodes[newEdge.from].file);
222-
if (fromNode) {
223-
const existingEdge = globalData.edges.find(e => e.from === fromNode.id && e.to === nodeId);
224-
if (!existingEdge) {
225-
globalData.edges.push({ from: fromNode.id, to: nodeId, count: newEdge.count || 1 });
226-
console.log(`Added new edge: ${fromNode.id} -> ${nodeId}, count: ${newEdge.count || 1}`);
227-
hasNewConnections = true;
228-
} else {
229-
console.log(`Edge already exists: ${fromNode.id} -> ${nodeId}, count: ${existingEdge.count}`);
230-
}
231-
}
232-
}
233-
}
234-
235-
// Mark the current node as visualized
236-
node.visualized = true;
237-
238-
if (hasNewConnections) {
239-
if (panel) {
240-
console.log('Sending updated data to webview');
241-
panel.webview.postMessage({ command: 'updateDiagram', data: globalData, positions: Array.from(nodePositions.entries()) });
242-
} else {
243-
console.log('Panel is undefined, cannot update diagram');
244-
}
245-
} else {
246-
console.log('No new connections found, diagram not updated');
247-
vscode.window.showInformationMessage('No new connections found for this node.');
248-
}
249-
} else {
250-
console.log('No call hierarchy found');
251-
vscode.window.showInformationMessage('No call hierarchy found for the selected function');
175+
// Merge the new data with existing data and update the diagram
176+
mergeFlowData(newData);
177+
showFlowDiagram(globalData, context);
252178
}
253179
} catch (error) {
254180
console.error('Error in visualizeNode:', error);
@@ -266,7 +192,7 @@ async function generateFlowDiagramFromCallHierarchy(
266192
color: getRandomPastelColor(),
267193
file: item.uri.fsPath,
268194
line: item.range.start.line,
269-
character: item.range.start.character
195+
character: item.selectionRange.start.character
270196
}];
271197

272198
let edges: {from: number, to: number, count: number}[] = [];
@@ -281,13 +207,14 @@ async function generateFlowDiagramFromCallHierarchy(
281207
let i = 1;
282208
for (let [key, count] of callCounts) {
283209
const [fromName] = key.split('-');
210+
const caller = incomingCalls.find(call => call.from.name === fromName)!;
284211
nodes.push({
285212
id: i,
286213
label: fromName,
287214
color: getRandomPastelColor(),
288-
file: incomingCalls.find(call => call.from.name === fromName)!.from.uri.fsPath,
289-
line: incomingCalls.find(call => call.from.name === fromName)!.from.range.start.line,
290-
character: incomingCalls.find(call => call.from.name === fromName)!.from.range.start.character
215+
file: caller.from.uri.fsPath,
216+
line: caller.from.range.start.line,
217+
character: caller.from.selectionRange.start.character
291218
});
292219
edges.push({from: i, to: 0, count: count});
293220
i++;

0 commit comments

Comments
 (0)