B
    bR                 @   s&  d Z ddlZddlZddlZddlmZ ddlmZ dZdZ	dZ
dZd	Zd
ZdZdddddgZdddgZeredZG dd dZG dd dZG dd dZG dd dZG dd dZG dd  d ZG d!d" d"Ze	fd#d$Ze	dfd%d&Znd'd$ Zd-ee d(d)d*Zee d(d+d,ZdS ).z%Common routines for processing Java.     N)Path)ListTz1.4)z1.8zC:/Program Files*/*/*jdk*/binz C:/Program Files*/*/*jdk*%s*/binz4/System/Library/Frameworks/JavaVM.framework/Headers/zA/System/Library/Frameworks/JavaVM.framework/Versions/%s*/Headers/z!/usr/lib/jvm/default-java/includez/usr/lib/jvm/java-*/includez/opt/oracle-jdk-bin-*/includez/opt/openjdk-bin-*/includez/usr/lib/openjdk-*/includez#/usr/lib/jvm/java-*-sun-%s*/includez&/usr/lib/jvm/java-%s*-openjdk*/includez/usr/java/jdk%s*/includezZ(\n|\\\\|//|\\[\'"]|[\'"{\};.()]|\d*\.\d*|[A-Za-z_][\w$.]*|<[A-Za-z_]\w+>|/\*|\*/|\[\]|->)c               @   st   e Zd ZdZefddZdd Zdd Zdd	 Zd
d Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd ZdS )
OuterStatezgThe initial state for parsing a Java file for classes,
        interfaces, and anonymous inner classes.c             C   s\   |dkrd| }t ||| _g | _g | _g | _d| _d| _g | _g | _dgg| _	d | _
d S )N)z1.1z1.2z1.3z1.4z1.5z1.6z1.7z1.856z9.0z10.0z11.0z12.0z13.0z14.0z15.0z16.0z17.0zJava version %s not supportedr      )NotImplementedErrorversionlistClasseslistOutputsstackBracketsbracketsnextAnonlocalClassesstackAnonClassBracketsanonStacksStackpackage)selfr	   msg r   4lib/python3.7/site-packages/SCons/Tool/JavaCommon.py__init__g   s    
zOuterState.__init__c             C   s   d S )Nr   )r   r   r   r   trace   s    zOuterState.tracec             C   s.   y| j S  tk
r(   t| }|| _ |S X d S )N)
classStateAttributeError
ClassState)r   retr   r   r   __getClassState   s    zOuterState.__getClassStatec             C   s.   y| j S  tk
r(   t| }|| _ |S X d S )N)ZpackageStater   PackageState)r   r   r   r   r   Z__getPackageState   s    zOuterState.__getPackageStatec             C   s:   y| j S  tk
r4   | | _tdt| }|| _ |S X d S )Nr   )	anonStater   outer_state	SkipStateAnonClassState)r   r   r   r   r   __getAnonClassState   s    zOuterState.__getAnonClassStatec             C   s0   y| j S  tk
r*   td| }|| _ |S X d S )Nr   )	skipStater   r!   )r   r   r   r   r   __getSkipState   s    
zOuterState.__getSkipStatec             C   s
   | j d S )N)r   )r   r   r   r   _getAnonStack   s    zOuterState._getAnonStackc             C   s   | j d | _ d S )Nr   )r   )r   r   r   r   openBracket   s    zOuterState.openBracketc             C   s   | j d | _ t| jrb| j | jd krb| jd| j | j  | j  | j	  | j  t| j
r| j | j
d kr| jtkr|    | j
  d S )Nr   r&   $)r   lenr   r   appendjoinr
   r   popr   r   r	   scopeStateVersionsr'   )r   r   r   r   closeBracket   s    






zOuterState.closeBracketc             C   s   |d d dkrt d| S |dkr,t d| S |dkr>|   n|dkrP|   n|dkrbt || S |d	krt| jd
kr|  S |  S |dkrt| jd
krd| _| j	| j
 |  S |dkr|  S |dkr|  S | S )N   z//
z/*z*/{})"'newr   )classZ	interfaceenumr   r   .)IgnoreStater(   r/   r*   r
   _OuterState__getAnonClassState_OuterState__getSkipStater   r   r+   r   _OuterState__getClassState_OuterState__getPackageState)r   tokenr   r   r   
parseToken   s0    




