Example #1
0
		private void CheckAttributeUsageCardinality(Attribute node, Type attrType, AttributeUsageAttribute usage)
		{
			if (usage.AllowMultiple)
				return;

			if (HasSiblingAttributesOfSameType(node, attrType))
				MultipleAttributeUsageError(node, attrType);
		}
Example #2
0
		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;
    }
Example #4
0
        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;
        }
Example #5
0
		private void CheckAttributeUsage(Attribute node, Type attrType, AttributeUsageAttribute usage)
		{
			CheckAttributeUsageTarget(node, attrType, usage);
			CheckAttributeUsageCardinality(node, attrType, usage);
		}
Example #6
0
		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;
		}
Example #7
0
        [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;
        }
Example #8
0
        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);
        }
Example #9
0
		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;
			}
Example #11
0
            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;
            }
Example #12
0
            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;
                }
            }
Example #13
0
 internal CAData(Type caType, AttributeUsageAttribute usage, int level) {
     this.caType = caType; 
     this.usage = usage; 
     this.level = level; 
 }
Example #14
0
 public AttributeInfo(AttributeUsageAttribute usage, int inheritanceLevel)
 {
     _usage            = usage;
     _inheritanceLevel = inheritanceLevel;
 }
Example #15
0
		private static AttributeTargets ValidAttributeTargetsFor(Type attrType, AttributeUsageAttribute usage)
		{
			return IsExtensionAttribute(attrType)
				? usage.ValidOn | AttributeTargets.Property
				: usage.ValidOn;
		}
Example #16
0
 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;
 }
Example #17
0
 public AttributeUsageWrapper(AttributeUsageAttribute usage)
 {
     this.usage = usage;
 }
Example #18
0
        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;
        }
Example #19
0
			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;
			}
Example #20
0
		private static bool IsValid(AttributeUsageAttribute usage, AttributeTargets target)
		{
			return target == (usage.ValidOn & target);
		}
Example #21
0
        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);
        }