• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 std::string & targetDirectory)15 bool CppServiceImplCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
16 {
17     if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
18         directory_ = GetFileParentPath(targetDirectory);
19     } else {
20         return false;
21     }
22 
23     if (!File::CreateParentDir(directory_)) {
24         Logger::E("CppServiceImplCodeEmitter", "Create '%s' failed!", directory_.c_str());
25         return false;
26     }
27 
28     return true;
29 }
30 
EmitCode()31 void CppServiceImplCodeEmitter::EmitCode()
32 {
33     EmitImplHeaderFile();
34     EmitImplSourceFile();
35 }
36 
EmitImplHeaderFile()37 void CppServiceImplCodeEmitter::EmitImplHeaderFile()
38 {
39     std::string filePath =
40         File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(implName_).c_str()));
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     std::string data = sb.ToString();
54     file.WriteData(data.c_str(), data.size());
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(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
63 
64     for (const auto &file : headerFiles) {
65         sb.AppendFormat("%s\n", file.ToString().c_str());
66     }
67 }
68 
EmitServiceImplDecl(StringBuilder & sb)69 void CppServiceImplCodeEmitter::EmitServiceImplDecl(StringBuilder &sb)
70 {
71     EmitBeginNamespace(sb);
72     sb.AppendFormat("class %sService : public %s {\n", baseName_.c_str(), interfaceName_.c_str());
73     sb.Append("public:\n");
74     EmitServiceImplBody(sb, TAB);
75     sb.Append("};\n");
76     EmitEndNamespace(sb);
77 }
78 
EmitServiceImplBody(StringBuilder & sb,const std::string & prefix)79 void CppServiceImplCodeEmitter::EmitServiceImplBody(StringBuilder &sb, const std::string &prefix)
80 {
81     EmitServiceImplConstructor(sb, TAB);
82     sb.Append("\n");
83     EmitServiceImplMethodDecls(sb, TAB);
84 }
85 
EmitServiceImplConstructor(StringBuilder & sb,const std::string & prefix)86 void CppServiceImplCodeEmitter::EmitServiceImplConstructor(StringBuilder &sb, const std::string &prefix)
87 {
88     sb.Append(prefix).AppendFormat("%s() = default;\n", implName_.c_str());
89     sb.Append(prefix).AppendFormat("virtual ~%s() = default;\n", implName_.c_str());
90 }
91 
EmitServiceImplMethodDecls(StringBuilder & sb,const std::string & prefix)92 void CppServiceImplCodeEmitter::EmitServiceImplMethodDecls(StringBuilder &sb, const std::string &prefix)
93 {
94     for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
95         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
96         EmitServiceImplMethodDecl(method, sb, prefix);
97         if (i + 1 < interface_->GetMethodNumber()) {
98             sb.Append("\n");
99         }
100     }
101 }
102 
EmitServiceImplMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)103 void CppServiceImplCodeEmitter::EmitServiceImplMethodDecl(
104     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
105 {
106     if (method->GetParameterNumber() == 0) {
107         sb.Append(prefix).AppendFormat("int32_t %s() override;\n", method->GetName().c_str());
108     } else {
109         StringBuilder paramStr;
110         paramStr.Append(prefix).AppendFormat("int32_t %s(", method->GetName().c_str());
111         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
112             AutoPtr<ASTParameter> param = method->GetParameter(i);
113             EmitInterfaceMethodParameter(param, paramStr, "");
114             if (i + 1 < method->GetParameterNumber()) {
115                 paramStr.Append(", ");
116             }
117         }
118 
119         paramStr.Append(") override;");
120 
121         sb.Append(SpecificationParam(paramStr, prefix + TAB));
122         sb.Append("\n");
123     }
124 }
125 
EmitImplSourceFile()126 void CppServiceImplCodeEmitter::EmitImplSourceFile()
127 {
128     std::string filePath = File::AdapterPath(
129         StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(implName_).c_str()));
130     File file(filePath, File::WRITE);
131     StringBuilder sb;
132 
133     EmitLicense(sb);
134     EmitImplSourceInclusions(sb);
135     sb.Append("\n");
136     EmitLogTagMacro(sb, FileName(implName_));
137     sb.Append("\n");
138     EmitBeginNamespace(sb);
139     EmitServiceImplGetMethodImpl(sb, "");
140     EmitServiceImplMethodImpls(sb, "");
141     EmitEndNamespace(sb);
142 
143     std::string data = sb.ToString();
144     file.WriteData(data.c_str(), data.size());
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(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(implName_));
153     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
154 
155     for (const auto &file : headerFiles) {
156         sb.AppendFormat("%s\n", file.ToString().c_str());
157     }
158 }
159 
GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles)160 void CppServiceImplCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles)
161 {
162     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
163 }
164 
EmitServiceImplMethodImpls(StringBuilder & sb,const std::string & prefix)165 void CppServiceImplCodeEmitter::EmitServiceImplMethodImpls(StringBuilder &sb, const std::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 std::string & prefix)176 void CppServiceImplCodeEmitter::EmitServiceImplMethodImpl(
177     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
178 {
179     if (method->GetParameterNumber() == 0) {
180         sb.Append(prefix).AppendFormat("int32_t %sService::%s()\n", baseName_.c_str(), method->GetName().c_str());
181     } else {
182         StringBuilder paramStr;
183         paramStr.Append(prefix).AppendFormat("int32_t %sService::%s(", baseName_.c_str(), method->GetName().c_str());
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 + TAB));
195         sb.Append("\n");
196     }
197 
198     sb.Append(prefix).Append("{\n");
199     sb.Append(prefix + TAB).Append("return HDF_SUCCESS;\n");
200     sb.Append(prefix).Append("}\n");
201 }
202 
EmitServiceImplGetMethodImpl(StringBuilder & sb,const std::string & prefix)203 void CppServiceImplCodeEmitter::EmitServiceImplGetMethodImpl(StringBuilder &sb, const std::string &prefix)
204 {
205     if (!interface_->IsSerializable()) {
206         sb.Append(prefix).AppendFormat(
207             "extern \"C\" %s *%sImplGetInstance(void)\n", interfaceName_.c_str(), baseName_.c_str());
208         sb.Append(prefix).Append("{\n");
209         sb.Append(prefix + TAB).AppendFormat("return new (std::nothrow) %s();\n", implName_.c_str());
210         sb.Append(prefix).Append("}\n\n");
211     }
212 }
213 } // namespace HDI
214 } // namespace OHOS