Merge "And one more backend for hidl-gen to create a simple static java library"
diff --git a/EnumType.cpp b/EnumType.cpp
index 8f959e7..1905a3e 100644
--- a/EnumType.cpp
+++ b/EnumType.cpp
@@ -374,7 +374,7 @@
}
}
-status_t EnumType::emitExportedHeader(Formatter &out) const {
+status_t EnumType::emitExportedHeader(Formatter &out, bool forJava) const {
const Annotation *annotation = findExportAnnotation();
CHECK(annotation != nullptr);
@@ -399,9 +399,61 @@
}
const ScalarType *scalarType = mStorageType->resolveToScalarType();
- CHECK(scalarType != NULL);
+ CHECK(scalarType != nullptr);
- std::string extra;
+ if (forJava) {
+ if (!name.empty()) {
+ out << "public final class "
+ << name
+ << " {\n";
+
+ out.indent();
+ } else {
+ out << "// Values declared in " << localName() << " follow.\n";
+ }
+
+ std::string extra; // unused, because ScalarType leaves this empty.
+ const std::string typeName =
+ scalarType->getJavaType(&extra, false /* forInitializer */);
+
+ std::vector<const EnumType *> chain;
+ getTypeChain(&chain);
+
+ for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
+ const auto &type = *it;
+
+ for (const auto &entry : type->values()) {
+ out << "public static final "
+ << typeName
+ << " "
+ << valuePrefix
+ << entry->name()
+ << " = ";
+
+ // javaValue will make the number signed.
+ std::string value = entry->javaValue(scalarType->getKind());
+ CHECK(!value.empty()); // use autofilled values for java.
+ out << value;
+
+ out << ";";
+
+ std::string comment = entry->comment();
+ if (!comment.empty() && comment != value) {
+ out << " // " << comment;
+ }
+
+ out << "\n";
+ }
+ }
+
+ if (!name.empty()) {
+ out.unindent();
+ out << "};\n";
+ }
+ out << "\n";
+
+ return OK;
+ }
if (!name.empty()) {
out << "typedef ";
diff --git a/EnumType.h b/EnumType.h
index e7823ef..c464cd2 100644
--- a/EnumType.h
+++ b/EnumType.h
@@ -85,7 +85,7 @@
void appendToExportedTypesVector(
std::vector<const Type *> *exportedTypes) const override;
- status_t emitExportedHeader(Formatter &out) const override;
+ status_t emitExportedHeader(Formatter &out, bool forJava) const override;
private:
void getTypeChain(std::vector<const EnumType *> *out) const;
diff --git a/Type.cpp b/Type.cpp
index eafda3a..d0b8f9d 100644
--- a/Type.cpp
+++ b/Type.cpp
@@ -404,7 +404,8 @@
std::vector<const Type *> * /* exportedTypes */) const {
}
-status_t Type::emitExportedHeader(Formatter & /* out */) const {
+status_t Type::emitExportedHeader(
+ Formatter & /* out */, bool /* forJava */) const {
return OK;
}
diff --git a/Type.h b/Type.h
index 04141ff..b65ce4b 100644
--- a/Type.h
+++ b/Type.h
@@ -196,7 +196,7 @@
virtual void appendToExportedTypesVector(
std::vector<const Type *> *exportedTypes) const;
- virtual status_t emitExportedHeader(Formatter &out) const;
+ virtual status_t emitExportedHeader(Formatter &out, bool forJava) const;
protected:
void handleError(Formatter &out, ErrorMode mode) const;
diff --git a/main.cpp b/main.cpp
index cef969e..d95dadb 100644
--- a/main.cpp
+++ b/main.cpp
@@ -343,6 +343,43 @@
return false;
}
+static void generateMakefileSectionForJavaConstants(
+ Formatter &out,
+ Coordinator *coordinator,
+ const FQName &packageFQName,
+ const std::vector<FQName> &packageInterfaces) {
+ out << "\n#"
+ << "\nGEN := $(intermediates)/"
+ << coordinator->convertPackageRootToPath(packageFQName)
+ << coordinator->getPackagePath(packageFQName, true /* relative */)
+ << "Constants.java";
+
+ out << "\n$(GEN): $(HIDL)\n";
+ for (const auto &iface : packageInterfaces) {
+ out << "$(GEN): $(LOCAL_PATH)/" << iface.name() << ".hal\n";
+ }
+ out << "\n$(GEN): PRIVATE_HIDL := $(HIDL)";
+ out << "\n$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)"
+ << "\n$(GEN): PRIVATE_CUSTOM_TOOL = \\";
+ out.indent();
+ out.indent();
+ out << "\n$(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \\"
+ << "\n-Ljava-constants"
+ << " -r"
+ << coordinator->getPackageRoot(packageFQName) << ":"
+ << coordinator->getPackageRootPath(packageFQName) << " \\\n";
+
+ out << packageFQName.string();
+ out << "\n";
+
+ out.unindent();
+ out.unindent();
+
+ out << "\n$(GEN):";
+ out << "\n\t$(transform-generated-source)";
+ out << "\nLOCAL_GENERATED_SOURCES += $(GEN)";
+}
+
static status_t generateMakefileForPackage(
const FQName &packageFQName,
const char *hidl_gen,
@@ -365,6 +402,7 @@
std::set<FQName> importedPackages;
AST *typesAST = nullptr;
+ std::vector<const Type *> exportedTypes;
for (const auto &fqName : packageInterfaces) {
AST *ast = coordinator->parse(fqName);
@@ -382,6 +420,7 @@
}
ast->getImportedPackages(&importedPackages);
+ ast->appendToExportedTypesVector(&exportedTypes);
}
bool packageIsJavaCompatible;
@@ -392,7 +431,9 @@
return err;
}
- if (!packageIsJavaCompatible) {
+ bool haveJavaConstants = !exportedTypes.empty();
+
+ if (!packageIsJavaCompatible && !haveJavaConstants) {
return OK;
}
@@ -425,7 +466,8 @@
LIBRARY_STYLE_END,
};
- for (int style = LIBRARY_STYLE_REGULAR; style != LIBRARY_STYLE_END;
+ for (int style = LIBRARY_STYLE_REGULAR;
+ (packageIsJavaCompatible && style != LIBRARY_STYLE_END);
++style) {
const std::string staticSuffix =
(style == LIBRARY_STYLE_STATIC) ? "-static" : "";
@@ -475,6 +517,31 @@
<< "JAVA_LIBRARY)\n\n";
}
+ if (haveJavaConstants) {
+ out << "\n"
+ << "########################################"
+ << "########################################\n\n";
+
+ out << "include $(CLEAR_VARS)\n"
+ << "LOCAL_MODULE := "
+ << libraryName
+ << "-java-constants"
+ << "\nLOCAL_MODULE_CLASS := JAVA_LIBRARIES\n\n"
+ << "intermediates := $(local-generated-sources-dir)\n\n"
+ << "HIDL := $(HOST_OUT_EXECUTABLES)/"
+ << hidl_gen
+ << "$(HOST_EXECUTABLE_SUFFIX)";
+
+ generateMakefileSectionForJavaConstants(
+ out, coordinator, packageFQName, packageInterfaces);
+
+ out << "\n# Avoid dependency cycle of framework.jar -> this-library "
+ << "-> framework.jar\n"
+ << "LOCAL_NO_STANDARD_LIBRARIES := true\n"
+ << "LOCAL_JAVA_LIBRARIES := core-oj\n\n"
+ << "include $(BUILD_STATIC_JAVA_LIBRARY)\n\n";
+ }
+
out << "\n\n"
<< "include $(call all-makefiles-under,$(LOCAL_PATH))\n";
@@ -817,7 +884,8 @@
const FQName &packageFQName,
const char * /* hidl_gen */,
Coordinator *coordinator,
- const std::string &outputPath) {
+ const std::string &outputPath,
+ bool forJava) {
CHECK(packageFQName.isValid()
&& !packageFQName.isFullyQualified()
@@ -852,8 +920,19 @@
return OK;
}
- CHECK(Coordinator::MakeParentHierarchy(outputPath));
- FILE *file = fopen(outputPath.c_str(), "w");
+ std::string path = outputPath;
+
+ if (forJava) {
+ path.append(coordinator->convertPackageRootToPath(packageFQName));
+
+ path.append(coordinator->getPackagePath(
+ packageFQName, true /* relative */));
+
+ path.append("Constants.java");
+ }
+
+ CHECK(Coordinator::MakeParentHierarchy(path));
+ FILE *file = fopen(path.c_str(), "w");
if (file == nullptr) {
return -errno;
@@ -864,24 +943,36 @@
out << "// This file is autogenerated by hidl-gen. Do not edit manually."
"\n\n";
- std::string guard = "HIDL_GENERATED_";
- guard += packageFQName.tokenName();
- guard += "_";
- guard += "EXPORTED_CONSTANTS_H_";
+ std::string guard;
+ if (forJava) {
+ out << "package " << packageFQName.javaPackage() << ";\n\n";
+ out << "public class Constants {\n";
+ out.indent();
+ } else {
+ guard = "HIDL_GENERATED_";
+ guard += packageFQName.tokenName();
+ guard += "_";
+ guard += "EXPORTED_CONSTANTS_H_";
- out << "#ifndef "
- << guard
- << "\n#define "
- << guard
- << "\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n";
-
- for (const auto &type : exportedTypes) {
- type->emitExportedHeader(out);
+ out << "#ifndef "
+ << guard
+ << "\n#define "
+ << guard
+ << "\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n";
}
- out << "#ifdef __cplusplus\n}\n#endif\n\n#endif // "
- << guard
- << "\n";
+ for (const auto &type : exportedTypes) {
+ type->emitExportedHeader(out, forJava);
+ }
+
+ if (forJava) {
+ out.unindent();
+ out << "}\n";
+ } else {
+ out << "#ifdef __cplusplus\n}\n#endif\n\n#endif // "
+ << guard
+ << "\n";
+ }
return OK;
}
@@ -922,7 +1013,8 @@
fqName,
hidl_gen,
coordinator,
- outputPath);
+ outputPath,
+ false /* forJava */);
}
},
@@ -970,6 +1062,22 @@
}
},
+ {"java-constants",
+ OutputHandler::NEEDS_DIR /* mOutputMode */,
+ validateForExportHeader,
+ [](const FQName &fqName,
+ const char *hidl_gen, Coordinator *coordinator,
+ const std::string &outputDir) -> status_t {
+ CHECK(!fqName.isFullyQualified());
+ return generateExportHeaderForPackage(
+ fqName,
+ hidl_gen,
+ coordinator,
+ outputDir,
+ true /* forJava */);
+ }
+ },
+
{"vts",
OutputHandler::NEEDS_DIR /* mOutputMode */,
validateForSource,