From 3b4cd94034ff3e5567a2ba6da35d640ff61db4b9 Mon Sep 17 00:00:00 2001 From: Adam Lesinski Date: Fri, 30 Oct 2015 16:31:42 -0700 Subject: AAPT2: Add support for comments in R.java Change-Id: Iaa5f3b75bf7de9dbf458fa5c452f7312989f4c4f --- tools/aapt2/java/JavaClassGenerator.cpp | 121 ++++++++++++++++++++++++++++++-- 1 file changed, 114 insertions(+), 7 deletions(-) (limited to 'tools/aapt2/java/JavaClassGenerator.cpp') diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp index 0175489cf6ea..dfd2ef6f5372 100644 --- a/tools/aapt2/java/JavaClassGenerator.cpp +++ b/tools/aapt2/java/JavaClassGenerator.cpp @@ -18,6 +18,8 @@ #include "Resource.h" #include "ResourceTable.h" #include "ResourceValues.h" +#include "ValueVisitor.h" + #include "java/AnnotationProcessor.h" #include "java/JavaClassGenerator.h" #include "util/StringPiece.h" @@ -109,13 +111,13 @@ void JavaClassGenerator::generateStyleable(const StringPiece16& packageNameToGen std::sort(sortedAttributes.begin(), sortedAttributes.end()); // First we emit the array containing the IDs of each attribute. - *out << " " + *out << " " << "public static final int[] " << transform(entryName) << " = {"; const size_t attrCount = sortedAttributes.size(); for (size_t i = 0; i < attrCount; i++) { if (i % kAttribsPerLine == 0) { - *out << "\n "; + *out << "\n "; } *out << sortedAttributes[i].first; @@ -123,11 +125,11 @@ void JavaClassGenerator::generateStyleable(const StringPiece16& packageNameToGen *out << ", "; } } - *out << "\n };\n"; + *out << "\n };\n"; // Now we emit the indices into the array. for (size_t i = 0; i < attrCount; i++) { - *out << " " + *out << " " << "public static" << finalModifier << " int " << transform(entryName); @@ -141,6 +143,85 @@ void JavaClassGenerator::generateStyleable(const StringPiece16& packageNameToGen } } +static void addAttributeFormatDoc(AnnotationProcessor* processor, Attribute* attr) { + const uint32_t typeMask = attr->typeMask; + if (typeMask & android::ResTable_map::TYPE_REFERENCE) { + processor->appendComment( + "

May be a reference to another resource, in the form\n" + "\"@[+][package:]type/name\" or a theme\n" + "attribute in the form\n" + "\"?[package:]type/name\"."); + } + + if (typeMask & android::ResTable_map::TYPE_STRING) { + processor->appendComment( + "

May be a string value, using '\\;' to escape characters such as\n" + "'\\n' or '\\uxxxx' for a unicode character;"); + } + + if (typeMask & android::ResTable_map::TYPE_INTEGER) { + processor->appendComment("

May be an integer value, such as \"100\"."); + } + + if (typeMask & android::ResTable_map::TYPE_BOOLEAN) { + processor->appendComment( + "

May be a boolean value, such as \"true\" or\n" + "\"false\"."); + } + + if (typeMask & android::ResTable_map::TYPE_COLOR) { + processor->appendComment( + "

May be a color value, in the form of \"#rgb\",\n" + "\"#argb\", \"#rrggbb#aarrggbb\"."); + } + + if (typeMask & android::ResTable_map::TYPE_FLOAT) { + processor->appendComment( + "

May be a floating point value, such as \"1.2\"."); + } + + if (typeMask & android::ResTable_map::TYPE_DIMENSION) { + processor->appendComment( + "

May be a dimension value, which is a floating point number appended with a\n" + "unit such as \"14.5sp\".\n" + "Available units are: px (pixels), dp (density-independent pixels),\n" + "sp (scaled pixels based on preferred font size), in (inches), and\n" + "mm (millimeters)."); + } + + if (typeMask & android::ResTable_map::TYPE_FRACTION) { + processor->appendComment( + "

May be a fractional value, which is a floating point number appended with\n" + "either % or %p, such as \"14.5%\".\n" + "The % suffix always means a percentage of the base size;\n" + "the optional %p suffix provides a size relative to some parent container."); + } + + if (typeMask & (android::ResTable_map::TYPE_FLAGS | android::ResTable_map::TYPE_ENUM)) { + if (typeMask & android::ResTable_map::TYPE_FLAGS) { + processor->appendComment( + "

Must be one or more (separated by '|') of the following " + "constant values.

"); + } else { + processor->appendComment("

Must be one of the following constant values.

"); + } + + processor->appendComment("\n\n" + "\n" + "\n" + "\n"); + for (const Attribute::Symbol& symbol : attr->symbols) { + std::stringstream line; + line << "" + << "" + << ""; + processor->appendComment(line.str()); + } + processor->appendComment("
ConstantValueDescription
" << symbol.symbol.name.value().entry << "" << std::hex << symbol.value << std::dec << "" << util::trimWhitespace(symbol.symbol.getComment()) << "
"); + } +} + bool JavaClassGenerator::generateType(const StringPiece16& packageNameToGenerate, const ResourceTablePackage* package, const ResourceTableType* type, @@ -186,7 +267,33 @@ bool JavaClassGenerator::generateType(const StringPiece16& packageNameToGenerate generateStyleable(packageNameToGenerate, unmangledName, static_cast( entry->values.front().value.get()), out); } else { - *out << " " << "public static" << finalModifier + AnnotationProcessor processor(" "); + if (entry->symbolStatus.state != SymbolState::kUndefined) { + processor.appendComment(entry->symbolStatus.comment); + } + + for (const auto& configValue : entry->values) { + processor.appendComment(configValue.value->getComment()); + } + + if (!entry->values.empty()) { + if (Attribute* attr = valueCast(entry->values.front().value.get())) { + // We list out the available values for the given attribute. + addAttributeFormatDoc(&processor, attr); + } + } + + std::string comment = processor.buildComment(); + if (!comment.empty()) { + *out << comment << "\n"; + } + + std::string annotations = processor.buildAnnotations(); + if (!annotations.empty()) { + *out << annotations << "\n"; + } + + *out << " " << "public static" << finalModifier << " int " << transform(unmangledName) << " = " << id << ";\n"; } } @@ -211,11 +318,11 @@ bool JavaClassGenerator::generate(const StringPiece16& packageNameToGenerate, } else { typeStr = toString(type->type); } - *out << " public static final class " << typeStr << " {\n"; + *out << " public static final class " << typeStr << " {\n"; if (!generateType(packageNameToGenerate, package.get(), type.get(), out)) { return false; } - *out << " }\n"; + *out << " }\n"; } } -- cgit v1.2.3