protected string GetCountTarget(Task taskElement) { if (taskElement.LoopCollection != null) { if (processConverter.Contract.TryGetProperty(taskElement.LoopCollection, out var property, out var entity)) { if (!entity.IsRootEntity) { return(null); //TODO Exception } if (property.PropertyType == PropertyType.Collection) { return($"{property.Name.ToLowerCamelCase()}.length"); } if (property.PropertyType == PropertyType.Dictionary) { return($"{ConversionTemplates.MappingKeysArrayName(property.Name.ToLowerCamelCase())}.length"); } } } else if (taskElement.LoopCardinality != "0") { return(taskElement.LoopCardinality.ToString()); } return(null); //TODO exception }
public override void ConvertElementLogic() { processReturnFunction = CreateProcessReturnFunction(); mainFunction = new SolidityFunction(GetElementCallName(), SolidityVisibility.Internal); mainFunction.AddParameters(processConverter.GetIdentifiersAsParameters()); var calledStartEventConverter = processConverter.ContractConverter.GetStartEventConverter(callActivity); var callSubprocessStatement = calledStartEventConverter.GetStatementForPrevious(callActivity); stateTracker = new SolidityStatement($"uint256 {ConversionTemplates.CallActivityCounter(GetElementCallName())}"); switch (callActivity.InstanceType) { case InstanceType.Single: //Call the subprocess. mainFunction.AddToBody(callSubprocessStatement); break; case InstanceType.Sequential: //Call the subprocess and create a counter. mainFunction.AddToBody(new SolidityStatement($"{ConversionTemplates.CallActivityCounter(GetElementCallName())} = 0")); mainFunction.AddToBody(callSubprocessStatement); break; case InstanceType.Parallel: //Call all of the subprocesses using an identifier, create a counter. mainFunction.AddToBody(new SolidityStatement($"{ConversionTemplates.CallActivityCounter(GetElementCallName())} = 0")); var solidityForLoop = new SolidityFor(GetLoopVariable(), GetCountTarget(callActivity)); solidityForLoop.AddToBody(callSubprocessStatement); mainFunction.AddToBody(solidityForLoop); break; } }
SolidityFunction CreateElementMainFunction() { SolidityFunction function = new SolidityFunction(GetElementCallName(), SolidityVisibility.Public); function.AddModifier($"{ConversionTemplates.StateGuardModifierName(GetElementCallName())}({processConverter.GetIdentifierNames()})"); function.AddParameters(processConverter.GetIdentifiersAsParameters()); /* * if (IsAddressGuardRequired()) * function.AddModifier($"{ConversionTemplates.AddressGuardModifierName(GetElementCallName())}({processConverter.GetIdentifierNames()})"); */ boundaryEventCalls.ForEach(c => function.AddToBody(c)); function.AddToBody(new SolidityStatement(userTaskElement.ValidationScript, false)); if (userTaskElement.Form.Fields != null) { foreach (var field in userTaskElement.Form.Fields) { //TODO: throw exception if no property has been found var propertyAndEntity = processConverter.GetPropertyAndEntity(field.PropertyExpression); var property = propertyAndEntity.Item1; var entity = propertyAndEntity.Item2; var formPropertyDisplayName = Helpers.ToLowerCamelCase(field.DisplayName); function.AddParameter(new SolidityParameter(Helpers.PropertyTypeToString(property, processConverter.ContractConverter), formPropertyDisplayName)); } } function.AddToBody(CreateCallNextBody()); return(function); }
SolidityModifier CreateAddressGuard() { //Initialize the modifier using the generated name SolidityModifier addressGuard = new SolidityModifier(ConversionTemplates.AddressGuardModifierName(GetElementCallName())); addressGuard.AddParameters(processConverter.GetIdentifiersAsParameters()); //Address is force assigned if (userTaskElement.Assignee.Address != null) { SolidityStatement requireStatement = new SolidityStatement($"require(msg.sender=={GetAssigneeAddress()})"); addressGuard.AddToBody(requireStatement); } //Address is not force assigned, it will be assigned to the first caller of the first task method containing this assignee else if (userTaskElement.Assignee.Name != null) { var addressPosition = $"{ConverterConfig.ADDRESS_MAPPING_VAR_NAME}[\"{userTaskElement.Assignee.Name}\"]"; var ifElseBlock = new SolidityIfElse(); //Assigns the address, if address has not been been yet assigned to the assignee ifElseBlock.AddConditionBlock($"{addressPosition} == address(0x0)", new SolidityStatement($"{addressPosition} = msg.sender")); //Checks whether the sender has the required address SolidityStatement requireStatement = new SolidityStatement($"require(msg.sender=={addressPosition})"); addressGuard.AddToBody(ifElseBlock); addressGuard.AddToBody(requireStatement); } return(addressGuard); }
SolidityFunction CreateElementMainFunction() { SolidityFunction function = new SolidityFunction(GetElementCallName(), SolidityVisibility.Public); function.AddModifier($"{ConversionTemplates.StateGuardModifierName(GetElementCallName())}({processConverter.GetIdentifierNames()})"); function.AddParameters(processConverter.GetIdentifiersAsParameters()); /* * if (IsAddressGuardRequired()) * function.AddModifier($"{ConversionTemplates.AddressGuardModifierName(GetElementCallName())}({processConverter.GetIdentifierNames()})"); */ boundaryEventCalls.ForEach(c => function.AddToBody(c)); function.AddToBody(new SolidityStatement(userTaskElement.ValidationScript, false)); foreach (var fieldGroup in userTaskElement.Form.FieldGroups) { foreach (var field in fieldGroup.Fields) { //var property = processConverter.GetProperty(field.ParamBind); var formPropertyDisplayName = Helpers.ToLowerCamelCase(field.Label); function.AddParameter(new SolidityParameter(Helpers.FormFieldToDataType(field), formPropertyDisplayName)); } } function.AddToBody(CreateCallNextBody()); return(function); }
string GetLoopVariable() { if (callActivity.LoopCollection != null || callActivity.LoopCardinality != "0") { return(ConversionTemplates.IdentifierVariableName(callActivity.Id)); } return(null); //TODO exception }
SolidityStatement CreateMultiInstanceCounterDefinition() { if (userTaskElement.LoopCardinality != 0 || userTaskElement.LoopCollection != null) { var variableName = ConversionTemplates.MultiInstanceCounterVariable(GetElementCallName()); return(new SolidityStatement($"uint256 {variableName}")); } return(null); }
public override SolidityStatement GetStatementForPrevious(ProcessElement previous) { var statement = new SolidityStatement(); if (counterVariablePresent) { statement.Add(new SolidityStatement($"{ConversionTemplates.MultiInstanceCounterVariable(GetElementCallName())} = 0")); } statement.Add(GetChangeActiveStateStatement(true)); return(statement); }
public override SolidityStatement GetStatementForPrevious(ProcessElement previous) { var statement = new SolidityStatement(); statement.Add(GetChangeActiveStateStatement(true)); //Call the return function of the parent call element, if it exists if (processConverter.ParentProcessConverter != null) { var callActivityReturnName = ConversionTemplates.CallActivityReturnFunctionName(processConverter.GetParentCallActivityCallName()); statement.Add($"{callActivityReturnName}({processConverter.ParentProcessConverter.GetIdentifierNames()})"); } return(statement); }
SolidityFunction CreateTouchFunction(TaskConverter attachedToConverter) { var function = new SolidityFunction($"touch{GetElementCallName()}", SolidityVisibility.Public, "bool"); function.AddParameters(processConverter.GetIdentifiersAsParameters()); function.AddModifier($"{ConversionTemplates.StateGuardModifierName(attachedToConverter.GetElementCallName())}({processConverter.GetIdentifierNames()})"); var solidityCondition = new SolidityIfElse(); solidityCondition.AddConditionBlock($"now > {GetTimerCondition()}", CreateTouchFunctionLogic(attachedToConverter)); function.AddToBody(solidityCondition); function.AddToBody(new SolidityStatement("return true")); return(function); }
SolidityModifier CreateStateGuard() { SolidityModifier stateGuard = new SolidityModifier(ConversionTemplates.StateGuardModifierName(GetElementCallName())); stateGuard.AddParameters(processConverter.GetIdentifiersAsParameters()); var activeStateFunctionName = ConversionTemplates.ActiveStatesFunctionName(processConverter.Id); var callParameters = processConverter.GetIdentifierNames(); if (callParameters.Length > 0) { callParameters += ","; } callParameters += $"\"{GetElementCallName()}\""; SolidityStatement requireStatement = new SolidityStatement($"require({activeStateFunctionName}({callParameters}) == true)"); stateGuard.AddToBody(requireStatement); return(stateGuard); }
SolidityFunction CreateProcessReturnFunction() { var function = new SolidityFunction(ConversionTemplates.CallActivityReturnFunctionName(GetElementCallName()), SolidityVisibility.Internal); function.AddParameters(processConverter.GetIdentifiersAsParameters()); var nextElementStatement = CreateNextElementStatement(); var incrementStatement = new SolidityStatement($"{ConversionTemplates.CallActivityCounter(GetElementCallName())}++"); var checkConditionBlock = new SolidityIfElse(); var calledStartEventConverter = processConverter.ContractConverter.GetStartEventConverter(callActivity); var callSubprocessStatement = calledStartEventConverter.GetStatementForPrevious(callActivity); checkConditionBlock.AddConditionBlock($"{ConversionTemplates.CallActivityCounter(GetElementCallName())} >= {GetCountTarget(callActivity)}", nextElementStatement); switch (callActivity.InstanceType) { case InstanceType.Single: function.AddToBody(nextElementStatement); break; case InstanceType.Sequential: //increment the counter, check if counter reached limit. //If counter reached limit, then call the next element. If not, call the subprocess again. function.AddToBody(incrementStatement); checkConditionBlock.AddConditionBlock("", callSubprocessStatement); function.AddToBody(checkConditionBlock); break; case InstanceType.Parallel: //increment the counter, check if counter reached limit. //If counter reached limit, then call the next element. If not, do nothing. function.AddToBody(incrementStatement); function.AddToBody(checkConditionBlock); break; } return(function); }
List <SolidityComponent> CreateCallNextBody() { var components = new List <SolidityComponent>(); var callNextStatement = GetChangeActiveStateStatement(false); callNextStatement.Add(processConverter.GetStatementOfNextElement(userTaskElement)); if (userTaskElement.InstanceType != InstanceType.Single) { //The tasks will run until it gets interrupted by some boundary event if (userTaskElement.LoopCardinality == -1 || (userTaskElement.LoopCardinality == 0 && userTaskElement.LoopCollection == null)) { return(components); } var ifStatement = new SolidityIfElse(); var counterVariableName = ConversionTemplates.MultiInstanceCounterVariable(GetElementCallName()); components.Add(new SolidityStatement($"{counterVariableName}++")); counterVariablePresent = true; if (userTaskElement.LoopCardinality > 0) { ifStatement.AddConditionBlock($"{counterVariableName} >= {userTaskElement.LoopCardinality}", callNextStatement); } else if (userTaskElement.LoopCollection != null) { ifStatement.AddConditionBlock($"{counterVariableName} >= {GetCountTarget(userTaskElement)}", callNextStatement); } components.Add(ifStatement); } else { components.Add(callNextStatement); } return(components); }