예제 #1
0
        public static async Task ComputeRefactoringAsync(
            RefactoringContext context,
            PropertyDeclarationSyntax property)
        {
            AccessorDeclarationSyntax setter = property.Setter();

            if (setter == null)
            {
                return;
            }

            ExpressionSyntax expression = GetExpression();

            if (expression == null)
            {
                return;
            }

            SimpleAssignmentExpressionInfo simpleAssignment = SyntaxInfo.SimpleAssignmentExpressionInfo(expression);

            if (!simpleAssignment.Success)
            {
                return;
            }

            if (!simpleAssignment.Left.IsKind(SyntaxKind.IdentifierName))
            {
                return;
            }

            if (!(simpleAssignment.Right is IdentifierNameSyntax identifierName))
            {
                return;
            }

            if (identifierName.Identifier.ValueText != "value")
            {
                return;
            }

            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

            INamedTypeSymbol containingType = semanticModel
                                              .GetDeclaredSymbol(property, context.CancellationToken)?
                                              .ContainingType;

            if (containingType == null)
            {
                return;
            }

            if (!containingType.Implements(MetadataNames.System_ComponentModel_INotifyPropertyChanged, allInterfaces: true))
            {
                return;
            }

            IMethodSymbol methodSymbol = SymbolUtility.FindMethodThatRaisePropertyChanged(containingType, expression.SpanStart, semanticModel);

            if (methodSymbol == null)
            {
                return;
            }

            Document document = context.Document;

            context.RegisterRefactoring(
                "Notify when property change",
                ct => RefactorAsync(document, property, methodSymbol.Name, ct),
                RefactoringIdentifiers.NotifyWhenPropertyChange);

            ExpressionSyntax GetExpression()
            {
                BlockSyntax body = setter.Body;

                if (body != null)
                {
                    if (body.Statements.SingleOrDefault(shouldThrow: false) is ExpressionStatementSyntax expressionStatement)
                    {
                        return(expressionStatement.Expression);
                    }
                }
                else
                {
                    return(setter.ExpressionBody?.Expression);
                }

                return(null);
            }
        }