o
    ;n0j@d                     @  s   d dl mZ d dlZd dlZd dlZd dlZd dlZd dlmZ G dd de	Z
G dd dejZddddZdddZedkrTd dlZdd ZeeddZee dS dS )    )annotationsN)Callablec                      s(   e Zd ZdZ		d	d
 fddZ  ZS )TranspilerErrorzIException raised when transpilation fails or encounters ambiguous syntax.Nissues!list[tuple[int, str, str]] | Nonemessage
str | Nonec              	     s   |pg | _ |rt | d S t| j }| d|dkrdnd d}| j D ]\}}}|d| d| d| d	7 }q%t | d S )
Nz issue   s z	 found:

z* Line : z
>> 
)r   super__init__len)selfr   r   Zissue_countZissues_textline_nocode	__class__ X/home/wildlama/miniconda3/envs/lam_a2e/lib/python3.10/site-packages/groovy/transpiler.pyr      s   

zTranspilerError.__init__)NN)r   r   r   r   )__name__
__module____qualname____doc__r   __classcell__r   r   r   r   r      s
    r   c                      s  e Zd Zdd Zdd	d
Z fddZdd ZdddZdddZdddZ	dddZ
dddZdddZdd"d#Zdd%d&Zdd(d)Zdd+d,Zdd.d/Zdd1d2Zdd4d5Zdd7d8Zdd:d;Zdd=d>Zdd@dAZddCdDZddFdGZddIdJZddLdMZddOdPZddRdSZddTdUZddVdWZddXdYZ dd[d\Z!dd^d_Z"ddadbZ#ddddeZ$ddgdhZ%ddjdkZ&ddmdnZ'ddpdqZ(ddsdtZ)ddvdwZ*ddydzZ+dd|d}Z,dddZ-dddZ.  Z/S )PythonToJSVisitorc                 C  s:   g | _ d| _t | _g | _g | _i | _| j| jd| _	d S )Nr   )ranger   )
js_linesindent_levelsetdeclared_varsr   source_lines	var_typestransform_rangetransform_lenbuiltin_transformsr   r   r   r   r   !   s   zPythonToJSVisitor.__init__nodeast.ASTr   strreturnNonec                 C  s<   t |dr|j}| j|d   }| j|||f dS dS )z3Add a transpilation issue with source code context.linenor	   N)hasattrr.   r#   stripr   append)r   r)   r   r   	line_textr   r   r   	add_issue/   s
   
zPythonToJSVisitor.add_issuec              
     sJ   zt  |W S  ty$ } z|jr| j|j W Y d }~dS d }~ww )Nr   )r   visitr   r   extend)r   r)   er   r   r   r4   6   s   zPythonToJSVisitor.visitc                 C  s   |  |dt|j  dS )NzUnsupported syntax: r   )r3   typer   r   r)   r   r   r   generic_visit>   s   zPythonToJSVisitor.generic_visitc                 C  s
   d| j  S )Nz    )r    r(   r   r   r   indentB   s   
zPythonToJSVisitor.indentast.FunctionDefc                 C  s   g }|j j D ]+}||j |jr1t|jtjr1|jj}t 	|t
t|d }|d ur1|| j|j< qd|j dd| dd }| j| |  jd7  _|jD ]}| | qQ|  jd8  _| jd d S )Nz	function (, ) {r	   })argsr1   arg
annotation
isinstanceastNameidglobalsgetgetattrbuiltinsr$   namejoinr   r    bodyr4   )r   r)   paramsrB   	type_nameZtype_objheaderstmtr   r   r   visit_FunctionDefF   s    
z#PythonToJSVisitor.visit_FunctionDefast.Attributec                 C  s   |  |j}| d|j S )N.)r4   valueattr)r   r)   rV   r   r   r   visit_Attribute[   s   z!PythonToJSVisitor.visit_Attribute
ast.Returnc                 C  s:   |j d u rdn| |j }| j|   d| d d S )Nr   return ;)rV   r4   r   r1   r:   )r   r)   Zret_valr   r   r   visit_Returna   s    zPythonToJSVisitor.visit_Returnast.Exprc                 C  s*   |  |j}| j|   | d d S )Nr[   )r4   rV   r   r1   r:   )r   r)   exprr   r   r   
visit_Exprf   s   zPythonToJSVisitor.visit_Expr
ast.Assignc                 C  s   t |jdkrtd|jd }| |}| |j}t|tjrQ|j| j	vrQ| j	
|j | |j}|d ur>|| j|j< | j|   d| d| d d S | j|   | d| d d S )Nr	   z2Multiple assignment targets are not supported yet.r   zlet z = r[   )r   targetsr   r4   rV   rD   rE   rF   rG   r"   addget_expr_typer$   r   r1   r:   )r   r)   Ztarget_nodetargetrV   Z	expr_typer   r   r   visit_Assignk   s   


