Ejemplo n.º 1
0
        private static void Handle(SyntaxNodeAnalysisContext context)
        {
            if (!context.IsExcludedFromAnalysis() &&
                context.Node is ObjectCreationExpressionSyntax objectCreation &&
                context.ContainingSymbol.IsStatic &&
                PropertyMetadata.TryGetConstructor(objectCreation, context.SemanticModel, context.CancellationToken, out _))
            {
                if (PropertyMetadata.TryGetRegisteredName(objectCreation, context.SemanticModel, context.CancellationToken, out _, out var registeredName))
                {
                    if (PropertyMetadata.TryGetPropertyChangedCallback(objectCreation, context.SemanticModel, context.CancellationToken, out var propertyChangedCallback) &&
                        Callback.TryGetTarget(propertyChangedCallback, KnownSymbols.PropertyChangedCallback, context.SemanticModel, context.CancellationToken, out var callbackIdentifier, out var target))
                    {
                        if (target.ContainingType.Equals(context.ContainingSymbol.ContainingType) &&
                            !target.Name.IsParts("On", registeredName, "Changed") &&
                            target.DeclaredAccessibility.IsEither(Accessibility.Private, Accessibility.Protected))
                        {
                            using (var walker = InvocationWalker.InContainingClass(target, context.SemanticModel, context.CancellationToken))
                            {
                                if (walker.IdentifierNames.Count == 1)
                                {
                                    context.ReportDiagnostic(
                                        Diagnostic.Create(
                                            Descriptors.WPF0005PropertyChangedCallbackShouldMatchRegisteredName,
                                            callbackIdentifier.GetLocation(),
                                            ImmutableDictionary <string, string> .Empty.Add("ExpectedName", $"On{registeredName}Changed"),
                                            callbackIdentifier,
                                            $"On{registeredName}Changed"));
                                }
                                else if (target.Name.StartsWith("On") &&
                                         target.Name.EndsWith("Changed"))
                                {
                                    foreach (var identifierName in walker.IdentifierNames)
                                    {
                                        if (identifierName.TryFirstAncestor(out ArgumentSyntax argument) &&
                                            argument != propertyChangedCallback &&
                                            MatchesPropertyChangedCallbackName(argument, target, context))
                                        {
                                            context.ReportDiagnostic(
                                                Diagnostic.Create(
                                                    Descriptors.WPF0005PropertyChangedCallbackShouldMatchRegisteredName,
                                                    callbackIdentifier.GetLocation(),
                                                    callbackIdentifier,
                                                    $"On{registeredName}Changed"));
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        if (target.TrySingleMethodDeclaration(context.CancellationToken, out var declaration) &&
                            Callback.IsSingleExpression(declaration))
                        {
                            context.ReportDiagnostic(Diagnostic.Create(Descriptors.WPF0023ConvertToLambda, propertyChangedCallback.GetLocation()));
                        }
                    }

                    if (PropertyMetadata.TryGetCoerceValueCallback(objectCreation, context.SemanticModel, context.CancellationToken, out var coerceValueCallback) &&
                        Callback.TryGetTarget(coerceValueCallback, KnownSymbols.CoerceValueCallback, context.SemanticModel, context.CancellationToken, out callbackIdentifier, out target))
                    {
                        if (target.ContainingType.Equals(context.ContainingSymbol.ContainingType) &&
                            !target.Name.IsParts("Coerce", registeredName))
                        {
                            using (var walker = InvocationWalker.InContainingClass(target, context.SemanticModel, context.CancellationToken))
                            {
                                if (walker.IdentifierNames.Count == 1)
                                {
                                    context.ReportDiagnostic(
                                        Diagnostic.Create(
                                            Descriptors.WPF0006CoerceValueCallbackShouldMatchRegisteredName,
                                            callbackIdentifier.GetLocation(),
                                            ImmutableDictionary <string, string> .Empty.Add("ExpectedName", $"Coerce{registeredName}"),
                                            callbackIdentifier,
                                            $"Coerce{registeredName}"));
                                }
                                else if (target.Name.StartsWith("Coerce"))
                                {
                                    foreach (var identifierName in walker.IdentifierNames)
                                    {
                                        if (identifierName.TryFirstAncestor(out ArgumentSyntax argument) &&
                                            argument != propertyChangedCallback &&
                                            MatchesCoerceValueCallbackName(argument, target, context))
                                        {
                                            context.ReportDiagnostic(
                                                Diagnostic.Create(
                                                    Descriptors.WPF0006CoerceValueCallbackShouldMatchRegisteredName,
                                                    callbackIdentifier.GetLocation(),
                                                    callbackIdentifier,
                                                    $"Coerce{registeredName}"));
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        if (target.TrySingleMethodDeclaration(context.CancellationToken, out var declaration) &&
                            Callback.IsSingleExpression(declaration))
                        {
                            context.ReportDiagnostic(Diagnostic.Create(Descriptors.WPF0023ConvertToLambda, propertyChangedCallback.GetLocation()));
                        }
                    }
                }

                if (PropertyMetadata.TryGetDependencyProperty(objectCreation, context.SemanticModel, context.CancellationToken, out var fieldOrProperty) &&
                    DependencyProperty.TryGetRegisteredType(fieldOrProperty, context.SemanticModel, context.CancellationToken, out var registeredType) &&
                    PropertyMetadata.TryGetDefaultValue(objectCreation, context.SemanticModel, context.CancellationToken, out var defaultValueArg))
                {
                    if (!PropertyMetadata.IsValueValidForRegisteredType(defaultValueArg.Expression, registeredType, context.SemanticModel, context.CancellationToken))
                    {
                        context.ReportDiagnostic(
                            Diagnostic.Create(
                                Descriptors.WPF0010DefaultValueMustMatchRegisteredType,
                                defaultValueArg.GetLocation(),
                                fieldOrProperty.Symbol,
                                registeredType));
                    }

                    if (registeredType.IsReferenceType)
                    {
                        var defaultValue = defaultValueArg.Expression;
                        if (defaultValue != null &&
                            !defaultValue.IsKind(SyntaxKind.NullLiteralExpression) &&
                            registeredType != KnownSymbols.FontFamily)
                        {
                            if (IsNonEmptyArrayCreation(defaultValue as ArrayCreationExpressionSyntax, context) ||
                                IsReferenceTypeCreation(defaultValue as ObjectCreationExpressionSyntax, context))
                            {
                                context.ReportDiagnostic(Diagnostic.Create(Descriptors.WPF0016DefaultValueIsSharedReferenceType, defaultValueArg.GetLocation(), fieldOrProperty.Symbol));
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        private static void Handle(SyntaxNodeAnalysisContext context)
        {
            if (!context.IsExcludedFromAnalysis() &&
                context.Node is InvocationExpressionSyntax registerCall &&
                context.ContainingSymbol.IsStatic &&
                TryGetAnyRegisterCall(registerCall, context, out var registerMethod) &&
                DependencyProperty.TryGetRegisteredName(registerCall, context.SemanticModel, context.CancellationToken, out var nameArg, out var registeredName))
            {
                if (registerMethod.TryFindParameter(KnownSymbols.ValidateValueCallback, out var parameter) &&
                    registerCall.TryFindArgument(parameter, out var validateValueCallback) &&
                    Callback.TryGetTarget(validateValueCallback, KnownSymbols.ValidateValueCallback, context.SemanticModel, context.CancellationToken, out var callBackIdentifier, out var target))
                {
                    if (target.ContainingType.Equals(context.ContainingSymbol.ContainingType) &&
                        !MatchesValidateValueCallbackName(validateValueCallback, target, context))
                    {
                        using var walker = InvocationWalker.InContainingClass(target, context.SemanticModel, context.CancellationToken);
                        if (walker.IdentifierNames.Count == 1)
                        {
                            context.ReportDiagnostic(
                                Diagnostic.Create(
                                    Descriptors.WPF0007ValidateValueCallbackCallbackShouldMatchRegisteredName,
                                    callBackIdentifier.GetLocation(),
                                    ImmutableDictionary <string, string> .Empty.Add("ExpectedName", $"Validate{registeredName}"),
                                    callBackIdentifier,
                                    $"Validate{registeredName}"));
                        }
                        else if (target.Name.StartsWith("Validate", StringComparison.Ordinal))
                        {
                            foreach (var identifierName in walker.IdentifierNames)
                            {
                                if (identifierName.TryFirstAncestor(out ArgumentSyntax? argument) &&
                                    argument != validateValueCallback &&
                                    MatchesValidateValueCallbackName(argument, target, context))
                                {
                                    context.ReportDiagnostic(
                                        Diagnostic.Create(
                                            Descriptors.WPF0007ValidateValueCallbackCallbackShouldMatchRegisteredName,
                                            callBackIdentifier.GetLocation(),
                                            callBackIdentifier,
                                            $"Validate{registeredName}"));
                                    break;
                                }
                            }
                        }
                    }

                    if (target.TrySingleMethodDeclaration(context.CancellationToken, out var declaration) &&
                        Callback.IsSingleExpression(declaration))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(Descriptors.WPF0023ConvertToLambda, validateValueCallback.GetLocation()));
                    }
                }

                if (nameArg.Expression is { } nameExpression&&
                    nameExpression.IsNameof() == false &&
                    context.ContainingSymbol.ContainingType.TryFindProperty(registeredName, out var property))
                {
                    if (nameArg.Expression.IsKind(SyntaxKind.StringLiteralExpression))
                    {
                        context.ReportDiagnostic(
                            Diagnostic.Create(
                                Descriptors.WPF0150UseNameofInsteadOfLiteral,
                                nameArg.GetLocation(),
                                ImmutableDictionary <string, string> .Empty.Add(nameof(IdentifierNameSyntax), property.Name),
                                property.Name));
                    }
                    else
                    {
                        context.ReportDiagnostic(
                            Diagnostic.Create(
                                Descriptors.WPF0151UseNameofInsteadOfConstant,
                                nameExpression.GetLocation(),
                                ImmutableDictionary <string, string> .Empty.Add(nameof(IdentifierNameSyntax), property.Name),
                                property.Name));
                    }
                }
            }
        }