X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fimport.cs;h=1cddf7c01f4b8478f80c0a158e47a25a1b688873;hb=66205238fc51274272ba9db9ce07e9b2fb60d1a6;hp=96f950551e21bd257d4a7114971fbb774d50f9aa;hpb=28046216b275e698f7dfafc866ee39497223eb9f;p=mono.git diff --git a/mcs/mcs/import.cs b/mcs/mcs/import.cs index 96f950551e2..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; - 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; + } + } + + 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; @@ -195,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 @@ -275,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); } @@ -327,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) { @@ -345,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 ()); @@ -374,7 +424,7 @@ namespace Mono.CSharp if (spec == null) return null; - ++dtype.Position; + ++dtype.DynamicPosition; tspec[index] = spec; } @@ -414,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 // @@ -427,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; @@ -436,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 @@ -545,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")) { @@ -645,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; @@ -741,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)) { @@ -803,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 { // @@ -858,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) { @@ -908,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; @@ -917,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; } } @@ -1078,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); @@ -1092,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; @@ -1107,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; @@ -1199,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 ()); @@ -1223,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) @@ -1706,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) {