&$zPythonToJSVisitor.visit_Assignexprscontextc                  s    fdd|D t dd D r |d| d t tdkrJtfddD sLd	d D } |d
d| d| d t dS dS )z|
        Check if an operation is type-safe.
        Raises TranspilerError if types are ambiguous or incompatible.
        c                      g | ]}  |qS r   )rc   ).0r^   r(   r   r   
<listcomp>       z7PythonToJSVisitor.check_type_safety.<locals>.<listcomp>c                 s  s    | ]}|d u V  qd S Nr   ri   tr   r   r   	<genexpr>       z6PythonToJSVisitor.check_type_safety.<locals>.<genexpr>z0Ambiguous operation: Cannot determine types for z=. Operation behavior may differ in JavaScript based on types.r	   c                 3  s    | ]	}| d  kV  qdS )r   Nr   rm   )typesr   r   ro      s    c                 S     g | ]}|j qS r   )r   rm   r   r   r   rj          z"Ambiguous operation: Mixed types (r=   z) in z$. Behavior may differ in JavaScript.N)anyr3   r   r   allrM   )r   r)   rg   rf   Z
type_namesr   )r   rq   r   check_type_safety   s   
"z#PythonToJSVisitor.check_type_safety	ast.BinOpc                 C  sf   |  |j}|  |j}|  |j}| j||j|jd| d| d| dd d| d| d| dS )N' rg   r<   ))r4   leftrightoprv   )r   r)   r|   r}   r~   r   r   r   visit_BinOp   s    zPythonToJSVisitor.visit_BinOpast.Addc                 C     dS )N+r   r8   r   r   r   	visit_Add      zPythonToJSVisitor.visit_Addast.Subc                 C  r   )N-r   r8   r   r   r   	visit_Sub   r   zPythonToJSVisitor.visit_Subast.Multc                 C  r   )N*r   r8   r   r   r   
visit_Mult   r   zPythonToJSVisitor.visit_Multast.Divc                 C  r   )N/r   r8   r   r   r   	visit_Div   r   zPythonToJSVisitor.visit_Divast.Comparec              
   C  s   t |jdkst |jdkrtd|jd }| |j}| |jd }t|tjr3| d| dS t|tj	rBd| d| dS | j
||j|jd d| d| | d| d	 | |}d
| d| d| dS )Nr	   z%Only single comparisons are supportedr   z
.includes(r{   !zcomparison ry   rz   r<   )r   opscomparatorsr   r4   r|   rD   rE   InNotInrv   )r   r)   r~   r|   r}   op_strr   r   r   visit_Compare   s"   

zPythonToJSVisitor.visit_Compareast.Gtc                 C  r   )N>r   r8   r   r   r   visit_Gt   r   zPythonToJSVisitor.visit_Gtast.Ltc                 C  r   )N<r   r8   r   r   r   visit_Lt   r   zPythonToJSVisitor.visit_Ltast.GtEc                 C  r   )Nz>=r   r8   r   r   r   	visit_GtE   r   zPythonToJSVisitor.visit_GtEast.LtEc                 C  r   )Nz<=r   r8   r   r   r   	visit_LtE   r   zPythonToJSVisitor.visit_LtEast.Eqc                 C  r   )Nz===r   r8   r   r   r   visit_Eq   r   zPythonToJSVisitor.visit_Eq	ast.NotEqc                 C  r   )Nz!==r   r8   r   r   r   visit_NotEq   r   zPythonToJSVisitor.visit_NotEqast.Inc                 C  r   )Ninr   r8   r   r   r   visit_In   r   zPythonToJSVisitor.visit_In	ast.NotInc                 C  r   )Nznot inr   r8   r   r   r   visit_NotIn   r   zPythonToJSVisitor.visit_NotInast.Ifc                 C  s  |  |j}| j|   d| dd  |  jd7  _|jD ]}|  | q |  jd8  _| j|   d  |}|jrt|jdkrt	|jd t
jr|jd }|  |j}| j|   d| dd  |  jd7  _|jD ]}|  | qt|  jd8  _| j|   d  |jrt|jdkrt	|jd t
jsO|jr| j|   dd  |  jd7  _|jD ]}|  | q|  jd8  _| j|   d  d S d S )	Nzif (r>   r?   r	   r@   r   z	else if (zelse )r4   testr   r1   r:   r    rN   orelser   rD   rE   If)r   r)   r   rR   currentr   r   r   visit_If   sD    

 

