Пример #1
0
 /// <summary>
 /// Mark all properties with the given name reachable.
 /// </summary>
 internal static void MarkPropertiesReachable(this TypeReference type, string propertyName, ReachableContext context)
 {
     while ((type != null) && (context.Contains(type)))
     {
         TypeDefinition typeDef = context.GetTypeDefinition(type);
         if (typeDef != null)
         {
             if (typeDef.HasProperties)
             {
                 foreach (PropertyDefinition prop in typeDef.Properties)
                 {
                     if (prop.Name == propertyName)
                     {
                         prop.MarkReachable(context);
                     }
                 }
             }
             type = typeDef.BaseType;
         }
         else
         {
             type = null;
         }
     }
 }
Пример #2
0
 /// <summary>
 /// Mark all properties with the given name reachable.
 /// </summary>
 internal static void MarkPropertiesReachable(this TypeReference type, string propertyName, ReachableContext context)
 {
     while ((type != null) && (context.Contains(type)))
     {
         TypeDefinition typeDef = context.GetTypeDefinition(type);
         if (typeDef != null)
         {
             if (typeDef.HasProperties)
             {
                 foreach (PropertyDefinition prop in typeDef.Properties)
                 {
                     if (prop.Name == propertyName)
                     {
                         prop.MarkReachable(context);
                     }
                 }
             }
             type = typeDef.BaseType;
         }
         else
         {
             type = null;
         }
     }
 }
Пример #3
0
 /// <summary>
 /// Mark all fields with the given name reachable.
 /// </summary>
 internal static void MarkFieldsReachable(this TypeReference type, string fieldName, ReachableContext context)
 {
     while ((type != null) && (context.Contains(type)))
     {
         TypeDefinition typeDef = context.GetTypeDefinition(type);
         if (typeDef != null)
         {
             if (typeDef.HasFields)
             {
                 foreach (FieldDefinition field in typeDef.Fields)
                 {
                     if (field.Name == fieldName)
                     {
                         field.MarkReachable(context);
                     }
                 }
             }
             type = typeDef.BaseType;
         }
         else
         {
             type = null;
         }
     }
 }
Пример #4
0
 /// <summary>
 /// Mark all fields with the given name reachable.
 /// </summary>
 internal static void MarkFieldsReachable(this TypeReference type, string fieldName, ReachableContext context)
 {
     while ((type != null) && (context.Contains(type)))
     {
         TypeDefinition typeDef = context.GetTypeDefinition(type);
         if (typeDef != null)
         {
             if (typeDef.HasFields)
             {
                 foreach (FieldDefinition field in typeDef.Fields)
                 {
                     if (field.Name == fieldName)
                     {
                         field.MarkReachable(context);
                     }
                 }
             }
             type = typeDef.BaseType;
         }
         else
         {
             type = null;
         }
     }
 }
Пример #5
0
        /// <summary>
        /// Mark all eachable items in argument as such.
        /// </summary>
        private static void Walk(ReachableContext context, MethodDefinition method)
        {
            method.DeclaringClass.MarkReachable(context);
            method.ReturnType.MarkReachable(context);

            // All parameters
            foreach (var param in method.Parameters)
            {
                param.MarkReachable(context);
            }

            // Base methods
            if (!method.IsStatic && !method.IsFinal)
            {
                MethodDefinition baseMethod;
                if ((baseMethod = method.GetBaseMethod()) != null)
                {
                    if (context.Contains(baseMethod.DeclaringClass))
                    {
                        baseMethod.MarkReachable(context);
                    }
                }
            }

            Walk(context, method.Body);
        }
Пример #6
0
        /// <summary>
        /// Resolve type reference into type defition.
        /// Generic instance types are resolved to their element type.
        /// </summary>
        internal static TypeDefinition Resolve(this TypeReference type, ReachableContext context)
        {
            if (context.Contains(type))
            {
                var typeDef = type as TypeDefinition;
                if (typeDef != null) { return typeDef; }

                var git = type as GenericInstanceType;
                if (git != null) { return git.ElementType.Resolve(context); }

                return context.GetTypeDefinition(type);
            }

            // Type not in project, don't care about it.
            return null;
        }
