Added RCT_DEBUG

This commit is contained in:
Nick Lockwood 2015-04-21 05:26:51 -07:00
parent b0348edcae
commit 8e15a0d5e7
14 changed files with 184 additions and 189 deletions

View File

@ -9,21 +9,7 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#ifdef __cplusplus #import "RCTDefines.h"
extern "C" {
#endif
/**
* By default, only raise an NSAssertion in debug mode
* (custom assert functions will still be called).
*/
#ifndef RCT_ASSERT
#if DEBUG
#define RCT_ASSERT 1
#else
#define RCT_ASSERT 0
#endif
#endif
/** /**
* The default error domain to be used for React errors. * The default error domain to be used for React errors.
@ -44,13 +30,14 @@ typedef void (^RCTAssertFunction)(
/** /**
* Private logging function - ignore this. * Private logging function - ignore this.
*/ */
void _RCTAssertFormat(BOOL, const char *, int, const char *, NSString *, ...) NS_FORMAT_FUNCTION(5,6); RCT_EXTERN void _RCTAssertFormat(
BOOL, const char *, int, const char *, NSString *, ...) NS_FORMAT_FUNCTION(5,6);
/** /**
* This is the main assert macro that you should use. * This is the main assert macro that you should use.
*/ */
#define RCTAssert(condition, ...) do { BOOL pass = ((condition) != 0); \ #define RCTAssert(condition, ...) do { BOOL pass = ((condition) != 0); \
if (RCT_ASSERT && !pass) { [[NSAssertionHandler currentHandler] handleFailureInFunction:@(__func__) \ if (RCT_NSASSERT && !pass) { [[NSAssertionHandler currentHandler] handleFailureInFunction:@(__func__) \
file:@(__FILE__) lineNumber:__LINE__ description:__VA_ARGS__]; } \ file:@(__FILE__) lineNumber:__LINE__ description:__VA_ARGS__]; } \
_RCTAssertFormat(pass, __FILE__, __LINE__, __func__, __VA_ARGS__); \ _RCTAssertFormat(pass, __FILE__, __LINE__, __func__, __VA_ARGS__); \
} while (false) } while (false)
@ -66,16 +53,12 @@ _RCTAssertFormat(pass, __FILE__, __LINE__, __func__, __VA_ARGS__); \
* macros. You can use these to replace the standard behavior with custom log * macros. You can use these to replace the standard behavior with custom log
* functionality. * functionality.
*/ */
void RCTSetAssertFunction(RCTAssertFunction assertFunction); RCT_EXTERN void RCTSetAssertFunction(RCTAssertFunction assertFunction);
RCTAssertFunction RCTGetAssertFunction(void); RCT_EXTERN RCTAssertFunction RCTGetAssertFunction(void);
/** /**
* This appends additional code to the existing assert function, without * This appends additional code to the existing assert function, without
* replacing the existing functionality. Useful if you just want to forward * replacing the existing functionality. Useful if you just want to forward
* assert info to an extra service without changing the default behavior. * assert info to an extra service without changing the default behavior.
*/ */
void RCTAddAssertFunction(RCTAssertFunction assertFunction); RCT_EXTERN void RCTAddAssertFunction(RCTAssertFunction assertFunction);
#ifdef __cplusplus
}
#endif

View File

