1 /*
2 * Copyright (c) 2021-2023 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 {"FileDescriptor", new ASTFdType() },
31 {"Ashmem", new ASTAshmemType() },
32 {"NativeBuffer", new ASTNativeBufferType()},
33 {"Pointer", new ASTPointerType() },
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 ParseNamespace(packageName_);
69 }
70
ParseNamespace(const std::string & nspaceStr)71 AutoPtr<ASTNamespace> AST::ParseNamespace(const std::string &nspaceStr)
72 {
73 AutoPtr<ASTNamespace> currNspace;
74 size_t begin = 0;
75 size_t index = 0;
76 while ((index = nspaceStr.find('.', begin)) != std::string::npos) {
77 std::string ns = StringHelper::SubStr(nspaceStr, begin, index);
78 AutoPtr<ASTNamespace> nspace;
79 if (currNspace == nullptr) {
80 nspace = FindNamespace(ns);
81 } else {
82 nspace = currNspace->FindNamespace(ns);
83 }
84 if (nspace == nullptr) {
85 nspace = new ASTNamespace(ns);
86 if (currNspace == nullptr) {
87 AddNamespace(nspace);
88 } else {
89 currNspace->AddNamespace(nspace);
90 }
91 }
92 currNspace = nspace;
93 begin = index + 1;
94 }
95 return currNspace;
96 }
97
AddNamespace(const AutoPtr<ASTNamespace> & nspace)98 void AST::AddNamespace(const AutoPtr<ASTNamespace> &nspace)
99 {
100 if (nspace == nullptr) {
101 return;
102 }
103 namespaces_.push_back(nspace);
104 }
105
FindNamespace(const std::string & nspaceStr)106 AutoPtr<ASTNamespace> AST::FindNamespace(const std::string &nspaceStr)
107 {
108 for (auto nspace : namespaces_) {
109 if (nspace->ToShortString() == nspaceStr) {
110 return nspace;
111 }
112 }
113 return nullptr;
114 }
115
GetNamespace(size_t index)116 AutoPtr<ASTNamespace> AST::GetNamespace(size_t index)
117 {
118 if (index >= namespaces_.size()) {
119 return nullptr;
120 }
121
122 return namespaces_[index];
123 }
124
AddInterfaceDef(const AutoPtr<ASTInterfaceType> & interface)125 void AST::AddInterfaceDef(const AutoPtr<ASTInterfaceType> &interface)
126 {
127 if (interface == nullptr) {
128 return;
129 }
130
131 interfaceDef_ = interface;
132 AddType(interface.Get());
133 }
134
AddSequenceableDef(const AutoPtr<ASTSequenceableType> & sequenceable)135 void AST::AddSequenceableDef(const AutoPtr<ASTSequenceableType> &sequenceable)
136 {
137 if (sequenceable == nullptr) {
138 return;
139 }
140
141 sequenceableDef_ = sequenceable;
142 AddType(sequenceable.Get());
143 }
144
AddType(const AutoPtr<ASTType> & type)145 void AST::AddType(const AutoPtr<ASTType> &type)
146 {
147 if (type == nullptr) {
148 return;
149 }
150
151 types_[type->ToString()] = type;
152 }
153
FindType(const std::string & typeName,bool lookImports)154 AutoPtr<ASTType> AST::FindType(const std::string &typeName, bool lookImports)
155 {
156 if (typeName.empty()) {
157 return nullptr;
158 }
159
160 for (const auto &type : types_) {
161 if (type.second->GetName() == typeName) {
162 return type.second;
163 }
164 }
165
166 auto basicTypePair = basicTypes_.find(typeName);
167 if (basicTypePair != basicTypes_.end()) {
168 return basicTypePair->second;
169 }
170
171 if (!lookImports) {
172 return nullptr;
173 }
174
175 AutoPtr<ASTType> type = nullptr;
176 for (const auto &importPair : imports_) {
177 type = importPair.second->FindType(typeName, false);
178 if (type != nullptr) {
179 break;
180 }
181 }
182 return type;
183 }
184
AddTypeDefinition(const AutoPtr<ASTType> & type)185 void AST::AddTypeDefinition(const AutoPtr<ASTType> &type)
186 {
187 if (type == nullptr) {
188 return;
189 }
190
191 AddType(type);
192 typeDefinitions_.push_back(type);
193 }
194
GetTypeDefintion(size_t index)195 AutoPtr<ASTType> AST::GetTypeDefintion(size_t index)
196 {
197 if (index >= typeDefinitions_.size()) {
198 return nullptr;
199 }
200 return typeDefinitions_[index];
201 }
202
Dump(const std::string & prefix)203 std::string AST::Dump(const std::string &prefix)
204 {
205 StringBuilder sb;
206
207 sb.Append(prefix);
208 sb.Append("AST[");
209 sb.Append("name: ").Append(name_).Append(" ");
210 sb.Append("file: ").Append(idlFilePath_);
211 sb.Append("]\n");
212
213 sb.Append("package ").Append(packageName_).Append(";");
214 sb.Append('\n');
215 sb.Append('\n');
216
217 if (imports_.size() > 0) {
218 for (const auto &import : imports_) {
219 sb.AppendFormat("import %s;\n", import.first.c_str());
220 }
221 sb.Append("\n");
222 }
223
224 if (typeDefinitions_.size() > 0) {
225 for (auto type : typeDefinitions_) {
226 std::string info = type->Dump("");
227 sb.Append(info).Append("\n");
228 }
229 }
230
231 if (interfaceDef_ != nullptr) {
232 std::string info = interfaceDef_->Dump("");
233 sb.Append(info).Append("\n");
234 }
235
236 return sb.ToString();
237 }
238
AddImport(const AutoPtr<AST> & importAst)239 bool AST::AddImport(const AutoPtr<AST> &importAst)
240 {
241 if (imports_.find(importAst->GetFullName()) != imports_.end()) {
242 return false;
243 }
244
245 imports_[importAst->GetFullName()] = importAst;
246
247 return true;
248 }
249
SetVersion(size_t & majorVer,size_t & minorVer)250 void AST::SetVersion(size_t &majorVer, size_t &minorVer)
251 {
252 majorVersion_ = majorVer;
253 minorVersion_ = minorVer;
254 }
255 } // namespace HDI
256 } // namespace OHOS