void RemoteObjectGenerator::methodStart(const Poco::CppParser::Function* pFuncOld, const CodeGenerator::Properties& properties) { if (_functions.find(pFuncOld->name()) != _functions.end()) return; _functions.insert(pFuncOld->name()); Poco::CppParser::Function* pFunc = methodClone(pFuncOld, properties); pFunc->makeInline(); // impl is just one single line Poco::CodeGeneration::CodeGenerator::Properties::const_iterator itSync = properties.find(Poco::CodeGeneration::Utility::SYNCHRONIZED); if (itSync != properties.end() && (itSync->second == Utility::VAL_TRUE || itSync->second.empty() || itSync->second == "all" || itSync->second == "remote")) { _codeInjectors.insert(std::make_pair(pFunc->name(), &RemoteObjectGenerator::syncFwdCodeGen)); } else { _codeInjectors.insert(std::make_pair(pFunc->name(), &RemoteObjectGenerator::fwdCodeGen)); } }
Poco::CppParser::Struct* XSDGenerator::convertToStruct(const Poco::CppParser::Function* pFunc, bool isResponse) { /// a type created by function parameters can never extend any other type std::string inputDataType; if (isResponse) inputDataType = GenUtility::getReplyMethodName(pFunc); else inputDataType = GenUtility::getRequestMethodName(pFunc); std::string decl(Poco::CodeGeneration::Utility::CLASS); decl.append(" "); decl.append(inputDataType); Poco::CppParser::Struct* pStruct = new Poco::CppParser::Struct(decl, true, &_ns); // now add for each param a set and get method, // also add a variable for each param (set the docu!!!!) // don't forget the return value! // return parameter std::string rdecl = pFunc->getReturnParameter(); if (!rdecl.empty() && rdecl != "void" && isResponse) { // if we have an inline type we must fetch the struct for that type // and add all children of that type as direct members of pStruct // or simply inherit from it :-) bool isInline = GenUtility::getInlineReturnParam(pFunc); if (isInline) { std::string fullResType = GenUtility::getResolvedReturnParameterType(pFunc->nameSpace(), pFunc); std::string resType(fullResType); //restype can either be a native type or a complex type which we serialize, or it can be hidden inside a template like vector, set,... SharedPtr bool isPtrType = GenUtility::isPtrType(resType); if (isPtrType) { std::vector<std::string> inn = GenUtility::getInnerTemplateTypes(resType); poco_assert (inn.size() == 1); resType = inn[0]; } bool isVectorOrNullable = GenUtility::isVectorType(resType) || GenUtility::isNullableType(resType) || GenUtility::isOptionalType(resType); if (isVectorOrNullable) { throw Poco::LogicException(pFunc->fullName() + ": For an inlined data type maxOccurs must be 1! No vector/set/multiset allowed"); } if (AbstractGenerator::BUILTIN_TYPES.find(resType) != AbstractGenerator::BUILTIN_TYPES.end()) { throw Poco::LogicException(pFunc->fullName() + ": Only complex data types can be inlined!"); } // now get the class definition for that file Poco::CppParser::Symbol* pSym = pFunc->nameSpace()->lookup(resType); if (pSym && pSym->kind() == Poco::CppParser::Symbol::SYM_STRUCT) { Poco::CppParser::Struct* pRetStruct = static_cast<Poco::CppParser::Struct*>(pSym); // deep copy members pRetStruct deepCopyMembers(pRetStruct, pStruct); } else throw Poco::LogicException("Failed to find data type for inlined return value in method: " + pFunc->fullName()); } else { std::string retParamName (GenUtility::getReturnParameterName(pFunc)); rdecl.append(" " + retParamName); Poco::CppParser::Parameter p(rdecl, 0); Poco::CppParser::Variable* pVar = createVariable(&p, pStruct); Poco::CppParser::Attributes attr; attr["order"] = "0"; pVar->setAttributes(attr); //pVar->setDocumentation("///[[order=0]]"); createGetFct(&p, pStruct); createSetFct(&p, pStruct); } } Poco::CppParser::Function::Iterator it = pFunc->begin(); Poco::CppParser::Function::Iterator itEnd = pFunc->end(); Poco::UInt32 unknownOrderOffset = 0xffff0000; CodeGenerator::Properties funcProps; GeneratorEngine::parseProperties(pFunc, funcProps); for (; it != itEnd; ++it) { std::string direction; CodeGenerator::Properties::iterator itProp = funcProps.find("$" + (*it)->name()); if (itProp != funcProps.end()) { CodeGenerator::Properties paramProps; // we need direction GeneratorEngine::parseElementProperties(itProp->second, paramProps); GeneratorEngine::getStringProperty(paramProps, Utility::DIRECTION, direction); } //isOutParam excludes soapheader already, do the same for replies bool inSoapHeader = GenUtility::getIsInHeader(pFunc, *it); if ( (isResponse && isOutParameter(*it) && direction != "in") || (!isResponse && !inSoapHeader && direction != "out")) { Poco::CppParser::Variable* pVar = createVariable(*it, pStruct); addVarDocu(pVar, pFunc, (*it)->name(), unknownOrderOffset++); createGetFct(*it, pStruct); createSetFct(*it, pStruct); } else if (inSoapHeader) { // Note: we must export for each soapHeader an element that has the same name as the parameter! Poco::CppParser::Parameter* pParam = *it; const std::string& declType = pParam->declType(); std::string name = GenUtility::getParameterName(pFunc, pParam); std::string aType = Poco::CodeGeneration::Utility::resolveType(pFunc->nameSpace(), declType); if (aType == declType) { _exportSoapHeaderTypes.insert (std::make_pair(name, aType)); } else { Poco::CppParser::Symbol* pSym = pFunc->nameSpace()->lookup(aType); poco_assert (pSym); _exportSoapHeaderTypes.insert (std::make_pair(name, pSym->name())); } } } return pStruct; }