• 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 String & targetDirectory)15 bool CppInterfaceCodeEmitter::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("CppInterfaceCodeEmitter", "Create '%s' failed!", directory_.string());
26         return false;
27     }
28 
29     return true;
30 }
31 
EmitCode()32 void CppInterfaceCodeEmitter::EmitCode()
33 {
34     EmitInterfaceHeaderFile();
35 }
36 
EmitInterfaceHeaderFile()37 void CppInterfaceCodeEmitter::EmitInterfaceHeaderFile()
38 {
39     String filePath = String::Format("%s/%s.h", directory_.string(), FileName(interfaceName_).string());
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     sb.Append("\n");
50     EmitInterfaceBuffSizeMacro(sb);
51     sb.Append("\n");
52     EmitBeginNamespace(sb);
53     EmitUsingNamespace(sb);
54     sb.Append("\n");
55     EmitInterfaceMethodCommands(sb, "");
56     sb.Append("\n");
57     EmitInterfaceDefinition(sb);
58     EmitEndNamespace(sb);
59     sb.Append("\n");
60     EmitTailMacro(sb, interfaceFullName_);
61 
62     String data = sb.ToString();
63     file.WriteData(data.string(), data.GetLength());
64     file.Flush();
65     file.Close();
66 }
67 
EmitInterfaceInclusions(StringBuilder & sb)68 void CppInterfaceCodeEmitter::EmitInterfaceInclusions(StringBuilder& sb)
69 {
70     HeaderFile::HeaderFileSet headerFiles;
71 
72     GetStdlibInclusions(headerFiles);
73     GetImportInclusions(headerFiles);
74     GetHeaderOtherLibInclusions(headerFiles);
75 
76     for (const auto& file : headerFiles) {
77         sb.AppendFormat("%s\n", file.ToString().string());
78     }
79 }
80 
GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles)81 void CppInterfaceCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet& headerFiles)
82 {
83     headerFiles.emplace(HeaderFile(HeaderFileType::C_STD_HEADER_FILE, "stdint"));
84     headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iremote_broker"));
85 }
86 
EmitInterfaceVersionMacro(StringBuilder & sb)87 void CppInterfaceCodeEmitter::EmitInterfaceVersionMacro(StringBuilder& sb)
88 {
89     sb.AppendFormat("#define %s %u\n", majorVerName_.string(), ast_->GetMajorVer());
90     sb.AppendFormat("#define %s %u\n", minorVerName_.string(), ast_->GetMinorVer());
91 }
92 
EmitInterfaceDefinition(StringBuilder & sb)93 void CppInterfaceCodeEmitter::EmitInterfaceDefinition(StringBuilder& sb)
94 {
95     if (!interface_->IsSerializable()) {
96         sb.AppendFormat("class %s : public IRemoteBroker {\n", interfaceName_.string());
97         sb.Append("public:\n");
98         EmitInterfaceDescriptor(sb, g_tab);
99         sb.Append("\n");
100         EmitInterfaceDestruction(sb, g_tab);
101         sb.Append("\n");
102         EmitGetMethodDecl(sb, g_tab);
103         sb.Append("\n");
104         EmitGetInstanceMethodDecl(sb, g_tab);
105         sb.Append("\n");
106         EmitInterfaceMethodsDecl(sb, g_tab);
107         sb.Append("};\n");
108     } else {
109         sb.AppendFormat("class %s : public IRemoteBroker {\n", interfaceName_.string());
110         sb.Append("public:\n");
111         EmitInterfaceDescriptor(sb, g_tab);
112         sb.Append("\n");
113         EmitInterfaceDestruction(sb, g_tab);
114         sb.Append("\n");
115         EmitInterfaceMethodsDecl(sb, g_tab);
116         sb.Append("};\n");
117     }
118 }
119 
EmitInterfaceDescriptor(StringBuilder & sb,const String & prefix)120 void CppInterfaceCodeEmitter::EmitInterfaceDescriptor(StringBuilder& sb, const String& prefix)
121 {
122     sb.Append(g_tab).AppendFormat("DECLARE_INTERFACE_DESCRIPTOR(u\"%s\");\n", interfaceFullName_.string());
123 }
124 
EmitGetMethodDecl(StringBuilder & sb,const String & prefix)125 void CppInterfaceCodeEmitter::EmitGetMethodDecl(StringBuilder& sb, const String& prefix)
126 {
127     sb.Append(prefix).AppendFormat("static sptr<%s> Get();\n", interface_->GetName().string());
128 }
129 
EmitGetInstanceMethodDecl(StringBuilder & sb,const String & prefix)130 void CppInterfaceCodeEmitter::EmitGetInstanceMethodDecl(StringBuilder& sb, const String& prefix)
131 {
132     sb.Append(prefix).AppendFormat("static sptr<%s> GetInstance(const std::string& serviceName);\n",
133         interface_->GetName().string());
134 }
135 
EmitInterfaceDestruction(StringBuilder & sb,const String & prefix)136 void CppInterfaceCodeEmitter::EmitInterfaceDestruction(StringBuilder& sb, const String& prefix)
137 {
138     sb.Append(prefix).AppendFormat("virtual ~%s() = default;\n", interface_->GetName().string());
139 }
140 
EmitInterfaceMethodsDecl(StringBuilder & sb,const String & prefix)141 void CppInterfaceCodeEmitter::EmitInterfaceMethodsDecl(StringBuilder& sb, const String& prefix)
142 {
143     for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
144         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
145         EmitInterfaceMethodDecl(method, sb, prefix);
146         sb.Append("\n");
147     }
148 
149     EmitInterfaceMethodDecl(interface_->GetVersionMethod(), sb, prefix);
150 }
151 
EmitInterfaceMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const String & prefix)152 void CppInterfaceCodeEmitter::EmitInterfaceMethodDecl(const AutoPtr<ASTMethod>& method, StringBuilder& sb,
153     const String& prefix)
154 {
155     if (method->GetParameterNumber() == 0) {
156         sb.Append(prefix).AppendFormat("virtual int32_t %s() = 0;\n", method->GetName().string());
157     } else {
158         StringBuilder paramStr;
159         paramStr.Append(prefix).AppendFormat("virtual int32_t %s(", method->GetName().string());
160         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
161             AutoPtr<ASTParameter> param = method->GetParameter(i);
162             EmitInterfaceMethodParameter(param, paramStr, "");
163             if (i + 1 < method->GetParameterNumber()) {
164                 paramStr.Append(", ");
165             }
166         }
167 
168         paramStr.Append(") = 0;");
169         sb.Append(SpecificationParam(paramStr, prefix + g_tab));
170         sb.Append("\n");
171     }
172 }
173 
EmitInterfaceMethodParameter(const AutoPtr<ASTParameter> & param,StringBuilder & sb,const String & prefix)174 void CppInterfaceCodeEmitter::EmitInterfaceMethodParameter(const AutoPtr<ASTParameter>& param, StringBuilder& sb,
175     const String& prefix)
176 {
177     sb.Append(prefix).Append(param->EmitCppParameter());
178 }
179 } // namespace HDI
180 } // namespace OHOS