zOuterState.parseTokenc             C   s   | j dkr,| jd }| jd|| jf  nr| j dkr| j| j g }|| j |  d d |  d< x|  D ]}|t	| qvW | jd
| | jd | _|  d dS )	zAdd an anonymous inner class)z1.1z1.2z1.3z1.4r   z%s$%d)z1.5z1.6z1.7z1.8r   r   z9.0z10.0z11.0z12.0z13.0z14.0z15.0z16.0z17.0r&   r   r)   N)r	   r
   r   r+   r   r   r   extendr'   strr,   )r   ZclazzZ	classNameZanonr   r   r   addAnonClass   s    

zOuterState.addAnonClassc             C   s
   || _ d S )N)r   )r   r   r   r   r   
setPackage  s    zOuterState.setPackageN)__name__
__module____qualname____doc__default_java_versionr   r   r=   r>   r;   r<   r'   r(   r/   r@   rC   rD   r   r   r   r   r   c   s   $	"r   c               @   sH   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
dS )
ScopeStatezk
        A state that parses code within a scope normally,
        within the confines of a scope.
        c             C   s   |j | _ || _d| _d S )Nr   )r    	old_stater   )r   rK   r   r   r   r     s    zScopeState.__init__c             C   s.   y| j S  tk
r(   t| }|| _ |S X d S )N)r   r   r   )r   r   r   r   r   r     s    zScopeState.__getClassStatec             C   s4   y| j S  tk
r.   tdt| }|| _ |S X d S )Nr   )r   r   r!   r"   )r   r   r   r   r   r#     s    zScopeState.__getAnonClassStatec             C   s0   y| j S  tk
r*   td| }|| _ |S X d S )Nr   )r$   r   r!   )r   r   r   r   r   r%   #  s    
zScopeState.__getSkipStatec             C   s   | j d | _ d S )Nr   )r   )r   r   r   r   r(   +  s    zScopeState.openBracketc             C   s   | j d | _ d S )Nr   )r   )r   r   r   r   r/   .  s    zScopeState.closeBracketc             C   s   |d d dkrt d| S |dkr,t d| S |dkr>|   nb|dkrn|   | jdkr| j   | jS n2|d	krt || S |d
kr|  S |dkr| 	 S | S )Nr0   z//r1   z/*z*/r2   r3   r   )r4   r5   r6   r9   )
r:   r(   r/   r   r    r'   r-   rK   _ScopeState__getAnonClassState_ScopeState__getSkipState)r   r?   r   r   r   r@   1  s$    




zScopeState.parseTokenN)rE   rF   rG   rH   r   Z_ScopeState__getClassStaterL   rM   r(   r/   r@   r   r   r   r   rJ     s   rJ   c               @   s    e Zd ZdZdd Zdd ZdS )r"   z/A state that looks for anonymous inner classes.c             C   s   |j | _ || _d| _d S )Nr   )r    rK   brace_level)r   rK   r   r   r   r   O  s    zAnonClassState.__init__c             C   s   |d d dkrt d| S |dkr,t d| S |dkr8| S |d dkrT|d d	krT| S |d
krl| jd | _| S | jdkr|dkrtdt| S |dkrt || S |dkr| jd | _| S |dkr| j  | jjtkrt| j	d
|S | j	
|S )Nr0   z//r1   z/*z*/r   <r&   >(r   r6   )r4   r5   )r2   )rK   )r:   rN   r!   r"   r    rC   r	   r.   rJ   rK   r@   )r   r?   r   r   r   r@   U  s0    




zAnonClassState.parseTokenN)rE   rF   rG   rH   r   r@   r   r   r   r   r"   L  s   r"   c               @   s    e Zd ZdZdd Zdd ZdS )r!   zcA state that will skip a specified number of tokens before
        reverting to the previous state.c             C   s   || _ || _d S )N)tokens_to_skiprK   )r   rS   rK   r   r   r   r   x  s    zSkipState.__init__c             C   s    | j d | _ | j dk r| jS | S )Nr   )rS   rK   )r   r?   r   r   r   r@   |  s    
zSkipState.parseTokenN)rE   rF   rG   rH   r   r@   r   r   r   r   r!   t  s   r!   c               @   s    e Zd ZdZdd Zdd ZdS )r   z<A state we go into when we hit a class or interface keyword.c             C   s
   || _ d S )N)r    )r   r    r   r   r   r     s    zClassState.__init__c             C   s   |dkr| S | j jr| j jd | j jd d kr| j jd }y|| }|| d ||< W n tk
rt   d||< Y nX t|| | }| j ji  | j j| | j jdg | j S )Nr1   r&   r   r   )r    r   r   KeyErrorrB   r+   r
   r   )r   r?   localsidxr   r   r   r@     s     
