
    G@d{^                        d Z ddlZddlZddlmZ ddlZddlZddlZddl	Z	ddl
mZmZmZmZmZ ddlZddlZddlmZ ddlmZmZmZmZmZ ddlmZ ddlmZmZmZm Z m!Z! ddl"m#Z#m$Z$m%Z%m&Z& dd	l'm(Z( dd
l)m*Z* ddl+m,Z,m-Z-  ej.         ej/         ej0                     ej1        e2                              Z3dZ4dZ5dZ6dZ7erdZ7 ej8        e9          Z:e% G d dee*e                      Z;d Z<e9dk    r e<             dS dS )z
Spyder Language Server Protocol Client implementation.

This client implements the calls and procedures required to
communicate with a v3.0 Language Server Protocol server.
    N)QObjectQProcessQSocketNotifierSignalSlot)SpyderConfigurationAccessor)DEVget_conf_pathget_debug_level
is_pynsistrunning_under_pytest)is_anaconda)CLIENT_CAPABILITESSERVER_CAPABILITESTEXT_DOCUMENT_SYNC_OPTIONSCompletionRequestTypesClientConstants)send_requestsend_notificationclass_registerhandles)MessageKind)LSPMethodProviderMixIn)getcwd_or_homeselect_portpendingserver_ready	127.0.0.1messagesverbosec                      e Zd ZdZ eee          Z ee          Z ee          Z	i  e
            dfdZd Zed             Zed             Zed             Zed             Zd	 Z eej                  d
             Zd Zd Zd Zd Zd Zd Zd Zd Zd Z e            d             Z d Z! e"e#           e$e%j&                  d                         Z' e$e%j(                  d             Z) e"e%j(                  d             Z* e+e%j,                  d             Z- e"e%j&                  d             Z. e+e%j/                  d             Z0ed             Z1ed             Z2dS ) 	LSPClientz4Language Server Protocol v3.0 client implementation.pythonc                    t          j        |            || _        d | _        d | _        d | _        d | _        d | _        d | _        d | _	        d | _
        || _        d| _        d| _        d| _        i | _        i | _        i | _        i | _        d| _        d| _        |d         st+          |d                   | _        n|d         | _        |d         | _        |                    dd          | _        |                    dd          | _        | j        r2| j        r+d}t6                              |           t;          |          || _        |                    d	i           | _        t@          | _!        tD          | _#        tI          j%                    | _&        |                    d
