private static MemberDeclarationSyntax GetNextDeclaration(MemberDeclarationSyntax declaration)
        {
            MemberDeclarationListInfo info = SyntaxInfo.MemberDeclarationListInfo(declaration.Parent);

            if (!info.Success)
            {
                return(null);
            }

            SyntaxList <MemberDeclarationSyntax> members = info.Members;

            if (members.Count <= 1)
            {
                return(null);
            }

            int index = members.IndexOf(declaration);

            if (index == members.Count - 1)
            {
                return(null);
            }

            return(members[index + 1]);
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            MemberDeclarationSyntax member,
            CancellationToken cancellationToken = default)
        {
            MemberDeclarationSyntax newMember = member;

            SyntaxToken identifier = GetIdentifier(member);

            if (identifier != default)
            {
                SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                string newName = NameGenerator.Default.EnsureUniqueName(identifier.ValueText, semanticModel, member.SpanStart);

                ISymbol symbol = semanticModel.GetDeclaredSymbol(member, cancellationToken);

                ImmutableArray <SyntaxNode> references = await SyntaxFinder.FindReferencesAsync(symbol, document.Solution(), documents : ImmutableHashSet.Create(document), cancellationToken : cancellationToken).ConfigureAwait(false);

                SyntaxToken newIdentifier = SyntaxFactory.Identifier(newName);

                newMember = member.ReplaceNodes(
                    references.Where(n => member.Contains(n)),
                    (n, _) =>
                {
                    if (n is IdentifierNameSyntax identifierName)
                    {
                        return(identifierName.WithIdentifier(newIdentifier.WithTriviaFrom(identifierName.Identifier)));
                    }
                    else
                    {
                        Debug.Fail(n.Kind().ToString());
                        return(n);
                    }
                });

                newMember = SetIdentifier(newMember, newIdentifier.WithRenameAnnotation());
            }
            else
            {
                newMember = newMember.WithNavigationAnnotation();
            }

            MemberDeclarationListInfo memberList = SyntaxInfo.MemberDeclarationListInfo(member.Parent);

            int index = memberList.IndexOf(member);

            if (index == 0)
            {
                SyntaxToken?openBrace = memberList.OpenBraceToken;

                if (openBrace != null &&
                    openBrace.Value.GetFullSpanEndLine() == member.GetFullSpanStartLine())
                {
                    newMember = newMember.WithLeadingTrivia(member.GetLeadingTrivia().Insert(0, NewLine()));
                }
            }

            return(await document.ReplaceMembersAsync(memberList, memberList.Members.Insert(index + 1, newMember), cancellationToken).ConfigureAwait(false));
        }
Beispiel #3
0
        private static SyntaxNode RemoveNode(MemberDeclarationSyntax member)
        {
            MemberDeclarationListInfo            memberList = SyntaxInfo.MemberDeclarationListInfo(member.Parent);
            SyntaxList <MemberDeclarationSyntax> members    = memberList.Members;

            MemberDeclarationListInfo newMemberList = memberList.RemoveNode(member, SyntaxRemoveOptions.KeepUnbalancedDirectives);

            int index = members.IndexOf(member);

            if (index == 0 &&
                index < members.Count - 1)
            {
                MemberDeclarationSyntax nextMember    = newMemberList[index];
                SyntaxTriviaList        leadingTrivia = nextMember.GetLeadingTrivia();

                if (leadingTrivia.FirstOrDefault().IsEndOfLineTrivia())
                {
                    MemberDeclarationSyntax newNextMember = nextMember.WithLeadingTrivia(leadingTrivia.RemoveAt(0));

                    newMemberList = newMemberList.ReplaceNode(nextMember, newNextMember);
                }
            }

            return(newMemberList.Parent);
        }
Beispiel #4
0
 private static Task <Document> ReplaceMembersAsync(
     Document document,
     MemberDeclarationListInfo info,
     IEnumerable <MemberDeclarationSyntax> newMembers,
     CancellationToken cancellationToken = default(CancellationToken))
 {
     return(document.ReplaceMembersAsync(info, newMembers, cancellationToken));
 }
        public static void ComputeRefactoring(RefactoringContext context, MemberDeclarationSyntax member)
        {
            MemberDeclarationListInfo info = SyntaxInfo.MemberDeclarationListInfo(member.Parent);

            if (!info.Success)
            {
                return;
            }

            SyntaxList <MemberDeclarationSyntax> members = info.Members;

            if (members.Count <= 1)
            {
                return;
            }

            int index = IndexOfMemberToSwap(member, members, context.Span);

            if (index == -1)
            {
                return;
            }

            SyntaxTree tree = member.SyntaxTree;

            FileLinePositionSpan fileLinePositionSpan = tree.GetLineSpan(context.Span, context.CancellationToken);

            int startLine = fileLinePositionSpan.StartLine();
            int endLine   = fileLinePositionSpan.EndLine();

            if (startLine <= tree.GetEndLine(members[index].TrimmedSpan(), context.CancellationToken))
            {
                return;
            }

            if (endLine >= tree.GetStartLine(members[index + 1].TrimmedSpan(), context.CancellationToken))
            {
                return;
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.RemoveMemberDeclarations))
            {
                context.RegisterRefactoring(
                    "Remove members above",
                    ct => ReplaceMembersAsync(context.Document, info, members.Skip(index + 1), ct));

                context.RegisterRefactoring(
                    "Remove members below",
                    ct => ReplaceMembersAsync(context.Document, info, members.Take(index + 1), ct));
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.SwapMemberDeclarations))
            {
                context.RegisterRefactoring(
                    "Swap members",
                    ct => SwapMembersAsync(context.Document, info, index, ct));
            }
        }
