Skip to content

Commit

Permalink
Added RCT_DEBUG
Browse files Browse the repository at this point in the history
  • Loading branch information
nicklockwood committed Apr 21, 2015
1 parent b0348ed commit 8e15a0d
Show file tree
Hide file tree
Showing 14 changed files with 185 additions and 190 deletions.
31 changes: 7 additions & 24 deletions React/Base/RCTAssert.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,7 @@

#import <Foundation/Foundation.h>

#ifdef __cplusplus
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
#import "RCTDefines.h"

/**
* The default error domain to be used for React errors.
Expand All @@ -44,13 +30,14 @@ typedef void (^RCTAssertFunction)(
/**
* 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.
*/
#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__]; } \
_RCTAssertFormat(pass, __FILE__, __LINE__, __func__, __VA_ARGS__); \
} while (false)
Expand All @@ -66,16 +53,12 @@ _RCTAssertFormat(pass, __FILE__, __LINE__, __func__, __VA_ARGS__); \
* macros. You can use these to replace the standard behavior with custom log
* functionality.
*/
void RCTSetAssertFunction(RCTAssertFunction assertFunction);
RCTAssertFunction RCTGetAssertFunction(void);
RCT_EXTERN void RCTSetAssertFunction(RCTAssertFunction assertFunction);
RCT_EXTERN RCTAssertFunction RCTGetAssertFunction(void);

/**
* This appends additional code to the existing assert function, without
* replacing the existing functionality. Useful if you just want to forward
* assert info to an extra service without changing the default behavior.
*/
void RCTAddAssertFunction(RCTAssertFunction assertFunction);

#ifdef __cplusplus
}
#endif
RCT_EXTERN void RCTAddAssertFunction(RCTAssertFunction assertFunction);
3 changes: 2 additions & 1 deletion React/Base/RCTBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#import <UIKit/UIKit.h>

#import "RCTBridgeModule.h"
#import "RCTDefines.h"
#import "RCTFrameUpdate.h"
#import "RCTInvalidating.h"
#import "RCTJavaScriptExecutor.h"
Expand Down Expand Up @@ -40,7 +41,7 @@ typedef NSArray *(^RCTBridgeModuleProviderBlock)(void);
/**
* 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.
Expand Down
75 changes: 37 additions & 38 deletions React/Base/RCTBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ typedef NS_ENUM(NSUInteger, RCTBridgeFields) {

// Get data entry
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
NSString *moduleClassName = parts[0];
Expand All @@ -164,33 +165,32 @@ typedef NS_ENUM(NSUInteger, RCTBridgeFields) {
}
}

#if DEBUG
if (RCT_DEBUG) {

// We may be able to get rid of this check in future, once people
// get used to the new registration system. That would potentially
// allow you to create modules that are not automatically registered
// We may be able to get rid of this check in future, once people
// get used to the new registration system. That would potentially
// allow you to create modules that are not automatically registered

static unsigned int classCount;
Class *classes = objc_copyClassList(&classCount);
for (unsigned int i = 0; i < classCount; i++)
{
Class cls = classes[i];
Class superclass = cls;
while (superclass)
static unsigned int classCount;
Class *classes = objc_copyClassList(&classCount);
for (unsigned int i = 0; i < classCount; i++)
{
if (class_conformsToProtocol(superclass, @protocol(RCTBridgeModule)))
Class cls = classes[i];
Class superclass = cls;
while (superclass)
{
if (![RCTModuleClassesByID containsObject:cls]) {
RCTLogError(@"Class %@ was not exported. Did you forget to use RCT_EXPORT_MODULE()?", NSStringFromClass(cls));
if (class_conformsToProtocol(superclass, @protocol(RCTBridgeModule)))
{
if (![RCTModuleClassesByID containsObject:cls]) {
RCTLogError(@"Class %@ was not exported. Did you forget to use RCT_EXPORT_MODULE()?", NSStringFromClass(cls));
}
break;
}
break;
superclass = class_getSuperclass(superclass);
}
superclass = class_getSuperclass(superclass);
}
}

#endif

});

return RCTModuleClassesByID;
Expand Down Expand Up @@ -289,13 +289,13 @@ - (instancetype)initWithReactMethodName:(NSString *)reactMethodName
_isClassMethod = [reactMethodName characterAtIndex:0] == '+';
_moduleClass = NSClassFromString(_moduleClassName);

#if DEBUG
if (RCT_DEBUG) {

// Sanity check
RCTAssert([_moduleClass conformsToProtocol:@protocol(RCTBridgeModule)],
@"You are attempting to export the method %@, but %@ does not \
conform to the RCTBridgeModule Protocol", objCMethodName, _moduleClassName);
#endif
// Sanity check
RCTAssert([_moduleClass conformsToProtocol:@protocol(RCTBridgeModule)],
@"You are attempting to export the method %@, but %@ does not \
conform to the RCTBridgeModule Protocol", objCMethodName, _moduleClassName);
}

// Get method signature
_methodSignature = _isClassMethod ?
Expand Down Expand Up @@ -449,20 +449,19 @@ - (void)invokeWithBridge:(RCTBridge *)bridge
arguments:(NSArray *)arguments
context:(NSNumber *)context
{
if (RCT_DEBUG) {

#if DEBUG

// Sanity check
RCTAssert([module class] == _moduleClass, @"Attempted to invoke method \
%@ on a module of class %@", _methodName, [module class]);
#endif

// Safety check
if (arguments.count != _argumentBlocks.count) {
RCTLogError(@"%@.%@ was called with %zd arguments, but expects %zd",
RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName,
arguments.count, _argumentBlocks.count);
return;
// Sanity check
RCTAssert([module class] == _moduleClass, @"Attempted to invoke method \
%@ on a module of class %@", _methodName, [module class]);

// Safety check
if (arguments.count != _argumentBlocks.count) {
RCTLogError(@"%@.%@ was called with %zd arguments, but expects %zd",
RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName,
arguments.count, _argumentBlocks.count);
return;
}
}

// Create invocation (we can't re-use this as it wouldn't be thread-safe)
Expand Down
15 changes: 4 additions & 11 deletions React/Base/RCTConvert.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#import "../Views/RCTAnimationType.h"
#import "../Views/RCTPointerEvents.h"

#import "RCTDefines.h"
#import "RCTLog.h"

/**
Expand Down Expand Up @@ -116,33 +117,25 @@ typedef BOOL css_overflow;

@end

#ifdef __cplusplus
extern "C" {
#endif

/**
* This function will attempt to set a property using a json value by first
* inferring the correct type from all available information, and then
* applying an appropriate conversion method. If the property does not
* 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
* destination object using KVC. If the property does not exist, or cannot
* 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.
*/
NSNumber *RCTConvertEnumValue(const char *, NSDictionary *, NSNumber *, id);

