fix(vipeye-internal): C 整型 typedef 内建到 builtins.vpi,修复 uint32 报未定义
Validation / Typecheck (push) Has been cancelled
Validation / Style (push) Has been cancelled
Validation / Test macos-latest (push) Has been cancelled
Validation / Test ubuntu-latest (push) Has been cancelled
Validation / Test windows-latest (push) Has been cancelled
Validation / Build (push) Has been cancelled
Validation / Required (push) Has been cancelled

TransPyC 的 includes/builtins.vp 提供 sizet/size_t/uzt/int8..uint64 以及
intfast*/uintfast*/intleast*/uintleast* 等 typedef。LSP 侧原先只靠 program.ts
的 _mergeViperBuiltinsVpSymbols 定位并合并该文件,而查找依赖工作区根与打开的
文件集合,在 Trae 等环境下找不到时这些注解会集体报"未定义"(同一工程在不同
编辑器/不同打开顺序下表现不一致)。

现把等价声明内建进 typeshed-fallback/stdlib/builtins.vpi:任意 Viper 工程无需
配置 includes 即可解析;工程自带 builtins.vp 时仍以工程声明为准(合并逻辑覆盖
同名符号,行为不变)。

新增回归用例:无 includes/builtins.vp 的工程可解析 uint32/sizet/int8/uint64
并得到 CUInt32T/CSizeT/CInt8T/CUInt64T。版本号提升至 1.1.417 并更新 CHANGELOG。
This commit is contained in:
TermiNexus committed 2026-09-22 19:30:55 +08:00
1 parent de2d49cc4a
commit f547737cf0
9 files changed
+131 -10

No files matched your search

