
    Je?                        d Z ddlZ ej                  d      Zd Z G d d      Z G d d      Z G d	 d
      Z G d d      Z G d de      Z	 G d de      Z
 G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d d e      Z G d! d"e      Z G d# d$e      Z G d% d&e      Z G d' d(e      Z G d) d*e      Zy)+z9Snippet Abstract Syntax Tree (AST) nodes and definitions.    Nz(\\)([^\\\s])c                 f    | \  }}d}|dk(  r
|dz  }d}d}n|dk(  rd}n|t        |      z  }||f|fS )NT
   r   F)len)offsetvaluelinecolmark_for_positions        =/usr/lib/python3/dist-packages/spyder/utils/snippets/nodes.py_compute_offset_strr      sW    ID#}	!	$!s5z#;)))    c                   $    e Zd ZdZdZdZdZdZdZy)SnippetKindtabstopplaceholderchoicevariablevariable_placeholderregexN)	__name__
__module____qualname__TABSTOPPLACEHOLDERCHOICEVARIABLEVARIABLE_PLACEHOLDERREGEX r   r   r   r      s!    GKFH1Er   r   c                       e Zd ZdZdZdZdZy)
FormatKindsimpleifif_elseelseN)r   r   r   SIMPLEIFIF_ELSEELSEr!   r   r   r#   r#   &   s    F	BGDr   r#   c                       e Zd ZdZdZdZy)NodeKindtextleafformatN)r   r   r   TEXTLEAFFORMATr!   r   r   r-   r-   -   s    DDFr   r-   c                   @    e Zd ZdZdZd
dZd Zd Zd Zd Z	d Z
d	 Zy)ASTNodez
    Base class that represents a node on a snippet AST.

    All other nodes should extend this class directly or indirectly.
    Nc                 t    || _         d | _        d| _        d| _        d| _        d| _        d| _        d| _        y )NTFr    )positionparentr   index_in_parent	to_deletedepthnamer	   selfr9   s     r   __init__zASTNode.__init__?   s<     !%!
	
r   c                     || _         y)zUpdates node text position.N)r9   r?   s     r   update_positionzASTNode.update_positionI   s	     r   c                     |S )z;Given a (line, col) position, compute actual node position.r!   )r@   r   s     r   compute_positionzASTNode.compute_positionM   s    r   c                      y)z{
        Update a node value or representation.

        Downstream classes can override this method if necessary.
        Nr!   r@   r	   s     r   updatezASTNode.updateQ        	r   c                      y)z
        This function should return a string that represents the current node.

        Downstream classes can override this method if necessary.
        Nr!   r@   s    r   r.   zASTNode.textY   rI   r   c                     d| _         y)zMark an AST node for deletion.TN)r<   rK   s    r   deletezASTNode.deletea   s	    r   c                 &    |j                  |        y)z*Accept visitor to iterate through the AST.N)visitr@   visitors     r   acceptzASTNode.accepte   s    dr   ))r   r   rS   )r   r   r   __doc__KINDrA   rC   rE   rH   r.   rM   rR   r!   r   r   r5   r5   4   s1     D!r   r5   c                   z    e Zd ZdZej
                  Zd Zed        Z	e	j                  d        Z	d Zd Zd Zd Zy	)
TextNodezw
    AST node representing a text sequence.

    The sequence is composed of one or more LeafNodes or any ASTNode.
    c                     t         j                  |        || _        t        |      D ]'  \  }}||_        | |_        | j                  dz   |_        ) y Nr   )r5   rA   _tokens	enumerater;   r:   r=   r@   tokensitokens       r   rA   zTextNode.__init__s   sM    !&) 	)HAu$%E!EL**q.EK	)r   c                     | j                   S N)rZ   rK   s    r   r]   zTextNode.tokens{   s    ||r   c                 |    || _         t        |      D ]'  \  }}||_        | j                  dz   |_        | |_        ) y rY   )rZ   r[   r;   r=   r:   r\   s       r   r]   zTextNode.tokens   s?    !&) 	 HAu$%E!**q.EKEL	 r   c                    g }|}t        | j                        D ]  \  }}| j                  dz   |_        |j                  |      }|j                  s8|j
                  }|t        | j                        dz
  k(  r]t        |      dk(  rOt        |t              r|d   }|d   \  }}||f||dz   ff}t        |t              r|j                  dk(  r||f||ff}|t        |      z  } g }	|D ])  }
