Skip to main content
Glama
code_analyzer.cpython-310.pyc13.7 kB
o y�g�k�@s�dZddlZddlZddlZddlmZmZmZmZm Z m Z ddl Z ddl mZmZmZmZejejd�e�e�ZGdd�dej�ZGd d �d �ZGd d �d ej�ZdS) z} Code Analysis Engine Responsible for parsing code using Python's AST and extracting entities, relationships, and metadata. �N)�Dict�List�Optional�Any�Tuple�Set�)�KnowledgeGraph� ComponentType�ComponentStatus�RelationshipType)�levelcs0eZdZdZdd�Z�fdd�Zdd�Z�ZS)� CodeVisitorz%AST visitor that tracks parent nodes.cCs i|_dS�N)�parents)�self�r�X/Users/sparshdrolia/Sparsh personal/persistent-code-mcp/persistent_code/code_analyzer.py�__init__s zCodeVisitor.__init__cs&t�|�D]}||j|<qt��|�Sr)�ast�iter_child_nodesr�super�visit)r�node�child�� __class__rrrs  zCodeVisitor.visitcCs |j�|�S)zGet parent of a node safely.)r�get)rrrrr� get_parent$s zCodeVisitor.get_parent)�__name__� __module__� __qualname__�__doc__rrr� __classcell__rrrrrs  rc @s&eZdZdZdefdd�Zddedeedeed efd d �Zd e j d ed e e eeffdd�Z d e j d eded eeeffdd�Zde jdeded eeeffdd�Zd e j d eded eeeffdd�Zd e j d eded eeeffdd�Zd e j d edeeefdeeefdef dd�ZdS) � CodeAnalyzerz5Analyzes Python code and updates the knowledge graph.�knowledge_graphcCs ||_dS)zxInitialize the code analyzer. Args: knowledge_graph: The knowledge graph to update N)r%)rr%rrrr+s zCodeAnalyzer.__init__N� code_text� file_path� component_id�returnc Cs�zlt�|�}t�}|�|�|rtj�|�nd}|dur4|jj|t j |t j d|��|r/d|inid�}n |jj ||t j d�|�||�}|�|||�}|�|||�} |�|||�} |�||| ||�t�d|���|WSty�} zLt�dt| ����|dur�|jj|r�tj�|�ndt j |t jd | ��|r�|t| �d �nd t| �id�}n|jj ||t jd t| �id �|WYd} ~ Sd} ~ wty�} zt�d t| ����|r�|ndWYd} ~ Sd} ~ ww)aJAnalyze code and update the knowledge graph. Args: code_text: The code to analyze file_path: Path to the file (optional) component_id: ID of an existing component to update (optional) Returns: component_id: ID of the analyzed component zunnamed_file.pyNz Python file: �path��name�component_typer&�status� description�metadata)r(r&r.z Successfully analyzed code from zSyntax error in code: z Python file with syntax errors: )r*�errorr1)r(r&r.r0zError analyzing code: )r�parserr�osr*�basenamer%� add_componentr �FILEr � IMPLEMENTED�update_component�_analyze_imports�_analyze_classes�_analyze_functions�_analyze_variables�_analyze_relationships�logger�info� SyntaxError�warning�str�PARTIAL� Exceptionr1) rr&r'r(�tree�visitor� file_name�imported_modulesZ classes_map� functions_mapZ variables_map�errr� analyze_code3sd  � � �  ����zCodeAnalyzer.analyze_coderE�file_idc Cs\g}t�|�D]�}t|tj�r>|jD]*}|jj|jtj t j d|j��d|j d�d�}|jj ||tjd�|�|j|f�qqt|tj�r�|jpHd}|jj|tj t j d|��ddid�}|jD]L}|jj|rm|�d|j��n|jtjt j d |�d |j��d|j |d �d�} |jj || tjd�|jj || tjd�|�|r�|�d|j��n|j| f�q^q|S) z�Extract and record imports from the AST. Args: tree: AST of the code file_id: ID of the file component Returns: imported_modules: List of (module_name, component_id) tuples zImported module: T)�external�alias)r,r-r.r/r0�� source_id� target_id�relationship_type�rM�.zImported from �: )rMrN� parent_module)rr� isinstance�Import�namesr%r5r,r �MODULEr r7�asname�add_relationshipr �IMPORTS�append� ImportFrom�module�FUNCTION�CONTAINS) rrErLrHrr,� module_id� module_nameZparent_module_idZ import_idrrrr9�s`     � ��  �  � ��&�zCodeAnalyzer._analyze_importsrFc Cs�i}t�|�D]�}t|tj�r�t�|�pd}g}|jD]}t|tj�r)|�|j�qd} zM|j } d} t |d�r>|j r>|j } n|j rF|j dn|} t | d�rT| j rT| j } n| d} |j �|�d�d�} | | krx| t| �krxd�| | d| ��} Wn'ty�}zt�d |j�d t|����d |j�d �} WYd }~nd }~ww|j j|jtj| tj||dd�|j D�|j | fd�d�}|j j||tjd�|D]}|j j|tjgdd�}|r�|dd}|j j||tj d�q�|�!|||�}|||j<q|S)a3Extract and record classes from the AST. Args: tree: AST of the code file_id: ID of the file component visitor: AST visitor with parent tracking Returns: class_map: Dictionary mapping class names to component IDs rSr� end_lineno������r&� rz Error extracting class code for rUzclass z (...): ...NcSsg|] }t|tj�r|j�qSr)rWr� FunctionDefr,)�.0�mrrr� <listcomp> sz1CodeAnalyzer._analyze_classes.<locals>.<listcomp>)�bases�methods� line_ranger+rO��query�component_types�limit�id)"rrrW�ClassDef� get_docstringrm�Namer^rt�lineno�hasattrre�bodyr%� get_component�split�len�joinrDr>rAr,rBr5r �CLASSr r7r\r rb� search_code�INHERITS�_analyze_methods)rrErLrFZ class_mapr� docstringrm�base� class_code� start_line�end_line� last_child� code_linesrJ�class_idZbase_componentsZbase_id� method_maprrrr:�s|     �������� �� �zCodeAnalyzer._analyze_classes� class_noder�cCsi}|jD]�}t|tj�r�t�|�pd}dd�|jjD�}|j�dd�|��d�}d} ze|j� |�d� d�} |j |j } d } t |d �rN|j rN|j |j } n|jrV|jd n|} t | d �rg| j rg| j |j } n| d } d | kru| kr�nn| t| �kr�d�| | | d ��} nd|�d�} Wn*ty�}zt�d|j�d|j�dt|����d|�d�} WYd}~nd}~ww|jj|j�d|j��tj| tj|||jtdd�|jD��tdd�|jD��||j t|d d �fd�d�}|jj||tjd�|||j<q|S)aOExtract and record methods from a class definition. Args: class_node: AST node for the class class_id: ID of the class component visitor: AST visitor with parent tracking Returns: method_map: Dictionary mapping method names to component IDs rScS�g|]}|j�qSr��arg�rj�arrrrlC�z1CodeAnalyzer._analyze_methods.<locals>.<listcomp>�(�, �)r&rhrrerfrgr�def �: ...z!Error extracting method code for rTrUNcs�&�|]}t|tj�r|jdkVqdS)� staticmethodN�rWrrwrt�rj�drrr� <genexpr>n��$z0CodeAnalyzer._analyze_methods.<locals>.<genexpr>csr�)� classmethodNr�r�rrrr�or�)� signature�class� is_static�is_class_method�argsror+rO)rzrWrrirvr�r,r~r%r{r|rxryrer}rDr>rArBr5r �METHODr r7�any�decorator_list�getattrr\r rb)rr�r�rFr�rr�� arg_namesr�Z method_coder�r�r�r�rJZ method_idrrrr�0s`   $ �$����� �zCodeAnalyzer._analyze_methodsc Cs�i}t�|�D]�}t|tj�r�|�|�}|rt|tj�rqt�|�p#d}dd�|jjD�}|j�dd� |��d�} d} zM|j } d} t |d�rM|j rM|j } n|j rU|j d n|} t | d�rc| j rc| j } n| d } |j�|�d �d �}| | kr�| t|�kr�d � || d | ��} Wn&ty�}zt�d|j�dt|����d| �d�} WYd}~nd}~ww|jj|jtj| tj|| ||j | fd�d�}|jj||tjd�|||j<q|S)a;Extract and record functions from the AST. Args: tree: AST of the code file_id: ID of the file component visitor: AST visitor with parent tracking Returns: function_map: Dictionary mapping function names to component IDs rScSr�rr�r�rrrrl�r�z3CodeAnalyzer._analyze_functions.<locals>.<listcomp>r�r�r�rrerfrgr&rhrz#Error extracting function code for rUr�r�N)r�r�ror+rO)rrrWrirrurvr�r,r~rxryrerzr%r{r|r}rDr>rArBr5r rar r7r\r rb)rrErLrFZ function_mapr�parentr�r�r�Z function_coder�r�r�r�rJZ function_idrrrr;�s^   ������ �zCodeAnalyzer._analyze_functionsc Cs�i}t�|�D]Q}t|tj�rX|�|�}|r#t|tj�s"t|tj�r#q|jD]1}t|tj�rW|j j |j t j |j �d�tjd|j ��d|jid�}|j j||tjd�|||j <q&q|S)aBExtract and record global variables from the AST. Args: tree: AST of the code file_id: ID of the file component visitor: AST visitor with parent tracking Returns: variable_map: Dictionary mapping variable names to component IDs z = ...zGlobal variable: �liner+rO)rrrW�Assignrruri�targetsrwr%r5rtr �VARIABLEr r7rxr\r rb) rrErLrFZ variable_maprr��targetZ variable_idrrrr<�s2       �� � �zCodeAnalyzer._analyze_variables� functions�classescCst|||||�}|�|�dS)agAnalyze function calls and other relationships from the AST. Args: tree: AST of the code file_id: ID of the file component functions: Dictionary of function names to component IDs classes: Dictionary of class names to component IDs visitor: AST visitor with parent tracking N)�FunctionCallVisitorr)rrErLr�r�rFZ call_visitorrrrr=sz#CodeAnalyzer._analyze_relationships)NN)rr r!r"r rrBrrKr�Modulerrr9rrr:rur�r;r<r=rrrrr$(s($$Q$J$b$Q$Q/�� � ��r$c@s(eZdZdZdd�Zdd�Zdd�ZdS) r�z:Visitor that finds function calls and other relationships.cCs4||_||_||_||_||_d|_d|_g|_dSr)�analyzerrLr�r��parent_visitor�current_function�current_method�calls)rr�rLr�r�r�rrrrs zFunctionCallVisitor.__init__cCsl|j}|j}|j�|�}|r"t|tj�r"|j�d|j��|_d|_n|j|_d|_|�|�||_||_dS)NrT) r�r�r�rrWrrur,� generic_visit)rr� old_function� old_methodr�rrr�visit_FunctionDef!s   z%FunctionCallVisitor.visit_FunctionDefcCs~d}t|jtj�rM|jj}||jvrLd}|jr$|j|jvr$|j|j}n|jr<|jj j |jt j gdd�}|r<|dd}|rL|jj j ||j|tjd�nkt|jtj�r�t|jjtj�r�|jjj}|jj}||jvr�|jj j |�d|��t j gdd�}|r�d}|jr�|j|jvr�|j|j}n|jr�|jj j |jt j gdd�}|r�|dd}|r�|jj j ||ddtjd�|�|�dS)NrrprrtrOrT)rW�funcrrwrtr�r�r�r�r%r�r r�r\r �CALLS� Attribute�value�attrr�r�)rr� func_nameZ caller_idZmethod_components�obj_name� method_nameZcurrent_method_componentsrrr� visit_Call6sf � ��   ��  �zFunctionCallVisitor.visit_CallN)rr r!r"rr�r�rrrrr�s  r�)r"rr3�logging�typingrrrrrr�networkx�nxr%r r r r � basicConfig�INFO� getLoggerrr>� NodeVisitorrr$r�rrrr�<module>s  o

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sparshdrolia/Persistent-code-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server