zPythonToJSVisitor.visit_Ifast.Callc                   s    fdd|j D }|j D ]
} j||dd qt|dkr&d|d  dS t|d	kr>d|d  d
|d  d|d  dS t|dkrHtdtd)zHTransform Python's range() to an equivalent JavaScript array expression.c                   rh   r   r4   ri   rB   r(   r   r   rj     rk   z5PythonToJSVisitor.transform_range.<locals>.<listcomp>zrange() argumentrz   r	   zArray.from({length: r   z}, (_, i) => i)   z - z}, (_, i) => i + r{      z/range() with step argument is not supported yetz'Invalid number of arguments for range())rA   rv   r   r   )r   r)   rA   rB   r   r(   r   r%     s   
$z!PythonToJSVisitor.transform_rangec                 C  sT   t |jdkrtd| |jd }| |jd }|tu r%d| dS | dS )zFTransform Python's len() to the equivalent JavaScript property access.r	   z len() takes exactly one argumentr   zObject.keys(z).lengthz.length)r   rA   r   r4   rc   dict)r   r)   Zarg_codern   r   r   r   r&     s   
zPythonToJSVisitor.transform_lenc              	   C  s   i }|j D ]3}t|jtjr|jjdu rd||j< q| |j}z
t|||j< W q ty8   |||j< Y qw d|d< t	
|S )z=Handle Gradio component calls and return JSON representation.NupdateZ__type__)keywordsrD   rV   rE   ConstantrB   r4   literal_eval	Exceptionjsondumps)r   r)   kwargskwrV   r   r   r    _handle_gradio_component_updates!  s   


z2PythonToJSVisitor._handle_gradio_component_updatesc                   s  zdd l }d}W n ty   d}Y nw t|jtjr~|jj jv r+ j|jj |S |r\z%|jjdkr: |W S t	||jjd }|rQt
||jjrQ |W S W n	 ty[   Y nw |jD ]} j||d|jj dd q_ |d|jj d	 d
S t|jtjr|rz4t|jjtjr|jjjdv r|jjdkr |W S t	||jjd }|rt
||jjr |W S W n	 ty   Y nw  |j} fdd|jD }t|jtjr j|j|jjd| d |jD ]} j||d| d q| dd| dS )Nr   TFr   zargument in z() callrz   zUnsupported function "z()"r   >   gradiogrc                   rh   r   r   r   r(   r   r   rj   k  rk   z0PythonToJSVisitor.visit_Call.<locals>.<listcomp>zobject in method call zargument in method call r<   r=   r{   )r   ImportErrorrD   funcrE   rF   rG   r'   r   rJ   
issubclassblocksBlockr   rA   rv   r3   	AttributerV   rW   r4   rM   )r   r)   r   Z
has_gradiocomponent_classrB   r   rA   r   r(   r   
visit_Call2  sj   

zPythonToJSVisitor.visit_Callast.Namec                 C  s   |j S rl   )rG   r8   r   r   r   
visit_Namey  s   zPythonToJSVisitor.visit_Nameast.Constantc                 C  s   |j d u rdS t|j S )Nnull)rV   reprr8   r   r   r   visit_Constant}  s   