d          | _'        |d         | _(        g | _)        d S )NF   externalport)default_porthoststdiozQIf server is set to use stdio communication, then it cannot be an external serverconfigurationsargs cmd)*r   __init__managerzmq_in_socketzmq_out_socketzmq_in_portzmq_out_port	transportserver	stdio_pidnotifierlanguageinitializedready_to_closerequest_seq
req_statuswatched_fileswatched_folders	req_replyserver_unresponsivetransport_unresponsiver   server_portserver_hostgetexternal_serverr*   loggererrorAssertionErrorfolderr+   r   client_capabilitesr   server_capabiliteszmqContextcontext_server_args_server_cmd	_requests)selfparentserver_settingsrJ   r9   rH   s         Ylib/python3.11/site-packages/spyder/plugins/completion/providers/languageserver/client.pyr/   zLSPClient.__init__L   s    	!"   #!#( &+# z* 	7*,V4 6  6  6D  /v6D*62.22:uEE$((%88
 : 	($. 	(<ELL '''-112BBGG"4"4{}} ,//;;*51     c                 d   t                      dk    rdS d                    || j        t          j                              }t          t          j        d|                    }t          j        t          j	        |                    s&t          j
        t          j	        |                     |S )z
        Get filename to redirect server or transport logs to in
        debugging mode.

        Parameters
        ----------
        kind: str
            It can be "server" or "transport".
        r   Nz{0}_{1}_{2}.loglsp_logs)r   formatr9   osgetpidr
   ospjoinexistsdirnamemakedirs)rS   kindfnamelocations       rV   _get_log_filenamezLSPClient._get_log_filename   s     !!4!((t}bikkJJ *e!<!<== z#+h//00 	/KH--...rW   c                 ,    |                      d          S )zO
        Filename to redirect the server process stdout/stderr output.
        r6   re   rS   s    rV   server_log_filezLSPClient.server_log_file   s    
 %%h///rW   c                 ,    |                      d          S )zZ
        Filename to redirect the transport process stdout/stderr
        output.
        r5   rg   rh   s    rV   transport_log_filezLSPClient.transport_log_file   s     %%k222rW   c                    g }| j         dk    r|t          j        dgz  }|| j        gz  }| j                            | j        | j                  }t          |          dk    r||	                    d          z  }| j         dk    rmt                      dk    r[|d| j        gz  }t                      dk    r|                    d           n't                      d	k    r|                    d
           |S )z!Arguments for the server process.r#   z-mr)   r'   r    z
--log-file   z-v   z-vv)r9   sys
executablerQ   rP   rZ   rD   rC   lensplitr   ri   appendrS   r,   host_and_ports      rV   server_argszLSPClient.server_args   s    =H$$S^T**D!"" )00!! 1 # # }!!M'',,,D=H$$):):Q)>)>\4#788D  A%%D!!!! ""a''E"""rW   c           
         t           j        dt          j        t          dd          d| j        dt          t                                g}d                    | j	        | j
                  }||                    d          z  }|d	t          | j                  d
t          | j                  gz  }| j        r/|dgz  }t                      dk    r|d| j        gz  }|| j        z  }n|dgz  }|S )z$Arguments for the transport process.z-ur5   zmain.pyz--folderz--transport-debugz*--server-host {host} --server-port {port} rm   rn   z--zmq-in-portz--zmq-out-portz--stdio-serverr   z--server-log-filez--external-server)rq   rr   r]   r^   LOCATIONrJ   strr   rZ   rD   rC   rt   r4   r3   r*   ri   rx   rv   s      rV   transport_argszLSPClient.transport_args   s    NHX{I66_%6%6!7!7
 EKK!! L # # 	##C((( 	#d&7"8"8!3t'7#8#8: 	: : 	*%&&D  1$$,d.BCCD$$DD())DrW   c                    | j                             t          j                  | _        | j                            d                    t                              | _        | j                             t          j                  | _	        | j	        
                    d           | j	                            d                    t                              | _        dS )z#Create PyZMQ sockets for transport.ztcp://{}r   N)rO   socketrM   PAIRr2   bind_to_random_portrZ   	LOCALHOSTr4   r1   set_hwmr3   rh   s    rV   create_transport_socketsz"LSPClient.create_transport_sockets   s    "l11#(;; /CCi((* *!\00::""1%%%-AAi((* *rW   c                 D    | j                             | j                   dS )z;Handle errors with the transport layer or server processes.N)sig_went_downemitr9   )rS   rH   s     rV   handle_process_errorszLSPClient.handle_process_errors   s#     	.....rW   c                 t   | j         s| j        rdS t                              d                    d                    | j                                       t          |           | _        | j        	                                }| j
        dk    rt          j        t                      dd          }t          j        |          st          j        |           t          j        dk    rdt          j        v r&|                    dt          j        d                    t'                      sBt)                      s4d	t          j        v r&|                    d	t          j        d	                    nvd}t          j        D ](}|                    |t          j        |                    )t                              d
                    |                                                     | j                            |           | j        j                            | j                   | j                            |           | j                            t          j                   | j        | j                            | j                   | j                            | j        d         | j        dd                    dS )zStart server.NzStarting server: {0}rn   r#   	lsp_pathscwdntUSERPROFILEAPPDATAz!Server process env variables: {0}r   r%   ) rF   r*   rG   inforZ   r^   rx   r   r6   processEnvironmentr9   r]   r
   r_   r[   ra   nameenvironinsertr   r   keyssetProcessEnvironmenterrorOccurredconnectr   setWorkingDirectorysetProcessChannelModeMergedChannelsri   setStandardOutputFilestart)rS   envr   vars       rV   start_serverzLSPClient.start_server   sJ     	4: 	F*11#((4;K2L2LMMNNN tnnk,,.. =H$$
 (=??K??C:c?? !C   w$
 !BJ..JJ}bj.GHHH %A*4,,A!RZ//JJy"*Y*?@@@ C z 1 1

3
30000KK;BB388::NNOOO 	))#...!))$*DEEE'',,,))(*ABBB+K--d.BCCC 	$*1-t/?/CDDDDDrW   c                    t                               d                    d                    | j                  | j                             t          |           | _        | j                                        }| j        dk    r{| j	        rtt          j        D ](}|                    |t          j        |                    )t                               d                    |                                                     | j                            |           | j        j                            | j                   | j	        rK| j                            t          j                   | j        | j                            | j                   nJ| j                            t          j                   | j        | j                            | j                   | j                            | j        d         | j        dd                    dS )zStart transport layer.zStarting transport for {1}: {0}rn   r#   z$Transport process env variables: {0}Nr   r%   )rG   r   rZ   r^   r|   r9   r   r5   r   r*   r[   r   r   r   r   r   r   r   r   SeparateChannelsrk   setStandardErrorFiler   r   r   )rS   r   r   s      rV   start_transportzLSPClient.start_transport4  s   5VCHHT%8994=II	K 	K 	K "$n//11 =H$$$z 1 1

3
30000KK>EE

     	,,S111 	$,,T-GHHH: 	NN001JKKK&233D4KLLLN001HIII&244T5LMMM 	T03T5H5LMMMMMrW   c                    |                                   |                                  |                                  | j                            t
          j                  }t          |t          j        |           | _	        | j	        j
                            | j                   t                              d                    | j                             dS )zStart client.zLSP {} client started!N)r   r   r   r1   
getsockoptrM   FDr   Readr8   	activatedr   on_msg_receivedrG   debugrZ   r9   )rS   fids     rV   r   zLSPClient.startU  s     	%%'''  ++CF33'_-A4HH''(<=== 	-44T]CCDDDDDrW   c                     t                               d                    | j                             | j        E| j        j                            | j                   | j                            d           d| _        | j	        3| j	        
                                 | j	                            d           | j                                         | j        5| j        
                                 | j                            d           dS dS )zStop transport and server.zStopping {} client...NFi  )rG   r   rZ   r9   r8   r   
