1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "ast/ast.h"
10
11 #include <cstdlib>
12
13 #include "util/string_builder.h"
14
15 namespace OHOS {
16 namespace HDI {
17 AST::TypeStringMap AST::basicTypes_ = {
18 {"boolean", new ASTBooleanType() },
19 {"byte", new ASTByteType() },
20 {"short", new ASTShortType() },
21 {"int", new ASTIntegerType() },
22 {"long", new ASTLongType() },
23 {"float", new ASTFloatType() },
24 {"double", new ASTDoubleType() },
25 {"String", new ASTStringType() },
26 {"unsigned char", new ASTUcharType() },
27 {"unsigned short", new ASTUshortType() },
28 {"unsigned int", new ASTUintType() },
29 {"unsigned long", new ASTUlongType() },
30 {"void", new ASTVoidType() },
31 {"FileDescriptor", new ASTFdType() },
32 {"Ashmem", new ASTAshmemType() },
33 {"BufferHandle", new ASTBufferHandleType()},
34 };
35
SetIdlFile(const std::string & idlFile)36 void AST::SetIdlFile(const std::string &idlFile)
37 {
38 idlFilePath_ = idlFile;
39 #ifdef __MINGW32__
40 size_t index = idlFilePath_.rfind('\\');
41 #else
42 size_t index = idlFilePath_.rfind('/');
43 #endif
44
45 size_t end = idlFilePath_.rfind(".idl");
46 if (end == std::string::npos) {
47 end = idlFile.size();
48 }
49
50 name_ = StringHelper::SubStr(idlFilePath_, (index == std::string::npos) ? 0 : (index + 1), end);
51 }
52
SetFullName(const std::string & fullName)53 void AST::SetFullName(const std::string &fullName)
54 {
55 size_t index = fullName.rfind('.');
56 if (index != std::string::npos) {
57 packageName_ = StringHelper::SubStr(fullName, 0, index);
58 name_ = StringHelper::SubStr(fullName, index + 1);
59 } else {
60 packageName_ = "";
61 name_ = fullName;
62 }
63 }
64
SetPackageName(const std::string & packageName)65 void AST::SetPackageName(const std::string &packageName)
66 {
67 packageName_ = packageName;
68 }
69
GetPackageName()70 std::string AST::GetPackageName()
71 {
72 return packageName_;
73 }
74
ParseNamespace(const std::string & nspaceStr)75 AutoPtr<ASTNamespace> AST::ParseNamespace(const std::string &nspaceStr)
76 {
77 AutoPtr<ASTNamespace> currNspace;
78 size_t begin = 0;
79 size_t index = 0;
80 while ((index = nspaceStr.find('.', begin)) != std::string::npos) {
81 std::string ns = StringHelper::SubStr(nspaceStr, begin, index);
82 AutoPtr<ASTNamespace> nspace;
83 if (currNspace == nullptr) {
84 nspace = FindNamespace(ns);
85 } else {
86 nspace = currNspace->FindNamespace(ns);
87 }
88 if (nspace == nullptr) {
89 nspace = new ASTNamespace(ns);
90 if (currNspace == nullptr) {
91 AddNamespace(nspace);
92 } else {
93 currNspace->AddNamespace(nspace);
94 }
95 }
96 currNspace = nspace;
97 begin = index + 1;
98 }
99 return currNspace;
100 }
101
AddNamespace(const AutoPtr<ASTNamespace> & nspace)102 void AST::AddNamespace(const AutoPtr<ASTNamespace> &nspace)
103 {
104 if (nspace == nullptr) {
105 return;
106 }
107 namespaces_.push_back(nspace);
108 }
109
FindNamespace(const std::string & nspaceStr)110 AutoPtr<ASTNamespace> AST::FindNamespace(const std::string &nspaceStr)
111 {
112 for (auto nspace : namespaces_) {
113 if (nspace->ToShortString() == nspaceStr) {
114 return nspace;
115 }
116 }
117 return nullptr;
118 }
119
GetNamespace(size_t index)120 AutoPtr<ASTNamespace> AST::GetNamespace(size_t index)
121 {
122 if (index >= namespaces_.size()) {
123 return nullptr;
124 }
125
126 return namespaces_[index];
127 }
128
AddInterfaceDef(const AutoPtr<ASTInterfaceType> & interface)129 void AST::AddInterfaceDef(const AutoPtr<ASTInterfaceType> &interface)
130 {
131 if (interface == nullptr) {
132 return;
133 }
134
135 interfaceDef_ = interface;
136 AddType(interface.Get());
137 }
138
AddSequenceableDef(const AutoPtr<ASTSequenceableType> & sequenceable)139 void AST::AddSequenceableDef(const AutoPtr<ASTSequenceableType> &sequenceable)
140 {
141 if (sequenceable == nullptr) {
142 return;
143 }
144
145 sequenceableDef_ = sequenceable;
146 AddType(sequenceable.Get());
147 }
148
AddType(const AutoPtr<ASTType> & type)149 void AST::AddType(const AutoPtr<ASTType> &type)
150 {
151 if (type == nullptr) {
152 return;
153 }
154
155 types_[type->ToString()] = type;
156 }
157
FindType(const std::string & typeName)158 AutoPtr<ASTType> AST::FindType(const std::string &typeName)
159 {
160 if (typeName.empty()) {
161 return nullptr;
162 }
163
164 auto it = types_.find(typeName);
165 if (it != types_.end()) {
166 return it->second;
167 }
168
169 auto basicTypePair = basicTypes_.find(typeName);
170 if (basicTypePair != basicTypes_.end()) {
171 return basicTypePair->second;
172 }
173
174 AutoPtr<ASTType> type = nullptr;
175 for (const auto &importPair : imports_) {
176 type = importPair.second->FindType(typeName);
177 if (type != nullptr) {
178 break;
179 }
180 }
181 return type;
182 }
183
AddTypeDefinition(const AutoPtr<ASTType> & type)184 void AST::AddTypeDefinition(const AutoPtr<ASTType> &type)
185 {
186 if (type == nullptr) {
187 return;
188 }
189
190 AddType(type);
191 typeDefinitions_.push_back(type);
192 }
193
GetTypeDefintion(size_t index)194 AutoPtr<ASTType> AST::GetTypeDefintion(size_t index)
195 {
196 if (index >= typeDefinitions_.size()) {
197 return nullptr;
198 }
199 return typeDefinitions_[index];
200 }
201
Dump(const std::string & prefix)202 std::string AST::Dump(const std::string &prefix)
203 {
204 StringBuilder sb;
205
206 sb.Append(prefix);
207 sb.Append("AST[");
208 sb.Append("name: ").Append(name_).Append(" ");
209 sb.Append("file: ").Append(idlFilePath_);
210 sb.Append("]\n");
211
212 sb.Append("package ").Append(packageName_).Append(";");
213 sb.Append('\n');
214 sb.Append('\n');
215
216 if (imports_.size() > 0) {
217 for (const auto &import : imports_) {
218 sb.AppendFormat("import %s;\n", import.first.c_str());
219 }
220 sb.Append("\n");
221 }
222
223 if (typeDefinitions_.size() > 0) {
224 for (auto type : typeDefinitions_) {
225 std::string info = type->Dump("");
226 sb.Append(info).Append("\n");
227 }
228 }
229
230 if (interfaceDef_ != nullptr) {
231 std::string info = interfaceDef_->Dump("");
232 sb.Append(info).Append("\n");
233 }
234
235 return sb.ToString();
236 }
237
AddImport(const AutoPtr<AST> & importAst)238 bool AST::AddImport(const AutoPtr<AST> &importAst)
239 {
240 if (imports_.find(importAst->GetFullName()) != imports_.end()) {
241 return false;
242 }
243
244 imports_[importAst->GetFullName()] = importAst;
245
246 return true;
247 }
248
SetVersion(size_t & majorVer,size_t & minorVer)249 void AST::SetVersion(size_t &majorVer, size_t &minorVer)
250 {
251 majorVersion_ = majorVer;
252 minorVersion_ = minorVer;
253 }
254 } // namespace HDI
255 } // namespace OHOS