Handled built in function

This commit is contained in:
abhigyantrumio 2025-08-04 03:49:32 +05:30
parent d92b1370d3
commit ac3559e19f
3 changed files with 368 additions and 30 deletions

View file

@ -226,6 +226,151 @@ public class ${name.replace(/\.[^/.]+$/, "")} {
}
};
// Generate content for built-in functions
const generateBuiltinFunctionContent = (functionName: string): string => {
switch (functionName) {
case 'round':
return `# Built-in Function: ${functionName}
"""
Rounds a number to the nearest integer.
"""
def round(number: float, ndigits: int = 0) -> float:
"""
Rounds a number to the nearest integer.
Args:
number (float): The number to round.
ndigits (int, optional): The number of decimal places to round to. Defaults to 0.
Returns:
float: The rounded number.
"""
# Implementation here
pass`;
case 'len':
return `# Built-in Function: ${functionName}
"""
Returns the number of items in an object.
"""
def len(obj: Any) -> int:
"""
Returns the number of items in an object.
Args:
obj (Any): The object to get the length of.
Returns:
int: The number of items.
"""
# Implementation here
pass`;
case 'print':
return `# Built-in Function: ${functionName}
"""
Prints the given arguments to the standard output.
"""
def print(*args, sep: str = " ", end: str = "\\n") -> None:
"""
Prints the given arguments to the standard output.
Args:
*args: The arguments to print.
sep (str, optional): The separator between arguments. Defaults to " ".
end (str, optional): The string to print at the end. Defaults to "\\n".
"""
# Implementation here
pass`;
case 'input':
return `# Built-in Function: ${functionName}
"""
Reads a line from the standard input.
"""
def input(prompt: str = "") -> str:
"""
Reads a line from the standard input.
Args:
prompt (str, optional): The prompt to display. Defaults to "".
Returns:
str: The input string.
"""
# Implementation here
pass`;
case 'open':
return `# Built-in Function: ${functionName}
"""
Opens a file and returns a file object.
"""
def open(file: str, mode: str = "r", buffering: int = -1, encoding: str | None = None, errors: str | None = None, newline: str | None = None) -> Any:
"""
Opens a file and returns a file object.
Args:
file (str): The path to the file.
mode (str, optional): The mode in which the file is opened. Defaults to "r".
buffering (int, optional): The buffering strategy. Defaults to -1.
encoding (str | None, optional): The encoding to use. Defaults to None.
errors (str | None, optional): How to handle encoding errors. Defaults to None.
newline (str | None, optional): How to handle newlines. Defaults to None.
Returns:
Any: The file object.
"""
# Implementation here
pass`;
case 'type':
return `# Built-in Function: ${functionName}
"""
Returns the type of an object.
"""
def type(obj: Any) -> type:
"""
Returns the type of an object.
Args:
obj (Any): The object to get the type of.
Returns:
type: The type of the object.
"""
# Implementation here
pass`;
case 'isinstance':
return `# Built-in Function: ${functionName}
"""
Checks if an object is an instance of a class or a tuple of classes.
"""
def isinstance(obj: Any, classinfo: type | tuple[type, ...]) -> bool:
"""
Checks if an object is an instance of a class or a tuple of classes.
Args:
obj (Any): The object to check.
classinfo (type | tuple[type, ...]): The class or tuple of classes to check against.
Returns:
bool: True if the object is an instance of the class or one of the classes in the tuple.
"""
# Implementation here
pass`;
case 'hasattr':
return `# Built-in Function: ${functionName}
"""
Checks if an object has an attribute.
"""
def hasattr(obj: Any, name: str) -> bool:
"""
Checks if an object has an attribute.
Args:
obj (Any): The object to check.
name (str): The name of the attribute to check for.
Returns:
bool: True if the object has the attribute, False otherwise.
"""
# Implementation here
pass`;
default:
return `# Built-in Function: ${functionName}
# No specific content available`;
}
};
// Get source info for selected node
const sourceInfo = useMemo((): SourceInfo | null => {
if (!selectedNodeId || !graph?.nodes) return null;
@ -258,21 +403,64 @@ public class ${name.replace(/\.[^/.]+$/, "")} {
// If still no file path, try reverse lookup by searching for the node name in file contents
if (!filePath && fileContents) {
console.log('SourceViewer - Searching file contents for node:', nodeName);
// Try multiple search patterns for the function
const searchPatterns = [
`def ${nodeName}(`, // Python function
`def ${nodeName} (`, // Python function with space
`function ${nodeName}(`, // JavaScript function
`function ${nodeName} (`, // JavaScript function with space
`const ${nodeName} =`, // JavaScript const
`let ${nodeName} =`, // JavaScript let
`var ${nodeName} =`, // JavaScript var
`class ${nodeName}`, // Class definition
`${nodeName}:`, // Object property or TypeScript type
`export const ${nodeName}`, // ES6 export
`export function ${nodeName}`, // ES6 export function
`public ${nodeName}(`, // Java/C# method
`private ${nodeName}(`, // Java/C# method
`protected ${nodeName}(`, // Java/C# method
// Also try with underscores and variations
`def ${nodeName}_`, // Python with underscore
`function ${nodeName}_`, // JavaScript with underscore
];
for (const [path, content] of fileContents) {
const patterns = [
`def ${nodeName}(`, // Python function
`function ${nodeName}(`, // JavaScript function
`const ${nodeName} =`, // JavaScript const
`class ${nodeName}`, // Class definition
`${nodeName}:`, // Object property or TypeScript type
];
console.log(`SourceViewer - Checking file: ${path}`);
if (patterns.some(pattern => content.includes(pattern))) {
// Check if any pattern matches
const foundPattern = searchPatterns.find(pattern => {
const found = content.includes(pattern);
if (found) {
console.log(`SourceViewer - Found pattern "${pattern}" in ${path}`);
}
return found;
});
if (foundPattern) {
filePath = path;
console.log('SourceViewer - Found file through content search:', filePath);
break;
}
}
// If still not found, try a more lenient search (case-insensitive)
if (!filePath) {
console.log('SourceViewer - Trying case-insensitive search for:', nodeName);
for (const [path, content] of fileContents) {
const lowerContent = content.toLowerCase();
const lowerNodeName = nodeName.toLowerCase();
if (lowerContent.includes(`def ${lowerNodeName}(`) ||
lowerContent.includes(`function ${lowerNodeName}(`) ||
lowerContent.includes(`const ${lowerNodeName} =`) ||
lowerContent.includes(`class ${lowerNodeName}`)) {
filePath = path;
console.log('SourceViewer - Found file through case-insensitive search:', filePath);
break;
}
}
}
}
}
@ -285,7 +473,23 @@ public class ${name.replace(/\.[^/.]+$/, "")} {
fileName,
nodeLabel: node.label,
nodeProperties: node.properties,
fileContentsSize: fileContents?.size || 0
fileContentsSize: fileContents?.size || 0,
// Add detailed relationship debugging
allRelationships: graph?.relationships?.length || 0,
containsRelationships: graph?.relationships?.filter(rel => rel.type === 'CONTAINS').length || 0,
relationshipsForThisNode: graph?.relationships?.filter(rel => rel.target === selectedNodeId || rel.source === selectedNodeId) || [],
fileNodesInGraph: graph?.nodes?.filter(n => n.label === 'File').map(n => ({
id: n.id,
path: n.properties.path,
filePath: n.properties.filePath,
name: n.properties.name
})) || [],
availableFileContents: fileContents ? Array.from(fileContents.entries()).map(([path, content]) => ({
path,
size: content.length,
firstLines: content.split('\n').slice(0, 3).join('\\n'),
containsSub: content.includes('def sub(') || content.includes('function sub(')
})) : []
});
// Try to get actual file content
@ -304,8 +508,20 @@ public class ${name.replace(/\.[^/.]+$/, "")} {
}
}
} else {
console.log('SourceViewer - No file content found, using mock content');
content = generateMockContent(node);
console.log('SourceViewer - No file content found, checking if this is a built-in function');
// Check if this is a built-in function
if (node.id.includes('builtin_') || nodeName === 'round' || nodeName === 'len' || nodeName === 'print' ||
['round', 'len', 'str', 'int', 'float', 'bool', 'list', 'dict', 'tuple', 'set',
'range', 'enumerate', 'zip', 'map', 'filter', 'sum', 'max', 'min', 'abs',
'print', 'input', 'open', 'type', 'isinstance', 'hasattr'].includes(nodeName)) {
content = generateBuiltinFunctionContent(nodeName);
console.log('SourceViewer - Using built-in function content for:', nodeName);
} else {
console.log('SourceViewer - Using mock content for user-defined node:', nodeName);
content = generateMockContent(node);
}
}
// Detect language from file extension

