Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ src/**/*.js.map
test_*.py
test_*.js
simple_test.py

# Sample project files (for testing module analysis)
sample_project/
90 changes: 90 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,28 @@

## ✨ Features

### 🔄 **Data Flow Analysis (NEW!)**

- **Global State Tracking**: Understand how global variables and state flow through your functions
- **Cross-Function Dependencies**: See which functions share data and how they interact
- **Dual Visualization Modes**:
- **Data Flow Graph**: Shows global state usage and data relationships
- **Function Call Graph**: Traditional call graph with data flow annotations
- **Smart Expansion**: Start from current function and automatically find related functions that share data
- **Large Codebase Navigation**: Trace data dependencies without manual ctrl+clicking through code
- **Multi-language Support**: Works with TypeScript, JavaScript, Python, Java, and more

### 🏗️ **Module Analysis**

- **Workspace-wide Analysis**: Get a 30,000 ft view of your entire codebase structure
- **Dependency Mapping**: Visualize how modules interact through imports, exports, and function calls
- **Multi-language Support**: Works with Python, TypeScript/JavaScript, and Java projects
- **Three Visualization Modes**:
- **Dependency Graph**: Shows module relationships and connections
- **Module Overview**: Displays imports and exports for each module
- **Dependency Matrix**: Connection counts and interaction patterns
- **Interactive Analysis**: Click to analyze workspace or focus on current file context

### 🔄 **Real-Time Flowchart Generation**

- Automatically generates flowcharts for functions as you navigate your code
Expand Down Expand Up @@ -88,6 +110,37 @@ def complex_function(data):

This function will show **Medium complexity (CC=6)** with ⚠️ indicators on decision nodes.

**Module Analysis Example:**

Create a simple Python project:

```python
# utils.py
def calculate_sum(numbers):
return sum(numbers)

class DataProcessor:
def process(self, data):
return calculate_sum(data)
```

```python
# main.py
from utils import DataProcessor, calculate_sum
import math

def main():
processor = DataProcessor()
result = processor.process([1, 2, 3, 4, 5])
sqrt_result = math.sqrt(result)
print(f"Result: {sqrt_result}")
```

The module analysis will show:
- **Dependencies**: main.py → utils.py, main.py → math (built-in)
- **Exports**: utils.py exports `calculate_sum` function and `DataProcessor` class
- **Function Calls**: Cross-module calls from main.py to utils.py functions

## Enhanced Node Readability

### Semantic Node Categories
Expand Down Expand Up @@ -133,6 +186,23 @@ Access theme and complexity settings via VS Code Settings (`Cmd/Ctrl + ,`) under

## 🚀 How to Use

### Module Analysis (NEW!)

1. **Open the Module Analysis View**: Click the Visor icon in the Activity Bar and select the "Module Analysis" tab
2. **Analyze Your Codebase**:
- **Workspace Analysis**: Click "🌐 Analyze Workspace" to get a complete overview of all modules
- **Current File Context**: Click "📄 Analyze Current File" to focus on the active file and its dependencies
3. **Explore Different Views**:
- **Dependencies**: Shows how modules connect to each other
- **Overview**: Detailed view of imports and exports per module
- **Matrix**: Connection counts and dependency patterns
4. **Interactive Features**:
- Pan and zoom the diagram
- Switch between visualization modes
- Export diagrams as SVG (coming soon)

### Function-Level Flowcharts

### Getting Started

1. **Install the Extension**: Search for "Visor" in the VS Code Extensions marketplace
Expand Down Expand Up @@ -236,6 +306,7 @@ Visor supports opening flowcharts in dedicated external windows for enhanced pro

### Core Components

#### Function-Level Analysis
- **AbstractParser**: Enhanced base class with semantic node creation and complexity analysis
- **ComplexityAnalyzer**: McCabe cyclomatic complexity calculation engine with language-specific support
- **ComplexityConfig**: Configuration management for complexity thresholds, indicators, and display options
Expand All @@ -247,6 +318,13 @@ Visor supports opening flowcharts in dedicated external windows for enhanced pro
- **FlowchartViewProvider**: Sidebar integration with complexity display and external window launcher
- **FlowchartPanelProvider**: Dedicated external window management with singleton pattern and proper cleanup

#### Module-Level Analysis (NEW!)
- **ModuleAnalyzer**: Core analyzer for workspace and file-context module analysis
- **ModuleAnalysisIR**: Intermediate representation for module dependencies, imports, exports, and function calls
- **Language Module Parsers**: Python, TypeScript/JavaScript, and Java parsers for extracting module-level information
- **ModuleMermaidGenerator**: Generates dependency graphs, module overviews, and dependency matrices
- **ModuleAnalysisProvider**: Webview provider for interactive module analysis visualization

### Performance Features

- **Object Pooling**: Reduces garbage collection overhead
Expand Down Expand Up @@ -303,6 +381,18 @@ code --extensionDevelopmentPath=.
- `yarn publish:patch`: Publishes a patch version
- `yarn release`: Full release workflow (test + publish + git tags)

### Commands

#### Function-Level Analysis
- **Visor: Generate Flowchart** - Generates flowchart for the current function
- **Visor: Open Flowchart in Panel** - Opens flowchart in a new panel/window
- **Visor: Open Flowchart to Side** - Opens flowchart beside current editor
- **Visor: Open Flowchart in New Column** - Opens flowchart in new column

