Exemple #1
0
        /// <summary>
        /// Mark all eachable items in argument as such.
        /// </summary>
        private static void Walk(ReachableContext context, ClassFile classFile)
        {
            // Mark owner
            classFile.DeclaringClass.MarkReachable(context);

            // Mark base class
            classFile.SuperClass.MarkReachable(context);

            // Mark interfaces
            if (classFile.Interfaces != null)
            {
                foreach (var intf in classFile.Interfaces)
                {
                    intf.MarkReachable(context);
                }
            }

            // Mark class ctor
            classFile.Methods.FirstOrDefault(x => x.Name == "<clinit>").MarkReachable(context);

            // Mark methods of imported classes reachable
            if (classFile.IsCreatedByLoader)
            {
                classFile.Methods.Where(x => x.IsPublic || x.IsProtected).ForEach(x => x.MarkReachable(context));
            }

            // If this is a class that does not have an imported C# wrapper, be safe and include everything from this class.
            if (!context.HasDexImport(classFile))
            {
                context.MarkAsRoot(classFile);
            }

            // Record in context
            context.RecordReachableType(classFile);
        }
Exemple #2
0
 /// <summary>
 /// Create a type builder for the given type with JavaImport attribute.
 /// </summary>
 internal static IClassBuilder CreateJavaImportBuilder(ReachableContext context, AssemblyCompiler compiler, TypeDefinition typeDef)
 {
     var javaImportAttr = typeDef.GetJavaImportAttribute(true);
     var className = (string)javaImportAttr.ConstructorArguments[0].Value;
     ClassFile classFile;
     if (!compiler.ClassLoader.TryLoadClass(className, out classFile))
         throw new ClassNotFoundException(className);
     context.RecordReachableType(classFile);
     return new SkipClassBuilder();
 }
Exemple #3
0
        /// <summary>
        /// Create a type builder for the given type with JavaImport attribute.
        /// </summary>
        internal static IClassBuilder CreateJavaImportBuilder(ReachableContext context, AssemblyCompiler compiler, TypeDefinition typeDef)
        {
            var       javaImportAttr = typeDef.GetJavaImportAttribute(true);
            var       className      = (string)javaImportAttr.ConstructorArguments[0].Value;
            ClassFile classFile;

            if (!compiler.ClassLoader.TryLoadClass(className, out classFile))
            {
                throw new ClassNotFoundException(className);
            }
            context.RecordReachableType(classFile);
            return(new SkipClassBuilder());
        }