z PythonToJSVisitor.visit_Constantast.Forc                 C  s   |  |j}|  |j}t|jtjr0t|jjtjr0|jjjdkr0t|jtjr0t	| j
|jj< | j|   d| d| dd  |  jd7  _|jD ]}|  | qM|  jd8  _| j|   d  d S )Nr   z	for (let z of r>   r?   r	   r@   )r4   rd   iterrD   rE   Callr   rF   rG   intr$   r   r1   r:   r    rN   )r   r)   rd   Z	iter_exprrR   r   r   r   	visit_For  s   &
zPythonToJSVisitor.visit_For	ast.Whilec                 C  sx   |  |j}| j|   d| dd  |  jd7  _|jD ]}|  | q |  jd8  _| j|   d  d S )Nzwhile (r>   r?   r	   r@   )r4   r   r   r1   r:   r    rN   )r   r)   r   rR   r   r   r   visit_While  s    
zPythonToJSVisitor.visit_Whileast.Listc                   &    fdd|j D }dd| dS )Nc                   rh   r   r   ri   eltr(   r   r   rj     rk   z0PythonToJSVisitor.visit_List.<locals>.<listcomp>[r=   ]eltsrM   r   r)   elementsr   r(   r   
visit_List     zPythonToJSVisitor.visit_List	ast.Tuplec                   r   )Nc                   rh   r   r   r   r(   r   r   rj     rk   z1PythonToJSVisitor.visit_Tuple.<locals>.<listcomp>r   r=   r   r   r   r   r(   r   visit_Tuple  r   zPythonToJSVisitor.visit_Tupleast.ListCompc                   s   t |jdkr |d t |jd } |j} |j} |j}|jr^d	 fdd|jD }| d| d| d	}t
|jtjrQ|jj|jjks\|d
| d| d	7 }|S | d
| d| d	}|S )z
        Transform a Python list comprehension into a combination of filter and map calls.
        For example:
            [x * 2 for x in arr if x > 10]
        becomes:
            arr.filter(x => x > 10).map(x => x * 2)
        r	   z7Only single generator list comprehensions are supportedr   z && c                 3  s    | ]}  |V  qd S rl   r   )ri   Zif_noder(   r   r   ro     s    z3PythonToJSVisitor.visit_ListComp.<locals>.<genexpr>z.filter(z => r{   z.map()r   
generatorsr3   r   r4   r   rd   r   ifsrM   rD   rE   rF   rG   )r   r)   genZiter_jsZ	target_jsZelt_js
conditionsresultr   r(   r   visit_ListComp  s"   
z PythonToJSVisitor.visit_ListCompast.Subscriptc                 C  s(   |  |j}|  |j}| d| dS )Nr   r   )r4   rV   slice)r   r)   rV   slice_valuer   r   r   visit_Subscript  s   z!PythonToJSVisitor.visit_Subscriptast.AugAssignc              	   C  sR   |  |j}|  |j }|  |j}| j|   | d| d| d d S )Nry   z= r[   )r4   rd   r~   r0   rV   r   r1   r:   )r   r)   rd   r~   rV   r   r   r   visit_AugAssign  s   *z!PythonToJSVisitor.visit_AugAssign
ast.BoolOpc                   s:     |j} fdd|jD }dd| d| dS )Nc                   rh   r   r   )ri   rV   r(   r   r   rj     rk   z2PythonToJSVisitor.visit_BoolOp.<locals>.<listcomp>r<   ry   r{   )r4   r~   valuesrM   )r   r)   r~   r   r   r(   r   visit_BoolOp  s   zPythonToJSVisitor.visit_BoolOpast.Andc                 C  r   )Nz&&r   r8   r   r   r   	visit_And  r   zPythonToJSVisitor.visit_Andast.Orc                 C  r   )Nz||r   r8   r   r   r   visit_Or  r   zPythonToJSVisitor.visit_Orast.Dictc                 C  s`   g }t |j|jD ]\}}|d u rq	| |}| |}|| d|  q	dd| dS )Nr   r?   r=   r@   )zipkeysr   r4   r1   rM   )r   r)   pairskeyrV   Zkey_jsZvalue_jsr   r   r   
visit_Dict  s   

zPythonToJSVisitor.visit_Dicttype | Nonec                 C  s   t |tjrt|jS t |tjr|j| jv r| j|j S dS t |tjr=| 	|j
}| 	|j}||kr;|dur;|S dS t |tjrEdS t |tjrMtS t |tjrUtS t |tjr]tS dS )z0Determine the type of an expression if possible.N)rD   rE   r   r7   rV   rF   rG   r$   BinOprc   r|   r}   r   ListlistDictr   Tupletuple)r   r)   Z	left_typeZ
right_typer   r   r   rc     s*   
zPythonToJSVisitor.get_expr_type)r)   r*   r   r+   r,   r-   )r,   r+   )r)   r;   )r)   rT   )r)   rY   )r)   r]   )r)   r`   )r)   r*   rf   r*   rg   r+   r,   r-   )r)   rw   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   r,   r+   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r   )r)   r*   r,   r   )0r   r   r   r   r3   r4   r9   r:   rS   rX   r\   r_   re   rv   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r%   r&   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rc   r   r   r   r   r   r       sZ    
























