private string GetPriorityComparisonBody() { var priorityComparison = new SolidityIfElse(); string ifCondition = string.Empty; //Make function of cycles comparing priorities foreach (var outputVarable in Decision.DecisionTable.Outputs.Select((value, i) => new { i, value })) { ifCondition += $"priorities[i].{outputVarable.value.Name} == currentOutput.{outputVarable.value.Name}"; if (outputVarable.i + 1 < Decision.DecisionTable.Outputs.Count) { ifCondition += " && "; } } priorityComparison.AddConditionBlock(ifCondition, new SolidityStatement("return currentOutput", true)); string elseCondition = string.Empty; foreach (var outputVarable in Decision.DecisionTable.Outputs.Select((value, i) => new { i, value })) { elseCondition += $"priorities[i].{outputVarable.value.Name} == newOutput.{outputVarable.value.Name}"; if (outputVarable.i + 1 < Decision.DecisionTable.Outputs.Count) { elseCondition += " && "; } } priorityComparison.AddConditionBlock(elseCondition, new SolidityStatement("return newOutput", true)); return(priorityComparison.ToString()); }
//Returns output for section representing situation if there is the match or not private string GetMatchOrNotBody(int ruleIndex) { //Assign maximum/minimum if this is the first met condition var noMatchCheck = new SolidityIfElse(); string noMatchCheckBody = string.Empty; foreach (var outputEntry in Decision.DecisionTable.Rules[ruleIndex].OutputEntries.Select((value, i) => new { i, value })) { var dataType = Decision.DecisionTable.Outputs[outputEntry.i].TypeRef; var convertedValue = ConvertToSolidityValue(outputEntry.value.Text, dataType); noMatchCheckBody += $"output.{Decision.DecisionTable.Outputs[outputEntry.i].Name.Replace(".", "__")} = {convertedValue};"; if (outputEntry.i + 1 < Decision.DecisionTable.Rules[ruleIndex].OutputEntries.Count()) { noMatchCheckBody += "\n"; } } noMatchCheck.AddConditionBlock("!matchedRule", new SolidityStatement(noMatchCheckBody, false)); //Assign maximum/minimum if the values are greater/lesser string matchCheckBody = string.Empty; foreach (var outputEntry in Decision.DecisionTable.Rules[ruleIndex].OutputEntries.Select((value, i) => new { i, value })) { var outputsCheck = new SolidityIfElse(); var dataType = Decision.DecisionTable.Outputs[outputEntry.i].TypeRef; var convertedValue = ConvertToSolidityValue(outputEntry.value.Text, dataType); string outputsCheckCondition = $"output.{Decision.DecisionTable.Outputs[outputEntry.i].Name} {Sign} {convertedValue}"; string outputsCheckBody = $"output.{Decision.DecisionTable.Outputs[outputEntry.i].Name.Replace(".", "__")} = {convertedValue};"; outputsCheck.AddConditionBlock(outputsCheckCondition, new SolidityStatement(outputsCheckBody, false)); matchCheckBody += outputsCheck.ToString(); } noMatchCheck.AddConditionBlock(string.Empty, new SolidityStatement(matchCheckBody, false)); return(noMatchCheck.ToString()); }
private SolidityIfElse GetConditionCheck(int ruleIndex) { var conditionCheck = new SolidityIfElse(); //Assign output if there is already the match string matchBody = GetMatchBody(ruleIndex); conditionCheck.AddConditionBlock("!matchedRule", new SolidityStatement(matchBody, false)); //Assign output if there is no match yet conditionCheck.AddConditionBlock("", new SolidityStatement("revert('Undefined output')", true)); return(conditionCheck); }
//Returns output for section representing situation if there is the match or not private string GetPriorityCheckBody(int ruleIndex) { var priorityCheck = new SolidityIfElse(); //Assign output if there is already match string matchBody = GetMatchBody(ruleIndex); priorityCheck.AddConditionBlock("!matchedRule", new SolidityStatement(matchBody, false)); //Assign output if there is no match yet string noMatchBody = GetNoMatchBody(ruleIndex); priorityCheck.AddConditionBlock("", new SolidityStatement(noMatchBody, true)); return(priorityCheck.ToString()); }
public override SolidityFunction CreateDecisionFunction() { //Define function's header FunctionName = Regex.Replace(Decision.Id, @" ", "").ToLowerCamelCase(); SolidityFunction function = new SolidityFunction(FunctionName, SolidityVisibility.Internal, $"{OutputStructName} memory", true); //Add declaration of helper varaibles function.AddToBody(new SolidityStatement($"{OutputStructName} memory output", true)); function.AddToBody(new SolidityStatement($"bool matchedRule = false", true)); //For each row representing rule create condition for if statement var rules = GetAllConditions(); foreach (var rule in rules.Select((value, i) => new { i, value })) { //Add to sum if the conditions are met string conditionBody = string.Empty; foreach (var outputEntry in Decision.DecisionTable.Rules[rule.i].OutputEntries.Select((value, i) => new { i, value })) { conditionBody += $"output.{Decision.DecisionTable.Outputs[outputEntry.i].Name.Replace(".", "__")} += {outputEntry.value.Text};\n"; } conditionBody += "matchedRule = true;"; //If the row is empty then do not put the logic into conditional statement function.AddToBody(AddBodyBasedOnRule(rule.value, conditionBody)); } //Add the rest of the function var undefinedOutputCheck = new SolidityIfElse(); undefinedOutputCheck.AddConditionBlock("!matchedRule", new SolidityStatement("revert('Undefined output')", true)); function.AddToBody(undefinedOutputCheck); function.AddToBody(new SolidityStatement("return output", true)); 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); }
public override SolidityFunction CreateDecisionFunction() { FunctionName = Regex.Replace(Decision.Id, @" ", "").ToLowerCamelCase(); SolidityFunction function = new SolidityFunction(FunctionName, SolidityVisibility.Internal, $"{OutputStructName} memory", true); //Add declaration of helper varaibles var prioritiesFormatted = GetPriorities(Decision); var noUniqueOutputs = Regex.Matches(prioritiesFormatted, $"{OutputStructName}").Count; function.AddToBody(new SolidityStatement($"{OutputStructName}[{noUniqueOutputs}] memory priorities = {prioritiesFormatted}", true)); function.AddToBody(new SolidityStatement($"{OutputStructName} memory output", true)); function.AddToBody(new SolidityStatement($"bool matchedRule = false", true)); var rules = GetAllConditions(); foreach (var rule in rules.Skip(PriorityOffset).Select((value, i) => new { i, value })) { string priorityCheck = GetPriorityCheckBody(rule.i + PriorityOffset); function.AddToBody(AddBodyBasedOnRule(rule.value, priorityCheck)); } //Add the rest of the function var undefinedOutputCheck = new SolidityIfElse(); undefinedOutputCheck.AddConditionBlock("!matchedRule", new SolidityStatement("revert('Undefined output')", true)); function.AddToBody(undefinedOutputCheck); function.AddToBody(new SolidityStatement("return output", true)); return(function); }
SolidityFunction CreateMainFunction() { var logicFunction = new SolidityFunction($"{GetElementCallName()}", SolidityVisibility.Internal); var body = CreateCallsToOutgoing(); logicFunction.AddParameters(processConverter.GetIdentifiersAsParameters()); if (gatewayElement.Incoming.Count == 1) { logicFunction.AddToBody(body); } else { //Increment the incoming variable logicFunction.AddToBody(new SolidityStatement($"{incrementVariableName} += 1")); var ifElseBlock = new SolidityIfElse(); string ifElseCondition = $"{incrementVariableName}=={gatewayElement.Incoming.Count}"; //reset the incoming flow count body.Add(incrementVariableName + " = 0"); ifElseBlock.AddConditionBlock(ifElseCondition, body); logicFunction.AddToBody(ifElseBlock); } return(logicFunction); }
public override IList <SolidityComponent> GetElementCode(List <ElementConverter> nextElements, IList <SequenceFlow> outgoingSeqFlows, IList <SolidityStruct> dataModel = null) { var logicFunction = new SolidityFunction(gateway.Id + "Logic", SolidityVisibility.Internal); var body = CreateParallelism(nextElements); if (gateway.Incoming.Count == 1) { logicFunction.AddToBody(body); return(new List <SolidityComponent> { logicFunction }); } else { var incomingFlowsVar = new SolidityStatement("int " + incVaribaleName + " = 0"); var ifElseBlock = new SolidityIfElse(); string ifElseCondition = incVaribaleName + "==" + gateway.Incoming.Count.ToString(); body.Add(incVaribaleName + " = 0"); ifElseBlock.AddConditionBlock(ifElseCondition, body); logicFunction.AddToBody(ifElseBlock); return(new List <SolidityComponent> { incomingFlowsVar, logicFunction }); } }
public override SolidityFunction CreateDecisionFunction() { //Define function's header FunctionName = Regex.Replace(Decision.Id, @" ", "").ToLowerCamelCase(); SolidityFunction function = new SolidityFunction(FunctionName, SolidityVisibility.Internal, $"{OutputStructName} memory", true); //Add declaration of helper varaibles function.AddToBody(new SolidityStatement($"{OutputStructName} memory output", true)); function.AddToBody(new SolidityStatement($"bool matchedRule = false", true)); //For each row representing rule create condition for if statement var rules = GetAllConditions(); foreach (var rule in rules.Select((value, i) => new { i, value })) { var noMatchCheck = GetMatchOrNotBody(rule.i); string conditionBody = noMatchCheck; conditionBody += "matchedRule = true;"; function.AddToBody(AddBodyBasedOnRule(rule.value, conditionBody)); } //Add the rest of the function var undefinedOutputCheck = new SolidityIfElse(); undefinedOutputCheck.AddConditionBlock("!matchedRule", new SolidityStatement("revert('Undefined output')", true)); function.AddToBody(undefinedOutputCheck); function.AddToBody(new SolidityStatement("return output", true)); return(function); }
public override SolidityFunction CreateDecisionFunction() { FunctionName = Regex.Replace(Decision.Id, @" ", "").ToLowerCamelCase(); SolidityFunction function = new SolidityFunction(FunctionName, SolidityVisibility.Internal, $"{OutputStructName} memory", true); //Add declaration of helper varaibles function.AddToBody(new SolidityStatement($"{OutputStructName} memory output", true)); function.AddToBody(new SolidityStatement($"bool matchedRule = false", true)); //Add checks of conditions for matches and their bodies var rules = GetAllConditions(); foreach (var rule in rules.Select((value, i) => new { i, value })) { var conditionCheck = GetConditionCheck(rule.i); function.AddToBody(AddBodyBasedOnRule(rule.value, conditionCheck.ToString())); } //Add the rest of the function var undefinedOutputCheck = new SolidityIfElse(); undefinedOutputCheck.AddConditionBlock("!matchedRule", new SolidityStatement("revert('Undefined output')", true)); function.AddToBody(undefinedOutputCheck); function.AddToBody(new SolidityStatement("return output", true)); return(function); }
SolidityIfElse CreateIfElseBlock(IList <SequenceFlow> outgoingSequenceFlows) { var ifElseBlock = new SolidityIfElse(); foreach (var sequenceFlow in outgoingSequenceFlows) { var targetConverter = processConverter.GetConverterOfElement(sequenceFlow.TargetId); ifElseBlock.AddConditionBlock(sequenceFlow.Condition, targetConverter.GetStatementForPrevious(gatewayElement)); } return(ifElseBlock); }
public void ThreeConditionsTest() { SolidityIfElse ifelse = new SolidityIfElse(); ifelse.AddConditionBlock("a == 2", new SolidityStatement("a = 0")); ifelse.AddConditionBlock("b == 2", new SolidityStatement("b = 0")); ifelse.AddConditionBlock("c == 2", new SolidityStatement("c = 0")); string expected = "if(a == 2){\n" + "\ta = 0;\n" + "}\n" + "else if(b == 2){\n" + "\tb = 0;\n" + "}\n" + "else if(c == 2){\n" + "\tc = 0;\n" + "}\n"; Assert.Equal(expected, ifelse.ToString()); }
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); }
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); }
//Adds either if-else statement or a general statement protected SolidityComponent AddBodyBasedOnRule(string ruleValue, string body) { //If the row is empty then do not put the logic into conditional statement if (string.IsNullOrEmpty(ruleValue)) { return(new SolidityStatement(body, false)); } else { var condition = new SolidityIfElse(); condition.AddConditionBlock(ruleValue, new SolidityStatement(body, false)); return(condition); } }
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); }
SolidityIfElse CreateIfElseBlock(List <ElementConverter> nextElements, IList <SequenceFlow> outgoingSeqFlows) { var ifElseBlock = new SolidityIfElse(); foreach (var seqFlow in outgoingSeqFlows) { foreach (var nextElement in nextElements) { if (seqFlow.TargetId == nextElement.GetElementId()) { ifElseBlock.AddConditionBlock(seqFlow.Condition, nextElement.GetStatementForPrevious(gateway)); } } } return(ifElseBlock); }
//Returns string representation of section checking existence of matched output in the priority list private string GetPirorityListCheck(int ruleIndex) { var priorityListCheck = new SolidityIfElse(); string priorityListCheckBody = "existsInOutput[i] = true;\n" + "outputSize++;\n" + "matchedRule = true;\n" + "break;"; string priorityListCheckCond = "!existsInOutput[i]"; foreach (var outputEntry in Decision.DecisionTable.Rules[ruleIndex].OutputEntries.Select((value, i) => new { i, value })) { var comparisonVar = $"priorities[i].{Decision.DecisionTable.Outputs[outputEntry.i].Name}"; var comparisonType = Decision.DecisionTable.Outputs[outputEntry.i].TypeRef; var comparisonEntry = outputEntry.value.Text; var comparison = ConvertExpressionToCondition(comparisonVar, comparisonType, comparisonEntry, true); priorityListCheckCond += $" && {comparison}"; } priorityListCheck.AddConditionBlock(priorityListCheckCond, new SolidityStatement(priorityListCheckBody, false)); return(priorityListCheck.ToString()); }
SolidityModifier CreateAddressGuard() { SolidityModifier addressGuard = new SolidityModifier("is" + GetTaskName() + "Authorized"); if (userTask.Assignee.Address != null) { SolidityStatement requireStatement = new SolidityStatement("require(msg.sender==" + GetAssigneeAddress() + ")"); addressGuard.AddToBody(requireStatement); } else if (userTask.Assignee.Name != null) { var addressPosition = Helpers.ADDRESS_MAPPING_VAR_NAME + "[\"" + userTask.Assignee.Name + "\"]"; var ifElseBlock = new SolidityIfElse(); ifElseBlock.AddConditionBlock(addressPosition + " == address(0x0)", new SolidityStatement(addressPosition + " = msg.sender")); SolidityStatement requireStatement = new SolidityStatement("require(msg.sender==" + addressPosition + ")"); addressGuard.AddToBody(ifElseBlock); addressGuard.AddToBody(requireStatement); } return(addressGuard); }
//Retruns for loop component initializing the output private SolidityFor GetInitializationForLoop(int noUniqueOutputs) { var initForLoop = new SolidityFor("i", $"{noUniqueOutputs}"); //Add only outputs that meet the conditions var initCheck = new SolidityIfElse(); string initCheckBody = $"output[j] = {OutputStructName}("; foreach (var output in Decision.DecisionTable.Outputs.Select((value, i) => new { i, value })) { initCheckBody += $"priorities[i].{output.value.Name}"; if (output.i + 1 < Decision.DecisionTable.Outputs.Count) { initCheckBody += ", "; } } initCheckBody += ");\n"; initCheckBody += "j++;"; initCheck.AddConditionBlock("existsInOutput[i]", new SolidityStatement(initCheckBody, false)); initForLoop.AddToBody(new SolidityStatement(initCheck.ToString(), false)); return(initForLoop); }
public override SolidityFunction CreateDecisionFunction() { FunctionName = Regex.Replace(Decision.Id, @" ", "").ToLowerCamelCase(); SolidityFunction function = new SolidityFunction(FunctionName, SolidityVisibility.Internal, $"{OutputStructName} memory", true); //Add declaration of helper varaibles function.AddToBody(new SolidityStatement($"{OutputStructName} memory output", true)); var emptyRule = false; //Add checks of conditions for matches and their bodies var rules = GetAllConditions(); foreach (var rule in rules.Select((value, i) => new { i, value })) { //Assign output if there is already the match string conditionBody = GetConditionBody(rule.i); //If the row is empty then do not put the logic into conditional statement if (string.IsNullOrEmpty(rule.value)) { var condition = new SolidityStatement(conditionBody, false); function.AddToBody(condition); emptyRule = true; break; } else { var condition = new SolidityIfElse(); condition.AddConditionBlock(rule.value, new SolidityStatement(conditionBody, false)); function.AddToBody(condition); } } //Add the rest of the function if (!emptyRule) { function.AddToBody(new SolidityStatement("revert('Undefined output')", true)); } return(function); }
public override SolidityFunction CreateDecisionFunction() { //Define function's header FunctionName = Regex.Replace(Decision.Id, @" ", "").ToLowerCamelCase(); SolidityFunction function = new SolidityFunction(FunctionName, SolidityVisibility.Internal, $"{OutputStructName}[] memory", true); //Add declaration of helper varaibles var prioritiesFormatted = GetPriorities(); var noUniqueOutputs = Regex.Matches(prioritiesFormatted, $"{OutputStructName}").Count; function.AddToBody(new SolidityStatement($"{OutputStructName}[{noUniqueOutputs}] memory priorities = {prioritiesFormatted}", true)); function.AddToBody(new SolidityStatement($"bool[{noUniqueOutputs}] memory existsInOutput", true)); function.AddToBody(new SolidityStatement($"uint outputSize = 0", true)); function.AddToBody(new SolidityStatement($"bool matchedRule = false", true)); var rules = GetAllConditions(); foreach (var rule in rules.Skip(PriorityOffset).Select((value, i) => new { i, value })) { string priorityListCheck = GetPirorityListCheck(rule.i + PriorityOffset); var priorityCheckLoop = new SolidityFor("i", $"{noUniqueOutputs}"); priorityCheckLoop.AddToBody(new SolidityStatement(priorityListCheck, false)); function.AddToBody(AddBodyBasedOnRule(rule.value, priorityCheckLoop.ToString())); } //Initialization of output list function.AddToBody(new SolidityStatement("uint j = 0", true)); function.AddToBody(new SolidityStatement($"{OutputStructName}[] memory output = new {OutputStructName}[](outputSize)", true)); var initForLoop = GetInitializationForLoop(noUniqueOutputs); function.AddToBody(initForLoop); //Add the rest of the function var undefinedOutputCheck = new SolidityIfElse(); undefinedOutputCheck.AddConditionBlock("!matchedRule", new SolidityStatement("revert('Undefined output')", true)); function.AddToBody(undefinedOutputCheck); function.AddToBody(new SolidityStatement("return output", true)); return(function); }