• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_interface_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 CppInterfaceCodeEmitter::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("CppInterfaceCodeEmitter", "Create '%s' failed!", directory_.c_str());
25         return false;
26     }
27 
28     return true;
29 }
30 
EmitCode()31 void CppInterfaceCodeEmitter::EmitCode()
32 {
33     EmitInterfaceHeaderFile();
34 }
35 
EmitInterfaceHeaderFile()36 void CppInterfaceCodeEmitter::EmitInterfaceHeaderFile()
37 {
38     std::string filePath =
39         File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(interfaceName_).c_str()));
40     File file(filePath, File::WRITE);
41     StringBuilder sb;
42 
43     EmitLicense(sb);
44     EmitHeadMacro(sb, interfaceFullName_);
45     sb.Append("\n");
46     EmitInterfaceInclusions(sb);
47     sb.Append("\n");
48     EmitInterfaceVersionMacro(sb);
49     if (!Options::GetInstance().DoPassthrough()) {
50         sb.Append("\n");
51         EmitInterfaceBuffSizeMacro(sb);
52     }
53     sb.Append("\n");
54     EmitBeginNamespace(sb);
55     EmitUsingNamespace(sb);
56     if (!Options::GetInstance().DoPassthrough()) {
57         sb.Append("\n");
58         EmitInterfaceMethodCommands(sb, "");
59     }
60     sb.Append("\n");
61     EmitInterfaceDefinition(sb);
62     EmitEndNamespace(sb);
63     sb.Append("\n");
64     EmitTailMacro(sb, interfaceFullName_);
65 
66     std::string data = sb.ToString();
67     file.WriteData(data.c_str(), data.size());
68     file.Flush();
69     file.Close();
70 }
71 
EmitInterfaceInclusions(StringBuilder & sb)72 void CppInterfaceCodeEmitter::EmitInterfaceInclusions(StringBuilder &sb)
73 {
74     HeaderFile::HeaderFileSet headerFiles;
75 
76     GetStdlibInclusions(headerFiles);
77     GetImportInclusions(headerFiles);
78     GetHeaderOtherLibInclusions(headerFiles);
79 
80     for (const auto &file : headerFiles) {
81         sb.AppendFormat("%s\n", file.ToString().c_str());
82     }
83 }
84 
GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles)85 void CppInterfaceCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles)
86 {
87     headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdint");
88     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_base");
89     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
90 }
91 
EmitInterfaceVersionMacro(StringBuilder & sb)92 void CppInterfaceCodeEmitter::EmitInterfaceVersionMacro(StringBuilder &sb)
93 {
94     sb.AppendFormat("#define %s %u\n", majorVerName_.c_str(), ast_->GetMajorVer());
95     sb.AppendFormat("#define %s %u\n", minorVerName_.c_str(), ast_->GetMinorVer());
96 }
97 
EmitInterfaceDefinition(StringBuilder & sb)98 void CppInterfaceCodeEmitter::EmitInterfaceDefinition(StringBuilder &sb)
99 {
100     if (!interface_->IsSerializable()) {
101         sb.AppendFormat("class %s : public HdiBase {\n", interfaceName_.c_str());
102         sb.Append("public:\n");
103         EmitInterfaceDescriptor(sb, TAB);
104         sb.Append("\n");
105         EmitInterfaceDestruction(sb, TAB);
106         sb.Append("\n");
107         EmitGetMethodDecl(sb, TAB);
108         sb.Append("\n");
109         EmitInterfaceMethodsDecl(sb, TAB);
110         sb.Append("};\n");
111     } else {
112         sb.AppendFormat("class %s : public HdiBase {\n", interfaceName_.c_str());
113         sb.Append("public:\n");
114         EmitInterfaceDescriptor(sb, TAB);
115         sb.Append("\n");
116         EmitInterfaceDestruction(sb, TAB);
117         sb.Append("\n");
118         EmitInterfaceMethodsDecl(sb, TAB);
119         sb.Append("};\n");
120     }
121 }
122 
EmitInterfaceDescriptor(StringBuilder & sb,const std::string & prefix)123 void CppInterfaceCodeEmitter::EmitInterfaceDescriptor(StringBuilder &sb, const std::string &prefix)
124 {
125     sb.Append(TAB).AppendFormat("DECLARE_HDI_DESCRIPTOR(u\"%s\");\n", interfaceFullName_.c_str());
126 }
127 
EmitGetMethodDecl(StringBuilder & sb,const std::string & prefix)128 void CppInterfaceCodeEmitter::EmitGetMethodDecl(StringBuilder &sb, const std::string &prefix)
129 {
130     sb.Append(prefix).AppendFormat("static sptr<%s> Get(bool isStub = false);\n", interface_->GetName().c_str());
131     sb.Append(prefix).AppendFormat(
132         "static sptr<%s> Get(const std::string &serviceName, bool isStub = false);\n", interface_->GetName().c_str());
133 }
134 
EmitInterfaceDestruction(StringBuilder & sb,const std::string & prefix)135 void CppInterfaceCodeEmitter::EmitInterfaceDestruction(StringBuilder &sb, const std::string &prefix)
136 {
137     sb.Append(prefix).AppendFormat("virtual ~%s() = default;\n", interface_->GetName().c_str());
138 }
139 
EmitInterfaceMethodsDecl(StringBuilder & sb,const std::string & prefix)140 void CppInterfaceCodeEmitter::EmitInterfaceMethodsDecl(StringBuilder &sb, const std::string &prefix)
141 {
142     for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
143         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
144         EmitInterfaceMethodDecl(method, sb, prefix);
145         sb.Append("\n");
146     }
147 
148     EmitInterfaceGetVersionMethod(sb, prefix);
149 }
150 
EmitInterfaceMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)151 void CppInterfaceCodeEmitter::EmitInterfaceMethodDecl(
152     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
153 {
154     if (method->GetParameterNumber() == 0) {
155         sb.Append(prefix).AppendFormat("virtual int32_t %s() = 0;\n", method->GetName().c_str());
156     } else {
157         StringBuilder paramStr;
158         paramStr.Append(prefix).AppendFormat("virtual int32_t %s(", method->GetName().c_str());
159         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
160             AutoPtr<ASTParameter> param = method->GetParameter(i);
161             EmitInterfaceMethodParameter(param, paramStr, "");
162             if (i + 1 < method->GetParameterNumber()) {
163                 paramStr.Append(", ");
164             }
165         }
166 
167         paramStr.Append(") = 0;");
168         sb.Append(SpecificationParam(paramStr, prefix + TAB));
169         sb.Append("\n");
170     }
171 }
172 
EmitInterfaceGetVersionMethod(StringBuilder & sb,const std::string & prefix)173 void CppInterfaceCodeEmitter::EmitInterfaceGetVersionMethod(StringBuilder &sb, const std::string &prefix)
174 {
175     AutoPtr<ASTMethod> method = interface_->GetVersionMethod();
176     sb.Append(prefix).AppendFormat("virtual int32_t %s(", method->GetName().c_str());
177     for (size_t i = 0; i < method->GetParameterNumber(); i++) {
178         AutoPtr<ASTParameter> param = method->GetParameter(i);
179         EmitInterfaceMethodParameter(param, sb, "");
180         if (i + 1 < method->GetParameterNumber()) {
181             sb.Append(", ");
182         }
183     }
184 
185     sb.AppendFormat(")\n");
186     sb.Append(prefix).Append("{\n");
187 
188     AutoPtr<ASTParameter> majorParam = method->GetParameter(0);
189     sb.Append(prefix + TAB).AppendFormat("%s = %s;\n", majorParam->GetName().c_str(), majorVerName_.c_str());
190     AutoPtr<ASTParameter> minorParam = method->GetParameter(1);
191     sb.Append(prefix + TAB).AppendFormat("%s = %s;\n", minorParam->GetName().c_str(), minorVerName_.c_str());
192 
193     sb.Append(prefix + TAB).Append("return HDF_SUCCESS;\n");
194     sb.Append(prefix).Append("}\n");
195 }
196 
EmitInterfaceMethodParameter(const AutoPtr<ASTParameter> & param,StringBuilder & sb,const std::string & prefix)197 void CppInterfaceCodeEmitter::EmitInterfaceMethodParameter(
198     const AutoPtr<ASTParameter> &param, StringBuilder &sb, const std::string &prefix)
199 {
200     sb.Append(prefix).Append(param->EmitCppParameter());
201 }
202 } // namespace HDI
203 } // namespace OHOS