static IEnumerable <T> CreateAttributeInstance <T> (CustomAttributeData attribute, ICustomAttributeProvider provider) where T : System.Attribute
    {
        var convertedAttributes = ConvertOldAttributes(attribute);

        if (convertedAttributes.Any())
        {
            return(convertedAttributes.OfType <T> ());
        }

        var expectedType = ConvertType(typeof(T), provider);

        if (attribute.AttributeType != expectedType && !IsSubclassOf(expectedType, attribute.AttributeType))
        {
            return(Enumerable.Empty <T> ());
        }

        System.Type attribType = ConvertType(attribute.AttributeType, provider);

        var constructorArguments = new object [attribute.ConstructorArguments.Count];

        for (int i = 0; i < constructorArguments.Length; i++)
        {
            var value = attribute.ConstructorArguments [i].Value;
            switch (attribute.ConstructorArguments [i].ArgumentType.FullName)
            {
            case "System.Type":
                if (value != null)
                {
                    if (attribType.Assembly == typeof(TypeManager).Assembly)
                    {
                        constructorArguments [i] = value;
                    }
                    else
                    {
                        constructorArguments [i] = System.Type.GetType(((Type)value).FullName);
                    }
                    if (constructorArguments [i] == null)
                    {
                        throw ErrorHelper.CreateError(1056, "Internal error: failed to instantiate mock attribute '{0}' (could not convert type constructor argument #{1}). Please file a bug report (https://github.com/xamarin/xamarin-macios/issues/new) with a test case.", attribType.FullName, i + 1);
                    }
                }
                break;

            default:
                constructorArguments [i] = value;
                break;
            }
        }

        var parameters = attribute.Constructor.GetParameters();
        var ctorTypes  = new System.Type [parameters.Length];

        for (int i = 0; i < ctorTypes.Length; i++)
        {
            var paramType = parameters [i].ParameterType;
            switch (paramType.FullName)
            {
            case "System.Type":
                if (attribType.Assembly == typeof(TypeManager).Assembly)
                {
                    ctorTypes [i] = typeof(Type);
                }
                else
                {
                    ctorTypes [i] = typeof(System.Type);
                }
                break;

            default:
                ctorTypes [i] = ConvertType(paramType, provider);
                break;
            }
            if (ctorTypes [i] == null)
            {
                throw ErrorHelper.CreateError(1057, "Internal error: failed to instantiate mock attribute '{0}' (could not convert constructor type #{1} ({2})). Please file a bug report (https://github.com/xamarin/xamarin-macios/issues/new) with a test case.", attribType.FullName, i, paramType.FullName);
            }
        }
        var ctor = attribType.GetConstructor(ctorTypes);

        if (ctor == null)
        {
            throw ErrorHelper.CreateError(1058, "Internal error: could not find a constructor for the mock attribute '{0}'. Please file a bug report (https://github.com/xamarin/xamarin-macios/issues/new) with a test case.", attribType.FullName);
        }
        var instance = ctor.Invoke(constructorArguments);

        for (int i = 0; i < attribute.NamedArguments.Count; i++)
        {
            var arg   = attribute.NamedArguments [i];
            var value = arg.TypedValue.Value;
            if (arg.TypedValue.ArgumentType == TypeManager.System_String_Array)
            {
                var typed_values = (CustomAttributeTypedArgument [])arg.TypedValue.Value;
                var arr          = new string [typed_values.Length];
                for (int a = 0; a < arr.Length; a++)
                {
                    arr [a] = (string)typed_values [a].Value;
                }
                value = arr;
            }
            else if (arg.TypedValue.ArgumentType.FullName == "System.Type[]")
            {
                var typed_values = (CustomAttributeTypedArgument [])arg.TypedValue.Value;
                var arr          = new Type [typed_values.Length];
                for (int a = 0; a < arr.Length; a++)
                {
                    arr [a] = (Type)typed_values [a].Value;
                }
                value = arr;
            }
            else if (arg.TypedValue.ArgumentType.IsArray)
            {
                throw ErrorHelper.CreateError(1059, "Internal error: failed to instantiate mock attribute '{0}' (unknown type for the named argument #{1} ({2}). Please file a bug report (https://github.com/xamarin/xamarin-macios/issues/new) with a test case.", attribType.FullName, i + 1, arg.MemberName);
            }
            if (arg.IsField)
            {
                attribType.GetField(arg.MemberName).SetValue(instance, value);
            }
            else
            {
                attribType.GetProperty(arg.MemberName).SetValue(instance, value, new object [0]);
            }
        }

        return(((T)instance).Yield());
    }
