private static void HandlePotentialSetMethod(SyntaxNodeAnalysisContext context, BlockSyntax body)
        {
            if (body == null)
            {
                return;
            }

            using (var pooled = ClrSetterWalker.Create(context.SemanticModel, context.CancellationToken, context.Node))
            {
                if (pooled.Item.HasError)
                {
                    return;
                }

                if (pooled.Item.IsSuccess)
                {
                    foreach (var statement in body.Statements)
                    {
                        if ((statement as ExpressionStatementSyntax)?.Expression != pooled.Item.SetValue &&
                            (statement as ExpressionStatementSyntax)?.Expression != pooled.Item.SetCurrentValue)
                        {
                            context.ReportDiagnostic(Diagnostic.Create(Descriptor, statement.GetLocation()));
                            return;
                        }
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Get the backing fields for the <paramref name="propertyDeclaration"/> these are different for readonly dependency properties where the setter returns the DependencyPropertyKey field
        /// </summary>
        internal static bool TryGetBackingFields(PropertyDeclarationSyntax propertyDeclaration, SemanticModel semanticModel, CancellationToken cancellationToken, out IFieldSymbol getField, out IFieldSymbol setField)
        {
            getField = null;
            setField = null;
            if (propertyDeclaration.TryGetAccessorDeclaration(SyntaxKind.GetAccessorDeclaration, out AccessorDeclarationSyntax getAccessor) &&
                propertyDeclaration.TryGetAccessorDeclaration(SyntaxKind.SetAccessorDeclaration, out AccessorDeclarationSyntax setAccessor))
            {
                using (var pooled = ClrGetterWalker.Create(semanticModel, cancellationToken, getAccessor))
                {
                    using (var setterWalker = ClrSetterWalker.Create(semanticModel, cancellationToken, setAccessor))
                    {
                        if (pooled.Item.HasError ||
                            setterWalker.Item.HasError)
                        {
                            return(false);
                        }

                        if (pooled.Item.IsSuccess &&
                            pooled.Item.Property.TryGetSymbol(semanticModel, cancellationToken, out getField) &&
                            setterWalker.Item.IsSuccess &&
                            setterWalker.Item.Property.TryGetSymbol(semanticModel, cancellationToken, out setField))
                        {
                            return(true);
                        }

                        var property = semanticModel.GetSymbolSafe(propertyDeclaration, cancellationToken) as IPropertySymbol;
                        return(TryGetBackingFieldsByName(property, out getField, out setField));
                    }
                }
            }

            return(false);
        }
예제 #3
0
        public static ClrSetterWalker Create(SemanticModel semanticModel, CancellationToken cancellationToken, SyntaxNode setter)
        {
            ClrSetterWalker walker;

            if (!Cache.TryDequeue(out walker))
            {
                walker = new ClrSetterWalker();
            }

            walker.HasError          = false;
            walker.SetValue          = null;
            walker.SetCurrentValue   = null;
            walker.semanticModel     = semanticModel;
            walker.cancellationToken = cancellationToken;
            walker.Visit(setter);
            return(walker);
        }
예제 #4
0
        private static bool IsAttachedSetMethod(MethodDeclarationSyntax method, SemanticModel semanticModel, CancellationToken cancellationToken, out IFieldSymbol setField)
        {
            setField = null;
            if (method == null ||
                method.ParameterList.Parameters.Count != 2 ||
                !method.ReturnType.IsVoid() ||
                !method.Modifiers.Any(SyntaxKind.StaticKeyword))
            {
                return(false);
            }

            using (var walker = ClrSetterWalker.Create(semanticModel, cancellationToken, method))
            {
                if (!walker.IsSuccess)
                {
                    return(false);
                }

                var memberAccess = (walker.SetValue?.Expression ?? walker.SetCurrentValue?.Expression) as MemberAccessExpressionSyntax;
                var member       = memberAccess?.Expression as IdentifierNameSyntax;
                if (memberAccess == null ||
                    member == null ||
                    !memberAccess.IsKind(SyntaxKind.SimpleMemberAccessExpression))
                {
                    return(false);
                }

                if (method.ParameterList.Parameters[0].Identifier.ValueText != member.Identifier.ValueText)
                {
                    return(false);
                }

                using (var valueWalker = ValueWalker.Create(method.ParameterList.Parameters[1].Identifier, memberAccess.Parent))
                {
                    if (!valueWalker.UsesValue)
                    {
                        return(false);
                    }
                }

                return(walker.Property.TryGetSymbol(semanticModel, cancellationToken, out setField));
            }
        }