View file

@ -47,59 +47,165 @@ const GraphVisualization: React.FC<GraphVisualizationProps> = ({
const convertToD3Format = (graph: KnowledgeGraph) => {
const nodeIds = new Set<string>();
// Convert nodes
const nodes: D3Node[] = graph.nodes.map((node: GraphNode) => {
nodeIds.add(node.id);
// First pass: collect all node IDs and analyze the graph structure
graph.nodes.forEach(node => nodeIds.add(node.id));
// Calculate node metrics for intelligent sizing
const nodeMetrics = new Map<string, {
inDegree: number;
outDegree: number;
totalDegree: number;
depth: number;
isRoot: boolean;
childrenCount: number;
}>();
// Initialize metrics
graph.nodes.forEach(node => {
nodeMetrics.set(node.id, {
inDegree: 0,
outDegree: 0,
totalDegree: 0,
depth: 0,
isRoot: false,
childrenCount: 0
});
});
// Calculate degrees and relationships
graph.relationships.forEach(rel => {
const sourceMetrics = nodeMetrics.get(rel.source);
const targetMetrics = nodeMetrics.get(rel.target);
// Determine node color and size based on type
if (sourceMetrics && targetMetrics) {
sourceMetrics.outDegree++;
targetMetrics.inDegree++;
// For CONTAINS relationships, count children
if (rel.type.toLowerCase() === 'contains') {
sourceMetrics.childrenCount++;
}
}
});
// Calculate total degree and identify root nodes
nodeMetrics.forEach((metrics) => {
metrics.totalDegree = metrics.inDegree + metrics.outDegree;
// Root nodes typically have high out-degree and low/zero in-degree
metrics.isRoot = metrics.inDegree === 0 && metrics.outDegree > 0;
});
// Calculate depth (simplified - could be more sophisticated)
const calculateDepth = (nodeId: string, visited = new Set<string>()): number => {
if (visited.has(nodeId)) return 0;
visited.add(nodeId);
const parentRels = graph.relationships.filter(rel =>
rel.target === nodeId && rel.type.toLowerCase() === 'contains'
);
if (parentRels.length === 0) return 0; // Root level
const parentDepths = parentRels.map(rel => calculateDepth(rel.source, new Set(visited)));
return Math.max(...parentDepths, 0) + 1;
};
// Calculate depths for all nodes
graph.nodes.forEach(node => {
const metrics = nodeMetrics.get(node.id);
if (metrics) {
metrics.depth = calculateDepth(node.id);
}
});
// Convert nodes with intelligent sizing
const nodes: D3Node[] = graph.nodes.map((node: GraphNode) => {
const metrics = nodeMetrics.get(node.id)!;
// Determine base color and size based on type
let color = '#69b3a2';
let size = 8;
let baseSize = 8;
switch (node.label.toLowerCase()) {
case 'project':
color = '#2E7D32';
size = 20;
baseSize = 25; // Largest - project root
break;
case 'folder':
color = '#F57C00';
size = 12;
baseSize = 16;
break;
case 'file':
color = '#1976D2';
size = 10;
baseSize = 12;
break;
case 'function':
color = '#00796B';
size = 8;
baseSize = 8;
break;
case 'method':
color = '#00695C';
size = 7;
baseSize = 7;
break;
case 'class':
color = '#C2185B';
size = 10;
baseSize = 12;
break;
case 'variable':
color = '#546E7A';
size = 6;
baseSize = 6;
break;
default:
color = '#69b3a2';
size = 8;
baseSize = 8;
}
// Calculate final size based on multiple factors
let finalSize = baseSize;
// Factor 1: Hierarchy depth (higher levels = bigger)
const depthMultiplier = Math.max(0.7, 1.5 - (metrics.depth * 0.15));
finalSize *= depthMultiplier;
// Factor 2: Connection importance (more connections = bigger)
if (metrics.totalDegree > 0) {
const connectionMultiplier = 1 + Math.min(0.8, metrics.totalDegree * 0.1);
finalSize *= connectionMultiplier;
}
// Factor 3: Container nodes (nodes with children) should be bigger
if (metrics.childrenCount > 0) {
const containerMultiplier = 1 + Math.min(0.6, metrics.childrenCount * 0.08);
finalSize *= containerMultiplier;
}
// Factor 4: Root nodes get a boost
if (metrics.isRoot) {
finalSize *= 1.4;
}
// Factor 5: Special boost for hub nodes (high degree centrality)
if (metrics.totalDegree > 10) {
finalSize *= 1.3;
color = adjustColorBrightness(color, 20); // Make hub nodes slightly brighter
}
// Ensure size bounds
finalSize = Math.max(4, Math.min(35, finalSize));
return {
id: node.id,
label: node.properties.name as string || node.id,
nodeType: node.label.toLowerCase(),
properties: node.properties,
color,
size
size: Math.round(finalSize),
// Store metrics for potential future use
metrics
};
});
// Convert links with validation
// Convert links with validation (unchanged)
const links: D3Link[] = [];
graph.relationships.forEach((rel: GraphRelationship) => {
// Validate that both source and target nodes exist
@ -152,6 +258,18 @@ const GraphVisualization: React.FC<GraphVisualizationProps> = ({
return { nodes, links };
};
// Helper function to adjust color brightness
const adjustColorBrightness = (hex: string, percent: number): string => {
const num = parseInt(hex.replace("#", ""), 16);
const amt = Math.round(2.55 * percent);
const R = (num >> 16) + amt;
const G = (num >> 8 & 0x00FF) + amt;
const B = (num & 0x0000FF) + amt;
return "#" + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 +
(G < 255 ? G < 1 ? 0 : G : 255) * 0x100 +
(B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1);
};
// Initialize D3 visualization
useEffect(() => {
if (!svgRef.current || !graph) return;
@ -435,18 +553,17 @@ const GraphVisualization: React.FC<GraphVisualizationProps> = ({
const defaultStyle: React.CSSProperties = {
width: '100%',
height: style.height || '700px',
minHeight: '600px',
height: '100%',
minHeight: '400px',
border: '1px solid #37474F',
borderRadius: '8px',
backgroundColor: '#263238',
position: 'relative',
boxShadow: '0 4px 20px rgba(0,0,0,0.1)',
...style
};
return (
<div className={`graph-visualization ${className}`} style={{ position: 'relative', width: '100%', minHeight: '600px' }}>
<div className={`graph-visualization ${className}`} style={{ position: 'relative', width: '100%', height: '100%', minHeight: '400px' }}>
<svg
ref={svgRef}
style={defaultStyle}

View file

@ -618,6 +618,11 @@ const HomePage: React.FC = () => {
100% { transform: rotate(360deg); }
}
#root {
height: 100vh;
width: 100vw;
}
input:focus, textarea:focus {
border-color: ${colors.primary} !important;
box-shadow: 0 0 0 3px ${colors.primary}20 !important;