From 3f1a4535d99cf6673e912eced7fa1f4843757321 Mon Sep 17 00:00:00 2001 From: Kevin Gozali Date: Thu, 13 Aug 2020 14:49:52 -0700 Subject: [PATCH] Codegen Gradle: add toggle to activate JavaGenerator implementation Summary: JavaGenerator is a Java-based implementation for generating codegen output from the parsed schema file. Right now the output is a hardcoded Java file. In the next commits, proper JavaGenerator impl will be added. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D23100171 fbshipit-source-id: 1bef23e3dba4d8c222ebdece0edeb4435d388cd4 --- RNTester/android/app/build.gradle | 1 + ReactAndroid/build.gradle | 1 + .../codegen/generator/JavaGenerator.java | 23 +++++----- .../react/codegen/plugin/CodegenPlugin.java | 43 ++++++++++++++----- .../plugin/CodegenPluginExtension.java | 5 ++- 5 files changed, 49 insertions(+), 24 deletions(-) diff --git a/RNTester/android/app/build.gradle b/RNTester/android/app/build.gradle index 7e404cbd4a..bbb98e3f60 100644 --- a/RNTester/android/app/build.gradle +++ b/RNTester/android/app/build.gradle @@ -229,4 +229,5 @@ react { enableCodegen = System.getenv("USE_CODEGEN") ?: false jsRootDir = file("$rootDir/RNTester") reactNativeRootDir = file("$rootDir") + useJavaGenerator = System.getenv("USE_CODEGEN_JAVAPOET") ?: false } diff --git a/ReactAndroid/build.gradle b/ReactAndroid/build.gradle index 233a20974d..dacb1a1bff 100644 --- a/ReactAndroid/build.gradle +++ b/ReactAndroid/build.gradle @@ -476,4 +476,5 @@ react { enableCodegen = System.getenv("USE_CODEGEN") ?: false jsRootDir = file("../Libraries") reactNativeRootDir = file("$rootDir") + useJavaGenerator = System.getenv("USE_CODEGEN_JAVAPOET") ?: false } diff --git a/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/src/main/java/com/facebook/react/codegen/generator/JavaGenerator.java b/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/src/main/java/com/facebook/react/codegen/generator/JavaGenerator.java index 1ff7146e9e..885c14aef2 100644 --- a/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/src/main/java/com/facebook/react/codegen/generator/JavaGenerator.java +++ b/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/src/main/java/com/facebook/react/codegen/generator/JavaGenerator.java @@ -10,23 +10,24 @@ package com.facebook.react.codegen.generator; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.TypeSpec; +import java.io.File; import java.io.IOException; -import java.nio.file.Paths; import javax.lang.model.element.Modifier; // TODO: Implement proper generator - this is a sample usage of JavaPoet public final class JavaGenerator { + private final File mSchemaFile; + private final String mJavaPackageName; + private final File mOutputDir; - private String mSchemaFilePath; - private String mOutputDir; - - public JavaGenerator(String schemaFilePath, String outputDir) { - mSchemaFilePath = schemaFilePath; + public JavaGenerator(final File schemaFile, final String javaPackageName, final File outputDir) { + mSchemaFile = schemaFile; + mJavaPackageName = javaPackageName; mOutputDir = outputDir; } public void build() throws IOException { - MethodSpec main = + final MethodSpec main = MethodSpec.methodBuilder("main") .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .returns(void.class) @@ -34,18 +35,16 @@ public final class JavaGenerator { .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!") .build(); - TypeSpec helloWorld = + final TypeSpec helloWorld = TypeSpec.classBuilder("ReactNativeCodegen") .addModifiers(Modifier.PUBLIC, Modifier.FINAL) .addMethod(main) .build(); - JavaFile javaFile = JavaFile.builder("com.facebook.react.codegen", helloWorld).build(); + final JavaFile javaFile = JavaFile.builder(mJavaPackageName, helloWorld).build(); System.out.println(javaFile.toString()); - if (!mOutputDir.isEmpty()) { - javaFile.writeToPath(Paths.get(mOutputDir)); - } + javaFile.writeTo(mOutputDir); } } diff --git a/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/src/main/java/com/facebook/react/codegen/plugin/CodegenPlugin.java b/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/src/main/java/com/facebook/react/codegen/plugin/CodegenPlugin.java index f8584eff4f..1d355efd00 100644 --- a/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/src/main/java/com/facebook/react/codegen/plugin/CodegenPlugin.java +++ b/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/src/main/java/com/facebook/react/codegen/plugin/CodegenPlugin.java @@ -8,9 +8,11 @@ package com.facebook.react.codegen.plugin; import com.android.build.gradle.BaseExtension; +import com.facebook.react.codegen.generator.JavaGenerator; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import java.io.File; +import java.io.IOException; import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.Task; @@ -95,16 +97,25 @@ public class CodegenPlugin implements Plugin { task.getInputs().files(generatedSchemaFile); task.getOutputs().dir(outputDir); - ImmutableList execCommands = - new ImmutableList.Builder() - .add("yarn") - .addAll(ImmutableList.copyOf(extension.nodeExecutableAndArgs)) - .add(extension.codegenGenerateNativeModuleSpecsCLI().getAbsolutePath()) - .add("android") - .add(generatedSchemaFile.getAbsolutePath()) - .add(outputDir.getAbsolutePath()) - .build(); - task.commandLine(execCommands); + if (extension.useJavaGenerator) { + generateJavaFromSchemaWithJavaGenerator( + generatedSchemaFile, + extension.codegenJavaPackageName, + new File(generatedSrcDir, "java")); + // TODO: generate JNI C++ files. + task.commandLine("echo"); + } else { + ImmutableList execCommands = + new ImmutableList.Builder() + .add("yarn") + .addAll(ImmutableList.copyOf(extension.nodeExecutableAndArgs)) + .add(extension.codegenGenerateNativeModuleSpecsCLI().getAbsolutePath()) + .add("android") + .add(generatedSchemaFile.getAbsolutePath()) + .add(outputDir.getAbsolutePath()) + .build(); + task.commandLine(execCommands); + } }); // 4. Add dependencies & generated sources to the project. @@ -140,4 +151,16 @@ public class CodegenPlugin implements Plugin { // TODO: Add JNI sources. }); } + + // Use Java-based generator implementation to produce the source files, instead of using the + // JS-based generator. + private void generateJavaFromSchemaWithJavaGenerator( + final File schemaFile, final String javaPackageName, final File outputDir) { + final JavaGenerator generator = new JavaGenerator(schemaFile, javaPackageName, outputDir); + try { + generator.build(); + } catch (final IOException e) { + // Ignore for now. + } + } } diff --git a/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/src/main/java/com/facebook/react/codegen/plugin/CodegenPluginExtension.java b/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/src/main/java/com/facebook/react/codegen/plugin/CodegenPluginExtension.java index b368c6883d..658230bd45 100644 --- a/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/src/main/java/com/facebook/react/codegen/plugin/CodegenPluginExtension.java +++ b/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/src/main/java/com/facebook/react/codegen/plugin/CodegenPluginExtension.java @@ -13,12 +13,13 @@ import org.gradle.api.Project; public class CodegenPluginExtension { // TODO: Remove beta. public String codegenJavaPackageName = "com.facebook.fbreact.specs.beta"; - public boolean enableCodegen; + public boolean enableCodegen = false; public File jsRootDir; public String[] nodeExecutableAndArgs = {"node"}; public File reactNativeRootDir; + public boolean useJavaGenerator = false; - public CodegenPluginExtension(Project project) { + public CodegenPluginExtension(final Project project) { this.reactNativeRootDir = new File(project.getRootDir(), "node_modules/react-native"); }