t        |
t              r|	|
z  }	|	j                  |
       + g }g }d }d }d }|	D ]T  \  }}||}|j                  ||f       n3||dz   k(  r+|j                  ||f       |j                  |       ||fg}|}||}}V ||k(  r!t        |      dkD  r|j                  ||f       t        |      dkD  r|j                  |       || _        |S )Nr   r   EPSILON)r[   rZ   r=   rE   r   r9   r   
isinstancelistLeafNoder>   append)r@   r   polygoncurrent_offsetr^   r_   r9   xyflatten_polygonsegmentsegmentscurrent_segment	current_x	current_y
previous_xs                   r   rE   zTextNode.compute_position   s   !$,,/ 	*HAu**q.EK"33NCN&& >>DLL)A--8})%h5'/{H'{1%&FQAJ#7%eX6$zzY6-.FQF+;4>)	*  	0G'4(7*&&w/		0
 		
# 		(DAq 
&&1v.i!m#&&	9'=>0$%q6(
#$ayI		( 
"?#a'&&	9'=>!#OOO, r   c                 z    dj                  | j                  D cg c]  }|j                          c}      S c c}w Nr8   )joinrZ   r.   r@   r_   s     r   r.   zTextNode.text   s)    ww$,,?

?@@?s   8c                 j    |j                  |        | j                  D ]  }|j                  |        y ra   )rO   rZ   rR   )r@   rQ   r_   s      r   rR   zTextNode.accept   s-    d\\ 	"ELL!	"r   c                 T    d| _         | j                  D ]  }|j                           y NT)r<   r]   rM   rw   s     r   rM   zTextNode.delete   s%    [[ 	ELLN	r   N)r   r   r   rT   r-   r1   rU   rA   propertyr]   setterrE   r.   rR   rM   r!   r   r   rW   rW   j   sY     ==D)   ]]   -^A"
r   rW   c                   H    e Zd ZdZej
                  ZddZd Zd Z	d Z
d Zy)	rg   z'Node that represents a terminal symbol.c                 J    t         j                  |        || _        || _        y ra   )r5   rA   r>   r	   )r@   r>   r	   s      r   rA   zLeafNode.__init__   s    	
r   c                     | j                         }t        ||      \  }}|| _        t        | j                        dk(  r
|f| _        |S ||f| _        |S rY   )r.   r   r   r   r	   r9   )r@   r   r	   
new_offsetr   s        r   rE   zLeafNode.compute_position   s\    		(;FE(J%
%!2tzz?a#IDM  $Z0DMr   c                 n    t         j                  d| j                        }| j                  dk(  r|dd  }|S )Nz\2left_curly_namer   )BACKSLASH_REPLACE_REGEXsubr	   r>   )r@   r.   s     r   r.   zLeafNode.text   s5    &**5$**=99))8Dr   c                 N    dj                  | j                  | j                        S )NzLeafNode({0}: {1}))r0   r>   r	   rK   s    r   __str__zLeafNode.__str__   s    #**499djjAAr   c                 @    dj                  | j                               S )Nz{0})r0   r   rK   s    r   __repr__zLeafNode.__repr__   s    }}T\\^,,r   N)rd   r8   )r   r   r   rT   r-   r2   rU   rA   rE   r.   r   r   r!   r   r   rg   rg      s(    1==D
B-r   rg   c                       e Zd ZdZy)SnippetASTNodez}
    Stub node that represents an actual snippet.

    Used to unify type hierarchies between int and variable snippets.
    N)r   r   r   rT   r!   r   r   r   r      s    
 	r   r   c                       e Zd ZdZd Zy)
