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));
	}
}
Ejemplo n.º 2
0
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;
}