
    Ki"                        d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	  ej                  e      Zg dZddgZ G d	 d
      ZddZddZy)zTypeScript tsconfig.json path alias resolver.

Resolves TypeScript path aliases (e.g., ``@/ -> src/``) declared in
``compilerOptions.paths`` so that ``IMPORTS_FROM`` edges can point to
real file paths instead of raw alias strings.
    )annotationsN)Path)Optional)z.tsz.tsxz.jsz.jsxz.vueztsconfig.jsonztsconfig.app.jsonc                  X    e Zd ZdZd
dZddZddZddZddZddZ		 	 	 	 	 	 	 	 ddZ
y	)TsconfigResolverzHResolves TypeScript path aliases (e.g., @/ -> src/) using tsconfig.json.c                    i | _         y )N)_cache)selfs    o/home/jay/workspace/scripts/.codegraph-venv/lib/python3.12/site-packages/code_review_graph/tsconfig_resolver.py__init__zTsconfigResolver.__init__   s	    13    c                   	 | j                  |      }|y|j                  d      }|j                  di       }|j                  dd      }|sy|rt        |      |z  j                         }nt        |      j                         }| j	                  |||      S # t
        t        t        f$ r t        j                  d|d       Y yw xY w)	z:Resolve a TS path alias to an absolute file path, or None.NbaseUrlpaths_tsconfig_dir z)TsconfigResolver: unexpected error for %sT)exc_info)
_load_tsconfig_for_filegetr   resolve_match_and_probeOSError
ValueError	TypeErrorloggerdebug)r
   
import_str	file_pathconfigbase_urlr   tsconfig_dirbase_dirs           r   resolve_aliaszTsconfigResolver.resolve_alias#   s    	11)<F~&,jj&;H*0**Wb*AE &

?B ?L .9BBD-557((UHEEY/ 	LL;YQU   		s   B 7B A
B ,CCc                   t        |      j                  j                         }|}g }	 t        |      }|| j                  v r'| j                  |   }|D ]  }|| j                  |<    |S |j                  |       t        D ]G  }||z  }	|	j                         s| j                  |	      }
||
d<   |D ]  }|
| j                  |<    |
c S  |j                  }||k(  r|D ]  }d| j                  |<    y|})z/Find and load tsconfig.json for the given file.r   N)	r   parentr   strr	   append_TSCONFIG_NAMESis_file_parse_tsconfig)r
   r   	start_dircurrentvisiteddir_strresultvisited_dirname	candidater   r%   s               r   r   z(TsconfigResolver._load_tsconfig_for_fileA   s   O**224	'lG$++%W-#* 6K/5DKK,6NN7#' "#dN	$$&!11)<F.5F?+'. :39K0:!M" ^^F #* 4K/3DKK,4G1 r   c                :    t               }| j                  ||      S )z5Parse a tsconfig.json file (supports JSONC comments).)set_resolve_extends)r
   tsconfig_pathseens      r   r*   z TsconfigResolver._parse_tsconfiga   s    $$]D99r   c                   t        |j                               }||v rt        j                  d|       i S ||hz  }	 |j	                  d      }| j                  |      }	 t        j                  |      }i }|j                  d      }|rt        |t               r|j                  d      r|j                  |z  j                         }	|	j                  s|	j                  d      }	|	j!                         rE| j#                  |	|      }
|
j                  d	i       }|j%                  d	i       j'                  |       |j                  d	i       }|j%                  d	i       j'                  |       |j                  d	i       }d
|v r|d
   |d
<   d|v r|d   |d<   |S # t
        $ r t        j                  d|       i cY S w xY w# t        j                  $ r t        j                  d|       i cY S w xY w)z/Recursively resolve the tsconfig extends chain.z&TsconfigResolver: cycle detected at %szutf-8)encodingz TsconfigResolver: cannot read %sz$TsconfigResolver: invalid JSON in %sextends.z.jsoncompilerOptionsr   r   )r&   r   r   r   	read_textr   _strip_jsonc_commentsjsonloadsJSONDecodeErrorr   
isinstance
startswithr%   suffixwith_suffixr)   r5   
setdefaultupdate)r
   r6   r7   	canonicalrawstrippeddatar/   r:   parent_pathparent_configparent_opts