zClassState.parseTokenN)rE   rF   rG   rH   r   r@   r   r   r   r   r     s   r   c               @   s    e Zd ZdZdd Zdd ZdS )r:   zOA state that will ignore all tokens until it gets to a
        specified token.c             C   s   || _ || _d S )N)ignore_untilrK   )r   rX   rK   r   r   r   r     s    zIgnoreState.__init__c             C   s   | j |kr| jS | S )N)rX   rK   )r   r?   r   r   r   r@     s    
zIgnoreState.parseTokenN)rE   rF   rG   rH   r   r@   r   r   r   r   r:     s   r:   c               @   s    e Zd ZdZdd Zdd ZdS )r   ztThe state we enter when we encounter the package keyword.
        We assume the next token will be the package name.c             C   s
   || _ d S )N)r    )r   r    r   r   r   r     s    zPackageState.__init__c             C   s   | j | | j S )N)r    rD   )r   r?   r   r   r   r@     s    zPackageState.parseTokenN)rE   rF   rG   rH   r   r@   r   r   r   r   r     s   r   c          	   C   s,   t | ddd}| }W d Q R X t||S )Nrzutf-8)encoding)openread
parse_java)fnr	   fdatar   r   r   parse_java_file  s    ra   c             C   s\   d}t |}|}x*t| D ]}||}|r||| qW |jrR|jdtj}||jfS )zParse a .java file and return a double of package directory,
        plus a list of .class files that compiling that .java file will
        produceNr9   )	r   _reTokenfindallr@   r   replaceossepr   )contentsr	   r   r   initialZ	currstater?   r   r   r   r]     s    
 r]   c             C   s   t j| S )z "Parse" a .java file.

        This actually just splits the file name, so the assumption here
        is that the file name matches the public class name, and that
        the path to the file is the same as the package name.
        )re   pathsplit)r^   r   r   r   ra     s    )returnc             C   sD   | dkr@g }|r t  t| }n
t  t}dd }t||ddS g S )a   Find possible java jdk installation directories.

    Returns a list for use as `default_paths` when looking up actual
    java binaries with :meth:`SCons.Tool.find_program_path`.
    The paths are sorted by version, latest first.

    Args:
        platform: selector for search algorithm.
        version: if not None, restrict the search to this version.

    Returns:
        list of default paths for jdk.
    win32c             S   s0   t | jd }|ds,d|ddd  }|S )a   Generates a sort key for win32 jdk versions.

            We'll have gotten a path like ...something/*jdk*/bin because
            that is the pattern we glob for. To generate the sort key,
            extracts the next-to-last component, then trims it further if
            it had a complex name, like 'java-1.8.0-openjdk-1.8.0.312-1',
            to try and put it on a common footing with the more common style,
            which looks like 'jdk-11.0.2'. 

            This is certainly fragile, and if someone has a 9.0 it won't
            sort right since this will still be alphabetic, BUT 9.0 was
            not an LTS release and is 30 mos out of support as this note
            is written so just assume it will be okay.
            rT   Zjdkr   r&   )r   parts
startswithrsplit)javadr   r   r   win32getvnum  s    
z+get_java_install_dirs.<locals>.win32getvnumT)keyreverse)globjava_win32_version_dir_globjava_win32_dir_globsorted)platformr	   pathsrr   r   r   r   get_java_install_dirs  s    
r{   c             C   s   |sg S | d dkrLt j|}t jt j|dd}|t j|dg}n| d dkrx|sdtg}qttt| }ntg }|sx@t	D ]}|
t| qW n"x tD ]}|
t||  qW g }x$|D ]}|
|t j|dg qW |S )a  Find java include paths for JNI building.

    Cannot be called in isolation - `javac` refers to an already detected
    compiler. Normally would would call :func:`get_java_install_dirs` first
    and then do lookups on the paths it returns before calling us.

    Args:
        env: construction environment, used to extract platform.
        javac: path to detected javac.
        version: if not None, restrict the search to this version.

    Returns:
        list of include directory paths.
    ZPLATFORMrl   z..ZincludedarwinZlinux)re   ri   dirnamenormpathr,   java_macos_include_dir_globrx   ru   #java_macos_version_include_dir_globjava_linux_include_dirs_globrA   $java_linux_version_include_dirs_glob)envZjavacr	   Zjavac_bin_dirZjava_inc_dirrz   Z
base_pathspr   r   r   get_java_include_paths  s(    


r   )N)rH   re   reru   Zpathlibr   typingr   Zjava_parsingrI   r.   rw   rv   r   r   r   r   compilerb   r   rJ   r"   r!   r   r:   r   ra   r]   rB   r{   r   r   r   r   r   <module>   sH   
 &D(
1