Example #1
0
        public static async Task <Document> RefactorAsync(
            Document document,
            PropertyDeclarationSyntax propertyDeclaration,
            bool prefixIdentifierWithUnderscore = true,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            string fieldName = TextUtility.ToCamelCase(
                propertyDeclaration.Identifier.ValueText,
                prefixWithUnderscore: prefixIdentifierWithUnderscore);

            FieldDeclarationSyntax fieldDeclaration = CreateBackingField(propertyDeclaration, fieldName)
                                                      .WithFormatterAnnotation();

            PropertyDeclarationSyntax newPropertyDeclaration = ExpandPropertyAndAddBackingField(propertyDeclaration, fieldName)
                                                               .WithTriviaFrom(propertyDeclaration)
                                                               .WithFormatterAnnotation();

            var parentMember = (MemberDeclarationSyntax)propertyDeclaration.Parent;
            SyntaxList <MemberDeclarationSyntax> members = parentMember.GetMembers();

            int propertyIndex = members.IndexOf(propertyDeclaration);

            if (propertyDeclaration.IsReadOnlyAutoProperty())
            {
                SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                IEnumerable <ReferencedSymbol> referencedSymbols = await SymbolFinder.FindReferencesAsync(
                    semanticModel.GetDeclaredSymbol(propertyDeclaration, cancellationToken),
                    document.Project.Solution,
                    cancellationToken).ConfigureAwait(false);

                ImmutableArray <IdentifierNameSyntax> identifierNames = SyntaxUtility
                                                                        .FindNodes <IdentifierNameSyntax>(oldRoot, referencedSymbols)
                                                                        .ToImmutableArray();

                var rewriter = new IdentifierNameSyntaxRewriter(identifierNames, Identifier(fieldName));

                var newParentMember = (MemberDeclarationSyntax)rewriter.Visit(parentMember);

                members = newParentMember.GetMembers();
            }

            int indexOfLastField = members.LastIndexOf(f => f.IsKind(SyntaxKind.FieldDeclaration));

            SyntaxList <MemberDeclarationSyntax> newMembers = members
                                                              .Replace(members[propertyIndex], newPropertyDeclaration)
                                                              .Insert(indexOfLastField + 1, fieldDeclaration);

            SyntaxNode newRoot = oldRoot.ReplaceNode(parentMember, parentMember.SetMembers(newMembers));

            return(document.WithSyntaxRoot(newRoot));
        }
        private static async Task <Document> ReplacePropertyWithAutoPropertyAsync(
            Document document,
            PropertyDeclarationSyntax property,
            CancellationToken cancellationToken)
        {
            SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var parentMember = (MemberDeclarationSyntax)property.Parent;

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            ISymbol fieldSymbol = GetFieldSymbol(property, semanticModel, cancellationToken);

            var declarator = (VariableDeclaratorSyntax)await fieldSymbol.DeclaringSyntaxReferences[0].GetSyntaxAsync(cancellationToken).ConfigureAwait(false);

            var variableDeclaration = (VariableDeclarationSyntax)declarator.Parent;

            SyntaxList <MemberDeclarationSyntax> members = parentMember.GetMembers();

            int propertyIndex = members.IndexOf(property);

            int fieldIndex = members.IndexOf((FieldDeclarationSyntax)variableDeclaration.Parent);

            IEnumerable <ReferencedSymbol> referencedSymbols = await SymbolFinder.FindReferencesAsync(
                fieldSymbol,
                document.Project.Solution,
                cancellationToken).ConfigureAwait(false);

            ImmutableArray <IdentifierNameSyntax> identifierNames = SyntaxUtility
                                                                    .FindNodes <IdentifierNameSyntax>(oldRoot, referencedSymbols)
                                                                    .ToImmutableArray();

            var rewriter = new IdentifierNameSyntaxRewriter(identifierNames, Identifier(property.Identifier.ValueText));

            var newParentMember = (MemberDeclarationSyntax)rewriter.Visit(parentMember);

            members = newParentMember.GetMembers();

            if (variableDeclaration.Variables.Count == 1)
            {
                newParentMember = newParentMember.RemoveNode(
                    newParentMember.GetMemberAt(fieldIndex),
                    SyntaxRemoveOptions.KeepUnbalancedDirectives);

                if (propertyIndex > fieldIndex)
                {
                    propertyIndex--;
                }
            }
            else
            {
                var field = (FieldDeclarationSyntax)members[fieldIndex];

                FieldDeclarationSyntax newField = field.RemoveNode(
                    field.Declaration.Variables[variableDeclaration.Variables.IndexOf(declarator)],
                    SyntaxRemoveOptions.KeepUnbalancedDirectives);

                members = members.Replace(field, newField.WithFormatterAnnotation());

                newParentMember = newParentMember.SetMembers(members);
            }

            members = newParentMember.GetMembers();

            property = (PropertyDeclarationSyntax)members[propertyIndex];

            PropertyDeclarationSyntax newProperty = CreateAutoProperty(property, declarator.Initializer);

            members = members.Replace(property, newProperty);

            newParentMember = newParentMember.SetMembers(members);

            SyntaxNode newRoot = oldRoot.ReplaceNode(parentMember, newParentMember);

            return(document.WithSyntaxRoot(newRoot));
        }