B
    A!p\²  ã               @   sd   d Z ddlmZ ddlZddlZddlZddlZdd„ ZG dd„ dƒZ	dd„ Z
dd	d
„Zdd„ ZdS )z^Graph manipulation utilities.

(dot generation adapted from pypy/translator/tool/make_dot.py)
é    Nc             C   s2   t  | ¡}t  t  | ¡¡}|  d¡d }|||fS )zDTransforms /some/path/foo.png into ('/some/path', 'foo.png', 'png').Ú.éÿÿÿÿ)ÚospÚbasenameÚdirnameÚabspathÚsplit)Úfilenamer   ÚstoredirÚtarget© r   ú+lib/python3.7/site-packages/pylint/graph.pyÚtarget_info_from_filename   s    
r   c               @   sL   e Zd ZdZddd„Zdd„ ZeeƒZdd	d
„Zdd„ Z	dd„ Z
dd„ ZdS )Ú
DotBackendzDot File backend.Núutf-8Údotc       	      C   s¼   |d kri }|| _ || _g | _d | _|  dt|ƒ ¡ |rH|  d| ¡ |rZ|  d| ¡ |rl|  d| ¡ |r–| ¡ dksˆtd| ƒ‚|  d| ¡ x | ¡ D ]}|  d 	|¡¡ q W d S )	Nzdigraph %s {z
rankdir=%szratio=%sz	size="%s")zutf-8z
iso-8859-1Úlatin1zunsupported charset %szcharset="%s"ú=)
Ú	graphnameÚrendererÚlinesÚ_sourceÚemitÚnormalize_node_idÚlowerÚAssertionErrorÚitemsÚjoin)	Úselfr   ZrankdirÚsizeZratioÚcharsetr   Zadditional_paramZparamr   r   r   Ú__init__    s&    

zDotBackend.__init__c             C   s,   | j dkr&|  d¡ d | j¡| _ | `| j S )zreturns self._sourceNz}
Ú
)r   r   r   r   )r   r   r   r   Ú
get_source?   s
    

zDotBackend.get_sourcec          
   C   s:  ddl }| j}|s.|r&| d¡r&|}nd| }|dk	rvt|ƒ\}}}|dkrht d|¡\}	}
t |	¡ q®t 	||¡}
n8d}t d|¡\}	}
t d|¡\}}t |	¡ t |¡ t
j|
dd	d
}	|	 | j¡ |	 ¡  |dkr6tjdk}|r|j| jdd|d||
d|g	|d n|j| jd||
d|g|d t |
¡ |S )a)  Generates a graph file.

        :param str outputfile: filename and path [defaults to graphname.png]
        :param str dotfile: filename and path [defaults to graphname.dot]
        :param str mapfile: filename and path

        :rtype: str
        :return: a path to the generated file
        r   Nz.dotz%s.dotr   Zpngz.pngÚwÚutf8)ÚencodingZwin32z-Tcmapxz-oz-T)Úshell)Ú
subprocessr   Úendswithr   ÚtempfileZmkstempÚosÚcloser   r   ÚcodecsÚopenÚwriteÚsourceÚsysÚplatformZcallr   Úunlink)r   Z
outputfileZdotfileZmapfiler(   Únamer
   Ú_r   ZpdotZdot_sourcepathZppngZ	use_shellr   r   r   ÚgenerateI   sN    






zDotBackend.generatec             C   s   | j  |¡ dS )zAdds <line> to final output.N)r   Úappend)r   Úliner   r   r   r   …   s    zDotBackend.emitc          	   K   sF   dd„ |  ¡ D ƒ}t|ƒt|ƒ }}|  d||d t|ƒ¡f ¡ dS )zwemit an edge from <name1> to <name2>.
        edge properties: see http://www.graphviz.org/doc/info/attrs.html
        c             S   s   g | ]\}}d ||f ‘qS )z%s="%s"r   )Ú.0ÚpropÚvaluer   r   r   ú
<listcomp>   s    z(DotBackend.emit_edge.<locals>.<listcomp>z%s -> %s [%s];z, N)r   r   r   r   Úsorted)r   Zname1Zname2ÚpropsÚattrsZn_fromZn_tor   r   r   Ú	emit_edge‰   s    zDotBackend.emit_edgec             K   s6   dd„ |  ¡ D ƒ}|  dt|ƒd t|ƒ¡f ¡ dS )ztemit a node with given properties.
        node properties: see http://www.graphviz.org/doc/info/attrs.html
        c             S   s   g | ]\}}d ||f ‘qS )z%s="%s"r   )r9   r:   r;   r   r   r   r<   •   s    z(DotBackend.emit_node.<locals>.<listcomp>z%s [%s];z, N)r   r   r   r   r=   )r   r4   r>   r?   r   r   r   Ú	emit_node‘   s    zDotBackend.emit_node)NNNr   r   N)NNN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r!   r#   Úpropertyr0   r6   r   r@   rA   r   r   r   r   r      s        

<r   c             C   s   d|  S )z)Returns a suitable DOT node id for `nid`.z"%s"r   )Znidr   r   r   r   ™   s    r   c             C   s@   | sdS g }|dkr|   ¡ }x|D ]}t| g tƒ ||ƒ q"W |S )z·given a dictionary representing an ordered graph (i.e. key are vertices
    and values is a list of destination vertices representing edges), return a
    list of detected cycles
    r   N)ÚkeysÚ_get_cyclesÚset)Ú
graph_dictZverticesÚresultÚverticer   r   r   Ú
get_cyclesž   s    
rM   c       	      C   sà   ||kr||g}x,|ddd… D ]}||kr,P |  d|¡ qW t|ƒ}| |¡}||d… |d|…  }||krx| |¡ dS | |¡ y8x2| | D ]&}||kr’t| ||||ƒ | |¡ q’W W n tk
rÒ   Y nX | ¡  dS )z5recursive function doing the real work for get_cyclesNr   r   )ÚinsertÚminÚindexr7   rH   ÚaddÚKeyErrorÚpop)	rJ   ÚpathZvisitedrK   rL   ÚcycleZnodeZ
start_fromrP   r   r   r   rH   ­   s*    


rH   )N)rE   Úos.pathrT   r   r+   r1   r*   r-   r   r   r   rM   rH   r   r   r   r   Ú<module>   s   |