Beispiel #6
0
        private static bool IsSingleInstanceConstructor(ConstructorDeclarationSyntax constructor)
        {
            MemberDeclarationListInfo info = SyntaxInfo.MemberDeclarationListInfo(constructor.Parent);

            return(info.Success &&
                   info
                   .Members
                   .OfType <ConstructorDeclarationSyntax>()
                   .All(f => f.Equals(constructor) || f.Modifiers.Contains(SyntaxKind.StaticKeyword)));
        }
Beispiel #7
0
 internal static Task <Document> ReplaceMembersAsync(
     this Document document,
     MemberDeclarationListInfo info,
     SyntaxList <MemberDeclarationSyntax> newMembers,
     CancellationToken cancellationToken = default(CancellationToken))
 {
     return(document.ReplaceNodeAsync(
                info.Parent,
                info.WithMembers(newMembers).Parent,
                cancellationToken));
 }
Beispiel #8
0
        public static async Task <Document> RefactorAsync(
            Document document,
            PropertyDeclarationSyntax propertyDeclaration,
            bool prefixIdentifierWithUnderscore = true,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            string fieldName = StringUtility.ToCamelCase(
                propertyDeclaration.Identifier.ValueText,
                prefixWithUnderscore: prefixIdentifierWithUnderscore);

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

            fieldName = NameGenerator.Default.EnsureUniqueMemberName(
                fieldName,
                semanticModel,
                propertyDeclaration.SpanStart,
                cancellationToken: cancellationToken);

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

            PropertyDeclarationSyntax newPropertyDeclaration = ExpandPropertyAndAddBackingField(propertyDeclaration, fieldName);

            newPropertyDeclaration = newPropertyDeclaration
                                     .WithModifiers(newPropertyDeclaration.Modifiers.Replace(SyntaxKind.AbstractKeyword, SyntaxKind.VirtualKeyword))
                                     .WithTriviaFrom(propertyDeclaration)
                                     .WithFormatterAnnotation();

            MemberDeclarationListInfo info = SyntaxInfo.MemberDeclarationListInfo(propertyDeclaration.Parent);

            SyntaxList <MemberDeclarationSyntax> members = info.Members;

            int propertyIndex = info.IndexOf(propertyDeclaration);

            if (IsReadOnlyAutoProperty(propertyDeclaration))
            {
                IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration, cancellationToken);

                ImmutableArray <SyntaxNode> nodes = await SyntaxFinder.FindReferencesAsync(propertySymbol, document, cancellationToken : cancellationToken).ConfigureAwait(false);

                IdentifierNameSyntax newNode = IdentifierName(fieldName);

                MemberDeclarationListInfo newInfo = SyntaxInfo.MemberDeclarationListInfo(info.Parent.ReplaceNodes(nodes, (f, _) => newNode.WithTriviaFrom(f)));

                members = newInfo.Members;
            }

            SyntaxList <MemberDeclarationSyntax> newMembers = members.ReplaceAt(propertyIndex, newPropertyDeclaration);

            newMembers = MemberDeclarationInserter.Default.Insert(newMembers, fieldDeclaration);

            return(await document.ReplaceMembersAsync(info, newMembers, cancellationToken).ConfigureAwait(false));
        }
Beispiel #9
0
        public static Task <Document> RefactorAsync(
            Document document,
            MemberDeclarationListSelection selectedMembers,
            Accessibility newAccessibility,
            CancellationToken cancellationToken)
        {
            SyntaxList <MemberDeclarationSyntax> newMembers = selectedMembers
                                                              .UnderlyingList
                                                              .ReplaceRange(selectedMembers.FirstIndex, selectedMembers.Count, selectedMembers.Select(f => SyntaxAccessibility.WithExplicitAccessibility(f, newAccessibility)));

            MemberDeclarationListInfo info = SyntaxInfo.MemberDeclarationListInfo(selectedMembers);

            return(document.ReplaceMembersAsync(info, newMembers, cancellationToken));
        }
        private static Task <Document> RefactorAsync(
            Document document,
            MemberDeclarationSyntax declaration,
            List <MemberDeclarationSyntax> assignableMembers,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            MemberDeclarationListInfo info = SyntaxInfo.MemberDeclarationListInfo(GetContainingDeclaration(declaration));

            SyntaxList <MemberDeclarationSyntax> newMembers = MemberDeclarationInserter.Default.Insert(info.Members, CreateConstructor(GetConstructorIdentifierText(info.Parent), assignableMembers));

            SyntaxNode newNode = info.WithMembers(newMembers).Parent.WithFormatterAnnotation();

            return(document.ReplaceNodeAsync(info.Parent, newNode, cancellationToken));
        }