#ifdef __cplusplus
}
#endif
RCT_EXTERN NSNumber *RCTConvertEnumValue(const char *, NSDictionary *, NSNumber *, id);

/**
* This macro is used for creating simple converter functions that just call
Expand Down
55 changes: 55 additions & 0 deletions React/Base/RCTDefines.h
Original file line number Diff line number Diff line change
@@ -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
27 changes: 10 additions & 17 deletions React/Base/RCTLog.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@
#import <Foundation/Foundation.h>

#import "RCTAssert.h"

#ifdef __cplusplus
extern "C" {
#endif
#import "RCTDefines.h"

/**
* Thresholds for logs to raise an assertion, or display redbox, respectively.
Expand Down Expand Up @@ -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
Expand All @@ -73,35 +70,35 @@ extern RCTLogFunction RCTDefaultLogFunction;
* below which logs will be ignored. Default is RCTLogLevelInfo for debug and
* RCTLogLevelError for production.
*/
void RCTSetLogThreshold(RCTLogLevel threshold);
RCTLogLevel RCTGetLogThreshold(void);
RCT_EXTERN void RCTSetLogThreshold(RCTLogLevel threshold);
RCT_EXTERN RCTLogLevel RCTGetLogThreshold(void);

/**
* 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
* functionality.
*/
void RCTSetLogFunction(RCTLogFunction logFunction);
RCTLogFunction RCTGetLogFunction(void);
RCT_EXTERN void RCTSetLogFunction(RCTLogFunction logFunction);
RCT_EXTERN RCTLogFunction RCTGetLogFunction(void);

/**
* This appends additional code to the existing log function, without replacing
* the existing functionality. Useful if you just want to forward logs to an
* 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
* of the passed block. This is useful for adding additional context to log
* 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.
*/
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 { \
if (lvl >= RCTLOG_FATAL_LEVEL) { RCTAssert(NO, __VA_ARGS__); } \
_RCTLogFormat(lvl, __FILE__, __LINE__, __VA_ARGS__); \
Expand All @@ -116,7 +113,3 @@ void _RCTLogFormat(RCTLogLevel, const char *, int, NSString *, ...) NS_FORMAT_FU
#define RCTLogWarn(...) _RCTLog(RCTLogLevelWarning, __VA_ARGS__)
#define RCTLogError(...) _RCTLog(RCTLogLevelError, __VA_ARGS__)
#define RCTLogMustFix(...) _RCTLog(RCTLogLevelMustFix, __VA_ARGS__)

#ifdef __cplusplus
}
#endif
Loading

0 comments on commit 8e15a0d

Please sign in to comment.