1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ast/ast.h"
17
18 #include <cstdlib>
19
20 #include "util/string_builder.h"
21
22 namespace OHOS {
23 namespace Idl {
24 AST::TypeStringMap AST::basicTypes_ = {
25 {"void", new ASTVoidType() },
26 {"boolean", new ASTBooleanType() },
27 {"byte", new ASTByteType() },
28 {"short", new ASTShortType() },
29 {"int", new ASTIntegerType() },
30 {"long", new ASTLongType() },
31 {"float", new ASTFloatType() },
32 {"double", new ASTDoubleType() },
33 {"String", new ASTStringType() },
34 {"String16", new ASTString16Type() },
35 {"char", new ASTCharType() },
36 {"unsigned char", new ASTUcharType() },
37 {"unsigned short", new ASTUshortType() },
38 {"unsigned int", new ASTUintType() },
39 {"unsigned long", new ASTUlongType() },
40 {"FileDescriptor", new ASTFdType() },
41 {"Ashmem", new ASTAshmemType() },
42 {"NativeBuffer", new ASTNativeBufferType()},
43 {"Pointer", new ASTPointerType() },
44 };
45
SetIdlFile(const std::string & idlFile)46 void AST::SetIdlFile(const std::string &idlFile)
47 {
48 idlFilePath_ = idlFile;
49 #ifdef __MINGW32__
50 size_t index = idlFilePath_.rfind('\\');
51 #else
52 size_t index = idlFilePath_.rfind('/');
53 #endif
54
55 size_t end = idlFilePath_.rfind(".idl");
56 if (end == std::string::npos) {
57 end = idlFile.size();
58 }
59
60 name_ = StringHelper::SubStr(idlFilePath_, (index == std::string::npos) ? 0 : (index + 1), end);
61 }
62
SetFullName(const std::string & fullName)63 void AST::SetFullName(const std::string &fullName)
64 {
65 std::string name = fullName;
66 size_t start = fullName.rfind("..");
67 if (start != std::string::npos) {
68 name = StringHelper::SubStr(fullName, start + strlen(".."));
69 }
70 size_t index = name.rfind('.');
71 if (index != std::string::npos) {
72 packageName_ = StringHelper::SubStr(name, 0, index);
73 name_ = StringHelper::SubStr(name, index + 1);
74 } else {
75 packageName_ = "";
76 name_ = name;
77 }
78 }
79
SetPackageName(const std::string & packageName)80 void AST::SetPackageName(const std::string &packageName)
81 {
82 packageName_ = packageName;
83 ParseNamespace(packageName_);
84 }
85
ParseNamespace(const std::string & nspaceStr)86 AutoPtr<ASTNamespace> AST::ParseNamespace(const std::string &nspaceStr)
87 {
88 AutoPtr<ASTNamespace> currNspace;
89 size_t begin = 0;
90 size_t index = 0;
91 while ((index = nspaceStr.find('.', begin)) != std::string::npos) {
92 std::string ns = StringHelper::SubStr(nspaceStr, begin, index);
93 AutoPtr<ASTNamespace> nspace;
94 if (currNspace == nullptr) {
95 nspace = NewNameSpace(ns);
96 } else {
97 nspace = currNspace->FindNamespace(ns);
98 if (nspace == nullptr) {
99 nspace = new ASTNamespace(ns);
100 currNspace->AddNamespace(nspace);
101 }
102 }
103 currNspace = nspace;
104 begin = index + 1;
105 }
106 if (currNspace == nullptr) {
107 currNspace = NewNameSpace("");
108 }
109 return currNspace;
110 }
111
NewNameSpace(std::string nameSpace)112 AutoPtr<ASTNamespace> AST::NewNameSpace(std::string nameSpace)
113 {
114 AutoPtr<ASTNamespace> currNspace = FindNamespace(nameSpace);
115 if (currNspace == nullptr) {
116 currNspace = new ASTNamespace(nameSpace);
117 AddNamespace(currNspace);
118 }
119 return currNspace;
120 }
121
AddNamespace(const AutoPtr<ASTNamespace> & nspace)122 void AST::AddNamespace(const AutoPtr<ASTNamespace> &nspace)
123 {
124 if (nspace == nullptr) {
125 return;
126 }
127 namespaces_.push_back(nspace);
128 }
129
FindNamespace(const std::string & nspaceStr)130 AutoPtr<ASTNamespace> AST::FindNamespace(const std::string &nspaceStr)
131 {
132 for (auto nspace : namespaces_) {
133 if (nspace->ToShortString() == nspaceStr) {
134 return nspace;
135 }
136 }
137 return nullptr;
138 }
139
GetNamespace(size_t index)140 AutoPtr<ASTNamespace> AST::GetNamespace(size_t index)
141 {
142 if (index >= namespaces_.size()) {
143 return nullptr;
144 }
145
146 return namespaces_[index];
147 }
148
AddInterfaceDef(const AutoPtr<ASTInterfaceType> & interface)149 void AST::AddInterfaceDef(const AutoPtr<ASTInterfaceType> &interface)
150 {
151 if (interface == nullptr) {
152 return;
153 }
154
155 interfaceDefs_.push_back(interface);
156 AddType(interface.Get());
157 }
158
GetInterfaceDef(size_t index)159 AutoPtr<ASTInterfaceType> AST::GetInterfaceDef(size_t index)
160 {
161 if (index >= interfaceDefs_.size()) {
162 return nullptr;
163 }
164
165 return interfaceDefs_[index];
166 }
167
GetSequenceableDef(size_t index)168 AutoPtr<ASTSequenceableType> AST::GetSequenceableDef(size_t index)
169 {
170 if (index >= sequenceableDefs_.size()) {
171 return nullptr;
172 }
173
174 return sequenceableDefs_[index];
175 }
176
AddSequenceableDef(const AutoPtr<ASTSequenceableType> & sequenceable)177 void AST::AddSequenceableDef(const AutoPtr<ASTSequenceableType> &sequenceable)
178 {
179 if (sequenceable == nullptr) {
180 return;
181 }
182
183 sequenceableDefs_.push_back(sequenceable);
184 AddType(sequenceable.Get());
185 }
186
GetRawDataDef(size_t index)187 AutoPtr<ASTRawDataType> AST::GetRawDataDef(size_t index)
188 {
189 if (index >= rawdataDefs_.size()) {
190 return nullptr;
191 }
192
193 return rawdataDefs_[index];
194 }
195
AddRawDataDef(const AutoPtr<ASTRawDataType> & rawdata)196 void AST::AddRawDataDef(const AutoPtr<ASTRawDataType> &rawdata)
197 {
198 if (rawdata == nullptr) {
199 return;
200 }
201
202 rawdataDefs_.push_back(rawdata);
203 AddType(rawdata.Get());
204 }
205
IndexOf(ASTInterfaceType * interface)206 int AST::IndexOf(ASTInterfaceType* interface)
207 {
208 for (size_t i = 0; i < interfaceDefs_.size(); i++) {
209 if (interfaceDefs_[i] == interface) {
210 return i;
211 }
212 }
213 return -1;
214 }
215
IndexOf(ASTSequenceableType * sequenceable)216 int AST::IndexOf(ASTSequenceableType* sequenceable)
217 {
218 for (size_t i = 0; i < sequenceableDefs_.size(); i++) {
219 if (sequenceableDefs_[i] == sequenceable) {
220 return i;
221 }
222 }
223 return -1;
224 }
225
IndexOf(ASTRawDataType * rawdata)226 int AST::IndexOf(ASTRawDataType* rawdata)
227 {
228 for (size_t i = 0; i < rawdataDefs_.size(); i++) {
229 if (rawdataDefs_[i] == rawdata) {
230 return i;
231 }
232 }
233 return -1;
234 }
235
IndexOf(ASTType * type)236 int AST::IndexOf(ASTType* type)
237 {
238 int i = 0;
239 for (auto it = types_.begin(); it != types_.end(); ++it, ++i) {
240 if (it->second == type) {
241 return i;
242 }
243 }
244 return -1;
245 }
246
AddType(const AutoPtr<ASTType> & type)247 void AST::AddType(const AutoPtr<ASTType> &type)
248 {
249 if (type == nullptr) {
250 return;
251 }
252
253 types_[type->ToString()] = type;
254 }
255
FindType(const std::string & typeName,bool lookImports)256 AutoPtr<ASTType> AST::FindType(const std::string &typeName, bool lookImports)
257 {
258 if (typeName.empty()) {
259 return nullptr;
260 }
261
262 for (const auto &type : types_) {
263 if ((typeName.find('.') == std::string::npos && type.second->GetName() == typeName) ||
264 type.first == typeName) {
265 return type.second;
266 }
267 }
268
269 auto basicTypePair = basicTypes_.find(typeName);
270 if (basicTypePair != basicTypes_.end()) {
271 return basicTypePair->second;
272 }
273
274 if (!lookImports) {
275 return nullptr;
276 }
277
278 AutoPtr<ASTType> type = nullptr;
279 for (const auto &importPair : imports_) {
280 type = importPair.second->FindType(typeName, false);
281 if (type != nullptr) {
282 break;
283 }
284 }
285 return type;
286 }
287
AddTypeDefinition(const AutoPtr<ASTType> & type)288 void AST::AddTypeDefinition(const AutoPtr<ASTType> &type)
289 {
290 if (type == nullptr) {
291 return;
292 }
293
294 AddType(type);
295 typeDefinitions_.push_back(type);
296 }
297
GetTypeDefintion(size_t index)298 AutoPtr<ASTType> AST::GetTypeDefintion(size_t index)
299 {
300 if (index >= typeDefinitions_.size()) {
301 return nullptr;
302 }
303 return typeDefinitions_[index];
304 }
305
Dump(const std::string & prefix)306 std::string AST::Dump(const std::string &prefix)
307 {
308 StringBuilder sb;
309
310 sb.Append(prefix);
311 if (Options::GetInstance().GetInterfaceType() == InterfaceType::SA) {
312 sb.Append("Module[");
313 } else {
314 sb.Append("AST[");
315 }
316 sb.Append("name: ").Append(name_).Append(" ");
317 sb.Append("file: ").Append(idlFilePath_);
318 sb.Append("]\n");
319
320 if (!packageName_.empty()) {
321 sb.Append("package ").Append(packageName_).Append(";");
322 sb.Append('\n');
323 sb.Append('\n');
324 }
325
326 if (imports_.size() > 0) {
327 std::string Keyword = "import";
328 if (Options::GetInstance().GetInterfaceType() == InterfaceType::SA) {
329 Keyword = "sequenceable";
330 }
331 for (const auto &import : imports_) {
332 sb.AppendFormat("%s %s;\n", Keyword.c_str(), import.first.c_str());
333 }
334 sb.Append("\n");
335 }
336
337 if (typeDefinitions_.size() > 0) {
338 for (auto type : typeDefinitions_) {
339 std::string info = type->Dump("");
340 sb.Append(info).Append("\n");
341 }
342 }
343
344 if (interfaceDefs_.size() > 0) {
345 for (auto type : interfaceDefs_) {
346 if (type->IsExternal()) {
347 std::string info = type->Dump("");
348 sb.Append(info).Append("\n");
349 }
350 }
351
352 for (auto type : interfaceDefs_) {
353 if (!type->IsExternal()) {
354 std::string info = type->Dump("");
355 sb.Append(info).Append("\n");
356 }
357 }
358 }
359
360 return sb.ToString();
361 }
362
AddImport(const AutoPtr<AST> & importAst)363 bool AST::AddImport(const AutoPtr<AST> &importAst)
364 {
365 if (imports_.find(importAst->GetFullName()) != imports_.end()) {
366 return false;
367 }
368
369 imports_[importAst->GetFullName()] = importAst;
370
371 return true;
372 }
373
AddImportName(const std::string & importName)374 void AST::AddImportName(const std::string &importName)
375 {
376 importNames_.emplace_back(importName);
377 }
378
SetVersion(size_t & majorVer,size_t & minorVer)379 void AST::SetVersion(size_t &majorVer, size_t &minorVer)
380 {
381 majorVersion_ = majorVer;
382 minorVersion_ = minorVer;
383 }
384
IsValid()385 bool AST::IsValid()
386 {
387 if (name_.empty()) {
388 return false;
389 }
390
391 return interfaceDefs_.size() > 0;
392 }
393
394 } // namespace Idl
395 } // namespace OHOS