protected void Compile() { tempToTextBoxMap.Clear(); var outputWindow = ServiceManager.Get <IFlowSharpCodeOutputWindowService>(); outputWindow.Clear(); IFlowSharpCanvasService canvasService = ServiceManager.Get <IFlowSharpCanvasService>(); IFlowSharpMenuService menuService = ServiceManager.Get <IFlowSharpMenuService>(); IFlowSharpCodeService codeService = ServiceManager.Get <IFlowSharpCodeService>(); BaseController canvasController = canvasService.ActiveController; List <string> refs = GetCanvasReferences(canvasController); List <GraphicElement> shapeSources = GetCanvasSources(canvasController); List <string> sourceFilenames = GetSourceFiles(shapeSources); bool isStandAlone = runner is StandAloneRunner; string filename = GetExeOrDllFilename(menuService.Filename); CompilerResults results = Compile(filename, sourceFilenames, refs, isStandAlone); DeleteTempFiles(sourceFilenames); if (!results.Errors.HasErrors) { outputWindow.WriteLine("No Errors"); } }
protected void GenerateCodeForWorkflow(IFlowSharpCodeService codeService, StringBuilder sb, GraphicElement el, int indent) { string strIndent = new String('\t', indent); while (el != null) { if ((el is IIfBox)) { // True clause var elTrue = codeService.GetTruePathFirstShape((IIfBox)el); // False clause var elFalse = codeService.GetFalsePathFirstShape((IIfBox)el); if (elTrue != null) { sb.AppendLine(strIndent + "bool " + el.Text.ToLower() + " = workflow." + el.Text + "(packet);"); sb.AppendLine(); sb.AppendLine(strIndent + "if (" + el.Text.ToLower() + ")"); sb.AppendLine(strIndent + "{"); GenerateCodeForWorkflow(codeService, sb, elTrue, indent + 1); sb.AppendLine(strIndent + "}"); if (elFalse != null) { sb.AppendLine(strIndent + "else"); sb.AppendLine(strIndent + "{"); GenerateCodeForWorkflow(codeService, sb, elFalse, indent + 1); sb.AppendLine(strIndent + "}"); } } else if (elFalse != null) { sb.AppendLine(strIndent + "bool " + el.Text.ToLower() + " = workflow." + el.Text + "(packet);"); sb.AppendLine(); sb.AppendLine(strIndent + "if (!" + el.Text.ToLower() + ")"); sb.AppendLine(strIndent + "{"); GenerateCodeForWorkflow(codeService, sb, elFalse, indent + 1); sb.AppendLine(strIndent + "}"); } // TODO: How to join back up with workflows that rejoin from if-then-else? break; } else { sb.AppendLine(strIndent + "workflow." + el.Text + "(packet);"); } el = codeService.NextElementInWorkflow(el); } }
public string GetWorkflowCode(IFlowSharpCodeService codeService, BaseController canvasController, GraphicElement wf) { StringBuilder sb = new StringBuilder(); string packetName = Clifton.Core.ExtensionMethods.ExtensionMethods.LeftOf(wf.Text, "Workflow"); GraphicElement elDefiningPacket = FindPacket(canvasController, packetName); if (elDefiningPacket == null) { ServiceManager.Get <IFlowSharpCodeOutputWindowService>().WriteLine("Workflow packet '" + packetName + "' must be defined."); } else { bool packetHasParameterlessConstructor = HasParameterlessConstructor(GetCode(elDefiningPacket), packetName); // TODO: Hardcoded for now for POC. sb.AppendLine("// This code has been auto-generated by FlowSharpCode"); sb.AppendLine("// Do not modify this code -- your changes will be overwritten!"); sb.AppendLine("namespace App"); sb.AppendLine("{"); sb.AppendLine("\tpublic partial class " + wf.Text); sb.AppendLine("\t{"); if (packetHasParameterlessConstructor) { sb.AppendLine("\t\tpublic static void Execute()"); sb.AppendLine("\t\t{"); sb.AppendLine("\t\t\tExecute(new " + packetName + "());"); sb.AppendLine("\t\t}"); sb.AppendLine(); } sb.AppendLine("\t\tpublic static void Execute(" + packetName + " packet)"); sb.AppendLine("\t\t{"); sb.AppendLine("\t\t\t" + wf.Text + " workflow = new " + wf.Text + "();"); // Fill in the workflow steps. GraphicElement el = codeService.FindStartOfWorkflow(canvasController, wf); GenerateCodeForWorkflow(codeService, sb, el, 3); // We're all done. sb.AppendLine("\t\t}"); sb.AppendLine("\t}"); sb.AppendLine("}"); } return(sb.ToString()); }
public void Load(string fullName) { // Testing externally started is a workaround for the fact that once we detect the "Stand Alone Runner" app, // which sets externallyStarted to true, subsequently any child windows that it opens results in AlreadyRunning // returning false, so we have to check if we already know that the runner was externally started. bool alreadyRunning = AlreadyRunning(); if (!alreadyRunning && !externallyStarted && !loaded) { IFlowSharpCodeService codeSvc = serviceManager.Get <IFlowSharpCodeService>(); process = codeSvc.LaunchProcess(fullName, String.Empty, _ => { }); loaded = true; } else if (alreadyRunning) { externallyStarted = true; loaded = false; // Ensure loaded flag stays false so we don't unload an externally started process. } }
protected void DrakonWorkflowCodeGenerator(BaseController canvasController, GraphicElement elClass, string className, string filename) { IFlowSharpCodeService codeService = ServiceManager.Get <IFlowSharpCodeService>(); GraphicElement el = codeService.FindStartOfWorkflow(canvasController, elClass); if (el == null) { var outputWindow = ServiceManager.Get <IFlowSharpCodeOutputWindowService>(); outputWindow.Clear(); outputWindow.WriteLine("Cannot find shape that is the start of the workflow."); } else { DrakonCodeTree dcg = new DrakonCodeTree(); codeService.ParseDrakonWorkflow(dcg, codeService, canvasController, el); var codeGenSvc = new PythonCodeGeneratorService(); dcg.GenerateCode(codeGenSvc); codeGenSvc.CodeResult.Insert(0, PYLINT + "\n"); File.WriteAllText(filename, codeGenSvc.CodeResult.ToString()); elClass.Json["python"] = codeGenSvc.CodeResult.ToString(); } }
public void Compile() { TerminateRunningProcess(); var outputWindow = ServiceManager.Get <IFlowSharpCodeOutputWindowService>(); outputWindow.Clear(); IFlowSharpCanvasService canvasService = ServiceManager.Get <IFlowSharpCanvasService>(); IFlowSharpMenuService menuService = ServiceManager.Get <IFlowSharpMenuService>(); IFlowSharpCodeService codeService = ServiceManager.Get <IFlowSharpCodeService>(); BaseController canvasController = canvasService.ActiveController; tempToTextBoxMap.Clear(); List <GraphicElement> compiledAssemblies = new List <GraphicElement>(); bool ok = CompileAssemblies(canvasController, compiledAssemblies); if (!ok) { DeleteTempFiles(); return; } List <string> refs = new List <string>(); List <string> sources = new List <string>(); // Add specific assembly references on the drawing. List <IAssemblyReferenceBox> references = GetReferences(canvasController); refs.AddRange(references.Select(r => r.Filename)); List <GraphicElement> rootSourceShapes = GetSources(canvasController); rootSourceShapes.ForEach(root => GetReferencedAssemblies(root).Where(refassy => refassy is IAssemblyBox).ForEach(refassy => refs.Add(((IAssemblyBox)refassy).Filename))); // Get code for workflow boxes first, as this code will then be included in the rootSourceShape code listing. IEnumerable <GraphicElement> workflowShapes = canvasController.Elements.Where(el => el is IWorkflowBox); workflowShapes.ForEach(wf => { string code = GetWorkflowCode(codeService, canvasController, wf); wf.Json["Code"] = code; }); List <GraphicElement> excludeClassShapes = new List <GraphicElement>(); List <GraphicElement> classes = GetClasses(canvasController); // Get CSharpClass shapes that contain DRAKON shapes. classes.Where(cls => HasDrakonShapes(canvasController, cls)).ForEach(cls => { excludeClassShapes.AddRange(canvasController.Elements.Where(el => cls.DisplayRectangle.Contains(el.DisplayRectangle))); DrakonCodeTree dcg = new DrakonCodeTree(); var workflowStart = codeService.FindStartOfWorkflow(canvasController, cls); codeService.ParseDrakonWorkflow(dcg, codeService, canvasController, workflowStart); var codeGenSvc = new CSharpCodeGeneratorService(); dcg.GenerateCode(codeGenSvc); InsertCodeInRunWorkflowMethod(cls, codeGenSvc.CodeResult); string filename = CreateCodeFile(cls); sources.Add(filename); }); rootSourceShapes.Where(root => !excludeClassShapes.Contains(root)).ForEach(root => { // Get all other shapes that are not part of CSharpClass shapes: // TODO: Better Linq! if (!String.IsNullOrEmpty(GetCode(root))) { string filename = CreateCodeFile(root); sources.Add(filename); } }); exeFilename = String.IsNullOrEmpty(menuService.Filename) ? "temp.exe" : Path.GetFileNameWithoutExtension(menuService.Filename) + ".exe"; Compile(exeFilename, sources, refs, true); DeleteTempFiles(); if (!results.Errors.HasErrors) { outputWindow.WriteLine("No Errors"); } }
// =================================================== // DRAKON workflow public GraphicElement ParseDrakonWorkflow(DrakonCodeTree dcg, IFlowSharpCodeService codeService, BaseController canvasController, GraphicElement el, bool inCondition = false) { while (el != null) { // If we're in a conditional and we encounter a shape with multiple "merge" connections, then we assume (I think rightly so) // that this is the end of the conditional branch, and that code should continue at this point outside of the "if-else" statement. if (inCondition) { var connections = el.Connections.Where(c => c.ElementConnectionPoint.Type == GripType.TopMiddle); if (connections.Count() > 1) { return(el); } } // All these if's. Yuck. if (el is IBeginForLoopBox) { var drakonLoop = new DrakonLoop() { Code = ParseCode(el) }; dcg.AddInstruction(drakonLoop); var nextEl = codeService.NextElementInWorkflow(el); if (nextEl != null) { el = ParseDrakonWorkflow(drakonLoop.LoopInstructions, codeService, canvasController, nextEl); } else { // TODO: error -- there are no further elements after the beginning for loop box! ServiceManager.Get <IFlowSharpCodeOutputWindowService>().WriteLine("Error: Drakon start 'for' loop does not have any statements!"); return(el); } } else if (el is IEndForLoopBox) { return(el); } else if (el is IIfBox) { var drakonIf = new DrakonIf() { Code = ParseCode(el) }; dcg.AddInstruction(drakonIf); var elTrue = codeService.GetTruePathFirstShape((IIfBox)el); var elFalse = codeService.GetFalsePathFirstShape((IIfBox)el); if (elTrue != null) { ParseDrakonWorkflow(drakonIf.TrueInstructions, codeService, canvasController, elTrue, true); } if (elFalse != null) { ParseDrakonWorkflow(drakonIf.FalseInstructions, codeService, canvasController, elFalse, true); } // dcg.AddInstruction(new DrakonEndIf()); } else if (el is IOutputBox) { dcg.AddInstruction(new DrakonOutput() { Code = ParseCode(el) }); } else { dcg.AddInstruction(new DrakonStatement() { Code = ParseCode(el) }); } el = codeService.NextElementInWorkflow(el); } return(null); }