예제 #1
0
        private static async Task <Document> ApplyAddUsingFixAsync(CodeFixContext context, ExpressionStatementSyntax statement)
        {
            var editor = await DocumentEditor.CreateAsync(context.Document).ConfigureAwait(false);

            var usesUnderscoreNames = editor.SemanticModel.SyntaxTree.GetRoot().UsesUnderscoreNames(editor.SemanticModel, CancellationToken.None);
            var containingType      = statement.FirstAncestor <TypeDeclarationSyntax>();

            var field = editor.AddField(
                containingType,
                usesUnderscoreNames
                    ? "_disposable"
                    : "disposable",
                Accessibility.Private,
                DeclarationModifiers.ReadOnly,
                SyntaxFactory.ParseTypeName("System.IDisposable").WithAdditionalAnnotations(Simplifier.Annotation),
                CancellationToken.None);

            var fieldAccess = usesUnderscoreNames
                ? SyntaxFactory.IdentifierName(field.Name())
                : SyntaxFactory.ParseExpression($"this.{field.Name()}");

            editor.ReplaceNode(
                statement,
                SyntaxFactory.ExpressionStatement(
                    (ExpressionSyntax)editor.Generator.AssignmentStatement(
                        fieldAccess,
                        statement.Expression))
                .WithLeadingTrivia(SyntaxFactory.ElasticMarker)
                .WithTrailingTrivia(SyntaxFactory.ElasticMarker));
            return(editor.GetChangedDocument());
        }
        internal static Task <Document> RefactorAsync(
            Document document,
            ExpressionStatementSyntax expressionStatement,
            ITypeSymbol typeSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            MemberDeclarationSyntax containingMember = expressionStatement.FirstAncestor <MemberDeclarationSyntax>();

            var containingType = (TypeDeclarationSyntax)containingMember.Parent;

            string name = NameGenerator.CreateName(typeSymbol, firstCharToLower: true) ?? DefaultNames.Variable;

            if (RefactoringSettings.Current.PrefixFieldIdentifierWithUnderscore)
            {
                name = "_" + name;
            }

            name = NameGenerator.Default.EnsureUniqueLocalName(
                name,
                semanticModel,
                expressionStatement.SpanStart,
                cancellationToken: cancellationToken);

            name = NameGenerator.Default.EnsureUniqueMemberName(
                name,
                semanticModel,
                containingType.OpenBraceToken.Span.End,
                cancellationToken: cancellationToken);

            ExpressionSyntax expression = expressionStatement.Expression;

            ExpressionStatementSyntax newExpressionStatement = ExpressionStatement(
                SimpleAssignmentExpression(
                    IdentifierName(Identifier(name).WithRenameAnnotation()),
                    expression.WithoutTrivia()).WithTriviaFrom(expression));

            newExpressionStatement = newExpressionStatement
                                     .WithTriviaFrom(expressionStatement)
                                     .WithFormatterAnnotation();

            FieldDeclarationSyntax fieldDeclaration = FieldDeclaration(
                (containingMember.GetModifiers().Contains(SyntaxKind.StaticKeyword)) ? Modifiers.PrivateStatic() : Modifiers.Private(),
                typeSymbol.ToMinimalTypeSyntax(semanticModel, containingType.OpenBraceToken.Span.End),
                name);

            fieldDeclaration = fieldDeclaration.WithFormatterAnnotation();

            TypeDeclarationSyntax newNode = containingType
                                            .ReplaceNode(expressionStatement, newExpressionStatement)
                                            .InsertMember(fieldDeclaration, MemberDeclarationComparer.ByKind);

            return(document.ReplaceNodeAsync(containingType, newNode, cancellationToken));
        }
        private static async Task <Document> ApplyAddUsingFixAsync(CodeFixContext context, ExpressionStatementSyntax statement)
        {
            var editor = await DocumentEditor.CreateAsync(context.Document).ConfigureAwait(false);

            var usesUnderscoreNames = editor.SemanticModel.SyntaxTree.GetRoot().UsesUnderscoreNames(editor.SemanticModel, CancellationToken.None);
            var name = usesUnderscoreNames
                ? "_disposable"
                : "disposable";
            var containingType = statement.FirstAncestor <TypeDeclarationSyntax>();
            var declaredSymbol = editor.SemanticModel.GetDeclaredSymbol(containingType);

            while (declaredSymbol.MemberNames.Contains(name))
            {
                name += "_";
            }

            var newField = (FieldDeclarationSyntax)editor.Generator.FieldDeclaration(
                name,
                accessibility: Accessibility.Private,
                modifiers: DeclarationModifiers.ReadOnly,
                type: SyntaxFactory.ParseTypeName("IDisposable"));
            var members = containingType.Members;

            if (members.TryGetFirst(x => x is FieldDeclarationSyntax, out MemberDeclarationSyntax field))
            {
                editor.InsertBefore(field, new[] { newField });
            }
            else if (members.TryGetFirst(out field))
            {
                editor.InsertBefore(field, new[] { newField });
            }
            else
            {
                editor.AddMember(containingType, newField);
            }

            var fieldAccess = usesUnderscoreNames
                ? SyntaxFactory.IdentifierName(name)
                : SyntaxFactory.ParseExpression($"this.{name}");

            editor.ReplaceNode(
                statement,
                SyntaxFactory.ExpressionStatement(
                    (ExpressionSyntax)editor.Generator.AssignmentStatement(fieldAccess, statement.Expression))
                .WithLeadingTrivia(SyntaxFactory.ElasticMarker)
                .WithTrailingTrivia(SyntaxFactory.ElasticMarker));
            return(editor.GetChangedDocument());
        }
        private static async Task <Document> ApplyFixAsync(CodeFixContext context, CancellationToken cancellationToken, ExpressionStatementSyntax statement, bool usesUnderscoreNames)
        {
            var editor = await DocumentEditor.CreateAsync(context.Document, cancellationToken)
                         .ConfigureAwait(false);

            var name = usesUnderscoreNames
                           ? "_disposable"
                           : "disposable";
            var containingType = statement.FirstAncestor <TypeDeclarationSyntax>();
            var declaredSymbol = (INamedTypeSymbol)editor.SemanticModel.GetDeclaredSymbolSafe(containingType, cancellationToken);

            while (declaredSymbol.MemberNames.Contains(name))
            {
                name += "_";
            }

            var newField = (FieldDeclarationSyntax)editor.Generator.FieldDeclaration(
                name,
                accessibility: Accessibility.Private,
                modifiers: DeclarationModifiers.ReadOnly,
                type: CompositeDisposableType);

            editor.AddField(containingType, newField);

            var fieldAccess = usesUnderscoreNames
                                  ? SyntaxFactory.IdentifierName(name)
                                  : SyntaxFactory.ParseExpression($"this.{name}");

            editor.ReplaceNode(
                statement,
                SyntaxFactory.ExpressionStatement(
                    (ExpressionSyntax)editor.Generator.AssignmentStatement(
                        fieldAccess,
                        ((ObjectCreationExpressionSyntax)editor.Generator.ObjectCreationExpression(
                             CompositeDisposableType))
                        .WithInitializer(
                            SyntaxFactory.InitializerExpression(
                                SyntaxKind.CollectionInitializerExpression,
                                SyntaxFactory.SingletonSeparatedList(
                                    statement.Expression)))))
                .WithLeadingTrivia(SyntaxFactory.ElasticMarker)
                .WithTrailingTrivia(SyntaxFactory.ElasticMarker));
            return(editor.GetChangedDocument());
        }
        private static async Task <Document> ApplyAddUsingFixAsync(CodeFixContext context, ExpressionStatementSyntax statement)
        {
            var editor = await DocumentEditor.CreateAsync(context.Document).ConfigureAwait(false);

            var statements = statement.FirstAncestor <BlockSyntax>().Statements.Where(s => s.SpanStart > statement.SpanStart);

            foreach (var statementSyntax in statements)
            {
                editor.RemoveNode(statementSyntax);
            }

            editor.ReplaceNode(
                statement,
                SyntaxFactory.UsingStatement(
                    declaration: null,
                    expression: statement.Expression,
                    statement: SyntaxFactory.Block(SyntaxFactory.List(statements))
                    .WithAdditionalAnnotations(Formatter.Annotation)));
            return(editor.GetChangedDocument());
        }