Пример #7
0
        /// <summary>
        /// Resolve type reference into type defition.
        /// Generic instance types are resolved to their element type.
        /// </summary>
        internal static TypeDefinition Resolve(this TypeReference type, ReachableContext context)
        {
            if (context.Contains(type))
            {
                var typeDef = type as TypeDefinition;
                if (typeDef != null)
                {
                    return(typeDef);
                }

                var git = type as GenericInstanceType;
                if (git != null)
                {
                    return(git.ElementType.Resolve(context));
                }

                return(context.GetTypeDefinition(type));
            }

            // Type not in project, don't care about it.
            return(null);
        }
Пример #8
0
        /// <summary>
        /// Mark all reachable items in argument as such.
        /// </summary>
        private static void Walk(ReachableContext context, MethodReference method)
        {
            method.ReturnType.MarkReachable(context);

            // All parameters
            if (method.HasParameters)
            {
                foreach (ParameterDefinition param in method.Parameters)
                {
                    Walk(context, (ParameterReference)param);
                }
            }

            // Generic parameters
            Walk(context, (IGenericParameterProvider)method);

            // Method definition?
            MethodDefinition methodDef;
            MethodSpecification methodSpec;
            if ((methodDef = method as MethodDefinition) != null)
            {
                // Code
                Walk(context, methodDef.Body);

                // Overrides
                foreach (MethodReference methodRef in methodDef.Overrides)
                {
                    methodRef.MarkReachable(context);
                }

                // Base methods
                if (methodDef.IsVirtual)
                {
                    MethodDefinition baseMethod;
                    if ((baseMethod = methodDef.GetBaseMethod()) != null)
                    {
                        if (context.Contains(baseMethod.DeclaringType))
                        {
                            baseMethod.MarkReachable(context);
                        }
                    }
                }

                // Custom attributes
                Walk(context, (ICustomAttributeProvider)methodDef);

                // Walk imported java classes
                CustomAttribute javaImportAttr;
                if ((javaImportAttr = methodDef.GetJavaImportAttribute()) != null)
                {
                    string className;
                    string memberName;
                    string descriptor;
                    javaImportAttr.GetDexOrJavaImportNames(methodDef, out memberName, out descriptor, out className);
                    ClassFile javaClass;
                    if (context.TryLoadClass(className, out javaClass))
                    {
                        var javaMethod = javaClass.Methods.FirstOrDefault(x => (x.Name == memberName) && (x.Descriptor == descriptor));
                        javaClass.MarkReachable(context);
                        javaMethod.MarkReachable(context);
                    }
                }

                // If this method is a property accessor, include the property also
                if (methodDef.SemanticsAttributes.HasFlag(MethodSemanticsAttributes.Getter))
                {
                    var prop = methodDef.DeclaringType.Properties.FirstOrDefault(x => x.GetMethod == methodDef);
                    prop.MarkReachable(context);
                }
                if (methodDef.SemanticsAttributes.HasFlag(MethodSemanticsAttributes.Setter))
                {
                    var prop = methodDef.DeclaringType.Properties.FirstOrDefault(x => x.SetMethod == methodDef);
                    prop.MarkReachable(context);
                }
            }
            else if ((methodSpec = method as MethodSpecification) != null)
            {
                // Method
                var elementRef = methodSpec.ElementMethod;
                elementRef.MarkReachable(context);

                // Generic arguments
                var gim = methodSpec as GenericInstanceMethod;
                if (gim != null)
                {
                    var elementDef = elementRef.Resolve();

                    for (int i = 0; i < gim.GenericArguments.Count; ++i)
                    {
                        bool isSerialized = elementDef.GenericParameters[i].IsSerializedParameter;
                        gim.GenericArguments[i].MarkReachable(context, isSerialized);
                    }
                }
            }
            else
            {
                // Try to resolve
                method.Resolve(context).MarkReachable(context);
            }
        }
