Loading tools/aapt2/flatten/ResourceTypeExtensions.h +28 −24 Original line number Diff line number Diff line Loading @@ -132,6 +132,32 @@ struct Public_header { uint32_t count; }; /** * A structure representing source data for a resource entry. * Appears after an android::ResTable_entry or android::ResTable_map_entry. * * TODO(adamlesinski): This causes some issues when runtime code checks * the size of an android::ResTable_entry. It assumes it is an * android::ResTable_map_entry if the size is bigger than an android::ResTable_entry * which may not be true if this structure is present. */ struct ResTable_entry_source { /** * File path reference. */ android::ResStringPool_ref path; /** * Line number this resource was defined on. */ uint32_t line; /** * Comment string reference. */ android::ResStringPool_ref comment; }; struct Public_entry { uint16_t entryId; Loading @@ -143,8 +169,7 @@ struct Public_entry { uint16_t state; android::ResStringPool_ref key; android::ResStringPool_ref source; uint32_t sourceLine; ResTable_entry_source source; }; /** Loading Loading @@ -173,28 +198,7 @@ struct SymbolTable_entry { * The index into the string pool where the name of this * symbol exists. */ uint32_t stringIndex; }; /** * A structure representing the source of a resourc entry. * Appears after an android::ResTable_entry or android::ResTable_map_entry. * * TODO(adamlesinski): This causes some issues when runtime code checks * the size of an android::ResTable_entry. It assumes it is an * android::ResTable_map_entry if the size is bigger than an android::ResTable_entry * which may not be true if this structure is present. */ struct ResTable_entry_source { /** * Index into the source string pool. */ uint32_t pathIndex; /** * Line number this resource was defined on. */ uint32_t line; android::ResStringPool_ref name; }; /** Loading tools/aapt2/flatten/TableFlattener.cpp +18 −5 Original line number Diff line number Diff line Loading @@ -54,9 +54,16 @@ static void strcpy16_htod(uint16_t* dst, size_t len, const StringPiece16& src) { struct FlatEntry { ResourceEntry* entry; Value* value; // The entry string pool index to the entry's name. uint32_t entryKey; // The source string pool index to the source file path. uint32_t sourcePathKey; uint32_t sourceLine; // The source string pool index to the comment. uint32_t commentKey; }; class SymbolWriter { Loading Loading @@ -318,8 +325,9 @@ private: if (mOptions.useExtendedChunks) { // Write the extra source block. This will be ignored by the Android runtime. ResTable_entry_source* sourceBlock = buffer->nextBlock<ResTable_entry_source>(); sourceBlock->pathIndex = util::hostToDevice32(entry->sourcePathKey); sourceBlock->path.index = util::hostToDevice32(entry->sourcePathKey); sourceBlock->line = util::hostToDevice32(entry->sourceLine); sourceBlock->comment.index = util::hostToDevice32(entry->commentKey); outEntry->size += sizeof(*sourceBlock); } Loading Loading @@ -486,12 +494,14 @@ private: publicEntry->entryId = util::hostToDevice32(entry->id.value()); publicEntry->key.index = util::hostToDevice32(mKeyPool.makeRef( entry->name).getIndex()); publicEntry->source.index = util::hostToDevice32(mSourcePool->makeRef( publicEntry->source.path.index = util::hostToDevice32(mSourcePool->makeRef( util::utf8ToUtf16(entry->symbolStatus.source.path)).getIndex()); if (entry->symbolStatus.source.line) { publicEntry->sourceLine = util::hostToDevice32( publicEntry->source.line = util::hostToDevice32( entry->symbolStatus.source.line.value()); } publicEntry->source.comment.index = util::hostToDevice32(mSourcePool->makeRef( entry->symbolStatus.comment).getIndex()); switch (entry->symbolStatus.state) { case SymbolState::kPrivate: Loading Loading @@ -565,13 +575,16 @@ private: lineNumber = value->getSource().line.value(); } const StringPool::Ref commentRef = mSourcePool->makeRef(value->getComment()); configToEntryListMap[configValue.config] .push_back(FlatEntry{ entry, value, keyIndex, (uint32_t) sourceRef.getIndex(), lineNumber }); lineNumber, (uint32_t) commentRef.getIndex() }); } } Loading Loading @@ -680,7 +693,7 @@ bool TableFlattener::consume(IAaptContext* context, ResourceTable* table) { // Update the offsets to their final values. if (symbolEntryData) { for (SymbolWriter::Entry& entry : symbolOffsets) { symbolEntryData->stringIndex = util::hostToDevice32(entry.name.getIndex()); symbolEntryData->name.index = util::hostToDevice32(entry.name.getIndex()); // The symbols were all calculated with the packageBuffer offset. We need to // add the beginning of the output buffer. Loading tools/aapt2/java/AnnotationProcessor.cpp +19 −11 Original line number Diff line number Diff line Loading @@ -21,16 +21,10 @@ namespace aapt { void AnnotationProcessor::appendCommentLine(const StringPiece16& line) { void AnnotationProcessor::appendCommentLine(const std::string& comment) { static const std::string sDeprecated = "@deprecated"; static const std::string sSystemApi = "@SystemApi"; if (line.empty()) { return; } std::string comment = util::utf16ToUtf8(line); if (comment.find(sDeprecated) != std::string::npos && !mDeprecated) { mDeprecated = true; if (!mAnnotations.empty()) { Loading Loading @@ -63,14 +57,28 @@ void AnnotationProcessor::appendCommentLine(const StringPiece16& line) { void AnnotationProcessor::appendComment(const StringPiece16& comment) { // We need to process line by line to clean-up whitespace and append prefixes. for (StringPiece16 line : util::tokenize(comment, u'\n')) { appendCommentLine(util::trimWhitespace(line)); line = util::trimWhitespace(line); if (!line.empty()) { appendCommentLine(util::utf16ToUtf8(line)); } } } void AnnotationProcessor::appendComment(const StringPiece& comment) { for (StringPiece line : util::tokenize(comment, '\n')) { line = util::trimWhitespace(line); if (!line.empty()) { appendCommentLine(line.toString()); } } } std::string AnnotationProcessor::buildComment() { if (!mComment.empty()) { mComment += "\n"; mComment += mPrefix; mComment += " */"; } return std::move(mComment); } Loading tools/aapt2/java/AnnotationProcessor.h +2 −1 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ public: * we need to collect all the comments. */ void appendComment(const StringPiece16& comment); void appendComment(const StringPiece& comment); /** * Finishes the comment and moves it to the caller. Subsequent calls to buildComment() have Loading @@ -85,7 +86,7 @@ private: bool mDeprecated = false; bool mSystemApi = false; void appendCommentLine(const StringPiece16& line); void appendCommentLine(const std::string& line); }; } // namespace aapt Loading tools/aapt2/java/JavaClassGenerator.cpp +114 −7 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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( "<p>May be a reference to another resource, in the form\n" "\"<code>@[+][<i>package</i>:]<i>type</i>/<i>name</i></code>\" or a theme\n" "attribute in the form\n" "\"<code>?[<i>package</i>:]<i>type</i>/<i>name</i></code>\"."); } if (typeMask & android::ResTable_map::TYPE_STRING) { processor->appendComment( "<p>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("<p>May be an integer value, such as \"<code>100</code>\"."); } if (typeMask & android::ResTable_map::TYPE_BOOLEAN) { processor->appendComment( "<p>May be a boolean value, such as \"<code>true</code>\" or\n" "\"<code>false</code>\"."); } if (typeMask & android::ResTable_map::TYPE_COLOR) { processor->appendComment( "<p>May be a color value, in the form of \"<code>#<i>rgb</i></code>\",\n" "\"<code>#<i>argb</i></code>\", \"<code>#<i>rrggbb</i></code\", or \n" "\"<code>#<i>aarrggbb</i></code>\"."); } if (typeMask & android::ResTable_map::TYPE_FLOAT) { processor->appendComment( "<p>May be a floating point value, such as \"<code>1.2</code>\"."); } if (typeMask & android::ResTable_map::TYPE_DIMENSION) { processor->appendComment( "<p>May be a dimension value, which is a floating point number appended with a\n" "unit such as \"<code>14.5sp</code>\".\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( "<p>May be a fractional value, which is a floating point number appended with\n" "either % or %p, such as \"<code>14.5%</code>\".\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( "<p>Must be one or more (separated by '|') of the following " "constant values.</p>"); } else { processor->appendComment("<p>Must be one of the following constant values.</p>"); } processor->appendComment("<table>\n<colgroup align=\"left\" />\n" "<colgroup align=\"left\" />\n" "<colgroup align=\"left\" />\n" "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>\n"); for (const Attribute::Symbol& symbol : attr->symbols) { std::stringstream line; line << "<tr><td>" << symbol.symbol.name.value().entry << "</td>" << "<td>" << std::hex << symbol.value << std::dec << "</td>" << "<td>" << util::trimWhitespace(symbol.symbol.getComment()) << "</td></tr>"; processor->appendComment(line.str()); } processor->appendComment("</table>"); } } bool JavaClassGenerator::generateType(const StringPiece16& packageNameToGenerate, const ResourceTablePackage* package, const ResourceTableType* type, Loading Loading @@ -186,6 +267,32 @@ bool JavaClassGenerator::generateType(const StringPiece16& packageNameToGenerate generateStyleable(packageNameToGenerate, unmangledName, static_cast<const Styleable*>( entry->values.front().value.get()), out); } else { 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<Attribute>(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"; } Loading Loading
tools/aapt2/flatten/ResourceTypeExtensions.h +28 −24 Original line number Diff line number Diff line Loading @@ -132,6 +132,32 @@ struct Public_header { uint32_t count; }; /** * A structure representing source data for a resource entry. * Appears after an android::ResTable_entry or android::ResTable_map_entry. * * TODO(adamlesinski): This causes some issues when runtime code checks * the size of an android::ResTable_entry. It assumes it is an * android::ResTable_map_entry if the size is bigger than an android::ResTable_entry * which may not be true if this structure is present. */ struct ResTable_entry_source { /** * File path reference. */ android::ResStringPool_ref path; /** * Line number this resource was defined on. */ uint32_t line; /** * Comment string reference. */ android::ResStringPool_ref comment; }; struct Public_entry { uint16_t entryId; Loading @@ -143,8 +169,7 @@ struct Public_entry { uint16_t state; android::ResStringPool_ref key; android::ResStringPool_ref source; uint32_t sourceLine; ResTable_entry_source source; }; /** Loading Loading @@ -173,28 +198,7 @@ struct SymbolTable_entry { * The index into the string pool where the name of this * symbol exists. */ uint32_t stringIndex; }; /** * A structure representing the source of a resourc entry. * Appears after an android::ResTable_entry or android::ResTable_map_entry. * * TODO(adamlesinski): This causes some issues when runtime code checks * the size of an android::ResTable_entry. It assumes it is an * android::ResTable_map_entry if the size is bigger than an android::ResTable_entry * which may not be true if this structure is present. */ struct ResTable_entry_source { /** * Index into the source string pool. */ uint32_t pathIndex; /** * Line number this resource was defined on. */ uint32_t line; android::ResStringPool_ref name; }; /** Loading
tools/aapt2/flatten/TableFlattener.cpp +18 −5 Original line number Diff line number Diff line Loading @@ -54,9 +54,16 @@ static void strcpy16_htod(uint16_t* dst, size_t len, const StringPiece16& src) { struct FlatEntry { ResourceEntry* entry; Value* value; // The entry string pool index to the entry's name. uint32_t entryKey; // The source string pool index to the source file path. uint32_t sourcePathKey; uint32_t sourceLine; // The source string pool index to the comment. uint32_t commentKey; }; class SymbolWriter { Loading Loading @@ -318,8 +325,9 @@ private: if (mOptions.useExtendedChunks) { // Write the extra source block. This will be ignored by the Android runtime. ResTable_entry_source* sourceBlock = buffer->nextBlock<ResTable_entry_source>(); sourceBlock->pathIndex = util::hostToDevice32(entry->sourcePathKey); sourceBlock->path.index = util::hostToDevice32(entry->sourcePathKey); sourceBlock->line = util::hostToDevice32(entry->sourceLine); sourceBlock->comment.index = util::hostToDevice32(entry->commentKey); outEntry->size += sizeof(*sourceBlock); } Loading Loading @@ -486,12 +494,14 @@ private: publicEntry->entryId = util::hostToDevice32(entry->id.value()); publicEntry->key.index = util::hostToDevice32(mKeyPool.makeRef( entry->name).getIndex()); publicEntry->source.index = util::hostToDevice32(mSourcePool->makeRef( publicEntry->source.path.index = util::hostToDevice32(mSourcePool->makeRef( util::utf8ToUtf16(entry->symbolStatus.source.path)).getIndex()); if (entry->symbolStatus.source.line) { publicEntry->sourceLine = util::hostToDevice32( publicEntry->source.line = util::hostToDevice32( entry->symbolStatus.source.line.value()); } publicEntry->source.comment.index = util::hostToDevice32(mSourcePool->makeRef( entry->symbolStatus.comment).getIndex()); switch (entry->symbolStatus.state) { case SymbolState::kPrivate: Loading Loading @@ -565,13 +575,16 @@ private: lineNumber = value->getSource().line.value(); } const StringPool::Ref commentRef = mSourcePool->makeRef(value->getComment()); configToEntryListMap[configValue.config] .push_back(FlatEntry{ entry, value, keyIndex, (uint32_t) sourceRef.getIndex(), lineNumber }); lineNumber, (uint32_t) commentRef.getIndex() }); } } Loading Loading @@ -680,7 +693,7 @@ bool TableFlattener::consume(IAaptContext* context, ResourceTable* table) { // Update the offsets to their final values. if (symbolEntryData) { for (SymbolWriter::Entry& entry : symbolOffsets) { symbolEntryData->stringIndex = util::hostToDevice32(entry.name.getIndex()); symbolEntryData->name.index = util::hostToDevice32(entry.name.getIndex()); // The symbols were all calculated with the packageBuffer offset. We need to // add the beginning of the output buffer. Loading
tools/aapt2/java/AnnotationProcessor.cpp +19 −11 Original line number Diff line number Diff line Loading @@ -21,16 +21,10 @@ namespace aapt { void AnnotationProcessor::appendCommentLine(const StringPiece16& line) { void AnnotationProcessor::appendCommentLine(const std::string& comment) { static const std::string sDeprecated = "@deprecated"; static const std::string sSystemApi = "@SystemApi"; if (line.empty()) { return; } std::string comment = util::utf16ToUtf8(line); if (comment.find(sDeprecated) != std::string::npos && !mDeprecated) { mDeprecated = true; if (!mAnnotations.empty()) { Loading Loading @@ -63,14 +57,28 @@ void AnnotationProcessor::appendCommentLine(const StringPiece16& line) { void AnnotationProcessor::appendComment(const StringPiece16& comment) { // We need to process line by line to clean-up whitespace and append prefixes. for (StringPiece16 line : util::tokenize(comment, u'\n')) { appendCommentLine(util::trimWhitespace(line)); line = util::trimWhitespace(line); if (!line.empty()) { appendCommentLine(util::utf16ToUtf8(line)); } } } void AnnotationProcessor::appendComment(const StringPiece& comment) { for (StringPiece line : util::tokenize(comment, '\n')) { line = util::trimWhitespace(line); if (!line.empty()) { appendCommentLine(line.toString()); } } } std::string AnnotationProcessor::buildComment() { if (!mComment.empty()) { mComment += "\n"; mComment += mPrefix; mComment += " */"; } return std::move(mComment); } Loading
tools/aapt2/java/AnnotationProcessor.h +2 −1 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ public: * we need to collect all the comments. */ void appendComment(const StringPiece16& comment); void appendComment(const StringPiece& comment); /** * Finishes the comment and moves it to the caller. Subsequent calls to buildComment() have Loading @@ -85,7 +86,7 @@ private: bool mDeprecated = false; bool mSystemApi = false; void appendCommentLine(const StringPiece16& line); void appendCommentLine(const std::string& line); }; } // namespace aapt Loading
tools/aapt2/java/JavaClassGenerator.cpp +114 −7 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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( "<p>May be a reference to another resource, in the form\n" "\"<code>@[+][<i>package</i>:]<i>type</i>/<i>name</i></code>\" or a theme\n" "attribute in the form\n" "\"<code>?[<i>package</i>:]<i>type</i>/<i>name</i></code>\"."); } if (typeMask & android::ResTable_map::TYPE_STRING) { processor->appendComment( "<p>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("<p>May be an integer value, such as \"<code>100</code>\"."); } if (typeMask & android::ResTable_map::TYPE_BOOLEAN) { processor->appendComment( "<p>May be a boolean value, such as \"<code>true</code>\" or\n" "\"<code>false</code>\"."); } if (typeMask & android::ResTable_map::TYPE_COLOR) { processor->appendComment( "<p>May be a color value, in the form of \"<code>#<i>rgb</i></code>\",\n" "\"<code>#<i>argb</i></code>\", \"<code>#<i>rrggbb</i></code\", or \n" "\"<code>#<i>aarrggbb</i></code>\"."); } if (typeMask & android::ResTable_map::TYPE_FLOAT) { processor->appendComment( "<p>May be a floating point value, such as \"<code>1.2</code>\"."); } if (typeMask & android::ResTable_map::TYPE_DIMENSION) { processor->appendComment( "<p>May be a dimension value, which is a floating point number appended with a\n" "unit such as \"<code>14.5sp</code>\".\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( "<p>May be a fractional value, which is a floating point number appended with\n" "either % or %p, such as \"<code>14.5%</code>\".\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( "<p>Must be one or more (separated by '|') of the following " "constant values.</p>"); } else { processor->appendComment("<p>Must be one of the following constant values.</p>"); } processor->appendComment("<table>\n<colgroup align=\"left\" />\n" "<colgroup align=\"left\" />\n" "<colgroup align=\"left\" />\n" "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>\n"); for (const Attribute::Symbol& symbol : attr->symbols) { std::stringstream line; line << "<tr><td>" << symbol.symbol.name.value().entry << "</td>" << "<td>" << std::hex << symbol.value << std::dec << "</td>" << "<td>" << util::trimWhitespace(symbol.symbol.getComment()) << "</td></tr>"; processor->appendComment(line.str()); } processor->appendComment("</table>"); } } bool JavaClassGenerator::generateType(const StringPiece16& packageNameToGenerate, const ResourceTablePackage* package, const ResourceTableType* type, Loading Loading @@ -186,6 +267,32 @@ bool JavaClassGenerator::generateType(const StringPiece16& packageNameToGenerate generateStyleable(packageNameToGenerate, unmangledName, static_cast<const Styleable*>( entry->values.front().value.get()), out); } else { 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<Attribute>(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"; } Loading