Пример #1
0
        internal static bool TryGetRegisterField(PropertyDeclarationSyntax property, SemanticModel semanticModel, CancellationToken cancellationToken, out BackingFieldOrProperty result)
        {
            result = default;
            if (TryGetBackingFields(property, semanticModel, cancellationToken, out var getter, out var setter))
            {
                if (DependencyProperty.TryGetDependencyPropertyKeyFieldOrProperty(getter, semanticModel, cancellationToken, out var keyField))
                {
                    getter = keyField;
                }

                if (ReferenceEquals(setter.Symbol, getter.Symbol))
                {
                    result = setter;
                    return(true);
                }
            }

            return(false);
        }
Пример #2
0
        private static void Handle(SyntaxNodeAnalysisContext context)
        {
            if (!context.IsExcludedFromAnalysis() &&
                context.Node is InvocationExpressionSyntax invocation &&
                TryGetArgs(context, out var target, out var propertyArg, out var valueArg) &&
                context.SemanticModel.TryGetSymbol(propertyArg.Expression, context.CancellationToken, out var symbol) &&
                BackingFieldOrProperty.TryCreateForDependencyProperty(symbol, out var fieldOrProperty))
            {
                if (IsWrongType(fieldOrProperty, valueArg, context, out var registeredType))
                {
                    context.ReportDiagnostic(
                        Diagnostic.Create(
                            Descriptors.WPF0014SetValueMustUseRegisteredType,
                            valueArg.GetLocation(),
                            target.Name,
                            registeredType));
                }

                if (fieldOrProperty.Type == KnownSymbols.DependencyProperty &&
                    DependencyProperty.TryGetDependencyPropertyKeyFieldOrProperty(fieldOrProperty, context.SemanticModel, context.CancellationToken, out var keyField))
                {
                    context.ReportDiagnostic(
                        Diagnostic.Create(
                            Descriptors.WPF0040SetUsingDependencyPropertyKey,
                            propertyArg.GetLocation(),
                            properties: ImmutableDictionary <string, string> .Empty.Add(nameof(DependencyPropertyKeyType), keyField.Name),
                            propertyArg,
                            keyField.CreateArgument(context.SemanticModel, propertyArg.SpanStart)));
                }

                if (target == KnownSymbols.DependencyObject.SetCurrentValue &&
                    fieldOrProperty.Symbol is IFieldSymbol setField &&
                    setField == KnownSymbols.FrameworkElement.DataContextProperty)
                {
                    context.ReportDiagnostic(
                        Diagnostic.Create(
                            Descriptors.WPF0043DoNotUseSetCurrentValueForDataContext,
                            invocation.GetLocation(),
                            setField.Name,
                            invocation.ArgumentList.Arguments[1]));
                }
            }
        }
Пример #3
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            var document   = context.Document;
            var syntaxRoot = await document.GetSyntaxRootAsync(context.CancellationToken)
                             .ConfigureAwait(false);

            var semanticModel = await document.GetSemanticModelAsync(context.CancellationToken)
                                .ConfigureAwait(false);

            foreach (var diagnostic in context.Diagnostics)
            {
                var token = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start);
                if (string.IsNullOrEmpty(token.ValueText))
                {
                    continue;
                }

                var invocation = syntaxRoot.FindNode(diagnostic.Location.SourceSpan)
                                 .FirstAncestorOrSelf <InvocationExpressionSyntax>();

                if (invocation == null || invocation.IsMissing)
                {
                    continue;
                }

                if (DependencyObject.TryGetSetValueCall(invocation, semanticModel, context.CancellationToken, out _) &&
                    BackingFieldOrProperty.TryCreateForDependencyProperty(semanticModel.GetSymbolSafe(invocation.ArgumentList.Arguments[0].Expression, context.CancellationToken), out var fieldOrProperty))
                {
                    if (DependencyProperty.TryGetDependencyPropertyKeyFieldOrProperty(
                            fieldOrProperty,
                            semanticModel,
                            context.CancellationToken,
                            out var keyField))
                    {
                        context.RegisterCodeFix(
                            CodeAction.Create(
                                invocation.ToString(),
                                cancellationToken => ApplyFixAsync(
                                    context.Document,
                                    invocation,
                                    null,
                                    keyField.CreateArgument(semanticModel, token.SpanStart),
                                    cancellationToken),
                                this.GetType().FullName),
                            diagnostic);
                    }

                    continue;
                }

                if (DependencyObject.TryGetSetCurrentValueCall(invocation, semanticModel, context.CancellationToken, out _) &&
                    BackingFieldOrProperty.TryCreateForDependencyProperty(semanticModel.GetSymbolSafe(invocation.ArgumentList.Arguments[0].Expression, context.CancellationToken), out fieldOrProperty))
                {
                    if (DependencyProperty.TryGetDependencyPropertyKeyFieldOrProperty(
                            fieldOrProperty,
                            semanticModel,
                            context.CancellationToken,
                            out var keyField))
                    {
                        context.RegisterCodeFix(
                            CodeAction.Create(
                                invocation.ToString(),
                                cancellationToken => ApplyFixAsync(
                                    context.Document,
                                    invocation,
                                    SetValueExpression(invocation.Expression),
                                    keyField.CreateArgument(semanticModel, token.SpanStart),
                                    cancellationToken),
                                this.GetType().FullName),
                            diagnostic);
                    }
                }
            }
        }