Skip to content

Commit e07a12b

Browse files
test(extract): pin Go struct field extraction and blank-identifier skip
Reproduce-first probe for the two fixes on this branch: RED without the descend fix (count_defs_with_label(r, "Field") == 0, expected 3), GREEN with it. Asserts the three named fields with their declared types in return_type, the absence of the blank identifier, and that interface members keep extracting exactly as before. Signed-off-by: Ilya Brykau <ilya.brykau@orca.security>
1 parent cb7cb44 commit e07a12b

1 file changed

Lines changed: 54 additions & 0 deletions

File tree

‎tests/test_extraction.c‎

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3015,6 +3015,59 @@ TEST(go_imports) {
30153015
PASS();
30163016
}
30173017

3018+
/* #1935: Go struct fields were never extracted — find_class_body() returns the
3019+
* struct_type node, whose only named child is a field_declaration_list, so the
3020+
* member loop matched nothing and every field was silently skipped (0 Field
3021+
* nodes for ~5055 declarations on the measured repo). Interfaces hold their
3022+
* method specs directly and always worked. The blank identifier `_` is struct
3023+
* padding, not a referenceable field, and must stay out (241 collision edges
3024+
* on two generated structs otherwise). */
3025+
TEST(extract_go_struct_fields_have_nodes) {
3026+
CBMFileResult *r = extract("package fxf\n\n"
3027+
"type Config struct {\n"
3028+
"\tName string\n"
3029+
"\tTimeout int\n"
3030+
"\tNested *Config\n"
3031+
"\t_ [8]byte\n"
3032+
"}\n\n"
3033+
"type Reader interface {\n"
3034+
"\tRead(p []byte) (int, error)\n"
3035+
"\tClose() error\n"
3036+
"}\n",
3037+
CBM_LANG_GO, "t", "cfg.go");
3038+
ASSERT_NOT_NULL(r);
3039+
ASSERT_FALSE(r->has_error);
3040+
/* RED before the descend fix: count is 0. The blank identifier must not
3041+
* bring it to 4. */
3042+
ASSERT_EQ(count_defs_with_label(r, "Field"), 3);
3043+
ASSERT_TRUE(has_def(r, "Field", "Name"));
3044+
ASSERT_TRUE(has_def(r, "Field", "Timeout"));
3045+
ASSERT_TRUE(has_def(r, "Field", "Nested"));
3046+
ASSERT_FALSE(has_def(r, "Field", "_"));
3047+
/* Each field carries its declared type in return_type. */
3048+
for (int i = 0; i < r->defs.count; i++) {
3049+
const CBMDefinition *d = &r->defs.items[i];
3050+
if (!d->label || strcmp(d->label, "Field") != 0) {
3051+
continue;
3052+
}
3053+
ASSERT_NOT_NULL(d->return_type);
3054+
if (strcmp(d->name, "Name") == 0) {
3055+
ASSERT_TRUE(strcmp(d->return_type, "string") == 0);
3056+
}
3057+
if (strcmp(d->name, "Timeout") == 0) {
3058+
ASSERT_TRUE(strcmp(d->return_type, "int") == 0);
3059+
}
3060+
if (strcmp(d->name, "Nested") == 0) {
3061+
ASSERT_TRUE(strcmp(d->return_type, "*Config") == 0);
3062+
}
3063+
}
3064+
/* Interface members keep extracting exactly as before. */
3065+
ASSERT_TRUE(has_def(r, "Method", "Read"));
3066+
ASSERT_TRUE(has_def(r, "Method", "Close"));
3067+
cbm_free_result(r);
3068+
PASS();
3069+
}
3070+
30183071
TEST(java_imports) {
30193072
CBMFileResult *r = extract(
30203073
"import java.util.List;\nimport java.util.ArrayList;\nimport static java.lang.Math.PI;\n"
@@ -6699,6 +6752,7 @@ SUITE(extraction) {
66996752
RUN_TEST(python_imports);
67006753
RUN_TEST(js_imports);
67016754
RUN_TEST(go_imports);
6755+
RUN_TEST(extract_go_struct_fields_have_nodes);
67026756
RUN_TEST(java_imports);
67036757
RUN_TEST(rust_imports);
67046758
RUN_TEST(c_imports);

0 commit comments

Comments
 (0)