• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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