// 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;
        }
Ejemplo n.º 3
0
        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;
        }
Ejemplo n.º 4
0
        public override void VisitAttribute(AttributeSyntax node)
        {
            var symbol = _semanticModel.GetSymbol(node);
            if (symbol != null)
                CreateTag(node.Name.Name, _classificationService.FunctionIdentifier);

            base.VisitAttribute(node);
        }
Ejemplo n.º 5
0
 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;
 }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        // 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);
 }
Ejemplo n.º 11
0
 internal static CSharpSyntaxNode GetAttributeArgumentSyntax(this AttributeData attribute, int parameterIndex, AttributeSyntax attributeSyntax)
 {
     Debug.Assert(attribute is SourceAttributeData);
     return(((SourceAttributeData)attribute).GetAttributeArgumentSyntax(parameterIndex, attributeSyntax));
 }
Ejemplo n.º 12
0
 public BasicSchemaAttribute(int id, string name, AttributeSyntax syntax)
 {
     this.Id = id;
     this.Name = name;
     this.Syntax = syntax;
 }
Ejemplo n.º 13
0
 public UpdateOrAddGenericDebtAttribute(AttributeSyntax newAttribute) : base(false)
 {
     NewAttribute = newAttribute;
 }
Ejemplo n.º 14
0
        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);
            }
        }
Ejemplo n.º 16
0
 public static bool EarlyDecodeIsConditionalAttribute(NamedTypeSymbol attributeType, AttributeSyntax attributeSyntax)
 {
     return EarlyDecodeIsTargetAttribute(attributeType, attributeSyntax, AttributeDescription.ConditionalAttribute);
 }
Ejemplo n.º 17
0
        public FixedLengthBehavior(AttributeSyntax attributeSyntax) : base(attributeSyntax)
        {
            TryEvaluateIntArgument(out int length);

            Length = length;
        }
Ejemplo n.º 18
0
 internal static bool IsEntityTriggerAttribute(AttributeSyntax attribute) => IsSpecifiedAttribute(attribute, "EntityTrigger");
Ejemplo n.º 19
0
        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);
 }
Ejemplo n.º 21
0
 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);
 }
Ejemplo n.º 22
0
        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);
            }
        }
Ejemplo n.º 24
0
 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);
        }
Ejemplo n.º 26
0
        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));
 }
Ejemplo n.º 28
0
        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);
        }
Ejemplo n.º 29
0
        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);
        }
Ejemplo n.º 30
0
 public virtual void VisitAttribute(AttributeSyntax node)
 {
     DefaultVisit(node);
 }
Ejemplo n.º 31
0
 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);
 }
Ejemplo n.º 32
0
 public static bool EarlyDecodeIsObsoleteAttribute(NamedTypeSymbol attributeType, AttributeSyntax attributeSyntax)
 {
     return EarlyDecodeIsTargetAttribute(attributeType, attributeSyntax, AttributeDescription.ObsoleteAttribute, skipParamCheck:true);
 }
Ejemplo n.º 33
0
 /// <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);
            }
        }
Ejemplo n.º 35
0
 public static string GetTypeName(this AttributeSyntax attributeSyntax) => attributeSyntax.Name switch
 {
 internal static bool IsNullableAnalysisEnabledIn(CSharpCompilation compilation, AttributeSyntax syntax)
 {
     return(compilation.IsNullableAnalysisEnabledIn(syntax));
 }
Ejemplo n.º 37
0
        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));
 }
Ejemplo n.º 39
0
        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))));
        }
Ejemplo n.º 40
0
        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;
            }
        }
Ejemplo n.º 42
0
        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());
            }
        }
Ejemplo n.º 44
0
        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();
 }
Ejemplo n.º 48
0
 public virtual void VisitAttribute(AttributeSyntax node)
 {
     DefaultVisit(node);
 }
Ejemplo n.º 49
0
        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);
        }
Ejemplo n.º 50
0
 public Symbol GetSymbol(AttributeSyntax syntax)
 {
     var result = _bindingResult.GetBoundNode(syntax) as BoundAttribute;
     return result?.AttributeSymbol;
 }
Ejemplo n.º 51
0
    /// <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));
    }