+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "vipeye-internal",
"version": "1.1.416",
"version": "1.1.417",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "vipeye-internal",
"version": "1.1.416",
"version": "1.1.417",
"license": "MIT",
"dependencies": {
"@yarnpkg/fslib": "2.10.4",
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "vipeye-internal",
"displayName": "vipeye",
"description": "Type checker for the Viper language",
"version": "1.1.416",
"version": "1.1.417",
"license": "MIT",
"private": true,
"files": [
@@ -291,3 +291,81 @@ def f() -> int:
serviceProvider.dispose();
require('fs').rmSync(path.join(__dirname, '__builtins_vp_typedef__'), { recursive: true, force: true });
});
// 回归:完全不依赖工程 includes/builtins.vp —— C 定宽/最快/最小整型 typedef 已内建到
// typeshed-fallback/stdlib/builtins.vpi。用于修"uint32 报未定义"在找回 builtins.vp
// 失败的工程(如 Trae 中打开的文件集合/工作区根不同)里依然复现的问题。
test('无 includes/builtins.vp 时,内建 builtins.vpi 提供 uint32/sizet/int8', () => {
const tempFile = new RealTempFile();
const serviceProvider = createServiceProvider(
createFromRealFileSystem(tempFile),
new NullConsole(),
tempFile
);
const fs = require('fs');
const testRoot = path.join(__dirname, '__builtins_vpi_only__');
fs.rmSync(testRoot, { recursive: true, force: true });
fs.mkdirSync(testRoot, { recursive: true });
const filePath = path.join(testRoot, 'main.vp');
// 该目录没有 includes/,也没有 extraPaths,builtins.vp 必然找不到。
fs.writeFileSync(
filePath,
`import t
def f(a: uint32, b: sizet, c: int8, d: uint64) -> uint32:
return a
`,
'utf8'
);
const projectRoot = UriEx.file(testRoot);
const configOptions = new ConfigOptions(projectRoot);
configOptions.internalTestMode = true;
configOptions.initializeTypeCheckingMode('standard');
configOptions.executionEnvironments = [
new ExecutionEnvironment(
'python',
projectRoot,
configOptions.diagnosticRuleSet,
configOptions.defaultPythonVersion,
configOptions.defaultPythonPlatform,
[],
/* skipNativeLibraries */ false,
/* defaultDialect */ 'viper'
),
];
const importResolver = new ImportResolver(serviceProvider, configOptions, new FullAccessHost(serviceProvider));
const program = new Program(importResolver, configOptions, serviceProvider);
const uri = UriEx.file(filePath);
program.setTrackedFiles([uri]);
while (program.analyze()) {
// 循环
}
const diagnostics = (program.getSourceFile(uri)?.getDiagnostics(configOptions) || []).map(
(d) => `[category=${d.category}] ${d.message}`
);
const undefinedDiags = diagnostics.filter((d) => d.includes('未定义') || d.includes('undefined'));
assert.strictEqual(
undefinedDiags.length,
0,
`内建 builtins.vpi 应提供 uint32/sizet/int8/uint64,实际: ${JSON.stringify(diagnostics)}`
);
// 注解类型:uint32 → CUInt32T,sizet → CSizeT,int8 → CInt8T,uint64 → CUInt64T
const parseResults = program.getSourceFile(uri)!.getParseResults();
const types = collectParamAnnotationTypes(program, parseResults!);
const fTypes = types.get('f') ?? [];
for (const expected of ['CUInt32T', 'CSizeT', 'CInt8T', 'CUInt64T']) {
assert(
fTypes.some((t) => t.includes(expected)),
`f() 参数注解应包含 ${expected},实际: ${JSON.stringify(fTypes)}`
);
}
program.dispose();
serviceProvider.dispose();
fs.rmSync(testRoot, { recursive: true, force: true });
});
@@ -2741,4 +2741,42 @@ def LOut(expr: Any, constraint: Any = None) -> Any:
# 声明在 builtins stub 中使 LSP 对任意 Viper 工程均可解析 rawptr,不依赖
# 项目 includes/builtins.vp 是否声明;编译器侧解析 rawptr 时优先走内置
# 路径并忽略本声明(见 TransPyC TypeAnnotationResolver / SymbolExtractor)。
rawptr: t.CTypedef = t.CPtr
rawptr: t.CTypedef = t.CPtr
# --- Viper 扩展:C 定宽/最快/最小整型 typedef(镜像 TransPyC includes/builtins.vp) ---
# 这些 typedef 由编译器内置的 includes/builtins.vp 提供。LSP 侧原先只靠
# program.ts 的 _mergeViperBuiltinsVpSymbols 在"被分析文件所在目录及其祖先目录的
# includes/ + 执行环境(root/extraPaths)"里找到该文件后合并符号,查找结果依赖
# 工作区根与打开的文件集合,某些环境下找不到文件时 uint32/int8/sizet 等会集体报
# "未定义"(同一工程在不同编辑器里表现不一致)。
# 因此在 builtins stub 中内建一份等价声明:任意 Viper 工程无需配置 includes 即可
# 解析;工程自带 builtins.vp 时仍以工程声明为准(合并逻辑会覆盖同名符号)。
sizet: t.CTypedef = t.CSizeT
size_t: t.CTypedef = sizet
uzt: t.CTypedef = sizet
int8: t.CTypedef = t.CInt8T
int16: t.CTypedef = t.CInt16T
int32: t.CTypedef = t.CInt32T
int64: t.CTypedef = t.CInt64T
uint8: t.CTypedef = t.CUInt8T
uint16: t.CTypedef = t.CUInt16T
uint32: t.CTypedef = t.CUInt32T
uint64: t.CTypedef = t.CUInt64T
intfast8: t.CTypedef = t.CIntFast8T
intfast16: t.CTypedef = t.CIntFast16T
intfast32: t.CTypedef = t.CIntFast32T
intfast64: t.CTypedef = t.CIntFast64T
uintfast8: t.CTypedef = t.CUIntFast8T
uintfast16: t.CTypedef = t.CUIntFast16T
uintfast32: t.CTypedef = t.CUIntFast32T
uintfast64: t.CTypedef = t.CUIntFast64T
intleast8: t.CTypedef = t.CIntLeast8T
intleast16: t.CTypedef = t.CIntLeast16T
intleast32: t.CTypedef = t.CIntLeast32T
intleast64: t.CTypedef = t.CIntLeast64T
uintleast8: t.CTypedef = t.CUIntLeast8T
uintleast16: t.CTypedef = t.CUIntLeast16T
uintleast32: t.CTypedef = t.CUIntLeast32T
uintleast64: t.CTypedef = t.CUIntLeast64T
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "vipeye",
"version": "1.1.416",
"version": "1.1.417",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "vipeye",
"version": "1.1.416",
"version": "1.1.417",
"license": "MIT",
"bin": {
"vipeye": "index.js",
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "vipeye",
"displayName": "Vipeye",
"description": "Type checker for the Viper language",
"version": "1.1.416",
"version": "1.1.417",
"license": "MIT",
"author": {
"name": "TermiNexus"
+5
View File
@@ -1,5 +1,10 @@
# Change Log
## 1.1.417
- **Built-in C integer typedefs**: `sizet`, `size_t`, `uzt`, `int8`–`uint64`, `intfast*`/`uintfast*`, `intleast*`/`uintleast*` are now declared in the built-in `builtins.vpi` stub, mirroring the compiler's `includes/builtins.vp`. Any Viper project resolves them without configuring `includes`, which fixes `uint32` (and the rest) being reported as undefined in setups where the project-level `builtins.vp` cannot be located — that lookup depends on the workspace root and the set of opened files, so the same project could behave differently across editors
- When a project ships its own `includes/builtins.vp`, its declarations still win: the merge overwrites same-named built-in symbols
## 1.1.416
- **New command `Viper: Cleanup and Deactivate`**: stops the language server of the current window (terminating the server process), disposes every resource the extension registered (commands, sidebar views, status bar, file watchers, flow chart panel), and optionally purges the global semantic highlighting cache (`~/.vipeye/cache/semantic-tokens`). Run it in every window before uninstalling or updating the extension — a running server keeps its working directory inside the extension folder (undeletable on Windows) and the home-directory cache is shared across windows, so otherwise uninstall leaves a half-deleted extension and other windows keep showing stale results even after restarting the extension host. Reload the window to bring Viper back
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "vscode-vipeye",
"version": "1.1.416",
"version": "1.1.417",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "vscode-vipeye",
"version": "1.1.416",
"version": "1.1.417",
"license": "MIT",
"dependencies": {
"mermaid": "^11.12.0",
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "vscode-vipeye",
"displayName": "Vipeye",
"description": "VS Code language support for Viper (LSP client)",
"version": "1.1.416",
"version": "1.1.417",
"private": true,
"license": "MIT",
"author": {