Пример #1
0
        /// <summary>
        /// Check if parent type if abstract and get abstract methods that would have not been implemented if it is the case
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        private HashSet <string> GetAbstractMethodsThatWouldntBeImlemented(TypeDefinition type)
        {
            HashSet <string> res = new HashSet <string>();

            if (type.BaseType != null)
            {
                AddUsing(type.BaseType.Namespace);
                TypeDefinition baseType = AnalysisUtils.GetTypeDefinitionFromTypeReference(type.BaseType, _modules);
                if (baseType != null)
                {
                    if (baseType.IsAbstract)
                    {
                        if (baseType.HasMethods)
                        {
                            foreach (MethodDefinition method in baseType.Methods)
                            {
                                if (AnalysisUtils.IsMethodAbstract(method))
                                {
                                    if (MethodAnalyzer.IsMethodUnsupported(method) ||
                                        analyzeHelpher._coreSupportedMethods.Contains(baseType.Namespace, baseType.Name, method.Name) ||
                                        analyzeHelpher.IsMethodSupported(method))
                                    {
                                        res.Add(method.Name);
                                    }
                                }
                            }
                        }
                        res.UnionWith(GetAbstractMethodsThatWouldntBeImlemented(baseType));
                    }
                }
            }
            return(res);
        }
Пример #2
0
        private bool TryGetConstructor(TypeReference type, out MethodDefinition constructor, bool returnConstructorIfAbstractType = false)
        {
            if (!returnConstructorIfAbstractType)
            {
                TypeDefinition td = AnalysisUtils.GetTypeDefinitionFromTypeReference(type, _modules);
                if (td == null || AnalysisUtils.IsTypeAbstract(td))
                {
                    constructor = null;
                    return(false);
                }
            }
            HashSet <MethodDefinition> constructors;

            if (TryGetConstructors(type, out constructors))
            {
                constructor = ConvertConstructorToGenericInstanceMethod(GetConstructorWithMinimumParameters(constructors), type);
                return(true);
            }
            // we should never be in this situation
            else
            {
                constructor = null;
                return(false);
            }
        }
Пример #3
0
        /// <summary>
        /// Resolve inheritance issues
        /// </summary>
        /// <param name="assemblyName"></param>
        /// <param name="typeName"></param>
        /// <param name="methodName"></param>
        /// <returns></returns>
        private MethodInfo GetMethodInfoResolvingInheritance(string assemblyName, string typeName, string methodName)
        {
            TypeDefinition currentType   = null;
            int            i             = 0;
            bool           keepSearching = true;

            while (i < _modules.Count && keepSearching)
            {
                ModuleDefinition module = _modules[i];
                if (module.Name.Replace(".dll", "") == assemblyName)
                {
                    if (module.HasTypes)
                    {
                        int j = 0;
                        while (j < module.Types.Count && keepSearching)
                        {
                            TypeDefinition type = module.Types[j];
                            if (type.Name == typeName)
                            {
                                currentType   = type;
                                keepSearching = false;
                            }
                            j++;
                        }
                    }
                    keepSearching = false;
                }
                i++;
            }
            while (currentType != null)
            {
                if (currentType.HasMethods)
                {
                    foreach (MethodDefinition method in currentType.Methods)
                    {
                        if (method.Name == methodName)
                        {
                            return(new MethodInfo(currentType.Scope.Name.Replace(".dll", ""), currentType.Name, methodName, true));
                        }
                    }
                }
                currentType = AnalysisUtils.GetTypeDefinitionFromTypeReference(currentType.BaseType, _modules);
            }
            return(new MethodInfo(assemblyName, typeName, methodName, true));
        }
Пример #4
0
        private bool PrepareForAdditionalType(TypeReference type, HashSet <string> methods)
        {
            var typeDef = AnalysisUtils.GetTypeDefinitionFromTypeReference(type, _modules);

            if (typeDef == null)
            {
                //we can't find the type.
                return(false);
            }
            bool isCoreSupported     = analyzeHelpher._coreSupportedMethods.ContainsType(type.Name, type.Namespace);
            bool isMscorlibSupported = analyzeHelpher.IsTypeSupported(type);

            if (isCoreSupported || isMscorlibSupported)
            {
                //type is already supported.
                return(false);
            }
            Set(typeDef, methods);
            return(true);
        }
        /// <summary>
        /// If the member is "override", this method returns the type where the
        /// corresponding "virtual" member is defined, otherwise it returns the
        /// member declaring type.
        /// </summary>
        public static TypeReference GetDeclaringTypeResolvingOverrides(MemberReference memberReference)
        {
            if (Cache.ContainsKey(memberReference))
            {
                return(Cache[memberReference]);
            }
            else
            {
                TypeReference declaringType = memberReference.DeclaringType;
                string        memberName    = memberReference.Name;

                if (memberReference is MethodReference)
                {
                    MethodReference  methodReference  = (MethodReference)memberReference;
                    MethodDefinition methodDefinition = null;
                    try
                    {
                        methodDefinition = methodReference.Resolve();
                    }
                    catch { }
                    if (methodDefinition != null)
                    {
                        if (AnalysisUtils.IsMethodOverride(methodDefinition))
                        {
                            TypeDefinition   typeDefinition = AnalysisUtils.GetTypeDefinitionFromTypeReference(declaringType, null);
                            MethodDefinition methodIsFirstDefinitionInParentType = AnalysisUtils.LookForMethodInParents(methodDefinition, typeDefinition);
                            if (methodIsFirstDefinitionInParentType != null)
                            {
                                return(methodIsFirstDefinitionInParentType.DeclaringType);
                            }
                        }
                    }
                }

                Cache.Add(memberReference, declaringType);

                return(declaringType);
            }
        }