FormatNodez_
    Base regex formatting node.

    All regex formatting nodes should extend this class.
    c                      y)z
        Transform a regex match.

        This method takes a regex result and applies some transformation to
        return a new string.
        r8   r!   r@   regex_results     r   transform_regexzFormatNode.transform_regex   s     r   N)r   r   r   rT   r   r!   r   r   r   r      s    r   r   c                       e Zd ZdZej
                  ZddZed        Z	e	j                  d        Z	d Zd Zd Zd	 Zd
 Zy)TabstopSnippetNodezp
    Node that represents an int tabstop snippet.

    This node represents the expressions ${int} or $int.
    Nc                     t         j                  |        t        t                     }t	        |j
                        | _        ||n|| _        | | j                  _        | j                  dz   | j                  _	        y rY   )
r   rA   rW   rg   intr	   number_placeholderr:   r=   )r@   r   r   default_placeholders       r   rA   zTabstopSnippetNode.__init__
  sd    %&xz2&,,',7,C[0 	#' "&**q.r   c                     | j                   S ra   r   rK   s    r   r   zTabstopSnippetNode.placeholder  s       r   c                 p    || _         | j                  dz   | j                   _        | | j                   _        y rY   )r   r=   r:   r@   r   s     r   r   zTabstopSnippetNode.placeholder  s.    '"&**q.#' r   c                 J   t        | j                  t              r:| j                  dz   | j                  _        | j                  j	                  |      }n3t        | j                  t
              rt        || j                        \  }}| j                  j                  | _        S rY   )re   r   r5   r=   rE   strr   r9   )r@   r   end_position_s       r   rE   z#TabstopSnippetNode.compute_position  s}    d''1&*jj1nD#,,==fEL))3/1&$:K:KLOL!))22r   c                     || _         y ra   r   )r@   new_placeholders     r   rH   zTabstopSnippetNode.update(  s
    +r   c                 6    | j                   j                         S ra   )r   r.   rK   s    r   r.   zTabstopSnippetNode.text+  s      %%''r   c                 \    |j                  |        | j                  j                  |       y ra   )rO   r   rR   rP   s     r   rR   zTabstopSnippetNode.accept.  s"    d  )r   c                 F    d| _         | j                  j                          y rz   )r<   r   rM   rK   s    r   rM   zTabstopSnippetNode.delete2  s      "r   ra   )r   r   r   rT   r   r   rU   rA   r{   r   r|   rE   rH   r.   rR   rM   r!   r   r   r   r      s`     D1 ! ! ( (
,(*#r   r   c                   6    e Zd ZdZej
                  ZddZd Zy)PlaceholderNodez
    Node that represents an int tabstop placeholder snippet.

    This node represents the expression ${int: placeholder}, where placeholder
    can be a snippet or text.
    c                 2    t         j                  | ||       y ra   )r   rA   )r@   r   r   s      r   rA   zPlaceholderNode.__init__A  s    ##D&+>r   c                    t        | j                  t              r| j                  S t        | j                  t              r| j                  j	                         S t        dj                  t        | j                                    )Nz<Placeholder should be of type SnippetASTNode or str, got {0})re   r   r   r5   r.   
ValueErrorr0   typerK   s    r   r.   zPlaceholderNode.textD  sm    d''-$$$))73$$))++ >>Df!%d&7&7!8?:; ;r   N)r8   )	r   r   r   rT   r   r   rU   rA   r.   r!   r   r   r   r   7  s     ""D?;r   r   c                   4    e Zd ZdZej
                  Zd Zd Zy)
ChoiceNodez
    Node that represents an int tabstop choice snippet.

    This node represents the expression ${int:|options|}, where options are
    text sequences separated by comma.
    c                 Z    t         j                  | ||d          |d   | _        || _        y )Nr   )r   rA   current_choicechoices)r@   r   r   s      r   rA   zChoiceNode.__init__Y  s+    ##D&'!*=%ajr   c                     || j                   vr%t        dj                  || j                               || _        || _        y )NzEChoice {0} is not a valid value for this snippet, expected any of {1})r   LookupErrorr0   r   r   )r@   r   s     r   rH   zChoiceNode.update^  sG    %  ==CV"($,,>89 9 %"r   N)	r   r   r   rT   r   r   rU   rA   rH   r!   r   r   r   r   O  s     D
#r   r   c                   :    e Zd ZdZej
                  Zd Zd Zd Z	y)VariableSnippetNodez
    Node that represents a variable snippet.

    This node represents the expression ${var} or $var, where var is some
    variable qualified name.
    c                 J    t         j                  |        || _        || _        y ra   )r   rA   r   r	   )r@   r   s     r   rA   zVariableSnippetNode.__init__t  s    % 
r   c                     || _         y ra   r	   rG   s     r   rH   zVariableSnippetNode.updatey  s	    
r   c                     | j                   S ra   r   rK   s    r   r.   zVariableSnippetNode.text|  s    zzr   N)
r   r   r   rT   r   r   rU   rA   rH   r.   r!   r   r   r   r   j  s#     D
r   r   c                   :    e Zd ZdZej
                  Zd Zd Zd Z	y)VariablePlaceholderNodez
    Node that represents a variable placeholder snippet.

    This node represents the expression ${var: placeholder}, where placeholder
    can be a snippet or text.
    c                 >    t         j                  | |       || _        y ra   )r   rA   r   )r@   r   r   s      r   rA   z VariablePlaceholderNode.__init__  s    $$T84'r   c                     || _         y ra   r   r   s     r   rH   zVariablePlaceholderNode.update  s
    'r   c                     t        | j                  t              r| j                  S t        | j                  t              r| j                  j	                         S y ra   )re   r   r   r5   r.   rK   s    r   r.   zVariablePlaceholderNode.text  sJ    d''-$$$))73 $$))++ 4r   N)
r   r   r   rT   r   r   rU   rA   rH   r.   r!   r   r   r   r     s#     ++D((,r   r   c                   4    e Zd ZdZej
                  Zd Zd Zy)	RegexNodea   
    Node that represents a variable regex transformation snippet.

    This node represents the expression ${var/regex/format/options}, where
    regex is a PCRE-valid regex expression, format corresponds to a FormatNode
    and options is a TextNode containing valid regex options.
    c                     t         j                  | |       t        j                  |j	                               | _        || _        || _        y ra   )r   rA   recompiler.   r   r0   options)r@   r   r   fmtr   s        r   rA   zRegexNode.__init__  s6    $$T84ZZ

-
r   c                     t        d      )Nz5Regex variable snippets are not currently implemented)NotImplementedErrorrK   s    r   r.   zRegexNode.text  s     " #> ? 	?r   N)	r   r   r   rT   r   r    rU   rA   r.   r!   r   r   r   r     s     D?r   r   c                   @    e Zd ZdZej
                  Zd Zd Zd Z	d Z
y)FormatSequenceNodez<Node that represents a sequence of formatting or text nodes.c                 <    t         j                  |        || _        y ra   )r   rA   formatting_nodes)r@   r   s     r   rA   zFormatSequenceNode.__init__  s    D! 0r   c                 :    | j                   j                  |       y ra   )r   rh   )r@   r   s     r   
add_formatzFormatSequenceNode.add_format  s    $$S)r   c                     d}| j                   D ]K  }t        |t              r||j                         z  }'t        |t              s8||j                  |      z  }M |S ru   )r   re   rW   r.   r   r   )r@   r   resultr   s       r   r   z"FormatSequenceNode.transform_regex  s\    (( 	<C#x(#((*$C,#--l;;		<
 r   c                 j    |j                  |        | j                  D ]  }|j                  |        y ra   )rO   r   )r@   rQ   r   s      r   rR   zFormatSequenceNode.accept  s/    d(( 	CMM#	r   N)r   r   r   rT   r#   r(   rU   rA   r   r   rR   r!   r   r   r   r     s$    FD1*r   r   c                   4    e Zd ZdZej
                  Zd Zd Zy)SimpleFormatNodez
    Extract a single group from a regex match.

    This node represents the expression $int or ${int} where int corresponds
    to a group on a regex match.
    c                 <    t         j                  |        || _        y ra   )r   rA   group_number)r@   r   s     r   rA   zSimpleFormatNode.__init__  s    D!(r   c                 8    |j                  | j                        S ra   )groupr   r   s     r   r   z SimpleFormatNode.transform_regex  s    !!$"3"344r   N)	r   r   r   rT   r-   r3   rU   rA   r   r!   r   r   r   r     s     ??D)5r   r   c                   4    e Zd ZdZej
                  Zd Zd Zy)IfFormatNodez
    Choose a string if a regex group was found.

    This node represents the expression ${group :+ value_if_exists}, where
    value_if_exists is evaluated if $group is present on the regex match.
    c                 >    t         j                  | |       || _        y ra   )r   rA   positive_match)r@   r   r   s      r   rA   zIfFormatNode.__init__      !!$5,r   c                 v    d}|j                  | j                        | j                  j                  |      }|S ru   )r   r   r   r   r@   r   r   s      r   r   zIfFormatNode.transform_regex  s9    d//0<((88FFr   N)	r   r   r   rT   r#   r)   rU   rA   r   r!   r   r   r   r     s     ==D-r   r   c                   4    e Zd ZdZej
                  Zd Zd Zy)
IfElseNodea/  
    Choose a string if a regex group was found, otherwise choose other.

    This node represents the expression
    ${group ?: value_if_exists : value_otherwise}, where
    value_if_exists is evaluated if $group is present on the regex match,
    otherwise, the node value_otherwise is evaluated.
    c                 L    t         j                  | |       || _        || _        y ra   )r   rA   r   negative_match)r@   r   r   r   s       r   rA   zIfElseNode.__init__  s"    !!$5,,r   c                     d}|j                  | j                        | j                  j                  |      }|S | j                  j                  |      }|S ru   )r   r   r   r   r   r   s      r   r   zIfElseNode.transform_regex  sX    d//0<((88FF  ((88FFr   N)	r   r   r   rT   r#   r*   rU   rA   r   r!   r   r   r   r     s     D-
r   r   c                   4    e Zd ZdZej
                  Zd Zd Zy)ElseNodea  
    Choose a string if a regex group was not found.

    This node represents the expression ${group :- value_if_not_exists}, where
    value_if_not_exists is evaluated if $group is not present on the
    regex match, otherwise the group value is returned.
    c                 >    t         j                  | |       || _        y ra   )r   rA   r   )r@   r   r   s      r   rA   zElseNode.__init__  r   r   c                     d}|j                  | j                        | j                  j                  |      }|S |j                  | j                        }|S ru   )r   r   r   r   r   s      r   r   zElseNode.transform_regex  sX    d//08((88FF  "''(9(9:Fr   N)	r   r   r   rT   r#   r+   rU   rA   r   r!   r   r   r   r     s     ??D-r   r   )rT   r   r   r   r   r   r#   r-   r5   rW   rg   r   r   r   r   r   r   r   r   r   r   r   r   r   r!   r   r   <module>r      s   @ 	$"**%56 *   3 3lWw Wt-w -B	W 	 $4# 4#n;( ;0## #6. ,,1 ,4?# ?2 65z 5$# *! 4 r   