1ca0551cfSopenharmony_ci/* 2ca0551cfSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3ca0551cfSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4ca0551cfSopenharmony_ci * you may not use this file except in compliance with the License. 5ca0551cfSopenharmony_ci * You may obtain a copy of the License at 6ca0551cfSopenharmony_ci * 7ca0551cfSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8ca0551cfSopenharmony_ci * 9ca0551cfSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10ca0551cfSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11ca0551cfSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12ca0551cfSopenharmony_ci * See the License for the specific language governing permissions and 13ca0551cfSopenharmony_ci * limitations under the License. 14ca0551cfSopenharmony_ci */ 15ca0551cfSopenharmony_ci 16ca0551cfSopenharmony_ci#include "codegen/code_emitter.h" 17ca0551cfSopenharmony_ci 18ca0551cfSopenharmony_ci#include <cctype> 19ca0551cfSopenharmony_ci 20ca0551cfSopenharmony_ci#include "util/file.h" 21ca0551cfSopenharmony_ci#include "util/options.h" 22ca0551cfSopenharmony_ci 23ca0551cfSopenharmony_cinamespace OHOS { 24ca0551cfSopenharmony_cinamespace Idl { 25ca0551cfSopenharmony_civoid CodeEmitter::EmitLicense(StringBuilder &sb) 26ca0551cfSopenharmony_ci{ 27ca0551cfSopenharmony_ci if (ast_->GetLicense().empty()) { 28ca0551cfSopenharmony_ci return; 29ca0551cfSopenharmony_ci } 30ca0551cfSopenharmony_ci sb.Append(ast_->GetLicense()).Append("\n\n"); 31ca0551cfSopenharmony_ci} 32ca0551cfSopenharmony_ci 33ca0551cfSopenharmony_cibool CodeEmitter::NeedFlag(const AutoPtr<ASTMethod> &method) const 34ca0551cfSopenharmony_ci{ 35ca0551cfSopenharmony_ci for (size_t i = 0; i < method->GetParameterNumber(); i++) { 36ca0551cfSopenharmony_ci AutoPtr<ASTParameter> param = method->GetParameter(i); 37ca0551cfSopenharmony_ci if (param == nullptr) { 38ca0551cfSopenharmony_ci return false; 39ca0551cfSopenharmony_ci } 40ca0551cfSopenharmony_ci AutoPtr<ASTType> type = param->GetType(); 41ca0551cfSopenharmony_ci if ((param->GetAttribute() & ASTParamAttr::PARAM_OUT) && 42ca0551cfSopenharmony_ci (type->IsStringType() || type->IsArrayType() || type->IsListType())) { 43ca0551cfSopenharmony_ci return true; 44ca0551cfSopenharmony_ci } 45ca0551cfSopenharmony_ci } 46ca0551cfSopenharmony_ci return false; 47ca0551cfSopenharmony_ci} 48ca0551cfSopenharmony_ci 49ca0551cfSopenharmony_ci/* 50ca0551cfSopenharmony_ci * -r option: -r ohos.hdi:./drivers/interface 51ca0551cfSopenharmony_ci * outDir: ./out 52ca0551cfSopenharmony_ci * package: ohos.hdi.foo.v1_0 53ca0551cfSopenharmony_ci * subPackage: foo.v1_0 54ca0551cfSopenharmony_ci * subPath: foo/v1_0 55ca0551cfSopenharmony_ci * GenPath: ./out/foo/v1_0/ 56ca0551cfSopenharmony_ci */ 57ca0551cfSopenharmony_cistd::string CodeEmitter::GetFileParentPath(const std::string &outDir) const 58ca0551cfSopenharmony_ci{ 59ca0551cfSopenharmony_ci if (outDir.size() > SIZE_MAX) { 60ca0551cfSopenharmony_ci return std::string(""); 61ca0551cfSopenharmony_ci } 62ca0551cfSopenharmony_ci std::string outPath = StringHelper::EndWith(outDir, SEPARATOR) ? outDir.substr(0, outDir.size() - 1) : outDir; 63ca0551cfSopenharmony_ci std::string subPackage = Options::GetInstance().GetSubPackage(ast_->GetPackageName()); 64ca0551cfSopenharmony_ci std::string subPath = StringHelper::Replace(subPackage, '.', SEPARATOR); 65ca0551cfSopenharmony_ci if (subPath.empty()) { 66ca0551cfSopenharmony_ci return File::AdapterPath(StringHelper::Format("%s/", outPath.c_str(), subPath.c_str())); 67ca0551cfSopenharmony_ci } else { 68ca0551cfSopenharmony_ci return File::AdapterPath(StringHelper::Format("%s/%s/", outPath.c_str(), subPath.c_str())); 69ca0551cfSopenharmony_ci } 70ca0551cfSopenharmony_ci} 71ca0551cfSopenharmony_ci 72ca0551cfSopenharmony_cistd::string CodeEmitter::PackageToFilePath(const std::string &packageName) const 73ca0551cfSopenharmony_ci{ 74ca0551cfSopenharmony_ci std::vector<std::string> packageVec = StringHelper::Split(Options::GetInstance().GetSubPackage(packageName), "."); 75ca0551cfSopenharmony_ci StringBuilder filePath; 76ca0551cfSopenharmony_ci for (auto iter = packageVec.begin(); iter != packageVec.end(); iter++) { 77ca0551cfSopenharmony_ci filePath.Append(FileName(*iter)); 78ca0551cfSopenharmony_ci if (iter != packageVec.end() - 1) { 79ca0551cfSopenharmony_ci filePath.Append(SEPARATOR); 80ca0551cfSopenharmony_ci } 81ca0551cfSopenharmony_ci } 82ca0551cfSopenharmony_ci 83ca0551cfSopenharmony_ci return filePath.ToString(); 84ca0551cfSopenharmony_ci} 85ca0551cfSopenharmony_ci 86ca0551cfSopenharmony_cistd::string CodeEmitter::InterfaceToFilePath(const std::string &interfaceName) const 87ca0551cfSopenharmony_ci{ 88ca0551cfSopenharmony_ci std::string fullName = interfaceName; 89ca0551cfSopenharmony_ci size_t index; 90ca0551cfSopenharmony_ci if (StringHelper::EndWith(fullName, "]")) { 91ca0551cfSopenharmony_ci index = fullName.find("["); 92ca0551cfSopenharmony_ci fullName = fullName.substr(0, index); 93ca0551cfSopenharmony_ci } 94ca0551cfSopenharmony_ci 95ca0551cfSopenharmony_ci index = fullName.rfind("."); 96ca0551cfSopenharmony_ci std::string prefix = fullName.substr(0, index + 1); 97ca0551cfSopenharmony_ci std::string suffix = fullName.substr(index + 1); 98ca0551cfSopenharmony_ci std::string fileName = prefix + (StringHelper::StartWith(suffix, "I") ? suffix.substr(1) : suffix) + "Proxy"; 99ca0551cfSopenharmony_ci return PackageToFilePath(fileName); 100ca0551cfSopenharmony_ci} 101ca0551cfSopenharmony_ci 102ca0551cfSopenharmony_cistd::string CodeEmitter::EmitMethodCmdID(const AutoPtr<ASTMethod> &method) 103ca0551cfSopenharmony_ci{ 104ca0551cfSopenharmony_ci return StringHelper::Format("CMD_%s_%s%s", 105ca0551cfSopenharmony_ci ConstantName(baseName_).c_str(), ConstantName(method->GetName()).c_str(), 106ca0551cfSopenharmony_ci method->GetMethodIdentifier().c_str()); 107ca0551cfSopenharmony_ci} 108ca0551cfSopenharmony_ci 109ca0551cfSopenharmony_civoid CodeEmitter::EmitInterfaceMethodCommands(StringBuilder &sb, const std::string &prefix) 110ca0551cfSopenharmony_ci{ 111ca0551cfSopenharmony_ci sb.Append(prefix).AppendFormat("enum {\n"); 112ca0551cfSopenharmony_ci sb.Append(prefix + TAB).Append(EmitMethodCmdID(interface_->GetVersionMethod())).Append(" = 0,\n"); 113ca0551cfSopenharmony_ci int i = 0; 114ca0551cfSopenharmony_ci for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) { 115ca0551cfSopenharmony_ci sb.Append(prefix + TAB).Append(EmitMethodCmdID(method)).AppendFormat(" = %d", i + 1).Append(",\n"); 116ca0551cfSopenharmony_ci i++; 117ca0551cfSopenharmony_ci } 118ca0551cfSopenharmony_ci sb.Append(prefix).Append("};\n"); 119ca0551cfSopenharmony_ci} 120ca0551cfSopenharmony_ci 121ca0551cfSopenharmony_cistd::string CodeEmitter::EmitVersionHeaderName(const std::string &name) const 122ca0551cfSopenharmony_ci{ 123ca0551cfSopenharmony_ci return StringHelper::Format("v%u_%u/%s", ast_->GetMajorVer(), ast_->GetMinorVer(), FileName(name).c_str()); 124ca0551cfSopenharmony_ci} 125ca0551cfSopenharmony_ci 126ca0551cfSopenharmony_civoid CodeEmitter::EmitLogTagMacro(StringBuilder &sb, const std::string &name) const 127ca0551cfSopenharmony_ci{ 128ca0551cfSopenharmony_ci sb.AppendFormat("#define HDF_LOG_TAG %s\n", name.c_str()); 129ca0551cfSopenharmony_ci} 130ca0551cfSopenharmony_ci 131ca0551cfSopenharmony_cistd::string CodeEmitter::ConstantName(const std::string &name) const 132ca0551cfSopenharmony_ci{ 133ca0551cfSopenharmony_ci StringBuilder sb; 134ca0551cfSopenharmony_ci 135ca0551cfSopenharmony_ci if (name.empty()) { 136ca0551cfSopenharmony_ci return name; 137ca0551cfSopenharmony_ci } 138ca0551cfSopenharmony_ci 139ca0551cfSopenharmony_ci for (size_t i = 0; i < name.size(); i++) { 140ca0551cfSopenharmony_ci char c = name[i]; 141ca0551cfSopenharmony_ci if (isupper(c) != 0) { 142ca0551cfSopenharmony_ci if (i > 1) { 143ca0551cfSopenharmony_ci sb.Append('_'); 144ca0551cfSopenharmony_ci } 145ca0551cfSopenharmony_ci sb.Append(c); 146ca0551cfSopenharmony_ci } else { 147ca0551cfSopenharmony_ci sb.Append(toupper(c)); 148ca0551cfSopenharmony_ci } 149ca0551cfSopenharmony_ci } 150ca0551cfSopenharmony_ci 151ca0551cfSopenharmony_ci return sb.ToString(); 152ca0551cfSopenharmony_ci} 153ca0551cfSopenharmony_ci 154ca0551cfSopenharmony_cistd::string CodeEmitter::PascalName(const std::string &name) const 155ca0551cfSopenharmony_ci{ 156ca0551cfSopenharmony_ci if (name.empty()) { 157ca0551cfSopenharmony_ci return name; 158ca0551cfSopenharmony_ci } 159ca0551cfSopenharmony_ci 160ca0551cfSopenharmony_ci StringBuilder sb; 161ca0551cfSopenharmony_ci for (size_t i = 0; i < name.size(); i++) { 162ca0551cfSopenharmony_ci char c = name[i]; 163ca0551cfSopenharmony_ci if (i == 0) { 164ca0551cfSopenharmony_ci if (islower(c)) { 165ca0551cfSopenharmony_ci c = toupper(c); 166ca0551cfSopenharmony_ci } 167ca0551cfSopenharmony_ci sb.Append(c); 168ca0551cfSopenharmony_ci } else { 169ca0551cfSopenharmony_ci if (c == '_') { 170ca0551cfSopenharmony_ci continue; 171ca0551cfSopenharmony_ci } 172ca0551cfSopenharmony_ci 173ca0551cfSopenharmony_ci if (islower(c) && name[i - 1] == '_') { 174ca0551cfSopenharmony_ci c = toupper(c); 175ca0551cfSopenharmony_ci } 176ca0551cfSopenharmony_ci sb.Append(c); 177ca0551cfSopenharmony_ci } 178ca0551cfSopenharmony_ci } 179ca0551cfSopenharmony_ci 180ca0551cfSopenharmony_ci return sb.ToString(); 181ca0551cfSopenharmony_ci} 182ca0551cfSopenharmony_ci 183ca0551cfSopenharmony_cistd::string CodeEmitter::FileName(const std::string &name) const 184ca0551cfSopenharmony_ci{ 185ca0551cfSopenharmony_ci if (name.empty()) { 186ca0551cfSopenharmony_ci return name; 187ca0551cfSopenharmony_ci } 188ca0551cfSopenharmony_ci 189ca0551cfSopenharmony_ci StringBuilder sb; 190ca0551cfSopenharmony_ci for (size_t i = 0; i < name.size(); i++) { 191ca0551cfSopenharmony_ci char c = name[i]; 192ca0551cfSopenharmony_ci if (isupper(c) != 0) { 193ca0551cfSopenharmony_ci // 2->Index of the last char array. 194ca0551cfSopenharmony_ci if ((i > 1) && (name[i - 1] != '.') && (name[i - 2] != '.')) { 195ca0551cfSopenharmony_ci sb.Append('_'); 196ca0551cfSopenharmony_ci } 197ca0551cfSopenharmony_ci sb.Append(tolower(c)); 198ca0551cfSopenharmony_ci } else { 199ca0551cfSopenharmony_ci sb.Append(c); 200ca0551cfSopenharmony_ci } 201ca0551cfSopenharmony_ci } 202ca0551cfSopenharmony_ci 203ca0551cfSopenharmony_ci return StringHelper::Replace(sb.ToString(), '.', '/'); 204ca0551cfSopenharmony_ci} 205ca0551cfSopenharmony_ci 206ca0551cfSopenharmony_cistd::string CodeEmitter::GetNamespace(const std::string &fpnp) const 207ca0551cfSopenharmony_ci{ 208ca0551cfSopenharmony_ci size_t pos = fpnp.find(".."); 209ca0551cfSopenharmony_ci if (pos == std::string::npos) { 210ca0551cfSopenharmony_ci return fpnp; 211ca0551cfSopenharmony_ci } 212ca0551cfSopenharmony_ci 213ca0551cfSopenharmony_ci return fpnp.substr(pos + strlen("..")); 214ca0551cfSopenharmony_ci} 215ca0551cfSopenharmony_ci 216ca0551cfSopenharmony_civoid CodeEmitter::EmitHeadMacro(StringBuilder &sb, const std::string &fullName) const 217ca0551cfSopenharmony_ci{ 218ca0551cfSopenharmony_ci std::string macroName = MacroName(fullName); 219ca0551cfSopenharmony_ci sb.Append("#ifndef ").Append(macroName).Append("\n"); 220ca0551cfSopenharmony_ci sb.Append("#define ").Append(macroName).Append("\n"); 221ca0551cfSopenharmony_ci} 222ca0551cfSopenharmony_ci 223ca0551cfSopenharmony_civoid CodeEmitter::EmitTailMacro(StringBuilder &sb, const std::string &fullName) const 224ca0551cfSopenharmony_ci{ 225ca0551cfSopenharmony_ci std::string macroName = MacroName(fullName); 226ca0551cfSopenharmony_ci sb.Append("#endif // ").Append(macroName.c_str()).Append("\n\n"); 227ca0551cfSopenharmony_ci} 228ca0551cfSopenharmony_ci 229ca0551cfSopenharmony_civoid CodeEmitter::EmitHeadExternC(StringBuilder &sb) const 230ca0551cfSopenharmony_ci{ 231ca0551cfSopenharmony_ci sb.Append("#ifdef __cplusplus\n"); 232ca0551cfSopenharmony_ci sb.Append("extern \"C\" {\n"); 233ca0551cfSopenharmony_ci sb.Append("#endif /* __cplusplus */\n"); 234ca0551cfSopenharmony_ci} 235ca0551cfSopenharmony_ci 236ca0551cfSopenharmony_civoid CodeEmitter::EmitTailExternC(StringBuilder &sb) const 237ca0551cfSopenharmony_ci{ 238ca0551cfSopenharmony_ci sb.Append("#ifdef __cplusplus\n"); 239ca0551cfSopenharmony_ci sb.Append("}\n"); 240ca0551cfSopenharmony_ci sb.Append("#endif /* __cplusplus */\n"); 241ca0551cfSopenharmony_ci} 242ca0551cfSopenharmony_ci 243ca0551cfSopenharmony_cistd::string CodeEmitter::MacroName(const std::string &name) const 244ca0551cfSopenharmony_ci{ 245ca0551cfSopenharmony_ci if (name.empty()) { 246ca0551cfSopenharmony_ci return name; 247ca0551cfSopenharmony_ci } 248ca0551cfSopenharmony_ci 249ca0551cfSopenharmony_ci std::string macro = StringHelper::StrToUpper(StringHelper::Replace(name, '.', '_')) + "_H"; 250ca0551cfSopenharmony_ci return macro; 251ca0551cfSopenharmony_ci} 252ca0551cfSopenharmony_ci} // namespace Idl 253ca0551cfSopenharmony_ci} // namespace OHOS 254