+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
// 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
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");
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)
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);
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)
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)
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);
}
}
- 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 {
using System.IO;
using System.Globalization;
using System.Collections;
+using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
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)
{