diff --git a/framework/tools/hdi-gen/ast/ast.h b/framework/tools/hdi-gen/ast/ast.h index e5a35da68c93c30b737081bb35434d53a59fff37..6c8ed9bacf292cb214f9fa99fb23be8cd4c8de7c 100644 --- a/framework/tools/hdi-gen/ast/ast.h +++ b/framework/tools/hdi-gen/ast/ast.h @@ -107,6 +107,11 @@ public: AutoPtr GetNamespace(size_t index); + inline std::vector> GetNamespace() + { + return namespaces_; + } + inline size_t GetNamespaceNumber() { return namespaces_.size(); @@ -153,6 +158,11 @@ public: bool AddImport(const AutoPtr &importAst); + void ClearImport() + { + return imports_.clear(); + } + inline const StrASTMap &GetImports() const { return imports_; diff --git a/framework/tools/hdi-gen/ast/ast_interface_type.cpp b/framework/tools/hdi-gen/ast/ast_interface_type.cpp index 5265a9b9b89748a1171b3fc95a4d3eff8db5b00e..9d264ee8956ea82d656bca24a9719328aa022634 100644 --- a/framework/tools/hdi-gen/ast/ast_interface_type.cpp +++ b/framework/tools/hdi-gen/ast/ast_interface_type.cpp @@ -27,6 +27,30 @@ void ASTInterfaceType::AddMethod(const AutoPtr &method) methods_.push_back(method); } +AutoPtr ASTInterfaceType::GetMethod(size_t index) +{ + if (index >= methods_.size()) { + return nullptr; + } + + return methods_[index]; +} + +bool ASTInterfaceType::AddExtendsInterface(AutoPtr interface) +{ + if (extendsInterface_ != nullptr) { + return false; + } + extendsInterface_ = interface; + return true; +} + +void ASTInterfaceType::SetVersion(size_t &majorVer, size_t &minorVer) +{ + majorVersion_ = majorVer; + minorVersion_ = minorVer; +} + std::vector> ASTInterfaceType::GetMethodsBySystem(SystemLevel system) const { std::vector> methods; @@ -106,13 +130,15 @@ std::string ASTInterfaceType::EmitCppType(TypeMode mode) const } switch (mode) { case TypeMode::NO_MODE: - return StringHelper::Format("%s<%s>", pointerName.c_str(), name_.c_str()); + return StringHelper::Format("%s<%s>", pointerName.c_str(), GetNameWithNamespace(namespace_, name_).c_str()); case TypeMode::PARAM_IN: - return StringHelper::Format("const %s<%s>&", pointerName.c_str(), name_.c_str()); + return StringHelper::Format( + "const %s<%s>&", pointerName.c_str(), GetNameWithNamespace(namespace_, name_).c_str()); case TypeMode::PARAM_OUT: - return StringHelper::Format("%s<%s>&", pointerName.c_str(), name_.c_str()); + return StringHelper::Format( + "%s<%s>&", pointerName.c_str(), GetNameWithNamespace(namespace_, name_).c_str()); case TypeMode::LOCAL_VAR: - return StringHelper::Format("%s<%s>", pointerName.c_str(), name_.c_str()); + return StringHelper::Format("%s<%s>", pointerName.c_str(), GetNameWithNamespace(namespace_, name_).c_str()); default: return "unknow type"; } @@ -159,9 +185,15 @@ void ASTInterfaceType::EmitCStubReadVar(const std::string &parcelName, const std void ASTInterfaceType::EmitCppWriteVar(const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix, unsigned int innerLevel) const { + sb.Append(prefix).AppendFormat("if (%s == nullptr) {\n", name.c_str()); + sb.Append(prefix + TAB) + .AppendFormat("HDF_LOGE(\"%%{public}s: parameter %s is nullptr!\", __func__);\n", name.c_str()); + sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n"); + sb.Append(prefix).Append("}\n"); + sb.Append("\n"); sb.Append(prefix).AppendFormat("if (!%s.WriteRemoteObject(", parcelName.c_str()); sb.AppendFormat("OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(%s, %s::GetDescriptor()))) {\n", - name.c_str(), name_.c_str()); + name.c_str(), GetNameWithNamespace(namespace_, name_).c_str()); sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str()); sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n"); sb.Append(prefix).Append("}\n"); @@ -171,10 +203,10 @@ void ASTInterfaceType::EmitCppReadVar(const std::string &parcelName, const std:: const std::string &prefix, bool initVariable, unsigned int innerLevel) const { if (initVariable) { - sb.Append(prefix).AppendFormat("sptr<%s> %s;\n", name_.c_str(), name.c_str()); + sb.Append(prefix).AppendFormat("sptr<%s> %s;\n", GetNameWithNamespace(namespace_, name_).c_str(), name.c_str()); } - sb.Append(prefix).AppendFormat( - "if (!ReadInterface<%s>(%s, %s)) {\n", name_.c_str(), parcelName.c_str(), name.c_str()); + sb.Append(prefix).AppendFormat("if (!ReadInterface<%s>(%s, %s)) {\n", + GetNameWithNamespace(namespace_, name_).c_str(), parcelName.c_str(), name.c_str()); sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read interface object\", __func__);\n"); sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n"); sb.Append(prefix).Append("}\n"); diff --git a/framework/tools/hdi-gen/ast/ast_interface_type.h b/framework/tools/hdi-gen/ast/ast_interface_type.h index 3160c20cba6862c403a15a27fafe13d870605d45..f3a8f43b98cea671fdab23e2a2b850952589020d 100644 --- a/framework/tools/hdi-gen/ast/ast_interface_type.h +++ b/framework/tools/hdi-gen/ast/ast_interface_type.h @@ -95,6 +95,8 @@ public: void AddMethod(const AutoPtr &method); + AutoPtr GetMethod(size_t index); + std::vector> GetMethodsBySystem(SystemLevel system) const; inline size_t GetMethodNumber() const @@ -112,6 +114,25 @@ public: return getVerMethod_; } + bool AddExtendsInterface(AutoPtr interface); + + AutoPtr GetExtendsInterface() + { + return extendsInterface_; + } + + inline size_t GetMajorVersion() + { + return majorVersion_; + } + + inline size_t GetMinorVersion() + { + return minorVersion_; + } + + void SetVersion(size_t &majorVer, size_t &minorVer); + bool IsInterfaceType() override; std::string ToString() const override; @@ -174,6 +195,9 @@ private: bool isSerializable_; std::vector> methods_; AutoPtr getVerMethod_; + AutoPtr extendsInterface_; + size_t majorVersion_; + size_t minorVersion_; }; } // namespace HDI } // namespace OHOS diff --git a/framework/tools/hdi-gen/ast/ast_type.cpp b/framework/tools/hdi-gen/ast/ast_type.cpp index f7aa92e19720da2c11f55a533b43c3b59e282adf..dd23d288ec7ddded6854a8a260788eaa5cf3fb52 100644 --- a/framework/tools/hdi-gen/ast/ast_type.cpp +++ b/framework/tools/hdi-gen/ast/ast_type.cpp @@ -311,5 +311,69 @@ void ASTType::RegisterReadMethod(Language language, SerMode mode, UtilMethodMap (void)language; (void)methods; } + +std::string ASTType::GetNameWithNamespace(AutoPtr space, std::string name) const +{ + std::vector namespaceVec = StringHelper::Split(space->ToString(), "."); + std::regex rVer("[V|v][0-9]+_[0-9]+"); + std::vector result; + bool findVersion = false; + + std::string rootPackage = Options::GetInstance().GetRootPackage(space->ToString()); + size_t rootPackageNum = StringHelper::Split(rootPackage, ".").size(); + + for (size_t i = 0; i < namespaceVec.size(); i++) { + std::string ns; + if (i < rootPackageNum) { + ns = StringHelper::StrToUpper(namespaceVec[i]); + } else if (!findVersion && std::regex_match(namespaceVec[i].c_str(), rVer)) { + ns = StringHelper::Replace(namespaceVec[i], 'v', 'V'); + findVersion = true; + } else { + if (findVersion) { + ns = namespaceVec[i]; + } else { + ns = PascalName(namespaceVec[i]); + } + } + + result.emplace_back(ns); + } + StringBuilder sb; + for (const auto &ns : result) { + sb.AppendFormat("%s::", ns.c_str()); + } + sb.Append(name); + return sb.ToString(); +} + +std::string ASTType::PascalName(const std::string &name) const +{ + if (name.empty()) { + return name; + } + + StringBuilder sb; + for (size_t i = 0; i < name.size(); i++) { + char c = name[i]; + if (i == 0) { + if (islower(c)) { + c = toupper(c); + } + sb.Append(c); + } else { + if (c == '_') { + continue; + } + + if (islower(c) && name[i - 1] == '_') { + c = toupper(c); + } + sb.Append(c); + } + } + + return sb.ToString(); +} } // namespace HDI } // namespace OHOS \ No newline at end of file diff --git a/framework/tools/hdi-gen/ast/ast_type.h b/framework/tools/hdi-gen/ast/ast_type.h index 7c6d3fbabf6ee7263ce5fa3b32802ba4450812bc..b20dbf2ca6974060dc1403192217dda7953599aa 100644 --- a/framework/tools/hdi-gen/ast/ast_type.h +++ b/framework/tools/hdi-gen/ast/ast_type.h @@ -10,6 +10,7 @@ #define OHOS_HDI_ASTTYPE_H #include +#include #include #include "ast/ast_namespace.h" @@ -198,6 +199,10 @@ public: virtual void RegisterReadMethod(Language language, SerMode mode, UtilMethodMap &methods) const; + virtual std::string GetNameWithNamespace(AutoPtr space, std::string name) const; + + virtual std::string PascalName(const std::string &name) const; + protected: TypeKind typeKind_; bool isPod_; diff --git a/framework/tools/hdi-gen/build_hdi_files_info.py b/framework/tools/hdi-gen/build_hdi_files_info.py index 7ea06e2ecff00933ec7b4381cd845d25cc9937b2..f133cf07cda07285c2a8d433a41a8afdb04d85a7 100755 --- a/framework/tools/hdi-gen/build_hdi_files_info.py +++ b/framework/tools/hdi-gen/build_hdi_files_info.py @@ -309,6 +309,11 @@ class IdlDetail(object): class IdlParser(object): def parse(self, ): all_idl_details = {} + if Option.language == "c": + self.parse_c_idl_files(all_idl_details) + self.parse_module_info(all_idl_details) + return + for idl_file in Option.idl_sources: idl_detail = self.parse_one(idl_file) all_idl_details[idl_detail.full_name()] = idl_detail @@ -333,6 +338,48 @@ class IdlParser(object): lex.get_token() return cur_idl_detail + def parse_c_idl_files(self, all_idl_details): + idl_sources_set = set() + idl_queue = [] + for idl_file in Option.idl_sources: + idl_queue.append(idl_file) + while len(idl_queue) > 0: + cur_idl_file = idl_queue.pop(0) + if cur_idl_file in idl_sources_set: + continue + idl_sources_set.add(cur_idl_file) + self.parse_c_idl_files_import(cur_idl_file, idl_queue) + for idl_file in idl_sources_set: + idl_detail = self.parse_one(idl_file) + all_idl_details[idl_detail.full_name()] = idl_detail + self.merged_idl_details(all_idl_details) + + def parse_c_idl_files_import(self, file_path, idl_queue): + lex = Lexer(file_path) + while lex.peek_token().token_type != TokenType.END_OF_FILE: + cur_token_type = lex.peek_token().token_type + if cur_token_type == TokenType.IMPORT: + lex.get_token() + token = lex.peek_token() + if lex.peek_token().token_type != TokenType.ID: + raise Exception("{}: expected package name before '{}'".format( + token.info(), token.value)) + idl_queue.append( + CodeGen.get_package_path(token.value) + ".idl") + lex.get_token() + + def merged_idl_details(self, all_idl_details): + merged_details = {} + source_idl_detail = self.parse_one(Option.idl_sources[0]) + for key, value in all_idl_details.items(): + if value.file_name not in merged_details: + value.package = source_idl_detail.package + value.version = source_idl_detail.version + merged_details[value.file_name] = value + all_idl_details.clear() + for key, value in merged_details.items(): + all_idl_details[key] = value + def parse_package(self, lex, cur_idl_detail): lex.get_token() # package token token = lex.peek_token() diff --git a/framework/tools/hdi-gen/codegen/code_emitter.cpp b/framework/tools/hdi-gen/codegen/code_emitter.cpp index 10bfe08353d23066815ef990d654d40e26ea1cc5..5ea7d0bac461d11446a272ad72647e2f43bbc435 100644 --- a/framework/tools/hdi-gen/codegen/code_emitter.cpp +++ b/framework/tools/hdi-gen/codegen/code_emitter.cpp @@ -146,11 +146,12 @@ std::string CodeEmitter::EmitMethodCmdID(const AutoPtr &method) void CodeEmitter::EmitInterfaceMethodCommands(StringBuilder &sb, const std::string &prefix) { sb.Append(prefix).AppendFormat("enum {\n"); + sb.Append(prefix + TAB).Append(EmitMethodCmdID(interface_->GetVersionMethod())).Append(" = 0,\n"); + int i = 0; for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) { - sb.Append(prefix + TAB).Append(EmitMethodCmdID(method)).Append(",\n"); + sb.Append(prefix + TAB).Append(EmitMethodCmdID(method)).AppendFormat(" = %d", i + 1).Append(",\n"); + i++; } - - sb.Append(prefix + TAB).Append(EmitMethodCmdID(interface_->GetVersionMethod())).Append(",\n"); sb.Append(prefix).Append("};\n"); } diff --git a/framework/tools/hdi-gen/codegen/code_generator.cpp b/framework/tools/hdi-gen/codegen/code_generator.cpp index 2cbf639c352949df7936f78f85b644e068c1fc7f..ff62d10941b77dd0333abe049c325b148dfc7af6 100644 --- a/framework/tools/hdi-gen/codegen/code_generator.cpp +++ b/framework/tools/hdi-gen/codegen/code_generator.cpp @@ -116,11 +116,19 @@ bool CodeGenerator::Generate(const StrAstMap &allAst) std::string outDir = Options::GetInstance().GetGenerationDirectory(); std::set sourceFile = Options::GetInstance().GetSourceFiles(); - for (const auto &ast : allAst) { - if (sourceFile.find(ast.second->GetIdlFilePath()) != sourceFile.end()) { + Language language = Options::GetInstance().GetLanguage(); + if (language == Language::CPP) { + for (const auto &ast : allAst) { + if (sourceFile.find(ast.second->GetIdlFilePath()) != sourceFile.end()) { + genCodeFunc(ast.second, outDir); + } + } + } else if (language == Language::C) { + for (const auto &ast : allAst) { genCodeFunc(ast.second, outDir); } } + return true; } diff --git a/framework/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.cpp b/framework/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.cpp index 8a3b759a30235e17185a6364ffada7a4c42c68df..cf6cb32f1047bf738c83f51ef236a1917a302096 100644 --- a/framework/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.cpp +++ b/framework/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.cpp @@ -77,6 +77,10 @@ void CppClientProxyCodeEmitter::EmitProxyHeaderInclusions(StringBuilder &sb) HeaderFile::HeaderFileSet headerFiles; headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(interfaceName_)); + if (interface_->GetExtendsInterface() != nullptr) { + headerFiles.emplace( + HeaderFileType::OWN_HEADER_FILE, EmitHeaderNameByInterface(interface_->GetExtendsInterface(), proxyName_)); + } GetHeaderOtherLibInclusions(headerFiles); for (const auto &file : headerFiles) { @@ -92,7 +96,8 @@ void CppClientProxyCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFi void CppClientProxyCodeEmitter::EmitProxyDecl(StringBuilder &sb, const std::string &prefix) { (void)prefix; - sb.AppendFormat("class %s : public IProxyBroker<%s> {\n", proxyName_.c_str(), interfaceName_.c_str()); + sb.AppendFormat("class %s : public IProxyBroker<%s> {\n", proxyName_.c_str(), + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); sb.Append("public:\n"); EmitProxyConstructor(sb, TAB); sb.Append("\n"); @@ -106,18 +111,30 @@ void CppClientProxyCodeEmitter::EmitProxyDecl(StringBuilder &sb, const std::stri void CppClientProxyCodeEmitter::EmitProxyConstructor(StringBuilder &sb, const std::string &prefix) const { sb.Append(prefix).AppendFormat("explicit %s(const sptr& remote)", proxyName_.c_str()); - sb.AppendFormat(" : IProxyBroker<%s>(remote) {}\n\n", interfaceName_.c_str()); + sb.AppendFormat( + " : IProxyBroker<%s>(remote) {}\n\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str()); sb.Append(prefix).AppendFormat("virtual ~%s() = default;\n", proxyName_.c_str()); } void CppClientProxyCodeEmitter::EmitProxyMethodDecls(StringBuilder &sb, const std::string &prefix) const { + AutoPtr interface = interface_; + while (interface != nullptr) { + for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) { + EmitProxyMethodDecl(method, sb, prefix); + sb.Append("\n"); + } + interface = interface->GetExtendsInterface(); + } + EmitProxyMethodDecl(interface_->GetVersionMethod(), sb, prefix); for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) { - EmitProxyMethodDecl(method, sb, prefix); sb.Append("\n"); + EmitProxyStaticMethodDecl(method, sb, prefix); + } + if (interface_->GetExtendsInterface() == nullptr) { + sb.Append("\n"); + EmitProxyStaticMethodDecl(interface_->GetVersionMethod(), sb, prefix); } - - EmitProxyMethodDecl(interface_->GetVersionMethod(), sb, prefix); } void CppClientProxyCodeEmitter::EmitProxyMethodDecl( @@ -144,9 +161,34 @@ void CppClientProxyCodeEmitter::EmitProxyMethodDecl( } } +void CppClientProxyCodeEmitter::EmitProxyStaticMethodDecl( + const AutoPtr &method, StringBuilder &sb, const std::string &prefix) const +{ + if (method->GetParameterNumber() == 0) { + sb.Append(prefix).AppendFormat( + "static int32_t %s_(const sptr remote);\n", method->GetName().c_str()); + } else { + StringBuilder paramStr; + paramStr.Append(prefix).AppendFormat("static int32_t %s_(", method->GetName().c_str()); + + for (size_t i = 0; i < method->GetParameterNumber(); i++) { + AutoPtr param = method->GetParameter(i); + EmitProxyMethodParameter(param, paramStr, ""); + paramStr.Append(", "); + } + paramStr.Append("const sptr remote"); + + paramStr.Append(");"); + + sb.Append(SpecificationParam(paramStr, prefix + TAB)); + sb.Append("\n"); + } +} + void CppClientProxyCodeEmitter::EmitProxyConstants(StringBuilder &sb, const std::string &prefix) const { - sb.Append(prefix).AppendFormat("static inline BrokerDelegator<%s> delegator_;\n", proxyName_.c_str()); + sb.Append(prefix).AppendFormat( + "static inline BrokerDelegator<%s> delegator_;\n", EmitDefinitionByInterface(interface_, proxyName_).c_str()); } void CppClientProxyCodeEmitter::EmitProxyMethodParameter( @@ -295,8 +337,8 @@ void CppClientProxyCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFi void CppClientProxyCodeEmitter::EmitGetMethodImpl(StringBuilder &sb, const std::string &prefix) const { - sb.Append(prefix).AppendFormat( - "%s %s::Get(bool isStub)\n", interface_->EmitCppType().c_str(), interface_->GetName().c_str()); + sb.Append(prefix).AppendFormat("%s %s::Get(bool isStub)\n", interface_->EmitCppType().c_str(), + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); sb.Append(prefix).Append("{\n"); sb.Append(prefix + TAB) .AppendFormat("return %s::Get(\"%s\", isStub);\n", interfaceName_.c_str(), FileName(implName_).c_str()); @@ -309,7 +351,8 @@ void CppClientProxyCodeEmitter::EmitGetInstanceMethodImpl(StringBuilder &sb, con std::string serMajorName = "serMajorVer"; std::string serMinorName = "serMinorVer"; sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(const std::string& serviceName, bool isStub)\n", - interface_->GetName().c_str(), interface_->GetName().c_str()); + EmitDefinitionByInterface(interface_, interfaceName_).c_str(), + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); sb.Append(prefix).Append("{\n"); EmitProxyPassthroughtLoadImpl(sb, prefix + TAB); sb.Append(prefix + TAB).Append("using namespace OHOS::HDI::ServiceManager::V1_0;\n"); @@ -325,7 +368,8 @@ void CppClientProxyCodeEmitter::EmitGetInstanceMethodImpl(StringBuilder &sb, con sb.Append(prefix + TAB + TAB).Append("return nullptr;\n"); sb.Append(prefix + TAB).Append("}\n\n"); sb.Append(prefix + TAB).AppendFormat("sptr<%s> %s = OHOS::HDI::hdi_facecast<%s>(remote);\n", - interfaceName_.c_str(), objName.c_str(), interfaceName_.c_str()); + EmitDefinitionByInterface(interface_, interfaceName_).c_str(), objName.c_str(), + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); sb.Append(prefix + TAB).AppendFormat("if (%s == nullptr) {\n", objName.c_str()); sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:iface_cast failed!\", __func__);\n"); sb.Append(prefix + TAB + TAB).Append("return nullptr;\n"); @@ -340,11 +384,12 @@ void CppClientProxyCodeEmitter::EmitGetInstanceMethodImpl(StringBuilder &sb, con sb.Append(prefix + TAB + TAB).Append("return nullptr;\n"); sb.Append(prefix + TAB).Append("}\n\n"); - sb.Append(prefix + TAB).AppendFormat("if (%s != %s) {\n", serMajorName.c_str(), majorVerName_.c_str()); + sb.Append(prefix + TAB).AppendFormat("if (%s != %d || %s < %d) {\n", + serMajorName.c_str(), ast_->GetMajorVer(), serMinorName.c_str(), ast_->GetMinorVer()); sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:check version failed! "); - sb.Append("version of service:%u.%u, version of client:%u.%u\", __func__,\n"); - sb.Append(prefix + TAB + TAB + TAB).AppendFormat("%s, %s, %s, %s);\n", serMajorName.c_str(), serMinorName.c_str(), - majorVerName_.c_str(), minorVerName_.c_str()); + sb.Append("version of service:%u.%u"); + sb.AppendFormat(", version of client:%d.%d\", __func__, ", ast_->GetMajorVer(), ast_->GetMinorVer()); + sb.AppendFormat("%s, %s);\n", serMajorName.c_str(), serMinorName.c_str()); sb.Append(prefix + TAB + TAB).Append("return nullptr;\n"); sb.Append(prefix + TAB).Append("}\n\n"); sb.Append(prefix + TAB).AppendFormat("return %s;\n", objName.c_str()); @@ -358,10 +403,10 @@ void CppClientProxyCodeEmitter::EmitProxyPassthroughtLoadImpl(StringBuilder &sb, if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) { sb.Append(prefix + TAB).Append("std::string desc = "); sb.Append("std::wstring_convert, char16_t>{}.to_bytes("); - sb.AppendFormat("%s::GetDescriptor());\n", interfaceName_.c_str()); + sb.AppendFormat("%s::GetDescriptor());\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str()); } else { - sb.Append(prefix + TAB) - .AppendFormat("std::string desc = Str16ToStr8(%s::GetDescriptor());\n", interfaceName_.c_str()); + sb.Append(prefix + TAB).AppendFormat("std::string desc = Str16ToStr8(%s::GetDescriptor());\n", + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); } sb.Append(prefix + TAB).Append("void *impl = LoadHdiImpl(desc.c_str(), "); sb.AppendFormat("serviceName == \"%s\" ? \"service\" : serviceName.c_str());\n", FileName(implName_).c_str()); @@ -372,31 +417,51 @@ void CppClientProxyCodeEmitter::EmitProxyPassthroughtLoadImpl(StringBuilder &sb, if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) { sb.Append(prefix + TAB).AppendFormat("return std::shared_ptr<%s>(reinterpret_cast<%s *>(impl));\n", - interfaceName_.c_str(), interfaceName_.c_str()); + EmitDefinitionByInterface(interface_, interfaceName_).c_str(), + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); } else { - sb.Append(prefix + TAB).AppendFormat("return reinterpret_cast<%s *>(impl);\n", interfaceName_.c_str()); + sb.Append(prefix + TAB).AppendFormat("return reinterpret_cast<%s *>(impl);\n", + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); } sb.Append(prefix).Append("}\n\n"); } void CppClientProxyCodeEmitter::EmitProxyMethodImpls(StringBuilder &sb, const std::string &prefix) { + AutoPtr interface = interface_; + AutoPtr metaInterface = interface_; + while (interface != nullptr) { + for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) { + EmitProxyMethodImpl(interface, method, sb, prefix); + sb.Append("\n"); + } + interface = interface->GetExtendsInterface(); + if (interface != nullptr) { + metaInterface = interface; + } + } + AutoPtr verMethod = interface_->GetVersionMethod(); + EmitProxyMethodImpl(metaInterface, verMethod, sb, prefix); for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) { - EmitProxyMethodImpl(method, sb, prefix); sb.Append("\n"); + EmitProxyStaticMethodImpl(method, sb, prefix); + } + if (interface_->GetExtendsInterface() == nullptr) { + sb.Append("\n"); + EmitProxyStaticMethodImpl(interface_->GetVersionMethod(), sb, prefix); } - - EmitProxyMethodImpl(interface_->GetVersionMethod(), sb, prefix); } -void CppClientProxyCodeEmitter::EmitProxyMethodImpl( +void CppClientProxyCodeEmitter::EmitProxyMethodImpl(const AutoPtr interface, const AutoPtr &method, StringBuilder &sb, const std::string &prefix) { if (method->GetParameterNumber() == 0) { - sb.Append(prefix).AppendFormat("int32_t %s::%s()\n", proxyName_.c_str(), method->GetName().c_str()); + sb.Append(prefix).AppendFormat( + "int32_t %s::%s()\n", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str()); } else { StringBuilder paramStr; - paramStr.Append(prefix).AppendFormat("int32_t %s::%s(", proxyName_.c_str(), method->GetName().c_str()); + paramStr.Append(prefix).AppendFormat( + "int32_t %s::%s(", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str()); for (size_t i = 0; i < method->GetParameterNumber(); i++) { AutoPtr param = method->GetParameter(i); EmitProxyMethodParameter(param, paramStr, ""); @@ -410,10 +475,50 @@ void CppClientProxyCodeEmitter::EmitProxyMethodImpl( sb.Append(SpecificationParam(paramStr, prefix + TAB)); sb.Append("\n"); } - EmitProxyMethodBody(method, sb, prefix); + EmitProxyMethodBody(interface, method, sb, prefix); +} + +void CppClientProxyCodeEmitter::EmitProxyStaticMethodImpl( + const AutoPtr &method, StringBuilder &sb, const std::string &prefix) +{ + if (method->GetParameterNumber() == 0) { + sb.Append(prefix).AppendFormat("int32_t %s::%s_(const sptr remote)\n", + EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str()); + } else { + StringBuilder paramStr; + paramStr.Append(prefix).AppendFormat( + "int32_t %s::%s_(", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str()); + for (size_t i = 0; i < method->GetParameterNumber(); i++) { + AutoPtr param = method->GetParameter(i); + EmitProxyMethodParameter(param, paramStr, ""); + paramStr.Append(", "); + } + + paramStr.Append("const sptr remote)"); + sb.Append(SpecificationParam(paramStr, prefix + TAB)); + sb.Append("\n"); + } + EmitProxyStaticMethodBody(method, sb, prefix); } -void CppClientProxyCodeEmitter::EmitProxyMethodBody( +void CppClientProxyCodeEmitter::EmitProxyMethodBody(const AutoPtr interface, + const AutoPtr &method, StringBuilder &sb, const std::string &prefix) +{ + sb.Append(prefix).Append("{\n"); + sb.Append(prefix + TAB).AppendFormat("return %s::%s_(", + EmitDefinitionByInterface(interface, proxyName_).c_str(), method->GetName().c_str()); + if (method->GetParameterNumber() > 0) { + for (size_t i = 0; i < method->GetParameterNumber(); i++) { + AutoPtr param = method->GetParameter(i); + sb.Append(param->GetName().c_str()); + sb.Append(", "); + } + } + sb.Append("Remote());\n"); + sb.Append(prefix).Append("}\n"); +} + +void CppClientProxyCodeEmitter::EmitProxyStaticMethodBody( const AutoPtr &method, StringBuilder &sb, const std::string &prefix) { std::string option = method->IsOneWay() ? "MessageOption::TF_ASYNC" : "MessageOption::TF_SYNC"; @@ -439,9 +544,8 @@ void CppClientProxyCodeEmitter::EmitProxyMethodBody( } } - sb.Append(prefix + TAB).AppendFormat("int32_t %s = Remote()->SendRequest(%s, %s, %s, %s);\n", - errorCodeName_.c_str(), EmitMethodCmdID(method).c_str(), dataParcelName_.c_str(), replyParcelName_.c_str(), - optionName_.c_str()); + sb.Append(prefix + TAB).AppendFormat("int32_t %s = remote->SendRequest(%s, %s, %s, %s);\n", errorCodeName_.c_str(), + EmitMethodCmdID(method).c_str(), dataParcelName_.c_str(), replyParcelName_.c_str(), optionName_.c_str()); sb.Append(prefix + TAB).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str()); sb.Append(prefix + TAB + TAB).AppendFormat( "HDF_LOGE(\"%%{public}s failed, error code is %%{public}d\", __func__, %s);\n", errorCodeName_.c_str()); @@ -466,8 +570,8 @@ void CppClientProxyCodeEmitter::EmitProxyMethodBody( void CppClientProxyCodeEmitter::EmitWriteInterfaceToken( const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const { - sb.Append(prefix).AppendFormat( - "if (!%s.WriteInterfaceToken(%s::GetDescriptor())) {\n", parcelName.c_str(), interfaceName_.c_str()); + sb.Append(prefix).AppendFormat("if (!%s.WriteInterfaceToken(%s::GetDescriptor())) {\n", parcelName.c_str(), + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); sb.Append(prefix + TAB) .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write interface descriptor!\", __func__);\n"); sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n"); diff --git a/framework/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.h b/framework/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.h index c471467ead0def914a96c0ec9f13d14408e9d225..bb0eae80b1756b28c233c4fb8c4462b7c6bfdd5d 100644 --- a/framework/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.h +++ b/framework/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.h @@ -64,16 +64,25 @@ private: void EmitProxyMethodImpls(StringBuilder &sb, const std::string &prefix); - void EmitProxyMethodImpl(const AutoPtr &method, StringBuilder &sb, const std::string &prefix); + void EmitProxyMethodImpl(const AutoPtr interface, const AutoPtr &method, + StringBuilder &sb, const std::string &prefix); - void EmitProxyMethodBody(const AutoPtr &method, StringBuilder &sb, const std::string &prefix); + void EmitProxyMethodBody(const AutoPtr interface, const AutoPtr &method, + StringBuilder &sb, const std::string &prefix); void EmitWriteInterfaceToken(const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const; - void EmitWriteFlagOfNeedSetMem(const AutoPtr &method, - const std::string &dataBufName, StringBuilder &sb, const std::string &prefix) const; + void EmitWriteFlagOfNeedSetMem(const AutoPtr &method, const std::string &dataBufName, StringBuilder &sb, + const std::string &prefix) const; void GetUtilMethods(UtilMethodMap &methods) override; + + void EmitProxyStaticMethodDecl( + const AutoPtr &method, StringBuilder &sb, const std::string &prefix) const; + + void EmitProxyStaticMethodImpl(const AutoPtr &method, StringBuilder &sb, const std::string &prefix); + + void EmitProxyStaticMethodBody(const AutoPtr &method, StringBuilder &sb, const std::string &prefix); }; } // namespace HDI } // namespace OHOS diff --git a/framework/tools/hdi-gen/codegen/cpp_code_emitter.cpp b/framework/tools/hdi-gen/codegen/cpp_code_emitter.cpp index db935e706db074eb59396afe6f7b83f4a7a6239a..b91f1c8a88ff3d1cb81514019c47cc04bb20a63e 100644 --- a/framework/tools/hdi-gen/codegen/cpp_code_emitter.cpp +++ b/framework/tools/hdi-gen/codegen/cpp_code_emitter.cpp @@ -269,5 +269,24 @@ std::string CppCodeEmitter::SpecificationParam(StringBuilder ¶mSb, const std } return paramStr; } + +std::string CppCodeEmitter::EmitHeaderNameByInterface(AutoPtr interface, const std::string &name) +{ + return StringHelper::Format( + "v%u_%u/%s", interface->GetMajorVersion(), interface->GetMinorVersion(), FileName(name).c_str()); +} + +std::string CppCodeEmitter::EmitDefinitionByInterface( + AutoPtr interface, const std::string &name) const +{ + StringBuilder sb; + std::vector cppNamespaceVec = EmitCppNameSpaceVec(interface->GetNamespace()->ToString()); + for (const auto &nspace : cppNamespaceVec) { + sb.AppendFormat("%s", nspace.c_str()); + sb.Append("::"); + } + sb.Append(name.c_str()); + return sb.ToString(); +} } // namespace HDI } // namespace OHOS \ No newline at end of file diff --git a/framework/tools/hdi-gen/codegen/cpp_code_emitter.h b/framework/tools/hdi-gen/codegen/cpp_code_emitter.h index 89170b5c900e3902189430e5d846fd91d78d084c..e5a1079db19f7b3494e00f76cbeec7d911e10042 100644 --- a/framework/tools/hdi-gen/codegen/cpp_code_emitter.h +++ b/framework/tools/hdi-gen/codegen/cpp_code_emitter.h @@ -65,6 +65,10 @@ protected: std::string MacroName(const std::string &name) const; std::string SpecificationParam(StringBuilder ¶mSb, const std::string &prefix) const; + + std::string EmitHeaderNameByInterface(AutoPtr interface, const std::string &name); + + std::string EmitDefinitionByInterface(AutoPtr interface, const std::string &name) const; }; } // namespace HDI } // namespace OHOS diff --git a/framework/tools/hdi-gen/codegen/cpp_interface_code_emitter.cpp b/framework/tools/hdi-gen/codegen/cpp_interface_code_emitter.cpp index cecd9058af957ef19f1391852b3709207267ea7a..b8cd9fa9da1ad0d8e72b4c02a44a8f0f369fe5a7 100644 --- a/framework/tools/hdi-gen/codegen/cpp_interface_code_emitter.cpp +++ b/framework/tools/hdi-gen/codegen/cpp_interface_code_emitter.cpp @@ -52,8 +52,6 @@ void CppInterfaceCodeEmitter::EmitInterfaceHeaderFile() EmitHeadMacro(sb, interfaceFullName_); sb.Append("\n"); EmitInterfaceInclusions(sb); - sb.Append("\n"); - EmitInterfaceVersionMacro(sb); if (!Options::GetInstance().DoPassthrough()) { sb.Append("\n"); EmitInterfaceBuffSizeMacro(sb); @@ -63,7 +61,11 @@ void CppInterfaceCodeEmitter::EmitInterfaceHeaderFile() EmitUsingNamespace(sb); if (!Options::GetInstance().DoPassthrough()) { sb.Append("\n"); - EmitInterfaceMethodCommands(sb, ""); + if (interface_->GetExtendsInterface() == nullptr) { + EmitInterfaceMethodCommands(sb, ""); + } else { + EmitInterfaceMethodCommandsWithExtends(sb, ""); + } } sb.Append("\n"); EmitInterfaceDefinition(sb); @@ -106,27 +108,40 @@ void CppInterfaceCodeEmitter::EmitInterfaceVersionMacro(StringBuilder &sb) const void CppInterfaceCodeEmitter::EmitInterfaceDefinition(StringBuilder &sb) { - if (!interface_->IsSerializable()) { + AutoPtr interface = interface_->GetExtendsInterface(); + if (interface != nullptr) { + sb.AppendFormat("class %s : public %s {\n", interfaceName_.c_str(), + EmitDefinitionByInterface(interface, interfaceName_).c_str()); + } else { sb.AppendFormat("class %s : public HdiBase {\n", interfaceName_.c_str()); - sb.Append("public:\n"); - EmitInterfaceDescriptor(sb, TAB); - sb.Append("\n"); - EmitInterfaceDestruction(sb, TAB); - sb.Append("\n"); + } + sb.Append("public:\n"); + EmitInterfaceDescriptor(sb, TAB); + sb.Append("\n"); + EmitInterfaceDestruction(sb, TAB); + sb.Append("\n"); + if (!interface_->IsSerializable()) { EmitGetMethodDecl(sb, TAB); sb.Append("\n"); - EmitInterfaceMethodsDecl(sb, TAB); - sb.Append("};\n"); + } + EmitInterfaceMethodsDecl(sb, TAB); + sb.Append("\n"); + EmitGetDescMethod(sb, TAB); + sb.Append("};\n"); +} + +void CppInterfaceCodeEmitter::EmitGetDescMethod(StringBuilder &sb, const std::string &prefix) const +{ + AutoPtr interface = interface_->GetExtendsInterface(); + if (interface == nullptr) { + sb.Append(prefix).Append("virtual const std::u16string GetDesc()"); } else { - sb.AppendFormat("class %s : public HdiBase {\n", interfaceName_.c_str()); - sb.Append("public:\n"); - EmitInterfaceDescriptor(sb, TAB); - sb.Append("\n"); - EmitInterfaceDestruction(sb, TAB); - sb.Append("\n"); - EmitInterfaceMethodsDecl(sb, TAB); - sb.Append("};\n"); + sb.Append(prefix).Append("const std::u16string GetDesc() override"); } + sb.Append("\n"); + sb.Append(prefix).Append("{").Append("\n"); + sb.Append(prefix + TAB).Append("return metaDescriptor_;\n"); + sb.Append(prefix).Append("}\n"); } void CppInterfaceCodeEmitter::EmitInterfaceDescriptor(StringBuilder &sb, const std::string &prefix) const @@ -182,7 +197,11 @@ void CppInterfaceCodeEmitter::EmitInterfaceMethodDecl( void CppInterfaceCodeEmitter::EmitInterfaceGetVersionMethod(StringBuilder &sb, const std::string &prefix) const { AutoPtr method = interface_->GetVersionMethod(); - sb.Append(prefix).AppendFormat("virtual int32_t %s(", method->GetName().c_str()); + if (interface_->GetExtendsInterface() == nullptr) { + sb.Append(prefix).AppendFormat("virtual int32_t %s(", method->GetName().c_str()); + } else { + sb.Append(prefix).AppendFormat("int32_t %s(", method->GetName().c_str()); + } for (size_t i = 0; i < method->GetParameterNumber(); i++) { AutoPtr param = method->GetParameter(i); EmitInterfaceMethodParameter(param, sb, ""); @@ -190,14 +209,17 @@ void CppInterfaceCodeEmitter::EmitInterfaceGetVersionMethod(StringBuilder &sb, c sb.Append(", "); } } - - sb.AppendFormat(")\n"); + sb.Append(")"); + if (interface_->GetExtendsInterface() != nullptr) { + sb.Append(" override"); + } + sb.Append("\n"); sb.Append(prefix).Append("{\n"); AutoPtr majorParam = method->GetParameter(0); - sb.Append(prefix + TAB).AppendFormat("%s = %s;\n", majorParam->GetName().c_str(), majorVerName_.c_str()); + sb.Append(prefix + TAB).AppendFormat("%s = %d;\n", majorParam->GetName().c_str(), ast_->GetMajorVer()); AutoPtr minorParam = method->GetParameter(1); - sb.Append(prefix + TAB).AppendFormat("%s = %s;\n", minorParam->GetName().c_str(), minorVerName_.c_str()); + sb.Append(prefix + TAB).AppendFormat("%s = %d;\n", minorParam->GetName().c_str(), ast_->GetMinorVer()); sb.Append(prefix + TAB).Append("return HDF_SUCCESS;\n"); sb.Append(prefix).Append("}\n"); @@ -208,5 +230,25 @@ void CppInterfaceCodeEmitter::EmitInterfaceMethodParameter( { sb.Append(prefix).Append(param->EmitCppParameter()); } + +void CppInterfaceCodeEmitter::EmitInterfaceMethodCommandsWithExtends(StringBuilder &sb, const std::string &prefix) +{ + size_t extendMethods = 0; + AutoPtr interface = interface_->GetExtendsInterface(); + while (interface != nullptr) { + extendMethods += interface->GetMethodNumber(); + interface = interface->GetExtendsInterface(); + } + + sb.Append(prefix).AppendFormat("enum {\n"); + for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { + AutoPtr method = interface_->GetMethod(i); + sb.Append(prefix + TAB) + .Append(EmitMethodCmdID(method)) + .AppendFormat(" = %d", extendMethods + i + 1) + .Append(",\n"); + } + sb.Append(prefix).Append("};\n"); +} } // namespace HDI } // namespace OHOS \ No newline at end of file diff --git a/framework/tools/hdi-gen/codegen/cpp_interface_code_emitter.h b/framework/tools/hdi-gen/codegen/cpp_interface_code_emitter.h index 0f6833ff8f830810b6aae890c9a5c51278b7e580..e7d0fd079a5bcb29813177493a823b8444c03ab3 100644 --- a/framework/tools/hdi-gen/codegen/cpp_interface_code_emitter.h +++ b/framework/tools/hdi-gen/codegen/cpp_interface_code_emitter.h @@ -48,6 +48,10 @@ private: void EmitInterfaceMethodParameter( const AutoPtr ¶m, StringBuilder &sb, const std::string &prefix) const; + + void EmitInterfaceMethodCommandsWithExtends(StringBuilder &sb, const std::string &prefix); + + void EmitGetDescMethod(StringBuilder &sb, const std::string &prefix) const; }; } // namespace HDI } // namespace OHOS diff --git a/framework/tools/hdi-gen/codegen/cpp_service_driver_code_emitter.cpp b/framework/tools/hdi-gen/codegen/cpp_service_driver_code_emitter.cpp index 34ff3245579555410b5f9ce3553a34a5c0555e80..4331867c8b0176d074eaafdbadffaf1e88c63ccb 100644 --- a/framework/tools/hdi-gen/codegen/cpp_service_driver_code_emitter.cpp +++ b/framework/tools/hdi-gen/codegen/cpp_service_driver_code_emitter.cpp @@ -158,7 +158,8 @@ void CppServiceDriverCodeEmitter::EmitDriverBind(StringBuilder &sb) const sb.Append(TAB).AppendFormat("%s->ioService.Open = NULL;\n", objName.c_str()); sb.Append(TAB).AppendFormat("%s->ioService.Release = NULL;\n\n", objName.c_str()); - sb.Append(TAB).AppendFormat("auto serviceImpl = %s::Get(true);\n", interfaceName_.c_str()); + sb.Append(TAB).AppendFormat( + "auto serviceImpl = %s::Get(true);\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str()); sb.Append(TAB).Append("if (serviceImpl == nullptr) {\n"); sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: failed to get of implement service\", __func__);\n"); sb.Append(TAB).Append(TAB).AppendFormat("delete %s;\n", objName.c_str()); @@ -167,7 +168,8 @@ void CppServiceDriverCodeEmitter::EmitDriverBind(StringBuilder &sb) const sb.Append(TAB).AppendFormat("%s->stub = OHOS::HDI::ObjectCollector::GetInstance().", objName.c_str()); sb.Append("GetOrNewObject(serviceImpl,\n"); - sb.Append(TAB).Append(TAB).AppendFormat("%s::GetDescriptor());\n", interfaceName_.c_str()); + sb.Append(TAB).Append(TAB).AppendFormat( + "%s::GetDescriptor());\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str()); sb.Append(TAB).AppendFormat("if (%s->stub == nullptr) {\n", objName.c_str()); sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: failed to get stub object\", __func__);\n"); sb.Append(TAB).Append(TAB).AppendFormat("delete %s;\n", objName.c_str()); diff --git a/framework/tools/hdi-gen/codegen/cpp_service_impl_code_emitter.cpp b/framework/tools/hdi-gen/codegen/cpp_service_impl_code_emitter.cpp index b7ef69353e37090a460e949db34cc044a0698bb5..67f6fbb18c4d89b765ddaa14a9ac0000b9c88e5c 100644 --- a/framework/tools/hdi-gen/codegen/cpp_service_impl_code_emitter.cpp +++ b/framework/tools/hdi-gen/codegen/cpp_service_impl_code_emitter.cpp @@ -77,7 +77,8 @@ void CppServiceImplCodeEmitter::EmitServiceImplInclusions(StringBuilder &sb) void CppServiceImplCodeEmitter::EmitServiceImplDecl(StringBuilder &sb) { EmitBeginNamespace(sb); - sb.AppendFormat("class %sService : public %s {\n", baseName_.c_str(), interfaceName_.c_str()); + sb.AppendFormat("class %sService : public %s {\n", baseName_.c_str(), + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); sb.Append("public:\n"); EmitServiceImplBody(sb, TAB); sb.Append("};\n"); @@ -100,9 +101,13 @@ void CppServiceImplCodeEmitter::EmitServiceImplConstructor(StringBuilder &sb, co void CppServiceImplCodeEmitter::EmitServiceImplMethodDecls(StringBuilder &sb, const std::string &prefix) const { - for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) { - EmitServiceImplMethodDecl(method, sb, prefix); - sb.Append("\n"); + AutoPtr interface = interface_; + while (interface != nullptr) { + for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) { + EmitServiceImplMethodDecl(method, sb, prefix); + sb.Append("\n"); + } + interface = interface->GetExtendsInterface(); } } @@ -170,9 +175,13 @@ void CppServiceImplCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFi void CppServiceImplCodeEmitter::EmitServiceImplMethodImpls(StringBuilder &sb, const std::string &prefix) const { - for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) { - EmitServiceImplMethodImpl(method, sb, prefix); - sb.Append("\n"); + AutoPtr interface = interface_; + while (interface != nullptr) { + for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) { + EmitServiceImplMethodImpl(method, sb, prefix); + sb.Append("\n"); + } + interface = interface->GetExtendsInterface(); } } diff --git a/framework/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.cpp b/framework/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.cpp index 75a12c3752b10ce8b982c6a8c3cf172d6a2ad2c2..899b2e355e9f7273cb180cc646ebba167765878e 100644 --- a/framework/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.cpp +++ b/framework/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.cpp @@ -68,6 +68,10 @@ void CppServiceStubCodeEmitter::EmitStubHeaderInclusions(StringBuilder &sb) HeaderFile::HeaderFileSet headerFiles; headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_)); + if (interface_->GetExtendsInterface() != nullptr) { + headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, + EmitHeaderNameByInterface(interface_->GetExtendsInterface(), stubName_)); + } GetHeaderOtherLibInclusions(headerFiles); for (const auto &file : headerFiles) { @@ -126,12 +130,26 @@ void CppServiceStubCodeEmitter::EmitStubOnRequestDecl(StringBuilder &sb, const s void CppServiceStubCodeEmitter::EmitStubMethodDecls(StringBuilder &sb, const std::string &prefix) const { - sb.Append("private:\n"); for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) { - EmitStubMethodDecl(method, sb, prefix); + EmitStubStaticMethodDecl(method, sb, prefix); + sb.Append("\n"); + } + if (interface_->GetExtendsInterface() == nullptr) { + EmitStubStaticMethodDecl(interface_->GetVersionMethod(), sb, prefix); sb.Append("\n"); } + + sb.Append("private:\n"); + AutoPtr interface = interface_; + while (interface != nullptr) { + for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) { + EmitStubMethodDecl(method, sb, prefix); + sb.Append("\n"); + } + interface = interface->GetExtendsInterface(); + } EmitStubMethodDecl(interface_->GetVersionMethod(), sb, prefix); + sb.Append("\n"); } void CppServiceStubCodeEmitter::EmitStubMethodDecl( @@ -142,12 +160,21 @@ void CppServiceStubCodeEmitter::EmitStubMethodDecl( optionName_.c_str()); } -void CppServiceStubCodeEmitter::EmitStubPrivateData(StringBuilder &sb, const std::string &prefix) const +void CppServiceStubCodeEmitter::EmitStubStaticMethodDecl( + const AutoPtr &method, StringBuilder &sb, const std::string &prefix) const { - sb.Append("private:\n"); sb.Append(prefix).AppendFormat( - "static inline ObjectDelegator<%s, %s> objDelegator_;\n", stubName_.c_str(), interfaceName_.c_str()); - sb.Append(prefix).AppendFormat("sptr<%s> impl_;\n", interfaceName_.c_str()); + "static int32_t %s%s_(MessageParcel& %s, MessageParcel& %s, MessageOption& %s, sptr<%s> impl);\n", + stubName_.c_str(), method->GetName().c_str(), dataParcelName_.c_str(), replyParcelName_.c_str(), + optionName_.c_str(), EmitDefinitionByInterface(interface_, interfaceName_).c_str()); +} + +void CppServiceStubCodeEmitter::EmitStubPrivateData(StringBuilder &sb, const std::string &prefix) const +{ + sb.Append(prefix).AppendFormat("static inline ObjectDelegator<%s, %s> objDelegator_;\n", + EmitDefinitionByInterface(interface_, stubName_).c_str(), + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); + sb.Append(prefix).AppendFormat("sptr<%s> impl_;\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str()); } void CppServiceStubCodeEmitter::EmitStubSourceFile() @@ -244,45 +271,51 @@ void CppServiceStubCodeEmitter::EmitInterfaceGetMethodImpl(StringBuilder &sb, co void CppServiceStubCodeEmitter::EmitGetMethodImpl(StringBuilder &sb, const std::string &prefix) const { - sb.Append(prefix).AppendFormat( - "sptr<%s> %s::Get(bool isStub)\n", interface_->GetName().c_str(), interface_->GetName().c_str()); + sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(bool isStub)\n", + EmitDefinitionByInterface(interface_, interfaceName_).c_str(), + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); sb.Append(prefix).Append("{\n"); - sb.Append(prefix + TAB) - .AppendFormat("return %s::Get(\"%s\", isStub);\n", interfaceName_.c_str(), FileName(implName_).c_str()); + sb.Append(prefix + TAB).AppendFormat("return %s::Get(\"%s\", isStub);\n", + EmitDefinitionByInterface(interface_, interfaceName_).c_str(), FileName(implName_).c_str()); sb.Append(prefix).Append("}\n"); } void CppServiceStubCodeEmitter::EmitGetInstanceMethodImpl(StringBuilder &sb, const std::string &prefix) const { sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(const std::string& serviceName, bool isStub)\n", - interface_->GetName().c_str(), interface_->GetName().c_str()); + EmitDefinitionByInterface(interface_, interfaceName_).c_str(), + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); sb.Append(prefix).Append("{\n"); sb.Append(prefix + TAB).Append("if (!isStub) {\n"); sb.Append(prefix + TAB + TAB).Append("return nullptr;\n"); sb.Append(prefix + TAB).Append("}\n"); - sb.Append(prefix + TAB) - .AppendFormat("std::string desc = Str16ToStr8(%s::GetDescriptor());\n", interfaceName_.c_str()); + sb.Append(prefix + TAB).AppendFormat("std::string desc = Str16ToStr8(%s::GetDescriptor());\n", + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); sb.Append(prefix + TAB).Append("void *impl = LoadHdiImpl(desc.c_str(), "); sb.AppendFormat("serviceName == \"%s\" ? \"service\" : serviceName.c_str());\n", FileName(implName_).c_str()); sb.Append(prefix + TAB).Append("if (impl == nullptr) {\n"); sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"failed to load hdi impl %{public}s\", desc.c_str());\n"); sb.Append(prefix + TAB + TAB).Append("return nullptr;\n"); sb.Append(prefix + TAB).Append("}\n"); - sb.Append(prefix + TAB).AppendFormat("return reinterpret_cast<%s *>(impl);\n", interfaceName_.c_str()); + sb.Append(prefix + TAB).AppendFormat("return reinterpret_cast<%s *>(impl);\n", + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); sb.Append(prefix).Append("}\n"); } void CppServiceStubCodeEmitter::EmitStubConstructorImpl(StringBuilder &sb, const std::string &prefix) const { - sb.Append(prefix).AppendFormat( - "%s::%s(const sptr<%s> &impl)\n", stubName_.c_str(), stubName_.c_str(), interfaceName_.c_str()); - sb.Append(prefix + TAB).AppendFormat(": IPCObjectStub(%s::GetDescriptor()), impl_(impl)\n", interfaceName_.c_str()); + sb.Append(prefix).AppendFormat("%s::%s(const sptr<%s> &impl)\n", + EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str(), + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); + sb.Append(prefix + TAB).AppendFormat(": IPCObjectStub(%s::GetDescriptor()), impl_(impl)\n", + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); sb.Append(prefix).Append("{\n"); sb.Append(prefix).Append("}\n\n"); - sb.Append(prefix).AppendFormat("%s::~%s()\n", stubName_.c_str(), stubName_.c_str()); + sb.Append(prefix).AppendFormat( + "%s::~%s()\n", EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str()); sb.Append(prefix).Append("{\n"); sb.Append(prefix + TAB).Append("ObjectCollector::GetInstance().RemoveObject(impl_);\n"); sb.Append(prefix).Append("}\n"); @@ -290,21 +323,25 @@ void CppServiceStubCodeEmitter::EmitStubConstructorImpl(StringBuilder &sb, const void CppServiceStubCodeEmitter::EmitStubOnRequestMethodImpl(StringBuilder &sb, const std::string &prefix) { - sb.Append(prefix).AppendFormat("int32_t %s::OnRemoteRequest(uint32_t code, ", stubName_.c_str()); + sb.Append(prefix).AppendFormat( + "int32_t %s::OnRemoteRequest(uint32_t code, ", EmitDefinitionByInterface(interface_, stubName_).c_str()); sb.Append("MessageParcel& data, MessageParcel& reply, MessageOption& option)\n"); sb.Append(prefix).Append("{\n"); sb.Append(prefix + TAB).Append("switch (code) {\n"); - for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) { - sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(method).c_str()); - sb.Append(prefix + TAB + TAB + TAB) - .AppendFormat("return %sStub%s(data, reply, option);\n", baseName_.c_str(), method->GetName().c_str()); - } - AutoPtr getVerMethod = interface_->GetVersionMethod(); sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(getVerMethod).c_str()); sb.Append(prefix + TAB + TAB + TAB) .AppendFormat("return %sStub%s(data, reply, option);\n", baseName_.c_str(), getVerMethod->GetName().c_str()); + AutoPtr interface = interface_; + while (interface != nullptr) { + for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) { + sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(method).c_str()); + sb.Append(prefix + TAB + TAB + TAB) + .AppendFormat("return %sStub%s(data, reply, option);\n", baseName_.c_str(), method->GetName().c_str()); + } + interface = interface->GetExtendsInterface(); + } sb.Append(prefix + TAB + TAB).Append("default: {\n"); sb.Append(prefix + TAB + TAB + TAB) @@ -317,20 +354,53 @@ void CppServiceStubCodeEmitter::EmitStubOnRequestMethodImpl(StringBuilder &sb, c void CppServiceStubCodeEmitter::EmitStubMethodImpls(StringBuilder &sb, const std::string &prefix) const { + AutoPtr interface = interface_; + AutoPtr mataInterface = interface_; + while (interface != nullptr) { + for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) { + EmitStubMethodImpl(interface, method, sb, prefix); + sb.Append("\n"); + } + interface = interface->GetExtendsInterface(); + if (interface != nullptr) { + mataInterface = interface; + } + } + AutoPtr verMethod = interface_->GetVersionMethod(); + EmitStubMethodImpl(mataInterface, verMethod, sb, prefix); for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) { - EmitStubMethodImpl(method, sb, prefix); sb.Append("\n"); + EmitStubStaticMethodImpl(method, sb, prefix); + } + if (interface_->GetExtendsInterface() == nullptr) { + sb.Append("\n"); + EmitStubStaticMethodImpl(verMethod, sb, prefix); } - - EmitStubMethodImpl(interface_->GetVersionMethod(), sb, prefix); } -void CppServiceStubCodeEmitter::EmitStubMethodImpl( +void CppServiceStubCodeEmitter::EmitStubMethodImpl(AutoPtr interface, const AutoPtr &method, StringBuilder &sb, const std::string &prefix) const { sb.Append(prefix).AppendFormat("int32_t %s::%s%s(MessageParcel& %s, MessageParcel& %s, MessageOption& %s)\n", - stubName_.c_str(), stubName_.c_str(), method->GetName().c_str(), dataParcelName_.c_str(), - replyParcelName_.c_str(), optionName_.c_str()); + EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str(), method->GetName().c_str(), + dataParcelName_.c_str(), replyParcelName_.c_str(), optionName_.c_str()); + sb.Append(prefix).Append("{\n"); + sb.Append(prefix + TAB).AppendFormat("return %s::%s%s_(%s, %s, %s, impl_);\n", + EmitDefinitionByInterface(interface, stubName_).c_str(), + stubName_.c_str(), method->GetName().c_str(), + dataParcelName_.c_str(), replyParcelName_.c_str(), + optionName_.c_str()); + sb.Append("}\n"); +} + +void CppServiceStubCodeEmitter::EmitStubStaticMethodImpl( + const AutoPtr &method, StringBuilder &sb, const std::string &prefix) const +{ + sb.Append(prefix).AppendFormat( + "int32_t %s::%s%s_(MessageParcel& %s, MessageParcel& %s, MessageOption& %s, sptr<%s> impl)\n", + EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str(), method->GetName().c_str(), + dataParcelName_.c_str(), replyParcelName_.c_str(), optionName_.c_str(), + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); sb.Append(prefix).Append("{\n"); // read interface token and check it @@ -370,7 +440,7 @@ void CppServiceStubCodeEmitter::EmitStubMethodImpl( void CppServiceStubCodeEmitter::EmitStubCallMethod( const AutoPtr &method, StringBuilder &sb, const std::string &prefix) const { - sb.Append(prefix).AppendFormat("int32_t %s = impl_->%s(", errorCodeName_.c_str(), method->GetName().c_str()); + sb.Append(prefix).AppendFormat("int32_t %s = impl->%s(", errorCodeName_.c_str(), method->GetName().c_str()); for (size_t i = 0; i < method->GetParameterNumber(); i++) { AutoPtr param = method->GetParameter(i); sb.Append(param->GetName()); @@ -390,8 +460,8 @@ void CppServiceStubCodeEmitter::EmitStubCallMethod( void CppServiceStubCodeEmitter::EmitStubReadInterfaceToken( const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const { - sb.Append(prefix).AppendFormat( - "if (%s.ReadInterfaceToken() != %s::GetDescriptor()) {\n", parcelName.c_str(), interfaceName_.c_str()); + sb.Append(prefix).AppendFormat("if (%s.ReadInterfaceToken() != %s::GetDescriptor()) {\n", parcelName.c_str(), + EmitDefinitionByInterface(interface_, interfaceName_).c_str()); sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: interface token check failed!\", __func__);\n"); sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n"); sb.Append(prefix).Append("}\n"); diff --git a/framework/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.h b/framework/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.h index 82e92e90427f371d4af56048a6a6550663a6ac91..aa115865037e4035e63c65dcbb687c3ce4f99e3f 100644 --- a/framework/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.h +++ b/framework/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.h @@ -66,19 +66,24 @@ private: void EmitStubMethodImpls(StringBuilder &sb, const std::string &prefix) const; - void EmitStubMethodImpl(const AutoPtr &method, StringBuilder &sb, const std::string &prefix) const; + void EmitStubMethodImpl(AutoPtr interface, const AutoPtr &method, StringBuilder &sb, + const std::string &prefix) const; + + void EmitStubStaticMethodImpl(const AutoPtr &method, StringBuilder &sb, const std::string &prefix) const; void EmitStubCallMethod(const AutoPtr &method, StringBuilder &sb, const std::string &prefix) const; void EmitStubReadInterfaceToken(const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const; - void EmitStubReadMemFlag(const AutoPtr &method, - const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const; + void EmitStubReadMemFlag(const AutoPtr &method, const std::string &parcelName, StringBuilder &sb, + const std::string &prefix) const; void EmitLocalVariable(const AutoPtr ¶m, const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const; void GetUtilMethods(UtilMethodMap &methods) override; + + void EmitStubStaticMethodDecl(const AutoPtr &method, StringBuilder &sb, const std::string &prefix) const; }; } // namespace HDI } // namespace OHOS diff --git a/framework/tools/hdi-gen/parser/parser.cpp b/framework/tools/hdi-gen/parser/parser.cpp index e5aa71c94af3b604a116c5a4a7d56d647ec97978..0de1d254de23d825df5e139f8e1fc9ccbcaa1718 100644 --- a/framework/tools/hdi-gen/parser/parser.cpp +++ b/framework/tools/hdi-gen/parser/parser.cpp @@ -52,6 +52,10 @@ bool Parser::Parse(const std::vector &fileDetails) } } + if (!PostProcess()) { + return false; + } + return true; } @@ -234,11 +238,6 @@ void Parser::ParseImportInfo() return; } - AutoPtr interfaceType = importAst->GetInterfaceDef(); - if (interfaceType != nullptr) { - interfaceType->SetSerializable(true); - } - if (!ast_->AddImport(importAst)) { LogError(token, StringHelper::Format("multiple import of '%s'", importName.c_str())); return; @@ -408,8 +407,9 @@ void Parser::ParseInterface(const AttrSet &attrs) } CheckInterfaceAttr(interfaceType, token); - + ParseInterfaceExtends(interfaceType); ParseInterfaceBody(interfaceType); + SetInterfaceVersion(interfaceType); ast_->AddInterfaceDef(interfaceType); } @@ -705,6 +705,9 @@ AutoPtr Parser::ParseParam() LogError(token, StringHelper::Format("'%s' parameter of interface type must be 'out' attribute", paramName.c_str())); } + if (!ifaceType->IsCallback()) { + ifaceType->SetSerializable(true); + } } return new ASTParameter(paramName, paramAttr, paramType); @@ -1713,5 +1716,276 @@ void Parser::ShowError() Logger::E(TAG, "%s", errMsg.c_str()); } } + +void Parser::ParseInterfaceExtends(AutoPtr &interface) +{ + Token token = lexer_.PeekToken(); + if (token.kind != TokenType::EXTENDS) { + return; + } + lexer_.GetToken(); + token = lexer_.PeekToken(); + if (token.kind != TokenType::ID) { + LogError( + token, StringHelper::Format("expected extends interface name before '%s' token", token.value.c_str())); + lexer_.SkipToken(TokenType::BRACES_LEFT); + return; + } + ParseExtendsInfo(interface); + lexer_.GetToken(); +} + +void Parser::ParseExtendsInfo(AutoPtr &interfaceType) +{ + Token token = lexer_.PeekToken(); + std::string extendsInterfaceName = token.value; + if (extendsInterfaceName.empty()) { + LogError(token, StringHelper::Format("extends interface name is empty")); + return; + } + if (!CheckImport(extendsInterfaceName)) { + LogError(token, StringHelper::Format("extends interface name is illegal")); + return; + } + auto iter = allAsts_.find(extendsInterfaceName); + AutoPtr extendsAst = (iter != allAsts_.end()) ? iter->second : nullptr; + if (extendsAst == nullptr) { + LogError(token, + StringHelper::Format("can not find idl file by extends interface name '%s', please check import info", + extendsInterfaceName.c_str())); + return; + } + if (!CheckExtendsName(interfaceType, extendsInterfaceName)) { + LogError(token, + StringHelper::Format( + "extends interface name must same as current interface name '%s'", interfaceType->GetName().c_str())); + return; + } + if (!CheckExtendsVersion(interfaceType, extendsInterfaceName, extendsAst)) { + LogError(token, StringHelper::Format("extends interface version must less than current interface version")); + return; + } + if (!interfaceType->AddExtendsInterface(extendsAst->GetInterfaceDef())) { + LogError(token, StringHelper::Format("multiple extends of '%s'", interfaceType->GetName().c_str())); + return; + } +} + +bool Parser::CheckExtendsName(AutoPtr &interfaceType, const std::string &extendsInterfaceName) +{ + size_t index = extendsInterfaceName.rfind("."); + std::string interfaceName = interfaceType->GetName(); + if (extendsInterfaceName.substr(index + 1).compare(interfaceName) != 0) { + return false; + } + return true; +} + +bool Parser::CheckExtendsVersion( + AutoPtr &interfaceType, const std::string &extendsName, AutoPtr extendsAst) +{ + if (extendsAst->GetMajorVer() != ast_->GetMajorVer() || extendsAst->GetMinorVer() >= ast_->GetMinorVer()) { + return false; + } + return true; +} + +void Parser::SetInterfaceVersion(AutoPtr &interfaceType) +{ + size_t majorVer = ast_->GetMajorVer(); + size_t minorVer = ast_->GetMinorVer(); + interfaceType->SetVersion(majorVer, minorVer); +} + +bool Parser::PostProcess() +{ + Language language = Options::GetInstance().GetLanguage(); + if (language != Language::C) { + return true; + } + if (!CheckExistExtends()) { + return true; + } + std::vector genVersion = {0, 0}; + std::string genPackageName; + AutoPtr ns; + if (!GetGenVersion(genVersion, genPackageName)) { + return false; + } + GetGenNamespace(ns); + AstMergeMap mergeMap; + SortAstByName(mergeMap, allAsts_); + allAsts_.clear(); + MergeAsts(mergeMap); + ModifyImport(allAsts_, genPackageName); + ModifyPackageNameAndVersion(allAsts_, genPackageName, genVersion); + ModifyInterfaceNamespace(ns); + + return true; +} + +bool Parser::CheckExistExtends() +{ + for (const auto &astPair : allAsts_) { + if (astPair.second->GetInterfaceDef() != nullptr && + astPair.second->GetInterfaceDef()->GetExtendsInterface() != nullptr) { + return true; + } + } + return false; +} + +bool Parser::GetGenVersion(std::vector &version, std::string &genPackageName) +{ + std::set sourceFile = Options::GetInstance().GetSourceFiles(); + for (const auto &ast : allAsts_) { + if (sourceFile.find(ast.second->GetIdlFilePath()) != sourceFile.end()) { + if (genPackageName == "") { + genPackageName = ast.second->GetPackageName(); + version[0] = ast.second->GetMajorVer(); + version[1] = ast.second->GetMinorVer(); + continue; + } + if (genPackageName != ast.second->GetPackageName() || version[0] != ast.second->GetMajorVer() || + version[1] != ast.second->GetMinorVer()) { + LogError(StringHelper::Format("merge ast failed, source files must have same package and version")); + return false; + } + } + } + return true; +} + +void Parser::GetGenNamespace(AutoPtr &ns) +{ + std::set sourceFile = Options::GetInstance().GetSourceFiles(); + for (const auto &ast : allAsts_) { + if (sourceFile.find(ast.second->GetIdlFilePath()) != sourceFile.end()) { + if (ast.second->GetInterfaceDef() != nullptr) { + ns = ast.second->GetInterfaceDef()->GetNamespace(); + return; + } + } + } +} + +void Parser::SortAstByName(AstMergeMap &mergeMap, StrAstMap &allAsts) +{ + for (const auto &astPair : allAsts) { + AutoPtr ast = astPair.second; + mergeMap[ast->GetName()].emplace(ast); + } +} + +void Parser::MergeAsts(AstMergeMap &mergeMap) +{ + for (const auto &setPair : mergeMap) { + std::string name = setPair.first; + auto astSet = setPair.second; + AutoPtr targetAst = nullptr; + for (const auto &ast : astSet) { + MergeAst(targetAst, ast); + } + AddAst(targetAst); + } +} + +void Parser::MergeAst(AutoPtr &targetAst, AutoPtr sourceAst) +{ + if (targetAst == nullptr) { + targetAst = sourceAst; + return; + } + MergeImport(targetAst, sourceAst); + MergeInterfaceDef(targetAst, sourceAst); + MergeTypeDefinitions(targetAst, sourceAst); + MergeTypes(targetAst, sourceAst); + MergeSequenceableDef(targetAst, sourceAst); +} + +void Parser::MergeImport(AutoPtr &targetAst, AutoPtr sourceAst) +{ + for (const auto &importPair : sourceAst->GetImports()) { + AutoPtr importAst = importPair.second; + targetAst->AddImport(importAst); + } +} + +void Parser::MergeInterfaceDef(AutoPtr &targetAst, AutoPtr sourceAst) +{ + AutoPtr sourceInterface = sourceAst->GetInterfaceDef(); + if (sourceInterface == nullptr) { + return; + } + AutoPtr targetInterface = targetAst->GetInterfaceDef(); + if (targetInterface == nullptr) { + targetInterface = sourceInterface; + return; + } + + for (size_t i = 0; i < sourceInterface->GetMethodNumber(); i++) { + targetInterface->AddMethod(sourceInterface->GetMethod(i)); + } + targetInterface->SetSerializable(sourceInterface->IsSerializable()); +} + +void Parser::MergeTypeDefinitions(AutoPtr &targetAst, AutoPtr sourceAst) +{ + for (size_t i = 0; i < sourceAst->GetTypeDefinitionNumber(); i++) { + targetAst->AddTypeDefinition(sourceAst->GetTypeDefintion(i)); + } +} + +void Parser::MergeSequenceableDef(AutoPtr &targetAst, AutoPtr sourceAst) +{ + if (sourceAst->GetSequenceableDef() != nullptr) { + targetAst->AddSequenceableDef(sourceAst->GetSequenceableDef()); + } +} + +void Parser::MergeTypes(AutoPtr &targetAst, AutoPtr sourceAst) +{ + for (const auto &typePair : sourceAst->GetTypes()) { + targetAst->AddType(typePair.second); + } +} + +void Parser::ModifyImport(StrAstMap &allAsts, std::string &genPackageName) +{ + for (const auto &astPair : allAsts) { + StrAstMap modifiedImport; + StrAstMap import = astPair.second->GetImports(); + for (const auto &importPair : import) { + if (importPair.second->GetName() == astPair.second->GetName()) { + continue; + } + modifiedImport[importPair.second->GetName()] = importPair.second; + } + astPair.second->ClearImport(); + for (const auto &importPair : modifiedImport) { + importPair.second->SetPackageName(genPackageName); + astPair.second->AddImport(importPair.second); + } + } +} + +void Parser::ModifyPackageNameAndVersion( + StrAstMap &allAsts, std::string &genPackageName, std::vector genVersion) +{ + for (const auto &astPair : allAsts) { + astPair.second->SetPackageName(genPackageName); + astPair.second->SetVersion(genVersion[0], genVersion[1]); + } +} + +void Parser::ModifyInterfaceNamespace(AutoPtr &ns) +{ + for (const auto &astPair : allAsts_) { + AutoPtr interface = astPair.second->GetInterfaceDef(); + if (interface != nullptr) { + interface->SetNamespace(ns); + } + } +} } // namespace HDI } // namespace OHOS \ No newline at end of file diff --git a/framework/tools/hdi-gen/parser/parser.h b/framework/tools/hdi-gen/parser/parser.h index 6aeea61c2d8b0fe25fa63f65ef818fe292c42baa..0e006389afaa8a5b160521ccabdf6aeeabaa384e 100644 --- a/framework/tools/hdi-gen/parser/parser.h +++ b/framework/tools/hdi-gen/parser/parser.h @@ -27,7 +27,13 @@ namespace OHOS { namespace HDI { using AttrSet = std::set; - +struct AstCompare { + bool operator()(const AutoPtr &lhs, const AutoPtr &rhs) const + { + return lhs->GetMinorVer() > rhs->GetMinorVer(); + } +}; +using AstMergeMap = std::map, AstCompare>>; class Parser { public: Parser() = default; @@ -177,6 +183,17 @@ private: bool CheckImport(const std::string &importName); + void ParseInterfaceExtends(AutoPtr &interface); + + void ParseExtendsInfo(AutoPtr &interfaceType); + + bool CheckExtendsName(AutoPtr &interfaceType, const std::string &extendsName); + + bool CheckExtendsVersion( + AutoPtr &interfaceType, const std::string &extendsName, AutoPtr extendsAst); + + void SetInterfaceVersion(AutoPtr &interfaceType); + inline static bool IsPrimitiveType(Token token) { return token.kind >= TokenType::BOOLEAN && token.kind <= TokenType::ASHMEM; @@ -190,6 +207,36 @@ private: void ShowError(); + bool PostProcess(); + + bool CheckExistExtends(); + + bool GetGenVersion(std::vector &version, std::string &genPackageName); + + void GetGenNamespace(AutoPtr &ns); + + void SortAstByName(AstMergeMap &mergeMap, StrAstMap &allAsts); + + void MergeAsts(AstMergeMap &mergeMap); + + void MergeAst(AutoPtr &targetAst, AutoPtr sourceAst); + + void MergeImport(AutoPtr &targetAst, AutoPtr sourceAst); + + void MergeInterfaceDef(AutoPtr &targetAst, AutoPtr sourceAst); + + void MergeTypes(AutoPtr &targetAst, AutoPtr sourceAst); + + void MergeSequenceableDef(AutoPtr &targetAst, AutoPtr sourceAst); + + void MergeTypeDefinitions(AutoPtr &targetAst, AutoPtr sourceAst); + + void ModifyImport(StrAstMap &allAsts, std::string &genPackageName); + + void ModifyPackageNameAndVersion(StrAstMap &allAsts, std::string &genPackageName, std::vector genVersion); + + void ModifyInterfaceNamespace(AutoPtr &ns); + Lexer lexer_; std::vector errors_; AutoPtr ast_;