diff --git a/packages/vipeye-internal/package-lock.json b/packages/vipeye-internal/package-lock.json index 82058824..2f48c444 100644 --- a/packages/vipeye-internal/package-lock.json +++ b/packages/vipeye-internal/package-lock.json @@ -1,12 +1,12 @@ { "name": "vipeye-internal", - "version": "1.1.420", + "version": "1.1.421", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "vipeye-internal", - "version": "1.1.420", + "version": "1.1.421", "license": "MIT", "dependencies": { "@yarnpkg/fslib": "2.10.4", diff --git a/packages/vipeye-internal/package.json b/packages/vipeye-internal/package.json index 5e7d2279..27cf6a7a 100644 --- a/packages/vipeye-internal/package.json +++ b/packages/vipeye-internal/package.json @@ -2,7 +2,7 @@ "name": "vipeye-internal", "displayName": "vipeye", "description": "Type checker for the Viper language", - "version": "1.1.420", + "version": "1.1.421", "license": "MIT", "private": true, "files": [ diff --git a/packages/vipeye-internal/src/analyzer/typeEvaluator.ts b/packages/vipeye-internal/src/analyzer/typeEvaluator.ts index 525b8f43..4322824e 100644 --- a/packages/vipeye-internal/src/analyzer/typeEvaluator.ts +++ b/packages/vipeye-internal/src/analyzer/typeEvaluator.ts @@ -8412,17 +8412,9 @@ export function createTypeEvaluator( if (isClassInstance(concreteSubtype)) { // Viper TypeSet:str/bytes 在类型组合中表示 C 字符串指针(i8*), - // 下标访问 a[i] 应返回 t.CChar(int 别名),而非 str/bytes。 - if ( - isViperTypeSetIndex && - ClassType.isBuiltIn(concreteSubtype, ['str', 'bytes']) - ) { - // 构造带 CChar 别名信息的 int 类型(保留 t.CChar 显示信息) - const ccharType = getViperCCharType(node); - if (ccharType) { - return ccharType; - } - return concreteSubtype; + // 下标访问 a[i] 应返回 char(i8 字符),而非 str/bytes。 + if (isViperTypeSetIndex && ClassType.isBuiltIn(concreteSubtype, ['str', 'bytes'])) { + return getBuiltInObject(node, 'char'); } // Viper TypeSet:非修饰基本类型(int/float/bool 等)在类型组合中 // 表示指针指向的目标类型(如 CConst | int | CPtr = const int*), @@ -8435,20 +8427,16 @@ export function createTypeEvaluator( ) { return concreteSubtype; } - // Viper 扩展:str/bytes 表示 C 字符串指针(i8* / i8*)。 + // Viper 扩展:str/bytes 表示 C 字符串指针(i8*)。 // 无论读写,下标访问 a[i] 都是指针解引用操作(C 语义): - // - 读取 a[i] 返回 t.CChar(i8 字节),而非 Python str.__getitem__ 的 str + // - 读取 a[i] 返回 char(i8 字节),与解引用 `*a` 的结果类型一致, + // 而非 Python str.__getitem__ 的 str // - 赋值 a[i] = v 是合法的指针写字节操作,不报 __setitem__ 不存在 if ( IsViperDialect(viperIndexFileInfo.executionEnvironment.dialect) && ClassType.isBuiltIn(concreteSubtype, ['str', 'bytes']) ) { - // 构造带 CChar 别名信息的 int 类型作为下标访问的目标类型 - const ccharType = getViperCCharType(node); - if (ccharType) { - return ccharType; - } - return concreteSubtype; + return getBuiltInObject(node, 'char'); } const typeResult = getTypeOfIndexedObjectOrClass(node, concreteSubtype, selfType, usage); if (typeResult.isIncomplete) { diff --git a/packages/vipeye-internal/src/tests/viperUnaryPointer.test.ts b/packages/vipeye-internal/src/tests/viperUnaryPointer.test.ts index 7b7e5400..ae5bd82a 100644 --- a/packages/vipeye-internal/src/tests/viperUnaryPointer.test.ts +++ b/packages/vipeye-internal/src/tests/viperUnaryPointer.test.ts @@ -587,13 +587,10 @@ def test_str_arith(fmt: str) -> int: assert.strictEqual(op.type, 'str', `指针算术结果应为 str (L${line}),实际: ${op.type}`); } - // L7:fmt[0] → t.CChar(C 的 char 字节;与 `*fmt` 的 char 可隐式互转) + // L7:fmt[0] → char(与 `*fmt` 解引用统一为同一元素类型) const subscript = indexTypes.find((i) => i.line === 7); assert(subscript, `下标访问未找到 (L7)`); - assert( - subscript.type.includes('CChar'), - `fmt[0] 应为 t.CChar,实际: ${subscript.type}` - ); + assert.strictEqual(subscript.type, 'char', `fmt[0] 应为 char,实际: ${subscript.type}`); const diagnostics = getDiagnostics(program, configOptions, uri); console.log('=== 诊断 ==='); diagnostics.forEach((d) => console.log(` ${d}`)); diff --git a/packages/vipeye/package-lock.json b/packages/vipeye/package-lock.json index 62d20835..f0f65db4 100644 --- a/packages/vipeye/package-lock.json +++ b/packages/vipeye/package-lock.json @@ -1,12 +1,12 @@ { "name": "vipeye", - "version": "1.1.420", + "version": "1.1.421", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "vipeye", - "version": "1.1.420", + "version": "1.1.421", "license": "MIT", "bin": { "vipeye": "index.js", diff --git a/packages/vipeye/package.json b/packages/vipeye/package.json index da5631fd..c5b6b46a 100644 --- a/packages/vipeye/package.json +++ b/packages/vipeye/package.json @@ -2,7 +2,7 @@ "name": "vipeye", "displayName": "Vipeye", "description": "Type checker for the Viper language", - "version": "1.1.420", + "version": "1.1.421", "license": "MIT", "author": { "name": "TermiNexus" diff --git a/packages/vscode-vipeye/CHANGELOG.md b/packages/vscode-vipeye/CHANGELOG.md index 567ff97b..f2356282 100644 --- a/packages/vscode-vipeye/CHANGELOG.md +++ b/packages/vscode-vipeye/CHANGELOG.md @@ -1,8 +1,12 @@ # Change Log +## 1.1.421 + +- `s[i]` on `str` / `bytes` now yields `char` (`i8`) instead of `t.CChar`, matching the dereference result of `*s` (the two remain implicitly convertible). Covers both the plain subscript path and the type-set subscript path (e.g. `CConst | str | CPtr` style annotations); iteration (`for ch in s`) and `Iterable` argument inference still produce `t.CChar` + ## 1.1.420 -- Pointer semantics for `str` / `bytes` (both are C `char*`, `i8*`) now cover pointer arithmetic and writes, matching the dereference support added earlier: `p + n`, `p - n` and `n + p` return the pointer type instead of reporting `reportOperatorIssue`, and `*p = v` is accepted as an assignment target. `p[i]` already yielded `t.CChar` and is unchanged +- Pointer semantics for `str` / `bytes` (both are C `char*`, `i8*`) now cover pointer arithmetic and writes, matching the dereference support added earlier: `p + n`, `p - n` and `n + p` return the pointer type instead of reporting `reportOperatorIssue`, and `*p = v` is accepted as an assignment target. Subscript access `p[i]` was already supported - Built-in C basic type names extended with `short` (`t.CShort`), `ushort` (`t.CUnsignedShort`), `ulong` (`t.CUnsignedLong`) and `ulonglong` (`t.CUnsignedLongLong`), alongside the existing `long` / `longlong` ## 1.1.419 diff --git a/packages/vscode-vipeye/package-lock.json b/packages/vscode-vipeye/package-lock.json index 0083fecb..e4121e3f 100644 --- a/packages/vscode-vipeye/package-lock.json +++ b/packages/vscode-vipeye/package-lock.json @@ -1,12 +1,12 @@ { "name": "vscode-vipeye", - "version": "1.1.420", + "version": "1.1.421", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "vscode-vipeye", - "version": "1.1.420", + "version": "1.1.421", "license": "MIT", "dependencies": { "mermaid": "^11.12.0", diff --git a/packages/vscode-vipeye/package.json b/packages/vscode-vipeye/package.json index 2f727a11..477ad657 100644 --- a/packages/vscode-vipeye/package.json +++ b/packages/vscode-vipeye/package.json @@ -1,8 +1,8 @@ { - "name": "vscode-vipeye", + "name": "vipeye", "displayName": "Vipeye", "description": "VS Code language support for Viper (LSP client)", - "version": "1.1.420", + "version": "1.1.421", "private": true, "license": "MIT", "author": {