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 "CompositeDeclaration.h"
18 #include "FunctionDeclaration.h"
19 #include "VarDeclaration.h"
20 #include "Declaration.h"
21
22 #include <algorithm>
23 #include <iostream>
24 #include <string>
25
26 namespace android {
27
CompositeDeclaration(const Type::Qualifier::Qualification qualifier,const std::string & name,std::vector<android::Declaration * > * fieldDeclarations)28 CompositeDeclaration::CompositeDeclaration(
29 const Type::Qualifier::Qualification qualifier,
30 const std::string &name,
31 std::vector<android::Declaration *> *fieldDeclarations)
32 : Declaration(""),
33 mQualifier(qualifier),
34 mFieldDeclarations(fieldDeclarations)
35 {
36 setName(name);
37 }
38
~CompositeDeclaration()39 CompositeDeclaration::~CompositeDeclaration() {
40 if(mFieldDeclarations != nullptr) {
41 for(auto* decl : *mFieldDeclarations) {
42 delete decl;
43 }
44 }
45 delete mFieldDeclarations;
46 }
47
setName(const std::string & name)48 void CompositeDeclaration::setName(const std::string &name) {
49 Declaration::setName(name);
50 forcePascalCase();
51 }
52
getQualifier() const53 const Type::Qualifier::Qualification &CompositeDeclaration::getQualifier() const {
54 return mQualifier;
55 }
56 const std::vector<android::Declaration *>*
getFieldDeclarations() const57 CompositeDeclaration::getFieldDeclarations() const {
58 return mFieldDeclarations;
59 }
60
generateInterface(Formatter & out) const61 void CompositeDeclaration::generateInterface(Formatter &out) const {
62 generateCommentText(out);
63 out << "interface " << getInterfaceName() << " {\n\n";
64
65 generateBody(out);
66
67 out << "};\n";
68 }
69
generateSource(Formatter & out) const70 void CompositeDeclaration::generateSource(Formatter &out) const {
71 CHECK(mQualifier == Type::Qualifier::STRUCT ||
72 mQualifier == Type::Qualifier::UNION ||
73 mQualifier == Type::Qualifier::ENUM);
74
75 out << Type::qualifierText(mQualifier) << " " << getName();
76
77 if (mQualifier == Type::Qualifier::ENUM) {
78 out << " : ";
79
80 if (mEnumTypeName.empty()) {
81 out << "int32_t /* NOTE: type is guessed */";
82 } else {
83 out << mEnumTypeName;
84 }
85
86 }
87
88 out << " {\n";
89
90 generateBody(out);
91
92 out << "};\n";
93 }
94
generateBody(Formatter & out) const95 void CompositeDeclaration::generateBody(Formatter &out) const {
96 out.indent();
97
98 for (auto *declaration : *mFieldDeclarations) {
99 declaration->generateCommentText(out);
100 declaration->generateSource(out);
101 out << "\n";
102 }
103
104 out.unindent();
105 }
106
processContents(AST & ast)107 void CompositeDeclaration::processContents(AST &ast) {
108 for (auto &declaration : *mFieldDeclarations) {
109 declaration->processContents(ast);
110 }
111
112 if (isInterface()) {
113 // move non function fields into a containing struct
114
115 auto nonFpDecs = new std::vector<Declaration*>;
116
117 auto it = mFieldDeclarations->begin();
118 while (it != mFieldDeclarations->end()) {
119 if((*it)->decType() != FunctionDeclaration::type()) {
120 bool keep = true;
121 if((*it)->decType() == VarDeclaration::type()) {
122 VarDeclaration* var = (VarDeclaration *)(*it);
123 // Conventional HALs were all required to have
124 // a member of this type.
125 // This member is no longer needed for HIDL
126 if(var->getType()->isHwDevice()) {
127 keep = false;
128 }
129 }
130
131 if (keep) {
132 nonFpDecs->push_back(*it);
133 }
134 it = mFieldDeclarations->erase(it);
135 } else {
136 it++;
137 }
138 }
139
140 if (!nonFpDecs->empty()) {
141 auto subStruct = new CompositeDeclaration(Type::Qualifier::STRUCT,
142 getName(),
143 nonFpDecs);
144
145 mFieldDeclarations->insert(mFieldDeclarations->begin(), subStruct);
146 }
147 }
148 }
149
getInterfaceName() const150 std::string CompositeDeclaration::getInterfaceName() const {
151 return "I" + getName();
152 }
153
isInterface() const154 bool CompositeDeclaration::isInterface() const {
155 if (mQualifier != Type::Qualifier::STRUCT) {
156 return false;
157 }
158
159 for (auto &declaration : *mFieldDeclarations) {
160 if (declaration->decType() == FunctionDeclaration::type()) {
161 return true;
162 }
163 }
164 return false;
165 }
166
setEnumTypeName(const std::string & name)167 void CompositeDeclaration::setEnumTypeName(const std::string &name) {
168 CHECK(mQualifier == Type::Qualifier::ENUM);
169
170 mEnumTypeName = name;
171 }
172
173 } //namespace android
174