o
    ٷi@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   issue_countissues_textline_nocode	__class__ E/home/ubuntu/.local/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)hasattrr0   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   r6   6   s   zPythonToJSVisitor.visitc                 C  s   |  |dt|j  dS )NzUnsupported syntax: r   )r5   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	   })argsr3   arg
annotation
isinstanceastNameidglobalsgetgetattrbuiltinsr&   namejoinr!   r"   bodyr6   )r   r+   paramsrD   	type_nametype_objheaderstmtr   r   r   visit_FunctionDefF   s    
z#PythonToJSVisitor.visit_FunctionDefast.Attributec                 C  s   |  |j}| d|j S )N.)r6   valueattr)r   r+   rY   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 ;)rY   r6   r!   r3   r<   )r   r+   ret_valr   r   r   visit_Returna   s    zPythonToJSVisitor.visit_Returnast.Exprc                 C  s*   |  |j}| j|   | d d S )Nr^   )r6   rY   r!   r3   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   r6   rY   rF   rG   rH   rI   r$   addget_expr_typer&   r!   r3   r<   )r   r+   target_nodetargetrY   	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   )rg   ).0rb   r*   r   r   
<listcomp>       z7PythonToJSVisitor.check_type_safety.<locals>.<listcomp>c                 s  s    | ]}|d u V  qd S Nr   ro   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   rs   )typesr   r   ru      s    c                 S     g | ]}|j qS r   )r   rs   r   r   r   rp          z"Ambiguous operation: Mixed types (r?   z) in z$. Behavior may differ in JavaScript.N)anyr5   r   r   allrO   )r   r+   rm   rl   
type_namesr   )r   rw   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' rm   r>   ))r6   leftrightopr}   )r   r+   r   r   r   r   r   r   visit_BinOp   s    zPythonToJSVisitor.visit_BinOpast.Addc                 C     dS )N+r   r:   r   r   r   	visit_Add      zPythonToJSVisitor.visit_Addast.Subc                 C  r   )N-r   r:   r   r   r   	visit_Sub   r   zPythonToJSVisitor.visit_Subast.Multc                 C  r   )N*r   r:   r   r   r   
visit_Mult   r   zPythonToJSVisitor.visit_Multast.Divc                 C  r   )N/r   r:   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 r   r   r>   )r   opscomparatorsr   r6   r   rF   rG   InNotInr}   )r   r+   r   r   r   op_strr   r   r   visit_Compare   s"   

zPythonToJSVisitor.visit_Compareast.Gtc                 C  r   )N>r   r:   r   r   r   visit_Gt   r   zPythonToJSVisitor.visit_Gtast.Ltc                 C  r   )N<r   r:   r   r   r   visit_Lt   r   zPythonToJSVisitor.visit_Ltast.GtEc                 C  r   )Nz>=r   r:   r   r   r   	visit_GtE   r   zPythonToJSVisitor.visit_GtEast.LtEc                 C  r   )Nz<=r   r:   r   r   r   	visit_LtE   r   zPythonToJSVisitor.visit_LtEast.Eqc                 C  r   )Nz===r   r:   r   r   r   visit_Eq   r   zPythonToJSVisitor.visit_Eq	ast.NotEqc                 C  r   )Nz!==r   r:   r   r   r   visit_NotEq   r   zPythonToJSVisitor.visit_NotEqast.Inc                 C  r   )Ninr   r:   r   r   r   visit_In   r   zPythonToJSVisitor.visit_In	ast.NotInc                 C  r   )Nznot inr   r:   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@   rA   r	   rB   r   z	else if (zelse )r6   testr!   r3   r<   r"   rP   orelser   rF   rG   If)r   r+   r   rU   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                   rn   r   r6   ro   rD   r*   r   r   rp     rq   z5PythonToJSVisitor.transform_range.<locals>.<listcomp>zrange() argumentr   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())rC   r}   r   r   )r   r+   rC   rD   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   rC   r   r6   rg   dict)r   r+   arg_codert   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update__type__)keywordsrF   rY   rG   ConstantrD   r6   literal_eval	Exceptionjsondumps)r   r+   kwargskwrY   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() callr   zUnsupported function "z()"r   >   grgradioc                   rn   r   r   r   r*   r   r   rp   k  rq   z0PythonToJSVisitor.visit_Call.<locals>.<listcomp>zobject in method call zargument in method call r>   r?   r   )r   ImportErrorrF   funcrG   rH   rI   r)   r   rL   
issubclassblocksBlockr   rC   r}   r5   	AttributerY   rZ   r6   rO   )r   r+   r   
has_gradiocomponent_classrD   r   rC   r   r*   r   
visit_Call2  sj   