Пример #9
0
        /// <summary>
        /// Mark all eachable items in argument as such.
        /// </summary>
        private static void Walk(ReachableContext context, MethodDefinition method)
        {
            method.DeclaringClass.MarkReachable(context);
            method.ReturnType.MarkReachable(context);

            // All parameters
            foreach (var param in method.Parameters)
            {
                param.MarkReachable(context);
            }

            // Base methods
            if (!method.IsStatic && !method.IsFinal)
            {
                MethodDefinition baseMethod;
                if ((baseMethod = method.GetBaseMethod()) != null)
                {
                    if (context.Contains(baseMethod.DeclaringClass))
                    {
                        baseMethod.MarkReachable(context);
                    }
                }
            }

            Walk(context, method.Body);
        }
Пример #10
0
        /// <summary>
        /// Mark all eachable items in argument as such.
        /// </summary>
        private static void Walk(ReachableContext context, MethodReference method)
        {
            method.ReturnType.MarkReachable(context);

            // All parameters
            if (method.HasParameters)
            {
                foreach (ParameterDefinition param in method.Parameters)
                {
                    Walk(context, (ParameterReference)param);
                }
            }

            // Generic parameters
            Walk(context, (IGenericParameterProvider)method);

            // Method definition?
            MethodDefinition    methodDef;
            MethodSpecification methodSpec;

            if ((methodDef = method as MethodDefinition) != null)
            {
                // Code
                Walk(context, methodDef.Body);

                // Overrides
                foreach (MethodReference methodRef in methodDef.Overrides)
                {
                    methodRef.MarkReachable(context);
                }

                // Base methods
                if (methodDef.IsVirtual)
                {
                    MethodDefinition baseMethod;
                    if ((baseMethod = methodDef.GetBaseMethod()) != null)
                    {
                        if (context.Contains(baseMethod.DeclaringType))
                        {
                            baseMethod.MarkReachable(context);
                        }
                    }
                }

                // Custom attributes
                Walk(context, (ICustomAttributeProvider)methodDef);

                // Walk imported java classes
                CustomAttribute javaImportAttr;
                if ((javaImportAttr = methodDef.GetJavaImportAttribute()) != null)
                {
                    string className;
                    string memberName;
                    string descriptor;
                    javaImportAttr.GetDexOrJavaImportNames(methodDef, out memberName, out descriptor, out className);
                    ClassFile javaClass;
                    if (context.TryLoadClass(className, out javaClass))
                    {
                        var javaMethod = javaClass.Methods.FirstOrDefault(x => (x.Name == memberName) && (x.Descriptor == descriptor));
                        javaClass.MarkReachable(context);
                        javaMethod.MarkReachable(context);
                    }
                }

                // If this method is a property accessor, include the property also
                if (methodDef.SemanticsAttributes.HasFlag(MethodSemanticsAttributes.Getter))
                {
                    var prop = methodDef.DeclaringType.Properties.FirstOrDefault(x => x.GetMethod == methodDef);
                    prop.MarkReachable(context);
                }
                if (methodDef.SemanticsAttributes.HasFlag(MethodSemanticsAttributes.Setter))
                {
                    var prop = methodDef.DeclaringType.Properties.FirstOrDefault(x => x.SetMethod == methodDef);
                    prop.MarkReachable(context);
                }
            }
            else if ((methodSpec = method as MethodSpecification) != null)
            {
                // Method
                methodSpec.ElementMethod.MarkReachable(context);

                // Generic arguments
                var gim = methodSpec as GenericInstanceMethod;
                if (gim != null)
                {
                    Walk(context, (IGenericInstance)gim);
                }
            }
            else
            {
                // Try to resolve
                method.Resolve(context).MarkReachable(context);
            }
        }