| /* | |
| * 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(StringPiece statement) { | |
| statements_.emplace_back(statement); | |
| } | |
| 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<ClassMember> member, | |
| bool can_overwrite) { | |
| Result result = Result::kAdded; | |
| auto iter = indexed_members_.find(member->GetName()); | |
| if (iter != indexed_members_.end()) { | |
| if (!can_overwrite) { | |
| return Result::kAlreadyExists; // Member exists, but overwriting is disallowed. | |
| } | |
| // 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<ClassMember>& 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<ClassMember>& 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, StringPiece package, bool final, | |
| bool strip_api_annotations, android::OutputStream* out) { | |
| Printer printer(out); | |
| printer.Print(sWarningHeader).Print("package ").Print(package).Println(";"); | |
| printer.Println(); | |
| def->Print(final, &printer, strip_api_annotations); | |
| } | |
| } // namespace aapt |