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,bool strip_api_annotations) const26 void ClassMember::Print(bool /*final*/, Printer* printer, bool strip_api_annotations) const {
27 processor_.Print(printer, strip_api_annotations);
28 }
29
AppendStatement(StringPiece statement)30 void MethodDefinition::AppendStatement(StringPiece statement) {
31 statements_.emplace_back(statement);
32 }
33
Print(bool final,Printer * printer,bool) const34 void MethodDefinition::Print(bool final, Printer* printer, bool) 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,bool strip_api_annotations) const77 void ClassDefinition::Print(bool final, Printer* printer, bool strip_api_annotations) const {
78 if (empty() && !create_if_empty_) {
79 return;
80 }
81
82 ClassMember::Print(final, printer, strip_api_annotations);
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, strip_api_annotations);
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,StringPiece package,bool final,bool strip_api_annotations,android::OutputStream * out)113 void ClassDefinition::WriteJavaFile(const ClassDefinition* def, StringPiece package, bool final,
114 bool strip_api_annotations, android::OutputStream* out) {
115 Printer printer(out);
116 printer.Print(sWarningHeader).Print("package ").Print(package).Println(";");
117 printer.Println();
118 def->Print(final, &printer, strip_api_annotations);
119 }
120
121 } // namespace aapt
122