Exemple #4
0
        /// <summary>
        /// Mark all base types and externally visible members reachable
        /// </summary>
        private static void Walk(ReachableContext context, TypeReference type)
        {
            // Generic parameters
            Walk(context, (IGenericParameterProvider)type);

            TypeDefinition typeDef;
            TypeSpecification typeSpec;
            GenericParameter genericParam;
            if ((typeDef = type as TypeDefinition) != null)
            {
                var isUsedInSerialization = typeDef.IsUsedInSerialization && !type.IsPrimitive && !typeDef.IsEnum 
                                            && !type.Namespace.StartsWith("System");

                // Mark base type reachable
                typeDef.BaseType.MarkReachable(context, isUsedInSerialization);

                // Mark declaring type reachable
                typeDef.DeclaringType.MarkReachable(context);

                // Mark implemented interfaces reachable
                if (typeDef.HasInterfaces)
                {
                    foreach (var intf in typeDef.Interfaces.Select(x => x.Interface))
                    {
                        intf.MarkReachable(context);
                    }
                }

                // If this is an attribute, include related types
                if (typeDef.IsAttribute())
                {
                    GetDot42InternalType(context, "IAttribute").MarkReachable(context);
                    GetDot42InternalType(context, "IAttributes").MarkReachable(context);
                }
                else if (typeDef.IsEnum)
                {
                    var boxingType = GetDot42InternalType(context, "Boxing");
                    boxingType.Methods.Where(x => (x.Name == "UnboxInteger" || x.Name == "UnboxLong")).ForEach(x => x.MarkReachable(context));
                }

                // Default & class ctor
                typeDef.FindDefaultCtor().MarkReachable(context);
                typeDef.GetClassCtor().MarkReachable(context);

                // Visit externally visible members
                if (typeDef.HasEvents)
                {
                    foreach (var evt in typeDef.Events)
                    {
                        if ((!evt.IsReachable) && context.Include(evt))
                        {
                            evt.MarkReachable(context); 
                        }
                    }
                }
                if (typeDef.HasFields)
                {
                    foreach (var field in typeDef.Fields)
                    {
                        // only public fields, so we don't pull any compiler generated stuff.
                        var isSerializable = isUsedInSerialization && !field.IsStatic && field.IsPublic;

                        if ((!field.IsReachable && context.Include(field)) || (!field.IsUsedInSerialization && isSerializable))
                        {                                                               
                            field.MarkReachable(context, isUsedInSerialization); 
                        }
                    }
                }
                if (typeDef.HasMethods)
                {
                    foreach (var method in typeDef.Methods)
                    {
                        if ((!method.IsReachable) && context.Include(method))
                        {
                            method.MarkReachable(context); 
                        }
                    }
                }
                if (typeDef.HasProperties)
                {
                    foreach (var prop in typeDef.Properties)
                    {
                        var isSerializable = isUsedInSerialization && prop.HasThis;
                        if ((!prop.IsReachable && context.Include(prop) || (!prop.IsUsedInSerialization && isSerializable)))
                        {
                            prop.MarkReachable(context, isUsedInSerialization); 
                        }
                    }
                }

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

                // Walk imported java classes
                CustomAttribute javaImportAttr;
                if ((javaImportAttr = typeDef.GetJavaImportAttribute()) != null)
                {
                    var javaClassName = (string)javaImportAttr.ConstructorArguments[0].Value;
                    ClassFile javaClass;
                    if (context.TryLoadClass(javaClassName, out javaClass))
                    {
                        javaClass.MarkReachable(context);
                    }
                }

                // Dex imported interfaces should have all their methods marked reachable.
                if (typeDef.IsInterface && typeDef.HasDexImportAttribute())
                {
                    typeDef.Methods.ForEach(x => x.MarkReachable(context));
                }

                // Record in context 
                context.RecordReachableType(typeDef);
            }
            else if ((typeSpec = type as TypeSpecification) != null)
            {
                // Element
                typeSpec.ElementType.MarkReachable(context, typeSpec.IsUsedInSerialization);

                // Generic instance
                GenericInstanceType git;
                FunctionPointerType fpt;
                RequiredModifierType reqModType;
                OptionalModifierType optModType;
                if ((git = typeSpec as GenericInstanceType) != null)
                {
                    if (git.ElementType.IsNullableT())
                    {
                        var typeofT = git.GenericArguments[0].Resolve(context);
                        if (typeofT != null && !typeofT.UsedInNullableT)
                        {
                            typeofT.UsedInNullableT = true;
                            DLog.Debug(DContext.CompilerAssemblyResolver, "found System.Nullable<{0}>", typeofT.FullName);
                        }
                    }
                    Walk(context, (IGenericInstance)git);
                }
                else if ((fpt = typeSpec as FunctionPointerType) != null)
                {
                    Walk(context, fpt.ReturnType);
                }
                else if ((reqModType = typeSpec as RequiredModifierType) != null)
                {
                    reqModType.ModifierType.MarkReachable(context);
                }
                else if ((optModType = typeSpec as OptionalModifierType) != null)
                {
                    optModType.ModifierType.MarkReachable(context);
                }
            }
            else if ((genericParam = type as GenericParameter) != null)
            {
                genericParam.IsSerializedParameter = genericParam.HasSerializedParameterAttribute();

                // Owner
                var owner = (MemberReference)genericParam.Owner;
                owner.MarkReachable(context);

                // Constraints
                if (genericParam.HasConstraints)
                {
                    foreach (TypeReference constraint in genericParam.Constraints)
                    {
                        constraint.MarkReachable(context);
                    }
                }
            }
            else
            {
                // Try to resolve
                type.Resolve(context).MarkReachable(context, type.IsUsedInSerialization);
            }
        }
