o
    Y۷i6                     @  s   d 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Zddlm	Z	 ddl
mZ ddl
mZ ddlmZmZ dd	lmZmZmZmZ dd
lmZmZmZmZ d&ddZd'ddZd(ddZd)d"d#Zd*d$d%Z e!dkrse"e  dS dS )+z-TVM-FFI Stub Generator (``tvm-ffi-stubgen``).    )annotationsNPath   )codegen)consts)FileInfocollect_files)collect_global_funcscollect_type_keysobject_info_from_type_keytoposort_objects)FuncInfo
ImportItem
InitConfigOptionsreturnintc                  C  st  t  } | jpg D ]}t| qdd | jD }tdd | jD }t }d}| jr:t| jd 	 }|
 r:|j}tj }|D ]%}zt|| W qA tyf   ttj d|j dt  tj  Y qAw | jr||dusrJ dt||| j||d	 |D ]8}| jrttj d
|j tj  z	t|| || W q~ ty   ttj d|j dt  tj  Y q~w ~dS )zCommand line entry point for ``tvm-ffi-stubgen``.

    This generates in-place type stubs inside special ``tvm-ffi-stubgen`` blocks
    in the given files or directories. See the module docstring for an
    overview and examples of the block syntax.
    c                 S  s   g | ]}t |qS  )ctypesCDLL).0libr   r   F/home/ubuntu/vllm_env/lib/python3.10/site-packages/tvm_ffi/stub/cli.py
<listcomp>2   s    z__main__.<locals>.<listcomp>c                 S  s   g | ]}t |qS r   r   )r   fr   r   r   r   3   s    Nr   z[Failed] File "z": z!init-path could not be determined)init_cfg	init_pathglobal_funcsz[File] )_parse_argsimports	importlibimport_moduledllsr	   filesr
   r   resolveis_fileparentCTY_MAP_DEFAULTScopy_stage_1	ExceptionprintTERM_REDpath	traceback
format_exc
TERM_RESETinit_stage_2verbose	TERM_CYAN_stage_3)optimpr#   r$   r   r   ty_mapfiler   r   r   __main__(   sR   
  r<   r;   r   r:   dict[str, str]Nonec                 C  s|   | j D ]8}|jdkr;zt|jtsJ |jd\}}W n ty2 } z
td|j d|d }~ww | || < qd S )Nzty-mapz->zInvalid ty_map format at line z. Example: `A.B -> C.D`)	code_blockskind
isinstanceparamstrsplit
ValueErrorlineno_startstrip)r;   r:   codelhsrhser   r   r   r+   c   s    

r+   r$   list[FileInfo]r   r   r   r   r   dict[str, list[FuncInfo]]c                   s  d fdd}dd  D }d	d  D t jB }|j }|r(|d
s(|d
7 }|d
}	t }
|D ]}|
|g  q2|
 D ]\}}||	ksM|	|sMq?t
||v rTg n||g dd d}t
t|| }t|}|sp|spq?||d
d }|jddd |d }||}|jddd}|tj|j||||||	kd W d    n1 sw   Y  |  |d }||}|jddd}|tj|j|dd W d    n1 sw   Y  |  q?d S )Nr/   r   r   r   c                   sh   |   st| dg d}n! D ]}| |jr|  S qtj| dd}|d us-J d|   | |S )Nr   )r/   linesr?   T)r;   include_emptyzFailed to read file: )existsr   samefiler/   	from_fileappend)r/   retr;   r$   r   r   _find_or_insert_filez   s   
z&_stage_2.<locals>._find_or_insert_filec                 S  s,   h | ]}|j D ]}|jd kr|jd qqS )globalr   r?   r@   rB   r   r;   rH   r   r   r   	<setcomp>   s    z_stage_2.<locals>.<setcomp>c                 S  s(   h | ]}|j D ]
}|jd kr|jqqS )objectrX   rY   r   r   r   rZ      s    .c                 S  s   | j jS )N)schemaname)r   r   r   r   <lambda>   s    z_stage_2.<locals>.<lambda>)key/T)parentsexist_okz_ffi_api.pyazutf-8)encoding)is_rootz__init__.py_ffi_api)	submodule)r/   r   r   r   )r(   BUILTIN_TYPE_KEYSprefixrG   endswithrstripr   
setdefaultitems
startswithsortedgetsetr   replacemkdiropenwriteGgenerate_ffi_apir?   reloadgenerate_init)r$   r:   r   r   r   rV   defined_func_prefixesdefined_objsprefix_filterroot_prefixprefixesrj   	obj_namesfuncsobjsobject_infos	directorytarget_pathtarget_filer   r   rU   r   r4   s   sf   


