예제 #1
0
        /// <summary>
        /// Finds matching dependencies for a given method by walking through the IL instructions.
        /// </summary>
        private void CheckMethod(TypeDefinition type, MethodDefinition method, ref SearchDefinition results)
        {
            // Check the return type
            if (method.ReturnType.ContainsGenericParameter)
            {
                CheckGenericParameters(type, method.ReturnType.GenericParameters, ref results);
            }

            if (results.GetAllMatchingDependencies(method.ReturnType.FullName).Any())
            {
                results.AddToFound(type, method.ReturnType.FullName);
            }

            // Check for any generic parameters
            if (method.ContainsGenericParameter)
            {
                CheckGenericParameters(type, method.GenericParameters, ref results);
            }

            if (method.HasParameters)
            {
                CheckParameters(type, method.Parameters, ref results);
            }

            // Check the contents of the method body
            CheckMethodBody(type, method, ref results);
        }
예제 #2
0
        /// <summary>
        /// Finds types that have a dependency on every items in a given list of dependencies.
        /// </summary>
        /// <param name="input">The set of type definitions to search.</param>
        /// <param name="dependencies">The set of dependencies to look for.</param>
        /// <returns>A list of dependencies found in the input classes.</returns>
        internal IReadOnlyList <TypeDefinition> FindTypesWithAllDependencies(IEnumerable <TypeDefinition> input, IEnumerable <string> dependencies)
        {
            // Set up the search definition
            var results = new SearchDefinition(dependencies);

            // Check each type in turn
            foreach (var type in input)
            {
                CheckType(type, ref results);
            }

            var output = new List <TypeDefinition>();

            foreach (var typeFound in results.TypesFound)
            {
                // NB: Nested classes won't be picked up here
                var match = input.FirstOrDefault(d => d.FullName.Equals(typeFound, StringComparison.InvariantCultureIgnoreCase));
                if (match != null &&
                    results.GetAllDependenciesMatchingAnyOf(results.GetDependenciesFoundForType(typeFound)).Count() == results.UniqueDependenciesCount)
                {
                    // Check found
                    output.Add(match);
                }
            }

            return(output);
        }
예제 #3
0
        /// <summary>
        /// Finds matching dependencies for a given type by walking through the type contents.
        /// </summary>
        private void CheckType(TypeDefinition type, ref SearchDefinition results)
        {
            // Have we already checked this type?
            if (results.IsChecked(type))
            {
                return;
            }

            // Add the current type to the checked list - this prevents any circular checks
            results.AddToChecked(type);

            // Does this directly inherit from a dependency?
            var baseClass = type.BaseType?.Resolve();

            if (baseClass != null)
            {
                foreach (var dependency in results.SearchList)
                {
                    if (baseClass.FullName.StartsWith(dependency, StringComparison.InvariantCultureIgnoreCase))
                    {
                        results.AddToFound(type, dependency);
                    }
                }
            }

            // Check the properties
            CheckProperties(type, ref results);

            // Check the generic parameters for the type
            if (type.HasGenericParameters)
            {
                CheckGenericParameters(type, type.GenericParameters, ref results);
            }

            // Check the fields
            CheckFields(type, ref results);

            // Check the events
            CheckEvents(type, ref results);

            // Check the nested types
            foreach (var nested in type.NestedTypes)
            {
                this.CheckType(nested, ref results);
            }

            // Check each method
            foreach (var method in type.Methods)
            {
                this.CheckMethod(type, method, ref results);
            }
        }
예제 #4
0
 /// <summary>
 /// Finds matching dependencies for a given method by walking through the events.
 /// </summary>
 private void CheckEvents(TypeDefinition type, ref SearchDefinition results)
 {
     if (type.HasEvents)
     {
         foreach (var eventDef in type.Events)
         {
             if (eventDef.HasOtherMethods)
             {
                 foreach (var method in eventDef.OtherMethods)
                 {
                     CheckMethod(type, method, ref results);
                 }
             }
         }
     }
 }
예제 #5
0
        /// <summary>
        /// Finds types that have a dependency on every items in a given list of dependencies.
        /// </summary>
        /// <param name="input">The set of type definitions to search.</param>
        /// <param name="dependencies">The set of dependencies to look for.</param>
        /// <returns>A list of dependencies found in the input classes.</returns>
        internal IReadOnlyList <TypeDefinition> FindTypesWithAllDependencies(IEnumerable <TypeDefinition> input, IEnumerable <string> dependencies)
        {
            var output = new List <TypeDefinition>();
            var found  = new List <string>();
            var start  = true;

            foreach (var dependency in dependencies)
            {
                if (start || found.Count > 0)
                {
                    // Set up the search definition
                    var results = new SearchDefinition(new string[] { dependency });

                    // Check each type in turn
                    foreach (var type in input)
                    {
                        CheckType(type, ref results);
                    }

                    if (start)
                    {
                        // Kick off the list of types that we have found
                        found = results.TypesFound.ToList();
                        start = false;
                    }
                    else
                    {
                        // Only select items that appear in both lists
                        found = found.Where(r => results.TypesFound.Contains(r)).ToList();
                    }
                }
            }

            foreach (var typeFound in found)
            {
                // NB: Nested classes won't be picked up here
                var match = input.FirstOrDefault(d => d.FullName.Equals(typeFound, StringComparison.InvariantCultureIgnoreCase));
                if (match != null)
                {
                    output.Add(match);
                }
            }

            return(output);
        }