@ -10,6 +10,7 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import "RCTBridgeModule.h" #import "RCTBridgeModule.h"
#import "RCTDefines.h"
#import "RCTFrameUpdate.h" #import "RCTFrameUpdate.h"
#import "RCTInvalidating.h" #import "RCTInvalidating.h"
#import "RCTJavaScriptExecutor.h" #import "RCTJavaScriptExecutor.h"
@ -40,7 +41,7 @@ typedef NSArray *(^RCTBridgeModuleProviderBlock)(void);
/** /**
* This function returns the module name for a given class. * This function returns the module name for a given class.
*/ */
extern NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass); RCT_EXTERN NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass);
/** /**
* Async batched bridge used to communicate with the JavaScript application. * Async batched bridge used to communicate with the JavaScript application.

View File

@ -143,7 +143,8 @@ static NSArray *RCTBridgeModuleClassesByModuleID(void)
// Get data entry // Get data entry
NSString *entry = @(*(const char **)(mach_header + addr)); NSString *entry = @(*(const char **)(mach_header + addr));
NSArray *parts = [[entry substringWithRange:(NSRange){2, entry.length - 3}] componentsSeparatedByString:@" "]; NSArray *parts = [[entry substringWithRange:(NSRange){2, entry.length - 3}]
componentsSeparatedByString:@" "];
// Parse class name // Parse class name
NSString *moduleClassName = parts[0]; NSString *moduleClassName = parts[0];
@ -164,7 +165,7 @@ static NSArray *RCTBridgeModuleClassesByModuleID(void)
} }
} }
#if DEBUG if (RCT_DEBUG) {
// We may be able to get rid of this check in future, once people // We may be able to get rid of this check in future, once people
// get used to the new registration system. That would potentially // get used to the new registration system. That would potentially
@ -188,8 +189,7 @@ static NSArray *RCTBridgeModuleClassesByModuleID(void)
superclass = class_getSuperclass(superclass); superclass = class_getSuperclass(superclass);
} }
} }
}
#endif
}); });
@ -289,13 +289,13 @@ static NSString *RCTStringUpToFirstArgument(NSString *methodName)
_isClassMethod = [reactMethodName characterAtIndex:0] == '+'; _isClassMethod = [reactMethodName characterAtIndex:0] == '+';
_moduleClass = NSClassFromString(_moduleClassName); _moduleClass = NSClassFromString(_moduleClassName);
#if DEBUG if (RCT_DEBUG) {
// Sanity check // Sanity check
RCTAssert([_moduleClass conformsToProtocol:@protocol(RCTBridgeModule)], RCTAssert([_moduleClass conformsToProtocol:@protocol(RCTBridgeModule)],
@"You are attempting to export the method %@, but %@ does not \ @"You are attempting to export the method %@, but %@ does not \
conform to the RCTBridgeModule Protocol", objCMethodName, _moduleClassName); conform to the RCTBridgeModule Protocol", objCMethodName, _moduleClassName);
#endif }
// Get method signature // Get method signature
_methodSignature = _isClassMethod ? _methodSignature = _isClassMethod ?
@ -449,13 +449,11 @@ static NSString *RCTStringUpToFirstArgument(NSString *methodName)
arguments:(NSArray *)arguments arguments:(NSArray *)arguments
context:(NSNumber *)context context:(NSNumber *)context
{ {
if (RCT_DEBUG) {
#if DEBUG
// Sanity check // Sanity check
RCTAssert([module class] == _moduleClass, @"Attempted to invoke method \ RCTAssert([module class] == _moduleClass, @"Attempted to invoke method \
%@ on a module of class %@", _methodName, [module class]); %@ on a module of class %@", _methodName, [module class]);
#endif
// Safety check // Safety check
if (arguments.count != _argumentBlocks.count) { if (arguments.count != _argumentBlocks.count) {
@ -464,6 +462,7 @@ static NSString *RCTStringUpToFirstArgument(NSString *methodName)
arguments.count, _argumentBlocks.count); arguments.count, _argumentBlocks.count);
return; return;
} }
}
// Create invocation (we can't re-use this as it wouldn't be thread-safe) // Create invocation (we can't re-use this as it wouldn't be thread-safe)
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:_methodSignature]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:_methodSignature];

View File

@ -16,6 +16,7 @@
#import "../Views/RCTAnimationType.h" #import "../Views/RCTAnimationType.h"
#import "../Views/RCTPointerEvents.h" #import "../Views/RCTPointerEvents.h"
#import "RCTDefines.h"
#import "RCTLog.h" #import "RCTLog.h"
/** /**
@ -116,33 +117,25 @@ typedef BOOL css_overflow;
@end @end
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* This function will attempt to set a property using a json value by first * This function will attempt to set a property using a json value by first
* inferring the correct type from all available information, and then * inferring the correct type from all available information, and then
* applying an appropriate conversion method. If the property does not * applying an appropriate conversion method. If the property does not
* exist, or the type cannot be inferred, the function will return NO. * exist, or the type cannot be inferred, the function will return NO.
*/ */
BOOL RCTSetProperty(id target, NSString *keyPath, SEL type, id json); RCT_EXTERN BOOL RCTSetProperty(id target, NSString *keyPath, SEL type, id json);
/** /**
* This function attempts to copy a property from the source object to the * This function attempts to copy a property from the source object to the
* destination object using KVC. If the property does not exist, or cannot * destination object using KVC. If the property does not exist, or cannot
* be set, it will do nothing and return NO. * be set, it will do nothing and return NO.
*/ */
BOOL RCTCopyProperty(id target, id source, NSString *keyPath); RCT_EXTERN BOOL RCTCopyProperty(id target, id source, NSString *keyPath);
/** /**
* Underlying implementation of RCT_ENUM_CONVERTER macro. Ignore this. * Underlying implementation of RCT_ENUM_CONVERTER macro. Ignore this.
*/ */
NSNumber *RCTConvertEnumValue(const char *, NSDictionary *, NSNumber *, id); RCT_EXTERN NSNumber *RCTConvertEnumValue(const char *, NSDictionary *, NSNumber *, id);
#ifdef __cplusplus
}
#endif
/** /**
* This macro is used for creating simple converter functions that just call * This macro is used for creating simple converter functions that just call

55
React/Base/RCTDefines.h Normal file
View File

@ -0,0 +1,55 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import <Foundation/Foundation.h>
/**
* Make global functions usable in C++
*/
#if defined(__cplusplus)
#define RCT_EXTERN extern "C" __attribute__((visibility("default")))
#else
#define RCT_EXTERN extern __attribute__((visibility("default")))
#endif
/**
* The RCT_DEBUG macro can be used to exclude error checking and logging code
* from release builds to improve performance and reduce binary size.
*/
#ifndef RCT_DEBUG
#if DEBUG
#define RCT_DEBUG 1
#else
#define RCT_DEBUG 0
#endif
#endif
/**
* The RCT_DEV macro can be used to enable or disable development tools
* such as the debug executors, dev menu, red box, etc.
*/
#ifndef RCT_DEV
#if DEBUG
#define RCT_DEV 1
#else
#define RCT_DEV 0
#endif
#endif
/**
* By default, only raise an NSAssertion in debug mode
* (custom assert functions will still be called).
*/
#ifndef RCT_NSASSERT
#if RCT_DEBUG
#define RCT_NSASSERT 1
#else
#define RCT_NSASSERT 0
#endif
#endif

