• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Print(bool,Printer * printer) const26 void ClassMember::Print(bool /*final*/, Printer* printer) const {
27   processor_.Print(printer);
28 }
29 
AppendStatement(const StringPiece & statement)30 void MethodDefinition::AppendStatement(const StringPiece& statement) {
31   statements_.push_back(statement.to_string());
32 }
33 
Print(bool final,Printer * printer) const34 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 
AddMember(std::unique_ptr<ClassMember> member)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 
empty() const68 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 
Print(bool final,Printer * printer) const77 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 
WriteJavaFile(const ClassDefinition * def,const StringPiece & package,bool final,io::OutputStream * out)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