# -*- coding: utf-8 -*- """扫描 TPV .vp 文件:找出"跨模块前缀引用但未 import"的模块(识别 as 别名)。 用法: python _check_imports.py """ import os import re ROOT = r"d:\Users\TermiNexus\Desktop\TransPyC\TransPyV\App\lib\core" DIRS = [os.path.join(ROOT, "Gen"), os.path.join(ROOT, "Handles")] # 忽略列表:基础库/枚举成员/llvmlite 属性/类名(大写开头且非模块) IGNORE = { "ast", "t", "c", "stdint", "stdio", "string", "stdlib", "memhub", "llvmlite", "viperlib", "sys", "math", "time", "hashlib", "vthreading", "subprocess", "argparse", "w32", "fileio", "win32", "win32console", "win32file", "win32base", "win32process", "win32sync", "win32thread", "win32time", "win32heap", "win32job", "win32namedpipe", "win32registry", "win32security", "win32service", "win32socket", "win32handle", "win32pipe", "win32io", "ASTKind", "ASTCtx", "OpKind", "CONST_NONE", "CONST_INT", "CONST_FLOAT", "CONST_STR", "CONST_BOOL", "MODE", "ASM_DESCR", "Alloca", "Subscript", "DefaultVal", "Arguments", "GenericClassFiles", "GenericClassNames", "GenericClassNodes", "GenericClassSha1s", "GenericTpNames", "GenericTypeArgs", "CDefineNames", "CDefineValues", "CDefineDoubleFlags", "CDefineStrFlags", "XmodCdefNames", "XmodCdefValues", "XmodCdefDoubleFlags", "XmodCdefStrFlags", "CTypedefNames", "CTypedefTypeStrs", "CTypedefVisiting", "VisibleStructs", "Node", "Pool", "T", "Current", "Scope", "Constant", "List", "Int", "Struct", "LocalClass", "RemoteClass", "Trans", "ExprHandle", "Type", "Value", "Function", "BasicBlock", "Param", "ParamNode", "GlobalVariable", "LLVMType", "IRBuilder", "LLVMModule", "MemBuddy", "Translator", "Generator", "Logger", "File", "SymbolTable", "VarEntry", "StructEntry", "FieldEntry", "EnumEntry", "EnumMember", "AsmOperand", "FuncEntry", "FuncDefaultsEntry", "TraceFrame", "Mixin", "TypeKind", "TypeInfo", "TypeRegistry", "Config", "Exporter", "Module", "State", "Default", "Utf8", "Case", "Error", "Handle", } # Gen Mixin 自引用(同包内类名) GEN_MIXINS = { "Generator", "BaseGenMixin", "TypeGenMixin", "TypeGenBase", "TypeGenCDef", "TypeGenCType", "TypeGenResolve", "TypeGenErr", "StructGenMixin", "ExprGenMixin", "ExprGenBase", "ExprGenConst", "ExprGenFstr", "ExprGenOps", "ExprGenCdef", "ExprGenName", "ExprGenAttr", "ExprGenCls", "CallGenMixin", "CallGenBase", "CallGenLeafKit", "CallGenCBuiltin", "CallGenCtor", "CallGenCall", "CallGenProp", "CallGenFd", "CallGenVt", "CallGenVa", "CallGenLib", "CallGenDispatch", "FuncGenBase", "FuncGenDef", "FuncGenMixin", "ClassGenMixin", "ClassGenBase", "ClassGenEnum", "ClassGenGeneric", "ClassGenVTable", "ClassGenDef", "ImportsGenMixin", "StmtGenMixin", "StmtGenDeclMixin", "StmtGenCifMixin", "AssignGenMixin", "VarGenMixin", "TranslatorGenMixin", "MatchGenMixin", "GenGenerator", } # 单字母/短名枚举等 SHORT = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "T", "U", "V", "W", "X", "Y", "Z", "N", "M", "I", "J", "K", "L", "O", "P", "Q", "R", "S", "A", "B", "C", "D", "E", "F", "G", "H"} def collect(): result = {} pat_import = re.compile(r'^\s*(?:import|from)\s+([\w\.]+)(?:\s+as\s+(\w+))?') pat_ref = re.compile(r'\b([A-Z][A-Za-z0-9_]*)\s*\.') for d in DIRS: for fn in sorted(os.listdir(d)): if not fn.endswith(".vp"): continue fp = os.path.join(d, fn) with open(fp, encoding="utf-8", errors="replace") as f: lines = f.readlines() imports = set() refs = set() for ln in lines: s = ln.strip() if s.startswith("#"): continue m = pat_import.match(s) if m: mod = m.group(1) alias = m.group(2) short = mod.split(".")[-1] if alias: imports.add(alias) imports.add(short) imports.add(mod) continue for rm in pat_ref.finditer(ln): refs.add(rm.group(1)) result[fp] = (imports, refs) return result def main(): files = collect() print("=== 使用但未 import(已去误报) ===") any_hit = False for fp, (imports, refs) in files.items(): missing = [] for r in sorted(refs): if r in IGNORE or r in GEN_MIXINS or r in SHORT: continue if r in imports: continue missing.append(r) if missing: any_hit = True print(f"\n{os.path.relpath(fp, ROOT)}") for m in missing: print(f" MISSING: {m}") if not any_hit: print("(无)") print("\n=== 完成 ===") if __name__ == "__main__": main()