
    G@d?                     D   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dS )+z9Snippet Abstract Syntax Tree (AST) nodes and definitions.    Nz(\\)([^\\\s])c                 r    | \  }}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        ;lib/python3.11/site-packages/spyder/utils/snippets/nodes.py_compute_offset_strr      sc    ID#}}	!	$!s5zz#;)))    c                   &    e Zd ZdZdZdZdZdZdZdS )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EEEr   r   c                       e Zd ZdZdZdZdZdS )
FormatKindsimpleifif_elseelseN)r   r   r   SIMPLEIFIF_ELSEELSEr!   r   r   r#   r#   &   s"        F	BGDDDr   r#   c                       e Zd ZdZdZdZdS )NodeKindtextleafformatN)r   r   r   TEXTLEAFFORMATr!   r   r   r-   r-   -   s        DDFFFr   r-   c                   B    e Zd ZdZdZddZd Zd Zd Zd Z	d	 Z
d
 ZdS )ASTNodez
    Base class that represents a node on a snippet AST.

    All other nodes should extend this class directly or indirectly.
    Nr   r   r7   c                 v    || _         d | _        d| _        d| _        d| _        d| _        d| _        d| _        d S )NTFr    )positionparentr   index_in_parent	to_deletedepthnamer	   selfr;   s     r   __init__zASTNode.__init__?   s@     !%!
	


r   c                     || _         dS )zUpdates node text position.N)r;   rA   s     r   update_positionzASTNode.update_positionI   s     r   c                     |S )z;Given a (line, col) position, compute actual node position.r!   )rB   r   s     r   compute_positionzASTNode.compute_positionM   s    r   c                     dS )z{
        Update a node value or representation.

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

        Downstream classes can override this method if necessary.
        Nr!   rB   s    r   r.   zASTNode.textY   rK   r   c                     d| _         dS )zMark an AST node for deletion.TN)r>   rM   s    r   deletezASTNode.deletea   s    r   c                 0    |                     |            dS )z*Accept visitor to iterate through the AST.N)visitrB   visitors     r   acceptzASTNode.accepte   s    dr   )r6   )r   r   r   __doc__KINDrC   rE   rG   rJ   r.   rO   rT   r!   r   r   r5   r5   4   s          D   ! ! !            r   r5   c                   t    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d	S )
TextNodezw
    AST node representing a text sequence.

    The sequence is composed of one or more LeafNodes or any ASTNode.
    c                     t                               |            || _        t          |          D ]"\  }}||_        | |_        | j        dz   |_        #d S Nr   )r5   rC   _tokens	enumerater=   r<   r?   rB   tokensitokens       r   rC   zTextNode.__init__s   s`    !&)) 	) 	)HAu$%E!EL*q.EKK	) 	)r   c                     | j         S N)r[   rM   s    r   r^   zTextNode.tokens{   s
    |r   c                 x    || _         t          |          D ]"\  }}||_        | j        dz   |_        | |_        #d S rZ   )r[   r\   r=   r?   r<   r]   s       r   r^   zTextNode.tokens   sL    !&)) 	  	 HAu$%E!*q.EKELL	  	 r   c                    g }|}t          | j                  D ]\  }}| j        dz   |_        |                    |          }|j        r|j        }|t          | j                  dz
  k    rnt          |          dk    r[t          |t                    r|d         }|d         \  }}||f||dz   ff}t          |t                    r|j
        dk    r||f||ff}|t          |          z  }g }	|D ]2}
t          |
t                    r|	|
z  }	|	                    |
           3g }g }d }d }d }|	D ]a\  }}||}|                    ||f           n<||dz   k    r3|                    ||f           |                    |           ||fg}|}||}}b||k    r*t          |          dk    r|                    ||f           t          |          dk    r|                    |           || _        |S )Nr   r   EPSILON)r\   r[   r?   rG   r   r;   r   
isinstancelistLeafNoder@   append)rB   r   polygoncurrent_offsetr_   r`   r;   xyflatten_polygonsegmentsegmentscurrent_segment	current_x	current_y
previous_xs                   r   rG   zTextNode.compute_position   s_   !$,// 	* 	*HAu*q.EK"33NCCN& * >DL))A---8}}))%h55 3'/{H'{1%&FQAJ#7%eX66 <$zY66-.FQF+;4>>) 	0 	0G'4(( 07*&&w////		
# 		( 		(DAq 
&&1v....i!m##&&	9'=>>>000$%q6(
#$ayII
""?##a''&&	9'=>>>!##OOO,,, r   c                 J    d                     d | j        D                       S )Nr:   c                 6    g | ]}|                                 S r!   )r.   ).0r`   s     r   
<listcomp>z!TextNode.text.<locals>.<listcomp>   s     ???

