X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fattribute.cs;h=3ff2d68ccb5ad38964c23c0890f4372c9a4406ef;hb=1004d95b6b70e8b67a2b6782e0832faab9fa269a;hp=a145c37211fd58b2441b23dd32ec5b35a6a12a7a;hpb=aea57f09d430ae672e03d96729d447c814ec867c;p=mono.git diff --git a/mcs/mcs/attribute.cs b/mcs/mcs/attribute.cs index a145c37211f..3ff2d68ccb5 100644 --- a/mcs/mcs/attribute.cs +++ b/mcs/mcs/attribute.cs @@ -258,6 +258,11 @@ namespace Mono.CSharp { Report.Error (1970, loc, "Do not use `{0}' directly. Use `dynamic' keyword instead", GetSignatureForError ()); } + public void Error_MisusedTupleAttribute () + { + Report.Error (8138, loc, "Do not use `{0}' directly. Use the tuple syntax instead", GetSignatureForError ()); + } + void Error_AttributeEmitError (string inner) { Report.Error (647, Location, "Error during emitting `{0}' attribute. The reason is `{1}'", @@ -1125,7 +1130,12 @@ namespace Mono.CSharp { cdata = encoder.ToArray (); } - if (!ctor.DeclaringType.IsConditionallyExcluded (context)) { + if (!IsConditionallyExcluded (ctor.DeclaringType)) { + if (Type == predefined.TupleElementNames) { + Error_MisusedTupleAttribute (); + return; + } + try { foreach (Attributable target in targets) target.ApplyAttributeBuilder (this, ctor, cdata, predefined); @@ -1166,6 +1176,18 @@ namespace Mono.CSharp { } } + bool IsConditionallyExcluded (TypeSpec type) + { + do { + if (type.IsConditionallyExcluded (context)) + return true; + + type = type.BaseType; + } while (type != null); + + return false; + } + private Expression GetValue () { if (pos_args == null || pos_args.Count < 1) @@ -1700,6 +1722,7 @@ namespace Mono.CSharp { public readonly PredefinedAttribute AssemblyAlgorithmId; public readonly PredefinedAttribute AssemblyFlags; public readonly PredefinedAttribute AssemblyFileVersion; + public readonly PredefinedAttribute AssemblyInformationalVersion; public readonly PredefinedAttribute ComImport; public readonly PredefinedAttribute CoClass; public readonly PredefinedAttribute AttributeUsage; @@ -1729,6 +1752,12 @@ namespace Mono.CSharp { // New in .NET 4.5 public readonly PredefinedStateMachineAttribute AsyncStateMachine; + // New in .NET 4.7 + public readonly PredefinedTupleElementNamesAttribute TupleElementNames; + + // New in .NET 4.7.1 + public readonly PredefinedAttribute IsReadOnly; + // // Optional types which are used as types and for member lookup // @@ -1800,6 +1829,7 @@ namespace Mono.CSharp { AssemblyCompany = new PredefinedAttribute (module, "System.Reflection", "AssemblyCompanyAttribute"); AssemblyCopyright = new PredefinedAttribute (module, "System.Reflection", "AssemblyCopyrightAttribute"); AssemblyTrademark = new PredefinedAttribute (module, "System.Reflection", "AssemblyTrademarkAttribute"); + AssemblyInformationalVersion = new PredefinedAttribute (module, "System.Reflection", "AssemblyInformationalVersionAttribute"); AsyncStateMachine = new PredefinedStateMachineAttribute (module, "System.Runtime.CompilerServices", "AsyncStateMachineAttribute"); @@ -1807,6 +1837,9 @@ namespace Mono.CSharp { CallerLineNumberAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerLineNumberAttribute"); CallerFilePathAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerFilePathAttribute"); + TupleElementNames = new PredefinedTupleElementNamesAttribute (module, "System.Runtime.CompilerServices", "TupleElementNamesAttribute"); + IsReadOnly = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "IsReadOnlyAttribute"); + // TODO: Should define only attributes which are used for comparison const System.Reflection.BindingFlags all_fields = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly; @@ -2157,4 +2190,83 @@ namespace Mono.CSharp { return tctor != null; } } + + public class PredefinedTupleElementNamesAttribute : PredefinedAttribute + { + MethodSpec tctor; + + public PredefinedTupleElementNamesAttribute (ModuleContainer module, string ns, string name) + : base (module, ns, name) + { + } + + public void EmitAttribute (FieldBuilder builder, TypeSpec type, Location loc) + { + var cab = CreateCustomAttributeBuilder (type, loc); + if (cab != null) + builder.SetCustomAttribute (cab); + } + + public void EmitAttribute (ParameterBuilder builder, TypeSpec type, Location loc) + { + var cab = CreateCustomAttributeBuilder (type, loc); + if (cab != null) + builder.SetCustomAttribute (cab); + } + + public void EmitAttribute (PropertyBuilder builder, TypeSpec type, Location loc) + { + var cab = CreateCustomAttributeBuilder (type, loc); + if (cab != null) + builder.SetCustomAttribute (cab); + } + + public void EmitAttribute (TypeBuilder builder, TypeSpec type, Location loc) + { + var cab = CreateCustomAttributeBuilder (type, loc); + if (cab != null) + builder.SetCustomAttribute (cab); + } + + CustomAttributeBuilder CreateCustomAttributeBuilder (TypeSpec type, Location loc) + { + if (tctor == null) { + tctor = module.PredefinedMembers.TupleElementNamesAttributeCtor.Resolve (loc); + if (tctor == null) + return null; + } + + var names = new List (type.TypeArguments.Length); + BuildStringElements (type, names); + return new CustomAttributeBuilder ((ConstructorInfo)tctor.GetMetaInfo (), new object [] { names.ToArray () }); + } + + // + // Returns an array of names when any element of the type is + // tuple with named element. The array is built for top level + // type therefore it can contain multiple tuple types + // + // Example: Func<(int, int), int, (int a, int b)[]> + // Output: { null, null, "a", "b" } + // + static void BuildStringElements (TypeSpec type, List names) + { + while (type is ArrayContainer) { + type = ((ArrayContainer)type).Element; + } + + var nts = type as NamedTupleSpec; + if (nts != null) { + names.AddRange (nts.Elements); + } else { + for (int i = 0; i < type.Arity; ++i) { + names.Add (null); + } + } + + foreach (var ta in type.TypeArguments) { + BuildStringElements (ta, names); + } + } + } }