Exemple #5
0
        /// <summary>
        /// Mark all base types and externally visible members reachable
        /// </summary>
        private static void Walk(ReachableContext context, TypeReference type)
        {
            // Generic parameters
            Walk(context, (IGenericParameterProvider)type);

            TypeDefinition typeDef;
            TypeSpecification typeSpec;
            GenericParameter genericParam;
            if ((typeDef = type as TypeDefinition) != null)
            {
                // Mark base type reachable
                typeDef.BaseType.MarkReachable(context);

                // Mark declaring type reachable
                typeDef.DeclaringType.MarkReachable(context);

                // Mark implemented interfaces reachable
                if (typeDef.HasInterfaces)
                {
                    foreach (var intf in typeDef.Interfaces.Select(x => x.Interface))
                    {
                        intf.MarkReachable(context);
                    }
                }

                // If is an an attribute include related types
                if (typeDef.IsAttribute())
                {
                    GetDot42InternalType(context, "IAttribute").MarkReachable(context);
                    GetDot42InternalType(context, "IAttributes").MarkReachable(context);
                    GetDot42InternalType(context, "IAnnotationType").MarkReachable(context);
                }
                else if (typeDef.IsEnum)
                {
                    var boxingType = GetDot42InternalType(context, "Boxing");
                    boxingType.Methods.Where(x => (x.Name == "UnboxInteger" || x.Name == "UnboxLong")).ForEach(x => x.MarkReachable(context));
                }

                // Default & class ctor
                typeDef.FindDefaultCtor().MarkReachable(context);
                typeDef.GetClassCtor().MarkReachable(context);

                // Visit externally visible members
                if (typeDef.HasEvents)
                {
                    foreach (var evt in typeDef.Events)
                    {
                        if ((!evt.IsReachable) && context.Include(evt))
                        {
                            evt.MarkReachable(context); 
                        }
                    }
                }
                if (typeDef.HasFields)
                {
                    foreach (var field in typeDef.Fields)
                    {
                        if ((!field.IsReachable) && context.Include(field))
                        {
                            field.MarkReachable(context); 
                        }
                    }
                }
                if (typeDef.HasMethods)
                {
                    foreach (var method in typeDef.Methods)
                    {
                        if ((!method.IsReachable) && context.Include(method))
                        {
                            method.MarkReachable(context); 
                        }
                    }
                }
                if (typeDef.HasProperties)
                {
                    foreach (var prop in typeDef.Properties)
                    {
                        if ((!prop.IsReachable) && context.Include(prop))
                        {
                            prop.MarkReachable(context); 
                        }
                    }
                }

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

                // Walk imported java classes
                CustomAttribute javaImportAttr;
                if ((javaImportAttr = typeDef.GetJavaImportAttribute()) != null)
                {
                    var javaClassName = (string)javaImportAttr.ConstructorArguments[0].Value;
                    ClassFile javaClass;
                    if (context.TryLoadClass(javaClassName, out javaClass))
                    {
                        javaClass.MarkReachable(context);
                    }
                }

                // Dex imported interfaces should have all their methods marked reachable.
                if (typeDef.IsInterface && typeDef.HasDexImportAttribute())
                {
                    typeDef.Methods.ForEach(x => x.MarkReachable(context));
                }

                // Record in context and create class builder
                context.RecordReachableType(typeDef);
            }
            else if ((typeSpec = type as TypeSpecification) != null)
            {
                // Element
                typeSpec.ElementType.MarkReachable(context);

                // Generic instance
                GenericInstanceType git;
                FunctionPointerType fpt;
                RequiredModifierType reqModType;
                OptionalModifierType optModType;
                if ((git = typeSpec as GenericInstanceType) != null)
                {
                    if (git.ElementType.IsNullableT())
                    {
                        var typeofT = git.GenericArguments[0].Resolve(context);
                        if (typeofT != null)
                        {
                            typeofT.UsedInNullableT = true;
                        }
                    }
                    Walk(context, (IGenericInstance)git);
                }
                else if ((fpt = typeSpec as FunctionPointerType) != null)
                {
                    Walk(context, fpt.ReturnType);
                }
                else if ((reqModType = typeSpec as RequiredModifierType) != null)
                {
                    reqModType.ModifierType.MarkReachable(context);
                }
                else if ((optModType = typeSpec as OptionalModifierType) != null)
                {
                    optModType.ModifierType.MarkReachable(context);
                }
            }
            else if ((genericParam = type as GenericParameter) != null)
            {
                // Owner
                var owner = (MemberReference)genericParam.Owner;
                owner.MarkReachable(context);

                // Constraints
                if (genericParam.HasConstraints)
                {
                    foreach (TypeReference constraint in genericParam.Constraints)
                    {
                        constraint.MarkReachable(context);
                    }
                }
            }
            else
            {
                // Try to resolve
                type.Resolve(context).MarkReachable(context);
            }
        }
