// Process the specified AttributeUsage attribute on the given ownerSymbol private void ProcessAttributeUsageAttribute(SourceAttributeData attributeUsageAttribute, Symbol ownerSymbol, AttributeSyntax node, DiagnosticBag diagnostics) { // Validate first ctor argument for AtributeUsage specification is a valid AttributeTargets enum member Debug.Assert(attributeUsageAttribute.AttributeConstructor == GetWellKnownTypeMember(WellKnownMember.System_AttributeUsageAttribute__ctor, diagnostics, node)); var targetArgument = (int)attributeUsageAttribute.PositionalArguments[0].Value; if (!AttributeUsageInfo.IsValidValueForAttributeTargets(targetArgument)) { // invalid attribute target Error(diagnostics, ErrorCode.ERR_InvalidAttributeArgument, node.ArgumentList.Arguments[0], GetAttributeNameFromSyntax(node)); } // AttributeUsage can only be specified for attribute classes if (ownerSymbol.Kind == SymbolKind.NamedType && !((NamedTypeSymbol)ownerSymbol).IsAttributeType(Compilation)) { Error(diagnostics, ErrorCode.ERR_AttributeUsageOnNonAttributeClass, node, GetAttributeNameFromSyntax(node)); } }
private void ProcessExtensionAttribute(SourceAttributeData attributeUsageAttribute, Symbol ownerSymbol, AttributeSyntax node, DiagnosticBag diagnostics, bool validTarget) { if (!validTarget) { return; } // [Extension] attribute should not be set explicitly. Error(diagnostics, ErrorCode.ERR_ExplicitExtension, node, WellKnownType.System_Runtime_CompilerServices_ExtensionAttribute.GetMetadataName()); }
// Process the given well known attribute applied to the given ownerSymbol private void ProcessWellKnownAttribute(SourceAttributeData attribute, Symbol ownerSymbol, AttributeSyntax node, DiagnosticBag diagnostics, bool validTarget) { var wellKnownAttribute = attribute.WellKnownAttribute; Debug.Assert(WellKnownTypes.IsWellKnownAttribute(wellKnownAttribute)); switch (wellKnownAttribute) { case WellKnownType.System_AttributeUsageAttribute: ProcessAttributeUsageAttribute(attribute, ownerSymbol, node, diagnostics); return; case WellKnownType.System_Runtime_CompilerServices_ExtensionAttribute: ProcessExtensionAttribute(attribute, ownerSymbol, node, diagnostics, validTarget); return; case WellKnownType.System_Reflection_DefaultMemberAttribute: ProcessDefaultMemberAttribute(ownerSymbol, node, diagnostics, validTarget); return; case WellKnownType.System_Runtime_CompilerServices_DateTimeConstantAttribute: case WellKnownType.System_Runtime_CompilerServices_DecimalConstantAttribute: case WellKnownType.System_Runtime_CompilerServices_InternalsVisibleToAttribute: // TODO semantic analysis of well known attributes return; } }
/// <summary> /// Verify if the attribute type can be applied to given owner symbol. /// Generate a diagnostic if it cannot be applied /// </summary> /// <param name="ownerSymbol">Symbol on which the attribute is applied</param> /// <param name="attributeType">Attribute class for the attribute</param> /// <param name="node">Syntax node for attribute specification</param> /// <param name="attributeLocation">Attribute target specifier location</param> /// <param name="diagnostics">Diagnostics</param> /// <returns>Whether attribute specification is allowed for the given symbol</returns> internal bool VerifyAttributeUsageTarget(Symbol ownerSymbol, NamedTypeSymbol attributeType, AttributeSyntax node, AttributeLocation attributeLocation, DiagnosticBag diagnostics) { var attributeUsageInfo = attributeType.AttributeUsageInfo(Compilation); if (attributeUsageInfo != null) { AttributeTargets attributeTarget; if (attributeLocation == AttributeLocation.Return) { // attribute on return type attributeTarget = AttributeTargets.ReturnValue; } else { attributeTarget = ownerSymbol.GetAttributeTarget(); } if ((attributeTarget & attributeUsageInfo.ValidTargets) != 0) { return(true); } // generate error Error(diagnostics, ErrorCode.ERR_AttributeOnBadSymbolType, node, GetAttributeNameFromSyntax(node), attributeUsageInfo.GetValidTargetsString()); } return(false); }
public static bool EarlyDecodeIsObsoleteAttribute(NamedTypeSymbol attributeType, AttributeSyntax attributeSyntax) { return(EarlyDecodeIsTargetAttribute(attributeType, attributeSyntax, AttributeDescription.ObsoleteAttribute, skipParamCheck: true)); }
public static bool EarlyDecodeIsConditionalAttribute(NamedTypeSymbol attributeType, AttributeSyntax attributeSyntax) { return(EarlyDecodeIsTargetAttribute(attributeType, attributeSyntax, AttributeDescription.ConditionalAttribute)); }
// compares by namespace and type name, ignores signatures private static bool EarlyDecodeIsTargetAttribute(NamedTypeSymbol attributeType, AttributeSyntax attributeSyntax, AttributeDescription description, bool skipParamCheck = false) { if (!skipParamCheck) { int parameterCount = description.GetParameterCount(signatureIndex: 0); int argumentCount = (attributeSyntax.ArgumentList != null) ? attributeSyntax.ArgumentList.Arguments.Count : 0; if (argumentCount != parameterCount) { return(false); } } Debug.Assert(!attributeType.IsErrorType()); string actualNamespaceName = attributeType.ContainingNamespace.ToDisplayString(SymbolDisplayFormat.QualifiedNameOnlyFormat); return(actualNamespaceName.Equals(description.Namespace) && attributeType.Name.Equals(description.Name)); }