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