B
    A!p\!                 @   sn   d Z ddlZddlmZmZ ddlmZ d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)PackageDiagramClassDiagram)LocalsVisitorbuiltinsc               @   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	   handler r   :lib/python3.7/site-packages/pylint/pyreverse/diadefslib.py__init__!   s    zDiaDefGenerator.__init__c             C   s"   |j }| jrd| j |f }|S )zget title for objectsz%s.%s)namemodule_namesroot)r   nodetitler   r   r   	get_title(   s    zDiaDefGenerator.get_titlec             C   s   |dkrt | jjS |S )z3activate some options if not explicitly deactivatedN)boolr   classes)r   Zoptionr   r   r   _set_option/   s    zDiaDefGenerator._set_optionc             C   s~   |  | jj| _|  | jj}|  | jj}d\}}|r<d}|rDd}| jjdk	rX| jj}| jjdk	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   7   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_levelsG   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   BUILTINS_NAME)r   r   r   r   r   	show_nodeK   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   r   	add_classQ   s    zDiaDefGenerator.add_classc             c   s8   |dkrdS x&|j ddD ]}| |s*q|V  qW dS )z%return ancestor nodes of a class noder   NF)Zrecurs)Z	ancestorsr    )r   r   levelancestorr   r   r   get_ancestorsV   s    
zDiaDefGenerator.get_ancestorsc             c   st   |dkrdS xbt |j t |j  D ]B}x<|D ]4}t|tjrJ|j}t|tjr4| 	|sbq4|V  q4W q*W 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_associated_   s    
zDiaDefGenerator.get_associatedc             C   sx   | j |s| |sdS | | x&| ||D ]}| ||d | q2W x&| ||D ]}| |||d  qZW d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.   m   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   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   r4   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
        )r7   r
   )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)r7   r	   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 )zHvisit astroid.ImportFrom  and catch modules for package diagram
        N)r7   Zadd_from_dependmodname)r   r   r   r   r   visit_importfrom   s    z'DefaultDiadefGenerator.visit_importfromN)
r/   r0   r1   r2   r   r8   r9   r:   r;   r=   r   r   r   r   r3   z   s   		r3   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 )N)r   r   )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   r4   r
   r5   r6   rsplitZ
get_modulesplitnextZilookupr   r.   )r   projectklassmoduler   r   r   r   r   class_diagram   s    
z"ClassDiadefGenerator.class_diagramN)r/   r0   r1   r2   r   rF   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 )N)r   )r   r   r   r   r   r      s    zDiadefsHandler.__init__c             C   s`   g }t || }x"| jjD ]}|||| qW |sFt|| |}x|D ]}|  qLW |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   appendrF   r3   r!   Zextract_relationships)r   rC   r	   Zdiagrams	generatorrD   Zdiagramr   r   r   get_diadefs   s    

zDiadefsHandler.get_diadefsN)r/   r0   r1   r2   r   rJ   r   r   r   r   rG      s   rG   )r2   r*   Zpylint.pyreverse.diagramsr   r   Zpylint.pyreverse.utilsr   r   r   r3   r>   rG   r   r   r   r   <module>   s   \8