View File

@ -10,10 +10,7 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "RCTAssert.h" #import "RCTAssert.h"
#import "RCTDefines.h"
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* Thresholds for logs to raise an assertion, or display redbox, respectively. * Thresholds for logs to raise an assertion, or display redbox, respectively.
@ -46,9 +43,9 @@ typedef void (^RCTLogFunction)(
); );
/** /**
* Get a given thread's name (or the current queue, iff in debug mode) * Get a given thread's name (or the current queue, if in debug mode)
*/ */
NSString *RCTThreadName(NSThread *); RCT_EXTERN NSString *RCTThreadName(NSThread *);
/** /**
* A method to generate a string from a collection of log data. To omit any * A method to generate a string from a collection of log data. To omit any
@ -73,35 +70,35 @@ extern RCTLogFunction RCTDefaultLogFunction;
* below which logs will be ignored. Default is RCTLogLevelInfo for debug and * below which logs will be ignored. Default is RCTLogLevelInfo for debug and
* RCTLogLevelError for production. * RCTLogLevelError for production.
*/ */
void RCTSetLogThreshold(RCTLogLevel threshold); RCT_EXTERN void RCTSetLogThreshold(RCTLogLevel threshold);
RCTLogLevel RCTGetLogThreshold(void); RCT_EXTERN RCTLogLevel RCTGetLogThreshold(void);
/** /**
* These methods get and set the current logging function called by the RCTLogXX * These methods get and set the current logging function called by the RCTLogXX
* macros. You can use these to replace the standard behavior with custom log * macros. You can use these to replace the standard behavior with custom log
* functionality. * functionality.
*/ */
void RCTSetLogFunction(RCTLogFunction logFunction); RCT_EXTERN void RCTSetLogFunction(RCTLogFunction logFunction);
RCTLogFunction RCTGetLogFunction(void); RCT_EXTERN RCTLogFunction RCTGetLogFunction(void);
/** /**
* This appends additional code to the existing log function, without replacing * This appends additional code to the existing log function, without replacing
* the existing functionality. Useful if you just want to forward logs to an * the existing functionality. Useful if you just want to forward logs to an
* extra service without changing the default behavior. * extra service without changing the default behavior.
*/ */
void RCTAddLogFunction(RCTLogFunction logFunction); RCT_EXTERN void RCTAddLogFunction(RCTLogFunction logFunction);
/** /**
* This method adds a conditional prefix to any messages logged within the scope * This method adds a conditional prefix to any messages logged within the scope
* of the passed block. This is useful for adding additional context to log * of the passed block. This is useful for adding additional context to log
* messages. The block will be performed synchronously on the current thread. * messages. The block will be performed synchronously on the current thread.
*/ */
void RCTPerformBlockWithLogPrefix(void (^block)(void), NSString *prefix); RCT_EXTERN void RCTPerformBlockWithLogPrefix(void (^block)(void), NSString *prefix);
/** /**
* Private logging functions - ignore these. * Private logging functions - ignore these.
*/ */
void _RCTLogFormat(RCTLogLevel, const char *, int, NSString *, ...) NS_FORMAT_FUNCTION(4,5); RCT_EXTERN void _RCTLogFormat(RCTLogLevel, const char *, int, NSString *, ...) NS_FORMAT_FUNCTION(4,5);
#define _RCTLog(lvl, ...) do { \ #define _RCTLog(lvl, ...) do { \
if (lvl >= RCTLOG_FATAL_LEVEL) { RCTAssert(NO, __VA_ARGS__); } \ if (lvl >= RCTLOG_FATAL_LEVEL) { RCTAssert(NO, __VA_ARGS__); } \
_RCTLogFormat(lvl, __FILE__, __LINE__, __VA_ARGS__); \ _RCTLogFormat(lvl, __FILE__, __LINE__, __VA_ARGS__); \
@ -116,7 +113,3 @@ void _RCTLogFormat(RCTLogLevel, const char *, int, NSString *, ...) NS_FORMAT_FU
#define RCTLogWarn(...) _RCTLog(RCTLogLevelWarning, __VA_ARGS__) #define RCTLogWarn(...) _RCTLog(RCTLogLevelWarning, __VA_ARGS__)
#define RCTLogError(...) _RCTLog(RCTLogLevelError, __VA_ARGS__) #define RCTLogError(...) _RCTLog(RCTLogLevelError, __VA_ARGS__)
#define RCTLogMustFix(...) _RCTLog(RCTLogLevelMustFix, __VA_ARGS__) #define RCTLogMustFix(...) _RCTLog(RCTLogLevelMustFix, __VA_ARGS__)
#ifdef __cplusplus
}
#endif