disconnectr   
setEnabledr5   closewaitForFinishedrO   destroyr6   rh   s    rV   stopzLSPClient.stopd  s    +224=AABBB=$M#..t/CDDDM$$U+++ DM >%N  """N**4000;"KK''----- #"rW   c                 T    | j                                         }|t          j        k    S )z#Detect if transport layer is alive.)r5   stater   
NotRunningrS   r   s     rV   is_transport_alivezLSPClient.is_transport_alivex  s#    $$&&+++rW   c                     d}t          j        | j                  sd}nV	 t          j        | j                                                  }n# t           j        $ r d}Y nw xY w|t           j        k    rd}|S )z"Check if an stdio server is alive.TFr-   )psutil
pid_existsr7   ProcessstatusNoSuchProcessSTATUS_ZOMBIE)rS   alive
pid_statuss      rV   is_stdio_alivezLSPClient.is_stdio_alive}  s     00 	EE #^DN;;BBDD

'      


 V111s   +A A A c                 T    | j                                         }|t          j        k    S )z Detect if a tcp server is alive.)r6   r   r   r   r   s     rV   is_server_alivezLSPClient.is_server_alive  s#    !!##+++rW   c                    d}| j         ru|                                 sat                              d                    | j                             | j        s&d| _        | j                            | j                   d}| j	        ru| 
                                sat                              d                    | j                             | j        s&d| _        | j                            | j                   d}| j        ru|                                 sat                              d                    | j                             | j        s&d| _        | j                            | j                   d}|S )zh
        Detect if the transport layer or server are down to inform our
        users about it.
        Fz Transport layer for {} is down!!TzLSP server for {} is down!!)r5   r   rG   r   rZ   r9   rB   r   r   r6   r   rA   r7   r   )rS   is_downs     rV   r   zLSPClient.is_down  sj   
 > 	$"9"9";"; 	LL299$-HHJ J J. 7.2+"''666G; 	t3355 	LL6==dmLLMMM+ 7+/("''666G> 	$"5"5"7"7 	LL6==dmLLMMM+ 7+/("''666GrW   c                    |                                  rdS | j        s|dk    rdS t          j        |v rdS | j        }|t
          j        k    r| j        ||d}|| j        | j        <   n0|t
          j        k    r| j        |d}n|t
          j	        k    r||d}t                              d                    ||                     t                      r| j                            ||f           d}t!          j                    }||z   }	 	 | j                            |t&          j        	           | xj        dz  c_        t+          |          S # t&          j        j        $ rq t!          j                    |k    r"| j                            | j                   Y dS | j        rt                              d
           t!          j        d           Y nw xY w)zSend message to transport.N
