2009-12-02 Marek Safar <marek.safar@gmail.com>
authorMarek Safar <marek.safar@gmail.com>
Wed, 2 Dec 2009 15:23:40 +0000 (15:23 -0000)
committerMarek Safar <marek.safar@gmail.com>
Wed, 2 Dec 2009 15:23:40 +0000 (15:23 -0000)
* typemanager.cs, parameter.cs, class.cs, delegate.cs, attribute.cs:
Encode dynamic type attribute for elements where attributes cannot
be used.

svn path=/trunk/mcs/; revision=147441

mcs/mcs/ChangeLog
mcs/mcs/attribute.cs
mcs/mcs/class.cs
mcs/mcs/delegate.cs
mcs/mcs/parameter.cs
mcs/mcs/typemanager.cs

index 652e0302643d192b821e0e635d8fb562a550f9b0..11926c2b19981c8abbc28076ec9aa58e9d281203 100644 (file)
@@ -1,3 +1,9 @@
+2009-12-02  Marek Safar  <marek.safar@gmail.com>
+
+       * typemanager.cs, parameter.cs, class.cs, delegate.cs, attribute.cs:
+       Encode dynamic type attribute for elements where attributes cannot
+       be used.
+
 2009-12-01  Marek Safar  <marek.safar@gmail.com>
 
         argument.cs, assign.cs, expression.cs, cs-parser.jay: Named
