• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <unistd.h>
17 #include <sys/stat.h>
18 #include "sa_code_emitter.h"
19 #include "ast/ast_map_type.h"
20 #include "ast/ast_orderedmap_type.h"
21 #include "type/sa_boolean_type_emitter.h"
22 #include "type/sa_byte_type_emitter.h"
23 #include "type/sa_short_type_emitter.h"
24 #include "type/sa_int_type_emitter.h"
25 #include "type/sa_long_type_emitter.h"
26 #include "type/sa_float_type_emitter.h"
27 #include "type/sa_double_type_emitter.h"
28 #include "type/sa_char_type_emitter.h"
29 #include "type/sa_string_type_emitter.h"
30 #include "type/sa_seq_type_emitter.h"
31 #include "type/sa_rawdata_type_emitter.h"
32 #include "type/sa_interface_type_emitter.h"
33 #include "type/sa_map_type_emitter.h"
34 #include "type/sa_orderedmap_type_emitter.h"
35 #include "type/sa_array_type_emitter.h"
36 #include "type/sa_uchar_type_emitter.h"
37 #include "type/sa_uint_type_emitter.h"
38 #include "type/sa_ulong_type_emitter.h"
39 #include "type/sa_ushort_type_emitter.h"
40 #include "type/sa_fd_type_emitter.h"
41 #include "type/sa_enum_type_emitter.h"
42 #include "type/sa_struct_type_emitter.h"
43 #include "type/sa_union_type_emitter.h"
44 #include "util/file.h"
45 #include "util/options.h"
46 #include "util/logger.h"
47 #include "util/string_helper.h"
48 
49 namespace OHOS {
50 namespace Idl {
51 SACodeEmitter::TypeEmitterMap SACodeEmitter::basicEmitters_ = {
52     {TypeKind::TYPE_BOOLEAN,           new SaBooleanTypeEmitter()     },
53     {TypeKind::TYPE_BYTE,              new SaByteTypeEmitter()        },
54     {TypeKind::TYPE_SHORT,             new SaShortTypeEmitter()       },
55     {TypeKind::TYPE_INT,               new SaIntTypeEmitter()         },
56     {TypeKind::TYPE_LONG,              new SaLongTypeEmitter()        },
57     {TypeKind::TYPE_FLOAT,             new SaFloatTypeEmitter()       },
58     {TypeKind::TYPE_DOUBLE,            new SaDoubleTypeEmitter()      },
59     {TypeKind::TYPE_CHAR,              new SaCharTypeEmitter()        },
60     {TypeKind::TYPE_STRING,            new SaStringTypeEmitter()      },
61     {TypeKind::TYPE_UCHAR,             new SaUcharTypeEmitter()       },
62     {TypeKind::TYPE_UINT,              new SaUintTypeEmitter()        },
63     {TypeKind::TYPE_ULONG,             new SaUlongTypeEmitter()       },
64     {TypeKind::TYPE_USHORT,            new SaUshortTypeEmitter()      },
65     {TypeKind::TYPE_FILEDESCRIPTOR,    new SaFdTypeEmitter()          },
66 };
67 
OutPut(const AutoPtr<AST> & ast,const std::string & targetDirectory,GenMode mode)68 bool SACodeEmitter::OutPut(const AutoPtr<AST> &ast, const std::string &targetDirectory, GenMode mode)
69 {
70     if (!Reset(ast, targetDirectory, mode)) {
71         return false;
72     }
73 
74     EmitCode();
75     return true;
76 }
77 
Reset(const AutoPtr<AST> & ast,const std::string & targetDirectory,GenMode mode)78 bool SACodeEmitter::Reset(const AutoPtr<AST> &ast, const std::string &targetDirectory, GenMode mode)
79 {
80     if ((ast == nullptr) || targetDirectory.empty()) {
81         return false;
82     }
83 
84     CleanData();
85 
86     ast_ = ast;
87     for (auto interface : ast_->GetInterfaceDefs()) {
88         if (interface->IsExternal() == false) {
89             interface_ = interface;
90             break;
91         }
92     }
93     if (interface_ != nullptr) {
94         interfaceName_ = interface_->GetName();
95         interfaceFullName_ = interface_->GetNamespace()->ToString() + interfaceName_;
96         baseName_ = StringHelper::StartWith(interfaceName_, "I") ? interfaceName_.substr(1) : interfaceName_;
97         proxyName_ = baseName_ + "Proxy";
98         proxyFullName_ = interface_->GetNamespace()->ToString() + proxyName_;
99 
100         stubName_ = baseName_ + "Stub";
101         stubFullName_ = interface_->GetNamespace()->ToString() + stubName_;
102 
103         clientName_ = baseName_ + "Client";
104         clientFullName_ = interface_->GetNamespace()->ToString() + clientName_;
105         deathRecipientName_ = StringHelper::StartWith(interfaceName_, "I") ? interfaceName_.substr(1) + "Recipient" :
106             interfaceName_ + "Recipient";
107     } else if (ast_->GetASTFileType() == ASTFileType::AST_TYPES) {
108         baseName_ = ast_->GetName();
109     }
110 
111     if (!ResolveDirectory(targetDirectory)) {
112         return false;
113     }
114 
115     return true;
116 }
117 
CleanData()118 void SACodeEmitter::CleanData()
119 {
120     Options &options = Options::GetInstance();
121 
122     domainId_ = options.GetDomainId();
123     logTag_ = options.GetLogTag();
124     hitraceTag_ = options.GetGenerateHitraceTag();
125     hitraceOn_ = options.DoHitraceState();
126     logOn_ = options.DoLogOn();
127     SaTypeEmitter::logOn_ = logOn_;
128     ast_ = nullptr;
129     interface_ = nullptr;
130     directory_ = "";
131     interfaceName_ = "";
132     interfaceFullName_ = "";
133     baseName_ = "";
134     proxyName_ = "";
135     proxyFullName_ = "";
136     stubName_ = "";
137     stubFullName_ = "";
138     clientName_ = "";
139     clientFullName_ = "";
140 }
141 
ResolveDirectory(const std::string & targetDirectory)142 bool SACodeEmitter::ResolveDirectory(const std::string &targetDirectory)
143 {
144     directory_ = targetDirectory;
145 #ifdef __MINGW32__
146     if (targetDirectory.find(":\\") == std::string::npos) {
147         char* cwd = getcwd(nullptr, 0);
148         directory_ = StringHelper::Format("%s\\%s", cwd, targetDirectory.c_str());
149         free(cwd);
150     }
151 #else
152     if (!StringHelper::StartWith(targetDirectory, "/")) {
153         char* cwd = getcwd(nullptr, 0);
154         directory_ = StringHelper::Format("%s/%s", cwd, targetDirectory.c_str());
155         free(cwd);
156     }
157 #endif
158 
159     if (!access(directory_.c_str(), R_OK | W_OK)) {
160         return true;
161     }
162 
163 #ifdef __MINGW32__
164     if (mkdir(directory_.c_str()) != 0) {
165 #else
166     if (mkdir(directory_.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) != 0) {
167 #endif
168         Logger::E(TAG, "Create \"%s\" directory failed.", directory_.c_str());
169         return false;
170     }
171 
172     return true;
173 }
174 
175 AutoPtr<SaTypeEmitter> SACodeEmitter::GetTypeEmitter(AutoPtr<ASTType> astType) const
176 {
177     AutoPtr<SaTypeEmitter> typeEmitter;
178     auto basicTypePair = basicEmitters_.find(astType->GetTypeKind());
179     if (basicTypePair != basicEmitters_.end()) {
180         typeEmitter = (static_cast<SaTypeEmitter*>(basicTypePair->second.Get()));
181     }
182 
183     if (typeEmitter == nullptr) {
184         typeEmitter = NewTypeEmitter(astType);
185     }
186 
187     if (astType->IsSequenceableType() || astType->IsInterfaceType() || astType->IsRawDataType()) {
188         typeEmitter->SetTypeName(astType->ToShortString());
189     } else if (astType->IsEnumType() || astType->IsStructType() || astType->IsUnionType()) {
190         typeEmitter->SetTypeName(astType->GetName());
191     } else {
192         typeEmitter->SetTypeName(astType->ToString());
193     }
194     return typeEmitter;
195 }
196 
197 std::string SACodeEmitter::GetNameWithNamespace(AutoPtr<ASTNamespace> space, const std::string name) const
198 {
199     std::vector<std::string> namespaceVec = StringHelper::Split(space->ToString(), ".");
200     std::vector<std::string> result;
201 
202     std::string rootPackage = Options::GetInstance().GetRootPackage(space->ToString());
203     size_t rootPackageNum = StringHelper::Split(rootPackage, ".").size();
204 
205     for (size_t i = 0; i < namespaceVec.size(); i++) {
206         std::string ns;
207         if (i < rootPackageNum) {
208             ns = StringHelper::StrToUpper(namespaceVec[i]);
209         } else {
210             ns = PascalName(namespaceVec[i]);
211         }
212 
213         result.emplace_back(ns);
214     }
215     StringBuilder sb;
216     for (const auto &ns : result) {
217         sb.AppendFormat("%s::", ns.c_str());
218     }
219     sb.Append(name);
220     return sb.ToString();
221 }
222 
223 AutoPtr<SaTypeEmitter> SACodeEmitter::NewTypeEmitter(AutoPtr<ASTType> astType) const
224 {
225     switch (astType->GetTypeKind()) {
226         case TypeKind::TYPE_MAP:
227             return NewMapTypeEmitter(astType);
228         case TypeKind::TYPE_ORDEREDMAP:
229             return NewOrderedMapTypeEmitter(astType);
230         case TypeKind::TYPE_ARRAY:
231             return NewArrayTypeEmitter(astType);
232         case TypeKind::TYPE_LIST:
233             return NewListTypeEmitter(astType);
234         case TypeKind::TYPE_ENUM:
235             return NewEnumTypeEmitter(astType);
236         case TypeKind::TYPE_STRUCT:
237             return NewStructTypeEmitter(astType);
238         case TypeKind::TYPE_UNION:
239             return NewUnionTypeEmitter(astType);
240         case TypeKind::TYPE_SEQUENCEABLE:
241             return new SaSeqTypeEmitter();
242         case TypeKind::TYPE_RAWDATA:
243             return new SaRawDataTypeEmitter();
244         case TypeKind::TYPE_INTERFACE:
245             return new SaInterfaceTypeEmitter();
246         default: {
247             // type not match, new a empty emitter
248             AutoPtr<SaTypeEmitter> typeEmitter = new SaTypeEmitter();
249             return typeEmitter;
250         }
251     }
252 }
253 
254 AutoPtr<SaTypeEmitter> SACodeEmitter::NewMapTypeEmitter(AutoPtr<ASTType> astType) const
255 {
256     AutoPtr<SaMapTypeEmitter> mapTypeEmitter = new SaMapTypeEmitter();
257     AutoPtr<ASTType> keyType = (static_cast<ASTMapType*>(astType.Get()))->GetKeyType();
258     AutoPtr<ASTType> valueType = (static_cast<ASTMapType*>(astType.Get()))->GetValueType();
259     AutoPtr<SaTypeEmitter> keyEmitter = GetTypeEmitter(keyType);
260     AutoPtr<SaTypeEmitter> valueEmitter = GetTypeEmitter(valueType);
261     mapTypeEmitter->SetKeyEmitter(keyEmitter);
262     mapTypeEmitter->SetValueEmitter(valueEmitter);
263     return mapTypeEmitter.Get();
264 }
265 
266 AutoPtr<SaTypeEmitter> SACodeEmitter::NewOrderedMapTypeEmitter(AutoPtr<ASTType> astType) const
267 {
268     AutoPtr<SaOrderedMapTypeEmitter> orderedmapTypeEmitter = new SaOrderedMapTypeEmitter();
269     AutoPtr<ASTType> keyType = (static_cast<ASTOrderedMapType*>(astType.Get()))->GetKeyType();
270     AutoPtr<ASTType> valueType = (static_cast<ASTOrderedMapType*>(astType.Get()))->GetValueType();
271     AutoPtr<SaTypeEmitter> keyEmitter = GetTypeEmitter(keyType);
272     AutoPtr<SaTypeEmitter> valueEmitter = GetTypeEmitter(valueType);
273     orderedmapTypeEmitter->SetKeyEmitter(keyEmitter);
274     orderedmapTypeEmitter->SetValueEmitter(valueEmitter);
275     return orderedmapTypeEmitter.Get();
276 }
277 
278 AutoPtr<SaTypeEmitter> SACodeEmitter::NewArrayTypeEmitter(AutoPtr<ASTType> astType) const
279 {
280     AutoPtr<SaArrayTypeEmitter> arrayTypeEmitter = new SaArrayTypeEmitter();
281     AutoPtr<ASTType> elemType = (static_cast<ASTArrayType*>(astType.Get()))->GetElementType();
282     AutoPtr<SaTypeEmitter> elemEmitter = GetTypeEmitter(elemType);
283     arrayTypeEmitter->SetElementEmitter(elemEmitter);
284     return arrayTypeEmitter.Get();
285 }
286 
287 AutoPtr<SaTypeEmitter> SACodeEmitter::NewListTypeEmitter(AutoPtr<ASTType> astType) const
288 {
289     AutoPtr<SaListTypeEmitter> listTypeEmitter = new SaListTypeEmitter();
290     AutoPtr<ASTType> elemType = (static_cast<ASTListType*>(astType.Get()))->GetElementType();
291     AutoPtr<SaTypeEmitter> elemEmitter = GetTypeEmitter(elemType);
292     listTypeEmitter->SetElementEmitter(elemEmitter);
293     return listTypeEmitter.Get();
294 }
295 
296 AutoPtr<SaTypeEmitter> SACodeEmitter::NewEnumTypeEmitter(AutoPtr<ASTType> astType) const
297 {
298     AutoPtr<SaEnumTypeEmitter> enumTypeEmitter = new SaEnumTypeEmitter();
299     AutoPtr<ASTEnumType> enumType = static_cast<ASTEnumType*>(astType.Get());
300     if (enumType->GetBaseType() != nullptr) {
301         AutoPtr<SaTypeEmitter> baseTypeEmitter = GetTypeEmitter(enumType->GetBaseType());
302         enumTypeEmitter->SetBaseTypeName(baseTypeEmitter->EmitCppType());
303     }
304     for (auto it : enumType->GetMembers()) {
305         if (it->GetExprValue() == nullptr) {
306             enumTypeEmitter->AddMember(new SaEnumValueEmitter(it->GetName(), std::string("")));
307         } else {
308             enumTypeEmitter->AddMember(new SaEnumValueEmitter(it->GetName(), it->GetExprValue()->EmitCode()));
309         }
310     }
311     return enumTypeEmitter.Get();
312 }
313 
314 AutoPtr<SaTypeEmitter> SACodeEmitter::NewStructTypeEmitter(AutoPtr<ASTType> astType) const
315 {
316     AutoPtr<SaStructTypeEmitter> structTypeEmitter = new SaStructTypeEmitter();
317     AutoPtr<ASTStructType> structType = (static_cast<ASTStructType*>(astType.Get()));
318     for (auto it : structType->GetMembers()) {
319         structTypeEmitter->AddMember(std::get<0>(it), GetTypeEmitter(std::get<1>(it)));
320     }
321     return structTypeEmitter.Get();
322 }
323 
324 AutoPtr<SaTypeEmitter> SACodeEmitter::NewUnionTypeEmitter(AutoPtr<ASTType> astType) const
325 {
326     AutoPtr<SaUnionTypeEmitter> unionTypeEmitter = new SaUnionTypeEmitter();
327     AutoPtr<ASTUnionType> unionType = (static_cast<ASTUnionType*>(astType.Get()));
328     for (size_t i = 0; i < unionType->GetMemberNumber(); i++) {
329         unionTypeEmitter->AddMember(unionType->GetMemberName(i), GetTypeEmitter(unionType->GetMemberType(i)));
330     }
331     return unionTypeEmitter.Get();
332 }
333 } // namespace Idl
334 } // namespace OHOS
335