#### Module-Level Analysis
- **Visor: Analyze Workspace Modules** - Analyzes all modules in the workspace
- **Visor: Analyze Current File Modules** - Analyzes current file and its dependencies

### Project Structure

```
Expand Down
23 changes: 23 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
"name": "Flowchart",
"type": "webview",
"icon": "media/icon.png"
},
{
"id": "visor.dataFlowView",
"name": "Data Flow",
"type": "webview",
"icon": "media/icon.png"
}
]
},
Expand Down Expand Up @@ -62,6 +68,16 @@
"command": "visor.maximizeFlowchartPanel",
"title": "Maximize Flowchart Panel",
"icon": "$(screen-full)"
},
{
"command": "visor.analyzeWorkspaceModules",
"title": "Analyze Workspace Modules",
"icon": "$(globe)"
},
{
"command": "visor.analyzeCurrentFileModules",
"title": "Analyze Current File Modules",
"icon": "$(file-code)"
}
],
"menus": {
Expand Down Expand Up @@ -100,6 +116,13 @@
{
"command": "visor.maximizeFlowchartPanel",
"when": "editorTextFocus"
},
{
"command": "visor.analyzeWorkspaceModules"
},
{
"command": "visor.analyzeCurrentFileModules",
"when": "editorTextFocus"
}
]
},
Expand Down
39 changes: 39 additions & 0 deletions sample_project/MainApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// MainApplication.java
package com.example.main;

import com.example.service.UserService;
import java.util.List;

public class MainApplication {
private UserService userService;

public MainApplication() {
this.userService = new UserService();
initializeData();
}

private void initializeData() {
userService.addUser("john_doe");
userService.addUser("jane_smith");
userService.addUser("admin");
}

public void run() {
System.out.println("Application started");

List<String> users = userService.getAllUsers();
System.out.println("Total users: " + userService.getUserCount());

for (String user : users) {
System.out.println("User: " + user);
}

boolean hasAdmin = userService.hasUser("admin");
System.out.println("Has admin: " + hasAdmin);
}

public static void main(String[] args) {
MainApplication app = new MainApplication();
app.run();
}
}
29 changes: 29 additions & 0 deletions sample_project/UserService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// UserService.java
package com.example.service;

import java.util.List;
import java.util.ArrayList;

public class UserService {
private List<String> users;

public UserService() {
this.users = new ArrayList<>();
}

public void addUser(String username) {
users.add(username);
}

public List<String> getAllUsers() {
return new ArrayList<>(users);
}

public int getUserCount() {
return users.size();
}

public boolean hasUser(String username) {
return users.contains(username);
}
}
34 changes: 34 additions & 0 deletions sample_project/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// app.ts
import { Calculator, add } from './math_utils';

class Application {
private calculator: Calculator;

constructor() {
this.calculator = new Calculator();
}

run(): void {
console.log("Starting application...");

// Use imported functions
const sum = add(10, 20);
console.log(`Direct addition: ${sum}`);

// Use calculator class
const calcResult1 = this.calculator.calculate('add', 5, 15);
const calcResult2 = this.calculator.calculate('multiply', 3, 7);

console.log(`Calculator results: ${calcResult1}, ${calcResult2}`);
console.log(`History: ${this.calculator.getHistory()}`);

this.displayResults([sum, calcResult1, calcResult2]);
}

private displayResults(results: number[]): void {
console.log("All results:", results);
}
}

const app = new Application();
app.run();
24 changes: 24 additions & 0 deletions sample_project/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# main.py
from utils import DataProcessor, calculate_average
import math

def main():
"""Main function that demonstrates module usage."""
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Use the DataProcessor class
processor = DataProcessor(data)
result = processor.process()

print(f"Data processing results: {result}")

# Use imported function directly
average = calculate_average(data)
print(f"Direct average calculation: {average}")

# Use standard library
sqrt_avg = math.sqrt(average)
print(f"Square root of average: {sqrt_avg}")

if __name__ == "__main__":
main()
34 changes: 34 additions & 0 deletions sample_project/math_utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// math_utils.ts
export function add(a: number, b: number): number {
return a + b;
}

export function multiply(a: number, b: number): number {
return a * b;
}

export class Calculator {
private history: number[] = [];

calculate(operation: string, a: number, b: number): number {
let result: number;

switch (operation) {
case 'add':
result = add(a, b);
break;
case 'multiply':
result = multiply(a, b);
break;
default:
result = 0;
}

this.history.push(result);
return result;
}

getHistory(): number[] {
return this.history.slice();
}
}
25 changes: 25 additions & 0 deletions sample_project/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# utils.py
def calculate_sum(numbers):
"""Calculate the sum of a list of numbers."""
total = 0
for num in numbers:
total += num
return total

def calculate_average(numbers):
"""Calculate the average of a list of numbers."""
if not numbers:
return 0
return calculate_sum(numbers) / len(numbers)

class DataProcessor:
def __init__(self, data):
self.data = data

def process(self):
"""Process the data using the utility functions."""
return {
'sum': calculate_sum(self.data),
'average': calculate_average(self.data),
'count': len(self.data)
}
Loading