View File

@ -11,6 +11,7 @@
#import "RCTAssert.h" #import "RCTAssert.h"
#import "RCTBridge.h" #import "RCTBridge.h"
#import "RCTDefines.h"
#import "RCTRedBox.h" #import "RCTRedBox.h"
@interface RCTBridge (Logging) @interface RCTBridge (Logging)
@ -36,7 +37,7 @@ static void RCTLogSetup()
{ {
RCTCurrentLogFunction = RCTDefaultLogFunction; RCTCurrentLogFunction = RCTDefaultLogFunction;
#if DEBUG #if RCT_DEBUG
RCTCurrentLogThreshold = RCTLogLevelInfo - 1; RCTCurrentLogThreshold = RCTLogLevelInfo - 1;
#else #else
RCTCurrentLogThreshold = RCTLogLevelError; RCTCurrentLogThreshold = RCTLogLevelError;
@ -102,7 +103,7 @@ NSString *RCTThreadName(NSThread *thread)
{ {
NSString *threadName = [thread isMainThread] ? @"main" : thread.name; NSString *threadName = [thread isMainThread] ? @"main" : thread.name;
if (threadName.length == 0) { if (threadName.length == 0) {
#if DEBUG #if DEBUG // This is DEBUG not RCT_DEBUG because it *really* must not ship in RC
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations" #pragma clang diagnostic ignored "-Wdeprecated-declarations"
threadName = @(dispatch_queue_get_label(dispatch_get_current_queue())); threadName = @(dispatch_queue_get_label(dispatch_get_current_queue()));
@ -161,12 +162,7 @@ void _RCTLogFormat(
NSString *format, ...) NSString *format, ...)
{ {
#if DEBUG BOOL log = RCT_DEBUG || (RCTCurrentLogFunction != nil);
BOOL log = YES;
#else
BOOL log = (RCTCurrentLogFunction != nil);
#endif
if (log && level >= RCTCurrentLogThreshold) { if (log && level >= RCTCurrentLogThreshold) {
// Get message // Get message
@ -188,7 +184,7 @@ void _RCTLogFormat(
level, fileName ? @(fileName) : nil, (lineNumber >= 0) ? @(lineNumber) : nil, message level, fileName ? @(fileName) : nil, (lineNumber >= 0) ? @(lineNumber) : nil, message
); );
#if DEBUG if (RCT_DEBUG) {
// Log to red box // Log to red box
if (level >= RCTLOG_REDBOX_LEVEL) { if (level >= RCTLOG_REDBOX_LEVEL) {
@ -197,8 +193,6 @@ void _RCTLogFormat(
// Log to JS executor // Log to JS executor
[RCTBridge logMessage:message level:level ? @(RCTLogLevels[level - 1]) : @"info"]; [RCTBridge logMessage:message level:level ? @(RCTLogLevels[level - 1]) : @"info"];
}
#endif
} }
} }

View File

@ -9,45 +9,47 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "RCTDefines.h"
/** /**
* RCTProfile * RCTProfile
* *
* This file provides a set of functions and macros for performance profiling * This file provides a set of functions and macros for performance profiling
* *
* NOTE: This API is a work in a work in progress, please consider it before * NOTE: This API is a work in a work in progress, please consider carefully
* before using. * before before using it.
*/ */
#if DEBUG #if RCT_DEV
/** /**
* Returns YES if the profiling information is currently being collected * Returns YES if the profiling information is currently being collected
*/ */
BOOL RCTProfileIsProfiling(void); RCT_EXTERN BOOL RCTProfileIsProfiling(void);
/** /**
* Start collecting profiling information * Start collecting profiling information
*/ */
void RCTProfileInit(void); RCT_EXTERN void RCTProfileInit(void);
/** /**
* Stop profiling and return a JSON string of the collected data - The data * Stop profiling and return a JSON string of the collected data - The data
* returned is compliant with google's trace event format - the format used * returned is compliant with google's trace event format - the format used
* as input to trace-viewer * as input to trace-viewer
*/ */
NSString *RCTProfileEnd(void); RCT_EXTERN NSString *RCTProfileEnd(void);
/** /**
* Collects the initial event information for the event and returns a reference ID * Collects the initial event information for the event and returns a reference ID
*/ */
NSNumber *_RCTProfileBeginEvent(void); RCT_EXTERN NSNumber *_RCTProfileBeginEvent(void);
/** /**
* The ID returned by BeginEvent should then be passed into EndEvent, with the * The ID returned by BeginEvent should then be passed into EndEvent, with the
* rest of the event information. Just at this point the event will actually be * rest of the event information. Just at this point the event will actually be
* registered * registered
*/ */
void _RCTProfileEndEvent(NSNumber *, NSString *, NSString *, id); RCT_EXTERN void _RCTProfileEndEvent(NSNumber *, NSString *, NSString *, id);
/** /**
* This pair of macros implicitly handle the event ID when beginning and ending * This pair of macros implicitly handle the event ID when beginning and ending
@ -69,7 +71,7 @@ _RCTProfileEndEvent(__rct_profile_id, name, category, args)
/** /**
* An event that doesn't have a duration (i.e. Notification, VSync, etc) * An event that doesn't have a duration (i.e. Notification, VSync, etc)
*/ */
void RCTProfileImmediateEvent(NSString *, NSTimeInterval , NSString *); RCT_EXTERN void RCTProfileImmediateEvent(NSString *, NSTimeInterval , NSString *);
/** /**
* Helper to profile the duration of the execution of a block. This method uses * Helper to profile the duration of the execution of a block. This method uses

View File

@ -13,10 +13,11 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import "RCTDefines.h"
#import "RCTLog.h" #import "RCTLog.h"
#import "RCTUtils.h" #import "RCTUtils.h"
#if DEBUG #if RCT_DEV
#pragma mark - Prototypes #pragma mark - Prototypes

View File

@ -282,23 +282,14 @@
- (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack showIfHidden:(BOOL)shouldShow - (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack showIfHidden:(BOOL)shouldShow
{ {
if (RCT_DEBUG) {
#if DEBUG dispatch_async(dispatch_get_main_queue(), ^{
dispatch_block_t block = ^{
if (!_window) { if (!_window) {
_window = [[RCTRedBoxWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; _window = [[RCTRedBoxWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
} }
[_window showErrorMessage:message withStack:stack showIfHidden:shouldShow]; [_window showErrorMessage:message withStack:stack showIfHidden:shouldShow];
}; });
if ([NSThread isMainThread]) {
block();
} else {
dispatch_async(dispatch_get_main_queue(), block);
} }
#endif
} }
- (NSString *)currentErrorMessage - (NSString *)currentErrorMessage

View File

@ -13,43 +13,36 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "RCTAssert.h" #import "RCTAssert.h"
#import "RCTDefines.h"
#ifdef __cplusplus
extern "C" {
#endif
// Utility functions for JSON object <-> string serialization/deserialization // Utility functions for JSON object <-> string serialization/deserialization
NSString *RCTJSONStringify(id jsonObject, NSError **error); RCT_EXTERN NSString *RCTJSONStringify(id jsonObject, NSError **error);
id RCTJSONParse(NSString *jsonString, NSError **error); RCT_EXTERN id RCTJSONParse(NSString *jsonString, NSError **error);
// Get MD5 hash of a string (TODO: currently unused. Remove?) // Get MD5 hash of a string (TODO: currently unused. Remove?)
NSString *RCTMD5Hash(NSString *string); RCT_EXTERN NSString *RCTMD5Hash(NSString *string);
// Get screen metrics in a thread-safe way // Get screen metrics in a thread-safe way
CGFloat RCTScreenScale(void); RCT_EXTERN CGFloat RCTScreenScale(void);
CGSize RCTScreenSize(void); RCT_EXTERN CGSize RCTScreenSize(void);
// Round float coordinates to nearest whole screen pixel (not point) // Round float coordinates to nearest whole screen pixel (not point)
CGFloat RCTRoundPixelValue(CGFloat value); RCT_EXTERN CGFloat RCTRoundPixelValue(CGFloat value);
CGFloat RCTCeilPixelValue(CGFloat value); RCT_EXTERN CGFloat RCTCeilPixelValue(CGFloat value);
CGFloat RCTFloorPixelValue(CGFloat value); RCT_EXTERN CGFloat RCTFloorPixelValue(CGFloat value);
// Get current time, for precise performance metrics // Get current time, for precise performance metrics
NSTimeInterval RCTTGetAbsoluteTime(void); RCT_EXTERN NSTimeInterval RCTTGetAbsoluteTime(void);
// Method swizzling // Method swizzling
void RCTSwapClassMethods(Class cls, SEL original, SEL replacement); RCT_EXTERN void RCTSwapClassMethods(Class cls, SEL original, SEL replacement);
void RCTSwapInstanceMethods(Class cls, SEL original, SEL replacement); RCT_EXTERN void RCTSwapInstanceMethods(Class cls, SEL original, SEL replacement);
// Module subclass support // Module subclass support
BOOL RCTClassOverridesClassMethod(Class cls, SEL selector); RCT_EXTERN BOOL RCTClassOverridesClassMethod(Class cls, SEL selector);
BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector); RCT_EXTERN BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector);
// Creates a standardized error object // Creates a standardized error object
// TODO(#6472857): create NSErrors and automatically convert them over the bridge. // TODO(#6472857): create NSErrors and automatically convert them over the bridge.
NSDictionary *RCTMakeError(NSString *message, id toStringify, NSDictionary *extraData); RCT_EXTERN NSDictionary *RCTMakeError(NSString *message, id toStringify, NSDictionary *extraData);
NSDictionary *RCTMakeAndLogError(NSString *message, id toStringify, NSDictionary *extraData); RCT_EXTERN NSDictionary *RCTMakeAndLogError(NSString *message, id toStringify, NSDictionary *extraData);
#ifdef __cplusplus
}
#endif

View File

@ -14,6 +14,7 @@
#import <JavaScriptCore/JavaScriptCore.h> #import <JavaScriptCore/JavaScriptCore.h>
#import "RCTAssert.h" #import "RCTAssert.h"
#import "RCTDefines.h"
#import "RCTLog.h" #import "RCTLog.h"
#import "RCTProfile.h" #import "RCTProfile.h"
#import "RCTUtils.h" #import "RCTUtils.h"
@ -321,10 +322,9 @@ static NSError *RCTNSErrorFromJSError(JSContextRef context, JSValueRef jsError)
asGlobalObjectNamed:(NSString *)objectName asGlobalObjectNamed:(NSString *)objectName
callback:(RCTJavaScriptCompleteBlock)onComplete callback:(RCTJavaScriptCompleteBlock)onComplete
{ {
if (RCT_DEBUG) {
#if DEBUG
RCTAssert(RCTJSONParse(script, NULL) != nil, @"%@ wasn't valid JSON!", script); RCTAssert(RCTJSONParse(script, NULL) != nil, @"%@ wasn't valid JSON!", script);
#endif }
__weak RCTContextExecutor *weakSelf = self; __weak RCTContextExecutor *weakSelf = self;
[self executeBlockOnJavaScriptQueue:RCTProfileBlock((^{ [self executeBlockOnJavaScriptQueue:RCTProfileBlock((^{

View File

@ -9,6 +9,7 @@
#import "RCTExceptionsManager.h" #import "RCTExceptionsManager.h"
#import "RCTDefines.h"
#import "RCTLog.h" #import "RCTLog.h"
#import "RCTRedBox.h" #import "RCTRedBox.h"
#import "RCTRootView.h" #import "RCTRootView.h"
@ -43,11 +44,10 @@ RCT_EXPORT_METHOD(reportUnhandledException:(NSString *)message
return; return;
} }
#if DEBUG if (RCT_DEBUG) {
[[RCTRedBox sharedInstance] showErrorMessage:message withStack:stack]; [[RCTRedBox sharedInstance] showErrorMessage:message withStack:stack];
return;
#else }
static NSUInteger reloadRetries = 0; static NSUInteger reloadRetries = 0;
const NSUInteger maxMessageLength = 75; const NSUInteger maxMessageLength = 75;
@ -76,21 +76,14 @@ RCT_EXPORT_METHOD(reportUnhandledException:(NSString *)message
NSString *name = [@"Unhandled JS Exception: " stringByAppendingString:sanitizedMessage]; NSString *name = [@"Unhandled JS Exception: " stringByAppendingString:sanitizedMessage];
[NSException raise:name format:@"Message: %@, stack: %@", message, prettyStack]; [NSException raise:name format:@"Message: %@, stack: %@", message, prettyStack];
} }
#endif
} }
RCT_EXPORT_METHOD(updateExceptionMessage:(NSString *)message RCT_EXPORT_METHOD(updateExceptionMessage:(NSString *)message
stack:(NSArray *)stack) stack:(NSArray *)stack)
{ {
if (RCT_DEBUG) {
#if DEBUG
[[RCTRedBox sharedInstance] updateErrorMessage:message withStack:stack]; [[RCTRedBox sharedInstance] updateErrorMessage:message withStack:stack];
}
#endif
} }
@end @end

View File

@ -18,6 +18,7 @@
#import "RCTAssert.h" #import "RCTAssert.h"
#import "RCTBridge.h" #import "RCTBridge.h"
#import "RCTConvert.h" #import "RCTConvert.h"
#import "RCTDefines.h"
#import "RCTLog.h" #import "RCTLog.h"
#import "RCTProfile.h" #import "RCTProfile.h"
#import "RCTRootView.h" #import "RCTRootView.h"
@ -703,20 +704,16 @@ static BOOL RCTCallPropertySetter(NSString *key, SEL setter, id value, id view,
((void (*)(id, SEL, id, id, id))objc_msgSend)(manager, setter, value, view, defaultView); ((void (*)(id, SEL, id, id, id))objc_msgSend)(manager, setter, value, view, defaultView);
}; };
#if DEBUG if (RCT_DEBUG) {
NSString *viewName = RCTViewNameForModuleName(RCTBridgeModuleNameForClass([manager class])); NSString *viewName = RCTViewNameForModuleName(RCTBridgeModuleNameForClass([manager class]));
NSString *logPrefix = [NSString stringWithFormat: NSString *logPrefix = [NSString stringWithFormat:
@"Error setting property '%@' of %@ with tag #%@: ", @"Error setting property '%@' of %@ with tag #%@: ",
key, viewName, [view reactTag]]; key, viewName, [view reactTag]];
RCTPerformBlockWithLogPrefix(block, logPrefix); RCTPerformBlockWithLogPrefix(block, logPrefix);
} else {
#else
block(); block();
}
#endif
return YES; return YES;
} }