treact-native] Export signature of methods
Summary: Creates a signature of the method that can be used for efficiently doing things based on the argument types. Reviewed By: astreet Differential Revision: D3147620 fb-gh-sync-id: da1419b96d61f5fc40861625d816c18b3c19b425 fbshipit-source-id: da1419b96d61f5fc40861625d816c18b3c19b425
This commit is contained in:
parent
9ad88c868f
commit
2c0f345cb8
|
@ -154,10 +154,11 @@ public abstract class BaseJavaModule implements NativeModule {
|
|||
}
|
||||
};
|
||||
|
||||
private class JavaMethod implements NativeMethod {
|
||||
public class JavaMethod implements NativeMethod {
|
||||
|
||||
private Method mMethod;
|
||||
private final ArgumentExtractor[] mArgumentExtractors;
|
||||
private final String mSignature;
|
||||
private final Object[] mArguments;
|
||||
private String mType = METHOD_TYPE_REMOTE;
|
||||
private final int mJSArgumentsNeeded;
|
||||
|
@ -167,6 +168,7 @@ public abstract class BaseJavaModule implements NativeModule {
|
|||
mMethod = method;
|
||||
Class[] parameterTypes = method.getParameterTypes();
|
||||
mArgumentExtractors = buildArgumentExtractors(parameterTypes);
|
||||
mSignature = buildSignature(parameterTypes);
|
||||
// Since native methods are invoked from a message queue executed on a single thread, it is
|
||||
// save to allocate only one arguments object per method that can be reused across calls
|
||||
mArguments = new Object[parameterTypes.length];
|
||||
|
@ -174,6 +176,75 @@ public abstract class BaseJavaModule implements NativeModule {
|
|||
mTraceName = BaseJavaModule.this.getName() + "." + mMethod.getName();
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return mMethod;
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
return mSignature;
|
||||
}
|
||||
|
||||
private String buildSignature(Class[] paramTypes) {
|
||||
StringBuilder builder = new StringBuilder(paramTypes.length);
|
||||
for (int i = 0; i < paramTypes.length; i++) {
|
||||
Class argumentClass = paramTypes[i];
|
||||
if (argumentClass == ExecutorToken.class) {
|
||||
if (!BaseJavaModule.this.supportsWebWorkers()) {
|
||||
throw new RuntimeException(
|
||||
"Module " + BaseJavaModule.this + " doesn't support web workers, but " +
|
||||
mMethod.getName() +
|
||||
" takes an ExecutorToken.");
|
||||
}
|
||||
|
||||
builder.append('T');
|
||||
} else if (argumentClass == boolean.class) {
|
||||
builder.append('z');
|
||||
} else if (argumentClass == Boolean.class) {
|
||||
builder.append('Z');
|
||||
} else if (argumentClass == int.class) {
|
||||
builder.append('i');
|
||||
} else if (argumentClass == Integer.class) {
|
||||
builder.append('I');
|
||||
} else if (argumentClass == double.class) {
|
||||
builder.append('d');
|
||||
} else if (argumentClass == Double.class) {
|
||||
builder.append('D');
|
||||
} else if (argumentClass == float.class) {
|
||||
builder.append('f');
|
||||
} else if (argumentClass == Float.class) {
|
||||
builder.append('F');
|
||||
} else if (argumentClass == String.class) {
|
||||
builder.append('S');
|
||||
} else if (argumentClass == Callback.class) {
|
||||
builder.append('X');
|
||||
} else if (argumentClass == Promise.class) {
|
||||
builder.append('P');
|
||||
Assertions.assertCondition(
|
||||
i == paramTypes.length - 1, "Promise must be used as last parameter only");
|
||||
mType = METHOD_TYPE_REMOTE_ASYNC;
|
||||
} else if (argumentClass == ReadableMap.class) {
|
||||
builder.append('M');
|
||||
} else if (argumentClass == ReadableArray.class) {
|
||||
builder.append('A');
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"Got unknown argument class: " + argumentClass.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
// Modules that support web workers are expected to take an ExecutorToken as the first
|
||||
// parameter to all their @ReactMethod-annotated methods.
|
||||
if (BaseJavaModule.this.supportsWebWorkers()) {
|
||||
if (builder.charAt(0) != 'T') {
|
||||
throw new RuntimeException(
|
||||
"Module " + BaseJavaModule.this + " supports web workers, but " + mMethod.getName() +
|
||||
"does not take an ExecutorToken as its first parameter.");
|
||||
}
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private ArgumentExtractor[] buildArgumentExtractors(Class[] paramTypes) {
|
||||
// Modules that support web workers are expected to take an ExecutorToken as the first
|
||||
// parameter to all their @ReactMethod-annotated methods. We compensate for that here.
|
||||
|
|
Loading…
Reference in New Issue