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