public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { Document document = context.Document; Microsoft.CodeAnalysis.Text.TextSpan textSpan = context.Span; CancellationToken cancellationToken = context.CancellationToken; CompilationUnitSyntax root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false) as CompilationUnitSyntax; SemanticModel model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); // if length is 0 then no particular range is selected, so pick the first enclosing member if (textSpan.Length == 0) { MemberDeclarationSyntax decl = root.FindToken(textSpan.Start).Parent.AncestorsAndSelf().OfType <MemberDeclarationSyntax>().FirstOrDefault(); if (decl != null) { textSpan = decl.FullSpan; } } IEnumerable <ExpandablePropertyInfo> properties = ExpansionChecker.GetExpandableProperties(textSpan, root, model); if (properties.Any()) { CodeAction action = CodeAction.Create( "Apply INotifyPropertyChanged pattern", c => ImplementNotifyPropertyChangedAsync(document, root, model, properties, c), equivalenceKey: nameof(ImplementNotifyPropertyChangedCodeRefactoringProvider)); context.RegisterRefactoring(action); } }
private static PropertyDeclarationSyntax ExpandProperty(PropertyDeclarationSyntax property, string backingFieldName) { AccessorDeclarationSyntax getter, setter; if (!ExpansionChecker.TryGetAccessors(property, out getter, out setter)) { throw new ArgumentException(); } if (getter.Body == null) { var returnFieldStatement = SyntaxFactory.ParseStatement(string.Format("return {0};", backingFieldName)); getter = getter .WithBody(SyntaxFactory.Block(SyntaxFactory.SingletonList(returnFieldStatement))); } getter = getter .WithSemicolonToken(default(SyntaxToken)); var setPropertyStatement = SyntaxFactory.ParseStatement(string.Format("SetProperty(ref {0}, value, \"{1}\");", backingFieldName, property.Identifier.ValueText)); setter = setter .WithBody(SyntaxFactory.Block(SyntaxFactory.SingletonList(setPropertyStatement))) .WithSemicolonToken(default(SyntaxToken)); var newProperty = property .WithAccessorList(SyntaxFactory.AccessorList(SyntaxFactory.List(new[] { getter, setter }))) .WithAdditionalAnnotations(Formatter.Annotation); return(newProperty); }
public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var document = context.Document; var textSpan = context.Span; var cancellationToken = context.CancellationToken; var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false) as CompilationUnitSyntax; var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); // if length is 0 then no particular range is selected, so pick the first enclosing member if (textSpan.Length == 0) { var decl = root.FindToken(textSpan.Start).Parent.AncestorsAndSelf().OfType <MemberDeclarationSyntax>().FirstOrDefault(); if (decl != null) { textSpan = decl.FullSpan; } } var properties = ExpansionChecker.GetExpandableProperties(textSpan, root, model); if (properties.Any()) { #pragma warning disable RS0005 context.RegisterRefactoring( CodeAction.Create("Apply INotifyPropertyChanged pattern", (c) => ImplementNotifyPropertyChangedAsync(document, root, model, properties, c))); #pragma warning restore RS0005 } }
public sealed override async Task <IEnumerable <CodeAction> > GetRefactoringsAsync(CodeRefactoringContext context) { var document = context.Document; var textSpan = context.Span; var cancellationToken = context.CancellationToken; var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false) as CompilationUnitSyntax; var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var properties = ExpansionChecker.GetExpandableProperties(textSpan, root, model); return(properties.Any() ? new[] { new ImplementNotifyPropertyChangedCodeAction("Apply INotifyPropertyChanged pattern", (c) => ImplementNotifyPropertyChangedAsync(document, root, model, properties, c)) } : null); }