@@ -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+
30183071TEST (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