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 "sa_code_emitter.h"
17 #include "ast/ast_map_type.h"
18 #include "type/sa_boolean_type_emitter.h"
19 #include "type/sa_byte_type_emitter.h"
20 #include "type/sa_short_type_emitter.h"
21 #include "type/sa_int_type_emitter.h"
22 #include "type/sa_long_type_emitter.h"
23 #include "type/sa_float_type_emitter.h"
24 #include "type/sa_double_type_emitter.h"
25 #include "type/sa_char_type_emitter.h"
26 #include "type/sa_string_type_emitter.h"
27 #include "type/sa_seq_type_emitter.h"
28 #include "type/sa_interface_type_emitter.h"
29 #include "type/sa_map_type_emitter.h"
30 #include "type/sa_array_type_emitter.h"
31
32 #include <cctype>
33 #include <sys/stat.h>
34 #include <unistd.h>
35 #include "util/file.h"
36 #include "util/options.h"
37 #include "util/logger.h"
38 #include "util/string_helper.h"
39
40 namespace OHOS {
41 namespace Idl {
42 SACodeEmitter::TypeEmitterMap SACodeEmitter::basicEmitters_ = {
43 {TypeKind::TYPE_BOOLEAN, new SaBooleanTypeEmitter() },
44 {TypeKind::TYPE_BYTE, new SaByteTypeEmitter() },
45 {TypeKind::TYPE_SHORT, new SaShortTypeEmitter() },
46 {TypeKind::TYPE_INT, new SaIntTypeEmitter() },
47 {TypeKind::TYPE_LONG, new SaLongTypeEmitter() },
48 {TypeKind::TYPE_FLOAT, new SaFloatTypeEmitter() },
49 {TypeKind::TYPE_DOUBLE, new SaDoubleTypeEmitter() },
50 {TypeKind::TYPE_CHAR, new SaCharTypeEmitter() },
51 {TypeKind::TYPE_STRING, new SaStringTypeEmitter() },
52 };
53
OutPut(const AutoPtr<AST> & ast,const std::string & targetDirectory,GenMode mode)54 bool SACodeEmitter::OutPut(const AutoPtr<AST> &ast, const std::string &targetDirectory, GenMode mode)
55 {
56 if (!Reset(ast, targetDirectory, mode)) {
57 return false;
58 }
59
60 EmitCode();
61 return true;
62 }
63
Reset(const AutoPtr<AST> & ast,const std::string & targetDirectory,GenMode mode)64 bool SACodeEmitter::Reset(const AutoPtr<AST> &ast, const std::string &targetDirectory, GenMode mode)
65 {
66 if ((ast == nullptr) || (ast->GetASTFileType() != ASTFileType::AST_IFACE)) {
67 return false;
68 }
69
70 CleanData();
71
72 ast_ = ast;
73 for (auto interface : ast_->GetInterfaceDefs()) {
74 if (interface->IsExternal() == false) {
75 interface_ = interface;
76 break;
77 }
78 }
79 if (interface_ != nullptr) {
80 interfaceName_ = interface_->GetName();
81 interfaceFullName_ = interface_->GetNamespace()->ToString() + interfaceName_;
82 baseName_ = StringHelper::StartWith(interfaceName_, "I") ? interfaceName_.substr(1) : interfaceName_;
83 proxyName_ = baseName_ + "Proxy";
84 proxyFullName_ = interface_->GetNamespace()->ToString() + proxyName_;
85
86 stubName_ = baseName_ + "Stub";
87 stubFullName_ = interface_->GetNamespace()->ToString() + stubName_;
88 deathRecipientName_ = StringHelper::StartWith(interfaceName_, "I") ? interfaceName_.substr(1) + "Recipient" :
89 interfaceName_ + "Recipient";
90 }
91
92 if (!ResolveDirectory(targetDirectory)) {
93 return false;
94 }
95
96 return true;
97 }
98
CleanData()99 void SACodeEmitter::CleanData()
100 {
101 Options &options = Options::GetInstance();
102
103 domainId_ = options.GetDomainId();
104 logTag_ = options.GetLogTag();
105 hitraceTag_ = options.GetGenerateHitraceTag();
106 hitraceOn_ = options.DoHitraceState();
107 logOn_ = options.DoLogOn();
108 SaTypeEmitter::logOn_ = logOn_;
109 ast_ = nullptr;
110 interface_ = nullptr;
111 directory_ = "";
112 interfaceName_ = "";
113 interfaceFullName_ = "";
114 baseName_ = "";
115 proxyName_ = "";
116 proxyFullName_ = "";
117 stubName_ = "";
118 stubFullName_ = "";
119 }
120
ResolveDirectory(const std::string & targetDirectory)121 bool SACodeEmitter::ResolveDirectory(const std::string &targetDirectory)
122 {
123 directory_ = targetDirectory;
124 #ifdef __MINGW32__
125 if (targetDirectory.find(":\\") == std::string::npos) {
126 char* cwd = getcwd(nullptr, 0);
127 directory_ = StringHelper::Format("%s\\%s", cwd, targetDirectory.c_str());
128 free(cwd);
129 }
130 #else
131 if (!StringHelper::StartWith(targetDirectory, "/")) {
132 char* cwd = getcwd(nullptr, 0);
133 directory_ = StringHelper::Format("%s/%s", cwd, targetDirectory.c_str());
134 free(cwd);
135 }
136 #endif
137
138 if (!access(directory_.c_str(), R_OK | W_OK)) {
139 return true;
140 }
141
142 #ifdef __MINGW32__
143 if (mkdir(directory_.c_str()) != 0) {
144 #else
145 if (mkdir(directory_.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) != 0) {
146 #endif
147 Logger::E(TAG, "Create \"%s\" directory failed.", directory_.c_str());
148 return false;
149 }
150
151 return true;
152 }
153
154 AutoPtr<SaTypeEmitter> SACodeEmitter::GetTypeEmitter(AutoPtr<ASTType> astType) const
155 {
156 AutoPtr<SaTypeEmitter> typeEmitter;
157 auto basicTypePair = basicEmitters_.find(astType->GetTypeKind());
158 if (basicTypePair != basicEmitters_.end()) {
159 typeEmitter = (static_cast<SaTypeEmitter*>(basicTypePair->second.Get()));
160 }
161
162 if (typeEmitter == nullptr) {
163 typeEmitter = NewTypeEmitter(astType);
164 }
165
166 typeEmitter->SetTypeName(astType->ToString());
167 return typeEmitter;
168 }
169
170 AutoPtr<SaTypeEmitter> SACodeEmitter::NewTypeEmitter(AutoPtr<ASTType> astType) const
171 {
172 switch (astType->GetTypeKind()) {
173 case TypeKind::TYPE_MAP:
174 return NewMapTypeEmitter(astType);
175 case TypeKind::TYPE_ARRAY:
176 return NewArrayTypeEmitter(astType);
177 case TypeKind::TYPE_LIST:
178 return NewListTypeEmitter(astType);
179 case TypeKind::TYPE_SEQUENCEABLE:
180 return new SaSeqTypeEmitter();
181 case TypeKind::TYPE_INTERFACE:
182 return new SaInterfaceTypeEmitter();
183 default: {
184 // type not match, new a empty emitter
185 AutoPtr<SaTypeEmitter> typeEmitter = new SaTypeEmitter();
186 return typeEmitter;
187 }
188 }
189 }
190
191 AutoPtr<SaTypeEmitter> SACodeEmitter::NewMapTypeEmitter(AutoPtr<ASTType> astType) const
192 {
193 AutoPtr<SaMapTypeEmitter> mapTypeEmitter = new SaMapTypeEmitter();
194 AutoPtr<ASTType> keyType = (static_cast<ASTMapType*>(astType.Get()))->GetKeyType();
195 AutoPtr<ASTType> valueType = (static_cast<ASTMapType*>(astType.Get()))->GetValueType();
196 AutoPtr<SaTypeEmitter> keyEmitter = GetTypeEmitter(keyType);
197 AutoPtr<SaTypeEmitter> valueEmitter = GetTypeEmitter(valueType);
198 mapTypeEmitter->SetKeyEmitter(keyEmitter);
199 mapTypeEmitter->SetValueEmitter(valueEmitter);
200 return mapTypeEmitter.Get();
201 }
202
203 AutoPtr<SaTypeEmitter> SACodeEmitter::NewArrayTypeEmitter(AutoPtr<ASTType> astType) const
204 {
205 AutoPtr<SaArrayTypeEmitter> arrayTypeEmitter = new SaArrayTypeEmitter();
206 AutoPtr<ASTType> elemType = (static_cast<ASTArrayType*>(astType.Get()))->GetElementType();
207 AutoPtr<SaTypeEmitter> elemEmitter = GetTypeEmitter(elemType);
208 arrayTypeEmitter->SetElementEmitter(elemEmitter);
209 return arrayTypeEmitter.Get();
210 }
211
212 AutoPtr<SaTypeEmitter> SACodeEmitter::NewListTypeEmitter(AutoPtr<ASTType> astType) const
213 {
214 AutoPtr<SaListTypeEmitter> listTypeEmitter = new SaListTypeEmitter();
215 AutoPtr<ASTType> elemType = (static_cast<ASTListType*>(astType.Get()))->GetElementType();
216 AutoPtr<SaTypeEmitter> elemEmitter = GetTypeEmitter(elemType);
217 listTypeEmitter->SetElementEmitter(elemEmitter);
218 return listTypeEmitter.Get();
219 }
220 } // namespace Idl
221 } // namespace OHOS
222