Remove the unused JavaGenerator from the React Native Gradle Plugin.
Summary: I'm removing the Java generation as we're not using it for now, and we're not maintaining it. Moreover is not feature complete, and still needs `react-native-codegen` to generate the Makefile/CMake/C++ code. We can still resort it if we decide to switch to AST based generation. Changelog: [Internal] [Changed] - Remove the unused JavaGenerator from the React Native Gradle Plugin Reviewed By: cipolleschi Differential Revision: D35930746 fbshipit-source-id: 624c411cdc678b270a647efc3cc8236b50018bef
This commit is contained in:
Родитель
0c4c6ca319
Коммит
63acead781
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.CodegenException;
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.facebook.react.codegen.generator.resolver.ResolvedType;
|
||||
import com.facebook.react.codegen.generator.resolver.TypeResolver;
|
||||
import com.squareup.javapoet.JavaFile;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Given a react-native-codegen JSON schema, generate a set of .java files for React Native. The
|
||||
* generator is isolated to a single schema, and a single Java package output.
|
||||
*/
|
||||
public final class JavaGenerator {
|
||||
public static final String LICENSE_HEADER =
|
||||
"/*\n"
|
||||
+ " * Copyright (c) Meta Platforms, Inc. and affiliates.\n"
|
||||
+ " *\n"
|
||||
+ " * This source code is licensed under the MIT license found in the\n"
|
||||
+ " * LICENSE file in the root directory of this source tree.\n"
|
||||
+ " *\n"
|
||||
+ " * Generated by react-native-codegen JavaGenerator.\n"
|
||||
+ " *\n"
|
||||
+ " * @"
|
||||
+ "generated\n"
|
||||
+ " * @"
|
||||
+ "nolint\n"
|
||||
+ " */\n\n";
|
||||
private final File mSchemaFile;
|
||||
private final String mJavaPackageName;
|
||||
private final File mOutputDir;
|
||||
|
||||
public JavaGenerator(final File schemaFile, final String javaPackageName, final File outputDir) {
|
||||
mSchemaFile = schemaFile;
|
||||
mJavaPackageName = javaPackageName;
|
||||
mOutputDir = outputDir;
|
||||
}
|
||||
|
||||
public void build() throws CodegenException, FileNotFoundException, IOException {
|
||||
// Step 1: Given a schema JSON, collect all types.
|
||||
final TypeData typeData = SchemaJsonParser.parse(mSchemaFile);
|
||||
|
||||
// Step 2: Resolve each type, then collect those that produce a class or interface (TypeSpec).
|
||||
final List<TypeSpec> typeSpecsToWrite =
|
||||
typeData.getAllTypes().stream()
|
||||
.map(
|
||||
t -> {
|
||||
final ResolvedType resolvedType =
|
||||
TypeResolver.resolveType(typeData.getType(t), typeData, false);
|
||||
final TypeSpec spec = resolvedType.getGeneratedCode(mJavaPackageName);
|
||||
return spec;
|
||||
})
|
||||
.filter(f -> f != null)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Step 3: Write all of the TypeSpec's into the output directory.
|
||||
for (final TypeSpec typeSpec : typeSpecsToWrite) {
|
||||
writeTypeSpecToFile(typeSpec);
|
||||
}
|
||||
}
|
||||
|
||||
private final void writeTypeSpecToFile(final TypeSpec typeSpec)
|
||||
throws CodegenException, IOException {
|
||||
JavaFile file = JavaFile.builder(mJavaPackageName, typeSpec).skipJavaLangImports(true).build();
|
||||
|
||||
// Instead of using JavaFile.writeTo() API, manage the output files ourselves because
|
||||
// JavaFile.addFileComment() does not support "block comment" style.
|
||||
// See https://github.com/square/javapoet/issues/682#issuecomment-512238075.
|
||||
Path outputDirPath = new File(mOutputDir, "java").toPath();
|
||||
|
||||
if (Files.exists(outputDirPath) && !Files.isDirectory(outputDirPath)) {
|
||||
throw new CodegenException(
|
||||
"Output path " + outputDirPath + " exists but is not a directory.");
|
||||
}
|
||||
|
||||
if (!mJavaPackageName.isEmpty()) {
|
||||
for (String packageComponent : mJavaPackageName.split("\\.")) {
|
||||
outputDirPath = outputDirPath.resolve(packageComponent);
|
||||
}
|
||||
Files.createDirectories(outputDirPath);
|
||||
}
|
||||
|
||||
Path outputPath = outputDirPath.resolve(typeSpec.name + ".java");
|
||||
try (Writer writer = new OutputStreamWriter(Files.newOutputStream(outputPath), UTF_8)) {
|
||||
writer.write(LICENSE_HEADER + file.toString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,275 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.AliasType;
|
||||
import com.facebook.react.codegen.generator.model.AnyType;
|
||||
import com.facebook.react.codegen.generator.model.ArrayType;
|
||||
import com.facebook.react.codegen.generator.model.BooleanType;
|
||||
import com.facebook.react.codegen.generator.model.CodegenException;
|
||||
import com.facebook.react.codegen.generator.model.DoubleType;
|
||||
import com.facebook.react.codegen.generator.model.FloatType;
|
||||
import com.facebook.react.codegen.generator.model.FunctionType;
|
||||
import com.facebook.react.codegen.generator.model.GenericObjectType;
|
||||
import com.facebook.react.codegen.generator.model.Int32Type;
|
||||
import com.facebook.react.codegen.generator.model.NativeModuleType;
|
||||
import com.facebook.react.codegen.generator.model.NullableType;
|
||||
import com.facebook.react.codegen.generator.model.NumberType;
|
||||
import com.facebook.react.codegen.generator.model.ObjectType;
|
||||
import com.facebook.react.codegen.generator.model.PromiseType;
|
||||
import com.facebook.react.codegen.generator.model.ReservedFunctionValueType;
|
||||
import com.facebook.react.codegen.generator.model.StringType;
|
||||
import com.facebook.react.codegen.generator.model.Type;
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.facebook.react.codegen.generator.model.TypeId;
|
||||
import com.facebook.react.codegen.generator.model.VoidType;
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class SchemaJsonParser {
|
||||
private final TypeData mTypeData = new TypeData();
|
||||
|
||||
public static TypeData parse(final File schemaFile)
|
||||
throws CodegenException, FileNotFoundException, IOException {
|
||||
final SchemaJsonParser parser = new SchemaJsonParser();
|
||||
return parser.buildTypeData(schemaFile);
|
||||
}
|
||||
|
||||
private TypeData buildTypeData(final File schemaFile)
|
||||
throws CodegenException, FileNotFoundException, IOException {
|
||||
final JsonParser parser = new JsonParser();
|
||||
final JsonElement rootElement = parser.parse(new FileReader(schemaFile));
|
||||
|
||||
final Map<String, Map<String, NativeModuleType>> collection = new HashMap<>();
|
||||
|
||||
if (rootElement.isJsonObject()) {
|
||||
final JsonObject root = rootElement.getAsJsonObject();
|
||||
final JsonObject modules = root.getAsJsonObject("modules");
|
||||
modules
|
||||
.entrySet()
|
||||
.forEach(
|
||||
entry -> {
|
||||
final String jsModuleName = entry.getKey();
|
||||
final JsonObject jsModule = entry.getValue().getAsJsonObject();
|
||||
final String jsModuleType = jsModule.get("type").getAsString();
|
||||
|
||||
if (!"NativeModule".equals(jsModuleType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (jsModule.has("excludedPlatforms")) {
|
||||
final JsonArray excludedPlatforms = jsModule.getAsJsonArray("excludedPlatforms");
|
||||
for (JsonElement p : excludedPlatforms) {
|
||||
if (p.getAsString().equals("android")) {
|
||||
// This module is not for Android.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Type parsedType =
|
||||
parseNativeModule(
|
||||
// TODO (T71955395): NativeModule spec type name does not
|
||||
// exist in the schema. For now assume it's "Spec".
|
||||
// The final type name will be the output class name.
|
||||
TypeId.of(jsModuleName, jsModuleName + "Spec"), jsModule);
|
||||
mTypeData.addType(parsedType);
|
||||
});
|
||||
}
|
||||
|
||||
return mTypeData;
|
||||
}
|
||||
|
||||
// Parse type information from a JSON "typeAnnotation" node.
|
||||
private Type parseTypeAnnotation(final TypeId typeId, final JsonObject originalTypeAnnotation) {
|
||||
JsonObject typeAnnotation = originalTypeAnnotation;
|
||||
String type = typeAnnotation.get("type").getAsString();
|
||||
boolean nullable = false;
|
||||
Type parsedType = null;
|
||||
|
||||
if (type.equals(NullableType.TYPE_NAME)) {
|
||||
nullable = true;
|
||||
typeAnnotation = typeAnnotation.get("typeAnnotation").getAsJsonObject();
|
||||
type = typeAnnotation.get("type").getAsString();
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case AliasType.TYPE_NAME:
|
||||
parsedType = parseAliasTypeAnnotation(typeId, typeAnnotation);
|
||||
break;
|
||||
case AnyType.TYPE_NAME:
|
||||
parsedType = new AnyType(typeId);
|
||||
break;
|
||||
case ArrayType.TYPE_NAME:
|
||||
parsedType = parseArrayTypeAnnotation(typeId, typeAnnotation);
|
||||
break;
|
||||
case BooleanType.TYPE_NAME:
|
||||
parsedType = new BooleanType(typeId);
|
||||
break;
|
||||
case DoubleType.TYPE_NAME:
|
||||
parsedType = new DoubleType(typeId);
|
||||
break;
|
||||
case FloatType.TYPE_NAME:
|
||||
parsedType = new FloatType(typeId);
|
||||
break;
|
||||
case FunctionType.TYPE_NAME:
|
||||
parsedType = parseFunctionTypeAnnotation(typeId, typeAnnotation);
|
||||
break;
|
||||
case GenericObjectType.TYPE_NAME:
|
||||
parsedType = new GenericObjectType(typeId);
|
||||
break;
|
||||
case Int32Type.TYPE_NAME:
|
||||
parsedType = new Int32Type(typeId);
|
||||
break;
|
||||
case NumberType.TYPE_NAME:
|
||||
// Use double type for generic numbers.
|
||||
parsedType = new DoubleType(typeId);
|
||||
break;
|
||||
case ObjectType.TYPE_NAME:
|
||||
parsedType = parseObjectTypeAnnotation(typeId, typeAnnotation);
|
||||
break;
|
||||
case PromiseType.TYPE_NAME:
|
||||
parsedType = new PromiseType(typeId);
|
||||
break;
|
||||
case ReservedFunctionValueType.TYPE_NAME:
|
||||
parsedType = parseReservedFunctionValueTypeAnnotation(typeId, typeAnnotation);
|
||||
break;
|
||||
case StringType.TYPE_NAME:
|
||||
parsedType = new StringType(typeId);
|
||||
break;
|
||||
case VoidType.TYPE_NAME:
|
||||
return VoidType.VOID;
|
||||
default:
|
||||
throw new CodegenException("Found invalid type annotation: " + type);
|
||||
}
|
||||
|
||||
final Type finalType = maybeCreateNullableType(nullable, parsedType);
|
||||
mTypeData.addType(finalType);
|
||||
return finalType;
|
||||
}
|
||||
|
||||
private NativeModuleType parseNativeModule(final TypeId typeId, final JsonObject json) {
|
||||
final JsonObject aliases = json.getAsJsonObject("aliases");
|
||||
final JsonArray properties = json.getAsJsonObject("spec").getAsJsonArray("properties");
|
||||
|
||||
final ImmutableList<Type> collectedAliases =
|
||||
ImmutableList.copyOf(
|
||||
aliases.entrySet().stream()
|
||||
.map(
|
||||
entry -> {
|
||||
final String typeName = entry.getKey();
|
||||
final JsonObject typeAnnotation = entry.getValue().getAsJsonObject();
|
||||
// The alias name is the type name that other types can refer to.
|
||||
return parseTypeAnnotation(
|
||||
TypeId.of(typeId.moduleName, typeName), typeAnnotation);
|
||||
})
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
ImmutableList.Builder<NativeModuleType.Property> collectedPropertiesBuilder =
|
||||
new ImmutableList.Builder<>();
|
||||
properties.forEach(
|
||||
p -> {
|
||||
final JsonObject node = p.getAsJsonObject();
|
||||
final String name = node.get("name").getAsString();
|
||||
final JsonObject typeAnnotation = node.getAsJsonObject("typeAnnotation");
|
||||
final boolean optional = node.get("optional").getAsBoolean();
|
||||
final TypeId propertyTypeId =
|
||||
TypeId.expandOf(typeId, CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, name));
|
||||
collectedPropertiesBuilder.add(
|
||||
new NativeModuleType.Property(
|
||||
name, parseTypeAnnotation(propertyTypeId, typeAnnotation), optional));
|
||||
});
|
||||
|
||||
return new NativeModuleType(typeId, collectedAliases, collectedPropertiesBuilder.build());
|
||||
}
|
||||
|
||||
private Type parseAliasTypeAnnotation(final TypeId typeId, final JsonObject typeAnnotation) {
|
||||
// For now, assume the alias lives inside the same file.
|
||||
return new AliasType(
|
||||
typeId, TypeId.of(typeId.moduleName, typeAnnotation.get("name").getAsString()));
|
||||
}
|
||||
|
||||
private Type parseArrayTypeAnnotation(final TypeId typeId, final JsonObject typeAnnotation) {
|
||||
final JsonObject elementTypeAnnotation = typeAnnotation.getAsJsonObject("elementType");
|
||||
final TypeId elementTypeId = TypeId.expandOf(typeId, "ElementType");
|
||||
// TODO (T71847026): Some array types are missing elementType annotation.
|
||||
final Type elementType =
|
||||
elementTypeAnnotation != null
|
||||
? parseTypeAnnotation(elementTypeId, elementTypeAnnotation)
|
||||
: new AnyType(elementTypeId);
|
||||
return new ArrayType(typeId, elementType);
|
||||
}
|
||||
|
||||
private Type parseFunctionTypeAnnotation(final TypeId typeId, final JsonObject typeAnnotation) {
|
||||
final JsonArray params = typeAnnotation.getAsJsonArray("params");
|
||||
|
||||
ImmutableList.Builder<FunctionType.ArgumentType> paramsList = new ImmutableList.Builder<>();
|
||||
|
||||
for (int i = 0; i < params.size(); i++) {
|
||||
final JsonElement p = params.get(i);
|
||||
final JsonObject node = p.getAsJsonObject();
|
||||
final String name = node.get("name").getAsString();
|
||||
paramsList.add(
|
||||
FunctionType.createArgument(
|
||||
name,
|
||||
parseTypeAnnotation(
|
||||
TypeId.expandOf(typeId, CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, name)),
|
||||
node.getAsJsonObject("typeAnnotation"))));
|
||||
}
|
||||
|
||||
final JsonObject returnTypeAnnotation = typeAnnotation.getAsJsonObject("returnTypeAnnotation");
|
||||
final Type returnType =
|
||||
parseTypeAnnotation(TypeId.expandOf(typeId, "ReturnType"), returnTypeAnnotation);
|
||||
|
||||
return new FunctionType(typeId, paramsList.build(), returnType);
|
||||
}
|
||||
|
||||
private Type parseObjectTypeAnnotation(final TypeId typeId, final JsonObject typeAnnotation) {
|
||||
final JsonArray properties = typeAnnotation.getAsJsonArray("properties");
|
||||
|
||||
ImmutableList.Builder<ObjectType.Property> propertiesList = new ImmutableList.Builder<>();
|
||||
properties.forEach(
|
||||
p -> {
|
||||
final JsonObject node = p.getAsJsonObject();
|
||||
final String name = node.get("name").getAsString();
|
||||
final boolean optional = node.get("optional").getAsBoolean();
|
||||
final JsonObject propertyTypeAnnotation = node.getAsJsonObject("typeAnnotation");
|
||||
final TypeId propertyTypeId =
|
||||
TypeId.expandOf(typeId, CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, name));
|
||||
final Type propertyType = parseTypeAnnotation(propertyTypeId, propertyTypeAnnotation);
|
||||
propertiesList.add(new ObjectType.Property(name, propertyType, optional));
|
||||
});
|
||||
|
||||
return new ObjectType(typeId, propertiesList.build());
|
||||
}
|
||||
|
||||
private Type parseReservedFunctionValueTypeAnnotation(
|
||||
final TypeId typeId, final JsonObject typeAnnotation) {
|
||||
return new ReservedFunctionValueType(
|
||||
typeId,
|
||||
ReservedFunctionValueType.ReservedName.valueOf(typeAnnotation.get("name").getAsString()));
|
||||
}
|
||||
|
||||
private Type maybeCreateNullableType(final boolean nullable, final Type original) {
|
||||
if (!nullable || original instanceof VoidType) {
|
||||
return original;
|
||||
}
|
||||
return new NullableType(TypeId.of(original.getTypeId()), original);
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
public final class AliasType extends Type {
|
||||
public static final String TYPE_NAME = "TypeAliasTypeAnnotation";
|
||||
|
||||
public final TypeId referredTypeId;
|
||||
|
||||
public AliasType(final TypeId typeId, final TypeId referredTypeId) {
|
||||
super(typeId);
|
||||
this.referredTypeId = referredTypeId;
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
public final class AnyType extends Type {
|
||||
public static final String TYPE_NAME = "AnyTypeAnnotation";
|
||||
|
||||
public AnyType(final TypeId typeId) {
|
||||
super(typeId);
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
public final class ArrayType extends Type {
|
||||
public static final String TYPE_NAME = "ArrayTypeAnnotation";
|
||||
|
||||
public final Type elementType;
|
||||
|
||||
public ArrayType(final TypeId typeId, final Type elementType) {
|
||||
super(typeId);
|
||||
this.elementType = elementType;
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
public final class BooleanType extends Type {
|
||||
public static final String TYPE_NAME = "BooleanTypeAnnotation";
|
||||
|
||||
public BooleanType(final TypeId typeId) {
|
||||
super(typeId);
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
public class CodegenException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public CodegenException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
public final class DoubleType extends NumberType {
|
||||
public static final String TYPE_NAME = "DoubleTypeAnnotation";
|
||||
|
||||
public DoubleType(final TypeId typeId) {
|
||||
super(typeId);
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
public final class FloatType extends NumberType {
|
||||
public static final String TYPE_NAME = "FloatTypeAnnotation";
|
||||
|
||||
public FloatType(final TypeId typeId) {
|
||||
super(typeId);
|
||||
}
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class FunctionType extends Type {
|
||||
public static final String TYPE_NAME = "FunctionTypeAnnotation";
|
||||
|
||||
public static class ArgumentType {
|
||||
public final String name;
|
||||
public final Type type;
|
||||
|
||||
// Note: Function argument is not optional.
|
||||
// TODO (T71926678): Revisit if optional should be supported.
|
||||
private ArgumentType(String name, Type type) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ArgumentType that = (ArgumentType) o;
|
||||
return Objects.equals(this.name, that.name) && Objects.equals(this.type, that.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + ": " + type;
|
||||
}
|
||||
}
|
||||
|
||||
public static ArgumentType createArgument(String name, Type type) {
|
||||
return new ArgumentType(name, type);
|
||||
}
|
||||
|
||||
public final List<ArgumentType> parameters;
|
||||
public final Type returnType;
|
||||
|
||||
public FunctionType(
|
||||
final TypeId typeId, final List<ArgumentType> parameters, final Type returnType) {
|
||||
super(typeId);
|
||||
this.parameters = Collections.unmodifiableList(parameters);
|
||||
this.returnType = returnType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass() || !super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final FunctionType that = (FunctionType) o;
|
||||
return Objects.equals(this.parameters, that.parameters)
|
||||
&& Objects.equals(this.returnType, that.returnType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), parameters, returnType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + returnType + ")" + this.getTypeId() + "(" + parameters + ")";
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
public final class GenericObjectType extends Type {
|
||||
public static final String TYPE_NAME = "GenericObjectTypeAnnotation";
|
||||
|
||||
public GenericObjectType(final TypeId typeId) {
|
||||
super(typeId);
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
public final class Int32Type extends NumberType {
|
||||
public static final String TYPE_NAME = "Int32TypeAnnotation";
|
||||
|
||||
public Int32Type(final TypeId typeId) {
|
||||
super(typeId);
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public final class NativeModuleType extends Type {
|
||||
public static String TYPE_NAME = "<NONE>"; // Not an actual type in the schema.
|
||||
|
||||
public final List<Type> aliases;
|
||||
public final List<Property> properties;
|
||||
|
||||
public static class Property {
|
||||
public final String name;
|
||||
public final FunctionType type;
|
||||
public final boolean optional;
|
||||
|
||||
public Property(final String name, final Type type, final boolean optional) {
|
||||
assertType(type, FunctionType.class);
|
||||
this.name = name;
|
||||
this.type = (FunctionType) type;
|
||||
this.optional = optional;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + ": " + (this.optional ? "?" : "") + type;
|
||||
}
|
||||
}
|
||||
|
||||
public NativeModuleType(
|
||||
final TypeId typeId, final List<Type> aliases, final List<Property> properties) {
|
||||
super(typeId);
|
||||
this.aliases = Collections.unmodifiableList(aliases);
|
||||
this.properties = Collections.unmodifiableList(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getTypeId() + "\n aliases: " + aliases + "\n properties: " + properties;
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
public final class NullableType extends Type {
|
||||
public static final String TYPE_NAME = "NullableTypeAnnotation";
|
||||
|
||||
public final Type innerType;
|
||||
|
||||
public NullableType(final TypeId typeId, final Type innerType) {
|
||||
super(typeId);
|
||||
this.innerType = innerType;
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
public abstract class NumberType extends Type {
|
||||
public static final String TYPE_NAME = "NumberTypeAnnotation";
|
||||
|
||||
public NumberType(final TypeId typeId) {
|
||||
super(typeId);
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public final class ObjectType extends Type {
|
||||
public static final String TYPE_NAME = "ObjectTypeAnnotation";
|
||||
|
||||
public static class Property {
|
||||
public final String name;
|
||||
public final Type type;
|
||||
public final boolean optional;
|
||||
|
||||
public Property(String name, Type type, boolean optional) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.optional = optional;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return (optional ? "?" : "") + name + ": " + type;
|
||||
}
|
||||
}
|
||||
|
||||
public final List<Property> properties;
|
||||
|
||||
public ObjectType(final TypeId typeId, final List<Property> properties) {
|
||||
super(typeId);
|
||||
this.properties = Collections.unmodifiableList(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getTypeId() + " -> " + properties;
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
public final class PromiseType extends Type {
|
||||
public static final String TYPE_NAME = "PromiseTypeAnnotation";
|
||||
|
||||
public PromiseType(final TypeId typeId) {
|
||||
super(typeId);
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
public final class ReservedFunctionValueType extends Type {
|
||||
public static final String TYPE_NAME = "ReservedFunctionValueTypeAnnotation";
|
||||
|
||||
public enum ReservedName {
|
||||
RootTag,
|
||||
}
|
||||
|
||||
public ReservedName reservedName;
|
||||
|
||||
public ReservedFunctionValueType(final TypeId typeId, ReservedName reservedName) {
|
||||
super(typeId);
|
||||
this.reservedName = reservedName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mTypeId + "(" + reservedName.toString() + ")";
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
public final class StringType extends Type {
|
||||
public static final String TYPE_NAME = "StringTypeAnnotation";
|
||||
|
||||
public StringType(final TypeId typeId) {
|
||||
super(typeId);
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class Type {
|
||||
public static String TYPE_NAME = "<NONE>";
|
||||
|
||||
protected final TypeId mTypeId;
|
||||
|
||||
public static <T extends Type> void assertType(
|
||||
final Type type, final Class<T> expectedTypeClass) {
|
||||
if (!expectedTypeClass.isInstance(type)) {
|
||||
throw new IllegalStateException(
|
||||
"Expected: " + expectedTypeClass.getName() + " but found: " + type.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
public Type(final TypeId typeId) {
|
||||
mTypeId = typeId;
|
||||
}
|
||||
|
||||
public TypeId getTypeId() {
|
||||
return mTypeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mTypeId.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final Type type = (Type) o;
|
||||
return Objects.equals(mTypeId, type.mTypeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mTypeId);
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/** A collection of all types information based on the parsed schema. */
|
||||
public final class TypeData {
|
||||
private final Map<TypeId, Type> mTypes = new HashMap<>();
|
||||
|
||||
public void addType(final TypeId typeId, final Type type) throws IllegalStateException {
|
||||
if (getType(typeId) != null) {
|
||||
throw new IllegalStateException("Found duplicated TypeId: " + typeId + " for: " + type);
|
||||
}
|
||||
mTypes.put(typeId, type);
|
||||
}
|
||||
|
||||
public void addType(final Type type) {
|
||||
addType(type.getTypeId(), type);
|
||||
}
|
||||
|
||||
public @Nullable Type getType(final TypeId typeId) {
|
||||
return mTypes.get(typeId);
|
||||
}
|
||||
|
||||
public Set<TypeId> getAllTypes() {
|
||||
return mTypes.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
mTypes.forEach(
|
||||
(k, v) -> {
|
||||
builder.append(v.toString());
|
||||
builder.append("\n");
|
||||
});
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
import java.util.Objects;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/** Represents the fully qualified name for a Flow type. */
|
||||
public final class TypeId {
|
||||
public final String moduleName;
|
||||
public final String typeName;
|
||||
|
||||
private static final String EMPTY_TYPE_NAME = "";
|
||||
|
||||
private TypeId(final String moduleName, final String typeName) {
|
||||
this.moduleName = moduleName;
|
||||
this.typeName = typeName;
|
||||
}
|
||||
|
||||
public static TypeId of(final String moduleName) {
|
||||
return new TypeId(moduleName, EMPTY_TYPE_NAME);
|
||||
}
|
||||
|
||||
public static TypeId of(final String moduleName, @Nullable final String typeName) {
|
||||
if (typeName == null) {
|
||||
return TypeId.of(moduleName);
|
||||
}
|
||||
|
||||
if (moduleName.equals(typeName)) {
|
||||
return TypeId.of(moduleName);
|
||||
}
|
||||
|
||||
return new TypeId(moduleName, typeName);
|
||||
}
|
||||
|
||||
public static TypeId of(final TypeId typeId) {
|
||||
return of(typeId.moduleName, typeId.typeName);
|
||||
}
|
||||
|
||||
public static TypeId expandOf(final TypeId typeId, String suffix) {
|
||||
return of(typeId.moduleName, typeId.typeName + suffix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"<moduleName = %s, typeName = %s>",
|
||||
moduleName, EMPTY_TYPE_NAME.equals(typeName) ? "\"\"" : typeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final TypeId typeId = (TypeId) o;
|
||||
return Objects.equals(moduleName, typeId.moduleName)
|
||||
&& Objects.equals(typeName, typeId.typeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(moduleName, typeName);
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.model;
|
||||
|
||||
public final class VoidType extends Type {
|
||||
public static final String TYPE_NAME = "VoidTypeAnnotation";
|
||||
public static final VoidType VOID = new VoidType(TypeId.of(""));
|
||||
|
||||
private VoidType(final TypeId typeId) {
|
||||
super(typeId);
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.AliasType;
|
||||
import com.facebook.react.codegen.generator.model.AnyType;
|
||||
import com.facebook.react.codegen.generator.model.Type;
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class AliasResolvedType extends ResolvedType<AliasType> {
|
||||
|
||||
private AliasResolvedType(final AliasType type, final boolean nullable) {
|
||||
super(type, nullable);
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public static ResolvedType create(
|
||||
final AliasType type, final TypeData typeData, final boolean nullable) {
|
||||
Type referredType = typeData.getType(type.referredTypeId);
|
||||
if (referredType != null) {
|
||||
return resolveType(referredType, typeData, nullable);
|
||||
}
|
||||
return resolveType(new AnyType(type.getTypeId()), typeData, nullable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeName getNativeType(final NativeTypeContext typeContext) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable TypeSpec getGeneratedCode(final String packageName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.squareup.javapoet.AnnotationSpec;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class Annotations {
|
||||
public static final AnnotationSpec OVERRIDE = AnnotationSpec.builder(Override.class).build();
|
||||
public static final AnnotationSpec NULLABLE = AnnotationSpec.builder(Nullable.class).build();
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.AnyType;
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
|
||||
public final class AnyResolvedType extends ResolvedType<AnyType> {
|
||||
|
||||
private AnyResolvedType(final AnyType type, final boolean nullable) {
|
||||
super(type, nullable);
|
||||
}
|
||||
|
||||
public static AnyResolvedType create(
|
||||
final AnyType type, final TypeData typeData, final boolean nullable) {
|
||||
return new AnyResolvedType(type, nullable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeName getNativeType(final NativeTypeContext typeContext) {
|
||||
switch (typeContext) {
|
||||
case FUNCTION_ARGUMENT:
|
||||
return TypeUtils.makeNullable(ReactClassNames.REACT_READABLE_MAP, mNullable);
|
||||
case FUNCTION_RETURN:
|
||||
return TypeUtils.makeNullable(ReactClassNames.REACT_WRITABLE_MAP, mNullable);
|
||||
default:
|
||||
return TypeUtils.makeNullable(TypeName.OBJECT, mNullable);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.ArrayType;
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.squareup.javapoet.ArrayTypeName;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
|
||||
public final class ArrayResolvedType extends ResolvedType<ArrayType> {
|
||||
|
||||
private final ResolvedType mElementResolvedType;
|
||||
|
||||
private ArrayResolvedType(final ArrayType type, final TypeData typeData, final boolean nullable) {
|
||||
super(type, nullable);
|
||||
mElementResolvedType = resolveType(mType.elementType, typeData, nullable);
|
||||
}
|
||||
|
||||
public static ArrayResolvedType create(
|
||||
final ArrayType type, final TypeData typeData, final boolean nullable) {
|
||||
return new ArrayResolvedType(type, typeData, nullable);
|
||||
}
|
||||
|
||||
public ResolvedType getElementResolvedType() {
|
||||
return mElementResolvedType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeName getNativeType(final NativeTypeContext typeContext) {
|
||||
switch (typeContext) {
|
||||
case FUNCTION_ARGUMENT:
|
||||
return TypeUtils.makeNullable(ReactClassNames.REACT_READABLE_ARRAY, mNullable);
|
||||
case FUNCTION_RETURN:
|
||||
return TypeUtils.makeNullable(ReactClassNames.REACT_WRITABLE_ARRAY, mNullable);
|
||||
default:
|
||||
return TypeUtils.makeNullable(
|
||||
ArrayTypeName.of(mElementResolvedType.getNativeType(typeContext)), mNullable);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.BooleanType;
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
|
||||
public final class BooleanResolvedType extends ResolvedType<BooleanType> {
|
||||
|
||||
private BooleanResolvedType(final BooleanType type, final boolean nullable) {
|
||||
super(type, nullable);
|
||||
}
|
||||
|
||||
public static BooleanResolvedType create(
|
||||
final BooleanType type, final TypeData typeData, final boolean nullable) {
|
||||
return new BooleanResolvedType(type, nullable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeName getNativeType(final NativeTypeContext typeContext) {
|
||||
return TypeUtils.makeNullable(TypeName.BOOLEAN, mNullable);
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import java.util.Map;
|
||||
|
||||
/** Names of Java classes required by generated code. */
|
||||
public class ClassNames {
|
||||
|
||||
// Java standard classes
|
||||
public static final TypeName STRING = ClassName.get(String.class);
|
||||
|
||||
public static final ParameterizedTypeName CONSTANTS_MAP =
|
||||
ParameterizedTypeName.get(ClassName.get(Map.class), ClassNames.STRING, ClassName.OBJECT);
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.FunctionType;
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.squareup.javapoet.AnnotationSpec;
|
||||
import com.squareup.javapoet.CodeBlock;
|
||||
import com.squareup.javapoet.MethodSpec;
|
||||
import com.squareup.javapoet.ParameterSpec;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.lang.model.element.Modifier;
|
||||
|
||||
public final class FunctionResolvedType extends ResolvedType<FunctionType> {
|
||||
private final Map<String, ResolvedType> mResolvedArgTypes;
|
||||
private final ResolvedType mResolvedReturnType;
|
||||
|
||||
private FunctionResolvedType(
|
||||
final FunctionType type, final TypeData typeData, final boolean nullable) {
|
||||
super(type, nullable);
|
||||
mResolvedReturnType = resolveType(type.returnType, typeData, nullable);
|
||||
mResolvedArgTypes =
|
||||
Collections.unmodifiableMap(
|
||||
type.parameters.stream()
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
item -> item.name, item -> resolveType(item.type, typeData, false))));
|
||||
}
|
||||
|
||||
public static FunctionResolvedType create(
|
||||
final FunctionType type, final TypeData typeData, final boolean nullable) {
|
||||
return new FunctionResolvedType(type, typeData, nullable);
|
||||
}
|
||||
|
||||
public ResolvedType getResolvedReturnType() {
|
||||
return mResolvedReturnType;
|
||||
}
|
||||
|
||||
public Map<String, ResolvedType> getResolvedArgTypes() {
|
||||
return mResolvedArgTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeName getNativeType(final NativeTypeContext typeContext) {
|
||||
return TypeUtils.makeNullable(ReactClassNames.REACT_CALLBACK, mNullable);
|
||||
}
|
||||
|
||||
public MethodSpec getGeneratedMethodWithReactAnnotation(String methodName) {
|
||||
TypeName resolvedReturnTypeName =
|
||||
mResolvedReturnType.getNativeType(NativeTypeContext.FUNCTION_RETURN);
|
||||
|
||||
boolean isReturnTypePromise = resolvedReturnTypeName == ReactClassNames.REACT_PROMISE;
|
||||
TypeName returnTypeName = isReturnTypePromise ? TypeName.VOID : resolvedReturnTypeName;
|
||||
|
||||
MethodSpec.Builder methodBuilder =
|
||||
MethodSpec.methodBuilder(methodName).addModifiers(Modifier.PUBLIC);
|
||||
methodBuilder.returns(returnTypeName);
|
||||
|
||||
if (!mNullable) {
|
||||
methodBuilder.addModifiers(Modifier.ABSTRACT);
|
||||
} else {
|
||||
String returnStatement = getFalsyReturnStatement(returnTypeName);
|
||||
if (returnStatement != null) {
|
||||
CodeBlock.Builder methodBody = CodeBlock.builder();
|
||||
methodBody.addStatement(returnStatement);
|
||||
methodBuilder.addCode(methodBody.build());
|
||||
}
|
||||
}
|
||||
|
||||
mResolvedArgTypes
|
||||
.entrySet()
|
||||
.forEach(
|
||||
e -> {
|
||||
String argName = e.getKey();
|
||||
ResolvedType argResolvedType = e.getValue();
|
||||
methodBuilder.addParameter(
|
||||
ParameterSpec.builder(
|
||||
argResolvedType.getNativeType(NativeTypeContext.FUNCTION_ARGUMENT),
|
||||
argName)
|
||||
.build());
|
||||
});
|
||||
|
||||
AnnotationSpec.Builder annotationBuilder = AnnotationSpec.builder(ReactClassNames.REACT_METHOD);
|
||||
|
||||
// Special case: Promise inserts additional method arg at the end.
|
||||
if (isReturnTypePromise) {
|
||||
methodBuilder.addParameter(
|
||||
ParameterSpec.builder(ReactClassNames.REACT_PROMISE, "promise").build());
|
||||
} else if (!TypeName.VOID.equals(returnTypeName)) {
|
||||
// A non-promise non-void return type means the method is synchronous.
|
||||
annotationBuilder.addMember("isBlockingSynchronousMethod", "$L", true);
|
||||
}
|
||||
|
||||
// React methods need special `@ReactMethod` annotation for now.
|
||||
methodBuilder.addAnnotation(annotationBuilder.build());
|
||||
|
||||
// TODO(T82242829) Add @DoNotStrip annotation
|
||||
|
||||
return methodBuilder.build();
|
||||
}
|
||||
|
||||
private static @Nullable String getFalsyReturnStatement(TypeName returnType) {
|
||||
// TODO: Handle nullable falsy return.
|
||||
if (returnType == TypeName.BOOLEAN) {
|
||||
return "return false";
|
||||
} else if (returnType == TypeName.DOUBLE) {
|
||||
return "return 0.0";
|
||||
} else if (returnType == ClassNames.STRING
|
||||
|| returnType == ReactClassNames.REACT_WRITABLE_ARRAY
|
||||
|| returnType == ReactClassNames.REACT_WRITABLE_MAP) {
|
||||
return "return null";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.CodegenException;
|
||||
import com.facebook.react.codegen.generator.model.GenericObjectType;
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
|
||||
public final class GenericObjectResolvedType extends ResolvedType<GenericObjectType> {
|
||||
|
||||
private GenericObjectResolvedType(final GenericObjectType type, final boolean nullable) {
|
||||
super(type, nullable);
|
||||
}
|
||||
|
||||
public static GenericObjectResolvedType create(
|
||||
final GenericObjectType type, final TypeData typeData, final boolean nullable) {
|
||||
return new GenericObjectResolvedType(type, nullable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeName getNativeType(final NativeTypeContext typeContext) {
|
||||
switch (typeContext) {
|
||||
case FUNCTION_ARGUMENT:
|
||||
return TypeUtils.makeNullable(ReactClassNames.REACT_READABLE_MAP, mNullable);
|
||||
case FUNCTION_RETURN:
|
||||
return TypeUtils.makeNullable(ReactClassNames.REACT_WRITABLE_MAP, mNullable);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
throw new CodegenException(
|
||||
"Unsupported GenericObjectType: " + mType + " - typeContext: " + typeContext);
|
||||
}
|
||||
}
|
|
@ -1,260 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.NativeModuleType;
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.CodeBlock;
|
||||
import com.squareup.javapoet.MethodSpec;
|
||||
import com.squareup.javapoet.ParameterSpec;
|
||||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.lang.model.element.Modifier;
|
||||
|
||||
public final class NativeModuleResolvedType extends ResolvedType<NativeModuleType> {
|
||||
private final Map<String, ResolvedType> mResolvedAliasTypes;
|
||||
private final Map<String, FunctionResolvedType> mResolvedPropertyTypes;
|
||||
|
||||
private NativeModuleResolvedType(
|
||||
final NativeModuleType type, final TypeData typeData, final boolean nullable) {
|
||||
super(type, nullable);
|
||||
mResolvedAliasTypes =
|
||||
Collections.unmodifiableMap(
|
||||
type.aliases.stream()
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
item -> item.getTypeId().typeName,
|
||||
item -> resolveType(item, typeData, false))));
|
||||
mResolvedPropertyTypes =
|
||||
Collections.unmodifiableMap(
|
||||
type.properties.stream()
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
item -> item.name,
|
||||
// TODO: Optional Object property is not necessarily nullable.
|
||||
item -> {
|
||||
final ResolvedType resolvedType =
|
||||
resolveType(item.type, typeData, item.optional);
|
||||
TypeUtils.assertCondition(
|
||||
resolvedType instanceof FunctionResolvedType,
|
||||
"NativeModules can only contain methods. Constants like '"
|
||||
+ item.name
|
||||
+ "' must be declared in the return type of the 'getConstants()' method.");
|
||||
return (FunctionResolvedType) resolvedType;
|
||||
})));
|
||||
}
|
||||
|
||||
public static NativeModuleResolvedType create(
|
||||
final NativeModuleType type, final TypeData typeData, final boolean nullable) {
|
||||
return new NativeModuleResolvedType(type, typeData, nullable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeName getNativeType(final NativeTypeContext typeContext) {
|
||||
throw new UnsupportedOperationException(
|
||||
"NativeModuleType cannot be referred to by other types.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable TypeSpec getGeneratedCode(final String packageName) {
|
||||
final TypeSpec.Builder classBuilder =
|
||||
TypeSpec.classBuilder(mType.getTypeId().typeName)
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
|
||||
.superclass(ReactClassNames.REACT_CONTEXT_BASE_JAVA_MODULE)
|
||||
.addSuperinterface(ReactClassNames.REACT_MODULE_WITH_SPEC)
|
||||
.addSuperinterface(ReactClassNames.REACT_TURBOMODULE);
|
||||
|
||||
final MethodSpec.Builder constructorBuilder =
|
||||
MethodSpec.constructorBuilder()
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.addParameter(
|
||||
ParameterSpec.builder(ReactClassNames.REACT_APPLICATION_CONTEXT, "reactContext")
|
||||
.build())
|
||||
.addStatement("super($N)", "reactContext");
|
||||
classBuilder.addMethod(constructorBuilder.build());
|
||||
|
||||
mResolvedPropertyTypes.forEach(
|
||||
(name, resolvedType) -> {
|
||||
if (name.equals("getConstants")) {
|
||||
classBuilder.addMethod(generateGetTypedExportedConstantsMethod());
|
||||
classBuilder.addMethod(generateGetConstantsMethod(resolvedType));
|
||||
} else {
|
||||
classBuilder.addMethod(
|
||||
((FunctionResolvedType) resolvedType).getGeneratedMethodWithReactAnnotation(name));
|
||||
}
|
||||
});
|
||||
|
||||
return classBuilder.build();
|
||||
}
|
||||
|
||||
// For now, getConstants() needs a runtime check to ensure the object return value has the
|
||||
// required properties. In the future, the method should return the specific object type that
|
||||
// can be verified during build time.
|
||||
private static MethodSpec generateGetConstantsMethod(final FunctionResolvedType resolvedType) {
|
||||
final ResolvedType resolvedReturnType = resolvedType.getResolvedReturnType();
|
||||
TypeUtils.assertCondition(
|
||||
resolvedReturnType instanceof ObjectResolvedType,
|
||||
"getConstants() method must return an exact object. Found: " + resolvedType.mType);
|
||||
|
||||
final ParameterizedTypeName returnType =
|
||||
ParameterizedTypeName.get(ClassName.get(Map.class), ClassNames.STRING, ClassName.OBJECT);
|
||||
return MethodSpec.methodBuilder("getConstants")
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
||||
.addAnnotation(Annotations.OVERRIDE)
|
||||
.returns(returnType.annotated(Annotations.NULLABLE))
|
||||
.addCode(
|
||||
getConstantsMethodBody(
|
||||
returnType, ((ObjectResolvedType) resolvedReturnType).getResolvedPropertyTypes()))
|
||||
.build();
|
||||
}
|
||||
|
||||
private static MethodSpec generateGetTypedExportedConstantsMethod() {
|
||||
return MethodSpec.methodBuilder("getTypedExportedConstants")
|
||||
.addModifiers(Modifier.PROTECTED, Modifier.ABSTRACT)
|
||||
.returns(ClassNames.CONSTANTS_MAP)
|
||||
.build();
|
||||
}
|
||||
|
||||
private static CodeBlock getConstantsMethodBody(
|
||||
final ParameterizedTypeName returnType, final Map<String, ResolvedType> constantsTypes) {
|
||||
final CodeBlock.Builder methodBody = CodeBlock.builder();
|
||||
|
||||
final Map<Boolean, List<Map.Entry<String, ResolvedType>>> constantsByNullability =
|
||||
constantsTypes.entrySet().stream()
|
||||
.collect(Collectors.partitioningBy(entry -> entry.getValue().mNullable));
|
||||
|
||||
final String constantsVariableName = "constants";
|
||||
final String obligatoryFlowConstantsVariableName = "obligatoryFlowConstants";
|
||||
final String optionalFlowConstantsVariableName = "optionalFlowConstants";
|
||||
final TypeName setOfStringsType =
|
||||
ParameterizedTypeName.get(ClassName.get(Set.class), ClassNames.STRING);
|
||||
final TypeName hashsetType = ClassName.get(HashSet.class);
|
||||
|
||||
methodBody.addStatement(
|
||||
"$T $N = $N()",
|
||||
returnType,
|
||||
constantsVariableName,
|
||||
generateGetTypedExportedConstantsMethod().name);
|
||||
|
||||
// Enable all of this for internal (debug) builds only.
|
||||
methodBody.beginControlFlow(
|
||||
"if ($1T.DEBUG || $1T.IS_INTERNAL_BUILD)", ReactClassNames.REACT_BUILD_CONFIG);
|
||||
{
|
||||
final List<String> obligatoryConstants =
|
||||
constantsByNullability.get(false).stream()
|
||||
.map(Map.Entry::getKey)
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
addVariableDeclaration(
|
||||
methodBody,
|
||||
obligatoryFlowConstantsVariableName,
|
||||
obligatoryConstants,
|
||||
setOfStringsType,
|
||||
hashsetType);
|
||||
|
||||
final List<String> optionalConstants =
|
||||
constantsByNullability.get(true).stream()
|
||||
.map(Map.Entry::getKey)
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
addVariableDeclaration(
|
||||
methodBody,
|
||||
optionalFlowConstantsVariableName,
|
||||
optionalConstants,
|
||||
setOfStringsType,
|
||||
hashsetType);
|
||||
|
||||
final String undeclaredConstantsVariableName = "undeclaredConstants";
|
||||
|
||||
methodBody
|
||||
.addStatement(
|
||||
"$T $N = new $T<>($N.keySet())",
|
||||
setOfStringsType,
|
||||
undeclaredConstantsVariableName,
|
||||
hashsetType,
|
||||
constantsVariableName)
|
||||
.addStatement(
|
||||
"$N.removeAll($N)",
|
||||
undeclaredConstantsVariableName,
|
||||
obligatoryFlowConstantsVariableName)
|
||||
.addStatement(
|
||||
"$N.removeAll($N)",
|
||||
undeclaredConstantsVariableName,
|
||||
optionalFlowConstantsVariableName);
|
||||
methodBody.add(
|
||||
checkForConstantsFulfillmentBlock(
|
||||
undeclaredConstantsVariableName,
|
||||
"Native Module Flow doesn\'t declare constants: %s"));
|
||||
|
||||
methodBody
|
||||
.addStatement(
|
||||
"$N = $N", undeclaredConstantsVariableName, obligatoryFlowConstantsVariableName)
|
||||
.addStatement(
|
||||
"$N.removeAll($N.keySet())", undeclaredConstantsVariableName, constantsVariableName);
|
||||
methodBody.add(
|
||||
checkForConstantsFulfillmentBlock(
|
||||
undeclaredConstantsVariableName, "Native Module doesn\'t fill in constants: %s"));
|
||||
}
|
||||
methodBody.endControlFlow();
|
||||
methodBody.addStatement("return $N", constantsVariableName);
|
||||
|
||||
return methodBody.build();
|
||||
}
|
||||
|
||||
private static void addVariableDeclaration(
|
||||
final CodeBlock.Builder builder,
|
||||
final String variableName,
|
||||
final List<String> values,
|
||||
final TypeName varType,
|
||||
final TypeName actualType) {
|
||||
if (values.isEmpty()) {
|
||||
builder.addStatement("$T $N = new $T<>()", varType, variableName, actualType);
|
||||
} else {
|
||||
builder.add(
|
||||
"$T $N = new $T<>($T.asList(\n",
|
||||
varType,
|
||||
variableName,
|
||||
actualType,
|
||||
ClassName.get(Arrays.class));
|
||||
builder.indent().indent();
|
||||
|
||||
int constantsToAdd = values.size();
|
||||
for (final String constantName : values) {
|
||||
builder.add("\"$L\"", constantName);
|
||||
if (--constantsToAdd > 0) {
|
||||
builder.add(",");
|
||||
}
|
||||
builder.add("\n");
|
||||
}
|
||||
|
||||
builder.unindent().unindent();
|
||||
builder.addStatement("))");
|
||||
}
|
||||
}
|
||||
|
||||
private static CodeBlock checkForConstantsFulfillmentBlock(
|
||||
final String undeclaredConstantsVariableName, final String formatString) {
|
||||
return CodeBlock.builder()
|
||||
.beginControlFlow("if (!$N.isEmpty())", undeclaredConstantsVariableName)
|
||||
.addStatement(
|
||||
"throw new IllegalStateException(String.format(\"" + formatString + "\", $N))",
|
||||
undeclaredConstantsVariableName)
|
||||
.endControlFlow()
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.NullableType;
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class NullableResolvedType extends ResolvedType<NullableType> {
|
||||
|
||||
private NullableResolvedType(final NullableType type, final boolean nullable) {
|
||||
super(type, nullable);
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public static ResolvedType create(
|
||||
final NullableType type, final TypeData typeData, final boolean nullable) {
|
||||
return resolveType(type.innerType, typeData, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeName getNativeType(final NativeTypeContext typeContext) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable TypeSpec getGeneratedCode(final String packageName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.CodegenException;
|
||||
import com.facebook.react.codegen.generator.model.DoubleType;
|
||||
import com.facebook.react.codegen.generator.model.FloatType;
|
||||
import com.facebook.react.codegen.generator.model.Int32Type;
|
||||
import com.facebook.react.codegen.generator.model.NumberType;
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
|
||||
public final class NumberResolvedType extends ResolvedType<NumberType> {
|
||||
|
||||
private NumberResolvedType(final NumberType type, final boolean nullable) {
|
||||
super(type, nullable);
|
||||
}
|
||||
|
||||
public static NumberResolvedType create(
|
||||
final NumberType type, final TypeData typeData, final boolean nullable) {
|
||||
return new NumberResolvedType(type, nullable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeName getNativeType(final NativeTypeContext typeContext) {
|
||||
if (mType instanceof Int32Type) {
|
||||
return TypeUtils.makeNullable(TypeName.INT, mNullable);
|
||||
}
|
||||
if (mType instanceof FloatType) {
|
||||
return TypeUtils.makeNullable(TypeName.FLOAT, mNullable);
|
||||
}
|
||||
if (mType instanceof DoubleType) {
|
||||
return TypeUtils.makeNullable(TypeName.DOUBLE, mNullable);
|
||||
}
|
||||
throw new CodegenException("Unsupported NumberType: " + mType.getClass());
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.CodegenException;
|
||||
import com.facebook.react.codegen.generator.model.ObjectType;
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class ObjectResolvedType extends ResolvedType<ObjectType> {
|
||||
private final Map<String, ResolvedType> mResolvedPropertyTypes;
|
||||
|
||||
private ObjectResolvedType(
|
||||
final ObjectType type, final TypeData typeData, final boolean nullable) {
|
||||
super(type, nullable);
|
||||
mResolvedPropertyTypes =
|
||||
Collections.unmodifiableMap(
|
||||
type.properties.stream()
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
item -> item.name,
|
||||
// TODO: Optional Object property is not necessarily nullable.
|
||||
item -> resolveType(item.type, typeData, item.optional))));
|
||||
}
|
||||
|
||||
public static ObjectResolvedType create(
|
||||
final ObjectType type, final TypeData typeData, final boolean nullable) {
|
||||
return new ObjectResolvedType(type, typeData, nullable);
|
||||
}
|
||||
|
||||
public Map<String, ResolvedType> getResolvedPropertyTypes() {
|
||||
return mResolvedPropertyTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeName getNativeType(final NativeTypeContext typeContext) {
|
||||
// TODO: It should return its own class type.
|
||||
// However, the NativeModule system only supports built-in ReadableMap/WritableMap for now.
|
||||
switch (typeContext) {
|
||||
case FUNCTION_ARGUMENT:
|
||||
return TypeUtils.makeNullable(ReactClassNames.REACT_READABLE_MAP, mNullable);
|
||||
case FUNCTION_RETURN:
|
||||
return TypeUtils.makeNullable(ReactClassNames.REACT_WRITABLE_MAP, mNullable);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
throw new CodegenException(
|
||||
"Unsupported ObjectType: " + mType + " - typeContext: " + typeContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable TypeSpec getGeneratedCode(final String packageName) {
|
||||
// TODO: Object type should produce is own class to represent its shape.
|
||||
// However, the NativeModule system only supports built-in ReadableMap/WritableMap for now.
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.PromiseType;
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
|
||||
public final class PromiseResolvedType extends ResolvedType<PromiseType> {
|
||||
|
||||
private PromiseResolvedType(final PromiseType type, final boolean nullable) {
|
||||
super(type, nullable);
|
||||
}
|
||||
|
||||
public static PromiseResolvedType create(
|
||||
final PromiseType type, final TypeData typeData, final boolean nullable) {
|
||||
return new PromiseResolvedType(type, nullable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeName getNativeType(final NativeTypeContext typeContext) {
|
||||
return TypeUtils.makeNullable(ReactClassNames.REACT_PROMISE, mNullable);
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.squareup.javapoet.ClassName;
|
||||
|
||||
/** Names of React-specific Java classes required by generated code. */
|
||||
public class ReactClassNames {
|
||||
|
||||
public static final ClassName REACT_APPLICATION_CONTEXT =
|
||||
ClassName.bestGuess("com.facebook.react.bridge.ReactApplicationContext");
|
||||
public static final ClassName REACT_CALLBACK =
|
||||
ClassName.bestGuess("com.facebook.react.bridge.Callback");
|
||||
public static final ClassName REACT_CONTEXT_BASE_JAVA_MODULE =
|
||||
ClassName.bestGuess("com.facebook.react.bridge.ReactContextBaseJavaModule");
|
||||
public static final ClassName REACT_METHOD =
|
||||
ClassName.bestGuess("com.facebook.react.bridge.ReactMethod");
|
||||
public static final ClassName REACT_MODULE_WITH_SPEC =
|
||||
ClassName.bestGuess("com.facebook.react.bridge.ReactModuleWithSpec");
|
||||
public static final ClassName REACT_PROMISE =
|
||||
ClassName.bestGuess("com.facebook.react.bridge.Promise");
|
||||
public static final ClassName REACT_READABLE_ARRAY =
|
||||
ClassName.bestGuess("com.facebook.react.bridge.ReadableArray");
|
||||
public static final ClassName REACT_READABLE_MAP =
|
||||
ClassName.bestGuess("com.facebook.react.bridge.ReadableMap");
|
||||
public static final ClassName REACT_WRITABLE_ARRAY =
|
||||
ClassName.bestGuess("com.facebook.react.bridge.WritableArray");
|
||||
public static final ClassName REACT_WRITABLE_MAP =
|
||||
ClassName.bestGuess("com.facebook.react.bridge.WritableMap");
|
||||
public static final ClassName REACT_BUILD_CONFIG =
|
||||
ClassName.bestGuess("com.facebook.react.common.build.ReactBuildConfig");
|
||||
public static final ClassName REACT_TURBOMODULE =
|
||||
ClassName.bestGuess("com.facebook.react.turbomodule.core.interfaces.TurboModule");
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.CodegenException;
|
||||
import com.facebook.react.codegen.generator.model.DoubleType;
|
||||
import com.facebook.react.codegen.generator.model.ReservedFunctionValueType;
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class ReservedFunctionValueResolvedType
|
||||
extends ResolvedType<ReservedFunctionValueType> {
|
||||
|
||||
private ReservedFunctionValueResolvedType(
|
||||
final ReservedFunctionValueType type, final boolean nullable) {
|
||||
super(type, nullable);
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public static ResolvedType create(
|
||||
final ReservedFunctionValueType type, final TypeData typeData, final boolean nullable) {
|
||||
switch (type.reservedName) {
|
||||
case RootTag:
|
||||
return resolveType(new DoubleType(type.getTypeId()), typeData, nullable);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
throw new CodegenException("Unsupported ReservedFunctionValueType: " + type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeName getNativeType(final NativeTypeContext typeContext) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable TypeSpec getGeneratedCode(final String packageName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.Type;
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class ResolvedType<T extends Type> {
|
||||
/** Contexts native types can appear in. */
|
||||
public enum NativeTypeContext {
|
||||
FUNCTION_ARGUMENT,
|
||||
FUNCTION_RETURN,
|
||||
DEFAULT,
|
||||
}
|
||||
|
||||
protected final T mType;
|
||||
protected final boolean mNullable;
|
||||
|
||||
protected ResolvedType(final T type, final boolean nullable) {
|
||||
mType = type;
|
||||
mNullable = nullable;
|
||||
}
|
||||
|
||||
protected static ResolvedType resolveType(
|
||||
final Type type, final TypeData typeData, final boolean nullable) {
|
||||
return TypeResolver.resolveType(type, typeData, nullable);
|
||||
}
|
||||
|
||||
public T getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
public boolean isNullable() {
|
||||
return mNullable;
|
||||
}
|
||||
|
||||
/** The Java type generated for this type */
|
||||
public abstract TypeName getNativeType(NativeTypeContext typeContext);
|
||||
|
||||
/** Generate code for this type itself, if applicable. */
|
||||
public @Nullable TypeSpec getGeneratedCode(final String packageName) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.StringType;
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
|
||||
public final class StringResolvedType extends ResolvedType<StringType> {
|
||||
|
||||
private StringResolvedType(final StringType type, final boolean nullable) {
|
||||
super(type, nullable);
|
||||
}
|
||||
|
||||
public static StringResolvedType create(
|
||||
final StringType type, final TypeData typeData, final boolean nullable) {
|
||||
return new StringResolvedType(type, nullable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeName getNativeType(final NativeTypeContext typeContext) {
|
||||
return TypeUtils.makeNullable(ClassNames.STRING, mNullable);
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.AliasType;
|
||||
import com.facebook.react.codegen.generator.model.AnyType;
|
||||
import com.facebook.react.codegen.generator.model.ArrayType;
|
||||
import com.facebook.react.codegen.generator.model.BooleanType;
|
||||
import com.facebook.react.codegen.generator.model.FunctionType;
|
||||
import com.facebook.react.codegen.generator.model.GenericObjectType;
|
||||
import com.facebook.react.codegen.generator.model.NativeModuleType;
|
||||
import com.facebook.react.codegen.generator.model.NullableType;
|
||||
import com.facebook.react.codegen.generator.model.NumberType;
|
||||
import com.facebook.react.codegen.generator.model.ObjectType;
|
||||
import com.facebook.react.codegen.generator.model.PromiseType;
|
||||
import com.facebook.react.codegen.generator.model.ReservedFunctionValueType;
|
||||
import com.facebook.react.codegen.generator.model.StringType;
|
||||
import com.facebook.react.codegen.generator.model.Type;
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.facebook.react.codegen.generator.model.VoidType;
|
||||
|
||||
public final class TypeResolver {
|
||||
public static ResolvedType resolveType(
|
||||
final Type type, final TypeData typeData, final boolean nullable) {
|
||||
|
||||
if (type instanceof AliasType) {
|
||||
return AliasResolvedType.create((AliasType) type, typeData, nullable);
|
||||
}
|
||||
|
||||
if (type instanceof AnyType) {
|
||||
return AnyResolvedType.create((AnyType) type, typeData, nullable);
|
||||
}
|
||||
|
||||
if (type instanceof ArrayType) {
|
||||
return ArrayResolvedType.create((ArrayType) type, typeData, nullable);
|
||||
}
|
||||
|
||||
if (type instanceof BooleanType) {
|
||||
return BooleanResolvedType.create((BooleanType) type, typeData, nullable);
|
||||
}
|
||||
|
||||
if (type instanceof FunctionType) {
|
||||
return FunctionResolvedType.create((FunctionType) type, typeData, nullable);
|
||||
}
|
||||
|
||||
if (type instanceof GenericObjectType) {
|
||||
return GenericObjectResolvedType.create((GenericObjectType) type, typeData, nullable);
|
||||
}
|
||||
|
||||
if (type instanceof NativeModuleType) {
|
||||
return NativeModuleResolvedType.create((NativeModuleType) type, typeData, nullable);
|
||||
}
|
||||
|
||||
if (type instanceof NullableType) {
|
||||
return NullableResolvedType.create((NullableType) type, typeData, nullable);
|
||||
}
|
||||
|
||||
if (type instanceof NumberType) {
|
||||
return NumberResolvedType.create((NumberType) type, typeData, nullable);
|
||||
}
|
||||
|
||||
if (type instanceof ObjectType) {
|
||||
return ObjectResolvedType.create((ObjectType) type, typeData, nullable);
|
||||
}
|
||||
|
||||
if (type instanceof PromiseType) {
|
||||
return PromiseResolvedType.create((PromiseType) type, typeData, nullable);
|
||||
}
|
||||
|
||||
if (type instanceof ReservedFunctionValueType) {
|
||||
return ReservedFunctionValueResolvedType.create(
|
||||
(ReservedFunctionValueType) type, typeData, nullable);
|
||||
}
|
||||
|
||||
if (type instanceof StringType) {
|
||||
return StringResolvedType.create((StringType) type, typeData, nullable);
|
||||
}
|
||||
|
||||
if (type instanceof VoidType) {
|
||||
return VoidResolvedType.create((VoidType) type, typeData, nullable);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unable to resolve unsupported type: " + type.getClass());
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.CodegenException;
|
||||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeVariableName;
|
||||
|
||||
public class TypeUtils {
|
||||
|
||||
public static TypeName getNativeClassName(TypeName className) {
|
||||
while (className instanceof ParameterizedTypeName) {
|
||||
className = ((ParameterizedTypeName) className).rawType;
|
||||
}
|
||||
|
||||
return (className instanceof TypeVariableName) ? TypeName.OBJECT : className.box();
|
||||
}
|
||||
|
||||
public static TypeName makeNullable(final TypeName typeName, final boolean isNullable) {
|
||||
if (isNullable) {
|
||||
if (typeName.isPrimitive()) {
|
||||
return typeName.box();
|
||||
}
|
||||
if (!typeName.annotations.contains(Annotations.NULLABLE)) {
|
||||
return typeName.annotated(Annotations.NULLABLE);
|
||||
}
|
||||
}
|
||||
return typeName;
|
||||
}
|
||||
|
||||
public static void assertCondition(final boolean condition, final String errorMessage)
|
||||
throws CodegenException {
|
||||
if (!condition) {
|
||||
throw new CodegenException(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.codegen.generator.resolver;
|
||||
|
||||
import com.facebook.react.codegen.generator.model.TypeData;
|
||||
import com.facebook.react.codegen.generator.model.VoidType;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class VoidResolvedType extends ResolvedType<VoidType> {
|
||||
|
||||
private VoidResolvedType(final VoidType type, final boolean nullable) {
|
||||
super(type, nullable);
|
||||
}
|
||||
|
||||
public static VoidResolvedType create(
|
||||
final VoidType type, final TypeData typeData, final boolean nullable) {
|
||||
return new VoidResolvedType(type, nullable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeName getNativeType(final NativeTypeContext typeContext) {
|
||||
return TypeName.VOID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable TypeSpec getGeneratedCode(final String packageName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
|
@ -228,7 +228,14 @@ abstract class ReactExtension @Inject constructor(project: Project) {
|
|||
val codegenJavaPackageName: Property<String> =
|
||||
objects.property(String::class.java).convention("com.facebook.fbreact.specs")
|
||||
|
||||
/** Whether the Java Generator (based on Javapoet) should be used or not. Default: false */
|
||||
/**
|
||||
* Whether the Java Generator (based on Javapoet) should be used or not. Please note that this is
|
||||
* currently deprecated as the Java generator is not supported anymore. Default: false
|
||||
*/
|
||||
@Deprecated(
|
||||
level = DeprecationLevel.ERROR,
|
||||
message =
|
||||
"Please note that this is deprecated as the Java generator is not supported and react-native-codegen should be used instead.")
|
||||
val useJavaGenerator: Property<Boolean> = objects.property(Boolean::class.java).convention(false)
|
||||
|
||||
/**
|
||||
|
|
|
@ -100,7 +100,6 @@ class ReactPlugin : Plugin<Project> {
|
|||
it.deprecatedReactRoot.set(extension.reactRoot)
|
||||
it.nodeExecutableAndArgs.set(extension.nodeExecutableAndArgs)
|
||||
it.codegenDir.set(extension.codegenDir)
|
||||
it.useJavaGenerator.set(extension.useJavaGenerator)
|
||||
it.codegenJavaPackageName.set(extension.codegenJavaPackageName)
|
||||
it.libraryName.set(extension.libraryName)
|
||||
it.generatedSrcDir.set(generatedSrcDir)
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
|
||||
package com.facebook.react.tasks
|
||||
|
||||
import com.facebook.react.codegen.generator.JavaGenerator
|
||||
import com.facebook.react.utils.windowsAwareCommandLine
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.file.Directory
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.RegularFile
|
||||
|
@ -28,8 +26,6 @@ abstract class GenerateCodegenArtifactsTask : Exec() {
|
|||
|
||||
@get:Input abstract val nodeExecutableAndArgs: ListProperty<String>
|
||||
|
||||
@get:Input abstract val useJavaGenerator: Property<Boolean>
|
||||
|
||||
@get:Input abstract val codegenJavaPackageName: Property<String>
|
||||
|
||||
@get:Input abstract val libraryName: Property<String>
|
||||
|
@ -52,19 +48,6 @@ abstract class GenerateCodegenArtifactsTask : Exec() {
|
|||
checkForDeprecatedProperty()
|
||||
setupCommandLine()
|
||||
super.exec()
|
||||
if (useJavaGenerator.getOrElse(false)) {
|
||||
// Use Java-based generator implementation to produce the source files,
|
||||
// this will override the JS-based generator output (for the Java files only).
|
||||
try {
|
||||
JavaGenerator(
|
||||
generatedSchemaFile.get().asFile,
|
||||
codegenJavaPackageName.get(),
|
||||
generatedSrcDir.get().asFile)
|
||||
.build()
|
||||
} catch (e: Exception) {
|
||||
throw GradleException("Failed to generate Java from schema.", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkForDeprecatedProperty() {
|
||||
|
|
Загрузка…
Ссылка в новой задаче