/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "java/ClassDefinition.h" #include "androidfw/StringPiece.h" using ::aapt::text::Printer; using ::android::StringPiece; namespace aapt { void ClassMember::Print(bool /*final*/, Printer* printer, bool strip_api_annotations) const { processor_.Print(printer, strip_api_annotations); } void MethodDefinition::AppendStatement(const StringPiece& statement) { statements_.push_back(statement.to_string()); } void MethodDefinition::Print(bool final, Printer* printer, bool) const { printer->Print(signature_).Println(" {"); printer->Indent(); for (const auto& statement : statements_) { printer->Println(statement); } printer->Undent(); printer->Print("}"); } ClassDefinition::Result ClassDefinition::AddMember(std::unique_ptr member) { Result result = Result::kAdded; auto iter = indexed_members_.find(member->GetName()); if (iter != indexed_members_.end()) { // Overwrite the entry. Be careful, as the key in indexed_members_ is actually memory owned // by the value at ordered_members_[index]. Since overwriting a value for a key doesn't replace // the key (the initial key inserted into the unordered_map is kept), we must erase and then // insert a new key, whose memory is being kept around. We do all this to avoid using more // memory for each key. size_t index = iter->second; // Erase the key + value from the map. indexed_members_.erase(iter); // Now clear the memory that was backing the key (now erased). ordered_members_[index].reset(); result = Result::kOverridden; } indexed_members_[member->GetName()] = ordered_members_.size(); ordered_members_.push_back(std::move(member)); return result; } bool ClassDefinition::empty() const { for (const std::unique_ptr& member : ordered_members_) { if (member != nullptr && !member->empty()) { return false; } } return true; } void ClassDefinition::Print(bool final, Printer* printer, bool strip_api_annotations) const { if (empty() && !create_if_empty_) { return; } ClassMember::Print(final, printer, strip_api_annotations); printer->Print("public "); if (qualifier_ == ClassQualifier::kStatic) { printer->Print("static "); } printer->Print("final class ").Print(name_).Println(" {"); printer->Indent(); for (const std::unique_ptr& member : ordered_members_) { // There can be nullptr members when a member is added to the ClassDefinition // and takes precedence over a previous member with the same name. The overridden member is // set to nullptr. if (member != nullptr) { member->Print(final, printer, strip_api_annotations); printer->Println(); } } printer->Undent(); printer->Print("}"); } constexpr static const char* sWarningHeader = "/* AUTO-GENERATED FILE. DO NOT MODIFY.\n" " *\n" " * This class was automatically generated by the\n" " * aapt tool from the resource data it found. It\n" " * should not be modified by hand.\n" " */\n\n"; void ClassDefinition::WriteJavaFile(const ClassDefinition* def, const StringPiece& package, bool final, bool strip_api_annotations, io::OutputStream* out) { Printer printer(out); printer.Print(sWarningHeader).Print("package ").Print(package).Println(";"); printer.Println(); def->Print(final, &printer, strip_api_annotations); } } // namespace aapt