Esempio n. 1
0
        /// <summary>
        /// Fix the visibility of the method
        /// </summary>
        private void FixVisibility()
        {
            // Update visibility/netslot based on base method
            var baseMethod = method.Overrides.FirstOrDefault(x => !x.DeclaringType.IsInterface);

            if ((baseMethod != null) && !method.HasSameVisibility(baseMethod))
            {
                if (baseMethod.IsAbstract)
                {
                    // Limit the visibility to that of the base method
                    method.CopyVisibilityFrom(baseMethod);
                }
                else
                {
                    // Require a new
                    method.RequireNewSlot();
                }
            }

            // Make sure signature types have a high enough visibility
            method.EnsureVisibility();

            // Limit the methods visibility
            method.LimitVisibility();
        }
Esempio n. 2
0
        /// <summary>
        /// Add abstract method (that do not yet exist) for all interface methods.
        /// </summary>
        private void AddAbstractInterfaceMethods(NetTypeDefinition typeDef, TargetFramework target)
        {
            if ((typeDef.IsInterface) || (this is IInterfaceConstantsTypeBuilder))
            {
                return;
            }

            var typeMethods = typeDef.Methods.ToList();

            foreach (var iterator in typeDef.Interfaces)
            {
                // Collect all interface methods
                var iDef     = iterator;
                var iMethods = iDef.GetElementType().Methods.Select(x => Tuple.Create(iDef, x)).ToList();
                iMethods.AddRange(iDef.GetElementType().GetBaseTypes(true).Where(x => x.GetElementType().IsInterface).SelectMany(x => x.GetElementType().Methods.Select(m => Tuple.Create(x, m))));
                foreach (var pair in iMethods)
                {
                    var iMethod = pair.Item2;
                    if (typeMethods.Any(x => x.IsExactDuplicate(iMethod)))
                    {
                        continue;
                    }

                    // Add abstract method
                    var method = new NetMethodDefinition(iMethod.Name, null, typeDef, target, iMethod.SignConvertMode, "TypeBuilder.AddAbstractInterfaceMethods");
                    method.AccessFlags = iMethod.AccessFlags;
                    method.Attributes  = iMethod.Attributes;
                    method.IsAbstract  = false;
                    method.IsVirtual   = !typeDef.IsSealed;
                    method.GenericParameters.AddRange(iMethod.GenericParameters.Select(x => new NetGenericParameter(GetMethodGenericParameterName(typeDef, x.Name), x.Name, method)));
                    method.ReturnType = GenericParameters.Resolve(iMethod.ReturnType, typeDef, target.TypeNameMap);
                    method.Parameters.AddRange(iMethod.Parameters.Select(x => new NetParameterDefinition(x.Name, GenericParameters.Resolve(x.ParameterType, typeDef, target.TypeNameMap), x.IsParams)));

                    // Check if there are duplicates now that the generic parameters are resolved.
                    if (typeMethods.Any(x => x.IsExactDuplicate(method)))
                    {
                        continue;
                    }

                    // Should we ignore this one?
                    if (IgnoreInterfaceMethod(method, iMethod))
                    {
                        continue;
                    }

                    // Test if the method is a duplicate of an existing method, but with different return type
                    var differentAccessMask = !method.HasSameVisibility(iMethod);
                    if (differentAccessMask || typeMethods.Any(x => x.IsDuplicate(method)) ||
                        ImplementAsExplicitInterfaceMethod(method, iMethod) || typeDef.NestedTypes.Any(x => x.Name == method.Name))
                    {
                        // Method with different return type exists.
                        // Make it an explicit interface method
                        method.SetExplicitImplementation(iMethod, pair.Item1);
                        method.IsAbstract = false;
                        method.IsVirtual  = false;
                    }
                    else
                    {
                        // Check for override
                        //method.IsOverride = isOverride;
                        if (method.IsOverride && method.Overrides.All(x => !x.IsVirtual))
                        {
                            // No need to override anything
                            continue;
                        }
                    }

                    // Create DexImport attribute
                    var typeCa   = iMethod.DeclaringType.CustomAttributes.First(x => x.AttributeType == null);
                    var methodCa = iMethod.CustomAttributes.First(x => x.AttributeType == null);
                    var ca       = new NetCustomAttribute(null, typeCa.ConstructorArguments[0], methodCa.ConstructorArguments[0], methodCa.ConstructorArguments[1]);
                    ca.CopyPropertiesFrom(methodCa);
                    method.CustomAttributes.Add(ca);

                    typeDef.Methods.Add(method);
                    typeMethods.Add(method);

                    // Avoid name conflicts
                    var nested = typeDef.NestedTypes.FirstOrDefault(x => x.Name == method.Name);
                    if (nested != null)
                    {
                        nested.Name = "Java" + nested.Name;
                    }
                }
            }
        }