예제 #1
0
 /// <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);
     }
 }
예제 #2
0
 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)));
 }
예제 #3
0
 public IEnumerable <JoinPoint <TTarget> > GetJoinPoints(ICilGraph targetCilGraph)
 {
     return(targetCilGraph
            .Vertices
            .OfType <TTarget>()
            .Where(m => this.Selector(m))
            .Select(m => new JoinPoint <TTarget>(m)));
 }
예제 #4
0
        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);
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
        /// <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);
        }
예제 #8
0
        /// <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));
        }
예제 #9
0
        /// <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();
        }
예제 #11
0
        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));
        }
예제 #12
0
 public static ICilGraph ReplaceVertex(this ICilGraph source, object originalVertex, object newVertex)
 {
     return(source.ReplaceVertices(v => v == originalVertex, newVertex));
 }
예제 #13
0
 public static ICilGraph GetClosedSetForRoots(this ICilGraph sourceGraph)
 {
     return(sourceGraph.GetClosedSetFor(sourceGraph.Roots));
 }
예제 #14
0
        /// <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;
        }