child_optscompiler_optionss                 r   r5   z!TsconfigResolver._resolve_extendsf   s   --/0	LLA9MIyk!	))7);C
 --c2	H-D
 !%)!4z'3/G4F4Fs4K(//'9BBDK%%)55g>""$ $ 5 5k4 H+//0A2F!!"3R8??L88$5r:
+R077
C!::&7<(( 0 ;F9&&.w7F7OA  	LL;]KI	 ## 	LL?OI	s#   F !G !F>=F>+G/.G/c                   g }d}t        |      }||k  r$||   }|dk(  ro|j                  |       |dz  }||k  rN||   }|j                  |       |dk(  r"|dz   |k  r|dz  }|j                  ||          n|dk(  rn|dz  }||k  rN|dz  }|dk(  rJ|dz   |k  rB||dz      dk(  r7|dz  }||dz
  k  r'||   dk(  r||dz      dk(  r|dz  }n|dz  }||dz
  k  r'|}|dk(  r:|dz   |k  r2||dz      dk(  r'|dz  }||k  r||   dk7  r|dz  }||k  r	||   dk7  r|j                  |       |dz  }||k  r$d	j                  |      }t        j                  d
d|      }|S )z<Remove // and /* */ comments and trailing commas from JSONC.r   "   \/*   
r   z,\s*([\]}])z\1)lenr'   joinresub)r
   textr/   inchcrJ   s           r   r>   z&TsconfigResolver._strip_jsonc_comments   s   I!eaBSyb!Q!eQAMM!$DyQUQYQd1g.cFA !e QSyQUQY4A;#+=Q!a%iAw#~$q1u+*<QFA	 !a%i ASyQUQY4A;#+=Q!eQ4FA !eQ4MM"FAI !eL 776?66.%:r   c                   dd}t        |j                         |d      }|D ]d  \  }}t        ||      }||D ]K  }	d|	v r|	j                  d|d      }
n|	}
||
z  j	                         }t        |      }|s>t        |      c c S  f y)zAMatch import_str against alias patterns and probe the filesystem.c                F    | d   }t        |j                  d      d         S )Nr   rV   )rY   	partition)itempats     r   _pattern_specificityz?TsconfigResolver._match_and_probe.<locals>._pattern_specificity   s$    q'Cs}}S)!,--r   T)keyreverseNrV   rS   )re   ztuple[str, list[str]]returnint)sorteditems_match_patternreplacer   _probe_pathr&   )r
   r   r   r"   rg   sorted_pathspatternreplacementsrD   replacementmappedcandidate_basefounds                r   r   z!TsconfigResolver._match_and_probe   s    	. ekkm1EtT%1 	&!G\#GZ8F~+ 	&+%(00fa@F(F"*V"3!<!<!>#N3u:%	&	&  r   N)rj   None)r   r&   r   r&   rj   Optional[str])r   r&   rj   zOptional[dict])r6   r   rj   dict)r6   r   r7   zset[str]rj   rz   )r]   r&   rj   r&   )r   r&   r   zdict[str, list[str]]r"   r   rj   ry   )__name__
__module____qualname____doc__r   r#   r   r*   r5   r>   r    r   r   r   r      sQ    R4<@:
*X.` $ 	
 
r   r   c                    d| vr	|| k(  rdS dS | j                  d      \  }}}|j                  |      r|j                  |      sy|rt        |      t        |      z
  n
t        |      }|t        |      | S )zAReturn the wildcard-matched suffix if pattern matches import_str.rV   r   N)rd   rC   endswithrY   )rr   r   prefix_
suffix_patends         r   rn   rn      s|    
'7*r44#--c2FAz!!&)j.A.A*.M/9#j/C
O
+s:Cc&k#&&r   c                <   | j                         r| S t        D ]J  }| j                  s| j                  |      nt	        t        |       |z         }|j                         sH|c S  | j                         r't        D ]  }| d| z  }|j                         s|c S  y)z6Probe base and base + extensions for an existing file.indexN)r)   _PROBE_EXTENSIONSrD   rE   r   r&   is_dir)baseextr2   s      r   rp   rp      s    ||~  15D$$S)$s4ySVBW	 {{}$ 	!Cse},I  "  	! r   )rr   r&   r   r&   rj   ry   )r   r   rj   zOptional[Path])r~   
__future__r   r?   loggingr[   pathlibr   typingr   	getLoggerr{   r   r   r(   r   rn   rp   r   r   r   <module>r      s\    #   	  			8	$ ;  #$78F F\
'r   