index 322c8b943e343a4ff62a2c47a473653ecb5703d1..784e92a12c3edc013c4146490b7464d0f1d5b261 100644 (file)
@@ -1923,6 +1923,7 @@ namespace Mono.CSharp {
 
                // New in .NET 4.0
                public readonly PredefinedAttribute Dynamic;
+               public readonly PredefinedAttribute DynamicTransform;   // DynamicAttribute with transform arguments
 
                //
                // Optional types which are used as types and for member lookup
@@ -1970,6 +1971,7 @@ namespace Mono.CSharp {
                        Extension = new PredefinedAttribute ("System.Runtime.CompilerServices", "ExtensionAttribute");
 
                        Dynamic = new PredefinedAttribute ("System.Runtime.CompilerServices", "DynamicAttribute");
+                       DynamicTransform = new PredefinedAttribute ("System.Runtime.CompilerServices", "DynamicAttribute");
 
                        DefaultMember = new PredefinedAttribute ("System.Reflection", "DefaultMemberAttribute");
                        DecimalConstant = new PredefinedAttribute ("System.Runtime.CompilerServices", "DecimalConstantAttribute");
index f968231c45eed8ac621663b66f51a746c01fb99c..97c1f8e733bc331557ea69ecbda1fb9915fc011f 100644 (file)
@@ -3952,6 +3952,16 @@ namespace Mono.CSharp {
                        if (TypeManager.IsDynamicType (ReturnType)) {
                                return_attributes = new ReturnParameter (this, MethodBuilder, Location);
                                PredefinedAttributes.Get.Dynamic.EmitAttribute (return_attributes.Builder);
+                       } else {
+                               var trans_flags = TypeManager.HasDynamicTypeUsed (ReturnType);
+                               if (trans_flags != null) {
+                                       var pa = PredefinedAttributes.Get.DynamicTransform;
+                                       if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+                                               return_attributes = new ReturnParameter (this, MethodBuilder, Location);
+                                               return_attributes.Builder.SetCustomAttribute (
+                                                       new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
+                                       }
+                               }
                        }
 
                        if (OptAttributes != null)
@@ -5574,8 +5584,17 @@ namespace Mono.CSharp {
 
                public override void Emit ()
                {
-                       if (TypeManager.IsDynamicType (member_type))
+                       if (TypeManager.IsDynamicType (member_type)) {
                                PredefinedAttributes.Get.Dynamic.EmitAttribute (FieldBuilder);
+                       } else {
+                               var trans_flags = TypeManager.HasDynamicTypeUsed (member_type);
+                               if (trans_flags != null) {
+                                       var pa = PredefinedAttributes.Get.DynamicTransform;
+                                       if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+                                               FieldBuilder.SetCustomAttribute (new CustomAttributeBuilder (pa.Constructor, new object[] { trans_flags }));
+                                       }
+                               }
+                       }
 
                        if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
                                PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (FieldBuilder);
@@ -6173,6 +6192,16 @@ namespace Mono.CSharp {
                        if (TypeManager.IsDynamicType (ReturnType)) {
                                return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
                                PredefinedAttributes.Get.Dynamic.EmitAttribute (return_attributes.Builder);
+                       } else {
+                               var trans_flags = TypeManager.HasDynamicTypeUsed (ReturnType);
+                               if (trans_flags != null) {
+                                       var pa = PredefinedAttributes.Get.DynamicTransform;
+                                       if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+                                               return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
+                                               return_attributes.Builder.SetCustomAttribute (
+                                                       new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
+                                       }
+                               }
                        }
 
                        if (OptAttributes != null)
@@ -6686,8 +6715,18 @@ namespace Mono.CSharp {
                                if (OptAttributes != null)
                                        OptAttributes.Emit ();
 
-                               if (TypeManager.IsDynamicType (member_type))
+                               if (TypeManager.IsDynamicType (member_type)) {
                                        PredefinedAttributes.Get.Dynamic.EmitAttribute (PropertyBuilder);
+                               } else {
+                                       var trans_flags = TypeManager.HasDynamicTypeUsed (member_type);
+                                       if (trans_flags != null) {
+                                               var pa = PredefinedAttributes.Get.DynamicTransform;
+                                               if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+                                                       PropertyBuilder.SetCustomAttribute (
+                                                               new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
+                                               }
+                                       }
+                               }
                        }
 
                        if (!Get.IsDummy)
index 6956bb7afe32fad479bda36a3b0fbdc98731e0bc..88d483c53960e9fcd7dd109244ed057ab59e0aa8 100644 (file)
@@ -286,6 +286,16 @@ namespace Mono.CSharp {
                        if (TypeManager.IsDynamicType (ret_type)) {
                                return_attributes = new ReturnParameter (this, InvokeBuilder, Location);
                                PredefinedAttributes.Get.Dynamic.EmitAttribute (return_attributes.Builder);
+                       } else {
+                               var trans_flags = TypeManager.HasDynamicTypeUsed (ret_type);
+                               if (trans_flags != null) {
+                                       var pa = PredefinedAttributes.Get.DynamicTransform;
+                                       if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+                                               return_attributes = new ReturnParameter (this, InvokeBuilder, Location);
+                                               return_attributes.Builder.SetCustomAttribute (
+                                                       new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
+                                       }
+                               }
                        }
 
                        Parameters.ApplyAttributes (InvokeBuilder);
index 543736c4127cc7388a34c9d3907b9c92bfabe31e..705b9e614a6886989ccd2631a161b04d429b6816 100644 (file)
@@ -546,8 +546,18 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (TypeManager.IsDynamicType (parameter_type))
+                       if (TypeManager.IsDynamicType (parameter_type)) {
                                PredefinedAttributes.Get.Dynamic.EmitAttribute (builder);
+                       } else {
+                               var trans_flags = TypeManager.HasDynamicTypeUsed (parameter_type);
+                               if (trans_flags != null) {
+                                       var pa = PredefinedAttributes.Get.DynamicTransform;
+                                       if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+                                               builder.SetCustomAttribute (
+                                                       new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
+                                       }
+                               }
+                       }
                }
 
                public override string[] ValidAttributeTargets {
index 050971ec40e052026fa9a3f1116faaa0bb4883db..03289650e5c3d094775bf56df2115c609864e6f6 100644 (file)
@@ -22,6 +22,7 @@ using System;
 using System.IO;
 using System.Globalization;
 using System.Collections;
+using System.Collections.Generic;
 using System.Reflection;
 using System.Reflection.Emit;
 using System.Text;
@@ -1309,6 +1310,55 @@ namespace Mono.CSharp {
                object[] res = t.GetCustomAttributes (pa.Type, false);
                return res != null && res.Length != 0;
        }
+
+       //
+       // Dynamic type or any element of type is dynamic type is used
+       //
+       // This method builds transformation array for dynamic types
+       // used in places where DynamicAttribute cannnot be applied to.
+       // It uses bool flag when type is of dynamic type and each
+       // section always starts with "false" for some reason.
+       //
+       // LAMESPEC: This should be part of C# specification !
+       // 
+       // Example: Func<dynamic, int, dynamic[]>
+       // Transformation: { false, true, false, false, true }
+       //
+       public static bool[] HasDynamicTypeUsed (Type t)
+       {
+               if (t is DynamicArrayType)
+                       return new bool[] { false, true };
+
+               if (t == null)
+                       return null;
+
+               if (IsGenericType (t)) {
+                       List<bool> transform = null;
+                       var targs = GetTypeArguments (t);
+                       for (int i = 0; i < targs.Length; ++i) {
+                               var element = HasDynamicTypeUsed (targs [i]);
+                               if (element != null) {
+                                       if (transform == null) {
+                                               transform = new List<bool> ();
+                                               for (int ii = 0; ii <= i; ++ii)
+                                                       transform.Add (false);
+                                       }
+
+                                       transform.AddRange (element);
+                               } else if (transform != null) {
+                                       transform.Add (false);
+                               }
+                       }
+
+                       if (transform != null)
+                               return transform.ToArray ();
+               }
+
+               if (object.ReferenceEquals (InternalType.Dynamic, t))
+                       return new bool [] { true };
+
+               return null;
+       }
        
        public static bool IsEnumType (Type t)
        {