Home | History | Annotate | Download | only in java
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "java/ClassDefinition.h"
     18 
     19 #include "androidfw/StringPiece.h"
     20 
     21 using ::aapt::text::Printer;
     22 using ::android::StringPiece;
     23 
     24 namespace aapt {
     25 
     26 void ClassMember::Print(bool /*final*/, Printer* printer) const {
     27   processor_.Print(printer);
     28 }
     29 
     30 void MethodDefinition::AppendStatement(const StringPiece& statement) {
     31   statements_.push_back(statement.to_string());
     32 }
     33 
     34 void MethodDefinition::Print(bool final, Printer* printer) const {
     35   printer->Print(signature_).Println(" {");
     36   printer->Indent();
     37   for (const auto& statement : statements_) {
     38     printer->Println(statement);
     39   }
     40   printer->Undent();
     41   printer->Print("}");
     42 }
     43 
     44 ClassDefinition::Result ClassDefinition::AddMember(std::unique_ptr<ClassMember> member) {
     45   Result result = Result::kAdded;
     46   auto iter = indexed_members_.find(member->GetName());
     47   if (iter != indexed_members_.end()) {
     48     // Overwrite the entry. Be careful, as the key in indexed_members_ is actually memory owned
     49     // by the value at ordered_members_[index]. Since overwriting a value for a key doesn't replace
     50     // the key (the initial key inserted into the unordered_map is kept), we must erase and then
     51     // insert a new key, whose memory is being kept around. We do all this to avoid using more
     52     // memory for each key.
     53     size_t index = iter->second;
     54 
     55     // Erase the key + value from the map.
     56     indexed_members_.erase(iter);
     57 
     58     // Now clear the memory that was backing the key (now erased).
     59     ordered_members_[index].reset();
     60     result = Result::kOverridden;
     61   }
     62 
     63   indexed_members_[member->GetName()] = ordered_members_.size();
     64   ordered_members_.push_back(std::move(member));
     65   return result;
     66 }
     67 
     68 bool ClassDefinition::empty() const {
     69   for (const std::unique_ptr<ClassMember>& member : ordered_members_) {
     70     if (member != nullptr && !member->empty()) {
     71       return false;
     72     }
     73   }
     74   return true;
     75 }
     76 
     77 void ClassDefinition::Print(bool final, Printer* printer) const {
     78   if (empty() && !create_if_empty_) {
     79     return;
     80   }
     81 
     82   ClassMember::Print(final, printer);
     83 
     84   printer->Print("public ");
     85   if (qualifier_ == ClassQualifier::kStatic) {
     86     printer->Print("static ");
     87   }
     88   printer->Print("final class ").Print(name_).Println(" {");
     89   printer->Indent();
     90 
     91   for (const std::unique_ptr<ClassMember>& member : ordered_members_) {
     92     // There can be nullptr members when a member is added to the ClassDefinition
     93     // and takes precedence over a previous member with the same name. The overridden member is
     94     // set to nullptr.
     95     if (member != nullptr) {
     96       member->Print(final, printer);
     97       printer->Println();
     98     }
     99   }
    100 
    101   printer->Undent();
    102   printer->Print("}");
    103 }
    104 
    105 constexpr static const char* sWarningHeader =
    106     "/* AUTO-GENERATED FILE. DO NOT MODIFY.\n"
    107     " *\n"
    108     " * This class was automatically generated by the\n"
    109     " * aapt tool from the resource data it found. It\n"
    110     " * should not be modified by hand.\n"
    111     " */\n\n";
    112 
    113 void ClassDefinition::WriteJavaFile(const ClassDefinition* def, const StringPiece& package,
    114                                     bool final, io::OutputStream* out) {
    115   Printer printer(out);
    116   printer.Print(sWarningHeader).Print("package ").Print(package).Println(";");
    117   printer.Println();
    118   def->Print(final, &printer);
    119 }
    120 
    121 }  // namespace aapt
    122