Beispiel #11
0
        public static Task <Document> RefactorAsync(
            Document document,
            MemberDeclarationSyntax member,
            CancellationToken cancellationToken = default)
        {
            MemberDeclarationListInfo info = SyntaxInfo.MemberDeclarationListInfo(member);

            SyntaxNode newNode = info
                                 .WithMembers(default(SyntaxList <MemberDeclarationSyntax>))
                                 .Parent
                                 .WithFormatterAnnotation();

            return(document.ReplaceNodeAsync(info.Parent, newNode, cancellationToken));
        }
        private static Task <Document> RefactorAsync(
            Document document,
            MemberDeclarationListSelection selectedMembers,
            MemberDeclarationComparer comparer,
            CancellationToken cancellationToken)
        {
            IEnumerable <MemberDeclarationSyntax> sorted = selectedMembers.OrderBy(f => f, comparer);

            MemberDeclarationListInfo info = SyntaxInfo.MemberDeclarationListInfo(selectedMembers);

            SyntaxList <MemberDeclarationSyntax> newMembers = info
                                                              .Members
                                                              .ReplaceRange(selectedMembers.FirstIndex, selectedMembers.Count, sorted);

            return(document.ReplaceMembersAsync(info, newMembers, cancellationToken));
        }
Beispiel #13
0
        private static Task <Document> SwapMembersAsync(
            Document document,
            MemberDeclarationListInfo info,
            int index,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            SyntaxList <MemberDeclarationSyntax> members = info.Members;

            MemberDeclarationSyntax member = members[index];

            SyntaxList <MemberDeclarationSyntax> newMembers = members.Replace(member, members[index + 1]);

            newMembers = newMembers.Replace(newMembers[index + 1], member);

            return(document.ReplaceMembersAsync(info, newMembers, cancellationToken));
        }
Beispiel #14
0
        private static Task <Document> RefactorAsync(
            Document document,
            MemberDeclarationListSelection selectedMembers,
            CancellationToken cancellationToken)
        {
            SyntaxList <MemberDeclarationSyntax> members = selectedMembers.UnderlyingList;

            IEnumerable <MemberDeclarationSyntax> newMembers = members.ModifyRange(
                selectedMembers.FirstIndex,
                selectedMembers.Count - 1,
                member => member.AppendToTrailingTrivia(CSharpFactory.NewLine()));

            MemberDeclarationListInfo membersInfo = SyntaxInfo.MemberDeclarationListInfo(selectedMembers);

            return(document.ReplaceMembersAsync(membersInfo, newMembers, cancellationToken));
        }