예제 #6
0
        private static async Task <Document> ApplyFixAsync(CodeFixContext context, CancellationToken cancellationToken, ExpressionStatementSyntax statement, bool usesUnderscoreNames)
        {
            var editor = await DocumentEditor.CreateAsync(context.Document, cancellationToken)
                         .ConfigureAwait(false);

            var containingType = statement.FirstAncestor <TypeDeclarationSyntax>();

            var field = editor.AddField(
                containingType,
                usesUnderscoreNames
                    ? "_disposable"
                    : "disposable",
                Accessibility.Private,
                DeclarationModifiers.ReadOnly,
                CompositeDisposableType,
                cancellationToken);

            var fieldAccess = usesUnderscoreNames
                                  ? SyntaxFactory.IdentifierName(field.Name())
                                  : SyntaxFactory.ParseExpression($"this.{field.Name()}");

            editor.ReplaceNode(
                statement,
                SyntaxFactory.ExpressionStatement(
                    (ExpressionSyntax)editor.Generator.AssignmentStatement(
                        fieldAccess,
                        ((ObjectCreationExpressionSyntax)editor.Generator.ObjectCreationExpression(
                             CompositeDisposableType))
                        .WithInitializer(
                            SyntaxFactory.InitializerExpression(
                                SyntaxKind.CollectionInitializerExpression,
                                SyntaxFactory.SingletonSeparatedList(
                                    statement.Expression)))))
                .WithLeadingTrivia(SyntaxFactory.ElasticMarker)
                .WithTrailingTrivia(SyntaxFactory.ElasticMarker));
            return(editor.GetChangedDocument());
        }
        private static async Task <Document> ApplyFixAsync(CodeFixContext context, CancellationToken cancellationToken, ExpressionStatementSyntax statement, IFieldSymbol field, bool usesUnderscoreNames)
        {
            var editor = await DocumentEditor.CreateAsync(context.Document, cancellationToken)
                         .ConfigureAwait(false);

            var block = statement.FirstAncestor <BlockSyntax>();

            if (block?.Statements != null)
            {
                var index = block.Statements.IndexOf(statement);
                if (index > 0 &&
                    block.Statements[index - 1] is ExpressionStatementSyntax expressionStatement &&
                    expressionStatement.Expression is AssignmentExpressionSyntax assignment &&
                    assignment.Right is ObjectCreationExpressionSyntax objectCreation)
                {
                    if ((assignment.Left is IdentifierNameSyntax identifierName &&
                         identifierName.Identifier.ValueText == field.Name) ||
                        (assignment.Left is MemberAccessExpressionSyntax memberAccess &&
                         memberAccess.Expression is ThisExpressionSyntax &&
                         memberAccess.Name.Identifier.ValueText == field.Name))
                    {
                        editor.RemoveNode(statement);
                        if (objectCreation.Initializer != null)
                        {
                            editor.ReplaceNode(
                                objectCreation,
                                GetNewObjectCreation(objectCreation, statement.Expression));
                            return(editor.GetChangedDocument());
                        }

                        editor.ReplaceNode(
                            objectCreation,
                            objectCreation.WithInitializer(
                                SyntaxFactory.InitializerExpression(
                                    SyntaxKind.CollectionInitializerExpression,
                                    SyntaxFactory.SingletonSeparatedList(statement.Expression))
                                .WithAdditionalAnnotations(Simplifier.Annotation, Formatter.Annotation)));
                        return(editor.GetChangedDocument());
                    }
                }
            }

            var memberAccessExpressionSyntax = usesUnderscoreNames
                                                   ? (MemberAccessExpressionSyntax)editor
                                               .Generator.MemberAccessExpression(
                SyntaxFactory.IdentifierName(field.Name),
                "Add")
                                                   : (MemberAccessExpressionSyntax)editor.Generator.MemberAccessExpression(
                editor.Generator.MemberAccessExpression(
                    SyntaxFactory.ThisExpression(),
                    SyntaxFactory.IdentifierName(field.Name)),
                "Add");

            editor.ReplaceNode(
                statement,
                SyntaxFactory.ExpressionStatement(
                    (InvocationExpressionSyntax)editor.Generator.InvocationExpression(
                        memberAccessExpressionSyntax,
                        statement.Expression)));
            return(editor.GetChangedDocument());
        }