Exemple #6
0
        /// <summary>
        /// Mark all eachable items in argument as such.
        /// </summary>
        private static void Walk(ReachableContext context, ClassFile classFile)
        {
            // Mark owner
            classFile.DeclaringClass.MarkReachable(context);

            // Mark base class
            classFile.SuperClass.MarkReachable(context);

            // Mark interfaces
            if (classFile.Interfaces != null)
            {
                foreach (var intf in classFile.Interfaces)
                {
                    intf.MarkReachable(context);
                }
            }

            // Mark class ctor
            classFile.Methods.FirstOrDefault(x => x.Name == "<clinit>").MarkReachable(context);

            // Mark methods of imported classes reachable
            if (classFile.IsCreatedByLoader)
            {
                classFile.Methods.Where(x => x.IsPublic || x.IsProtected).ForEach(x => x.MarkReachable(context));
            }

            // If this is a class that does not have an imported C# wrapper, be safe and include everything from this class.
            if (!context.HasDexImport(classFile))
            {
                context.MarkAsRoot(classFile);
            }

            // Record in context
            context.RecordReachableType(classFile);
        }
Exemple #7
0
        /// <summary>
        /// Mark all base types and externally visible members reachable
        /// </summary>
        private static void Walk(ReachableContext context, TypeReference type)
        {
            // Generic parameters
            Walk(context, (IGenericParameterProvider)type);

            TypeDefinition    typeDef;
            TypeSpecification typeSpec;
            GenericParameter  genericParam;

            if ((typeDef = type as TypeDefinition) != null)
            {
                // Mark base type reachable
                typeDef.BaseType.MarkReachable(context);

                // Mark declaring type reachable
                typeDef.DeclaringType.MarkReachable(context);

                // Mark implemented interfaces reachable
                if (typeDef.HasInterfaces)
                {
                    foreach (var intf in typeDef.Interfaces.Select(x => x.Interface))
                    {
                        intf.MarkReachable(context);
                    }
                }

                // If is an an attribute include related types
                if (typeDef.IsAttribute())
                {
                    GetDot42InternalType(context, "IAttribute").MarkReachable(context);
                    GetDot42InternalType(context, "IAttributes").MarkReachable(context);
                    GetDot42InternalType(context, "IAnnotationType").MarkReachable(context);
                }
                else if (typeDef.IsEnum)
                {
                    var boxingType = GetDot42InternalType(context, "Boxing");
                    boxingType.Methods.Where(x => (x.Name == "UnboxInteger" || x.Name == "UnboxLong")).ForEach(x => x.MarkReachable(context));
                }

                // Default & class ctor
                typeDef.FindDefaultCtor().MarkReachable(context);
                typeDef.GetClassCtor().MarkReachable(context);

                // Visit externally visible members
                if (typeDef.HasEvents)
                {
                    foreach (var evt in typeDef.Events)
                    {
                        if ((!evt.IsReachable) && context.Include(evt))
                        {
                            evt.MarkReachable(context);
                        }
                    }
                }
                if (typeDef.HasFields)
                {
                    foreach (var field in typeDef.Fields)
                    {
                        if ((!field.IsReachable) && context.Include(field))
                        {
                            field.MarkReachable(context);
                        }
                    }
                }
                if (typeDef.HasMethods)
                {
                    foreach (var method in typeDef.Methods)
                    {
                        if ((!method.IsReachable) && context.Include(method))
                        {
                            method.MarkReachable(context);
                        }
                    }
                }
                if (typeDef.HasProperties)
                {
                    foreach (var prop in typeDef.Properties)
                    {
                        if ((!prop.IsReachable) && context.Include(prop))
                        {
                            prop.MarkReachable(context);
                        }
                    }
                }

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

                // Walk imported java classes
                CustomAttribute javaImportAttr;
                if ((javaImportAttr = typeDef.GetJavaImportAttribute()) != null)
                {
                    var       javaClassName = (string)javaImportAttr.ConstructorArguments[0].Value;
                    ClassFile javaClass;
                    if (context.TryLoadClass(javaClassName, out javaClass))
                    {
                        javaClass.MarkReachable(context);
                    }
                }

                // Dex imported interfaces should have all their methods marked reachable.
                if (typeDef.IsInterface && typeDef.HasDexImportAttribute())
                {
                    typeDef.Methods.ForEach(x => x.MarkReachable(context));
                }

                // Record in context and create class builder
                context.RecordReachableType(typeDef);
            }
            else if ((typeSpec = type as TypeSpecification) != null)
            {
                // Element
                typeSpec.ElementType.MarkReachable(context);

                // Generic instance
                GenericInstanceType  git;
                FunctionPointerType  fpt;
                RequiredModifierType reqModType;
                OptionalModifierType optModType;
                if ((git = typeSpec as GenericInstanceType) != null)
                {
                    if (git.ElementType.IsNullableT())
                    {
                        var typeofT = git.GenericArguments[0].Resolve(context);
                        if (typeofT != null)
                        {
                            typeofT.UsedInNullableT = true;
                        }
                    }
                    Walk(context, (IGenericInstance)git);
                }
                else if ((fpt = typeSpec as FunctionPointerType) != null)
                {
                    Walk(context, fpt.ReturnType);
                }
                else if ((reqModType = typeSpec as RequiredModifierType) != null)
                {
                    reqModType.ModifierType.MarkReachable(context);
                }
                else if ((optModType = typeSpec as OptionalModifierType) != null)
                {
                    optModType.ModifierType.MarkReachable(context);
                }
            }
            else if ((genericParam = type as GenericParameter) != null)
            {
                // Owner
                var owner = (MemberReference)genericParam.Owner;
                owner.MarkReachable(context);

                // Constraints
                if (genericParam.HasConstraints)
                {
                    foreach (TypeReference constraint in genericParam.Constraints)
                    {
                        constraint.MarkReachable(context);
                    }
                }
            }
            else
            {
                // Try to resolve
                type.Resolve(context).MarkReachable(context);
            }
        }