???r   )joinr[   rM   s    r   r.   zTextNode.text   s%    ww??$,???@@@r   c                 n    |                     |            | j        D ]}|                    |           d S rb   )rQ   r[   rT   )rB   rS   r`   s      r   rT   zTextNode.accept   sD    d\ 	" 	"ELL!!!!	" 	"r   c                 P    d| _         | j        D ]}|                                 d S NT)r>   r^   rO   )rB   r`   s     r   rO   zTextNode.delete   s3    [ 	 	ELLNNNN	 	r   N)r   r   r   rU   r-   r1   rV   rC   propertyr^   setterrG   r.   rT   rO   r!   r   r   rX   rX   j   s          =D) ) )   X ]    ] - - -^A A A" " "
    r   rX   c                   @    e Zd ZdZej        Zd
dZd Zd Z	d Z
d Zd	S )rh   z'Node that represents a terminal symbol.re   r:   c                 V    t                               |            || _        || _        d S rb   )r5   rC   r@   r	   )rB   r@   r	   s      r   rC   zLeafNode.__init__   s(    	


r   c                     |                                  }t          ||          \  }}|| _        t          | j                  dk    r	|f| _        n	||f| _        |S rZ   )r.   r   r   r   r	   r;   )rB   r   r	   
new_offsetr   s        r   rG   zLeafNode.compute_position   s\    		(;FE(J(J%
%!2tz??a#IDMM#Z0DMr   c                 p    t                               d| j                  }| j        dk    r
|dd          }|S )Nz\2left_curly_namer   )BACKSLASH_REPLACE_REGEXsubr	   r@   )rB   r.   s     r   r.   zLeafNode.text   s9    &**5$*==9)))8Dr   c                 B    d                     | j        | j                  S )NzLeafNode({0}: {1}))r0   r@   r	   rM   s    r   __str__zLeafNode.__str__   s    #**49djAAAr   c                 P    d                     |                                           S )Nz{0})r0   r   rM   s    r   __repr__zLeafNode.__repr__   s    }}T\\^^,,,r   N)re   r:   )r   r   r   rU   r-   r2   rV   rC   rG   r.   r   r   r!   r   r   rh   rh      st        11=D   
    B B B- - - - -r   rh   c                       e Zd ZdZdS )SnippetASTNodez}
    Stub node that represents an actual snippet.

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

    All regex formatting nodes should extend this class.
    c                     dS )z
        Transform a regex match.

        This method takes a regex result and applies some transformation to
        return a new string.
        r:   r!   rB   regex_results     r   transform_regexzFormatNode.transform_regex   s	     rr   N)r   r   r   rU   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dS )TabstopSnippetNodezp
    Node that represents an int tabstop snippet.

    This node represents the expressions ${int} or $int.
    Nc                     t                               |            t          t                                }t	          |j                  | _        ||n|| _        | | j        _        | j	        dz   | j        _	        d S rZ   )
