/// <summary> /// Prepend program point as first of contained points. /// Is connected with flow edge to FirstPoint /// </summary> /// <param name="programPoint">Prepended point</param> internal void PreprendFlowWith(ProgramPointBase programPoint) { var first = FirstPoint; programPoint.AddFlowChild(first); _containedPoints.Insert(0, programPoint); }
/// <summary> /// Set throw branches from current point into specified program points. These branches contain /// catch point and handles given ThrowInfo values. /// </summary> /// <param name="branches">ThrowInfo values specifiing udpates/creations/deletions of throw branches</param> /// <param name="removeFlowChildren">If true flow children will be removed, otherwise no other than catch point children are affected</param> public void SetThrowBranching(IEnumerable <ThrowInfo> branches, bool removeFlowChildren = false) { //create indexed structure for branches var indexed = new Dictionary <CatchBlockDescription, ThrowInfo>(); foreach (var branch in branches) { indexed.Add(branch.Catch, branch); } //update already existing branches var childrenCopy = CurrentProgramPoint.FlowChildren.ToArray(); foreach (var child in childrenCopy) { var catchChild = child as CatchPoint; if (catchChild == null) { if (removeFlowChildren) { CurrentProgramPoint.RemoveFlowChild(child); } continue; } ThrowInfo info; if (indexed.TryGetValue(catchChild.CatchDescription, out info)) { catchChild.ReThrow(info); //remove branch from index because it is already complete indexed.Remove(catchChild.CatchDescription); } else { //no more it contains branch for this catch child //disconnect it from graph CurrentProgramPoint.RemoveFlowChild(catchChild); catchChild.RemoveFlowChild(catchChild.TargetPoint); } } //add new branches foreach (var throwInfo in indexed.Values) { //create catch point according to specified throw info var catchPoint = new CatchPoint(CurrentProgramPoint, throwInfo.Catch); InitializeNewPoint(catchPoint, catchPoint.TargetPoint.OwningPPGraph); catchPoint.ReThrow(throwInfo); //connect branch into graph CurrentProgramPoint.AddFlowChild(catchPoint); catchPoint.AddFlowChild(catchPoint.TargetPoint); } }
/// <summary> /// Add extension branch indexed by given key /// </summary> /// <param name="key">Key of added extension</param> /// <param name="ppGraph">Extending program point graph</param> /// <param name="type">Type of extension</param> /// <returns>Extension point which connect extending ppGraph with Owner</returns> internal ExtensionPoint Add(object key, ProgramPointGraph ppGraph, ExtensionType type) { if (!IsConnected) { connect(); } ppGraph.Context._callers.Add(Owner); Owner.Services.SetServices(ppGraph); var extension = new ExtensionPoint(Owner, ppGraph, type); Owner.Services.SetServices(extension); _extensions.Add(key, extension); //connect ppGraph into current graph Owner.AddFlowChild(extension); extension.Graph.End.AddFlowChild(Sink); return(extension); }
/// <summary> /// Expand given statements int program point base chain /// </summary> /// <param name="statements">Statements to expand</param> /// <returns>Program points created from statements expanding</returns> private List <ProgramPointBase> expandStatements(IEnumerable <LangElement> statements) { var points = new List <ProgramPointBase>(); ProgramPointBase lastPoint = null; foreach (var statement in statements) { var expanded = ElementExpander.ExpandStatement(statement, reportCreation); if (lastPoint != null) { //connect before expanded points lastPoint.AddFlowChild(expanded[0]); } lastPoint = expanded[expanded.Length - 1]; points.AddRange(expanded); } return(points); }