Codegen: Generate module C++ lookup function for JNI next to the spec classes
Summary: The TurboModule system requires a lookup function to map the spec name (name used in JS) to the C++ TurboModule subclass. This is a pure C function. For now, generate one lookup function per set of modules found in the codegen schema. Changelog: [Internal] Reviewed By: hramos Differential Revision: D23618281 fbshipit-source-id: 889e07bdd4f2e5e93c4d14e60225f5b0c6683917
This commit is contained in:
Родитель
e26c280782
Коммит
0351c57e6a
|
@ -23,6 +23,8 @@ project.xcworkspace
|
|||
|
||||
# Gradle
|
||||
/build/
|
||||
/packages/react-native-codegen/android/build/
|
||||
/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/build
|
||||
/packages/rn-tester/android/app/build/
|
||||
/packages/rn-tester/android/app/gradle/
|
||||
/packages/rn-tester/android/app/gradlew
|
||||
|
|
|
@ -105,20 +105,19 @@ public class CodegenPlugin implements Plugin<Project> {
|
|||
extension.codegenJavaPackageName,
|
||||
new File(generatedSrcDir, "java"));
|
||||
});
|
||||
// TODO: generate JNI C++ files.
|
||||
task.commandLine("echo");
|
||||
} else {
|
||||
ImmutableList<String> execCommands =
|
||||
new ImmutableList.Builder<String>()
|
||||
.add("yarn")
|
||||
.addAll(ImmutableList.copyOf(extension.nodeExecutableAndArgs))
|
||||
.add(extension.codegenGenerateNativeModuleSpecsCLI().getAbsolutePath())
|
||||
.add("android")
|
||||
.add(generatedSchemaFile.getAbsolutePath())
|
||||
.add(outputDir.getAbsolutePath())
|
||||
.build();
|
||||
task.commandLine(execCommands);
|
||||
}
|
||||
|
||||
ImmutableList<String> execCommands =
|
||||
new ImmutableList.Builder<String>()
|
||||
.add("yarn")
|
||||
.addAll(ImmutableList.copyOf(extension.nodeExecutableAndArgs))
|
||||
.add(extension.codegenGenerateNativeModuleSpecsCLI().getAbsolutePath())
|
||||
.add("android")
|
||||
.add(generatedSchemaFile.getAbsolutePath())
|
||||
.add(outputDir.getAbsolutePath())
|
||||
.add(extension.libraryName)
|
||||
.build();
|
||||
task.commandLine(execCommands);
|
||||
});
|
||||
|
||||
// 4. Add dependencies & generated sources to the project.
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
|
||||
package com.facebook.react.codegen.plugin;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
import java.io.File;
|
||||
import java.util.StringTokenizer;
|
||||
import org.gradle.api.Project;
|
||||
|
||||
public class CodegenPluginExtension {
|
||||
|
@ -15,12 +17,14 @@ public class CodegenPluginExtension {
|
|||
public String codegenJavaPackageName = "com.facebook.fbreact.specs.beta";
|
||||
public boolean enableCodegen = false;
|
||||
public File jsRootDir;
|
||||
public String libraryName;
|
||||
public String[] nodeExecutableAndArgs = {"node"};
|
||||
public File reactNativeRootDir;
|
||||
public boolean useJavaGenerator = false;
|
||||
|
||||
public CodegenPluginExtension(final Project project) {
|
||||
this.reactNativeRootDir = new File(project.getRootDir(), "node_modules/react-native");
|
||||
this.libraryName = projectPathToLibraryName(project.getPath());
|
||||
}
|
||||
|
||||
public File codegenDir() {
|
||||
|
@ -34,4 +38,16 @@ public class CodegenPluginExtension {
|
|||
public File codegenGenerateNativeModuleSpecsCLI() {
|
||||
return new File(this.reactNativeRootDir, "scripts/generate-native-modules-specs-cli.js");
|
||||
}
|
||||
|
||||
private String projectPathToLibraryName(final String projectPath) {
|
||||
final StringTokenizer tokenizer = new StringTokenizer(projectPath, ":-_.");
|
||||
final StringBuilder nameBuilder = new StringBuilder();
|
||||
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
nameBuilder.append(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, tokenizer.nextToken()));
|
||||
}
|
||||
nameBuilder.append("Spec");
|
||||
|
||||
return nameBuilder.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,10 @@ Native::_MODULE_NAME_::SpecJSI::Native::_MODULE_NAME_::SpecJSI(const JavaTurboMo
|
|||
::_PROPERTIES_MAP_::
|
||||
}`.trim();
|
||||
|
||||
const oneModuleLookupTemplate = ` if (moduleName == "::_MODULE_NAME_::") {
|
||||
return std::make_shared<Native::_MODULE_NAME_::SpecJSI>(params);
|
||||
}`;
|
||||
|
||||
const template = `
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
|
@ -61,6 +65,10 @@ namespace react {
|
|||
|
||||
::_MODULES_::
|
||||
|
||||
std::shared_ptr<TurboModule> ::_LIBRARY_NAME_::_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms) {
|
||||
::_MODULE_LOOKUP_::
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
`;
|
||||
|
@ -323,10 +331,17 @@ module.exports = {
|
|||
})
|
||||
.join('\n');
|
||||
|
||||
const moduleLookup = Object.keys(nativeModules)
|
||||
.map(name => {
|
||||
return oneModuleLookupTemplate.replace(/::_MODULE_NAME_::/g, name);
|
||||
})
|
||||
.join('\n');
|
||||
|
||||
const fileName = `${moduleSpecName}-generated.cpp`;
|
||||
const replacedTemplate = template
|
||||
.replace(/::_MODULES_::/g, modules)
|
||||
.replace(/::_LIBRARY_NAME_::/g, libraryName)
|
||||
.replace(/::_MODULE_LOOKUP_::/g, moduleLookup)
|
||||
.replace(/::_INCLUDE_::/g, `"${moduleSpecName}.h"`);
|
||||
return new Map([[fileName, replacedTemplate]]);
|
||||
},
|
||||
|
|
|
@ -43,6 +43,8 @@ namespace react {
|
|||
|
||||
::_MODULES_::
|
||||
|
||||
std::shared_ptr<TurboModule> ::_LIBRARY_NAME_::_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms);
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
`;
|
||||
|
@ -71,8 +73,9 @@ module.exports = {
|
|||
.join('\n');
|
||||
|
||||
const fileName = `${moduleSpecName}.h`;
|
||||
const replacedTemplate = template.replace(/::_MODULES_::/g, modules);
|
||||
|
||||
const replacedTemplate = template
|
||||
.replace(/::_MODULES_::/g, modules)
|
||||
.replace(/::_LIBRARY_NAME_::/g, libraryName);
|
||||
return new Map([[fileName, replacedTemplate]]);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -42,6 +42,12 @@ NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const JavaTurboMo
|
|||
methodMap_[\\"getArrays\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getArrays};
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule> COMPLEX_OBJECTS_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms) {
|
||||
if (moduleName == \\"SampleTurboModule\\") {
|
||||
return std::make_shared<NativeSampleTurboModuleSpecJSI>(params);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
|
@ -72,6 +78,12 @@ NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const JavaTurboMo
|
|||
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule> EMPTY_NATIVE_MODULES_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms) {
|
||||
if (moduleName == \\"SampleTurboModule\\") {
|
||||
return std::make_shared<NativeSampleTurboModuleSpecJSI>(params);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
|
@ -107,6 +119,12 @@ NativeAliasTurboModuleSpecJSI::NativeAliasTurboModuleSpecJSI(const JavaTurboModu
|
|||
methodMap_[\\"cropImage\\"] = MethodMetadata {1, __hostFunction_NativeAliasTurboModuleSpecJSI_cropImage};
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule> NATIVE_MODULES_WITH_TYPE_ALIASES_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms) {
|
||||
if (moduleName == \\"AliasTurboModule\\") {
|
||||
return std::make_shared<NativeAliasTurboModuleSpecJSI>(params);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
|
@ -190,6 +208,18 @@ NativeExceptionsManagerSpecJSI::NativeExceptionsManagerSpecJSI(const JavaTurboMo
|
|||
methodMap_[\\"dismissRedbox\\"] = MethodMetadata {0, __hostFunction_NativeExceptionsManagerSpecJSI_dismissRedbox};
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule> REAL_MODULE_EXAMPLE_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms) {
|
||||
if (moduleName == \\"CameraRollManager\\") {
|
||||
return std::make_shared<NativeCameraRollManagerSpecJSI>(params);
|
||||
}
|
||||
if (moduleName == \\"ImagePickerIOS\\") {
|
||||
return std::make_shared<NativeImagePickerIOSSpecJSI>(params);
|
||||
}
|
||||
if (moduleName == \\"ExceptionsManager\\") {
|
||||
return std::make_shared<NativeExceptionsManagerSpecJSI>(params);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
|
@ -273,6 +303,12 @@ NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const JavaTurboMo
|
|||
methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise};
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule> SIMPLE_NATIVE_MODULES_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms) {
|
||||
if (moduleName == \\"SampleTurboModule\\") {
|
||||
return std::make_shared<NativeSampleTurboModuleSpecJSI>(params);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
|
@ -317,6 +353,15 @@ NativeSample2TurboModuleSpecJSI::NativeSample2TurboModuleSpecJSI(const JavaTurbo
|
|||
methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc};
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule> TWO_MODULES_DIFFERENT_FILES_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms) {
|
||||
if (moduleName == \\"SampleTurboModule\\") {
|
||||
return std::make_shared<NativeSampleTurboModuleSpecJSI>(params);
|
||||
}
|
||||
if (moduleName == \\"Sample2TurboModule\\") {
|
||||
return std::make_shared<NativeSample2TurboModuleSpecJSI>(params);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
|
@ -359,6 +404,15 @@ NativeSample2TurboModuleSpecJSI::NativeSample2TurboModuleSpecJSI(const JavaTurbo
|
|||
methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc};
|
||||
}
|
||||
|
||||
std::shared_ptr<TurboModule> TWO_MODULES_SAME_FILE_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms) {
|
||||
if (moduleName == \\"SampleTurboModule\\") {
|
||||
return std::make_shared<NativeSampleTurboModuleSpecJSI>(params);
|
||||
}
|
||||
if (moduleName == \\"Sample2TurboModule\\") {
|
||||
return std::make_shared<NativeSample2TurboModuleSpecJSI>(params);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
|
|
|
@ -29,6 +29,8 @@ public:
|
|||
};
|
||||
|
||||
|
||||
std::shared_ptr<TurboModule> COMPLEX_OBJECTS_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms);
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
|
@ -64,6 +66,8 @@ public:
|
|||
};
|
||||
|
||||
|
||||
std::shared_ptr<TurboModule> EMPTY_NATIVE_MODULES_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms);
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
|
@ -99,6 +103,8 @@ public:
|
|||
};
|
||||
|
||||
|
||||
std::shared_ptr<TurboModule> NATIVE_MODULES_WITH_TYPE_ALIASES_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms);
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
|
@ -150,6 +156,8 @@ public:
|
|||
};
|
||||
|
||||
|
||||
std::shared_ptr<TurboModule> REAL_MODULE_EXAMPLE_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms);
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
|
@ -185,6 +193,8 @@ public:
|
|||
};
|
||||
|
||||
|
||||
std::shared_ptr<TurboModule> SIMPLE_NATIVE_MODULES_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms);
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
|
@ -228,6 +238,8 @@ public:
|
|||
};
|
||||
|
||||
|
||||
std::shared_ptr<TurboModule> TWO_MODULES_DIFFERENT_FILES_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms);
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
|
@ -271,6 +283,8 @@ public:
|
|||
};
|
||||
|
||||
|
||||
std::shared_ptr<TurboModule> TWO_MODULES_SAME_FILE_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms);
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
|
|
|
@ -15,9 +15,8 @@ const mkdirp = require('mkdirp');
|
|||
const os = require('os');
|
||||
const path = require('path');
|
||||
|
||||
function generateSpec(platform, schemaPath, outputDirectory) {
|
||||
const libraryName = 'FBReactNativeSpec';
|
||||
const moduleSpecName = 'FBReactNativeSpec';
|
||||
function generateSpec(platform, schemaPath, outputDirectory, libraryName) {
|
||||
const moduleSpecName = libraryName;
|
||||
const schemaText = fs.readFileSync(schemaPath, 'utf-8');
|
||||
|
||||
if (schemaText == null) {
|
||||
|
@ -97,7 +96,8 @@ function main() {
|
|||
const platform = args[0];
|
||||
const schemaPath = args[1];
|
||||
const outputDir = args[2];
|
||||
generateSpec(platform, schemaPath, outputDir);
|
||||
const libraryName = args[3] || 'FBReactNativeSpec';
|
||||
generateSpec(platform, schemaPath, outputDir, libraryName);
|
||||
}
|
||||
|
||||
main();
|
||||
|
|
Загрузка…
Ссылка в новой задаче