r   rC   rX   rh   intr	   number_placeholderr<   r?   )rB   r   r   default_placeholders       r   rC   zTabstopSnippetNode.__init__
  sp    %%%&xzz22&,'',7,C[[0 	#' "&*q.r   c                     | j         S rb   r   rM   s    r   r   zTabstopSnippetNode.placeholder  s      r   c                 T    || _         | j        dz   | j         _        | | j         _        d S rZ   )r   r?   r<   rB   r   s     r   r   zTabstopSnippetNode.placeholder  s,    '"&*q.#'   r   c                    t          | j        t                    r/| j        dz   | j        _        | j                            |          }n2t          | j        t
                    rt          || j                  \  }}| j        j        | _        |S rZ   )rf   r   r5   r?   rG   strr   r;   )rB   r   end_position_s       r   rG   z#TabstopSnippetNode.compute_position  s    d'11 	M&*j1nD#,==fEELL)3// 	M1&$:KLLOL!)2r   c                     || _         d S rb   r   )rB   new_placeholders     r   rJ   zTabstopSnippetNode.update(  s    +r   c                 4    | j                                         S rb   )r   r.   rM   s    r   r.   zTabstopSnippetNode.text+  s     %%'''r   c                 d    |                     |            | j                            |           d S rb   )rQ   r   rT   rR   s     r   rT   zTabstopSnippetNode.accept.  s1    d  )))))r   c                 F    d| _         | j                                         d S r|   )r>   r   rO   rM   s    r   rO   zTabstopSnippetNode.delete2  s$      """""r   rb   )r   r   r   rU   r   r   rV   rC   r}   r   r~   rG   rJ   r.   rT   rO   r!   r   r   r   r      s          D1 1 1 1 ! ! X! ( ( (
  , , ,( ( (* * *# # # # #r   r   c                   .    e Zd ZdZej        ZddZd ZdS )PlaceholderNodez
    Node that represents an int tabstop placeholder snippet.

    This node represents the expression ${int: placeholder}, where placeholder
    can be a snippet or text.
    r:   c                 >    t                               | ||           d S rb   )r   rC   )rB   r   r   s      r   rC   zPlaceholderNode.__init__A  s     ##D&+>>>>>r   c                    t          | j        t                    r| j        S t          | j        t                    r| j                                        S t          d                    t          | j                                      )Nz<Placeholder should be of type SnippetASTNode or str, got {0})rf   r   r   r5   r.   
ValueErrorr0   typerM   s    r   r.   zPlaceholderNode.textD  s~    d'-- 	;$$)733 	;$))+++ >>Df!%d&7!8!8?: ?:; ; ;r   N)r:   )	r   r   r   rU   r   r   rV   rC   r.   r!   r   r   r   r   7  sK          "D? ? ? ?; ; ; ; ;r   r   c                   ,    e Zd ZdZej        Zd Zd ZdS )
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                 r    t                               | ||d                    |d         | _        || _        d S )Nr   )r   rC   current_choicechoices)rB   r   r   s      r   rC   zChoiceNode.__init__Y  s5    ##D&'!*===%ajr   c                     || j         vr(t          d                    || j                             || _        || _        d S )NzEChoice {0} is not a valid value for this snippet, expected any of {1})r   LookupErrorr0   r   r   )rB   r   s     r   rJ   zChoiceNode.update^  sV    %%  ==CV"($,>8 >89 9 9 %"r   N)	r   r   r   rU   r   r   rV   rC   rJ   r!   r   r   r   r   O  sF          D  
# # # # #r   r   c                   2    e Zd ZdZej        Zd Zd Zd Z	dS )VariableSnippetNodez
    Node that represents a variable snippet.

    This node represents the expression ${var} or $var, where var is some
    variable qualified name.
    c                 V    t                               |            || _        || _        d S rb   )r   rC   r   r	   )rB   r   s     r   rC   zVariableSnippetNode.__init__t  s(    %%% 


r   c                     || _         d S rb   r	   rI   s     r   rJ   zVariableSnippetNode.updatey  s    


r   c                     | j         S rb   r   rM   s    r   r.   zVariableSnippetNode.text|  s
    zr   N)
r   r   r   rU   r   r   rV   rC   rJ   r.   r!   r   r   r   r   j  sU          D  
      r   r   c                   2    e Zd ZdZej        Zd Zd Zd Z	dS )VariablePlaceholderNodez
    Node that represents a variable placeholder snippet.

    This node represents the expression ${var: placeholder}, where placeholder
    can be a snippet or text.
    c                 J    t                               | |           || _        d S rb   )r   rC   r   )rB   r   r   s      r   rC   z VariablePlaceholderNode.__init__  s&    $$T8444'r   c                     || _         d S rb   r   r   s     r   rJ   zVariablePlaceholderNode.update  s    'r   c                     t          | j        t                    r| j        S t          | j        t                    r| j                                        S d S rb   )rf   r   r   r5   r.   rM   s    r   r.   zVariablePlaceholderNode.text  sV    d'-- 	,$$)733 	, $))+++	, 	,r   N)
