/// <summary> /// Applies an IL modification to the given source graph. /// </summary> /// <param name="targetCilGraph">Graph to which an IL modification will be applied.</param> /// <remarks> /// The <see cref="PointCut"/> will be applied to the <paramref name="targetCilGraph"/>, and /// each identified target will have the <see cref="ConceptWeaver"/> applied. /// </remarks> public void Weave(ICilGraph targetCilGraph) { foreach (var joinPoint in this.PointCut.GetJoinPoints(targetCilGraph)) { joinPoint.Weave(this.ConceptWeaver); } }
public static ICilGraph Merge(this ICilGraph original, ICilGraph addition) { return(new CilGraph( original.Vertices.Concat(addition.Vertices), original.ParentChildEdges.Concat(addition.ParentChildEdges), original.SiblingEdges.Concat(addition.SiblingEdges), original.DependencyEdges.Concat(addition.DependencyEdges))); }
public IEnumerable <JoinPoint <TTarget> > GetJoinPoints(ICilGraph targetCilGraph) { return(targetCilGraph .Vertices .OfType <TTarget>() .Where(m => this.Selector(m)) .Select(m => new JoinPoint <TTarget>(m))); }
public static ICilGraph ReplaceVertices(this ICilGraph source, Func <object, bool> predicate, object newVertex) { var fullGraph = new CilGraph( source.Vertices.Select(v => predicate(v) ? newVertex : v), source.ParentChildEdges.Select(e => e.ReplaceVertices(predicate, newVertex, (from, to) => new ParentChildCilEdge(to, from))), source.SiblingEdges.Select(e => e.ReplaceVertices(predicate, newVertex, (from, to) => new SiblingCilEdge(to, from))), source.DependencyEdges.Select(e => e.ReplaceVertices(predicate, newVertex, (from, to) => new DependencyCilEdge(from, to)))); return(fullGraph); }
/// <summary> /// Creates a new <see cref="CloningContext"/> /// </summary> /// <param name="cilGraph">CIL graph for the cloning operation</param> /// <param name="rootSource">Top level source type for the cloning operation</param> /// <param name="targetModule">Module into which the <paramref name="rootSource"/> will be introduced</param> public CloningContext(ICilGraph cilGraph, TypeDefinition rootSource, ModuleDefinition targetModule) { Contract.Requires(cilGraph != null); Contract.Requires(rootSource != null); Contract.Ensures(this.CilGraph != null); Contract.Ensures(this.ClonersBySource != null); Contract.Ensures(this.RootSource != null); Contract.Ensures(this.RootTarget == null); Contract.Ensures(this.TargetModule != null); this.CilGraph = cilGraph; this.RootSource = rootSource; this.TargetModule = targetModule; this.ClonersBySource = new Dictionary <object, IReadOnlyCollection <ICloner <object, object> > >(this.CilGraph.VertexCount); }
/// <summary> /// Creates a new <see cref="CloningContext"/> /// </summary> /// <param name="cilGraph">CIL graph for the cloning operation</param> /// <param name="rootSource">Top level source type for the cloning operation</param> /// <param name="rootTarget">Top level target type for the cloning operation</param> public CloningContext(ICilGraph cilGraph, TypeDefinition rootSource, TypeDefinition rootTarget) { Contract.Requires(cilGraph != null); Contract.Requires(rootSource != null); Contract.Requires(rootTarget != null); Contract.Ensures(this.CilGraph != null); Contract.Ensures(this.ClonersBySource != null); Contract.Ensures(this.RootSource != null); Contract.Ensures(this.RootTarget != null); this.CilGraph = cilGraph; this.RootSource = rootSource; this.RootTarget = rootTarget; this.TypeCache = new Dictionary <string, TypeReference>(); this.FieldCache = new Dictionary <string, FieldReference>(); this.MethodCache = new Dictionary <string, MethodReference>(); this.ClonersBySource = new Dictionary <object, IReadOnlyCollection <ICloner <object, object> > >(this.CilGraph.VertexCount); }
/// <summary> /// Retrieves the minimal subset of vertices from the <paramref name="sourceGraph"/> /// that are required to fully support the <paramref name="startItems"/>. /// </summary> /// <param name="sourceGraph">Graph from which the vertices will be pulled</param> /// <param name="startItems">Items which form the starting set of the subset</param> /// <returns></returns> private static HashSet <object> FindMinimalVerticesSubset( this ICilGraph sourceGraph, IEnumerable <object> startItems) { Contract.Requires(sourceGraph != null); Contract.Requires(startItems != null); Contract.Ensures(Contract.Result <HashSet <object> >() != null); var vertices = new HashSet <object>(); var stack = new Stack <object>(startItems); while (stack.Count > 0) { var currentItem = stack.Pop(); // skip this item if it's already been added to the vertices if (!vertices.Add(currentItem)) { continue; } // include dependencies of included items foreach (var dependency in from edge in sourceGraph.DependencyEdges where edge.Dependent == currentItem && !vertices.Contains(edge.DependsOn) select edge.DependsOn) { stack.Push(dependency); } // include children of included items foreach (var child in from edge in sourceGraph.ParentChildEdges where edge.Parent == currentItem && !vertices.Contains(edge.Child) select edge.Child) { stack.Push(child); } } return(vertices); }
/// <summary> /// Given a source graph and a set of start items, returns a minimal subset of the source /// graph that contains all start items /// </summary> /// <param name="sourceGraph">Source graph for the crop operation</param> /// <param name="startItems">Vertices of <paramref name="sourceGraph"/> which form the basis of the crop operation</param> /// <returns></returns> public static ICilGraph GetClosedSetFor(this ICilGraph sourceGraph, IEnumerable <object> startItems) { Contract.Requires(sourceGraph != null); Contract.Ensures(Contract.Result <ICilGraph>() != null); if (startItems == null || !startItems.Any()) { return(new CilGraph(new object[0], new ParentChildCilEdge[0], new SiblingCilEdge[0], new DependencyCilEdge[0])); } if (startItems.Any(item => !sourceGraph.ContainsVertex(item))) { throw new ArgumentException("All start items must be vertices in the source graph.", nameof(startItems)); } // perform a search for all vertices that will be included in the var vertices = sourceGraph.FindMinimalVerticesSubset(startItems); // dependencies are maintained, and all member dependencies are included var depedencyEdges = from edge in sourceGraph.DependencyEdges where vertices.Contains(edge.Dependent) select new DependencyCilEdge(edge.Dependent, edge.DependsOn); // parent/child relationships are maintained, and all member children are included var parentChildEdges = from edge in sourceGraph.ParentChildEdges where vertices.Contains(edge.Parent) select new ParentChildCilEdge(edge.Parent, edge.Child); // sibling edges maintain order // sibling relationships only make sense when a parent is included, and all siblings within an included parent are included var siblingEdges = from edge in sourceGraph.SiblingEdges where vertices.Contains(edge.First) && vertices.Contains(edge.Second) select new SiblingCilEdge(edge.First, edge.Second); return(new CilGraph(vertices, parentChildEdges, siblingEdges, depedencyEdges)); }
/// <summary> /// Given a source graph and a set of start items, returns a minimal subset of the source /// graph that contains all start items /// </summary> /// <param name="sourceGraph">Source graph for the crop operation</param> /// <param name="startItems">Vertices of <paramref name="sourceGraph"/> which form the basis of the crop operation</param> /// <returns></returns> public ICilGraph Crop(ICilGraph sourceGraph, params object[] startItems) { Contract.Requires(sourceGraph != null); Contract.Ensures(Contract.Result<ICilGraph>() != null); if (startItems == null || startItems.Length == 0) { return new CilGraph(new object[0], new ParentChildCilEdge[0], new SiblingCilEdge[0], new DependencyCilEdge[0]); } if (startItems.Any(item => !sourceGraph.ContainsVertex(item))) { throw new ArgumentException("All start items must be vertices in the source graph.", nameof(startItems)); } // perform a search for all vertices that will be included in the var vertices = GraphCropper.FindMinimalVerticesSubset(sourceGraph, startItems); // dependencies are maintained, and all member dependencies are included var depedencyEdges = from edge in sourceGraph.DependencyEdges where vertices.Contains(edge.Dependent) select new DependencyCilEdge(edge.Dependent, edge.DependsOn); // parent/child relationships are maintained, and all member children are included var parentChildEdges = from edge in sourceGraph.ParentChildEdges where vertices.Contains(edge) select new ParentChildCilEdge(edge.Parent, edge.Child); // sibling edges maintain order // sibling relationships only make sense when a parent is included, and all siblings within an included parent are included var siblingEdges = from edge in sourceGraph.SiblingEdges where vertices.Contains(edge.First) && vertices.Contains(edge.Second) select new SiblingCilEdge(edge.First, edge.Second); return new CilGraph(vertices, parentChildEdges, siblingEdges, depedencyEdges); }
public void Weave(ICilGraph sourceGraph) { Contract.Requires(sourceGraph != null); throw new NotSupportedException(); }
public static ICilGraph ReplaceVertices(this ICilGraph source, Func <object, bool> predicate, ICilGraph newVertexGraph, object newVertex) { var newSource = source == newVertexGraph ? source : source.Merge(newVertexGraph); return(newSource.ReplaceVertices(predicate, newVertex)); }
public static ICilGraph ReplaceVertex(this ICilGraph source, object originalVertex, object newVertex) { return(source.ReplaceVertices(v => v == originalVertex, newVertex)); }
public static ICilGraph GetClosedSetForRoots(this ICilGraph sourceGraph) { return(sourceGraph.GetClosedSetFor(sourceGraph.Roots)); }
/// <summary> /// Retrieves the minimal subset of vertices from the <paramref name="sourceGraph"/> /// that are required to fully support the <paramref name="startItems"/>. /// </summary> /// <param name="sourceGraph">Graph from which the vertices will be pulled</param> /// <param name="startItems">Items which form the starting set of the subset</param> /// <returns></returns> private static HashSet<object> FindMinimalVerticesSubset( ICilGraph sourceGraph, IEnumerable<object> startItems) { Contract.Requires(sourceGraph != null); Contract.Requires(startItems != null); Contract.Ensures(Contract.Result<HashSet<object>>() != null); var vertices = new HashSet<object>(); var stack = new Stack<object>(startItems); while (stack.Count > 0) { var currentItem = stack.Pop(); // skip this item if it's already been added to the vertices if (!vertices.Add(currentItem)) { continue; } // include dependencies of included items foreach (var dependency in from edge in sourceGraph.DependencyEdges where edge.Dependent == currentItem && !vertices.Contains(edge.DependsOn) select edge.DependsOn) { stack.Push(dependency); } // include children of included items foreach (var child in from edge in sourceGraph.ParentChildEdges where edge.Parent == currentItem && !vertices.Contains(edge.Child) select edge.Child) { stack.Push(child); } } return vertices; }