r4   r8   r   c                   s  t  }t   g }d}| jD ]5}|jdkrB|j\}}	}
|t|t|	o,t|	to,|		 dk|
r0|
nd d |
r;|
dks@|
drBd}q| jD ]%}|jdkrk||jd	 g }|D ]	}||jj qXt||||| qF| jD ].}|jd
kr|j}t|tsJ t|}|||}t|j} | t||||| qo fdd|D }| jD ]}|jdkrt|||  nq| jD ]}|jdkr| B }|r|dhB }t|||  nq| jD ]}|jdkrt| q| j|j|jd d S )NFzimport-objecttrue)type_checking_onlyalias_FFI_LOAD_LIBzlibinfo.load_lib_moduleTrW   r   r[   c                   s   g | ]	}|j  vr|qS r   )	full_name)r   idefined_typesr   r   r      s    z_stage_3.<locals>.<listcomp>zimport-section__all__LIBexport)r5   dry_run)rr   r?   r@   rB   rS   r   boolrA   rC   lowerrk   rq   addr]   r^   rw   generate_global_funcsr   r   generate_objectgenerate_import_sectiongenerate_allgenerate_exportupdater5   r   )r;   r8   r:   r   defined_funcsr    ffi_load_lib_importedrH   r^   r   r   r   functype_keyobj_infor   export_namesr   r   r   r7      sp   

















r7   c               	   C  s~  G dd dt jt j} d/dd}t jd	d
tj tj tj d| d}|jdt	dddd |jdt	dddd |jdt	ddd |jdt	ddd |jdt	ddd |jdt
ddtj dd |jd d!d"d#d$ |jd%d&d'd( |jd)d&d*d( | }|j|j|jg}d }t|rt|s|d+ t|j|j|jd,}|js|  td- t||j||j||j|j|j|jd.S )0Nc                   @  s   e Zd ZdS )z"_parse_args.<locals>.HelpFormatterN)__name__
__module____qualname__r   r   r   r   HelpFormatter   s    r   arg
str | Noner   	list[str]c                 S  s   | sg S dd |  dD S )Nc                 S  s   g | ]
}|  r|  qS r   )rG   )r   itemr   r   r   r     s    z8_parse_args.<locals>._split_list_arg.<locals>.<listcomp>;)rD   )r   r   r   r   _split_list_arg  s   z$_parse_args.<locals>._split_list_argztvm-ffi-stubgena  Generate type stubs for TVM FFI extensions. It supports two modes
- In `--init-*` mode, it generates missing `_ffi_api.py` and `__init__.py` files, based on the registered global functions and object types in the loaded libraries.
- In normal mode, it processes the given files/directories in-place, generating type stubs inside special `tvm-ffi-stubgen` directive blocks.

Documentation: r\   )progdescriptionformatter_classz	--imports IMPORTSz\Additional imports to load before generation, separated by ';' (e.g. 'pkgA;pkgB.submodule').)typedefaultmetavarhelpz--dllsLIBSzShared libraries to preload before generation (e.g. TVM runtime or your extension), separated by ';'. This ensures global function and object metadata is available. Platform-specific suffixes like .so/.dylib/.dll are supported.z--init-pypkgzuPython package name to generate stubs for (e.g. apache-tvm-ffi). Required together with --init-lib and --init-prefix.)r   r   r   z
--init-libzCMake target that produces the shared library to load for stub generation (e.g. tvm_ffi_shared). Required together with --init-pypkg and --init-prefix.z--init-prefixzGlobal function/object prefix to include when generating stubs (e.g. tvm_ffi.). Required together with --init-pypkg and --init-lib.z--indent   zbExtra spaces added inside each generated block, relative to the indentation of the corresponding 'z' line.r$   *PATHzFiles or directories to process. Directories are scanned recursively; only .py and .pyi files are modified. Use tvm-ffi-stubgen directives to select where stubs are generated.)nargsr   r   z	--verbose
store_truezvPrint a unified diff of changes to each file. This is useful for debugging or previewing changes before applying them.)actionr   z	--dry-runz`Don't write changes to files. This is useful for previewing changes without modifying any files.zE--init-pypkg, --init-lib, and --init-prefix must be provided together)pkgshared_targetrj   r   )r    r#   r3   indentr$   r5   r   )r   r   r   r   )argparseArgumentDefaultsHelpFormatterRawTextHelpFormatterArgumentParserr(   r6   DOC_URLr2   add_argumentrC   r   
STUB_BEGIN
parse_args
init_pypkginit_libinit_prefixanyallerrorr   r$   
print_helpsysexitr   r    r#   r   r5   r   )r   r   parserargs
init_flagsr   r   r   r   r      s   

	
		


r   )r   r   )r;   r   r:   r=   r   r>   )r$   rL   r:   r=   r   r   r   r   r   rM   r   r>   )
r;   r   r8   r   r:   r=   r   rM   r   r>   )r   r   )#__doc__
__future__r   r   r   r!   r   r0   pathlibr   r   r   rw   r   r(   
file_utilsr   r	   	lib_stater
   r   r   r   utilsr   r   r   r   r<   r+   r4   r7   r   r   r   r   r   r   r   <module>   s,   

;

I
B 