Exemplo n.º 2
0
    IEnumerable <T> CreateAttributeInstance <T> (CustomAttributeData attribute, ICustomAttributeProvider provider) where T : System.Attribute
    {
        var convertedAttributes = ConvertOldAttributes(attribute);

        if (convertedAttributes.Any())
        {
            return(convertedAttributes.OfType <T> ());
        }

        var expectedType = ConvertType(typeof(T), provider);

        if (attribute.AttributeType != expectedType && !IsSubclassOf(expectedType, attribute.AttributeType))
        {
            return(Enumerable.Empty <T> ());
        }

        System.Type attribType = ConvertType(attribute.AttributeType, provider);

        var constructorArguments = new object [attribute.ConstructorArguments.Count];

        for (int i = 0; i < constructorArguments.Length; i++)
        {
            var value = attribute.ConstructorArguments [i].Value;
            switch (attribute.ConstructorArguments [i].ArgumentType.FullName)
            {
            case "System.Type":
                if (value != null)
                {
                    if (attribType.Assembly == typeof(TypeManager).Assembly)
                    {
                        constructorArguments [i] = value;
                    }
                    else
                    {
                        constructorArguments [i] = System.Type.GetType(((Type)value).FullName);
                    }
                    if (constructorArguments [i] == null)
                    {
                        throw ErrorHelper.CreateError(1056, attribType.FullName, i + 1);
                    }
                }
                break;

            default:
                constructorArguments [i] = value;
                break;
            }
        }

        var parameters = attribute.Constructor.GetParameters();
        var ctorTypes  = new System.Type [parameters.Length];

        for (int i = 0; i < ctorTypes.Length; i++)
        {
            var paramType = parameters [i].ParameterType;
            switch (paramType.FullName)
            {
            case "System.Type":
                if (attribType.Assembly == typeof(TypeManager).Assembly)
                {
                    ctorTypes [i] = typeof(Type);
                }
                else
                {
                    ctorTypes [i] = typeof(System.Type);
                }
                break;

            default:
                ctorTypes [i] = ConvertType(paramType, provider);
                break;
            }
            if (ctorTypes [i] == null)
            {
                throw ErrorHelper.CreateError(1057, attribType.FullName, i, paramType.FullName);
            }
        }
        var ctor = attribType.GetConstructor(ctorTypes);

        if (ctor == null)
        {
            throw ErrorHelper.CreateError(1058, attribType.FullName);
        }
        var instance = ctor.Invoke(constructorArguments);

        for (int i = 0; i < attribute.NamedArguments.Count; i++)
        {
            var arg   = attribute.NamedArguments [i];
            var value = arg.TypedValue.Value;
            if (arg.TypedValue.ArgumentType == TypeManager.System_String_Array)
            {
                var typed_values = (CustomAttributeTypedArgument [])arg.TypedValue.Value;
                var arr          = new string [typed_values.Length];
                for (int a = 0; a < arr.Length; a++)
                {
                    arr [a] = (string)typed_values [a].Value;
                }
                value = arr;
            }
            else if (arg.TypedValue.ArgumentType.FullName == "System.Type[]")
            {
                var typed_values = (CustomAttributeTypedArgument [])arg.TypedValue.Value;
                var arr          = new Type [typed_values.Length];
                for (int a = 0; a < arr.Length; a++)
                {
                    arr [a] = (Type)typed_values [a].Value;
                }
                value = arr;
            }
            else if (arg.TypedValue.ArgumentType.IsArray)
            {
                throw ErrorHelper.CreateError(1073, attribType.FullName, i + 1, arg.MemberName);
            }
            if (arg.IsField)
            {
                attribType.GetField(arg.MemberName).SetValue(instance, value);
            }
            else
            {
                attribType.GetProperty(arg.MemberName).SetValue(instance, value, new object [0]);
            }
        }

        return(((T)instance).Yield());
    }