* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "ast/ast.h"
#include <cstdlib>
#include "util/string_builder.h"
namespace OHOS {
namespace HDI {
AST::AST()
{
types_["boolean"] = new ASTBooleanType();
types_["byte"] = new ASTByteType();
types_["short"] = new ASTShortType();
types_["int"] = new ASTIntegerType();
types_["long"] = new ASTLongType();
types_["float"] = new ASTFloatType();
types_["double"] = new ASTDoubleType();
types_["String"] = new ASTStringType();
types_["unsigned char"] = new ASTUcharType();
types_["unsigned short"] = new ASTUshortType();
types_["unsigned int"] = new ASTUintType();
types_["unsigned long"] = new ASTUlongType();
types_["void"] = new ASTVoidType();
types_["FileDescriptor"] = new ASTFdType();
types_["Ashmem"] = new ASTAshmemType();
}
void AST::SetIdlFile(const String &idlFile)
{
idlFilePath_ = idlFile;
#ifdef __MINGW32__
int index = idlFilePath_.LastIndexOf('\\');
#else
int index = idlFilePath_.LastIndexOf('/');
#endif
int end = idlFilePath_.LastIndexOf(".idl");
name_ = idlFilePath_.Substring((index == -1) ? 0 : (index + 1), end);
}
void AST::SetFullName(const String &fullName)
{
int index = fullName.LastIndexOf('.');
if (index != -1) {
packageName_ = fullName.Substring(0, index);
name_ = fullName.Substring(index + 1);
} else {
packageName_ = "";
name_ = fullName;
}
}
void AST::SetPackageName(const String &packageName)
{
packageName_ = packageName;
}
String AST::GetPackageName()
{
return packageName_;
}
AutoPtr<ASTNamespace> AST::ParseNamespace(const String &nspaceStr)
{
AutoPtr<ASTNamespace> currNspace;
int begin = 0;
int index = 0;
while ((index = nspaceStr.IndexOf('.', begin)) != -1) {
String ns = nspaceStr.Substring(begin, index);
AutoPtr<ASTNamespace> nspace;
if (currNspace == nullptr) {
nspace = FindNamespace(ns);
} else {
nspace = currNspace->FindNamespace(ns);
}
if (nspace == nullptr) {
nspace = new ASTNamespace(ns);
if (currNspace == nullptr) {
AddNamespace(nspace);
} else {
currNspace->AddNamespace(nspace);
}
}
currNspace = nspace;
begin = index + 1;
}
return currNspace;
}
void AST::AddNamespace(const AutoPtr<ASTNamespace> &nspace)
{
if (nspace == nullptr) {
return;
}
namespaces_.push_back(nspace);
}
AutoPtr<ASTNamespace> AST::FindNamespace(const String &nspaceStr)
{
for (auto nspace : namespaces_) {
if (nspace->ToShortString().Equals(nspaceStr)) {
return nspace;
}
}
return nullptr;
}
AutoPtr<ASTNamespace> AST::GetNamespace(size_t index)
{
if (index >= namespaces_.size()) {
return nullptr;
}
return namespaces_[index];
}
void AST::AddInterfaceDef(const AutoPtr<ASTInterfaceType> &interface)
{
if (interface == nullptr) {
return;
}
interfaceDef_ = interface;
AddType(interface.Get());
}
void AST::AddSequenceableDef(const AutoPtr<ASTSequenceableType> &sequenceable)
{
if (sequenceable == nullptr) {
return;
}
sequenceableDef_ = sequenceable;
AddType(sequenceable.Get());
}
void AST::AddType(const AutoPtr<ASTType> &type)
{
if (type == nullptr) {
return;
}
types_[type->ToString()] = type;
}
AutoPtr<ASTType> AST::FindType(const String &typeName)
{
if (typeName.IsEmpty()) {
return nullptr;
}
auto it = types_.find(typeName);
if (it != types_.end()) {
return it->second;
}
AutoPtr<ASTType> type = nullptr;
for (const auto &importPair : imports_) {
type = importPair.second->FindType(typeName);
if (type != nullptr) {
break;
}
}
return type;
}
void AST::AddTypeDefinition(const AutoPtr<ASTType> &type)
{
if (type == nullptr) {
return;
}
AddType(type);
typeDefinitions_.push_back(type);
}
AutoPtr<ASTType> AST::GetTypeDefintion(size_t index)
{
if (index >= typeDefinitions_.size()) {
return nullptr;
}
return typeDefinitions_[index];
}
String AST::Dump(const String &prefix)
{
StringBuilder sb;
sb.Append(prefix);
sb.Append("AST[");
sb.Append("name: ").Append(name_).Append(" ");
sb.Append("file: ").Append(idlFilePath_);
sb.Append("]\n");
sb.Append("package ").Append(packageName_).Append(";");
sb.Append('\n');
sb.Append('\n');
if (imports_.size() > 0) {
for (const auto &import : imports_) {
sb.AppendFormat("import %s;\n", import.first.string());
}
sb.Append("\n");
}
if (typeDefinitions_.size() > 0) {
for (auto type : typeDefinitions_) {
String info = type->Dump("");
sb.Append(info).Append("\n");
}
}
if (interfaceDef_ != nullptr) {
String info = interfaceDef_->Dump("");
sb.Append(info).Append("\n");
}
return sb.ToString();
}
bool AST::AddImport(const AutoPtr<AST> &importAst)
{
if (imports_.find(importAst->GetFullName()) != imports_.end()) {
return false;
}
imports_[importAst->GetFullName()] = importAst;
return true;
}
void AST::SetVersion(size_t &majorVer, size_t &minorVer)
{
majorVersion_ = majorVer;
minorVersion_ = minorVer;
}
}
}