internal void DecodeClassInterfaceAttribute(AttributeSyntax nodeOpt, DiagnosticBag diagnostics) { Debug.Assert(!this.HasErrors); TypedConstant ctorArgument = this.CommonConstructorArguments[0]; Debug.Assert(ctorArgument.Kind == TypedConstantKind.Enum || ctorArgument.Kind == TypedConstantKind.Primitive); ClassInterfaceType interfaceType = ctorArgument.Kind == TypedConstantKind.Enum ? ctorArgument.DecodeValue <ClassInterfaceType>(SpecialType.System_Enum) : (ClassInterfaceType)ctorArgument.DecodeValue <short>(SpecialType.System_Int16); switch (interfaceType) { case ClassInterfaceType.None: case Cci.Constants.ClassInterfaceType_AutoDispatch: case Cci.Constants.ClassInterfaceType_AutoDual: break; default: // CS0591: Invalid value for argument to '{0}' attribute Location attributeArgumentSyntaxLocation = this.GetAttributeArgumentSyntaxLocation(0, nodeOpt); diagnostics.Add(ErrorCode.ERR_InvalidAttributeArgument, attributeArgumentSyntaxLocation, nodeOpt != null ? nodeOpt.GetErrorDisplayName() : ""); break; } }
internal void DecodeInterfaceTypeAttribute(AttributeSyntax node, DiagnosticBag diagnostics) { Debug.Assert(!this.HasErrors); TypedConstant ctorArgument = this.CommonConstructorArguments[0]; Debug.Assert(ctorArgument.Kind == TypedConstantKind.Enum || ctorArgument.Kind == TypedConstantKind.Primitive); ComInterfaceType interfaceType = ctorArgument.Kind == TypedConstantKind.Enum ? ctorArgument.DecodeValue <ComInterfaceType>(SpecialType.System_Enum) : (ComInterfaceType)ctorArgument.DecodeValue <short>(SpecialType.System_Int16); switch (interfaceType) { case Cci.Constants.ComInterfaceType_InterfaceIsDual: case Cci.Constants.ComInterfaceType_InterfaceIsIDispatch: case ComInterfaceType.InterfaceIsIInspectable: case ComInterfaceType.InterfaceIsIUnknown: break; default: // CS0591: Invalid value for argument to '{0}' attribute CSharpSyntaxNode attributeArgumentSyntax = this.GetAttributeArgumentSyntax(0, node); diagnostics.Add(ErrorCode.ERR_InvalidAttributeArgument, attributeArgumentSyntax.Location, node.GetErrorDisplayName()); break; } }
private DeclarativeSecurityAction DecodeSecurityAction(TypedConstant typedValue, Symbol targetSymbol, AttributeSyntax nodeOpt, DiagnosticBag diagnostics, out bool hasErrors) { Debug.Assert((object)targetSymbol != null); Debug.Assert(targetSymbol.Kind == SymbolKind.Assembly || targetSymbol.Kind == SymbolKind.NamedType || targetSymbol.Kind == SymbolKind.Method); int securityAction = (int)typedValue.Value; bool isPermissionRequestAction; switch (securityAction) { case (int)DeclarativeSecurityAction.InheritanceDemand: case (int)DeclarativeSecurityAction.LinkDemand: if (this.IsTargetAttribute(targetSymbol, AttributeDescription.PrincipalPermissionAttribute)) { // CS7052: SecurityAction value '{0}' is invalid for PrincipalPermission attribute string displayString; Location syntaxLocation = GetSecurityAttributeActionSyntaxLocation(nodeOpt, typedValue, out displayString); diagnostics.Add(ErrorCode.ERR_PrincipalPermissionInvalidAction, syntaxLocation, displayString); hasErrors = true; return(DeclarativeSecurityAction.None); } isPermissionRequestAction = false; break; case 1: // Native compiler allows security action value 1 for security attributes on types/methods, even though there is no corresponding field in System.Security.Permissions.SecurityAction enum. // We will maintain compatibility. case (int)DeclarativeSecurityAction.Assert: case (int)DeclarativeSecurityAction.Demand: case (int)DeclarativeSecurityAction.PermitOnly: case (int)DeclarativeSecurityAction.Deny: isPermissionRequestAction = false; break; case (int)DeclarativeSecurityAction.RequestMinimum: case (int)DeclarativeSecurityAction.RequestOptional: case (int)DeclarativeSecurityAction.RequestRefuse: isPermissionRequestAction = true; break; default: { // CS7049: Security attribute '{0}' has an invalid SecurityAction value '{1}' string displayString; Location syntaxLocation = GetSecurityAttributeActionSyntaxLocation(nodeOpt, typedValue, out displayString); diagnostics.Add(ErrorCode.ERR_SecurityAttributeInvalidAction, syntaxLocation, nodeOpt != null ? nodeOpt.GetErrorDisplayName() : "", displayString); hasErrors = true; return(DeclarativeSecurityAction.None); } } // Validate security action for symbol kind if (isPermissionRequestAction) { if (targetSymbol.Kind == SymbolKind.NamedType || targetSymbol.Kind == SymbolKind.Method) { // Types and methods cannot take permission requests. // CS7051: SecurityAction value '{0}' is invalid for security attributes applied to a type or a method string displayString; Location syntaxLocation = GetSecurityAttributeActionSyntaxLocation(nodeOpt, typedValue, out displayString); diagnostics.Add(ErrorCode.ERR_SecurityAttributeInvalidActionTypeOrMethod, syntaxLocation, displayString); hasErrors = true; return(DeclarativeSecurityAction.None); } } else { if (targetSymbol.Kind == SymbolKind.Assembly) { // Assemblies cannot take declarative security. // CS7050: SecurityAction value '{0}' is invalid for security attributes applied to an assembly string displayString; Location syntaxLocation = GetSecurityAttributeActionSyntaxLocation(nodeOpt, typedValue, out displayString); diagnostics.Add(ErrorCode.ERR_SecurityAttributeInvalidActionAssembly, syntaxLocation, displayString); hasErrors = true; return(DeclarativeSecurityAction.None); } } hasErrors = false; return((DeclarativeSecurityAction)securityAction); }
internal string DecodeGuidAttribute(AttributeSyntax nodeOpt, DiagnosticBag diagnostics) { Debug.Assert(!this.HasErrors); var guidString = (string)this.CommonConstructorArguments[0].Value; // Native compiler allows only a specific GUID format: "D" format (32 digits separated by hyphens) Guid guid; if (!Guid.TryParseExact(guidString, "D", out guid)) { // CS0591: Invalid value for argument to '{0}' attribute Location attributeArgumentSyntaxLocation = this.GetAttributeArgumentSyntaxLocation(0, nodeOpt); diagnostics.Add(ErrorCode.ERR_InvalidAttributeArgument, attributeArgumentSyntaxLocation, (object)nodeOpt != null ? nodeOpt.GetErrorDisplayName() : ""); guidString = String.Empty; } return(guidString); }
private void ValidateConditionalAttribute(CSharpAttributeData attribute, AttributeSyntax node, DiagnosticBag diagnostics) { Debug.Assert(this.IsConditional); Debug.Assert(!attribute.HasErrors); if (!this.DeclaringCompilation.IsAttributeType(this)) { // CS1689: Attribute '{0}' is only valid on methods or attribute classes diagnostics.Add(ErrorCode.ERR_ConditionalOnNonAttributeClass, node.Location, node.GetErrorDisplayName()); } else { string name = attribute.GetConstructorArgument <string>(0, SpecialType.System_String); if (name == null || !SyntaxFacts.IsValidIdentifier(name)) { // CS0633: The argument to the '{0}' attribute must be a valid identifier CSharpSyntaxNode attributeArgumentSyntax = attribute.GetAttributeArgumentSyntax(0, node); diagnostics.Add(ErrorCode.ERR_BadArgumentToAttribute, attributeArgumentSyntax.Location, node.GetErrorDisplayName()); } } }
// Process the specified AttributeUsage attribute on the given ownerSymbol private AttributeUsageInfo DecodeAttributeUsageAttribute(CSharpAttributeData attribute, AttributeSyntax node, bool diagnose, DiagnosticBag diagnosticsOpt = null) { Debug.Assert(diagnose == (diagnosticsOpt != null)); Debug.Assert(!attribute.HasErrors); Debug.Assert(!this.IsErrorType()); // AttributeUsage can only be specified for attribute classes if (!this.DeclaringCompilation.IsAttributeType(this)) { if (diagnose) { diagnosticsOpt.Add(ErrorCode.ERR_AttributeUsageOnNonAttributeClass, node.Name.Location, node.GetErrorDisplayName()); } return(AttributeUsageInfo.Null); } else { AttributeUsageInfo info = attribute.DecodeAttributeUsageAttribute(); // Validate first ctor argument for AttributeUsage specification is a valid AttributeTargets enum member if (!info.HasValidAttributeTargets) { if (diagnose) { // invalid attribute target CSharpSyntaxNode attributeArgumentSyntax = attribute.GetAttributeArgumentSyntax(0, node); diagnosticsOpt.Add(ErrorCode.ERR_InvalidAttributeArgument, attributeArgumentSyntax.Location, node.GetErrorDisplayName()); } return(AttributeUsageInfo.Null); } return(info); } }
/// <summary> /// Validate attribute usage target and duplicate attributes. /// </summary> /// <param name="attribute">Bound attribute</param> /// <param name="node">Syntax node for attribute specification</param> /// <param name="compilation">Compilation</param> /// <param name="symbolPart">Symbol part to which the attribute has been applied.</param> /// <param name="diagnostics">Diagnostics</param> /// <param name="uniqueAttributeTypes">Set of unique attribute types applied to the symbol</param> private bool ValidateAttributeUsage( CSharpAttributeData attribute, AttributeSyntax node, CSharpCompilation compilation, AttributeLocation symbolPart, DiagnosticBag diagnostics, HashSet <NamedTypeSymbol> uniqueAttributeTypes) { Debug.Assert(!attribute.HasErrors); NamedTypeSymbol attributeType = attribute.AttributeClass; AttributeUsageInfo attributeUsageInfo = attributeType.GetAttributeUsageInfo(); // Given attribute can't be specified more than once if AllowMultiple is false. if (!uniqueAttributeTypes.Add(attributeType) && !attributeUsageInfo.AllowMultiple) { diagnostics.Add(ErrorCode.ERR_DuplicateAttribute, node.Name.Location, node.Name); return(false); } // Verify if the attribute type can be applied to given owner symbol. AttributeTargets attributeTarget; if (symbolPart == AttributeLocation.Return) { // attribute on return type Debug.Assert(this.Kind == SymbolKind.Method); attributeTarget = AttributeTargets.ReturnValue; } else { attributeTarget = this.GetAttributeTarget(); } if ((attributeTarget & attributeUsageInfo.ValidTargets) == 0) { // generate error diagnostics.Add(ErrorCode.ERR_AttributeOnBadSymbolType, node.Name.Location, node.Name, attributeUsageInfo.GetValidTargetsErrorArgument()); return(false); } if (attribute.IsSecurityAttribute(compilation)) { switch (this.Kind) { case SymbolKind.Assembly: case SymbolKind.NamedType: case SymbolKind.Method: break; default: // CS7070: Security attribute '{0}' is not valid on this declaration type. Security attributes are only valid on assembly, type and method declarations. diagnostics.Add(ErrorCode.ERR_SecurityAttributeInvalidTarget, node.Name.Location, node.GetErrorDisplayName()); return(false); } } return(true); }