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}'",
}
}
+ public void SetOwner (Attributable owner)
+ {
+ targets [0] = owner;
+ }
+
/// <summary>
/// Tries to resolve the type of the attribute. Flags an error if it can't, and complain is true.
/// </summary>
return null;
}
- ObsoleteAttribute obsolete_attr = Type.GetAttributeObsolete ();
- if (obsolete_attr != null) {
- AttributeTester.Report_ObsoleteMessage (obsolete_attr, Type.GetSignatureForError (), Location, Report);
- }
+ Type.CheckObsoleteness (context, expression.StartLocation);
ResolveContext rc = null;
return false;
}
- ObsoleteAttribute obsolete_attr;
-
if (member is PropertyExpr) {
var pi = ((PropertyExpr) member).PropertyInfo;
return false;
}
- obsolete_attr = pi.GetAttributeObsolete ();
+// if (!context.IsObsolete)
+ pi.CheckObsoleteness (ec, member.StartLocation);
+
pi.MemberDefinition.SetIsAssigned ();
} else {
var fi = ((FieldExpr) member).Spec;
return false;
}
- obsolete_attr = fi.GetAttributeObsolete ();
+// if (!context.IsObsolete)
+ fi.CheckObsoleteness (ec, member.StartLocation);
+
fi.MemberDefinition.SetIsAssigned ();
}
- if (obsolete_attr != null && !context.IsObsolete)
- AttributeTester.Report_ObsoleteMessage (obsolete_attr, member.GetSignatureForError (), member.Location, Report);
-
if (a.Type != member.Type) {
a.Expr = Convert.ImplicitConversionRequired (ec, a.Expr, member.Type, a.Expr.Location);
}
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);
}
}
+ 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)
Attrs.AddRange (attrs);
}
+ public static void AttachFromPartial (Attributable target, Attributable partialSrc)
+ {
+ if (target.OptAttributes == null) {
+ target.OptAttributes = partialSrc.OptAttributes;
+ } else {
+ target.OptAttributes.Attrs.AddRange (partialSrc.OptAttributes.Attrs);
+ }
+
+ foreach (var attr in partialSrc.OptAttributes.Attrs) {
+ attr.SetOwner (target);
+ }
+ }
+
public void AttachTo (Attributable attributable, IMemberContext context)
{
foreach (Attribute a in Attrs)
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;
// New in .NET 4.5
public readonly PredefinedStateMachineAttribute AsyncStateMachine;
+ // New in .NET 4.7
+ public readonly PredefinedTupleElementNamesAttribute TupleElementNames;
+
//
// Optional types which are used as types and for member lookup
//
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");
CallerLineNumberAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerLineNumberAttribute");
CallerFilePathAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerFilePathAttribute");
+ TupleElementNames = new PredefinedTupleElementNamesAttribute (module, "System.Runtime.CompilerServices", "TupleElementNamesAttribute");
+
// 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;
int[] bits = decimal.GetBits (value);
AttributeEncoder encoder = new AttributeEncoder ();
- encoder.Encode ((byte) (bits[3] >> 16));
- encoder.Encode ((byte) (bits[3] >> 31));
+ encoder.Encode ((byte) ((bits[3] & 0xFF0000) >> 16)); // Scale
+ encoder.Encode ((byte) ((bits[3] >> 31) << 7)); // Sign encoded as 0x80 for negative, 0x0 for possitive
encoder.Encode ((uint) bits[2]);
encoder.Encode ((uint) bits[1]);
encoder.Encode ((uint) bits[0]);
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<string> (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<string> 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);
+ }
+ }
+ }
}