Пример #6
0
        public void Run()
        {
            if (!_isInitialized)
            {
                throw new Exception("ClassAnalyzer must be initialized. Please call Init() first.");
            }

            if (CanWorkOnElement())
            {
                Stack <TypeDefinition> typesToAnalyze = new Stack <TypeDefinition>();
                // We don't directly analyze the selected type because we want to start with its "oldest" parent.
                // Sometimes, we have to update our set of unsupported methods, so we need to start with the oldest parent to make sure we don't forget to implement a method from an interface or an abstract class which has been added during the execution of the program.
                do
                {
                    typesToAnalyze.Push(Element);
                    Element = AnalysisUtils.GetTypeDefinitionFromTypeReference(Element.BaseType, _modules);
                }while (Element != null && (Element.FullName != "System.Object" || Element.FullName != "System.ValueType") && CanWorkOnElement(Element));
                while (typesToAnalyze.Count > 0)
                {
                    TypeDefinition   firstParent    = typesToAnalyze.Pop();
                    string           parentAssembly = firstParent.Scope.Name.Replace(".dll", "");
                    HashSet <string> unsupportedMethodsInParent;
                    if (_unsupportedMethods.ContainsKey(parentAssembly))
                    {
                        if (_unsupportedMethods[parentAssembly].TryGetValue(firstParent.Name, out unsupportedMethodsInParent))
                        {
                            Set(firstParent, unsupportedMethodsInParent);
                        }
                        else
                        {
                            Set(firstParent, new HashSet <string>());
                        }
                        Execute();
                    }
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Retrieve all methods that must be implemented because they are defined in an interface that the type implements.
        /// Needed because it's unlikely that every single method from an interface is called at least once in the analyzed assemblies.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        private HashSet <string> GetMethodsInheritedFromInterfaces(TypeDefinition type)
        {
            HashSet <string> res = new HashSet <string>();

            if (type.HasInterfaces)
            {
                foreach (InterfaceImplementation @interface in type.Interfaces)
                {
                    TypeDefinition interfaceTypeDefinition = AnalysisUtils.GetTypeDefinitionFromTypeReference(@interface.InterfaceType, _modules);
                    if (interfaceTypeDefinition != null)
                    {
                        string typeName = interfaceTypeDefinition.Name;
                        bool   isInterfaceTypeUnsupported = IsTypeGoingToBeImplemented(interfaceTypeDefinition);
                        string assemblyName = interfaceTypeDefinition.Scope.Name.Replace(".dll", "");
                        //interface is not used in client code, but can still be defined in Core/mscorlib
                        if (!isInterfaceTypeUnsupported)
                        {
                            if (interfaceTypeDefinition.HasMethods)
                            {
                                if (analyzeHelpher._coreSupportedMethods.ContainsType(interfaceTypeDefinition.Name, interfaceTypeDefinition.Namespace))
                                {
                                    _implementedInterfaces.Add(@interface.InterfaceType);
                                    AddUsing(interfaceTypeDefinition.Namespace);
                                    foreach (MethodDefinition method in interfaceTypeDefinition.Methods)
                                    {
                                        //Check if method is supported and implement it if it is
                                        if (analyzeHelpher._coreSupportedMethods.Contains(interfaceTypeDefinition.Namespace, interfaceTypeDefinition.Name, method.Name))
                                        {
                                            res.Add(method.Name);
                                        }
                                    }
                                }
                                else if (analyzeHelpher.IsTypeSupported(@interface.InterfaceType))
                                {
                                    _implementedInterfaces.Add(@interface.InterfaceType);
                                    AddUsing(interfaceTypeDefinition.Namespace);

                                    //isInterfaceRequired = true;
                                    _implementedInterfaces.Add(@interface.InterfaceType);
                                    foreach (MethodDefinition method in interfaceTypeDefinition.Methods)
                                    {
                                        //Check if method is supported and implement it if it is
                                        if (analyzeHelpher.IsMethodSupported(method))
                                        {
                                            res.Add(method.Name);
                                        }
                                    }
                                }
                                else
                                {
                                    if ((_outputOptions.OutputOnlyPublicAndProtectedMembers && (interfaceTypeDefinition.IsPublic || interfaceTypeDefinition.IsNestedPublic || interfaceTypeDefinition.IsNestedFamily)) ||
                                        (!_outputOptions.OutputOnlyPublicAndProtectedMembers))
                                    {
                                        _implementedInterfaces.Add(@interface.InterfaceType);
                                        AddUsing(interfaceTypeDefinition.Namespace);
                                        AddTypeToImplement(interfaceTypeDefinition);
                                    }
                                }
                            }
                        }
                        //interface is used in client code or needed because of inheritance
                        else
                        {
                            //isInterfaceRequired = true;
                            HashSet <string> methodsToImplements;
                            //Check if the interface is used in the client code
                            if (_unsupportedMethods.ContainsKey(assemblyName))
                            {
                                if (!_unsupportedMethods[assemblyName].TryGetValue(interfaceTypeDefinition.Name, out methodsToImplements))
                                {
                                    methodsToImplements = _additionalTypesToImplement[interfaceTypeDefinition];
                                }
                            }
                            else
                            {
                                methodsToImplements = _additionalTypesToImplement[interfaceTypeDefinition];
                            }
                            foreach (MethodDefinition method in interfaceTypeDefinition.Methods)
                            {
                                if (methodsToImplements.Contains(method.Name))
                                {
                                    res.Add(method.Name);
                                }
                            }
                            if ((_outputOptions.OutputOnlyPublicAndProtectedMembers && (interfaceTypeDefinition.IsPublic || interfaceTypeDefinition.IsNestedPublic || interfaceTypeDefinition.IsNestedFamily)) ||
                                (!_outputOptions.OutputOnlyPublicAndProtectedMembers))
                            {
                                _implementedInterfaces.Add(interfaceTypeDefinition);
                                AddUsing(interfaceTypeDefinition.Namespace);
                            }
                        }
                    }
                }
            }
            return(res);
        }
Пример #8
0
 private void GetCustomAttributes(HashSet <string> unsupportedMethodsInCurrentType)
 {
     if (Element.HasCustomAttributes)
     {
         foreach (CustomAttribute customAttribute in Element.CustomAttributes)
         {
             if (customAttribute.AttributeType.FullName == "System.Windows.Markup.ContentPropertyAttribute")
             {
                 if (customAttribute.HasConstructorArguments)
                 {
                     string propertyName = customAttribute.ConstructorArguments[0].Value.ToString();
                     // we need to add this property anyway because it can be used in the xaml without ever mentionned
                     // and it could also never be used in the c# code.
                     if (!unsupportedMethodsInCurrentType.Contains("get_" + propertyName) && !unsupportedMethodsInCurrentType.Contains("set_" + propertyName))
                     {
                         AddUsing(customAttribute.AttributeType.Namespace);
                         AddCustomAttribute(customAttribute, false); //false because not indexer
                     }
                 }
             }
             else if (customAttribute.AttributeType.FullName == "System.ComponentModel.TypeConverterAttribute")
             {
                 AddCustomAttribute(customAttribute, false);
                 AddUsing("System.Windows.Markup");
                 AddUsing("DotNetForHtml5.Core");
             }
             else if (customAttribute.AttributeType.FullName == "System.Reflection.DefaultMemberAttribute")
             {
                 if (customAttribute.HasConstructorArguments)
                 {
                     string propertyName = customAttribute.ConstructorArguments[0].Value.ToString();
                     if (propertyName == "Item")
                     {
                         AddCustomAttribute(customAttribute, true); // true because is indexer
                     }
                     // DefaultMemberAttribute is not supported at the moment
                     //else
                     //{
                     //    if (_unsupportedMethodsInCurrentType.Contains("get_" + propertyName) || _unsupportedMethodsInCurrentType.Contains("set_" + propertyName))
                     //    {
                     //        _parentClassAnalyzer.AddUsing(customAttribute.AttributeType.Namespace);
                     //        _parentClassAnalyzer.AddCustomAttribute("[DefaultMember(\"" + propertyName + "\")]");
                     //    }
                     //}
                 }
             }
         }
     }
     if (Element.HasInterfaces)
     {
         foreach (InterfaceImplementation @interface in Element.Interfaces)
         {
             TypeDefinition interfaceTypeDefinition = AnalysisUtils.GetTypeDefinitionFromTypeReference(@interface.InterfaceType, _modules);
             if (interfaceTypeDefinition != null)
             {
                 if (interfaceTypeDefinition.HasCustomAttributes)
                 {
                     foreach (CustomAttribute customAttribute in interfaceTypeDefinition.CustomAttributes)
                     {
                         if (customAttribute.AttributeType.FullName == "System.Reflection.DefaultMemberAttribute")
                         {
                             if (customAttribute.HasConstructorArguments)
                             {
                                 string propertyName = customAttribute.ConstructorArguments[0].Value.ToString();
                                 if (propertyName == "Item")
                                 {
                                     AddCustomAttribute(customAttribute, true);
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
 }