[ffigen] Check that property types aren't incomplete (#415)

* Skip methods that have incomplete types

Also change how method return types are parsed

* Fix overly generic method return types

* Fix tests

* Bit field test

* Fix the bug

* Fix warning wording
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart
index f2e4fc9..3c8aab3 100644
--- a/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart
@@ -137,6 +137,13 @@
   final itf = _interfaceStack.top.interface;
   final fieldName = cursor.spelling();
   final fieldType = cursor.type().toCodeGenType();
+
+  if (fieldType.isIncompleteCompound) {
+    _logger.warning('Property "$fieldName" in instance "${itf.originalName}" '
+        'has incomplete type: $fieldType.');
+    return;
+  }
+
   final dartDoc = getCursorDocComment(cursor);
 
   final propertyAttributes =
diff --git a/pkgs/ffigen/test/native_objc_test/bad_method_test.dart b/pkgs/ffigen/test/native_objc_test/bad_method_test.dart
index 625cc2b..3b87c5b 100644
--- a/pkgs/ffigen/test/native_objc_test/bad_method_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/bad_method_test.dart
@@ -24,11 +24,18 @@
       generateBindingsForCoverage('bad_method');
     });
 
-    test("Test methods that weren't skipped", () {
+    test("Test incomplete struct methods that weren't skipped", () {
       final obj = BadMethodTestObject.new1(lib);
       final structPtr = obj.incompletePointerReturn();
       expect(structPtr.address, 1234);
       expect(obj.incompletePointerParam_(structPtr), 1234);
     });
+
+    test("Test bit field methods that weren't skipped", () {
+      final obj = BadMethodTestObject.new1(lib);
+      final bitFieldPtr = obj.bitFieldPointerReturn();
+      expect(bitFieldPtr.address, 5678);
+      expect(obj.bitFieldPointerParam_(bitFieldPtr), 5678);
+    });
   });
 }
diff --git a/pkgs/ffigen/test/native_objc_test/bad_method_test.m b/pkgs/ffigen/test/native_objc_test/bad_method_test.m
index 132daf8..bef4ede 100644
--- a/pkgs/ffigen/test/native_objc_test/bad_method_test.m
+++ b/pkgs/ffigen/test/native_objc_test/bad_method_test.m
@@ -6,6 +6,11 @@
 
 struct IncompleteStruct;
 
+struct BitField {
+  int x:3;
+  int y:12;
+};
+
 @interface BadMethodTestObject : NSObject {
 }
 
@@ -14,6 +19,13 @@
 - (int64_t)incompleteParam:(struct IncompleteStruct)x;  // Skipped.
 - (int64_t)incompletePointerParam:(struct IncompleteStruct*)x;  // Not skipped.
 
+- (struct BitField)bitFieldReturn;  // Skipped.
+- (struct BitField*)bitFieldPointerReturn;  // Not skipped.
+- (int64_t)bitFieldParam:(struct BitField)x;  // Skipped.
+- (int64_t)bitFieldPointerParam:(struct BitField*)x;  // Not skipped.
+
+@property struct BitField bitFieldProperty;  // Skipped.
+
 @end
 
 @implementation BadMethodTestObject
@@ -26,4 +38,12 @@
   return (int64_t)x;
 }
 
+- (struct BitField*)bitFieldPointerReturn {
+  return (struct BitField*)5678;
+}
+
+- (int64_t)bitFieldPointerParam:(struct BitField*)x {
+  return (int64_t)x;
+}
+
 @end