// 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; }
internal static bool TryGetInformation(AttributeSyntax node, out int id, out string description) { id = 0; description = null; var name = node.Name as IdentifierNameSyntax; if (name?.Identifier.Text != "WorkItem") { return false; } var args = GetArgs(node); if (args.Count == 1 && int.TryParse(args[0], out id)) { return true; } if (args.Count == 2 && int.TryParse(args[0], out id)) { description = args[1].ToString(); return true; } return false; }
public override void VisitAttribute(AttributeSyntax node) { var symbol = _semanticModel.GetSymbol(node); if (symbol != null) CreateTag(node.Name.Name, _classificationService.FunctionIdentifier); base.VisitAttribute(node); }
private static List<string> GetArgs(AttributeSyntax node) { var list = new List<string>(); foreach (var arg in node.ArgumentList.Arguments) { list.Add(arg.GetExpression().ToString().Replace("\"", "")); } return list; }
internal static AttributeSyntax UpdateAttribute(AttributeSyntax node, int id, string url) { var descriptionArg = SyntaxFactory.SimpleArgument( SyntaxFactory.LiteralExpression( SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(value: url).WithLeadingTrivia(SyntaxFactory.Space))); var idArg = SyntaxFactory.SimpleArgument( SyntaxFactory.LiteralExpression( SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(value: id))); var list = SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList<ArgumentSyntax>(new[] { idArg, descriptionArg })); return node.WithArgumentList(list); }
// 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); }
// 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()); }
public override SyntaxNode VisitAttribute(AttributeSyntax node) { return(node); }
internal static CSharpSyntaxNode GetAttributeArgumentSyntax(this AttributeData attribute, int parameterIndex, AttributeSyntax attributeSyntax) { Debug.Assert(attribute is SourceAttributeData); return(((SourceAttributeData)attribute).GetAttributeArgumentSyntax(parameterIndex, attributeSyntax)); }
public BasicSchemaAttribute(int id, string name, AttributeSyntax syntax) { this.Id = id; this.Name = name; this.Syntax = syntax; }
public UpdateOrAddGenericDebtAttribute(AttributeSyntax newAttribute) : base(false) { NewAttribute = newAttribute; }
public static ExpressionSyntax GetPositionExpression(this AttributeSyntax node, int position) { var candidate = FindByPosition(node.ArgumentList, position); return(candidate?.Expression); }
private void ProcessDefaultMemberAttribute(Symbol ownerSymbol, AttributeSyntax node, DiagnosticBag diagnostics, bool validTarget) { if (!validTarget) { return; } NamedTypeSymbol ownerType = (NamedTypeSymbol)ownerSymbol; //cast should succeed since validTarget is true if (ownerType.Indexers.Any()) { Error(diagnostics, ErrorCode.ERR_DefaultMemberOnIndexedType, node); } }
public static bool EarlyDecodeIsConditionalAttribute(NamedTypeSymbol attributeType, AttributeSyntax attributeSyntax) { return EarlyDecodeIsTargetAttribute(attributeType, attributeSyntax, AttributeDescription.ConditionalAttribute); }
public FixedLengthBehavior(AttributeSyntax attributeSyntax) : base(attributeSyntax) { TryEvaluateIntArgument(out int length); Length = length; }
internal static bool IsEntityTriggerAttribute(AttributeSyntax attribute) => IsSpecifiedAttribute(attribute, "EntityTrigger");
internal static bool TryGetParameterNodeNextToAttribute(SyntaxNodeAnalysisContext context, AttributeSyntax attributeExpression, out SyntaxNode inputType) { var parameter = attributeExpression.Parent.Parent; return(TryGetChildTypeNode(parameter, out inputType)); }
private static bool IsArgumentListToken(AttributeSyntax expression, SyntaxToken token) { return(expression.ArgumentList != null && expression.ArgumentList.Span.Contains(token.SpanStart) && token != expression.ArgumentList.CloseParenToken); }
private BoundAttribute BindAttribute(AttributeSyntax syntax) { var attributeSymbol = IntrinsicAttributes.AllAttributes.FirstOrDefault(x => x.Name == syntax.Name.Name.Text) ?? new AttributeSymbol(syntax.Name.Name.Text, string.Empty); return new BoundAttribute(attributeSymbol); }
public void VisitAttribute(AttributeSyntax node) { if (node == null) throw new ArgumentNullException("node"); node.Validate(); node.Name.Accept(this); if (node.ArgumentList != null) node.ArgumentList.Accept(this); }
private static bool TryGetFirstMismatch(IMethodSymbol methodSymbol, AttributeSyntax attributeSyntax, SyntaxNodeAnalysisContext context, out AttributeArgumentSyntax attributeArgument) { attributeArgument = null; if (methodSymbol.Parameters.Length > 0 && methodSymbol.Parameters != null && attributeSyntax.ArgumentList is AttributeArgumentListSyntax argumentList && argumentList.Arguments.Count > 0) { for (var i = 0; i < Math.Min(CountArgs(attributeSyntax), methodSymbol.Parameters.Length); i++) { var argument = argumentList.Arguments[i]; var parameter = methodSymbol.Parameters[i]; if (argument is null || argument.NameEquals != null || parameter is null) { attributeArgument = argument; return(true); } if (parameter.IsParams && parameter.Type is IArrayTypeSymbol arrayType) { for (var j = i; j < CountArgs(attributeSyntax); j++) { if (!IsTypeMatch(arrayType.ElementType, argument)) { attributeArgument = argument; return(true); } } return(false); } if (!IsTypeMatch(parameter.Type, argument)) { attributeArgument = argument; return(true); } } } return(false); bool IsTypeMatch(ITypeSymbol parameterType, AttributeArgumentSyntax argument) { if (parameterType == KnownSymbol.Object) { return(true); } if (parameterType is ITypeParameterSymbol typeParameter) { foreach (var constraintType in typeParameter.ConstraintTypes) { if (constraintType is INamedTypeSymbol namedType && namedType.IsGenericType && namedType.TypeArguments.Any(x => x is ITypeParameterSymbol)) { // Lazy here. continue; } if (!IsTypeMatch(constraintType, argument)) { return(false); } } return(true); } if (argument.Expression.IsKind(SyntaxKind.NullLiteralExpression)) { if (parameterType.IsValueType && parameterType.Name != "Nullable") { return(false); } return(true); } if (!argument.Expression.IsAssignableTo(parameterType, context.SemanticModel)) { return(false); } return(true); } }
public override void VisitAttribute(AttributeSyntax node) { CreateTag(node.Name.Name, _classificationService.ClassIdentifier); base.VisitAttribute(node); }
private static bool TrySingleTestAttribute(MethodDeclarationSyntax method, SemanticModel semanticModel, CancellationToken cancellationToken, out AttributeSyntax attribute) { attribute = null; var count = 0; foreach (var attributeList in method.AttributeLists) { foreach (var candidate in attributeList.Attributes) { if (Roslyn.AnalyzerExtensions.Attribute.IsType(candidate, KnownSymbol.NUnitTestAttribute, semanticModel, cancellationToken)) { attribute = candidate; count++; } else if (Roslyn.AnalyzerExtensions.Attribute.IsType(candidate, KnownSymbol.NUnitTestCaseAttribute, semanticModel, cancellationToken) || Roslyn.AnalyzerExtensions.Attribute.IsType(candidate, KnownSymbol.NUnitTestCaseSourceAttribute, semanticModel, cancellationToken)) { count++; } } } return(count == 1 && attribute != null); }
public static ExpressionSyntax GetNameEqualsExpression(this AttributeSyntax node, string nameEquals) { var candidate = FindByNameEquals(node.ArgumentList, nameEquals); return(candidate?.Expression); }
/// <summary> /// Creates an AttributeSemanticModel that allows asking semantic questions about an attribute node. /// </summary> public static AttributeSemanticModel Create(SyntaxTreeSemanticModel containingSemanticModel, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Symbol?attributeTarget, Binder rootBinder, ImmutableDictionary <Symbol, Symbol> parentRemappedSymbolsOpt) { rootBinder = attributeTarget is null ? rootBinder : new ContextualAttributeBinder(rootBinder, attributeTarget); return(new AttributeSemanticModel(syntax, attributeType, aliasOpt, rootBinder, containingSemanticModel, parentRemappedSymbolsOpt: parentRemappedSymbolsOpt)); }
public static MethodDeclarationSyntax AddAttribute(this MethodDeclarationSyntax node, AttributeSyntax attr) { var existing = node.AttributeLists; var last = existing.Last(); var list = new SeparatedSyntaxList <AttributeSyntax>(); list = list.Add(attr); var newList = SyntaxFactory.AttributeList(list) .WithLeadingTrivia(last.GetClosestWhitespaceTrivia(true)) .WithTrailingTrivia(last.GetClosestWhitespaceTrivia(false)); existing = existing.Add(newList); node = node.WithAttributeLists(existing); return(node); }
private DeclarativeSecurityAction DecodeSecurityAttributeAction(Symbol targetSymbol, CSharpCompilation compilation, AttributeSyntax nodeOpt, out bool hasErrors, DiagnosticBag diagnostics) { Debug.Assert((object)targetSymbol != null); Debug.Assert(targetSymbol.Kind == SymbolKind.Assembly || targetSymbol.Kind == SymbolKind.NamedType || targetSymbol.Kind == SymbolKind.Method); Debug.Assert(this.IsSecurityAttribute(compilation)); var ctorArgs = this.CommonConstructorArguments; if (!ctorArgs.Any()) { // NOTE: Security custom attributes must have a valid SecurityAction as its first argument, we have none here. // NOTE: Ideally, we should always generate 'CS7048: First argument to a security attribute must be a valid SecurityAction' for this case. // NOTE: However, native compiler allows applying System.Security.Permissions.HostProtectionAttribute attribute without any argument and uses // NOTE: SecurityAction.LinkDemand as the default SecurityAction in this case. We maintain compatibility with the native compiler for this case. // BREAKING CHANGE: Even though the native compiler intends to allow only HostProtectionAttribute to be applied without any arguments, // it doesn't quite do this correctly // The implementation issue leads to the native compiler allowing any user defined security attribute with a parameterless constructor and a named property argument as the first // attribute argument to have the above mentioned behavior, even though the comment clearly mentions that this behavior was intended only for the HostProtectionAttribute. // We currently allow this case only for the HostProtectionAttribute. In future if need arises, we can exactly match native compiler's behavior. if (this.IsTargetAttribute(targetSymbol, AttributeDescription.HostProtectionAttribute)) { hasErrors = false; return(DeclarativeSecurityAction.LinkDemand); } } else { TypedConstant firstArg = ctorArgs.First(); TypeSymbol firstArgType = (TypeSymbol)firstArg.Type; if ((object)firstArgType != null && firstArgType.Equals(compilation.GetWellKnownType(WellKnownType.System_Security_Permissions_SecurityAction))) { return(DecodeSecurityAction(firstArg, targetSymbol, nodeOpt, diagnostics, out hasErrors)); } } // CS7048: First argument to a security attribute must be a valid SecurityAction diagnostics.Add(ErrorCode.ERR_SecurityAttributeMissingAction, nodeOpt != null ? nodeOpt.Name.Location : NoLocation.Singleton); hasErrors = true; return(DeclarativeSecurityAction.None); }
public virtual void VisitAttribute(AttributeSyntax node) { DefaultVisit(node); }
public static string GetAttributeSyntaxOid(AttributeSyntax syntax) { // This is a static mapping, because the prefix table might not be available, when this is first needed. int lastOctet = syntax - AttributeSyntax.Undefined; return String.Format(AttributeSyntaxOidFormat, lastOctet); }
public static bool EarlyDecodeIsObsoleteAttribute(NamedTypeSymbol attributeType, AttributeSyntax attributeSyntax) { return EarlyDecodeIsTargetAttribute(attributeType, attributeSyntax, AttributeDescription.ObsoleteAttribute, skipParamCheck:true); }
/// <summary> /// Method to early decode the type of well-known attribute which can be queried during the BindAttributeType phase. /// This method is called first during attribute binding so that any attributes that affect semantics of type binding /// can be decoded here. /// </summary> /// <remarks> /// NOTE: If you are early decoding any new well-known attribute, make sure to update PostEarlyDecodeWellKnownAttributeTypes /// to default initialize this data. /// </remarks> internal virtual void EarlyDecodeWellKnownAttributeType(NamedTypeSymbol attributeType, AttributeSyntax attributeSyntax) { }
private static bool TryFindIdentical(MethodDeclarationSyntax method, AttributeSyntax attribute, SyntaxNodeAnalysisContext context, out AttributeSyntax identical) { if (Roslyn.AnalyzerExtensions.Attribute.TryGetTypeName(attribute, out var name)) { foreach (var attributeList in method.AttributeLists) { foreach (var candidate in attributeList.Attributes) { if (Roslyn.AnalyzerExtensions.Attribute.TryGetTypeName(candidate, out var candidateName) && name == candidateName && !ReferenceEquals(candidate, attribute) && IsIdentical(attribute, candidate)) { identical = candidate; return(true); } } } } identical = null; return(false); bool IsIdentical(AttributeSyntax x, AttributeSyntax y) { if (x.ArgumentList == null && y.ArgumentList == null) { return(true); } if (x.ArgumentList == null || y.ArgumentList == null) { return(false); } if (x.ArgumentList.Arguments.LastIndexOf(a => a.NameEquals == null) != y.ArgumentList.Arguments.LastIndexOf(a => a.NameEquals == null)) { return(false); } for (var i = 0; i < Math.Min(x.ArgumentList.Arguments.Count, y.ArgumentList.Arguments.Count); i++) { var xa = x.ArgumentList.Arguments[i]; var ya = y.ArgumentList.Arguments[i]; if (xa.NameEquals != null || ya.NameEquals != null) { return(xa.NameEquals != null && ya.NameEquals != null); } if (xa.Expression is LiteralExpressionSyntax xl && ya.Expression is LiteralExpressionSyntax yl) { if (xl.Token.Text == yl.Token.Text) { continue; } return(false); } if (xa.Expression is IdentifierNameSyntax xn && ya.Expression is IdentifierNameSyntax yn) { if (xn.Identifier.ValueText == yn.Identifier.ValueText && context.SemanticModel.TryGetSymbol(xn, context.CancellationToken, out ISymbol xs) && context.SemanticModel.TryGetSymbol(yn, context.CancellationToken, out ISymbol ys) && xs.Equals(ys)) { continue; } return(false); } if (xa.Expression is MemberAccessExpressionSyntax xma && ya.Expression is MemberAccessExpressionSyntax yma) { if (xma.Name.Identifier.ValueText == yma.Name.Identifier.ValueText && context.SemanticModel.TryGetSymbol(xma, context.CancellationToken, out ISymbol xs) && context.SemanticModel.TryGetSymbol(yma, context.CancellationToken, out ISymbol ys) && xs.Equals(ys)) { continue; } return(false); } if (TryGetArrayExpressions(xa.Expression, out var xExpressions) && TryGetArrayExpressions(ya.Expression, out var yExpressions)) { if (xExpressions.Count != yExpressions.Count) { return(false); } for (var j = 0; j < xExpressions.Count; j++) { if (xExpressions[j] is LiteralExpressionSyntax xLiteral && yExpressions[j] is LiteralExpressionSyntax yLiteral && xLiteral.Token.Text != yLiteral.Token.Text) { return(false); } } continue; } return(false); } return(true); } }
public static string GetTypeName(this AttributeSyntax attributeSyntax) => attributeSyntax.Name switch {
internal static bool IsNullableAnalysisEnabledIn(CSharpCompilation compilation, AttributeSyntax syntax) { return(compilation.IsNullableAnalysisEnabledIn(syntax)); }
static CodeAction CreateAttributeCodeAction(Document document, SyntaxNode root, ExpressionSyntax node, IMethodSymbol constructor, AttributeSyntax attribute) { var arguments = attribute.ArgumentList.Arguments; var idx = arguments.IndexOf(node.Parent as AttributeArgumentSyntax); var name = constructor.Parameters[idx].Name; return(CodeActionFactory.Create( node.Span, DiagnosticSeverity.Info, string.Format(GettextCatalog.GetString("Add argument name '{0}'"), name), t2 => { var newArguments = SyntaxFactory.SeparatedList <AttributeArgumentSyntax>( attribute.ArgumentList.Arguments.Take(idx).Concat( attribute.ArgumentList.Arguments.Skip(idx).Select((arg, i) => { if (arg.NameEquals != null) { return arg; } return SyntaxFactory.AttributeArgument(null, SyntaxFactory.NameColon(constructor.Parameters[i + idx].Name), arg.Expression); }) ) ); var newAttribute = attribute.WithArgumentList(attribute.ArgumentList.WithArguments(newArguments)); var newRoot = root.ReplaceNode((SyntaxNode)attribute, newAttribute).WithAdditionalAnnotations(Formatter.Annotation); return Task.FromResult(document.WithSyntaxRoot(newRoot)); } )); }
/// <summary> /// Creates a speculative AttributeSemanticModel that allows asking semantic questions about an attribute node that did not appear in the original source code. /// </summary> public static AttributeSemanticModel CreateSpeculative(SyntaxTreeSemanticModel parentSemanticModel, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Binder rootBinder, ImmutableDictionary <Symbol, Symbol> parentRemappedSymbolsOpt, int position) { Debug.Assert(parentSemanticModel != null); Debug.Assert(rootBinder != null); Debug.Assert(rootBinder.IsSemanticModelBinder); return(new AttributeSemanticModel(syntax, attributeType, aliasOpt, rootBinder, parentSemanticModelOpt: parentSemanticModel, parentRemappedSymbolsOpt: parentRemappedSymbolsOpt, speculatedPosition: position)); }
private static Task <Document> AddJustificationToAttributeAsync(Document document, SyntaxNode syntaxRoot, AttributeSyntax attribute) { var attributeName = SyntaxFactory.IdentifierName(nameof(SuppressMessageAttribute.Justification)); var newArgument = SyntaxFactory.AttributeArgument(SyntaxFactory.NameEquals(attributeName), null, GetNewAttributeValue()); var newArgumentList = attribute.ArgumentList.AddArguments(newArgument); return(Task.FromResult(document.WithSyntaxRoot(syntaxRoot.ReplaceNode(attribute.ArgumentList, newArgumentList)))); }
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 override void EarlyDecodeWellKnownAttributeType(NamedTypeSymbol attributeType, AttributeSyntax attributeSyntax) { Debug.Assert(!attributeType.IsErrorType()); // NOTE: OptionalAttribute is decoded specially before any of the other attributes and stored in the parameter // symbol (rather than in the EarlyWellKnownAttributeData) because it is needed during overload resolution. if (CSharpAttributeData.IsTargetEarlyAttribute(attributeType, attributeSyntax, AttributeDescription.OptionalAttribute)) { _lazyHasOptionalAttribute = ThreeState.True; } }
internal static Location GetAttributeArgumentSyntaxLocation(this AttributeData attribute, int parameterIndex, AttributeSyntax attributeSyntaxOpt) { if (attributeSyntaxOpt == null) { return(NoLocation.Singleton); } Debug.Assert(attribute is SourceAttributeData); return(((SourceAttributeData)attribute).GetAttributeArgumentSyntax(parameterIndex, attributeSyntaxOpt).Location); }
private ConstantValue DecodeDefaultParameterValueAttribute(AttributeDescription description, CSharpAttributeData attribute, AttributeSyntax node, bool diagnose, DiagnosticBag diagnosticsOpt) { Debug.Assert(!attribute.HasErrors); if (description.Equals(AttributeDescription.DefaultParameterValueAttribute)) { return(DecodeDefaultParameterValueAttribute(attribute, node, diagnose, diagnosticsOpt)); } else if (description.Equals(AttributeDescription.DecimalConstantAttribute)) { return(attribute.DecodeDecimalConstantValue()); } else { Debug.Assert(description.Equals(AttributeDescription.DateTimeConstantAttribute)); return(attribute.DecodeDateTimeConstantValue()); } }
public override SyntaxNode VisitAttribute(AttributeSyntax node) { int id; string description; if (!BasicAttributeUtil.TryGetInformation(node, out id, out description)) { return node; } var info = _workItemUtil.GetUpdatedWorkItemInfo(_filePath, node.GetLocation().GetMappedLineSpan(), id, description); if (info.HasValue) { node = BasicAttributeUtil.UpdateAttribute(node, info.Value.Id, info.Value.Description); } return node; }
private ConstantValue DecodeDefaultParameterValueAttribute(CSharpAttributeData attribute, AttributeSyntax node, bool diagnose, DiagnosticBag diagnosticsOpt) { Debug.Assert(!diagnose || diagnosticsOpt != null); if (HasDefaultArgumentSyntax) { // error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute if (diagnose) { diagnosticsOpt.Add(ErrorCode.ERR_DefaultValueUsedWithAttributes, node.Name.Location); } return(ConstantValue.Bad); } // BREAK: In dev10, DefaultParameterValueAttribute could not be applied to System.Type or array parameters. // When this was attempted, dev10 produced CS1909, ERR_DefaultValueBadParamType. Roslyn takes a different // approach: instead of looking at the parameter type, we look at the argument type. There's nothing wrong // with providing a default value for a System.Type or array parameter, as long as the default parameter // is not a System.Type or an array (i.e. null is fine). Since we are no longer interested in the type of // the parameter, all occurrences of CS1909 have been replaced with CS1910, ERR_DefaultValueBadValueType, // to indicate that the argument type, rather than the parameter type, is the source of the problem. Debug.Assert(attribute.CommonConstructorArguments.Length == 1); // the type of the value is the type of the expression in the attribute: var arg = attribute.CommonConstructorArguments[0]; SpecialType specialType = arg.Kind == TypedConstantKind.Enum ? ((INamedTypeSymbol)arg.Type).EnumUnderlyingType.SpecialType : arg.Type.SpecialType; var compilation = this.DeclaringCompilation; var constantValueDiscriminator = ConstantValue.GetDiscriminator(specialType); HashSet <DiagnosticInfo> useSiteDiagnostics = null; if (constantValueDiscriminator == ConstantValueTypeDiscriminator.Bad) { if (arg.Kind != TypedConstantKind.Array && arg.Value == null) { if (this.Type.IsReferenceType) { constantValueDiscriminator = ConstantValueTypeDiscriminator.Null; } else { // error CS1908: The type of the argument to the DefaultParameterValue attribute must match the parameter type if (diagnose) { diagnosticsOpt.Add(ErrorCode.ERR_DefaultValueTypeMustMatch, node.Name.Location); } return(ConstantValue.Bad); } } else { // error CS1910: Argument of type '{0}' is not applicable for the DefaultParameterValue attribute if (diagnose) { diagnosticsOpt.Add(ErrorCode.ERR_DefaultValueBadValueType, node.Name.Location, arg.Type); } return(ConstantValue.Bad); } } else if (!compilation.Conversions.ClassifyConversion((TypeSymbol)arg.Type, this.Type, ref useSiteDiagnostics).Kind.IsImplicitConversion()) { // error CS1908: The type of the argument to the DefaultParameterValue attribute must match the parameter type if (diagnose) { diagnosticsOpt.Add(ErrorCode.ERR_DefaultValueTypeMustMatch, node.Name.Location); diagnosticsOpt.Add(node.Name.Location, useSiteDiagnostics); } return(ConstantValue.Bad); } if (diagnose) { diagnosticsOpt.Add(node.Name.Location, useSiteDiagnostics); } return(ConstantValue.Create(arg.Value, constantValueDiscriminator)); }
private bool IsValidCallerInfoContext(AttributeSyntax node) { return(!ContainingSymbol.IsExplicitInterfaceImplementation() && !ContainingSymbol.IsOperator() && !IsOnPartialImplementation(node)); }
public override void VisitAttribute(AttributeSyntax node) { throw new NotImplementedException(); }
private async Task <Document> ConvertToAsyncPackageAsync(CodeFixContext context, Diagnostic diagnostic, CancellationToken cancellationToken) { var semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var compilation = await context.Document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); var root = await context.Document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var baseTypeSyntax = root.FindNode(diagnostic.Location.SourceSpan).FirstAncestorOrSelf <BaseTypeSyntax>(); var classDeclarationSyntax = baseTypeSyntax.FirstAncestorOrSelf <ClassDeclarationSyntax>(); var initializeMethodSyntax = classDeclarationSyntax.DescendantNodes() .OfType <MethodDeclarationSyntax>() .FirstOrDefault(method => method.Modifiers.Any(modifier => modifier.IsKind(SyntaxKind.OverrideKeyword)) && method.Identifier.Text == Types.Package.Initialize); var baseInitializeInvocationSyntax = initializeMethodSyntax?.Body?.DescendantNodes() .OfType <InvocationExpressionSyntax>() .FirstOrDefault(ies => ies.Expression is MemberAccessExpressionSyntax memberAccess && memberAccess.Name?.Identifier.Text == Types.Package.Initialize && memberAccess.Expression is BaseExpressionSyntax); var getServiceInvocationsSyntax = new List <InvocationExpressionSyntax>(); AttributeSyntax packageRegistrationSyntax = null; { var userClassSymbol = semanticModel.GetDeclaredSymbol(classDeclarationSyntax, context.CancellationToken); var packageRegistrationType = compilation.GetTypeByMetadataName(Types.PackageRegistrationAttribute.FullName); var packageRegistrationInstance = userClassSymbol?.GetAttributes().FirstOrDefault(a => a.AttributeClass == packageRegistrationType); if (packageRegistrationInstance?.ApplicationSyntaxReference != null) { packageRegistrationSyntax = (AttributeSyntax)await packageRegistrationInstance.ApplicationSyntaxReference.GetSyntaxAsync(cancellationToken).ConfigureAwait(false); } } if (initializeMethodSyntax != null) { getServiceInvocationsSyntax.AddRange( from invocation in initializeMethodSyntax.DescendantNodes().OfType <InvocationExpressionSyntax>() let memberBinding = invocation.Expression as MemberAccessExpressionSyntax let identifierName = invocation.Expression as IdentifierNameSyntax where identifierName?.Identifier.Text == Types.Package.GetService || (memberBinding.Name.Identifier.Text == Types.Package.GetService && memberBinding.Expression.IsKind(SyntaxKind.ThisExpression)) select invocation); } // Make it easier to track nodes across changes. var nodesToTrack = new List <SyntaxNode> { baseTypeSyntax, initializeMethodSyntax, baseInitializeInvocationSyntax, packageRegistrationSyntax, }; nodesToTrack.AddRange(getServiceInvocationsSyntax); nodesToTrack.RemoveAll(n => n == null); var updatedRoot = root.TrackNodes(nodesToTrack); // Replace the Package base type with AsyncPackage baseTypeSyntax = updatedRoot.GetCurrentNode(baseTypeSyntax); var asyncPackageBaseTypeSyntax = SyntaxFactory.SimpleBaseType(Types.AsyncPackage.TypeSyntax.WithAdditionalAnnotations(Simplifier.Annotation)) .WithLeadingTrivia(baseTypeSyntax.GetLeadingTrivia()) .WithTrailingTrivia(baseTypeSyntax.GetTrailingTrivia()); updatedRoot = updatedRoot.ReplaceNode(baseTypeSyntax, asyncPackageBaseTypeSyntax); // Update the PackageRegistration attribute if (packageRegistrationSyntax != null) { var trueExpression = SyntaxFactory.LiteralExpression(SyntaxKind.TrueLiteralExpression); packageRegistrationSyntax = updatedRoot.GetCurrentNode(packageRegistrationSyntax); var allowsBackgroundLoadingSyntax = packageRegistrationSyntax.ArgumentList.Arguments.FirstOrDefault(a => a.NameEquals?.Name?.Identifier.Text == Types.PackageRegistrationAttribute.AllowsBackgroundLoading); if (allowsBackgroundLoadingSyntax != null) { updatedRoot = updatedRoot.ReplaceNode( allowsBackgroundLoadingSyntax, allowsBackgroundLoadingSyntax.WithExpression(trueExpression)); } else { updatedRoot = updatedRoot.ReplaceNode( packageRegistrationSyntax, packageRegistrationSyntax.AddArgumentListArguments( SyntaxFactory.AttributeArgument(trueExpression).WithNameEquals(SyntaxFactory.NameEquals(Types.PackageRegistrationAttribute.AllowsBackgroundLoading)))); } } // Find the Initialize override, if present, and update it to InitializeAsync if (initializeMethodSyntax != null) { var cancellationTokenLocalVarName = SyntaxFactory.IdentifierName("cancellationToken"); var progressLocalVarName = SyntaxFactory.IdentifierName("progress"); initializeMethodSyntax = updatedRoot.GetCurrentNode(initializeMethodSyntax); var newBody = initializeMethodSyntax.Body; var leadingTrivia = SyntaxFactory.TriviaList( SyntaxFactory.Comment(@"// When initialized asynchronously, we *may* be on a background thread at this point."), SyntaxFactory.LineFeed, SyntaxFactory.Comment(@"// Do any initialization that requires the UI thread after switching to the UI thread."), SyntaxFactory.LineFeed, SyntaxFactory.Comment(@"// Otherwise, remove the switch to the UI thread if you don't need it."), SyntaxFactory.LineFeed); var switchToMainThreadStatement = SyntaxFactory.ExpressionStatement( SyntaxFactory.AwaitExpression( SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.ThisExpression(), SyntaxFactory.IdentifierName(Types.ThreadHelper.JoinableTaskFactory)), SyntaxFactory.IdentifierName(Types.JoinableTaskFactory.SwitchToMainThreadAsync))) .AddArgumentListArguments(SyntaxFactory.Argument(cancellationTokenLocalVarName)))) .WithLeadingTrivia(leadingTrivia) .WithTrailingTrivia(SyntaxFactory.LineFeed); if (baseInitializeInvocationSyntax != null) { var baseInitializeAsyncInvocationBookmark = new SyntaxAnnotation(); var baseInitializeAsyncInvocationSyntax = SyntaxFactory.AwaitExpression( baseInitializeInvocationSyntax .WithLeadingTrivia() .WithExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.BaseExpression(), SyntaxFactory.IdentifierName(Types.AsyncPackage.InitializeAsync))) .AddArgumentListArguments( SyntaxFactory.Argument(cancellationTokenLocalVarName), SyntaxFactory.Argument(progressLocalVarName))) .WithLeadingTrivia(baseInitializeInvocationSyntax.GetLeadingTrivia()) .WithAdditionalAnnotations(baseInitializeAsyncInvocationBookmark); newBody = newBody.ReplaceNode(initializeMethodSyntax.GetCurrentNode(baseInitializeInvocationSyntax), baseInitializeAsyncInvocationSyntax); var baseInvocationStatement = newBody.GetAnnotatedNodes(baseInitializeAsyncInvocationBookmark).First().FirstAncestorOrSelf <StatementSyntax>(); newBody = newBody.InsertNodesAfter( baseInvocationStatement, new[] { switchToMainThreadStatement.WithLeadingTrivia(switchToMainThreadStatement.GetLeadingTrivia().Insert(0, SyntaxFactory.LineFeed)) }); } else { newBody = newBody.WithStatements( newBody.Statements.Insert(0, switchToMainThreadStatement)); } var initializeAsyncMethodSyntax = initializeMethodSyntax .WithIdentifier(SyntaxFactory.Identifier(Types.AsyncPackage.InitializeAsync)) .WithReturnType(Types.Task.TypeSyntax.WithAdditionalAnnotations(Simplifier.Annotation)) .AddModifiers(SyntaxFactory.Token(SyntaxKind.AsyncKeyword)) .AddParameterListParameters( SyntaxFactory.Parameter(cancellationTokenLocalVarName.Identifier).WithType(Types.CancellationToken.TypeSyntax.WithAdditionalAnnotations(Simplifier.Annotation)), SyntaxFactory.Parameter(progressLocalVarName.Identifier).WithType(Types.IProgress.TypeSyntaxOf(Types.ServiceProgressData.TypeSyntax).WithAdditionalAnnotations(Simplifier.Annotation))) .WithBody(newBody); updatedRoot = updatedRoot.ReplaceNode(initializeMethodSyntax, initializeAsyncMethodSyntax); // Replace GetService calls with GetServiceAsync getServiceInvocationsSyntax = updatedRoot.GetCurrentNodes <InvocationExpressionSyntax>(getServiceInvocationsSyntax).ToList(); updatedRoot = updatedRoot.ReplaceNodes( getServiceInvocationsSyntax, (orig, node) => { var invocation = (InvocationExpressionSyntax)node; if (invocation.Expression is IdentifierNameSyntax methodName) { invocation = invocation.WithExpression(SyntaxFactory.IdentifierName(Types.AsyncPackage.GetServiceAsync)); } else if (invocation.Expression is MemberAccessExpressionSyntax memberAccess) { invocation = invocation.WithExpression( memberAccess.WithName(SyntaxFactory.IdentifierName(Types.AsyncPackage.GetServiceAsync))); } return(SyntaxFactory.ParenthesizedExpression(SyntaxFactory.AwaitExpression(invocation)) .WithAdditionalAnnotations(Simplifier.Annotation)); }); updatedRoot = await Utils.AddUsingTaskEqualsDirectiveAsync(updatedRoot, cancellationToken); } var newDocument = context.Document.WithSyntaxRoot(updatedRoot); newDocument = await ImportAdder.AddImportsAsync(newDocument, Simplifier.Annotation, cancellationToken : cancellationToken); return(newDocument); }
public Symbol GetSymbol(AttributeSyntax syntax) { var result = _bindingResult.GetBoundNode(syntax) as BoundAttribute; return result?.AttributeSymbol; }
/// <summary> /// Takes an OperationContract attribute node and returns a new node with 'AsyncPattern = true' /// </summary> /// <param name="originalAttribute"></param> /// <returns></returns> private static AttributeSyntax ComputeNewOperationContractAttributeNode(AttributeSyntax originalAttribute) { var newAttributeArguments = new List<AttributeArgumentSyntax> { Syntax.AttributeArgument(Syntax.LiteralExpression(SyntaxKind.TrueLiteralExpression)) .WithNameEquals(Syntax.NameEquals(Syntax.IdentifierName("AsyncPattern"), Syntax.Token(SyntaxKind.EqualsToken))) }; SeparatedSyntaxList<AttributeArgumentSyntax> newAttributeArgumentList; if (originalAttribute.ArgumentList == null) { newAttributeArgumentList = Syntax.SeparatedList( newAttributeArguments, Enumerable.Empty<SyntaxToken>()); } else { newAttributeArgumentList = Syntax.SeparatedList( originalAttribute.ArgumentList.Arguments.Concat(newAttributeArguments), Enumerable.Range(0, originalAttribute.ArgumentList.Arguments.SeparatorCount + 1).Select(i => Syntax.Token(SyntaxKind.CommaToken))); } return originalAttribute.WithArgumentList(Syntax.AttributeArgumentList(newAttributeArgumentList)); }