Skip to content

Commit d4afb9f

Browse files
committed
接通显式构造函数文档检查并避免虚构返回要求
1 parent b455217 commit d4afb9f

8 files changed

Lines changed: 86 additions & 20 deletions

File tree

‎crates/codeguard-adapters/src/clang_documentation_ast.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub fn parse_clang_documentation_ast(raw: &[u8], source: &[u8]) -> Result<Value,
2828
if node["isImplicit"] == true {
2929
continue;
3030
}
31-
let ordinary_method = kind == "CXXMethodDecl"
31+
let ordinary_method = matches!(kind, "CXXMethodDecl" | "CXXConstructorDecl")
3232
&& class_context
3333
&& node["name"].as_str().is_some_and(|name| {
3434
!name.is_empty()
@@ -46,7 +46,7 @@ pub fn parse_clang_documentation_ast(raw: &[u8], source: &[u8]) -> Result<Value,
4646
kind,
4747
"TranslationUnitDecl" | "NamespaceDecl" | "LinkageSpecDecl" | "CXXRecordDecl"
4848
) {
49-
// 类本身的契约仍未核验;只扩展有明确类上下文的普通方法。
49+
// 类本身的契约仍未核验;只扩展有明确类上下文的普通方法与显式构造函数。
5050
if kind == "CXXRecordDecl" {
5151
unresolved.insert(kind.to_owned());
5252
}

‎crates/codeguard-adapters/tests/clang_documentation_structure_contract.rs‎

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ fn actual_cpp17_ast_retains_method_descriptions_and_unsupported_contracts() {
7878
String::from_utf8_lossy(&version.stdout)
7979
.starts_with("Apple clang version 21.0.0 (clang-2100.3.34.2)")
8080
);
81-
let source = b"struct Box {\n/// Read a value.\n/// @param x Input value.\n/// @return The value.\nint read(int x);\n/// Clear the box.\nvoid clear();\nint undocumented();\nBox();\nint operator+(int x);\n};\n";
81+
let source = b"struct Box {\n/// Read a value.\n/// @param x Input value.\n/// @return The value.\nint read(int x);\n/// Clear the box.\nvoid clear();\nint undocumented();\n/// Create the box.\n/// @param size Initial size.\nBox(int size);\nint operator+(int x);\n};\n";
8282
let mut child = Command::new(&clang)
8383
.args([
8484
"-fsyntax-only",
@@ -108,8 +108,8 @@ fn actual_cpp17_ast_retains_method_descriptions_and_unsupported_contracts() {
108108
"{observed}"
109109
);
110110
let functions = observed["functions"].as_array().unwrap();
111-
assert_eq!(functions.len(), 3, "{observed}");
112-
for name in ["read", "clear"] {
111+
assert_eq!(functions.len(), 4, "{observed}");
112+
for name in ["read", "clear", "Box"] {
113113
let method = functions.iter().find(|m| m["name"] == name).unwrap();
114114
assert_eq!(method["missing_components"], json!([]));
115115
}
@@ -121,7 +121,7 @@ fn actual_cpp17_ast_retains_method_descriptions_and_unsupported_contracts() {
121121
undocumented["missing_components"],
122122
json!(["documentation_comment"])
123123
);
124-
for kind in ["CXXRecordDecl", "CXXConstructorDecl", "CXXMethodDecl"] {
124+
for kind in ["CXXRecordDecl", "CXXMethodDecl"] {
125125
assert!(
126126
observed["unresolved_declaration_kinds"]
127127
.as_array()
@@ -137,7 +137,7 @@ fn actual_cpp17_ast_retains_method_descriptions_and_unsupported_contracts() {
137137
assert!(path.is_absolute());
138138
let evidence = json!({
139139
"qualification":"not_granted",
140-
"scope":"cpp17_ordinary_in_class_methods_only",
140+
"scope":"cpp17_ordinary_in_class_methods_and_explicit_constructors",
141141
"source_sha256":format!("{:x}", Sha256::digest(source)),
142142
"test_source_sha256":format!("{:x}", Sha256::digest(include_bytes!("clang_documentation_structure_contract.rs"))),
143143
"compiler_version":String::from_utf8_lossy(&version.stdout).trim(),
@@ -148,3 +148,42 @@ fn actual_cpp17_ast_retains_method_descriptions_and_unsupported_contracts() {
148148
std::fs::write(path, serde_json::to_vec_pretty(&evidence).unwrap()).unwrap();
149149
}
150150
}
151+
152+
#[test]
153+
fn explicit_constructor_requires_parameters_but_never_invents_return_contract() {
154+
let source = b"struct Box { Box(int size); };";
155+
let offset = source.windows(3).rposition(|w| w == b"Box").unwrap();
156+
let constructor = json!({"kind":"CXXConstructorDecl","name":"Box","loc":{"offset":offset,"tokLen":3},"type":{"qualType":"void (int)"},"inner":[
157+
{"kind":"ParmVarDecl","name":"size"},
158+
{"kind":"FullComment","inner":[
159+
{"kind":"ParagraphComment","inner":[{"kind":"TextComment","text":"Create the box."}]},
160+
{"kind":"ParamCommandComment","param":"size","paramIdx":0,"inner":[{"kind":"ParagraphComment","inner":[{"kind":"TextComment","text":"Initial size."}]}]}
161+
]}
162+
]});
163+
let mut ast = json!({"kind":"TranslationUnitDecl","inner":[{"kind":"CXXRecordDecl","name":"Box","inner":[constructor.clone()]}]});
164+
let observed =
165+
parse_clang_documentation_ast(&serde_json::to_vec(&ast).unwrap(), source).unwrap();
166+
assert_eq!(observed["functions"].as_array().unwrap().len(), 1);
167+
assert_eq!(
168+
observed["functions"][0]["return_description"],
169+
"not_applicable"
170+
);
171+
assert_eq!(observed["functions"][0]["missing_components"], json!([]));
172+
assert!(valid_clang_documentation_structure(&observed, Some(source)));
173+
ast["inner"][0]["inner"][0]["inner"][1]["inner"][1]["inner"][0]["inner"][0]["text"] =
174+
json!(" ");
175+
let observed =
176+
parse_clang_documentation_ast(&serde_json::to_vec(&ast).unwrap(), source).unwrap();
177+
assert_eq!(
178+
observed["functions"][0]["missing_components"],
179+
json!(["parameter:size"])
180+
);
181+
let outside = json!({"kind":"TranslationUnitDecl","inner":[constructor]});
182+
let observed =
183+
parse_clang_documentation_ast(&serde_json::to_vec(&outside).unwrap(), source).unwrap();
184+
assert_eq!(observed["functions"], json!([]));
185+
assert_eq!(
186+
observed["unresolved_declaration_kinds"],
187+
json!(["CXXConstructorDecl"])
188+
);
189+
}

‎openspec/changes/introduce-rust-codeguard-cli/specs/native-tool-adapters/spec.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,3 +1240,11 @@ Clang documentation observation SHALL inspect non-implicit ordinary identifier-n
12401240
#### Scenario: Class member with missing documentation
12411241
- **WHEN** an explicit C++ class contains a directly located ordinary method without a documentation comment
12421242
- **THEN** the adapter SHALL retain its location and missing-comment observation while keeping class documentation unresolved and coverage unproven
1243+
1244+
### Requirement: Explicit in-class constructor documentation SHALL omit return obligations
1245+
1246+
The C++ adapter SHALL observe explicitly declared, identifier-named constructors within verified ordinary record traversal using frozen-source positions and actual parameter-comment binding. Constructor purpose and applicable parameter descriptions SHALL be checked structurally; no return description SHALL be required for Clang's void constructor type. Implicit constructors, out-of-class contexts, template-dependent names and unsupported contracts SHALL remain unqualified or unresolved.
1247+
1248+
#### Scenario: Constructor parameter description is empty
1249+
- **WHEN** an explicit in-class constructor has a purpose but an empty description for a named parameter
1250+
- **THEN** observation SHALL retain the missing parameter component, mark return description not_applicable, and SHALL NOT invent a return obligation or grant semantic qualification

‎openspec/changes/introduce-rust-codeguard-cli/tasks.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@
345345
- [ ] 8.26 实现 c 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。
346346
- [ ] 8.27 完成 c 的 dependencies/CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。
347347
- [ ] 8.28 为 cpp 固化六类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。
348-
- [ ] 8.29 实现 cpp 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 新增C++17局部原生/WASM对照:12例实际执行,包含2例语义边界;1测试通过、0忽略,未授予生产资格,见[验收记录](../../../tests/acceptance/cpp17-native-wasm-differential.md)。 编译数据库静态解析基础已补充:有界参数数组、原序多配置、命令字符串不执行及畸形/超限反例;2测试通过,已接到项目发现,记录双读稳定摘要与unknown配置;发现测试先失败后2项通过。尚未接到原生执行,不升级构建生态状态。 公开init定向4项默认/WASM均通过,补充六类参数上下文阻塞,涵盖静态摘要持久化、command-only阻塞及配置变化/删除时保留任务;见[初始化验收](../../../tests/acceptance/c-family-compilation-database-init.md)。 C++17类内普通方法已有实际Clang结构观察,类/构造/模板等仍未解析,见[局部验收](../../../tests/acceptance/cpp17-method-documentation.md)。
348+
- [ ] 8.29 实现 cpp 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。 新增C++17局部原生/WASM对照:12例实际执行,包含2例语义边界;1测试通过、0忽略,未授予生产资格,见[验收记录](../../../tests/acceptance/cpp17-native-wasm-differential.md)。 编译数据库静态解析基础已补充:有界参数数组、原序多配置、命令字符串不执行及畸形/超限反例;2测试通过,已接到项目发现,记录双读稳定摘要与unknown配置;发现测试先失败后2项通过。尚未接到原生执行,不升级构建生态状态。 公开init定向4项默认/WASM均通过,补充六类参数上下文阻塞,涵盖静态摘要持久化、command-only阻塞及配置变化/删除时保留任务;见[初始化验收](../../../tests/acceptance/c-family-compilation-database-init.md)。 C++17类内普通方法及显式构造已有实际Clang结构观察,构造不要求返回说明;类/析构/模板等仍未解析,见[局部验收](../../../tests/acceptance/cpp17-method-documentation.md)。
349349
- [ ] 8.30 完成 cpp 的 dependencies/CVE/security/build 适用能力及整体验收;验收:依赖生态映射和逐类别真实证据齐备,缺口未解决不升级 stable。
350350
- [ ] 8.31 为 objc 固化六类别适用性、候选工具/方言/版本及缺口;验收:每个槽位有实际依据,not_applicable 不得用缺工具解释。
351351
- [ ] 8.32 实现 objc 的 lint/comments 适配与规则;验收:真实工具正确样本和违规样本、错误配置/版本/报告反例通过,格式化不能冒充注释检查。

‎rulepacks/production_acceptance_plan_v1.json‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"crates/codeguard-adapters/src/cargo_documentation_config.rs": "2544cb061cd0f89cd888b6e5de933c88ad6efd6a160e81c5d5869023bb67e8b6",
1717
"crates/codeguard-adapters/src/cargo_documentation_workspace.rs": "0814890f213919c7a111ea520e26ced4110d6afa98b8583e1b99d79027aa6ebd",
1818
"crates/codeguard-adapters/src/cargo_workspace_reference.rs": "95f9ed06ac881ee17a124edca4ae3f6541690ef60aeabd0d1a6ffac0ede1cb02",
19-
"crates/codeguard-adapters/src/clang_documentation_ast.rs": "314133b87d470c0cb5ab0af08d8aa53f2fe123dbb3edb0910f4c9817fabc8eba",
19+
"crates/codeguard-adapters/src/clang_documentation_ast.rs": "5396c23863b2b89d954cc2191737920f79847d9e3113f7ee5a07312a627a91df",
2020
"crates/codeguard-adapters/src/clang_documentation_rule.rs": "4e7a99010c5a62fdd6812ce16068749863a5777df1103e304055ad8e3d8f834c",
2121
"crates/codeguard-adapters/src/clang_documentation_structure.rs": "368112aafedb8144d38cc05466586e7b3a21e6e937ceaade76133b9113fd005a",
2222
"crates/codeguard-adapters/src/gradle_dependency_check_plan.rs": "dfb85a3dfcf6c5e0697bb3eb58ecbd8f2d47feb71f60db506f765b0ee86b23f3",
@@ -25,7 +25,7 @@
2525
"crates/codeguard-adapters/src/ruff_settings.rs": "23736d55ef974a9f0b571d162365c6554001fa5ee3b2b69db6deb4507466af88",
2626
"crates/codeguard-adapters/tests/clang_documentation_ast_contract.rs": "3ed16ccb058ecfa147228ddb5dac768be2ce5d0f214324766324c09bb2a60ced",
2727
"crates/codeguard-adapters/tests/clang_documentation_contract.rs": "9d603b7ccb435c5e55837156e76d506573e8703aadf7017be07b6cf28281e261",
28-
"crates/codeguard-adapters/tests/clang_documentation_structure_contract.rs": "8b6a58a8a4d1c2a62bb1089c70466be0dc73c0715c205cbc0addc2ececd551f8",
28+
"crates/codeguard-adapters/tests/clang_documentation_structure_contract.rs": "d27769a0da59999d186cbe3b5a6c059e2a1269e00708c1f967c5f24f25367141",
2929
"crates/codeguard-adapters/tests/ruff_settings_contract.rs": "a34cd88caaf4d1d49688bcbc31d534ba21b5298f5e1a1c9bd59125ceda3e072a",
3030
"crates/codeguard-cli/src/c_family_comments_arguments.rs": "5de2e41865b78231ad1ac3aab9a61549e4a56c1b12e89801f23e83abdda01a3e",
3131
"crates/codeguard-cli/src/c_family_comments_command.rs": "e0a453ea25c547920b6d8f3c4b36ce346c8150c5e0ce510c32e4b24f21743fed",
@@ -177,7 +177,7 @@
177177
"tests/acceptance/clang-standalone-native.md": "155e64133bc4353cdbfe223c8e2c5bf1d2ab2c3e95c7c2e0232e9931988db017",
178178
"tests/acceptance/clippy-documentation-aggregate.md": "99f0b90dafda408b755f414277b55313c453771131038adada6295e572f15cc6",
179179
"tests/acceptance/clippy-documentation-contract.md": "7843e99c75b262710126c0c1b56596a0a004db563603b0575564e86416304060",
180-
"tests/acceptance/cpp17-method-documentation.md": "442a1de468a39bce576846284c860a6b71e33633a182f67d05330c4d4c485fc6",
180+
"tests/acceptance/cpp17-method-documentation.md": "46c26b5aef2c417e8af1d5c3e181780adcee86248d796bb9daa029c54a919a77",
181181
"tests/acceptance/cpp17-native-wasm-differential.md": "5177a5877bcba9d417c18d373a9431f86e95cfdea26d0f91a12241a5e8881f3e",
182182
"tests/acceptance/erlang-native-first-workbench.md": "3303eaec7903b193c5794901831b0b89fc0e6b6aae80086d60b0ef8b75b9d4d1",
183183
"tests/acceptance/eslint-directory-feedback.md": "8aa71fcd3bb1b7b5dde384b14e883cbc8190546e07e86c63d8d936ebfa42a05b",
@@ -221,7 +221,7 @@
221221
"tests/acceptance/evidence/clang-documentation-structure-native-wasm.json": "aafb2ce8b949800819a8ca38e37d911bfcc5365ca754a045abc8b34184211f20",
222222
"tests/acceptance/evidence/clang-documentation-structure-native.json": "9749be2e060aed4c529cab0f61444a89a34e3c0365938c7df0cd5845272218cf",
223223
"tests/acceptance/evidence/clang-documentation-structure-schema.json": "1c522b5fef58da2d81d556242d0c6f2d707e2e3e67dc4abde5ba3a214dbfea8a",
224-
"tests/acceptance/evidence/cpp17-method-documentation.json": "6a68ee5f0926ae2390a9b6a1eec1158a6598db3232780746b9dd4c9911bc7095",
224+
"tests/acceptance/evidence/cpp17-method-documentation.json": "5b8e03941cdae4e4c6d944097e979d6aa5bff95836cff8bd284bbdec6f216554",
225225
"tests/acceptance/evidence/cpp17-native-wasm-differential.json": "b0faaeca50331a007993217a685d65e7d2aa5468a60e95a171c5f0a60f2d8d99",
226226
"tests/acceptance/evidence/java-native-tool-source-inventory-2026-10-07.json": "b9d8e2bf5f16ccd370a699d9d4b177b1b108c55c85b981b7f9a42eeef7ce6cec",
227227
"tests/acceptance/evidence/python-comments-native-boundaries-wasm.json": "2bfd032700f6eea01e6d6598aba43bdb69d38f2053c034b6a76367b68afda342",
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# C++17 类内普通方法文档局部验收
22

3-
对应introduce-rust-codeguard-cli的8.29、15.3。新增类内普通标识符方法的函数文档结构观察,沿用冻结源码定位、用途/参数/内置返回类型检查。类契约、构造函数、运算符、模板、类外方法仍未解析;语义准确性、错误/行为均未评估,不授予生产资格。
3+
对应introduce-rust-codeguard-cli的8.29、15.3。新增类内普通标识符方法的函数文档结构观察,沿用冻结源码定位、用途/参数/内置返回类型检查。类契约、析构函数、运算符、模板、类外方法仍未解析;语义准确性、错误/行为均未评估,不授予生产资格。
44

5-
新增合约测试先因未提取类方法失败;实现后AST回归6项、结构合约含真实Clang3项通过。最终Apple Clang21使用C++17 stdin实际生成AST,3通过、0忽略;read/clear无缺失组件,undocumented缺少注释,类/构造函数/运算符保留unresolved。
5+
新增合约测试先因未提取类方法失败;前一普通方法检查点AST回归6项、结构合约含真实Clang3项通过。该检查点Apple Clang21使用C++17 stdin实际生成AST,3通过、0忽略;read/clear无缺失组件,undocumented缺少注释,类/构造函数/运算符保留unresolved。
66

77
[机器证据](evidence/cpp17-method-documentation.json)仅在全部断言通过后写出,绑定源码、测试、编译器及实际AST摘要,保存脱敏结构观察。本轮未验收智能体宿主、完整项目配置、独立精度或任务关闭。
8+
9+
当前显式构造函数增量:新测试先失败后通过,空参数描述产生parameter:size而不产生return;类外构造上下文仍未解析。真实Clang样例包含有用途及参数说明的Box(int size),read/clear/Box三者无缺失组件,undocumented缺少注释,类/运算符仍未解析。最终AST6项、结构合约含真实工具4项实际通过、0忽略;同名机器证据已更新为本次输入、测试及AST摘要,历史记录可从b455217读取。

‎tests/acceptance/evidence/cpp17-method-documentation.json‎

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"compiler_sha256": "34129c71a01a74f7f3b2443521519b2e5447553fa187f5fcafaaf8c42cc192e2",
33
"compiler_version": "Apple clang version 21.0.0 (clang-2100.3.34.2)\nTarget: arm64-apple-darwin27.0.0\nThread model: posix\nInstalledDir: /Library/Developer/CommandLineTools/usr/bin",
4-
"native_ast_sha256": "bb780891570bdbc66c2b83ff0c4947455c4ef0772ea59fb43ce213d8d7066efb",
4+
"native_ast_sha256": "59a3867d4c2532316ebdb7534779653c18fcb58fe36c874d8b3276f17087ca3a",
55
"observation": {
66
"authority": "local_unverified",
77
"coverage_proven": false,
@@ -50,20 +50,37 @@
5050
"purpose_description": "unknown",
5151
"return_description": "unknown",
5252
"structure_status": "observed_supported_subset"
53+
},
54+
{
55+
"column_byte": 1,
56+
"comment_presence": "present",
57+
"line": 11,
58+
"missing_components": [],
59+
"name": "Box",
60+
"offset_byte": 200,
61+
"parameters": [
62+
{
63+
"description": "nonempty",
64+
"index": 0,
65+
"name": "size"
66+
}
67+
],
68+
"purpose_description": "nonempty",
69+
"return_description": "not_applicable",
70+
"structure_status": "observed_supported_subset"
5371
}
5472
],
5573
"observation_type": "clang_function_documentation_structure",
5674
"qualification": "not_granted",
5775
"schema_version": "0.1.0",
5876
"semantic_accuracy": "not_evaluated",
5977
"unresolved_declaration_kinds": [
60-
"CXXConstructorDecl",
6178
"CXXMethodDecl",
6279
"CXXRecordDecl"
6380
]
6481
},
6582
"qualification": "not_granted",
66-
"scope": "cpp17_ordinary_in_class_methods_only",
67-
"source_sha256": "a8d5b93ced2efa3bcbdf6ae647df192652dd1a8daf2059b3410ce5140534a556",
68-
"test_source_sha256": "8b6a58a8a4d1c2a62bb1089c70466be0dc73c0715c205cbc0addc2ececd551f8"
83+
"scope": "cpp17_ordinary_in_class_methods_and_explicit_constructors",
84+
"source_sha256": "6049fae8aec9786b36e75a684c195db4b55155fe2281ad8e6bd0b1504a76b13c",
85+
"test_source_sha256": "d27769a0da59999d186cbe3b5a6c059e2a1269e00708c1f967c5f24f25367141"
6986
}

‎tests/acceptance/evidence/production-acceptance-plan/all.json‎

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)