RCTUtils Obj-C nullability annotations

Summary:
Add Objective-C nullability annotations to RCTUtils

public

Reviewed By: javache

Differential Revision: D2797331

fb-gh-sync-id: b918179625865760edc8c6fcc189ad78f819f3e3
This commit is contained in:
Nick Lockwood 2016-01-21 07:49:45 -08:00 committed by facebook-github-bot-7
parent d33b554f5d
commit 34d5fa2695
3 changed files with 66 additions and 55 deletions

View File

@ -119,7 +119,7 @@ void _RCTAssertFormat(
void RCTFatal(NSError *error)
{
_RCTLogNativeInternal(RCTLogLevelFatal, NULL, 0, @"%@", [error localizedDescription]);
_RCTLogNativeInternal(RCTLogLevelFatal, NULL, 0, @"%@", error.localizedDescription);
RCTFatalHandler fatalHandler = RCTGetFatalHandler();
if (fatalHandler) {
@ -128,8 +128,8 @@ void RCTFatal(NSError *error)
#if DEBUG
@try {
#endif
NSString *name = [NSString stringWithFormat:@"%@: %@", RCTFatalExceptionName, [error localizedDescription]];
NSString *message = RCTFormatError([error localizedDescription], error.userInfo[RCTJSStackTraceKey], 75);
NSString *name = [NSString stringWithFormat:@"%@: %@", RCTFatalExceptionName, error.localizedDescription];
NSString *message = RCTFormatError(error.localizedDescription, error.userInfo[RCTJSStackTraceKey], 75);
[NSException raise:name format:@"%@", message];
#if DEBUG
} @catch (NSException *e) {}

View File

@ -16,10 +16,12 @@
#import "RCTAssert.h"
#import "RCTDefines.h"
NS_ASSUME_NONNULL_BEGIN
// JSON serialization/deserialization
RCT_EXTERN NSString *RCTJSONStringify(id jsonObject, NSError **error);
RCT_EXTERN id RCTJSONParse(NSString *jsonString, NSError **error);
RCT_EXTERN id RCTJSONParseMutable(NSString *jsonString, NSError **error);
RCT_EXTERN NSString *__nullable RCTJSONStringify(id __nullable jsonObject, NSError **error);
RCT_EXTERN id __nullable RCTJSONParse(NSString *__nullable jsonString, NSError **error);
RCT_EXTERN id __nullable RCTJSONParseMutable(NSString *__nullable jsonString, NSError **error);
// Strip non JSON-safe values from an object graph
RCT_EXTERN id RCTJSONClean(id object);
@ -51,13 +53,13 @@ RCT_EXTERN void RCTSwapInstanceMethods(Class cls, SEL original, SEL replacement)
RCT_EXTERN BOOL RCTClassOverridesClassMethod(Class cls, SEL selector);
RCT_EXTERN BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector);
// Creates a standardized error object
RCT_EXTERN NSDictionary<NSString *, id> *RCTMakeError(NSString *message, id toStringify, NSDictionary<NSString *, id> *extraData);
RCT_EXTERN NSDictionary<NSString *, id> *RCTMakeAndLogError(NSString *message, id toStringify, NSDictionary<NSString *, id> *extraData);
// Creates a standardized error object to return in callbacks
RCT_EXTERN NSDictionary<NSString *, id> *RCTMakeError(NSString *message, id __nullable toStringify, NSDictionary<NSString *, id> *__nullable extraData);
RCT_EXTERN NSDictionary<NSString *, id> *RCTMakeAndLogError(NSString *message, id __nullable toStringify, NSDictionary<NSString *, id> *__nullable extraData);
RCT_EXTERN NSDictionary<NSString *, id> *RCTJSErrorFromNSError(NSError *error);
RCT_EXTERN NSDictionary<NSString *, id> *RCTJSErrorFromCodeMessageAndNSError(NSString *code, NSString *message, NSError *error);
RCT_EXTERN NSDictionary<NSString *, id> *RCTJSErrorFromCodeMessageAndNSError(NSString *code, NSString *message, NSError *__nullable error);
// The default error code that will be sent in the .code value of the Error object to js
// The default error code to use as the `code` property for callback error objects
RCT_EXTERN NSString *const RCTErrorUnspecified;
// Returns YES if React is running in a test environment
@ -67,26 +69,26 @@ RCT_EXTERN BOOL RCTRunningInTestEnvironment(void);
RCT_EXTERN BOOL RCTRunningInAppExtension(void);
// Returns the shared UIApplication instance, or nil if running in an App Extension
RCT_EXTERN UIApplication *RCTSharedApplication(void);
RCT_EXTERN UIApplication *__nullable RCTSharedApplication(void);
// Returns the current main window, useful if you need to access the root view
// or view controller, e.g. to present a modal view controller or alert.
RCT_EXTERN UIWindow *RCTKeyWindow(void);
RCT_EXTERN UIWindow *__nullable RCTKeyWindow(void);
// Return a UIAlertView initialized with the given values
// or nil if running in an app extension
RCT_EXTERN UIAlertView *RCTAlertView(NSString *title,
NSString *message,
id delegate,
NSString *cancelButtonTitle,
NSArray<NSString *> *otherButtonTitles);
RCT_EXTERN UIAlertView *__nullable RCTAlertView(NSString *title,
NSString *__nullable message,
id __nullable delegate,
NSString *__nullable cancelButtonTitle,
NSArray<NSString *> *__nullable otherButtonTitles);
// Create an NSError in the RCTErrorDomain
RCT_EXTERN NSError *RCTErrorWithMessage(NSString *message);
// Convert nil values to NSNull, and vice-versa
RCT_EXTERN id RCTNilIfNull(id value);
RCT_EXTERN id RCTNullIfNil(id value);
RCT_EXTERN id __nullable RCTNilIfNull(id __nullable value);
RCT_EXTERN id RCTNullIfNil(id __nullable value);
// Convert NaN or infinite values to zero, as these aren't JSON-safe
RCT_EXTERN double RCTZeroIfNaN(double value);
@ -95,14 +97,14 @@ RCT_EXTERN double RCTZeroIfNaN(double value);
RCT_EXTERN NSURL *RCTDataURL(NSString *mimeType, NSData *data);
// Gzip functionality - compression level in range 0 - 1 (-1 for default)
RCT_EXTERN NSData *RCTGzipData(NSData *data, float level);
RCT_EXTERN NSData *RCTGzipData(NSData *__nullable data, float level);
// Returns the relative path within the main bundle for an absolute URL
// (or nil, if the URL does not specify a path within the main bundle)
RCT_EXTERN NSString *RCTBundlePathForURL(NSURL *URL);
RCT_EXTERN NSString *__nullable RCTBundlePathForURL(NSURL *__nullable URL);
// Determines if a given image URL actually refers to an XCAsset
RCT_EXTERN BOOL RCTIsXCAssetURL(NSURL *imageURL);
RCT_EXTERN BOOL RCTIsXCAssetURL(NSURL *__nullable imageURL);
// Converts a CGColor to a hex string
RCT_EXTERN NSString *RCTColorToHexString(CGColorRef color);
@ -111,5 +113,7 @@ RCT_EXTERN NSString *RCTColorToHexString(CGColorRef color);
RCT_EXTERN NSString *RCTUIKitLocalizedString(NSString *string);
// URL manipulation
RCT_EXTERN NSString *RCTGetURLQueryParam(NSURL *URL, NSString *param);
RCT_EXTERN NSURL *RCTURLByReplacingQueryParam(NSURL *URL, NSString *param, NSString *value);
RCT_EXTERN NSString *__nullable RCTGetURLQueryParam(NSURL *__nullable URL, NSString *param);
RCT_EXTERN NSURL *__nullable RCTURLByReplacingQueryParam(NSURL *__nullable URL, NSString *param, NSString *__nullable value);
NS_ASSUME_NONNULL_END

View File

@ -23,7 +23,7 @@
NSString *const RCTErrorUnspecified = @"EUNSPECIFIED";
NSString *RCTJSONStringify(id jsonObject, NSError **error)
NSString *__nullable RCTJSONStringify(id __nullable jsonObject, NSError **error)
{
static SEL JSONKitSelector = NULL;
static NSSet<Class> *collectionTypes;
@ -44,14 +44,14 @@ NSString *RCTJSONStringify(id jsonObject, NSError **error)
}
// Use Foundation JSON method
NSData *jsonData = [NSJSONSerialization
NSData *jsonData = jsonObject ? [NSJSONSerialization
dataWithJSONObject:jsonObject
options:(NSJSONWritingOptions)NSJSONReadingAllowFragments
error:error];
error:error] : nil;
return jsonData ? [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding] : nil;
}
static id _RCTJSONParse(NSString *jsonString, BOOL mutable, NSError **error)
static id __nullable _RCTJSONParse(NSString *__nullable jsonString, BOOL mutable, NSError **error)
{
static SEL JSONKitSelector = NULL;
static SEL JSONKitMutableSelector = NULL;
@ -110,12 +110,12 @@ static id _RCTJSONParse(NSString *jsonString, BOOL mutable, NSError **error)
return nil;
}
id RCTJSONParse(NSString *jsonString, NSError **error)
id __nullable RCTJSONParse(NSString *__nullable jsonString, NSError **error)
{
return _RCTJSONParse(jsonString, NO, error);
}
id RCTJSONParseMutable(NSString *jsonString, NSError **error)
id __nullable RCTJSONParseMutable(NSString *__nullable jsonString, NSError **error)
{
return _RCTJSONParse(jsonString, YES, error);
}
@ -311,18 +311,22 @@ BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector)
return NO;
}
NSDictionary<NSString *, id> *RCTMakeError(NSString *message, id toStringify, NSDictionary<NSString *, id> *extraData)
NSDictionary<NSString *, id> *RCTMakeError(NSString *message,
id __nullable toStringify,
NSDictionary<NSString *, id> *__nullable extraData)
{
if (toStringify) {
message = [message stringByAppendingString:[toStringify description]];
}
NSMutableDictionary<NSString *, id> *error = [NSMutableDictionary dictionaryWithDictionary:extraData];
NSMutableDictionary<NSString *, id> *error = [extraData mutableCopy] ?: [NSMutableDictionary new];
error[@"message"] = message;
return error;
}
NSDictionary<NSString *, id> *RCTMakeAndLogError(NSString *message, id toStringify, NSDictionary<NSString *, id> *extraData)
NSDictionary<NSString *, id> *RCTMakeAndLogError(NSString *message,
id __nullable toStringify,
NSDictionary<NSString *, id> *__nullable extraData)
{
NSDictionary<NSString *, id> *error = RCTMakeError(message, toStringify, extraData);
RCTLogError(@"\nError: %@", error);
@ -331,11 +335,15 @@ NSDictionary<NSString *, id> *RCTMakeAndLogError(NSString *message, id toStringi
NSDictionary<NSString *, id> *RCTJSErrorFromNSError(NSError *error)
{
return RCTJSErrorFromCodeMessageAndNSError(RCTErrorUnspecified, nil, error);
return RCTJSErrorFromCodeMessageAndNSError(RCTErrorUnspecified,
error.localizedDescription,
error);
}
// TODO: Can we just replace RCTMakeError with this function instead?
NSDictionary<NSString *, id> *RCTJSErrorFromCodeMessageAndNSError(NSString *code, NSString *message, NSError *error)
NSDictionary<NSString *, id> *RCTJSErrorFromCodeMessageAndNSError(NSString *code,
NSString *message,
NSError *__nullable error)
{
NSString *errorMessage;
NSArray<NSString *> *stackTrace = [NSThread callStackSymbols];
@ -356,7 +364,6 @@ NSDictionary<NSString *, id> *RCTJSErrorFromCodeMessageAndNSError(NSString *code
return RCTMakeError(errorMessage, nil, errorInfo);
}
BOOL RCTRunningInTestEnvironment(void)
{
static BOOL isTestEnvironment = NO;
@ -372,7 +379,7 @@ BOOL RCTRunningInAppExtension(void)
return [[[[NSBundle mainBundle] bundlePath] pathExtension] isEqualToString:@"appex"];
}
UIApplication *RCTSharedApplication(void)
UIApplication *__nullable RCTSharedApplication(void)
{
if (RCTRunningInAppExtension()) {
return nil;
@ -380,7 +387,7 @@ UIApplication *RCTSharedApplication(void)
return [[UIApplication class] performSelector:@selector(sharedApplication)];
}
UIWindow *RCTKeyWindow(void)
UIWindow *__nullable RCTKeyWindow(void)
{
if (RCTRunningInAppExtension()) {
return nil;
@ -390,11 +397,11 @@ UIWindow *RCTKeyWindow(void)
return RCTSharedApplication().keyWindow;
}
UIAlertView *RCTAlertView(NSString *title,
NSString *message,
id delegate,
NSString *cancelButtonTitle,
NSArray<NSString *> *otherButtonTitles)
UIAlertView *__nullable RCTAlertView(NSString *title,
NSString *__nullable message,
id __nullable delegate,
NSString *__nullable cancelButtonTitle,
NSArray<NSString *> *__nullable otherButtonTitles)
{
if (RCTRunningInAppExtension()) {
RCTLogError(@"RCTAlertView is unavailable when running in an app extension");
@ -421,12 +428,12 @@ NSError *RCTErrorWithMessage(NSString *message)
return [[NSError alloc] initWithDomain:RCTErrorDomain code:0 userInfo:errorInfo];
}
id RCTNullIfNil(id value)
id RCTNullIfNil(id __nullable value)
{
return value ?: (id)kCFNull;
}
id RCTNilIfNull(id value)
id __nullable RCTNilIfNull(id __nullable value)
{
return value == (id)kCFNull ? nil : value;
}
@ -443,14 +450,14 @@ NSURL *RCTDataURL(NSString *mimeType, NSData *data)
[data base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)0]]];
}
BOOL RCTIsGzippedData(NSData *); // exposed for unit testing purposes
BOOL RCTIsGzippedData(NSData *data)
BOOL RCTIsGzippedData(NSData *__nullable); // exposed for unit testing purposes
BOOL RCTIsGzippedData(NSData *__nullable data)
{
UInt8 *bytes = (UInt8 *)data.bytes;
return (data.length >= 2 && bytes[0] == 0x1f && bytes[1] == 0x8b);
}
NSData *RCTGzipData(NSData *input, float level)
NSData *RCTGzipData(NSData *__nullable input, float level)
{
if (input.length == 0 || RCTIsGzippedData(input)) {
return input;
@ -493,7 +500,7 @@ NSData *RCTGzipData(NSData *input, float level)
return output;
}
NSString *RCTBundlePathForURL(NSURL *URL)
NSString *__nullable RCTBundlePathForURL(NSURL *__nullable URL)
{
if (!URL.fileURL) {
// Not a file path
@ -512,7 +519,7 @@ NSString *RCTBundlePathForURL(NSURL *URL)
return path;
}
BOOL RCTIsXCAssetURL(NSURL *imageURL)
BOOL RCTIsXCAssetURL(NSURL *__nullable imageURL)
{
NSString *name = RCTBundlePathForURL(imageURL);
if (name.pathComponents.count != 1) {
@ -598,7 +605,7 @@ NSString *RCTUIKitLocalizedString(NSString *string)
return UIKitBundle ? [UIKitBundle localizedStringForKey:string value:string table:nil] : string;
}
NSString *RCTGetURLQueryParam(NSURL *URL, NSString *param)
NSString *__nullable RCTGetURLQueryParam(NSURL *__nullable URL, NSString *param)
{
RCTAssertParam(param);
if (!URL) {
@ -618,7 +625,7 @@ NSString *RCTGetURLQueryParam(NSURL *URL, NSString *param)
return nil;
}
NSURL *RCTURLByReplacingQueryParam(NSURL *URL, NSString *param, NSString *value)
NSURL *__nullable RCTURLByReplacingQueryParam(NSURL *__nullable URL, NSString *param, NSString *__nullable value)
{
RCTAssertParam(param);
if (!URL) {