Exemple #8
0
        /// <summary>
        /// Mark all base types and externally visible members reachable
        /// </summary>
        private static void Walk(ReachableContext context, TypeReference type)
        {
            // Generic parameters
            Walk(context, (IGenericParameterProvider)type);

            TypeDefinition    typeDef;
            TypeSpecification typeSpec;
            GenericParameter  genericParam;

            if ((typeDef = type as TypeDefinition) != null)
            {
                var isUsedInSerialization = typeDef.IsUsedInSerialization && !type.IsPrimitive && !typeDef.IsEnum &&
                                            !type.Namespace.StartsWith("System");

                // Mark base type reachable
                typeDef.BaseType.MarkReachable(context, isUsedInSerialization);

                // Mark declaring type reachable
                typeDef.DeclaringType.MarkReachable(context);

                // Mark implemented interfaces reachable
                if (typeDef.HasInterfaces)
                {
                    foreach (var intf in typeDef.Interfaces.Select(x => x.InterfaceType))
                    {
                        intf.MarkReachable(context);
                    }
                }

                // If this is an attribute, include related types
                if (typeDef.IsAttribute())
                {
                    GetDot42InternalType(context, "IAttribute").MarkReachable(context);
                    GetDot42InternalType(context, "IAttributes").MarkReachable(context);
                }
                else if (typeDef.IsEnum)
                {
                    var boxingType = GetDot42InternalType(context, "Boxing");
                    boxingType.Methods.Where(x => (x.Name == "UnboxInteger" || x.Name == "UnboxLong")).ForEach(x => x.MarkReachable(context));
                }

                // Default & class ctor
                typeDef.FindDefaultCtor().MarkReachable(context);
                typeDef.GetClassCtor().MarkReachable(context);

                // Visit externally visible members
                if (typeDef.HasEvents)
                {
                    foreach (var evt in typeDef.Events)
                    {
                        if ((!evt.IsReachable) && context.Include(evt))
                        {
                            evt.MarkReachable(context);
                        }
                    }
                }
                if (typeDef.HasFields)
                {
                    foreach (var field in typeDef.Fields)
                    {
                        // only public fields, so we don't pull any compiler generated stuff.
                        var isSerializable = isUsedInSerialization && !field.IsStatic && field.IsPublic;

                        if ((!field.IsReachable && context.Include(field)) || (!field.IsUsedInSerialization && isSerializable))
                        {
                            field.MarkReachable(context, isUsedInSerialization);
                        }
                    }
                }
                if (typeDef.HasMethods)
                {
                    foreach (var method in typeDef.Methods)
                    {
                        if ((!method.IsReachable) && context.Include(method))
                        {
                            method.MarkReachable(context);
                        }
                    }
                }
                if (typeDef.HasProperties)
                {
                    foreach (var prop in typeDef.Properties)
                    {
                        var isSerializable = isUsedInSerialization && prop.HasThis;
                        if ((!prop.IsReachable && context.Include(prop) || (!prop.IsUsedInSerialization && isSerializable)))
                        {
                            prop.MarkReachable(context, isUsedInSerialization);
                        }
                    }
                }

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

                // Walk imported java classes
                CustomAttribute javaImportAttr;
                if ((javaImportAttr = typeDef.GetJavaImportAttribute()) != null)
                {
                    var       javaClassName = (string)javaImportAttr.ConstructorArguments[0].Value;
                    ClassFile javaClass;
                    if (context.TryLoadClass(javaClassName, out javaClass))
                    {
                        javaClass.MarkReachable(context);
                    }
                }

                // Dex imported interfaces should have all their methods marked reachable.
                if (typeDef.IsInterface && typeDef.HasDexImportAttribute())
                {
                    typeDef.Methods.ForEach(x => x.MarkReachable(context));
                }

                // Record in context
                context.RecordReachableType(typeDef);
            }
            else if ((typeSpec = type as TypeSpecification) != null)
            {
                // Element
                typeSpec.ElementType.MarkReachable(context, typeSpec.IsUsedInSerialization);

                // Generic instance
                GenericInstanceType  git;
                FunctionPointerType  fpt;
                RequiredModifierType reqModType;
                OptionalModifierType optModType;
                if ((git = typeSpec as GenericInstanceType) != null)
                {
                    if (git.ElementType.IsNullableT())
                    {
                        var typeofT = git.GenericArguments[0].Resolve(context);
                        if (typeofT != null && !typeofT.UsedInNullableT)
                        {
                            typeofT.UsedInNullableT = true;
                            DLog.Debug(DContext.CompilerAssemblyResolver, "found System.Nullable<{0}>", typeofT.FullName);
                        }
                    }
                    Walk(context, (IGenericInstance)git);
                }
                else if ((fpt = typeSpec as FunctionPointerType) != null)
                {
                    Walk(context, fpt.ReturnType);
                }
                else if ((reqModType = typeSpec as RequiredModifierType) != null)
                {
                    reqModType.ModifierType.MarkReachable(context);
                }
                else if ((optModType = typeSpec as OptionalModifierType) != null)
                {
                    optModType.ModifierType.MarkReachable(context);
                }
            }
            else if ((genericParam = type as GenericParameter) != null)
            {
                genericParam.IsSerializedParameter = genericParam.HasSerializedParameterAttribute();

                // Owner
                var owner = (MemberReference)genericParam.Owner;
                owner.MarkReachable(context);

                // Constraints
                if (genericParam.HasConstraints)
                {
                    foreach (TypeReference constraint in genericParam.Constraints)
                    {
                        constraint.MarkReachable(context);
                    }
                }
            }
            else
            {
                // Try to resolve
                type.Resolve(context).MarkReachable(context, type.IsUsedInSerialization);
            }
        }