a
    =a"                     @   sv   d Z ddlZddlmZ ddlmZmZ ddlmZ G dd dZ	G dd	 d	ee	Z
G d
d de	ZG dd dZdS )zHhandle diagram generation options for class diagram or default diagrams
    N)BUILTINS)ClassDiagramPackageDiagram)LocalsVisitorc                   @   s`   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd ZdS )DiaDefGeneratorz!handle diagram generation optionsc                 C   s    |j | _ |   || _d| _dS )z%common Diagram Handler initializationN)config_set_default_optionslinkerclassdiagramselfr	   Zhandler r   :lib/python3.9/site-packages/pylint/pyreverse/diadefslib.py__init__#   s    zDiaDefGenerator.__init__c                 C   s$   |j }| jr | j  d| }|S )zget title for objects.)namemodule_namesroot)r   nodetitler   r   r   	get_title*   s    zDiaDefGenerator.get_titlec                 C   s   |du rt | jjS |S )z3activate some options if not explicitly deactivatedN)boolr   classes)r   Zoptionr   r   r   _set_option1   s    zDiaDefGenerator._set_optionc                 C   s~   |  | jj| _|  | jj}|  | jj}d\}}|r<d}|rDd}| jjdurX| jj}| jjdurl| jj}|| | _| _dS )z6set different default options with _default dictionary)r   r   N)	r   r   r   all_ancestorsall_associatedZshow_ancestorsZshow_associated	anc_levelassociation_level)r   r   r   r   r   r   r   r   r   9   s    z$DiaDefGenerator._set_default_optionsc                 C   s   | j | jfS )zhelp function for search levels)r   r   )r   r   r   r   _get_levelsI   s    zDiaDefGenerator._get_levelsc                 C   s   | j jrdS | jtkS )z&true if builtins and not show_builtinsT)r   Zshow_builtinr   r   r   r   r   r   r   r   	show_nodeM   s    zDiaDefGenerator.show_nodec                 C   s$   | j | | j| || dS )z%visit one class and add it to diagramN)r	   visitr
   
add_objectr   r    r   r   r   	add_classS   s    zDiaDefGenerator.add_classc                 c   s4   |dkrdS |j ddD ]}| |s(q|V  qdS )z%return ancestor nodes of a class noder   NF)Zrecurs)Z	ancestorsr!   )r   r   levelancestorr   r   r   get_ancestorsX   s    
zDiaDefGenerator.get_ancestorsc                 c   sl   |dkrdS t |j t |j  D ]>}|D ]4}t|tjrF|j}t|tjr0| 	|s^q0|V  q0q(dS )z'return associated nodes of a class noder   N)
listZinstance_attrs_typevaluesZlocals_type
isinstanceastroidZInstanceZ_proxiedZClassDefr!   )r   
klass_noder%   Zassociation_nodesr   r   r   r   get_associateda   s    
zDiaDefGenerator.get_associatedc                 C   sp   | j |s| |sdS | | | ||D ]}| ||d | q0| ||D ]}| |||d  qTdS )z1extract recursively classes related to klass_nodeN   )r
   Zhas_noder!   r$   r'   extract_classesr-   )r   r,   r   r   r&   r   r   r   r   r/   o   s    
zDiaDefGenerator.extract_classesN)__name__
__module____qualname____doc__r   r   r   r   r   r!   r$   r'   r-   r/   r   r   r   r   r       s   	r   c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )DefaultDiadefGeneratorzgenerate minimum diagram definition for the project :

    * a package diagram including project's modules
    * a class diagram including project's classes
    c                 C   s   t | || t|  d S N)r   r   r   r   r   r   r   r      s    zDefaultDiadefGenerator.__init__c                 C   sF   | j j}t|jdkr*td|j || _nd| _td|j || _dS )z_visit a pyreverse.utils.Project node

        create a diagram definition for packages
        r.   zpackages %sNz
classes %s)	r   modelenmodulesr   r   
pkgdiagramr   r
   )r   r   r6   r   r   r   visit_project   s
    z$DefaultDiadefGenerator.visit_projectc                 C   s   | j r| j | jfS | jfS )z`leave the pyreverse.utils.Project node

        return the generated diagram definition
        )r9   r
   r    r   r   r   leave_project   s    z$DefaultDiadefGenerator.leave_projectc                 C   s&   | j r"| j| | j |j| dS )z_visit an astroid.Module node

        add this class to the package diagram definition
        N)r9   r	   r"   r#   r   r    r   r   r   visit_module   s    z#DefaultDiadefGenerator.visit_modulec                 C   s   |   \}}| ||| dS )z\visit an astroid.Class node

        add this class to the class diagram definition
        N)r   r/   )r   r   r   r   r   r   r   visit_classdef   s    z%DefaultDiadefGenerator.visit_classdefc                 C   s   | j r| j ||j dS )z?visit astroid.ImportFrom  and catch modules for package diagramN)r9   Zadd_from_dependmodnamer    r   r   r   visit_importfrom   s    z'DefaultDiadefGenerator.visit_importfromN)
r0   r1   r2   r3   r   r:   r;   r<   r=   r?   r   r   r   r   r4   |   s   		r4   c                   @   s    e Zd ZdZdd Zdd ZdS )ClassDiadefGeneratorz[generate a class diagram definition including all classes related to a
    given class
    c                 C   s   t | || d S r5   )r   r   r   r   r   r   r      s    zClassDiadefGenerator.__init__c                 C   s   t || jj| _t|jdkr:|dd\}}||}n|jd }|dd }t	|
|}|  \}}| ||| | jS )z^return a class diagram definition for the given klass and its
        related klasses
        r.   r   r   r   )r   r   r6   r
   r7   r8   rsplitZ
get_modulesplitnextZilookupr   r/   )r   projectklassmoduler   r   r   r   r   class_diagram   s    
z"ClassDiadefGenerator.class_diagramN)r0   r1   r2   r3   r   rG   r   r   r   r   r@      s   r@   c                   @   s    e Zd ZdZdd Zdd ZdS )DiadefsHandlerzYhandle diagram definitions :

    get it from user (i.e. xml files) or generate them
    c                 C   s
   || _ d S r5   )r   )r   r   r   r   r   r      s    zDiadefsHandler.__init__c                 C   sX   g }t || }| jjD ]}|||| q|sBt|| |}|D ]}|  qF|S )av  Get the diagrams configuration data

        :param project:The pyreverse project
        :type project: pyreverse.utils.Project
        :param linker: The linker
        :type linker: pyreverse.inspector.Linker(IdGeneratorMixIn, LocalsVisitor)

        :returns: The list of diagram definitions
        :rtype: list(:class:`pylint.pyreverse.diagrams.ClassDiagram`)
        )r@   r   r   appendrG   r4   r"   Zextract_relationships)r   rD   r	   Zdiagrams	generatorrE   Zdiagramr   r   r   get_diadefs   s    

zDiadefsHandler.get_diadefsN)r0   r1   r2   r3   r   rK   r   r   r   r   rH      s   rH   )r3   r+   Zpylint.constantsr   Zpylint.pyreverse.diagramsr   r   Zpylint.pyreverse.utilsr   r   r4   r@   rH   r   r   r   r   <module>   s   \7