initialize)idmethodparams)r   result)r   r   zPerform request {0} with id {1}r%   Tflagsz#The send queue is full! Retrying...g?)r   r:   r   CANCELr<   r   REQUESTr=   RESPONSENOTIFICATIONrG   r   rZ   r   rR   ru   timer2   
send_pyobjrM   NOBLOCKintrH   Againr   r   r9   warningsleep)	rS   r   r   rb   _idmsgtimeout
start_timetimeout_times	            rV   sendzLSPClient.send  s   <<>> 	F  	Fl$:$:F!V++F;&&&&   C
 17DOD,--[)))&  CC [---   C
 	6==fcJJKKK  !! 	1N!!3-000 Y[[
!G+	#..s#+.FFF  A%  3xx9?   9;;--&++DM:::FF# JNN#HIII
2	s   AE A
G5GGc           	         | j                             d           	 	 | j                            t          j                  }	 |d         }t                              d                    | j	        |                     n# t          $ r Y nw xY wd|v rt                              d                    | j	        t          |d                                        | j	        dk    rt                      d	k    st          r|d                             d
d          }|d                             di                               d          }|7d                    |          }|dz   |z   }| j                            |           |d         }|| j        v r | j        |         ddg i           nd|v rt|d         d	         dk    rad|v rt'          |d                   | _        |d         | j        v r4| j        |d                  }t-          | |          } ||d                    nd|v r|d         |d         }|| j        v r| j        |         }|| j        v rl| j        |         }t-          | |          } ||d         |           | j                            |           || j        v r| j                            |           n;# t2          $ r Y n/t          j        $ r | j                             d           Y dS w xY w)zProcess received messages.FTr   r   z{} response: {}rH   z{} Response error: {}r#   r   messager-   data	tracebackN
r   r   $r   )r8   r   r1   
recv_pyobjrM   r   rG   r   rZ   r9   KeyErrorreprr   r	   rE   r^   sig_server_errorr   r@   r   r<   handler_registrygetattrr=   popRuntimeErrorZMQError)	rS   respr   r   r   req_idhandler_namehandlerreq_types	            rV   r   zLSPClient.on_msg_received  sK    	  '''8	7)443;4GG!(^FLL)00GGI I I I   D d??LL!8"(&T']8K8K"L"LN N N}00 +,,q00C0&*7m&7&7	2&F&FG)-g):):62)F)F),[)9)9 &(4,.GGI,>,>	,5,<w,F	 $ 5 : :9 E E E!%d!T^332DN624(BHHH%%H~a(C//4<</24:D,>T-BBB $ 5d8n E )&-dL&A&AG#GDN333%%H~1!%d!T_44'+v'>H'4+@@@/3/DX/N*1$*E*E 'X ? ? ? $ 3 3F ; ; ;#)T^#;#;$(N$6$6v$>$>$>    <   ((...m8	s<   %K ;A? >K ?
B	K BH9K 
K>(K>=K>c                     || j         v rF| j         |         }t          | |          } ||          }d|v r|d         r|d         | j        |<   |S d S )Nresponse_callbackrequires_response)sender_registryr   r@   )rS   r   r   r   r   r   s         rV   perform_requestzLSPClient.perform_request#  sr    T)))/7LdL11G'&//C"f,,-. F*01D*EDN3'J *)rW   )r   c                     |d         | _         | j        s| j                                        nd }|t	          j        t          j        | j                            	                                | j
        t          d}|S )Npid)	processIdrootUricapabilitiestrace)r7   rF   r5   r   pathlibPathr]   abspathrJ   as_urirK   TRACE)rS   r   r,   kwargsr   s        rV   r   zLSPClient.initialize.  ss      040DNdn&&((($|CK$<$<==DDFF 3	
 
 rW   c                 
    i }|S N rS   r   s     rV   shutdownzLSPClient.shutdown;      rW   c                     d| _         d S )NT)r;   )rS   responser,   s      rV   handle_shutdownzLSPClient.handle_shutdown@  s    "rW   c                 
    i }|S r  r  r  s     rV   exitzLSPClient.exitD  r  rW   c                    |d         }t          |d         t                    r|d         }t          |d<   ||d         d<   |d         |                    d           | j                            |           d| _        |                                  |                     | j	                   | j
                            | j        | j                   dS )zd
        Register server capabilities and inform other plugins that it's
        available.
        r   textDocumentSyncchangeNT)
isinstancer   r   r   rL   updater:   initialized_callsend_configurationsr+   sig_initializer   r9   )rS   rL   r,   rb   s       rV   process_server_capabilitiesz%LSPClient.process_server_capabilitiesI  s     0?();<cBB 	D%&89D5O12?C128<019""#5666&&'9:::   	  !4555 	  !8$-HHHHHrW   c                 
    i }|S r  r  r  s     rV   r  zLSPClient.initialized_callg  r  rW   c                 8    | j         d         }|d         d         S )N	workspaceworkspaceFolders	supportedrL   rS   workspace_settingss     rV   support_multiple_workspacesz%LSPClient.support_multiple_workspacesm  s!    !4[A!"45kBBrW   c                 8    | j         d         }|d         d         S )Nr  r  changeNotificationsr  r  s     rV   support_workspace_updatez"LSPClient.support_workspace_updater  s"    !4[A!"456KLLrW   N)3__name__
__module____qualname____doc__r   dictr{   r  r   r   r   r/   re   propertyri   rk   rx   r|   r   r   r   ProcessErrorr   r   r   r   r   r   r   r   r   r   r   r   r   SERVER_READYr   r   
INITIALIZEr   SHUTDOWNr  r  r   EXITr  r  INITIALIZEDr  r  r"  r  rW   rV   r"   r"   =   sL       >> VD#&&N vc{{ F3KKM "$&(("< < < <|  . 0 0 X0 3 3 X3   X.   X>* * * 
T(
  / / ! /;E ;E ;EzN N NBE E E. . .(, , ,
  , , ,
  <5 5 5n 
TVV; ; V;z   W\\/:;;;	 	 <; 	 \/8999  :9 W#,--# # .-# 49:::  ;: W#.//I I 0/I: 4@AAA  BA
 C C XC M M XM M MrW   r"   c                  `   ddl m}   | d          }d}dddd	}t          |||          }|                                 |j                            |j                   t          j        t          j        t          j	                   t          j        |                                           d
S )zTest LSP client.r   )qapplication   )	test_timez%--host %(host)s --port %(port)s --tcpr   i'  pyls)r)   r'   r.   N)spyder.utils.qthelpersr0  r"   r   aboutToQuitr   r   signalSIGINTSIG_DFLrq   r  exec_)r0  appserver_args_fmtrU   lsps        rV   testr=  x  s    333333
,
#
#
#C=O*DHHO
C/
:
:CIIKKKOCH%%%
M&-000HSYY[[rW   __main__)=r&  loggingr[   os.pathpathr]   r   r6  rq   r   qtpy.QtCorer   r   r   r   r   rM   r   spyder.api.config.mixinsr   spyder.config.baser	   r
   r   r   r   spyder.config.utilsr   spyder.plugins.completion.apir   r   r   r   r   =spyder.plugins.completion.providers.languageserver.decoratorsr   r   r   r   <spyder.plugins.completion.providers.languageserver.transportr   <spyder.plugins.completion.providers.languageserver.providersr   spyder.utils.miscr   r   realpathr^   getcwdr`   __file__rz   PENDINGr*  r   r  	getLoggerr#  rG   r"   r=  r  rW   rV   <module>rP     s     				         



  I H H H H H H H H H H H H H 



  A @ @ @ @ @K K K K K K K K K K K K K K + + + + + +             > > > > > > > > > > > >           9 9 9 9 9 9 9 9 3<!,X!6!68 8 9 9
	 	 E		8	$	$ wM wM wM wM wM/1L wM wM wMt   zDFFFFF rW   