#



G













r   Ffnr   validateboolr,   r+   c              
   C  s  |rt | }|jrt|j }td| dzt | }t|}W n t	y7 } ztdd|d}~ww zt
|}W n tyQ } ztdd|d}~ww |rzddl}W n tyf   tddw d}t
|D ]}	t|	t
jr|	j| jkr|	} nqn|rg }
t
|D ]}	t|	t
jr|	jdur|
|	 q|
stdd|
D ]}t|js|j}| |d	   }td
| d| dqd}t
|D ]}	t|	t
jt
jfr|	} nq|du rtddt }| |_t|t
jr4dd |jjD }|jdd | dd  | j!d	7  _!|j|"  d|#|j$ d | j!d	8  _!|jd n|#| |j%rCt|j%dd |jS )a5  
    Transpiles a Python function to JavaScript and returns the JavaScript code as a string.

    Parameters:
        fn: The Python function to transpile.
        validate: If True, the function will be validated to ensure it takes no arguments & only returns gradio component property updates. This is used when Groovy is used inside Gradio and `gradio` must be installed to use this.

    Returns:
        The JavaScript code as a string.

    Raises:
        TranspilerError: If the function cannot be transpiled or if the transpiled function is not valid.
    z>Function must take no arguments for client-side use, but got: )r   z1Could not retrieve source code from the function.Nz Could not parse function source.r   z(Gradio must be installed for validation.zMFunction must return Gradio component updates, but no return statement found.r	   zKFunction must only return Gradio component updates. Invalid return at line r   z>No function or lambda definition found in the provided source.c                 S  rr   r   )rB   r   r   r   r   rj   Y  rs   ztranspile.<locals>.<listcomp>z
function (r=   r>   r?   rZ   r[   r@   )r   r   )&inspect	signature
parametersr  r   r   	getsourcetextwrapdedentr   rE   parseSyntaxErrorr   r   walkrD   FunctionDefrL   r   ReturnrV   r1   _is_valid_gradio_returnr.   
splitlinesr0   Lambdar   r#   rA   r   rM   r    r:   r4   rN   r   )r  r  sigZparam_namessourcer6   treer   Z	func_noder)   Zreturn_nodesZreturn_noder   r2   visitorrA   r   r   r   	transpile  s   






r  r)   r*   c              	   C  s  t | tjrt | jtjrgt | jjtjrg| jjjdv rez<ddl}| jj	dkr*W dS t
|| jj	d}|rSt||jjrV| jrAW dS | jD ]}|jdkrO W dS qDW dS W dS W dS  ttfyd   Y dS w dS t | jtjrz<ddl}| jjdkr|W dS t
|| jjd}|rt||jjr| jrW dS | jD ]}|jdkr W dS qW dS W dS W dS  ttfy   Y dS w dS t | tjtjfr| jsdS tdd	 | jD S dS )
z
    Check if a return value is a valid Gradio component or collection of components.

    Args:
        node: The AST node representing the return value

    Returns:
        bool: True if the return value is valid, False otherwise
    >   r   r   r   Nr   TFrV   c                 s  s    | ]}t |V  qd S rl   )r  r   r   r   r   ro     rp   z*_is_valid_gradio_return.<locals>.<genexpr>)rD   rE   r   r   r   rV   rF   rG   r   rW   rJ   r   r   r   rA   r   rB   r   AttributeErrorr  r   r   ru   )r)   r   r   r   r   r   r   r  j  sr   




			r  __main__c                   C  s   t jddd dS )Nr   T)selectedvisibleinfo)r   r   r   r   r   r   filter_rows_by_term  s   r   T)r  )F)r  r   r  r  r,   r+   )r)   r*   r,   r  )
__future__r   rE   rK   r  r   r  collections.abcr   r   r   NodeVisitorr   r  r  r   r   r   r   Zjs_codeprintr   r   r   r   <module>   s(       k
b@