zPythonToJSVisitor.visit_Callast.Namec                 C  s   |j S rr   )rI   r:   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)rY   reprr:   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@   rA   r	   rB   )r6   ri   iterrF   rG   Callr   rH   rI   intr&   r!   r3   r<   r"   rP   )r   r+   ri   	iter_exprrU   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@   rA   r	   rB   )r6   r   r!   r3   r<   r"   rP   )r   r+   r   rU   r   r   r   visit_While  s    
zPythonToJSVisitor.visit_Whileast.Listc                   &    fdd|j D }dd| dS )Nc                   rn   r   r   ro   eltr*   r   r   rp     rq   z0PythonToJSVisitor.visit_List.<locals>.<listcomp>[r?   ]eltsrO   r   r+   elementsr   r*   r   
visit_List     zPythonToJSVisitor.visit_List	ast.Tuplec                   r   )Nc                   rn   r   r   r   r*   r   r   rp     rq   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 rr   r   )ro   if_noder*   r   r   ru     s    z3PythonToJSVisitor.visit_ListComp.<locals>.<genexpr>z.filter(z => r   z.map()r   
generatorsr5   r   r6   r   ri   r   ifsrO   rF   rG   rH   rI   )r   r+   geniter_js	target_jselt_js
conditionsresultr   r*   r   visit_ListComp  s"   
z PythonToJSVisitor.visit_ListCompast.Subscriptc                 C  s(   |  |j}|  |j}| d| dS )Nr   r   )r6   rY   slice)r   r+   rY   slice_valuer   r   r   visit_Subscript  s   z!PythonToJSVisitor.visit_Subscriptast.AugAssignc              	   C  sR   |  |j}|  |j }|  |j}| j|   | d| d| d d S )Nr   z= r^   )r6   ri   r   r2   rY   r!   r3   r<   )r   r+   ri   r   rY   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                   rn   r   r   )ro   rY   r*   r   r   rp     rq   z2PythonToJSVisitor.visit_BoolOp.<locals>.<listcomp>r>   r   r   )r6   r   valuesrO   )r   r+   r   r  r   r*   r   visit_BoolOp  s   zPythonToJSVisitor.visit_BoolOpast.Andc                 C  r   )Nz&&r   r:   r   r   r   	visit_And  r   zPythonToJSVisitor.visit_Andast.Orc                 C  r   )Nz||r   r:   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   rA   r?   rB   )zipkeysr  r6   r3   rO   )r   r+   pairskeyrY   key_js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)rF   rG   r   r9   rY   rH   rI   r&   BinOprg   r   r   r   ListlistDictr   Tupletuple)r   r+   	left_type
right_typer   r   r   rg     s*   
zPythonToJSVisitor.get_expr_type)r+   r,   r   r-   r.   r/   )r.   r-   )r+   r=   )r+   rW   )r+   r\   )r+   ra   )r+   rd   )r+   r,   rl   r,   rm   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+   r  )r+   r,   r.   r  )0r   r   r   r   r5   r6   r;   r<   rV   r[   r`   rc   rk   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  rg   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  rx   r   )rD   r   r   r   r   rp   Y  ry   ztranspile.<locals>.<listcomp>z
function (r?   r@   rA   r]   r^   rB   )r   r   )&inspect	signature
parametersr  r	  r   	getsourcetextwrapdedentr   rG   parseSyntaxErrorr   r   walkrF   FunctionDefrN   r   ReturnrY   r3   _is_valid_gradio_returnr0   
splitlinesr2   Lambdar   r%   rC   r!   rO   r"   r<   r6   rP   r   )r  r  sigparam_namessourcer8   treer   	func_noder+   return_nodesreturn_noder   r4   visitorrC   r   r   r   	transpile  s   






r1  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   TFrY   c                 s  s    | ]}t |V  qd S rr   )r&  r   r   r   r   ru     rv   z*_is_valid_gradio_return.<locals>.<genexpr>)rF   rG   r   r   r   rY   rH   rI   r   rZ   rL   r   r   r   rC   r   rD   r   AttributeErrorr  r  r   r{   )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   r7  T)r  )F)r  r   r  r  r.   r-   )r+   r,   r.   r  )
__future__r   rG   rM   r  r   r  collections.abcr   r   r   NodeVisitorr   r1  r&  r   r   r   r7  js_codeprintr   r   r   r   <module>   s(       k
b@