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 "codegen/cpp_service_impl_code_emitter.h"
10 #include "util/file.h"
11 #include "util/logger.h"
12
13 namespace OHOS {
14 namespace HDI {
ResolveDirectory(const String & targetDirectory)15 bool CppServiceImplCodeEmitter::ResolveDirectory(const String& targetDirectory)
16 {
17 if (ast_->GetASTFileType() == ASTFileType::AST_IFACE ||
18 ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
19 directory_ = GetFilePath(targetDirectory);
20 } else {
21 return false;
22 }
23
24 if (!File::CreateParentDir(directory_)) {
25 Logger::E("CppServiceImplCodeEmitter", "Create '%s' failed!", directory_.string());
26 return false;
27 }
28
29 return true;
30 }
31
EmitCode()32 void CppServiceImplCodeEmitter::EmitCode()
33 {
34 EmitImplHeaderFile();
35 EmitImplSourceFile();
36 }
37
EmitImplHeaderFile()38 void CppServiceImplCodeEmitter::EmitImplHeaderFile()
39 {
40 String filePath = String::Format("%s/%s.h", directory_.string(), FileName(baseName_ + "Service").string());
41 File file(filePath, File::WRITE);
42 StringBuilder sb;
43
44 EmitLicense(sb);
45 EmitHeadMacro(sb, implFullName_);
46 sb.Append("\n");
47 EmitServiceImplInclusions(sb);
48 sb.Append("\n");
49 EmitServiceImplDecl(sb);
50 sb.Append("\n");
51 EmitTailMacro(sb, implFullName_);
52
53 String data = sb.ToString();
54 file.WriteData(data.string(), data.GetLength());
55 file.Flush();
56 file.Close();
57 }
58
EmitServiceImplInclusions(StringBuilder & sb)59 void CppServiceImplCodeEmitter::EmitServiceImplInclusions(StringBuilder& sb)
60 {
61 HeaderFile::HeaderFileSet headerFiles;
62 headerFiles.emplace(HeaderFile(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(stubName_)));
63
64 for (const auto& file : headerFiles) {
65 sb.AppendFormat("%s\n", file.ToString().string());
66 }
67 }
68
EmitServiceImplDecl(StringBuilder & sb)69 void CppServiceImplCodeEmitter::EmitServiceImplDecl(StringBuilder& sb)
70 {
71 EmitBeginNamespace(sb);
72 sb.Append("\n");
73 sb.AppendFormat("class %sService : public %s {\n", baseName_.string(), stubName_.string());
74 sb.Append("public:\n");
75 EmitServiceImplBody(sb, g_tab);
76 sb.Append("};\n");
77
78 sb.Append("\n");
79 EmitEndNamespace(sb);
80 }
81
EmitServiceImplBody(StringBuilder & sb,const String & prefix)82 void CppServiceImplCodeEmitter::EmitServiceImplBody(StringBuilder& sb, const String& prefix)
83 {
84 EmitServiceImplDestruction(sb, g_tab);
85 sb.Append("\n");
86 EmitServiceImplMethodDecls(sb, g_tab);
87 }
88
EmitServiceImplDestruction(StringBuilder & sb,const String & prefix)89 void CppServiceImplCodeEmitter::EmitServiceImplDestruction(StringBuilder& sb, const String& prefix)
90 {
91 sb.Append(prefix).AppendFormat("virtual ~%sService() {}\n", baseName_.string());
92 }
93
EmitServiceImplMethodDecls(StringBuilder & sb,const String & prefix)94 void CppServiceImplCodeEmitter::EmitServiceImplMethodDecls(StringBuilder& sb, const String& prefix)
95 {
96 for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
97 AutoPtr<ASTMethod> method = interface_->GetMethod(i);
98 EmitServiceImplMethodDecl(method, sb, prefix);
99 if (i + 1 < interface_->GetMethodNumber()) {
100 sb.Append("\n");
101 }
102 }
103 }
104
EmitServiceImplMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const String & prefix)105 void CppServiceImplCodeEmitter::EmitServiceImplMethodDecl(const AutoPtr<ASTMethod>& method, StringBuilder& sb,
106 const String& prefix)
107 {
108 if (method->GetParameterNumber() == 0) {
109 sb.Append(prefix).AppendFormat("int32_t %s() override;\n", method->GetName().string());
110 } else {
111 StringBuilder paramStr;
112 paramStr.Append(prefix).AppendFormat("int32_t %s(", method->GetName().string());
113 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
114 AutoPtr<ASTParameter> param = method->GetParameter(i);
115 EmitInterfaceMethodParameter(param, paramStr, "");
116 if (i + 1 < method->GetParameterNumber()) {
117 paramStr.Append(", ");
118 }
119 }
120
121 paramStr.Append(") override;");
122
123 sb.Append(SpecificationParam(paramStr, prefix + g_tab));
124 sb.Append("\n");
125 }
126 }
127
EmitImplSourceFile()128 void CppServiceImplCodeEmitter::EmitImplSourceFile()
129 {
130 String filePath = String::Format("%s/%s.cpp", directory_.string(), FileName(baseName_ + "Service").string());
131 File file(filePath, File::WRITE);
132 StringBuilder sb;
133
134 EmitLicense(sb);
135 EmitImplSourceInclusions(sb);
136 sb.Append("\n");
137 EmitBeginNamespace(sb);
138 sb.Append("\n");
139 EmitServiceImplMethodImpls(sb, "");
140 sb.Append("\n");
141 EmitEndNamespace(sb);
142
143 String data = sb.ToString();
144 file.WriteData(data.string(), data.GetLength());
145 file.Flush();
146 file.Close();
147 }
148
EmitImplSourceInclusions(StringBuilder & sb)149 void CppServiceImplCodeEmitter::EmitImplSourceInclusions(StringBuilder& sb)
150 {
151 HeaderFile::HeaderFileSet headerFiles;
152 headerFiles.emplace(HeaderFile(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(implName_)));
153 headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base"));
154
155 for (const auto& file : headerFiles) {
156 sb.AppendFormat("%s\n", file.ToString().string());
157 }
158 }
159
GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles)160 void CppServiceImplCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet& headerFiles)
161 {
162 headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base"));
163 }
164
EmitServiceImplMethodImpls(StringBuilder & sb,const String & prefix)165 void CppServiceImplCodeEmitter::EmitServiceImplMethodImpls(StringBuilder& sb, const String& prefix)
166 {
167 for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
168 AutoPtr<ASTMethod> method = interface_->GetMethod(i);
169 EmitServiceImplMethodImpl(method, sb, prefix);
170 if (i + 1 < interface_->GetMethodNumber()) {
171 sb.Append("\n");
172 }
173 }
174 }
175
EmitServiceImplMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const String & prefix)176 void CppServiceImplCodeEmitter::EmitServiceImplMethodImpl(const AutoPtr<ASTMethod>& method, StringBuilder& sb,
177 const String& prefix)
178 {
179 if (method->GetParameterNumber() == 0) {
180 sb.Append(prefix).AppendFormat("int32_t %sService::%s()\n", baseName_.string(), method->GetName().string());
181 } else {
182 StringBuilder paramStr;
183 paramStr.Append(prefix).AppendFormat("int32_t %sService::%s(", baseName_.string(), method->GetName().string());
184 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
185 AutoPtr<ASTParameter> param = method->GetParameter(i);
186 EmitInterfaceMethodParameter(param, paramStr, "");
187 if (i + 1 < method->GetParameterNumber()) {
188 paramStr.Append(", ");
189 }
190 }
191
192 paramStr.AppendFormat(")");
193
194 sb.Append(SpecificationParam(paramStr, prefix + g_tab));
195 sb.Append("\n");
196 }
197
198 sb.Append(prefix).Append("{\n");
199 sb.Append(prefix + g_tab).Append("return HDF_SUCCESS;\n");
200 sb.Append(prefix).Append("}\n");
201 }
202 } // namespace HDI
203 } // namespace OHOS