[ffigen] Test autorelease pools and more copying cases (#385)

diff --git a/pkgs/ffigen/test/native_objc_test/automated_ref_count_config.yaml b/pkgs/ffigen/test/native_objc_test/automated_ref_count_config.yaml
index b925491..bc4982e 100644
--- a/pkgs/ffigen/test/native_objc_test/automated_ref_count_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/automated_ref_count_config.yaml
@@ -3,8 +3,9 @@
 language: objc
 output: 'test/native_objc_test/automated_ref_count_bindings.dart'
 functions:
-  exclude:
-    - '.*'
+  include:
+    - createAutoreleasePool
+    - destroyAutoreleasePool
 headers:
   entry-points:
     - 'test/native_objc_test/automated_ref_count_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.dart b/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.dart
index 74c1270..74302f9 100644
--- a/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.dart
@@ -86,6 +86,10 @@
       expect(counter.value, 2);
       final obj3 = obj1.makeACopy();
       expect(counter.value, 3);
+      final obj4 = obj1.copyWithZone_(nullptr);
+      expect(counter.value, 4);
+      final obj5 = obj1.copy();
+      expect(counter.value, 5);
     }
 
     test('copy methods ref count correctly', () {
@@ -97,6 +101,37 @@
       calloc.free(counter);
     });
 
+    autoreleaseMethodsInner(Pointer<Int32> counter) {
+      final obj = ArcTestObject.makeAndAutorelease_(lib, counter);
+      expect(counter.value, 1);
+    }
+
+    test('autorelease methods ref count correctly', () {
+      final counter = calloc<Int32>();
+      counter.value = 0;
+
+      final pool1 = lib.createAutoreleasePool();
+      autoreleaseMethodsInner(counter);
+      doGC();
+      // The autorelease pool is still holding a reference to the object.
+      expect(counter.value, 1);
+      lib.destroyAutoreleasePool(pool1);
+      expect(counter.value, 0);
+
+      final pool2 = lib.createAutoreleasePool();
+      final obj = ArcTestObject.makeAndAutorelease_(lib, counter);
+      expect(counter.value, 1);
+      doGC();
+      expect(counter.value, 1);
+      lib.destroyAutoreleasePool(pool2);
+      // The obj variable still holds a reference to the object.
+      expect(counter.value, 1);
+      obj.release();
+      expect(counter.value, 0);
+
+      calloc.free(counter);
+    });
+
     castFromPointerInnerReleaseAndRetain(int address) {
       final fromCast = RefCounted.castFromPointer(
           lib, Pointer<ObjCObject>.fromAddress(address),
diff --git a/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.m b/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.m
index 78e5a6b..f4a4fc9 100644
--- a/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.m
+++ b/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.m
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #import <Foundation/NSObject.h>
+#import <Foundation/NSAutoreleasePool.h>
 
 @interface ArcTestObject : NSObject {
   int32_t* counter;
@@ -11,11 +12,13 @@
 + (instancetype)allocTheThing;
 + (instancetype)newWithCounter:(int32_t*) _counter;
 - (instancetype)initWithCounter:(int32_t*) _counter;
++ (ArcTestObject*)makeAndAutorelease:(int32_t*) _counter;
 - (void)setCounter:(int32_t*) _counter;
 - (void)dealloc;
 - (ArcTestObject*)unownedReference;
 - (ArcTestObject*)copyMe;
 - (ArcTestObject*)makeACopy;
+- (id)copyWithZone:(NSZone*) zone;
 - (ArcTestObject*)returnsRetained NS_RETURNS_RETAINED;
 
 @end
@@ -44,6 +47,10 @@
   return [super init];
 }
 
++ (instancetype)makeAndAutorelease:(int32_t*) _counter {
+  return [[[ArcTestObject alloc] initWithCounter: _counter] autorelease];
+}
+
 - (void)setCounter:(int32_t*) _counter {
   counter = _counter;
   ++*counter;
@@ -66,12 +73,24 @@
   return [[ArcTestObject alloc] initWithCounter: counter];
 }
 
+- (id)copyWithZone:(NSZone*) zone {
+  return [[ArcTestObject alloc] initWithCounter: counter];
+}
+
 - (ArcTestObject*)returnsRetained NS_RETURNS_RETAINED {
   return [self retain];
 }
 
 @end
 
+id createAutoreleasePool() {
+  return [NSAutoreleasePool new];
+}
+
+void destroyAutoreleasePool(id pool) {
+  [pool release];
+}
+
 @implementation RefCounted
 
 - (instancetype)init {
@@ -97,4 +116,4 @@
   return (int64_t) self;
 }
 
-@end
\ No newline at end of file
+@end