public static async Task <Document> RefactorAsync(
            Document document,
            MemberDeclarationListSelection selectedMembers,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            IEnumerable <MemberDeclarationSyntax> newMembers = selectedMembers
                                                               .UnderlyingList
                                                               .ModifyRange(
                selectedMembers.FirstIndex,
                selectedMembers.Count,
                member =>
            {
                ArrowExpressionClauseSyntax expressionBody = CSharpUtility.GetExpressionBody(member);

                if (expressionBody != null &&
                    ExpandExpressionBodyAnalysis.IsFixable(expressionBody))
                {
                    return((MemberDeclarationSyntax)Refactor(expressionBody, semanticModel, cancellationToken)
                           .WithFormatterAnnotation());
                }

                return(member);
            });

            return(await document.ReplaceMembersAsync(SyntaxInfo.MemberDeclarationListInfo(selectedMembers.Parent), newMembers, cancellationToken).ConfigureAwait(false));
        }
        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));
        }
        public static Task <Document> RefactorAsync(
            Document document,
            MemberDeclarationListSelection selectedMembers,
            CancellationToken cancellationToken)
        {
            IEnumerable <MemberDeclarationSyntax> newMembers = selectedMembers
                                                               .UnderlyingList
                                                               .ModifyRange(
                selectedMembers.FirstIndex,
                selectedMembers.Count,
                member =>
            {
                if (CanRefactor(member))
                {
                    var newMember = (MemberDeclarationSyntax)Refactor(member);

                    return(newMember
                           .WithTrailingTrivia(member.GetTrailingTrivia())
                           .WithFormatterAnnotation());
                }

                return(member);
            });

            return(document.ReplaceMembersAsync(SyntaxInfo.MemberDeclarationListInfo(selectedMembers.Parent), newMembers, cancellationToken));
        }
        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]);
        }
Exemplo n.º 5
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);
        }
        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));
            }
        }
Exemplo n.º 7
0
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, MemberDeclarationSyntax declaration)
        {
            if (!context.IsRefactoringEnabled(RefactoringIdentifiers.IntroduceConstructor))
            {
                return;
            }

            List <MemberDeclarationSyntax> members = null;

            SyntaxKind kind = declaration.Kind();

            if (kind.Is(SyntaxKind.PropertyDeclaration, SyntaxKind.FieldDeclaration))
            {
                if (context.Span.Contains(declaration.Span))
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    if (CanBeAssignedFromConstructor(declaration, context.Span, semanticModel, context.CancellationToken))
                    {
                        members = new List <MemberDeclarationSyntax>()
                        {
                            declaration
                        };
                    }
                }
            }
            else if (kind.Is(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration))
            {
                SemanticModel semanticModel = null;

                foreach (MemberDeclarationSyntax member in SyntaxInfo.MemberDeclarationListInfo(declaration).Members)
                {
                    if (context.Span.Contains(member.Span))
                    {
                        if (semanticModel == null)
                        {
                            semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);
                        }

                        if (CanBeAssignedFromConstructor(member, context.Span, semanticModel, context.CancellationToken))
                        {
                            (members ?? (members = new List <MemberDeclarationSyntax>())).Add(member);
                        }
                    }
                }
            }

            if (members == null)
            {
                return;
            }

            context.RegisterRefactoring(
                "Introduce constructor",
                ct => RefactorAsync(context.Document, declaration, members, ct),
                RefactoringIdentifiers.IntroduceConstructor);
        }
Exemplo n.º 8
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)));
        }
Exemplo n.º 9
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));
        }
        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));
        }
Exemplo n.º 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));
        }
Exemplo n.º 12
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,
            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));
        }
Exemplo n.º 14
0
        public static async Task <Document> RefactorAsync(
            Document document,
            MemberDeclarationListSelection selectedMembers,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            IEnumerable <MemberDeclarationSyntax> newMembers = selectedMembers
                                                               .UnderlyingList
                                                               .ModifyRange(
                selectedMembers.FirstIndex,
                selectedMembers.Count,
                f => (MemberDeclarationSyntax)Refactor(CSharpUtility.GetExpressionBody(f), semanticModel, cancellationToken).WithFormatterAnnotation());

            return(await document.ReplaceMembersAsync(SyntaxInfo.MemberDeclarationListInfo(selectedMembers.Parent), newMembers, cancellationToken).ConfigureAwait(false));
        }
Exemplo n.º 15
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));
        }
        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));
        }
Exemplo n.º 19
0
        public static void AnalyzeNamedType(SymbolAnalysisContext context)
        {
            var symbol = (INamedTypeSymbol)context.Symbol;

            if (!symbol.TypeKind.Is(TypeKind.Class, TypeKind.Struct, TypeKind.Interface))
            {
                return;
            }

            SyntaxReference syntaxReference = symbol.DeclaringSyntaxReferences.SingleOrDefault(shouldThrow: false);

            if (syntaxReference == null)
            {
                return;
            }

            if (!(syntaxReference.GetSyntax(context.CancellationToken) is MemberDeclarationSyntax memberDeclaration))
            {
                return;
            }

            SyntaxToken partialKeyword = SyntaxInfo.ModifierListInfo(memberDeclaration).Modifiers.Find(SyntaxKind.PartialKeyword);

            if (!partialKeyword.IsKind(SyntaxKind.PartialKeyword))
            {
                return;
            }

            if (SyntaxInfo.MemberDeclarationListInfo(memberDeclaration)
                .Members
                .Any(member => member.Kind() == SyntaxKind.MethodDeclaration && ((MethodDeclarationSyntax)member).Modifiers.Contains(SyntaxKind.PartialKeyword)))
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.RemovePartialModifierFromTypeWithSinglePart, partialKeyword);
        }
Exemplo n.º 20
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));
        }