X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fimport.cs;h=1cddf7c01f4b8478f80c0a158e47a25a1b688873;hb=HEAD;hp=d302724c386d84cf5998ceaec7fd542b43e47b2e;hpb=c6f75c367aba6c14fb86861853ca6009978c0f9b;p=mono.git diff --git a/mcs/mcs/import.cs b/mcs/mcs/import.cs index d302724c386..1cddf7c01f4 100644 --- a/mcs/mcs/import.cs +++ b/mcs/mcs/import.cs @@ -30,15 +30,18 @@ namespace Mono.CSharp public abstract class MetadataImporter { // - // Dynamic types reader with additional logic to reconstruct a dynamic - // type using DynamicAttribute values + // Types reader with additional logic to reconstruct extra + // type information encoded in custom attributes values // - protected struct DynamicTypeReader + protected struct AttributesTypeInfoReader { static readonly bool[] single_attribute = { true }; - public int Position; - bool[] flags; + public int DynamicPosition; + bool[] dynamicFlags; + + public int TuplePosition; + string[] tupleNames; // There is no common type for CustomAttributeData and we cannot // use ICustomAttributeProvider @@ -47,10 +50,12 @@ namespace Mono.CSharp // // A member provider which can be used to get CustomAttributeData // - public DynamicTypeReader (object provider) + public AttributesTypeInfoReader (object provider) { - Position = 0; - flags = null; + DynamicPosition = 0; + TuplePosition = 0; + dynamicFlags = null; + tupleNames = null; this.provider = provider; } @@ -62,7 +67,7 @@ namespace Mono.CSharp if (provider != null) ReadAttribute (); - return flags != null && Position < flags.Length && flags[Position]; + return dynamicFlags != null && DynamicPosition < dynamicFlags.Length && dynamicFlags [DynamicPosition]; } // @@ -73,7 +78,34 @@ namespace Mono.CSharp if (provider != null) ReadAttribute (); - return flags != null; + return dynamicFlags != null; + } + + public bool HasNamedTupleAttribute () + { + if (provider != null) + ReadAttribute (); + + return tupleNames != null; + } + + public IList GetNamedTupleElements (int length) + { + if (TuplePosition == 0 && length == tupleNames.Length) + return tupleNames; + + for (int i = TuplePosition; i < length + TuplePosition; ++i) { + if (tupleNames [i] != null) { + var res = new string [length]; + Array.Copy (tupleNames, TuplePosition, res, 0, length); + return res; + } + } + + // + // Current range can be just padding + // + return null; } IList GetCustomAttributes () @@ -100,22 +132,40 @@ namespace Mono.CSharp if (cad.Count > 0) { foreach (var ca in cad) { var dt = ca.Constructor.DeclaringType; - if (dt.Name != "DynamicAttribute" || dt.Namespace != CompilerServicesNamespace) + if (dt.Namespace != CompilerServicesNamespace) continue; - if (ca.ConstructorArguments.Count == 0) { - flags = single_attribute; - break; - } + switch (dt.Name) { + case "DynamicAttribute": + if (ca.ConstructorArguments.Count == 0) { + dynamicFlags = single_attribute; + break; + } + + var arg_type = ca.ConstructorArguments [0].ArgumentType; + + if (arg_type.IsArray && MetaType.GetTypeCode (arg_type.GetElementType ()) == TypeCode.Boolean) { + var carg = (IList)ca.ConstructorArguments [0].Value; + dynamicFlags = new bool [carg.Count]; + for (int i = 0; i < dynamicFlags.Length; ++i) { + if (MetaType.GetTypeCode (carg [i].ArgumentType) == TypeCode.Boolean) + dynamicFlags [i] = (bool)carg [i].Value; + } + } - var arg_type = ca.ConstructorArguments[0].ArgumentType; + break; + case "TupleElementNamesAttribute": + if (ca.ConstructorArguments.Count != 1) + break; - if (arg_type.IsArray && MetaType.GetTypeCode (arg_type.GetElementType ()) == TypeCode.Boolean) { - var carg = (IList) ca.ConstructorArguments[0].Value; - flags = new bool[carg.Count]; - for (int i = 0; i < flags.Length; ++i) { - if (MetaType.GetTypeCode (carg[i].ArgumentType) == TypeCode.Boolean) - flags[i] = (bool) carg[i].Value; + var tuple_arg_type = ca.ConstructorArguments [0].ArgumentType; + if (tuple_arg_type.IsArray && MetaType.GetTypeCode (tuple_arg_type.GetElementType ()) == TypeCode.String) { + var carg = (IList)ca.ConstructorArguments [0].Value; + tupleNames = new string [carg.Count]; + for (int i = 0; i < tupleNames.Length; ++i) { + if (MetaType.GetTypeCode (carg [i].ArgumentType) == TypeCode.String) + tupleNames [i] = (string)carg [i].Value; + } } break; @@ -142,6 +192,7 @@ namespace Mono.CSharp compiled_types = new Dictionary (40, ReferenceEquality.Default); assembly_2_definition = new Dictionary (ReferenceEquality.Default); IgnorePrivateMembers = true; + IgnoreCompilerGeneratedField = true; } #region Properties @@ -154,6 +205,8 @@ namespace Mono.CSharp public bool IgnorePrivateMembers { get; set; } + public bool IgnoreCompilerGeneratedField { get; set; } + #endregion public abstract void AddCompiledType (TypeBuilder builder, TypeSpec spec); @@ -179,8 +232,10 @@ namespace Mono.CSharp break; default: // Ignore private fields (even for error reporting) to not require extra dependencies - if ((IgnorePrivateMembers && !declaringType.IsStruct) || - HasAttribute (CustomAttributeData.GetCustomAttributes (fi), "CompilerGeneratedAttribute", CompilerServicesNamespace)) + if (IgnorePrivateMembers && !declaringType.IsStruct) + return null; + + if (IgnoreCompilerGeneratedField && HasAttribute (CustomAttributeData.GetCustomAttributes (fi), "CompilerGeneratedAttribute", CompilerServicesNamespace)) return null; mod = Modifiers.PRIVATE; @@ -190,7 +245,7 @@ namespace Mono.CSharp TypeSpec field_type; try { - field_type = ImportType (fi.FieldType, new DynamicTypeReader (fi)); + field_type = ImportType (fi.FieldType, new AttributesTypeInfoReader (fi), declaringType); // // Private field has private type which is not fixed buffer @@ -270,7 +325,7 @@ namespace Mono.CSharp if (add.Modifiers != remove.Modifiers) throw new NotImplementedException ("Different accessor modifiers " + ei.Name); - var event_type = ImportType (ei.EventHandlerType, new DynamicTypeReader (ei)); + var event_type = ImportType (ei.EventHandlerType, new AttributesTypeInfoReader (ei), declaringType); var definition = new ImportedMemberDefinition (ei, event_type, this); return new EventSpec (declaringType, definition, event_type, add.Modifiers, add, remove); } @@ -322,15 +377,15 @@ namespace Mono.CSharp var type = tparams[pos]; int index = pos - first; - tspec[index] = (TypeParameterSpec) CreateType (type, new DynamicTypeReader (), false); + tspec[index] = (TypeParameterSpec) CreateType (type, new AttributesTypeInfoReader (), false); } return tspec; } - TypeSpec[] CreateGenericArguments (int first, MetaType[] tparams, DynamicTypeReader dtype) + TypeSpec[] CreateGenericArguments (int first, MetaType[] tparams, AttributesTypeInfoReader dtype) { - ++dtype.Position; + ++dtype.DynamicPosition; var tspec = new TypeSpec [tparams.Length - first]; for (int pos = first; pos < tparams.Length; ++pos) { @@ -340,8 +395,8 @@ namespace Mono.CSharp TypeSpec spec; if (type.HasElementType) { var element = type.GetElementType (); - ++dtype.Position; - spec = ImportType (element, dtype); + ++dtype.DynamicPosition; + spec = ImportType (element, dtype, null); if (!type.IsArray) { throw new NotImplementedException ("Unknown element type " + type.ToString ()); @@ -360,7 +415,7 @@ namespace Mono.CSharp // } // if (!IsMissingType (type) && type.IsGenericTypeDefinition) { - var start_pos = spec.DeclaringType == null ? 0 : spec.DeclaringType.MemberDefinition.TypeParametersCount; + var start_pos = GetDeclaringTypesTypeParametersCount (spec); var targs = CreateGenericArguments (start_pos, type.GetGenericArguments (), dtype); spec = spec.MakeGenericType (module, targs); } @@ -369,13 +424,24 @@ namespace Mono.CSharp if (spec == null) return null; - ++dtype.Position; + ++dtype.DynamicPosition; tspec[index] = spec; } return tspec; } + static int GetDeclaringTypesTypeParametersCount (TypeSpec spec) + { + int total = 0; + while (spec.DeclaringType != null) { + total += spec.DeclaringType.MemberDefinition.TypeParametersCount; + spec = spec.DeclaringType; + } + + return total; + } + public MethodSpec CreateMethod (MethodBase mb, TypeSpec declaringType) { Modifiers mod = ReadMethodModifiers (mb, declaringType); @@ -398,6 +464,9 @@ namespace Mono.CSharp kind = MemberKind.Constructor; returnType = module.Compiler.BuiltinTypes.Void; } else { + var mi = (MethodInfo)mb; + returnType = ImportType (mi.ReturnType, new AttributesTypeInfoReader (mi.ReturnParameter), declaringType); + // // Detect operators and destructors // @@ -411,7 +480,7 @@ namespace Mono.CSharp kind = MemberKind.Operator; } } - } else if (parameters.IsEmpty && name == Destructor.MetadataName) { + } else if (parameters.IsEmpty && name == Destructor.MetadataName && returnType.Kind == MemberKind.Void) { kind = MemberKind.Destructor; if (declaringType.BuiltinType == BuiltinTypeSpec.Type.Object) { mod &= ~Modifiers.OVERRIDE; @@ -420,9 +489,6 @@ namespace Mono.CSharp } } - var mi = (MethodInfo) mb; - returnType = ImportType (mi.ReturnType, new DynamicTypeReader (mi.ReturnParameter)); - // Cannot set to OVERRIDE without full hierarchy checks // this flag indicates that the method could be override // but further validation is needed @@ -529,13 +595,13 @@ namespace Mono.CSharp // Strip reference wrapping // var el = p.ParameterType.GetElementType (); - types[i] = ImportType (el, new DynamicTypeReader (p)); // TODO: 1-based positio to be csc compatible + types[i] = ImportType (el, new AttributesTypeInfoReader (p), parent); // TODO: 1-based positio to be csc compatible } else if (i == 0 && method.IsStatic && (parent.Modifiers & Modifiers.METHOD_EXTENSION) != 0 && HasAttribute (CustomAttributeData.GetCustomAttributes (method), "ExtensionAttribute", CompilerServicesNamespace)) { mod = Parameter.Modifier.This; - types[i] = ImportType (p.ParameterType, new DynamicTypeReader (p)); + types[i] = ImportType (p.ParameterType, new AttributesTypeInfoReader (p), parent); } else { - types[i] = ImportType (p.ParameterType, new DynamicTypeReader (p)); + types[i] = ImportType (p.ParameterType, new AttributesTypeInfoReader (p), parent); if (i >= pi.Length - 2 && types[i] is ArrayContainer) { if (HasAttribute (CustomAttributeData.GetCustomAttributes (p), "ParamArrayAttribute", "System")) { @@ -629,14 +695,7 @@ namespace Mono.CSharp if (set_param_count == 0) { set_based_param = ParametersCompiled.EmptyReadOnlyParameters; } else { - // - // Create indexer parameters based on setter method parameters (the last parameter has to be removed) - // - var data = new IParameterData[set_param_count]; - var types = new TypeSpec[set_param_count]; - Array.Copy (set.Parameters.FixedParameters, data, set_param_count); - Array.Copy (set.Parameters.Types, types, set_param_count); - set_based_param = new ParametersImported (data, types, set.Parameters.HasParams); + set_based_param = IndexerSpec.CreateParametersFromSetter (set, set_param_count); } mod = set.Modifiers; @@ -725,26 +784,26 @@ namespace Mono.CSharp public TypeSpec CreateType (MetaType type) { - return CreateType (type, new DynamicTypeReader (), true); + return CreateType (type, new AttributesTypeInfoReader (), true); } public TypeSpec CreateNestedType (MetaType type, TypeSpec declaringType) { - return CreateType (type, declaringType, new DynamicTypeReader (type), false); + return CreateType (type, declaringType, new AttributesTypeInfoReader (type), false); } - TypeSpec CreateType (MetaType type, DynamicTypeReader dtype, bool canImportBaseType) + TypeSpec CreateType (MetaType type, AttributesTypeInfoReader dtype, bool canImportBaseType) { TypeSpec declaring_type; if (type.IsNested && !type.IsGenericParameter) - declaring_type = CreateType (type.DeclaringType, new DynamicTypeReader (type.DeclaringType), true); + declaring_type = CreateType (type.DeclaringType, new AttributesTypeInfoReader (type.DeclaringType), true); else declaring_type = null; return CreateType (type, declaring_type, dtype, canImportBaseType); } - protected TypeSpec CreateType (MetaType type, TypeSpec declaringType, DynamicTypeReader dtype, bool canImportBaseType) + protected TypeSpec CreateType (MetaType type, TypeSpec declaringType, AttributesTypeInfoReader dtype, bool canImportBaseType) { TypeSpec spec; if (import_cache.TryGetValue (type, out spec)) { @@ -787,7 +846,7 @@ namespace Mono.CSharp return null; if (declaringType == null) { // Simple case, no nesting - spec = CreateType (type_def, null, new DynamicTypeReader (), canImportBaseType); + spec = CreateType (type_def, null, new AttributesTypeInfoReader (), canImportBaseType); spec = spec.MakeGenericType (module, targs); } else { // @@ -814,7 +873,7 @@ namespace Mono.CSharp if (t.Kind == MemberKind.MissingType) spec = t; else - spec = MemberCache.FindNestedType (spec, t.Name, t.Arity); + spec = MemberCache.FindNestedType (spec, t.Name, t.Arity, false); if (t.Arity > 0) { spec = spec.MakeGenericType (module, targs.Skip (targs_pos).Take (spec.Arity).ToArray ()); @@ -834,7 +893,7 @@ namespace Mono.CSharp if (index > 0) name = name.Substring (0, index); - spec = MemberCache.FindNestedType (spec, name, targs.Length - targs_pos); + spec = MemberCache.FindNestedType (spec, name, targs.Length - targs_pos, false); if (spec.Arity > 0) { spec = spec.MakeGenericType (module, targs.Skip (targs_pos).ToArray ()); @@ -842,6 +901,14 @@ namespace Mono.CSharp } } + if (spec.IsTupleType && dtype.HasNamedTupleAttribute ()) { + var names = dtype.GetNamedTupleElements (spec.Arity); + if (names != null) + return NamedTupleSpec.MakeType (module, (InflatedTypeSpec) spec, names); + + dtype.TuplePosition += spec.Arity; + } + // Don't add generic type with dynamic arguments, they can interfere with same type // using object type arguments if (!spec.HasDynamicElement) { @@ -892,7 +959,8 @@ namespace Mono.CSharp } } - if (kind == MemberKind.Class) { + switch (kind) { + case MemberKind.Class: if ((ma & TypeAttributes.Sealed) != 0) { if ((ma & TypeAttributes.Abstract) != 0) mod |= Modifiers.STATIC; @@ -901,6 +969,13 @@ namespace Mono.CSharp } else if ((ma & TypeAttributes.Abstract) != 0) { mod |= Modifiers.ABSTRACT; } + break; + case MemberKind.Struct: + if (HasAttribute (CustomAttributeData.GetCustomAttributes (type), "IsReadOnlyAttribute", CompilerServicesNamespace)) { + mod |= Modifiers.READONLY; + } + + break; } } @@ -1062,7 +1137,7 @@ namespace Mono.CSharp else if (type.BaseType != null) { TypeSpec base_type; if (!IsMissingType (type.BaseType) && type.BaseType.IsGenericType) - base_type = CreateType (type.BaseType, new DynamicTypeReader (type), true); + base_type = CreateType (type.BaseType, new AttributesTypeInfoReader (type), true); else base_type = CreateType (type.BaseType); @@ -1076,7 +1151,7 @@ namespace Mono.CSharp } } - protected void ImportTypes (MetaType[] types, Namespace targetNamespace, bool importExtensionTypes) + public void ImportTypes (MetaType[] types, Namespace targetNamespace, bool importExtensionTypes) { Namespace ns = targetNamespace; string prev_namespace = null; @@ -1091,7 +1166,7 @@ namespace Mono.CSharp if (t.Name[0] == '<') continue; - var it = CreateType (t, null, new DynamicTypeReader (t), true); + var it = CreateType (t, null, new AttributesTypeInfoReader (t), true); if (it == null) continue; @@ -1183,15 +1258,15 @@ namespace Mono.CSharp public TypeSpec ImportType (MetaType type) { - return ImportType (type, new DynamicTypeReader (type)); + return ImportType (type, new AttributesTypeInfoReader (type), null); } - TypeSpec ImportType (MetaType type, DynamicTypeReader dtype) + TypeSpec ImportType (MetaType type, AttributesTypeInfoReader dtype, TypeSpec currentType) { if (type.HasElementType) { var element = type.GetElementType (); - ++dtype.Position; - var spec = ImportType (element, dtype); + ++dtype.DynamicPosition; + var spec = ImportType (element, dtype, currentType); if (type.IsArray) return ArrayContainer.MakeType (module, spec, type.GetArrayRank ()); @@ -1207,11 +1282,19 @@ namespace Mono.CSharp if (compiled_types.TryGetValue (type, out compiled_type)) { if (compiled_type.BuiltinType == BuiltinTypeSpec.Type.Object && dtype.IsDynamicObject ()) return module.Compiler.BuiltinTypes.Dynamic; + } else { + compiled_type = CreateType (type, dtype, true); + } - return compiled_type; + if (currentType == compiled_type && currentType?.IsGeneric == true) { + // + // Inflates current type to match behaviour of TypeDefinition::CurrentType used by compiled types + // + var targs = compiled_type.MemberDefinition.TypeParameters; + compiled_type = compiled_type.MakeGenericType (module, targs); } - return CreateType (type, dtype, true); + return compiled_type; } static bool IsMissingType (MetaType type) @@ -1690,7 +1773,7 @@ namespace Mono.CSharp token = null; foreach (var internals in internals_visible_to) { - if (internals.Name != assembly.Name) + if (!String.Equals(internals.Name, assembly.Name, StringComparison.OrdinalIgnoreCase)) continue; if (token == null && assembly is AssemblyDefinition) {