예제 #6
0
        /// <summary>
        /// Finds matching dependencies for a given method by walking through the fields.
        /// </summary>
        private void CheckFields(TypeDefinition type, ref SearchDefinition results)
        {
            if (type.HasFields)
            {
                foreach (var field in type.Fields)
                {
                    // The field could be a generic property
                    if (field.ContainsGenericParameter)
                    {
                        CheckParameters(type, field.FieldType.GenericParameters, ref results);
                    }

                    if (results.GetAllMatchingDependencies(field.FieldType.FullName).Any())
                    {
                        results.AddToFound(type, field.FieldType.FullName);
                    }
                }
            }
        }
예제 #7
0
        /// <summary>
        /// Finds matching dependencies for a given method by walking through the fields.
        /// </summary>
        private void CheckFields(TypeDefinition type, ref SearchDefinition results)
        {
            if (type.HasFields)
            {
                foreach (var field in type.Fields)
                {
                    // The field could be a generic property
                    if (field.ContainsGenericParameter)
                    {
                        CheckGenericParameters(type, field.FieldType.GenericParameters, ref results);
                    }

                    if (results.SearchList.Any(m => field.FieldType.FullName.StartsWith(m)))
                    {
                        results.AddToFound(type, field.FieldType.FullName);
                    }
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Finds matching dependencies for a given method by walking through the properties.
        /// </summary>
        private void CheckProperties(TypeDefinition type, ref SearchDefinition results)
        {
            if (type.HasProperties)
            {
                foreach (var property in type.Properties)
                {
                    // The property could be a generic property
                    if (property.ContainsGenericParameter)
                    {
                        CheckParameters(type, property.PropertyType.GenericParameters, ref results);
                    }

                    // Check the property type
                    if (results.GetAllMatchingDependencies(property.PropertyType.FullName).Any())
                    {
                        results.AddToFound(type, property.PropertyType.FullName);
                    }
                }
            }
        }
예제 #9
0
        /// <summary>
        /// Finds matching dependencies for a given method by walking through the properties.
        /// </summary>
        private void CheckProperties(TypeDefinition type, ref SearchDefinition results)
        {
            if (type.HasProperties)
            {
                foreach (var property in type.Properties)
                {
                    // The property could be a generic property
                    if (property.ContainsGenericParameter)
                    {
                        CheckGenericParameters(type, property.PropertyType.GenericParameters, ref results);
                    }

                    // Check the property type
                    if (results.SearchList.Any(m => property.PropertyType.FullName.StartsWith(m)))
                    {
                        results.AddToFound(type, property.PropertyType.FullName);
                    }
                }
            }
        }
예제 #10
0
        /// <summary>
        /// Finds matching dependencies for a given method by scanning the code.
        /// </summary>
        private void CheckMethodBody(TypeDefinition type, MethodDefinition method, ref SearchDefinition results)
        {
            if (method.HasBody)
            {
                foreach (var variable in method.Body.Variables)
                {
                    // Check any nested types in methods - the compiler will create one for every asynchronous method or iterator.
                    if (variable.VariableType.IsNested)
                    {
                        CheckType(variable.VariableType.Resolve(), ref results);
                    }
                    else
                    {
                        if (variable.VariableType.ContainsGenericParameter)
                        {
                            CheckParameters(type, variable.VariableType.GenericParameters, ref results);
                        }

                        if (results.GetAllMatchingDependencies(variable.VariableType.FullName).Any())
                        {
                            results.AddToFound(type, variable.VariableType.FullName);
                        }
                    }
                }

                // Check each instruction for references to our types
                foreach (var instruction in method.Body.Instructions)
                {
                    if (instruction.Operand != null)
                    {
                        var operands = ExtractTypeNames(instruction.Operand.ToString());
                        var matches  = results.GetAllDependenciesMatchingAnyOf(operands);
                        foreach (var item in matches)
                        {
                            results.AddToFound(type, item);
                        }
                    }
                }
            }
        }
예제 #11
0
        /// <summary>
        /// Finds matching dependencies for a given method by scanning the code.
        /// </summary>
        private void CheckMethodBody(TypeDefinition type, MethodDefinition method, ref SearchDefinition results)
        {
            if (method.HasBody)
            {
                foreach (var variable in method.Body.Variables)
                {
                    // Check any nested types in methods - the compiler will create one for every asynchronous method or iterator.
                    if (variable.VariableType.IsNested)
                    {
                        CheckType(variable.VariableType.Resolve(), ref results);
                    }
                    else
                    {
                        if (variable.VariableType.ContainsGenericParameter)
                        {
                            CheckGenericParameters(type, variable.VariableType.GenericParameters, ref results);
                        }

                        if (results.SearchList.Any(m => variable.VariableType.FullName.StartsWith(m)))
                        {
                            results.AddToFound(type, variable.VariableType.FullName);
                        }
                    }
                }

                // Check each instruction for references to our types
                foreach (var instruction in method.Body.Instructions)
                {
                    if (instruction.Operand != null)
                    {
                        var operand = instruction.Operand.ToString();
                        var matches = results.SearchList.Where(m => operand.Contains(m)).ToArray();
                        foreach (var item in matches)
                        {
                            results.AddToFound(type, item);
                        }
                    }
                }
            }
        }
예제 #12
0
        /// <summary>
        /// Finds matching dependencies for a given method by walking through the IL instructions.
        /// </summary>
        private void CheckMethod(TypeDefinition type, MethodDefinition method, ref SearchDefinition results)
        {
            // Check the return type
            if (method.ReturnType.ContainsGenericParameter)
            {
                CheckGenericParameters(type, method.ReturnType.GenericParameters, ref results);
            }

            if (results.SearchList.Any(m => method.ReturnType.FullName.StartsWith(m)))
            {
                results.AddToFound(type, method.ReturnType.FullName);
            }

            // Check for any generic parameters
            if (method.ContainsGenericParameter)
            {
                CheckGenericParameters(type, method.GenericParameters, ref results);
            }

            // Check the contents of the method body
            CheckMethodBody(type, method, ref results);
        }
예제 #13
0
        /// <summary>
        /// Finds matching dependencies for a given method by walking through the IL instructions.
        /// </summary>
        private void CheckMethod(TypeDefinition type, MethodDefinition method, ref SearchDefinition results)
        {
            // Check the return type
            if (method.ReturnType.ContainsGenericParameter)
            {
                CheckParameters(type, method.ReturnType.GenericParameters, ref results);
            }

            if (method.ReturnType.IsGenericInstance)
            {
                var returnTypeAsGenericInstance = method.ReturnType as GenericInstanceType;
                if (returnTypeAsGenericInstance.HasGenericArguments)
                {
                    CheckParameters(type, returnTypeAsGenericInstance.GenericArguments, ref results);
                }
            }

            if (results.GetAllMatchingDependencies(method.ReturnType.FullName).Any())
            {
                results.AddToFound(type, method.ReturnType.FullName);
            }

            // Check for any generic parameters
            if (method.ContainsGenericParameter)
            {
                CheckParameters(type, method.GenericParameters, ref results);
            }

            if (method.HasParameters)
            {
                CheckParameters(type, method.Parameters.Select(x => x.ParameterType), ref results);
            }

            // Check the contents of the method body
            CheckMethodBody(type, method, ref results);
        }
예제 #14
0
 /// <summary>
 /// Finds matching dependencies for a set of generic parameters
 /// </summary>
 private static void CheckGenericParameters(TypeDefinition type, IEnumerable <GenericParameter> parameters, ref SearchDefinition results)
 {
     foreach (var generic in parameters)
     {
         if (results.SearchList.Any(m => generic.FullName.StartsWith(m)))
         {
             results.AddToFound(type, generic.FullName);
         }
     }
 }
예제 #15
0
 /// <summary>
 /// Finds matching dependencies for a set of generic or not parameters
 /// </summary>
 private void CheckParameters(TypeDefinition type, IEnumerable <TypeReference> parameters, ref SearchDefinition results)
 {
     foreach (var parameter in parameters)
     {
         if (IsTypeGeneric(parameter.FullName))
         {
             var types   = ExtractTypeNames(parameter.FullName);
             var matches = results.GetAllDependenciesMatchingAnyOf(types);
             foreach (var item in matches)
             {
                 results.AddToFound(type, item);
             }
         }
         else
         {
             if (results.GetAllMatchingDependencies(parameter.FullName).Any())
             {
                 results.AddToFound(type, parameter.FullName);
             }
         }
     }
 }
예제 #16
0
 /// <summary>
 /// Finds matching dependencies for a set of generic parameters
 /// </summary>
 private static void CheckGenericParameters(TypeDefinition type, IEnumerable <GenericParameter> parameters, ref SearchDefinition results)
 {
     foreach (var generic in parameters)
     {
         if (results.GetAllMatchingDependencies(generic.FullName).Any())
         {
             results.AddToFound(type, generic.FullName);
         }
     }
 }
예제 #17
0
 private void CheckParameters(TypeDefinition type, IEnumerable <ParameterDefinition> parameters, ref SearchDefinition results)
 {
     foreach (var parameter in parameters)
     {
         string fullName = parameter.ParameterType?.FullName ?? String.Empty;
         if (results.GetAllMatchingDependencies(fullName).Any())
         {
             results.AddToFound(type, fullName);
         }
     }
 }