//===--- FoundationBridge.m -----------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// #import "FoundationBridge.h" #import @implementation ObjectBehaviorVerifier { NSMutableArray *_actions; } - (instancetype)init { self = [super init]; if (self) { _actions = [[NSMutableArray alloc] init]; } return self; } - (void)dealloc { [_actions release]; [super dealloc]; } - (void)appendAction:(ObjectBehaviorAction)action { [_actions addObject:@(action)]; switch (action) { case ObjectBehaviorActionRetain: _wasRetained = YES; break; case ObjectBehaviorActionMutableCopy: _wasMutableCopied = YES; // fall through case ObjectBehaviorActionCopy: _wasCopied = YES; break; } } - (void)enumerate:(void (^)(ObjectBehaviorAction))block { for (NSNumber *action in _actions) { block((ObjectBehaviorAction)action.integerValue); } } - (void)reset { [_actions removeAllObjects]; _wasRetained = NO; _wasMutableCopied = NO; _wasCopied = NO; } - (void)dump { [self enumerate:^(ObjectBehaviorAction action) { switch (action) { case ObjectBehaviorActionRetain: printf("retain\n"); break; case ObjectBehaviorActionMutableCopy: printf("mutableCopy\n"); break; case ObjectBehaviorActionCopy: printf("copy\n"); break; } }]; } @end @implementation ImmutableDataVerifier - (instancetype)init { self = [super init]; if (self) { _verifier = [[ObjectBehaviorVerifier alloc] init]; char *bytes = "hello world"; _data = [[NSData alloc] initWithBytes:bytes length:strlen(bytes)]; } return self; } - (instancetype)initWithData:(NSData *)data verifier:(ObjectBehaviorVerifier *)verifier { self = [super init]; if (self) { _verifier = [verifier retain]; _data = [data mutableCopyWithZone:nil]; } return self; } - (void)dealloc { [_verifier release]; [_data release]; [super dealloc]; } - (id)retain { [_verifier appendAction:ObjectBehaviorActionRetain]; return [super retain]; } - (id)copyWithZone:(NSZone *)zone { [_verifier appendAction:ObjectBehaviorActionCopy]; return [super retain]; } - (id)mutableCopyWithZone:(NSZone *)zone { [_verifier appendAction:ObjectBehaviorActionMutableCopy]; return [[MutableDataVerifier alloc] initWithData:_data verifier:_verifier]; } - (NSUInteger)length { return _data.length; } - (const void *)bytes { return _data.bytes; } - (NSData *)subdataWithRange:(NSRange)range { return [_data subdataWithRange:range]; } @end @implementation MutableDataVerifier - (instancetype)init { self = [super init]; if (self) { _verifier = [[ObjectBehaviorVerifier alloc] init]; char *bytes = "hello world"; _data = [[NSMutableData alloc] initWithBytes:bytes length:strlen(bytes)]; } return self; } - (instancetype)initWithData:(NSData *)data verifier:(ObjectBehaviorVerifier *)verifier { self = [super init]; if (self) { _verifier = [verifier retain]; _data = [data mutableCopyWithZone:nil]; } return self; } - (void)dealloc { [_verifier release]; [_data release]; [super dealloc]; } - (id)retain { [_verifier appendAction:ObjectBehaviorActionRetain]; return [super retain]; } - (id)copyWithZone:(NSZone *)zone { [_verifier appendAction:ObjectBehaviorActionCopy]; return [[ImmutableDataVerifier alloc] initWithData:_data verifier:_verifier]; } - (id)mutableCopyWithZone:(NSZone *)zone { [_verifier appendAction:ObjectBehaviorActionMutableCopy]; return [[MutableDataVerifier alloc] initWithData:_data verifier:_verifier]; } - (NSUInteger)length { return _data.length; } - (void)setLength:(NSUInteger)length { _data.length = length; } - (const void *)bytes { return _data.bytes; } - (void *)mutableBytes { return _data.mutableBytes; } - (void)appendBytes:(const void *)bytes length:(NSUInteger)length { [_data appendBytes:bytes length:length]; } - (NSData *)subdataWithRange:(NSRange)range { return [_data subdataWithRange:range]; } @end void takesData(NSData *object) { // do NOTHING here... } NSData *returnsData() { static dispatch_once_t once = 0L; static NSData *data = nil; dispatch_once(&once, ^{ char *bytes = "hello world"; data = [[NSData alloc] initWithBytes:bytes length:strlen(bytes)]; }); return data; } BOOL identityOfData(NSData *data) { return data == returnsData(); } @implementation CalendarBridgingTester - (NSCalendar *)autoupdatingCurrentCalendar { return [NSCalendar autoupdatingCurrentCalendar]; } - (BOOL)verifyAutoupdatingCalendar:(NSCalendar *)calendar { Class autoCalendarClass = (Class)objc_lookUpClass("_NSAutoCalendar"); if (autoCalendarClass && [calendar isKindOfClass:autoCalendarClass]) { return YES; } else { autoCalendarClass = (Class)objc_lookUpClass("NSAutoCalendar"); return [calendar isKindOfClass:autoCalendarClass]; } } @end @implementation TimeZoneBridgingTester - (NSTimeZone *)autoupdatingCurrentTimeZone { return [NSTimeZone localTimeZone]; } - (BOOL)verifyAutoupdatingTimeZone:(NSTimeZone *)tz { Class autoTimeZoneClass = (Class)objc_lookUpClass("__NSLocalTimeZone"); return [tz isKindOfClass:autoTimeZoneClass]; } @end @implementation LocaleBridgingTester - (NSLocale *)autoupdatingCurrentLocale { return [NSLocale autoupdatingCurrentLocale]; } - (BOOL)verifyAutoupdatingLocale:(NSLocale *)locale { Class autoLocaleClass = (Class)objc_lookUpClass("NSAutoLocale"); return [locale isKindOfClass:autoLocaleClass]; } @end @implementation NumberBridgingTester - (BOOL)verifyKeysInRange:(NSRange)range existInDictionary:(NSDictionary *)dictionary { for (NSUInteger i = 0; i < range.length; i += 1) { if (!dictionary[@(range.location + i)]) { return NO; } } return YES; } @end