• 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_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