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 22namespace OHOS { 23namespace Idl { 24AST::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 46void 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 63void 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 80void AST::SetPackageName(const std::string &packageName) 81{ 82 packageName_ = packageName; 83 ParseNamespace(packageName_); 84} 85 86AutoPtr<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 112AutoPtr<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 122void AST::AddNamespace(const AutoPtr<ASTNamespace> &nspace) 123{ 124 if (nspace == nullptr) { 125 return; 126 } 127 namespaces_.push_back(nspace); 128} 129 130AutoPtr<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 140AutoPtr<ASTNamespace> AST::GetNamespace(size_t index) 141{ 142 if (index >= namespaces_.size()) { 143 return nullptr; 144 } 145 146 return namespaces_[index]; 147} 148 149void 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 159AutoPtr<ASTInterfaceType> AST::GetInterfaceDef(size_t index) 160{ 161 if (index >= interfaceDefs_.size()) { 162 return nullptr; 163 } 164 165 return interfaceDefs_[index]; 166} 167 168AutoPtr<ASTSequenceableType> AST::GetSequenceableDef(size_t index) 169{ 170 if (index >= sequenceableDefs_.size()) { 171 return nullptr; 172 } 173 174 return sequenceableDefs_[index]; 175} 176 177void 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 187int AST::IndexOf(ASTInterfaceType* interface) 188{ 189 for (size_t i = 0; i < interfaceDefs_.size(); i++) { 190 if (interfaceDefs_[i] == interface) { 191 return i; 192 } 193 } 194 return -1; 195} 196 197int AST::IndexOf(ASTSequenceableType* sequenceable) 198{ 199 for (size_t i = 0; i < sequenceableDefs_.size(); i++) { 200 if (sequenceableDefs_[i] == sequenceable) { 201 return i; 202 } 203 } 204 return -1; 205} 206 207int AST::IndexOf(ASTType* type) 208{ 209 int i = 0; 210 for (auto it = types_.begin(); it != types_.end(); ++it, ++i) { 211 if (it->second == type) { 212 return i; 213 } 214 } 215 return -1; 216} 217 218void AST::AddType(const AutoPtr<ASTType> &type) 219{ 220 if (type == nullptr) { 221 return; 222 } 223 224 types_[type->ToString()] = type; 225} 226 227AutoPtr<ASTType> AST::FindType(const std::string &typeName, bool lookImports) 228{ 229 if (typeName.empty()) { 230 return nullptr; 231 } 232 233 for (const auto &type : types_) { 234 if ((typeName.find('.') == std::string::npos && type.second->GetName() == typeName) || 235 type.first == typeName) { 236 return type.second; 237 } 238 } 239 240 auto basicTypePair = basicTypes_.find(typeName); 241 if (basicTypePair != basicTypes_.end()) { 242 return basicTypePair->second; 243 } 244 245 if (!lookImports) { 246 return nullptr; 247 } 248 249 AutoPtr<ASTType> type = nullptr; 250 for (const auto &importPair : imports_) { 251 type = importPair.second->FindType(typeName, false); 252 if (type != nullptr) { 253 break; 254 } 255 } 256 return type; 257} 258 259void AST::AddTypeDefinition(const AutoPtr<ASTType> &type) 260{ 261 if (type == nullptr) { 262 return; 263 } 264 265 AddType(type); 266 typeDefinitions_.push_back(type); 267} 268 269AutoPtr<ASTType> AST::GetTypeDefintion(size_t index) 270{ 271 if (index >= typeDefinitions_.size()) { 272 return nullptr; 273 } 274 return typeDefinitions_[index]; 275} 276 277std::string AST::Dump(const std::string &prefix) 278{ 279 StringBuilder sb; 280 281 sb.Append(prefix); 282 if (Options::GetInstance().GetInterfaceType() == InterfaceType::SA) { 283 sb.Append("Module["); 284 } else { 285 sb.Append("AST["); 286 } 287 sb.Append("name: ").Append(name_).Append(" "); 288 sb.Append("file: ").Append(idlFilePath_); 289 sb.Append("]\n"); 290 291 if (!packageName_.empty()) { 292 sb.Append("package ").Append(packageName_).Append(";"); 293 sb.Append('\n'); 294 sb.Append('\n'); 295 } 296 297 if (imports_.size() > 0) { 298 std::string Keyword = "import"; 299 if (Options::GetInstance().GetInterfaceType() == InterfaceType::SA) { 300 Keyword = "sequenceable"; 301 } 302 for (const auto &import : imports_) { 303 sb.AppendFormat("%s %s;\n", Keyword.c_str(), import.first.c_str()); 304 } 305 sb.Append("\n"); 306 } 307 308 if (typeDefinitions_.size() > 0) { 309 for (auto type : typeDefinitions_) { 310 std::string info = type->Dump(""); 311 sb.Append(info).Append("\n"); 312 } 313 } 314 315 if (interfaceDefs_.size() > 0) { 316 for (auto type : interfaceDefs_) { 317 if (type->IsExternal()) { 318 std::string info = type->Dump(""); 319 sb.Append(info).Append("\n"); 320 } 321 } 322 323 for (auto type : interfaceDefs_) { 324 if (!type->IsExternal()) { 325 std::string info = type->Dump(""); 326 sb.Append(info).Append("\n"); 327 } 328 } 329 } 330 331 return sb.ToString(); 332} 333 334bool AST::AddImport(const AutoPtr<AST> &importAst) 335{ 336 if (imports_.find(importAst->GetFullName()) != imports_.end()) { 337 return false; 338 } 339 340 imports_[importAst->GetFullName()] = importAst; 341 342 return true; 343} 344 345void AST::SetVersion(size_t &majorVer, size_t &minorVer) 346{ 347 majorVersion_ = majorVer; 348 minorVersion_ = minorVer; 349} 350 351bool AST::IsValid() 352{ 353 if (name_.empty()) { 354 return false; 355 } 356 357 return interfaceDefs_.size() > 0; 358} 359 360} // namespace Idl 361} // namespace OHOS