r   r   r   rU   r   r   rV   rC   rJ   r.   r!   r   r   r   r     sU          +D( ( (( ( (, , , , ,r   r   c                   ,    e Zd ZdZej        Zd Zd ZdS )	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                               | |           t          j        |                                          | _        || _        || _        d S rb   )r   rC   recompiler.   r   r0   options)rB   r   r   fmtr   s        r   rC   zRegexNode.__init__  sC    $$T8444Z

--
r   c                      t          d          )Nz5Regex variable snippets are not currently implemented)NotImplementedErrorrM   s    r   r.   zRegexNode.text  s     " #> ? ? 	?r   N)	r   r   r   rU   r   r    rV   rC   r.   r!   r   r   r   r     sF          D  ? ? ? ? ?r   r   c                   8    e Zd ZdZej        Zd Zd Zd Z	d Z
dS )FormatSequenceNodez<Node that represents a sequence of formatting or text nodes.c                 H    t                               |            || _        d S rb   )r   rC   formatting_nodes)rB   r   s     r   rC   zFormatSequenceNode.__init__  s$    D!!! 0r   c                 :    | j                             |           d S rb   )r   ri   )rB   r   s     r   
add_formatzFormatSequenceNode.add_format  s    $$S)))))r   c                     d}| j         D ]\}t          |t                    r||                                z  }/t          |t                    r||                    |          z  }]|S Nr:   )r   rf   rX   r.   r   r   )rB   r   resultr   s       r   r   z"FormatSequenceNode.transform_regex  so    ( 	< 	<C#x(( <#((**$C,, <#--l;;;r   c                 n    |                     |            | j        D ]}|                     |           d S rb   )rQ   r   )rB   rS   r   s      r   rT   zFormatSequenceNode.accept  sE    d( 	 	CMM#	 	r   N)r   r   r   rU   r#   r(   rV   rC   r   r   rT   r!   r   r   r   r     s^        FFD1 1 1* * *      r   r   c                   ,    e Zd ZdZej        Zd Zd ZdS )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                 H    t                               |            || _        d S rb   )r   rC   group_number)rB   r   s     r   rC   zSimpleFormatNode.__init__  s$    D!!!(r   c                 6    |                     | j                  S rb   )groupr   r   s     r   r   z SimpleFormatNode.transform_regex  s    !!$"3444r   N)	r   r   r   rU   r-   r3   rV   rC   r   r!   r   r   r   r     sE          ?D) ) )5 5 5 5 5r   r   c                   ,    e Zd ZdZej        Zd Zd ZdS )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                 J    t                               | |           || _        d S rb   )r   rC   positive_match)rB   r   r   s      r   rC   zIfFormatNode.__init__  &    !!$555,r   c                 r    d}|                     | j                  | j                            |          }|S r   )r   r   r   r   rB   r   r   s      r   r   zIfFormatNode.transform_regex  s9    d/00<(88FFFr   N)	r   r   r   rU   r#   r)   rV   rC   r   r!   r   r   r   r     sE          =D- - -    r   r   c                   ,    e Zd ZdZej        Zd Zd ZdS )
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                 X    t                               | |           || _        || _        d S rb   )r   rC   r   negative_match)rB   r   r   r   s       r   rC   zIfElseNode.__init__  s.    !!$555,,r   c                     d}|                     | j                  | j                            |          }n| j                            |          }|S r   )r   r   r   r   r   r   s      r   r   zIfElseNode.transform_regex  sQ    d/00<(88FFFF(88FFFr   N)	r   r   r   rU   r#   r*   rV   rC   r   r!   r   r   r   r     sF          D- - -
    r   r   c                   ,    e Zd ZdZej        Zd Zd ZdS )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                 J    t                               | |           || _        d S rb   )r   rC   r   )rB   r   r   s      r   rC   zElseNode.__init__  r   r   c                     d}|                     | j                  | j                            |          }n|                     | j                  }|S r   )r   r   r   r   r   s      r   r   zElseNode.transform_regex  sQ    d/008(88FFFF!''(9::Fr   N)	r   r   r   rU   r#   r+   rV   rC   r   r!   r   r   r   r     sE          ?D- - -    r   r   )rU   r   r   r   r   r   r#   r-   r5   rX   rh   r   r   r   r   r   r   r   r   r   r   r   r   r   r!   r   r   <module>r      sl   @ ? 				$"*%566 * * *                     3 3 3 3 3 3 3 3lW W W W Ww W W Wt- - - - -w - - -B	 	 	 	 	W 	 	 	       $4# 4# 4# 4# 4# 4# 4# 4#n; ; ; ; ;( ; ; ;0# # # # ## # # #6    .   ,, , , , ,1 , , ,4? ? ? ? ?# ? ? ?2       65 5 5 5 5z 5 5 5$    #   *    !   4         r   