Beispiel #15
0
        /// <summary>
        /// Creates a new document with the specified members replaced with new members.
        /// </summary>
        /// <param name="document"></param>
        /// <param name="info"></param>
        /// <param name="newMembers"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static Task <Document> ReplaceMembersAsync(
            this Document document,
            MemberDeclarationListInfo info,
            SyntaxList <MemberDeclarationSyntax> newMembers,
            CancellationToken cancellationToken = default)
        {
            if (document == null)
            {
                throw new ArgumentNullException(nameof(document));
            }

            return(document.ReplaceNodeAsync(
                       info.Parent,
                       info.WithMembers(newMembers).Parent,
                       cancellationToken));
        }
        public static Task <Document> RefactorAsync(
            Document document,
            EventFieldDeclarationSyntax eventFieldDeclaration,
            IEventSymbol eventSymbol,
            ITypeSymbol eventArgsSymbol,
            bool supportsCSharp6,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            MemberDeclarationListInfo info = SyntaxInfo.MemberDeclarationListInfo(eventFieldDeclaration.Parent);

            MethodDeclarationSyntax method = CreateOnEventMethod(eventSymbol, eventArgsSymbol, supportsCSharp6)
                                             .WithFormatterAnnotation();

            SyntaxList <MemberDeclarationSyntax> newMembers = MemberDeclarationInserter.Default.Insert(info.Members, method);

            return(document.ReplaceMembersAsync(info, newMembers, cancellationToken));
        }
        private static bool CanFieldBeAssignedFromConstructor(
            FieldDeclarationSyntax fieldDeclaration,
            TextSpan span,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            VariableDeclaratorSyntax variable = fieldDeclaration
                                                .Declaration?
                                                .Variables
                                                .SingleOrDefault(shouldThrow: false);

            if (variable == null)
            {
                return(false);
            }

            MemberDeclarationListInfo info = SyntaxInfo.MemberDeclarationListInfo(GetContainingDeclaration(fieldDeclaration));

            if (!info.Success)
            {
                return(false);
            }

            ISymbol symbol = semanticModel.GetDeclaredSymbol(variable, cancellationToken);

            if (symbol == null)
            {
                return(false);
            }

            if (symbol.IsStatic)
            {
                return(false);
            }

            foreach (MemberDeclarationSyntax member in info.Members)
            {
                if (IsBackingField(member, symbol, span, semanticModel, cancellationToken))
                {
                    return(false);
                }
            }

            return(true);
        }
        private async Task <Document> RefactorAsync(
            Document document,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            ConstructorDeclarationSyntax constructor = Constructor;

            MemberDeclarationListInfo info = SyntaxInfo.MemberDeclarationListInfo(constructor.Parent);

            SyntaxList <MemberDeclarationSyntax> members = info.Members;

            SyntaxList <MemberDeclarationSyntax> newMembers = members.Replace(
                constructor,
                constructor.AddBodyStatements(CreateAssignments().ToArray()));

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

            newMembers = newMembers.InsertRange(
                GetDeclarationIndex(members),
                CreateDeclarations(constructor, semanticModel, cancellationToken));

            return(await document.ReplaceMembersAsync(info, newMembers, cancellationToken).ConfigureAwait(false));
        }
Beispiel #19
0
        public static async Task <Document> RefactorAsync(
            Document document,
            PropertyDeclarationSyntax propertyDeclaration,
            bool prefixIdentifierWithUnderscore = true,
            CancellationToken cancellationToken = default)
        {
            string fieldName = StringUtility.ToCamelCase(
                propertyDeclaration.Identifier.ValueText,
                prefixWithUnderscore: prefixIdentifierWithUnderscore);

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

            fieldName = NameGenerator.Default.EnsureUniqueName(
                fieldName,
                semanticModel,
                propertyDeclaration.SpanStart);

            FieldDeclarationSyntax fieldDeclaration = FieldDeclaration(
                (propertyDeclaration.Modifiers.Contains(SyntaxKind.StaticKeyword)) ? Modifiers.Private_Static() : Modifiers.Private(),
                propertyDeclaration.Type,
                fieldName,
                propertyDeclaration.Initializer).WithFormatterAnnotation();

            IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration, cancellationToken);

            PropertyDeclarationSyntax newPropertyDeclaration = ExpandAccessors(document, propertyDeclaration, propertySymbol, fieldName, semanticModel)
                                                               .WithModifiers(propertyDeclaration.Modifiers.Replace(SyntaxKind.AbstractKeyword, SyntaxKind.VirtualKeyword))
                                                               .WithTriviaFrom(propertyDeclaration)
                                                               .WithFormatterAnnotation();

            MemberDeclarationListInfo membersInfo = SyntaxInfo.MemberDeclarationListInfo(propertyDeclaration.Parent);

            SyntaxList <MemberDeclarationSyntax> members = membersInfo.Members;

            int propertyIndex = membersInfo.IndexOf(propertyDeclaration);

            AccessorListSyntax accessorList = propertyDeclaration.AccessorList;

            if (accessorList?.Getter()?.IsAutoImplemented() == true &&
                accessorList.Setter() == null)
            {
                ImmutableArray <SyntaxNode> nodes = await SyntaxFinder.FindReferencesAsync(propertySymbol, document, cancellationToken : cancellationToken).ConfigureAwait(false);

                IdentifierNameSyntax newNode = IdentifierName(fieldName);

                SyntaxNode newParent = membersInfo.Parent.ReplaceNodes(nodes, (node, _) =>
                {
                    if (node.IsParentKind(SyntaxKind.SimpleMemberAccessExpression) &&
                        ((MemberAccessExpressionSyntax)node.Parent).Expression.IsKind(SyntaxKind.BaseExpression))
                    {
                        return(node);
                    }

                    return(newNode.WithTriviaFrom(node));
                });

                MemberDeclarationListInfo newMembersInfo = SyntaxInfo.MemberDeclarationListInfo(newParent);

                members = newMembersInfo.Members;
            }

            SyntaxList <MemberDeclarationSyntax> newMembers = members.ReplaceAt(propertyIndex, newPropertyDeclaration);

            newMembers = MemberDeclarationInserter.Default.Insert(newMembers, fieldDeclaration);

            return(await document.ReplaceMembersAsync(membersInfo, newMembers, cancellationToken).ConfigureAwait(false));
        }