1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "util/logger.h"
16 #include "sa_ts_code_emitter.h"
17
18 namespace OHOS {
19 namespace Idl {
CheckInterfaceType() const20 bool SATsCodeEmitter::CheckInterfaceType() const
21 {
22 if (interface_ == nullptr) {
23 return false;
24 }
25 int methodNumber = static_cast<int>(interface_->GetMethodNumber());
26 for (int i = 0; i < methodNumber; i++) {
27 AutoPtr<ASTMethod> method = interface_->GetMethod(i);
28 if (method == nullptr) {
29 return false;
30 }
31 AutoPtr<ASTType> type = method->GetReturnType();
32 AutoPtr<SaTypeEmitter> typeEmitter = GetTypeEmitter(type);
33 if ((type->GetTypeKind() != TypeKind::TYPE_VOID) &&
34 (typeEmitter != nullptr && typeEmitter->EmitTsType() == "unknown type")) {
35 Logger::E("SATsCodeEmitter", "unsupported type in .idl file for method '%s'", method->GetName().c_str());
36 return false;
37 }
38 int paramNumber = static_cast<int>(method->GetParameterNumber());
39 for (int j = 0; j < paramNumber; j++) {
40 AutoPtr<ASTParameter> param = method->GetParameter(j);
41 type = param->GetType();
42 typeEmitter = GetTypeEmitter(type);
43 if ((type->GetTypeKind() != TypeKind::TYPE_VOID) &&
44 (typeEmitter != nullptr && typeEmitter->EmitTsType() == "unknown type")) {
45 Logger::E("SATsCodeEmitter", "unsupported type in .idl file for method '%s'",
46 method->GetName().c_str());
47 return false;
48 }
49 }
50 }
51 return true;
52 }
53
FileName(const std::string & name) const54 std::string SATsCodeEmitter::FileName(const std::string &name) const
55 {
56 if (name.empty()) {
57 return name;
58 }
59
60 StringBuilder sb;
61 for (size_t i = 0; i < name.size(); i++) {
62 char c = name[i];
63 if (isupper(c) != 0) {
64 if (i > 0) {
65 sb.Append('_');
66 }
67 sb.Append(tolower(c));
68 } else {
69 sb.Append(c);
70 }
71 }
72
73 return StringHelper::Replace(sb.ToString(), '.', '/');
74 }
75
MethodName(const std::string & name) const76 std::string SATsCodeEmitter::MethodName(const std::string &name) const
77 {
78 if (name.empty() || islower(name[0])) {
79 return name;
80 }
81 return StringHelper::Format("%c%s", tolower(name[0]), name.substr(1).c_str());
82 }
83
SuffixAdded(const std::string & originName) const84 const std::string SATsCodeEmitter::SuffixAdded(const std::string &originName) const
85 {
86 std::string varSuffix("Var");
87 return originName + varSuffix;
88 }
89
EmitInterfaceMethodCommands(StringBuilder & sb,const std::string & prefix)90 void SATsCodeEmitter::EmitInterfaceMethodCommands(StringBuilder &sb, const std::string &prefix)
91 {
92 int methodNumber = static_cast<int>(interface_->GetMethodNumber());
93 for (int i = 0; i < methodNumber; i++) {
94 AutoPtr<ASTMethod> method = interface_->GetMethod(i);
95 sb.Append(prefix).AppendFormat("static readonly COMMAND_%s = %d;\n",
96 ConstantName(method->GetName()).c_str(), i + 1);
97 }
98 }
99
EmitInterfaceImports(StringBuilder & sb) const100 void SATsCodeEmitter::EmitInterfaceImports(StringBuilder &sb) const
101 {
102 int methodNumber = static_cast<int>(interface_->GetMethodNumber());
103 for (int i = 0; i < methodNumber; i++) {
104 AutoPtr<ASTMethod> method = interface_->GetMethod(i);
105 sb.AppendFormat("import {%sCallback} from \"./%s\";\n", MethodName(method->GetName()).c_str(),
106 FileName(interfaceName_).c_str());
107 }
108 sb.AppendFormat("import %s from \"./%s\";\n", interface_->GetName().c_str(), FileName(interfaceName_).c_str());
109 sb.Append("import rpc from \"@ohos.rpc\";\n");
110 EmitInterfaceSelfDefinedTypeImports(sb);
111
112 for (auto interface : ast_->GetInterfaceDefs()) {
113 if (interface->IsExternal() == false) {
114 continue;
115 }
116 std::string dependInterface = interface->GetName();
117 std::string dependStubName = StringHelper::StartWith(dependInterface, 'I') ?
118 dependInterface.substr(1) + "Stub" :
119 dependInterface + "Stub";
120 sb.AppendFormat("import %s from \"./%s\";\n", dependStubName.c_str(), FileName(dependStubName).c_str());
121 }
122 }
123
EmitInterfaceSelfDefinedTypeImports(StringBuilder & sb) const124 void SATsCodeEmitter::EmitInterfaceSelfDefinedTypeImports(StringBuilder &sb) const
125 {
126 int sequenceableNumber = static_cast<int>(ast_->GetSequenceableDefNumber());
127 for (int i = 0; i < sequenceableNumber; i++) {
128 AutoPtr<ASTSequenceableType> seqType = ast_->GetSequenceableDef(i);
129 sb.AppendFormat("import %s from \"./%s\";\n", seqType->GetName().c_str(),
130 FileName(seqType->GetName()).c_str());
131 }
132
133 for (auto interface : ast_->GetInterfaceDefs()) {
134 if (interface->IsExternal() == true) {
135 sb.AppendFormat("import %s from \"./%s\";\n", interface->GetName().c_str(),
136 FileName(interface->GetName()).c_str());
137 }
138 }
139 }
140
EmitInterfaceMethodHead(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const141 void SATsCodeEmitter::EmitInterfaceMethodHead(AutoPtr<ASTMethod> &method, StringBuilder &sb,
142 const std::string &prefix) const
143 {
144 sb.Append(prefix).AppendFormat("%s(", MethodName(method->GetName()).c_str());
145 int paramNumber = static_cast<int>(method->GetParameterNumber());
146 for (int i = 0; i < paramNumber; i++) {
147 AutoPtr<ASTParameter> param = method->GetParameter(i);
148 if (param->GetAttribute() & ASTParamAttr::PARAM_IN) {
149 AutoPtr<SaTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
150 if (typeEmitter != nullptr) {
151 sb.AppendFormat("%s: %s, ", param->GetName().c_str(), typeEmitter->EmitTsType().c_str());
152 }
153 }
154 }
155 sb.AppendFormat("callback: %sCallback", MethodName(method->GetName()).c_str());
156 }
157 } // namespace Idl
158 } // namespace OHOS