private void CheckAttributeUsageCardinality(Attribute node, Type attrType, AttributeUsageAttribute usage) { if (usage.AllowMultiple) return; if (HasSiblingAttributesOfSameType(node, attrType)) MultipleAttributeUsageError(node, attrType); }
private void CheckAttributeUsageTarget(Attribute node, Type attrType, AttributeUsageAttribute usage) { var validAttributeTargets = ValidAttributeTargetsFor(attrType, usage); if (validAttributeTargets == AttributeTargets.All) return; var target = AttributeTargetsFor(node); if (target.HasValue && !IsValid(target.Value, validAttributeTargets)) Errors.Add(CompilerErrorFactory.InvalidAttributeTarget(node, attrType, validAttributeTargets)); }
public static AttributeUsageAttribute GetAttributeUsage (Type attributeType) { if (attributeType == null) throw new ArgumentNullException ("attributeType"); var cachedInstance = s_attributeUsageCache.GetOrAdd (attributeType, GetLazyAttributeUsage).Value; var newInstance = new AttributeUsageAttribute (cachedInstance.ValidOn); newInstance.AllowMultiple = cachedInstance.AllowMultiple; newInstance.Inherited = cachedInstance.Inherited; return newInstance; }
private bool Check(AttributeUsageAttribute attribute) { if (null == attribute) { throw new UnitTestException(string.Format(CultureInfo.InvariantCulture, Resources.DecorationTestException_MissingMessage, Member.Name, "AttributeUsage")); } if (ValidOn != attribute.ValidOn) { throw new UnitTestException(string.Format(CultureInfo.InvariantCulture, Resources.AttributeUsage_ValidOn, Member.Name)); } if (AllowMultiple != attribute.AllowMultiple) { throw new UnitTestException(string.Format(CultureInfo.InvariantCulture, AllowMultiple ? Resources.AttributeUsage_AllowMultipleTrue : Resources.AttributeUsage_AllowMultipleFalse, Member.Name)); } if (Inherited != attribute.Inherited) { throw new UnitTestException(string.Format(CultureInfo.InvariantCulture, Inherited ? Resources.AttributeUsage_InheritedTrue : Resources.AttributeUsage_InheritedFalse, Member.Name)); } return true; }
private void CheckAttributeUsage(Attribute node, Type attrType, AttributeUsageAttribute usage) { CheckAttributeUsageTarget(node, attrType, usage); CheckAttributeUsageCardinality(node, attrType, usage); }
public AttributeUsageAttribute GetAttributeUsageAttribute () { if (!arg_resolved) // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args. // But because a lot of attribute class code must be rewritten will be better to wait... Resolve (); if (resolve_error) return DefaultUsageAttribute; AttributeUsageAttribute usage_attribute = new AttributeUsageAttribute ((AttributeTargets)((Constant) PosArguments [0].Expr).GetValue ()); var field = GetPropertyValue ("AllowMultiple") as BoolConstant; if (field != null) usage_attribute.AllowMultiple = field.Value; field = GetPropertyValue ("Inherited") as BoolConstant; if (field != null) usage_attribute.Inherited = field.Value; return usage_attribute; }
[System.Security.SecurityCritical] // auto-generated internal static AttributeUsageAttribute GetAttributeUsage(RuntimeType decoratedAttribute) { RuntimeModule decoratedModule = decoratedAttribute.GetRuntimeModule(); MetadataImport scope = decoratedModule.MetadataImport; CustomAttributeRecord[] car = CustomAttributeData.GetCustomAttributeRecords(decoratedModule, decoratedAttribute.MetadataToken); AttributeUsageAttribute attributeUsageAttribute = null; for (int i = 0; i < car.Length; i++) { CustomAttributeRecord caRecord = car[i]; RuntimeType attributeType = decoratedModule.ResolveType(scope.GetParentToken(caRecord.tkCtor), null, null) as RuntimeType; if (attributeType != (RuntimeType)typeof(AttributeUsageAttribute)) continue; if (attributeUsageAttribute != null) throw new FormatException(String.Format( CultureInfo.CurrentUICulture, Environment.GetResourceString("Format_AttributeUsage"), attributeType)); AttributeTargets targets; bool inherited, allowMultiple; ParseAttributeUsageAttribute(caRecord.blob, out targets, out inherited, out allowMultiple); attributeUsageAttribute = new AttributeUsageAttribute(targets, allowMultiple, inherited); } if (attributeUsageAttribute == null) return AttributeUsageAttribute.Default; return attributeUsageAttribute; }
internal static object[] GetCustomAttributes(ICustomAttributeProvider obj, Type attributeType, bool inherit) { if (obj == null) { throw new ArgumentNullException(nameof(obj)); } if (attributeType == null) { throw new ArgumentNullException(nameof(attributeType)); } if (attributeType == typeof(MonoCustomAttrs)) { attributeType = null; } #if NETCORE if (attributeType == typeof(Attribute)) { attributeType = null; } #endif object[] r; object[] res = GetCustomAttributesBase(obj, attributeType, false); // shortcut if (!inherit && res.Length == 1) { if (res [0] == null) { throw new CustomAttributeFormatException("Invalid custom attribute format"); } if (attributeType != null) { if (attributeType.IsAssignableFrom(res[0].GetType())) { r = (object[])Array.CreateInstance(attributeType, 1); r[0] = res[0]; } else { r = (object[])Array.CreateInstance(attributeType, 0); } } else { r = (object[])Array.CreateInstance(res[0].GetType(), 1); r[0] = res[0]; } return(r); } if (inherit && GetBase(obj) == null) { inherit = false; } // if AttributeType is sealed, and Inherited is set to false, then // there's no use in scanning base types if ((attributeType != null && attributeType.IsSealed) && inherit) { AttributeUsageAttribute usageAttribute = RetrieveAttributeUsage( attributeType); if (!usageAttribute.Inherited) { inherit = false; } } var initialSize = Math.Max(res.Length, 16); List <Object> a = null; ICustomAttributeProvider btype = obj; object[] array; /* Non-inherit case */ if (!inherit) { if (attributeType == null) { foreach (object attr in res) { if (attr == null) { throw new CustomAttributeFormatException("Invalid custom attribute format"); } } var result = new Attribute [res.Length]; res.CopyTo(result, 0); return(result); } a = new List <object> (initialSize); foreach (object attr in res) { if (attr == null) { throw new CustomAttributeFormatException("Invalid custom attribute format"); } Type attrType = attr.GetType(); if (attributeType != null && !attributeType.IsAssignableFrom(attrType)) { continue; } a.Add(attr); } if (attributeType == null || attributeType.IsValueType) { array = new Attribute [a.Count]; } else { array = Array.CreateInstance(attributeType, a.Count) as object[]; } a.CopyTo(array, 0); return(array); } /* Inherit case */ var attributeInfos = new Dictionary <Type, AttributeInfo> (initialSize); int inheritanceLevel = 0; a = new List <object> (initialSize); do { foreach (object attr in res) { AttributeUsageAttribute usage; if (attr == null) { throw new CustomAttributeFormatException("Invalid custom attribute format"); } Type attrType = attr.GetType(); if (attributeType != null) { if (!attributeType.IsAssignableFrom(attrType)) { continue; } } AttributeInfo firstAttribute; if (attributeInfos.TryGetValue(attrType, out firstAttribute)) { usage = firstAttribute.Usage; } else { usage = RetrieveAttributeUsage(attrType); } // only add attribute to the list of attributes if // - we are on the first inheritance level, or the attribute can be inherited anyway // and ( // - multiple attributes of the type are allowed // or ( // - this is the first attribute we've discovered // or // - the attribute is on same inheritance level than the first // attribute that was discovered for this attribute type )) if ((inheritanceLevel == 0 || usage.Inherited) && (usage.AllowMultiple || (firstAttribute == null || (firstAttribute != null && firstAttribute.InheritanceLevel == inheritanceLevel)))) { a.Add(attr); } if (firstAttribute == null) { attributeInfos.Add(attrType, new AttributeInfo(usage, inheritanceLevel)); } } if ((btype = GetBase(btype)) != null) { inheritanceLevel++; res = GetCustomAttributesBase(btype, attributeType, true); } } while (inherit && btype != null); if (attributeType == null || attributeType.IsValueType) { array = new Attribute [a.Count]; } else { array = Array.CreateInstance(attributeType, a.Count) as object[]; } // copy attributes to array a.CopyTo(array, 0); return(array); }
AttributeUsageAttribute GetAttributeUsageAttribute () { if (pos_values == null) // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args. // But because a lot of attribute class code must be rewritten will be better to wait... Resolve (); if (resolve_error) return DefaultUsageAttribute; AttributeUsageAttribute usage_attribute = new AttributeUsageAttribute ((AttributeTargets)pos_values [0]); object field = GetPropertyValue ("AllowMultiple"); if (field != null) usage_attribute.AllowMultiple = (bool)field; field = GetPropertyValue ("Inherited"); if (field != null) usage_attribute.Inherited = (bool)field; return usage_attribute; }
public AttributeInfo (AttributeUsageAttribute usage, int inheritanceLevel) { _usage = usage; _inheritanceLevel = inheritanceLevel; }
private bool CheckAttributeUsage(Analyzer/*!*/ analyzer, AttributeUsageAttribute usage, ref bool duplicateFound) { if (usage != null && (target.AcceptsTargets & usage.ValidOn) == 0) { analyzer.ErrorSink.Add(Errors.InvalidAttributeUsage, analyzer.SourceUnit, node.Position, node.QualifiedName.ToString()); return false; } // check duplicate usage of this attribute: if (!duplicateFound && (usage == null || !usage.AllowMultiple) && target.GetAttributeUsageCount(type, node.TargetSelector) > 1) { analyzer.ErrorSink.Add(Errors.DuplicateAttributeUsage, analyzer.SourceUnit, node.Position, node.QualifiedName.ToString()); duplicateFound = true; return false; } return true; }
private void ApplySpecialAttributes(Analyzer/*!*/ analyzer) { if (type.Equals(SpecialCustomAttribute.AppStaticAttribute)) { Debug.Assert(node.CallSignature.Parameters.Count == 0, "Should be checked by ResolveOverload"); ApplySpecialAttribute(analyzer, SpecialAttributes.AppStatic, null); isEmitted = false; } else if (type.Equals(SpecialCustomAttribute.ExportAttribute)) { Debug.Assert(node.CallSignature.Parameters.Count == 0, "Should be checked by ResolveOverload"); if (!analyzer.SourceUnit.CompilationUnit.IsPure) { analyzer.ErrorSink.Add(Errors.ExportAttributeInNonPureUnit, analyzer.SourceUnit, node.Position); } else { ApplySpecialAttribute(analyzer, SpecialAttributes.Export, Core.ExportAttribute.Default); } isEmitted = false; } else if (type.Equals(SpecialCustomAttribute.OutAttribute)) { Debug.Assert(node.CallSignature.Parameters.Count == 0, "Should be checked by ResolveOverload"); ApplySpecialAttribute(analyzer, SpecialAttributes.Out, new System.Runtime.InteropServices.OutAttribute()); isEmitted = true; } else if (type.Equals(SpecialCustomAttribute.DllImportAttribute)) { isEmitted = false; } else if (ReferenceEquals(type.TypeDesc, DTypeDesc.AttributeUsageAttributeTypeDesc)) { // set usage of the attribute defined by this attribute's target // Debug.Assert(node.CallSignature.Parameters.Count > 0, "Missing arguments should be checked by ResolveOverload"); int valid_on = Convert.ObjectToInteger(node.CallSignature.Parameters[0].Expression.GetValue()); AttributeUsageAttribute usage = new AttributeUsageAttribute((AttributeTargets)valid_on); foreach (NamedActualParam param in node.NamedParameters) { if (param.Name.Equals("AllowMultiple")) { usage.AllowMultiple = Convert.ObjectToBoolean(param.Expression.GetValue()); } else if (param.Name.Equals("Inherited")) { usage.Inherited = Convert.ObjectToBoolean(param.Expression.GetValue()); } } ApplySpecialAttribute(analyzer, SpecialAttributes.AttributeUsage, usage); isEmitted = true; } else { isEmitted = true; } }
internal CAData(Type caType, AttributeUsageAttribute usage, int level) { this.caType = caType; this.usage = usage; this.level = level; }
public AttributeInfo(AttributeUsageAttribute usage, int inheritanceLevel) { _usage = usage; _inheritanceLevel = inheritanceLevel; }
private static AttributeTargets ValidAttributeTargetsFor(Type attrType, AttributeUsageAttribute usage) { return IsExtensionAttribute(attrType) ? usage.ValidOn | AttributeTargets.Property : usage.ValidOn; }
internal static AttributeUsageAttribute GetAttributeUsage(RuntimeType decoratedAttribute) { Module module = decoratedAttribute.Module; MetadataImport metadataImport = module.MetadataImport; CustomAttributeRecord[] customAttributeRecords = CustomAttributeData.GetCustomAttributeRecords(module, decoratedAttribute.MetadataToken); AttributeUsageAttribute attribute = null; for (int i = 0; i < customAttributeRecords.Length; i++) { CustomAttributeRecord record = customAttributeRecords[i]; RuntimeType type = module.ResolveType(metadataImport.GetParentToken((int) record.tkCtor), null, null) as RuntimeType; if (type == typeof(AttributeUsageAttribute)) { AttributeTargets targets; bool flag; bool flag2; if (attribute != null) { throw new FormatException(string.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Format_AttributeUsage"), new object[] { type })); } ParseAttributeUsageAttribute(record.blob, out targets, out flag, out flag2); attribute = new AttributeUsageAttribute(targets, flag2, flag); } } if (attribute == null) { return AttributeUsageAttribute.Default; } return attribute; }
public AttributeUsageWrapper(AttributeUsageAttribute usage) { this.usage = usage; }
static IEnumerable<IAttributeInfo> GetCustomAttributes(MethodInfo method, Type attributeType, AttributeUsageAttribute attributeUsage) { IEnumerable<IAttributeInfo> results = CustomAttributeData.GetCustomAttributes(method) .Where(attr => attributeType.IsAssignableFrom(attr.Constructor.ReflectedType)) .OrderBy(attr => attr.Constructor.ReflectedType.Name) .Select(Reflector.Wrap) .Cast<IAttributeInfo>() .ToList(); if (attributeUsage.Inherited && (attributeUsage.AllowMultiple || !results.Any())) { // Need to find the parent method, which may not necessarily be on the parent type var baseMethod = GetParent(method); if (baseMethod != null) results = results.Concat(GetCustomAttributes(baseMethod, attributeType, attributeUsage)); } return results; }
private AttributeUsageAttribute GetAttributeUsage() { AttributeTargets validOn = AttributeTargets.All; bool allowMultiple = false; bool inherited = true; foreach (CustomAttributeData cad in CustomAttributeData.GetCustomAttributes(attributeType)) { if (cad.Constructor.DeclaringType == JVM.Import(typeof(AttributeUsageAttribute))) { if (cad.ConstructorArguments.Count == 1 && cad.ConstructorArguments[0].ArgumentType == JVM.Import(typeof(AttributeTargets))) { validOn = (AttributeTargets)cad.ConstructorArguments[0].Value; } foreach (CustomAttributeNamedArgument cana in cad.NamedArguments) { if (cana.MemberInfo.Name == "AllowMultiple") { allowMultiple = (bool)cana.TypedValue.Value; } else if (cana.MemberInfo.Name == "Inherited") { inherited = (bool)cana.TypedValue.Value; } } } } AttributeUsageAttribute attr = new AttributeUsageAttribute(validOn); attr.AllowMultiple = allowMultiple; attr.Inherited = inherited; return attr; }
private static bool IsValid(AttributeUsageAttribute usage, AttributeTargets target) { return target == (usage.ValidOn & target); }
private static Attribute[] InternalParamGetCustomAttributes(ParameterInfo param, Type?type, bool inherit) { Debug.Assert(param != null); // For ParameterInfo's we need to make sure that we chain through all the MethodInfo's in the inheritance chain that // have this ParameterInfo defined. .We pick up all the CustomAttributes for the starting ParameterInfo. We need to pick up only attributes // that are marked inherited from the remainder of the MethodInfo's in the inheritance chain. // For MethodInfo's on an interface we do not do an inheritance walk so the default ParameterInfo attributes are returned. // For MethodInfo's on a class we walk up the inheritance chain but do not look at the MethodInfo's on the interfaces that the // class inherits from and return the respective ParameterInfo attributes List <Type> disAllowMultiple = new List <Type>(); object?[] objAttr; if (type == null) { type = typeof(Attribute); } objAttr = param.GetCustomAttributes(type, false); for (int i = 0; i < objAttr.Length; i++) { Type objType = objAttr[i] !.GetType(); AttributeUsageAttribute attribUsage = InternalGetAttributeUsage(objType); if (attribUsage.AllowMultiple == false) { disAllowMultiple.Add(objType); } } // Get all the attributes that have Attribute as the base class Attribute[] ret; if (objAttr.Length == 0) { ret = CreateAttributeArrayHelper(type, 0); } else { ret = (Attribute[])objAttr; } if (param.Member.DeclaringType is null) // This is an interface so we are done. { return(ret); } if (!inherit) { return(ret); } ParameterInfo?baseParam = GetParentDefinition(param); while (baseParam != null) { objAttr = baseParam.GetCustomAttributes(type, false); int count = 0; for (int i = 0; i < objAttr.Length; i++) { Type objType = objAttr[i] !.GetType(); AttributeUsageAttribute attribUsage = InternalGetAttributeUsage(objType); if ((attribUsage.Inherited) && (disAllowMultiple.Contains(objType) == false)) { if (attribUsage.AllowMultiple == false) { disAllowMultiple.Add(objType); } count++; } else { objAttr[i] = null; } } // Get all the attributes that have Attribute as the base class Attribute[] attributes = CreateAttributeArrayHelper(type, count); count = 0; for (int i = 0; i < objAttr.Length; i++) { if (objAttr[i] != null) { attributes[count] = (Attribute)objAttr[i] !; // TODO-NULLABLE Indexer nullability tracked (https://github.com/dotnet/roslyn/issues/34644) count++; } } Attribute[] temp = ret; ret = CreateAttributeArrayHelper(type, temp.Length + count); Array.Copy(temp, 0, ret, 0, temp.Length); int offset = temp.Length; for (int i = 0; i < attributes.Length; i++) { ret[offset + i] = attributes[i]; } baseParam = GetParentDefinition(baseParam); } return(ret); }