private void ReplaceQualifiedNames()
        {
            IEnumerable <QualifiedNameSyntax> qualifiedNames = tree.GetRoot().DescendantNodes().OfType <QualifiedNameSyntax>();

            foreach (QualifiedNameSyntax oldQualifiedNameNode in qualifiedNames) // iterate over all qualified names in the file
            {
                if (!(oldQualifiedNameNode.Parent is QualifiedNameSyntax))
                {
                    var    qualifiedSymbolInfo = semanticModel.GetSymbolInfo(oldQualifiedNameNode);
                    string nsString            = oldQualifiedNameNode.Left.WithoutTrivia().GetText().ToString();
                    if (qualifiedSymbolInfo.Symbol != null)
                    {
                        string   className = qualifiedSymbolInfo.Symbol.Name.ToString();
                        sdk_map2 sdkMap    = SDKMappingSQLConnector.GetInstance().GetSDKMapFromClassAndNamespace(TransformProject.sdkId, nsString, className);
                        if (sdkMap != null)
                        {
                            string newNamespace = sdkMap.namespace_map.new_namespace;
                            string newClassName = sdkMap.new_classname;
                            QualifiedNameSyntax newQualifiedNameNode = QualifiedName(IdentifierName(newNamespace), IdentifierName(newClassName)).WithTriviaFrom(oldQualifiedNameNode);
                            documentEditor.ReplaceNode(oldQualifiedNameNode, newQualifiedNameNode);
                        }
                    }
                }
            }
        }
        internal static void AddOnPropertyChanged(this DocumentEditor editor, ExpressionSyntax mutation, ExpressionStatementSyntax onPropertyChanged)
        {
            switch (mutation.Parent)
            {
            case SimpleLambdaExpressionSyntax lambda:
                editor.ReplaceNode(
                    lambda,
                    x => x.AddStatements(onPropertyChanged));
                break;

            case ParenthesizedLambdaExpressionSyntax lambda:
                editor.ReplaceNode(
                    lambda,
                    x => x.AddStatements(onPropertyChanged));
                break;

            case ExpressionStatementSyntax expressionStatement:
                editor.AddOnPropertyChangedAfter(expressionStatement, onPropertyChanged);
                break;

            case PrefixUnaryExpressionSyntax {
                    Parent: IfStatementSyntax ifNot
            } unary
                when unary.IsKind(SyntaxKind.LogicalNotExpression) :
                    editor.AddOnPropertyChangedAfter(ifNot, onPropertyChanged);

                break;
            }
        }
Beispiel #3
0
        private static void ConvertToLambda(DocumentEditor editor, SyntaxNode toReplace, IMethodSymbol method, MethodDeclarationSyntax declaration, CancellationToken cancellationToken)
        {
            if (method.Parameters.TrySingle(out var parameter))
            {
                if (declaration.ExpressionBody is ArrowExpressionClauseSyntax expressionBody)
                {
                    editor.ReplaceNode(
                        toReplace,
                        SyntaxFactory.ParseExpression($"{parameter.Name} => {expressionBody.Expression}")
                        .WithLeadingTriviaFrom(toReplace));
                    RemoveMethod(editor, method, declaration, cancellationToken);
                }
                else if (declaration.Body is BlockSyntax body &&
                         body.Statements.TrySingle(out var statement) &&
                         statement is ReturnStatementSyntax returnStatement)
                {
                    editor.ReplaceNode(
                        toReplace,
                        SyntaxFactory.ParseExpression($"{parameter.Name} => {returnStatement.Expression}")
                        .WithLeadingTriviaFrom(toReplace));
                    RemoveMethod(editor, method, declaration, cancellationToken);
                }
            }

            if (method.Parameters.Length == 2 &&
                method.Parameters.TryElementAt(0, out var parameter1) &&
                method.Parameters.TryElementAt(1, out var parameter2))
            {
                if (declaration.ExpressionBody is ArrowExpressionClauseSyntax expressionBody)
                {
                    editor.ReplaceNode(
                        toReplace,
                        SyntaxFactory.ParseExpression($"({parameter1.Name}, {parameter2.Name}) => {expressionBody.Expression}")
                        .WithLeadingTriviaFrom(toReplace));
                    RemoveMethod(editor, method, declaration, cancellationToken);
                }
                else if (declaration.Body is BlockSyntax body &&
                         body.Statements.TrySingle(out var statement))
                {
                    switch (statement)
                    {
                    case ReturnStatementSyntax returnStatement:
                        editor.ReplaceNode(
                            toReplace,
                            SyntaxFactory.ParseExpression($"({parameter1.Name}, {parameter2.Name}) => {returnStatement.Expression}")
                            .WithLeadingTriviaFrom(toReplace));
                        RemoveMethod(editor, method, declaration, cancellationToken);
                        break;

                    case ExpressionStatementSyntax expressionStatement:
                        editor.ReplaceNode(
                            toReplace,
                            SyntaxFactory.ParseExpression($"({parameter1.Name}, {parameter2.Name}) => {expressionStatement.Expression}")
                            .WithLeadingTriviaFrom(toReplace));
                        RemoveMethod(editor, method, declaration, cancellationToken);
                        break;
                    }
                }
            }
        }
 private static void UseLambda(DocumentEditor editor, IdentifierNameSyntax identifierName, CancellationToken cancellationToken)
 {
     if (editor.SemanticModel.TryGetSymbol(identifierName, cancellationToken, out IMethodSymbol method))
     {
         if (method.Parameters.Length == 0)
         {
             _ = editor.ReplaceNode(
                 identifierName,
                 x => SyntaxFactory.ParseExpression($"() => {x.Identifier.ValueText}()"));
         }
         else if (method.Parameters.TrySingle(out var parameter))
         {
             var parameterName = SafeParameterName(parameter, identifierName);
             _ = editor.ReplaceNode(
                 identifierName,
                 x => SyntaxFactory.ParseExpression($"{parameterName} => {x.Identifier.ValueText}({parameterName})"));
         }
         else
         {
             var parameters = string.Join(", ", method.Parameters.Select(x => SafeParameterName(x, identifierName)));
             _ = editor.ReplaceNode(
                 identifierName,
                 x => SyntaxFactory.ParseExpression($"({parameters}) => {x.Identifier.ValueText}({parameters})"));
         }
     }
 }
        private static void ApplyInitializeInCtorFix(
            DocumentEditor editor,
            ConstructorDeclarationSyntax ctor,
            PropertyDeclarationSyntax property,
            ObjectCreationExpressionSyntax objectCreation)
        {
            var member = editor.SemanticModel.UnderscoreFields()
                ? (ExpressionSyntax)SyntaxFactory.IdentifierName(property.Identifier.ValueText)
                : SyntaxFactory.MemberAccessExpression(
                SyntaxKind.SimpleMemberAccessExpression,
                SyntaxFactory.ThisExpression(),
                SyntaxFactory.Token(SyntaxKind.DotToken),
                SyntaxFactory.IdentifierName(property.Identifier.ValueText));
            var assignment =
                SyntaxFactory.ExpressionStatement(
                    SyntaxFactory.AssignmentExpression(
                        SyntaxKind.SimpleAssignmentExpression,
                        member,
                        objectCreation));

            editor.ReplaceNode(ctor.Body, (x, _) => ((BlockSyntax)x).AddStatements(assignment));
            editor.ReplaceNode(
                property,
                (x, _) => ((PropertyDeclarationSyntax)x).WithExpressionBody(null)
                .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None))
                .WithAccessorList(GetOnlyAccessorList));
        }
Beispiel #6
0
        private static void RemoveExpression(DocumentEditor editor, ArgumentSyntax argument, IMethodSymbol invoker, bool usesUnderscoreNames, CancellationToken cancellationToken)
        {
            var invocation = argument.FirstAncestorOrSelf <InvocationExpressionSyntax>();

            if (PropertyChanged.TryGetInvokedPropertyChangedName(invocation, editor.SemanticModel, cancellationToken, out var name) == AnalysisResult.Yes)
            {
                var property = editor.SemanticModel.GetDeclaredSymbolSafe(argument.FirstAncestorOrSelf <PropertyDeclarationSyntax>(), cancellationToken);
                if (property?.Name == name)
                {
                    editor.ReplaceNode(
                        invocation,
                        SyntaxFactory.ParseExpression(Snippet.OnPropertyChanged(invoker, property?.Name, usesUnderscoreNames).TrimEnd(';'))
                        .WithSimplifiedNames()
                        .WithLeadingElasticLineFeed()
                        .WithTrailingElasticLineFeed()
                        .WithAdditionalAnnotations(Formatter.Annotation));
                }
                else
                {
                    editor.ReplaceNode(
                        invocation,
                        SyntaxFactory.ParseExpression(Snippet.OnOtherPropertyChanged(invoker, name, usesUnderscoreNames).TrimEnd(';'))
                        .WithSimplifiedNames()
                        .WithLeadingElasticLineFeed()
                        .WithTrailingElasticLineFeed()
                        .WithAdditionalAnnotations(Formatter.Annotation));
                }
            }
        }
Beispiel #7
0
        private static void ReplaceMagicStrings(
            Dictionary <string, string> constants,
            SyntaxNode classNode,
            DocumentEditor editor,
            MagicStringsReplacementStatistics stats)
        {
            foreach (var child in classNode.DescendantNodes().OfType <LiteralExpressionSyntax>().Where(s => s.Kind() == SyntaxKind.StringLiteralExpression))
            {
                var value = child.WithoutTrivia().GetText().ToString();
                if (value == "\"\"")
                {
                    if (IsIgnoredEmptyStringNode(child))
                    {
                        continue;
                    }

                    var stringEmpty = SyntaxFactory.MemberAccessExpression(
                        SyntaxKind.SimpleMemberAccessExpression,
                        SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.StringKeyword)),
                        SyntaxFactory.IdentifierName("Empty"));

                    if (child.HasLeadingTrivia)
                    {
                        stringEmpty = stringEmpty.WithLeadingTrivia(child.GetLeadingTrivia());
                    }

                    if (child.HasTrailingTrivia)
                    {
                        stringEmpty = stringEmpty.WithTrailingTrivia(child.GetTrailingTrivia());
                    }

                    editor.ReplaceNode(child, stringEmpty);
                    stats.EmptyStringsReplaced++;
                }

                if (constants.TryGetValue(value, out var name))
                {
                    if (IsNodeConst(child))
                    {
                        continue;
                    }

                    var useConstant = SyntaxFactory.IdentifierName(name);

                    if (child.HasLeadingTrivia)
                    {
                        useConstant = useConstant.WithLeadingTrivia(child.GetLeadingTrivia());
                    }

                    if (child.HasTrailingTrivia)
                    {
                        useConstant = useConstant.WithTrailingTrivia(child.GetTrailingTrivia());
                    }

                    editor.ReplaceNode(child, useConstant);
                    stats.MagicStringsReplaced++;
                }
            }
        }
Beispiel #8
0
        private static void MakeAutoPropertyNotifyWhenValueChanges(DocumentEditor editor, PropertyDeclarationSyntax propertyDeclaration, IMethodSymbol invoker, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            if (Property.IsMutableAutoProperty(propertyDeclaration, out var getter, out var setter))
            {
                if (getter.Body != null ||
                    getter.ContainsSkippedText ||
                    setter.Body != null ||
                    setter.ContainsSkippedText)
                {
                    return;
                }

                var underscoreFields = CodeStyle.UnderscoreFields(semanticModel);
                var property         = semanticModel.GetDeclaredSymbolSafe(propertyDeclaration, cancellationToken);
                var backingField     = editor.AddBackingField(propertyDeclaration, underscoreFields, cancellationToken);
                var fieldAccess      = underscoreFields
                    ? backingField.Name()
                    : $"this.{backingField.Name()}";
                var code = StringBuilderPool.Borrow()
                           .AppendLine($"public Type PropertyName")
                           .AppendLine("{")
                           .AppendLine($"    get => {fieldAccess};")
                           .AppendLine()
                           .AppendLine("    set")
                           .AppendLine("    {")
                           .AppendLine($"        if ({Snippet.EqualityCheck(property.Type, "value", fieldAccess, semanticModel)})")
                           .AppendLine("        {")
                           .AppendLine($"           return;")
                           .AppendLine("        }")
                           .AppendLine()
                           .AppendLine($"        {fieldAccess} = value;")
                           .AppendLine($"        {Snippet.OnPropertyChanged(invoker, property.Name, underscoreFields)}")
                           .AppendLine("    }")
                           .AppendLine("}")
                           .Return();
                var template = ParseProperty(code);
                editor.ReplaceNode(
                    getter,
                    x => x.WithExpressionBody(template.Getter().ExpressionBody)
                    .WithTrailingElasticLineFeed()
                    .WithAdditionalAnnotations(Formatter.Annotation));
                editor.ReplaceNode(
                    setter,
                    x => x.WithBody(template.Setter().Body)
                    .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None))
                    .WithAdditionalAnnotations(Formatter.Annotation));
                if (propertyDeclaration.Initializer != null)
                {
                    editor.ReplaceNode(
                        propertyDeclaration,
                        x => x.WithoutInitializer());
                }

                editor.ReplaceNode(propertyDeclaration, x => x.WithAdditionalAnnotations(Formatter.Annotation));
            }
        }
Beispiel #9
0
        private static async Task <Solution> InlineAndRemoveMethodAsync(
            Document document,
            ExpressionStatementSyntax expressionStatement,
            MethodDeclarationSyntax methodDeclaration,
            StatementSyntax[] statements,
            ParameterInfo[] parameterInfos,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (expressionStatement.SyntaxTree.Equals(methodDeclaration.SyntaxTree))
            {
                DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);

                Solution solution = document.Project.Solution;

                StatementSyntax[] newStatements = await ReplaceParameterExpressionWithArgumentExpressionAsync(
                    parameterInfos,
                    statements,
                    solution,
                    cancellationToken).ConfigureAwait(false);

                newStatements[0] = newStatements[0].WithLeadingTrivia(expressionStatement.GetLeadingTrivia());
                newStatements[statements.Length - 1] = newStatements[statements.Length - 1].WithTrailingTrivia(expressionStatement.GetTrailingTrivia());

                if (expressionStatement.Parent.IsKind(SyntaxKind.Block))
                {
                    var block = (BlockSyntax)expressionStatement.Parent;

                    BlockSyntax newBlock = block.WithStatements(block.Statements.ReplaceRange(expressionStatement, newStatements));

                    editor.ReplaceNode(block, newBlock);
                }
                else
                {
                    editor.ReplaceNode(expressionStatement, Block(newStatements));
                }

                editor.RemoveNode(methodDeclaration);

                document = editor.GetChangedDocument();

                return(document.Project.Solution);
            }
            else
            {
                Solution solution = document.Project.Solution;

                document = await InlineMethodAsync(document, expressionStatement, statements, parameterInfos, cancellationToken).ConfigureAwait(false);

                DocumentId documentId = solution.GetDocumentId(methodDeclaration.SyntaxTree);

                solution = document.Project.Solution;

                return(await RemoveMethodAsync(solution.GetDocument(documentId), methodDeclaration, cancellationToken).ConfigureAwait(false));
            }
        }
Beispiel #10
0
        private static void FixArgument(DocumentEditor editor, AttributeSyntax attributeSyntax, ITypeSymbol inType, ITypeSymbol outType)
        {
            editor.ReplaceNode(
                attributeSyntax.ArgumentList.Arguments[0],
                editor.Generator.AttributeArgument(
                    editor.Generator.TypeOfExpression(editor.Generator.TypeExpression(inType))));

            editor.ReplaceNode(
                attributeSyntax.ArgumentList.Arguments[1],
                editor.Generator.AttributeArgument(
                    editor.Generator.TypeOfExpression(editor.Generator.TypeExpression(outType))));
        }
Beispiel #11
0
        private static void MakeAutoPropertySet(DocumentEditor editor, PropertyDeclarationSyntax propertyDeclaration, IMethodSymbol setAndRaise, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            var classDeclaration = propertyDeclaration.FirstAncestorOrSelf <ClassDeclarationSyntax>();

            if (classDeclaration == null)
            {
                return;
            }

            if (Property.IsMutableAutoProperty(propertyDeclaration, out var getter, out var setter))
            {
                if (getter.Body != null ||
                    getter.ContainsSkippedText ||
                    setter.Body != null ||
                    setter.ContainsSkippedText)
                {
                    return;
                }

                var underscoreFields = CodeStyle.UnderscoreFields(semanticModel);
                var backingField     = editor.AddBackingField(propertyDeclaration, underscoreFields, cancellationToken);
                var fieldAccess      = underscoreFields
                    ? backingField.Name()
                    : $"this.{backingField.Name()}";
                var code = StringBuilderPool.Borrow()
                           .AppendLine($"public Type PropertyName")
                           .AppendLine("{")
                           .AppendLine($"    get => {fieldAccess};")
                           .AppendLine($"    set => {(underscoreFields ? string.Empty : "this.")}{setAndRaise.Name}(ref {fieldAccess}, value);")
                           .AppendLine("}")
                           .Return();
                var template = ParseProperty(code);
                editor.ReplaceNode(
                    getter,
                    x => x.WithExpressionBody(template.Getter().ExpressionBody)
                    .WithLeadingLineFeed());

                editor.ReplaceNode(
                    setter,
                    x => x.WithExpressionBody(template.Setter().ExpressionBody)
                    .WithLeadingLineFeed()
                    .WithTrailingLineFeed());

                if (propertyDeclaration.Initializer != null)
                {
                    editor.ReplaceNode(
                        propertyDeclaration,
                        (node, g) => ((PropertyDeclarationSyntax)node).WithoutInitializer());
                }

                editor.ReplaceNode(propertyDeclaration, x => x.WithAdditionalAnnotations(Formatter.Annotation));
            }
        }
        internal static void AddOnPropertyChanged(this DocumentEditor editor, BlockSyntax block, ExpressionStatementSyntax onPropertyChangedStatement, int after)
        {
            _ = editor.ReplaceNode(
                block,
                x =>
            {
                if (onPropertyChangedStatement.Expression is InvocationExpressionSyntax onPropertyChanged)
                {
                    for (var i = after; i < x.Statements.Count; i++)
                    {
                        var statement = x.Statements[i];

                        // We can't use the semantic model here as it may not track nodes added before in fixall
                        switch (statement)
                        {
                        case ExpressionStatementSyntax {
                            Expression: AssignmentExpressionSyntax _
                        } :
                            break;

                        case ExpressionStatementSyntax {
                            Expression: InvocationExpressionSyntax other
                        }
                            when onPropertyChanged.IsEquivalentTo(other) :
                                return(x);
Beispiel #13
0
        internal static FieldDeclarationSyntax AddBackingField(this DocumentEditor editor, PropertyDeclarationSyntax propertyDeclaration, bool usesUnderscoreNames, CancellationToken cancellationToken)
        {
            var property = editor.SemanticModel.GetDeclaredSymbolSafe(propertyDeclaration, cancellationToken);
            var name     = usesUnderscoreNames
                ? $"_{property.Name.ToFirstCharLower()}"
                : property.Name.ToFirstCharLower();

            while (property.ContainingType.MemberNames.Any(x => x == name))
            {
                name += "_";
            }

            if (SyntaxFacts.GetKeywordKind(name) != SyntaxKind.None ||
                SyntaxFacts.GetContextualKeywordKind(name) != SyntaxKind.None)
            {
                name = "@" + name;
            }

            var backingField = (FieldDeclarationSyntax)editor.Generator.FieldDeclaration(
                name,
                accessibility: Accessibility.Private,
                modifiers: DeclarationModifiers.None,
                type: propertyDeclaration.Type,
                initializer: propertyDeclaration.Initializer?.Value);
            var type = (TypeDeclarationSyntax)propertyDeclaration.Parent;

            editor.ReplaceNode(
                type,
                (node, generator) => AddBackingField((TypeDeclarationSyntax)node, backingField, property.Name, generator));
            return(backingField);
        }
        private static void AddUsingToEndOfBlock(DocumentEditor editor, BlockSyntax block, ExpressionSyntax expression)
        {
            foreach (var statementSyntax in block.Statements)
            {
                editor.RemoveNode(statementSyntax);
            }

            editor.ReplaceNode(
                block,
                SyntaxFactory.Block(
                    SyntaxFactory.UsingStatement(
                        declaration: null,
                        expression: GetExpression(),
                        statement: block.WithAdditionalAnnotations(Formatter.Annotation))));

            ExpressionSyntax GetExpression()
            {
                if (expression is DeclarationExpressionSyntax declaration &&
                    declaration.Designation is SingleVariableDesignationSyntax singleVariable)
                {
                    return(SyntaxFactory.IdentifierName(singleVariable.Identifier));
                }

                return(expression);
            }
        }
 private static void ReplaceWithUsing(DocumentEditor editor, InvocationExpressionSyntax invocation, CancellationToken cancellationToken)
 {
     if (DisposeCall.TryGetDisposedRootMember(invocation, editor.SemanticModel, cancellationToken, out var root) &&
         editor.SemanticModel.TryGetSymbol(root, cancellationToken, out ILocalSymbol local) &&
         local.TrySingleDeclaration(cancellationToken, out VariableDeclarationSyntax declaration) &&
         invocation.TryFirstAncestor(out ExpressionStatementSyntax expressionStatement) &&
         declaration.Parent is LocalDeclarationStatementSyntax localDeclarationStatement)
     {
         if (expressionStatement.Parent is BlockSyntax finallyBlock &&
             finallyBlock.Parent is FinallyClauseSyntax finallyClause &&
             finallyClause.Parent is TryStatementSyntax tryStatement &&
             !tryStatement.Catches.Any())
         {
             if (declaration.Variables.TrySingle(out var declarator) &&
                 declarator.Initializer?.Value.IsKind(SyntaxKind.NullLiteralExpression) == true &&
                 tryStatement.Block.Statements.TryFirst(out var statement) &&
                 statement is ExpressionStatementSyntax assignExpressionStatement &&
                 assignExpressionStatement.Expression is AssignmentExpressionSyntax assignment)
             {
                 editor.ReplaceNode(
                     tryStatement,
                     SyntaxFactory.UsingStatement(
                         SyntaxFactory.VariableDeclaration(
                             SyntaxFactory.ParseTypeName("var"),
                             SyntaxFactory.SingletonSeparatedList(
                                 declarator.WithInitializer(SyntaxFactory.EqualsValueClause(assignment.Right)))),
                         null,
                         tryStatement.Block.WithStatements(tryStatement.Block.Statements.RemoveAt(0))));
                 editor.RemoveNode(localDeclarationStatement);
             }
        public async Task <Solution> InlineAndRemoveMethodAsync(InvocationExpressionSyntax invocation, ExpressionSyntax expression)
        {
            if (invocation.SyntaxTree == MethodDeclaration.SyntaxTree)
            {
                DocumentEditor editor = await DocumentEditor.CreateAsync(Document, CancellationToken).ConfigureAwait(false);

                ExpressionSyntax newExpression = RewriteExpression(invocation, expression);

                editor.ReplaceNode(invocation, newExpression);

                editor.RemoveNode(MethodDeclaration);

                return(editor.GetChangedDocument().Solution());
            }
            else
            {
                Document newDocument = await InlineMethodAsync(invocation, expression).ConfigureAwait(false);

                DocumentId documentId = Document.Solution().GetDocumentId(MethodDeclaration.SyntaxTree);

                newDocument = await newDocument.Solution().GetDocument(documentId).RemoveMemberAsync(MethodDeclaration, CancellationToken).ConfigureAwait(false);

                return(newDocument.Solution());
            }
        }
        private static async Task <Document> SwapArgumentsOrderAsync(Document document, IObjectCreationOperation creation, int paramPosition, int argumentCount, CancellationToken token)
        {
            DocumentEditor editor = await DocumentEditor.CreateAsync(document, token).ConfigureAwait(false);

            SyntaxNode parameter = AddNameOfIfLiteral(creation.Arguments[paramPosition].Value, editor.Generator);
            SyntaxNode newCreation;

            if (argumentCount == 2)
            {
                if (paramPosition == 0)
                {
                    newCreation = editor.Generator.ObjectCreationExpression(creation.Type, creation.Arguments[1].Syntax, parameter);
                }
                else
                {
                    newCreation = editor.Generator.ObjectCreationExpression(creation.Type, parameter, creation.Arguments[0].Syntax);
                }
            }
            else
            {
                Debug.Assert(argumentCount == 3);
                if (paramPosition == 0)
                {
                    newCreation = editor.Generator.ObjectCreationExpression(creation.Type, creation.Arguments[1].Syntax, parameter, creation.Arguments[2].Syntax);
                }
                else
                {
                    newCreation = editor.Generator.ObjectCreationExpression(creation.Type, parameter, creation.Arguments[1].Syntax, creation.Arguments[0].Syntax);
                }
            }
            editor.ReplaceNode(creation.Syntax, newCreation);
            return(editor.GetChangedDocument());
        }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            Document          doc = context.Document;
            CancellationToken cancellationToken = context.CancellationToken;
            SyntaxNode        root = await doc.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            SemanticModel model = await doc.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            // If we're able to make the desired substitution...
            var(targetNode, replacementField) = GetTaskCreationOptionsField(context, root, model, cancellationToken);
            if (replacementField != null)
            {
                // ...then offer it.
                string title = MicrosoftNetCoreAnalyzersResources.DoNotCreateTaskCompletionSourceWithWrongArgumentsFix;
                context.RegisterCodeFix(
                    new MyCodeAction(title,
                                     async ct =>
                {
                    // Replace "TaskContinuationOptions.Value" with "TaskCreationOptions.Value"
                    DocumentEditor editor = await DocumentEditor.CreateAsync(doc, ct).ConfigureAwait(false);
                    editor.ReplaceNode(targetNode,
                                       editor.Generator.Argument(
                                           editor.Generator.MemberAccessExpression(
                                               editor.Generator.TypeExpressionForStaticMemberAccess(replacementField.ContainingType), replacementField.Name)));
                    return(editor.GetChangedDocument());
                },
                                     equivalenceKey: title),
                    context.Diagnostics);
            }
Beispiel #19
0
        private static void ApplyFixGU0005(DocumentEditor editor, ArgumentSyntax nameArgument, CancellationToken cancellationToken)
        {
            var argumentListSyntax = nameArgument.FirstAncestorOrSelf <ArgumentListSyntax>();
            var arguments          = new ArgumentSyntax[argumentListSyntax.Arguments.Count];
            var method             = editor.SemanticModel.GetSymbolSafe(argumentListSyntax.Parent, cancellationToken) as IMethodSymbol;
            var messageIndex       = ParameterIndex(method, "message");
            var nameIndex          = ParameterIndex(method, "paramName");

            for (var i = 0; i < argumentListSyntax.Arguments.Count; i++)
            {
                if (i == messageIndex)
                {
                    arguments[nameIndex] = argumentListSyntax.Arguments[i];
                    continue;
                }

                if (i == nameIndex)
                {
                    arguments[messageIndex] = argumentListSyntax.Arguments[i];
                    continue;
                }

                arguments[i] = argumentListSyntax.Arguments[i];
            }

            var updated = argumentListSyntax.WithArguments(SyntaxFactory.SeparatedList(arguments, argumentListSyntax.Arguments.GetSeparators()));

            editor.ReplaceNode(argumentListSyntax, updated);
        }
Beispiel #20
0
            private void VisitExpression(ExpressionSyntax node)
            {
                var newNode = this.Command.NewExpression
                              .WithAdditionalAnnotations(new SyntaxAnnotation($"{Id}"));

                DocumentEditor.ReplaceNode(node, newNode);
            }
Beispiel #21
0
            public static void UpdateMethodBody(DocumentEditor editor, SyntaxNode syntaxNode, string src)
            {
                var methodDeclaration = syntaxNode.FirstAncestorOrSelf <MethodDeclarationSyntax>();
                var body = (BlockSyntax)SyntaxFactory.ParseStatement(src).WithAdditionalAnnotations(Formatter.Annotation);

                editor.ReplaceNode(methodDeclaration.Body, body);
            }
Beispiel #22
0
        private static async Task <Document> ConvertToArrayEmptyAsync(Document document, SyntaxNode nodeToFix, CancellationToken cancellationToken)
        {
            DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);

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

            SyntaxGenerator generator = editor.Generator;

            INamedTypeSymbol?arrayTypeSymbol = semanticModel.Compilation.GetSpecialType(SpecialType.System_Array);

            if (arrayTypeSymbol == null)
            {
                return(document);
            }

            ITypeSymbol?elementType = GetArrayElementType(nodeToFix, semanticModel, cancellationToken);

            if (elementType == null)
            {
                return(document);
            }

            SyntaxNode arrayEmptyInvocation = GenerateArrayEmptyInvocation(generator, arrayTypeSymbol, elementType).WithTriviaFrom(nodeToFix);

            editor.ReplaceNode(nodeToFix, arrayEmptyInvocation);
            return(editor.GetChangedDocument());
        }
            /// <summary>
            /// if a nested type is being moved, this ensures its containing type is partial.
            /// </summary>
            private void AddPartialModifiersToTypeChain(
                DocumentEditor documentEditor, bool removeAttributesAndComments)
            {
                var semanticFacts = State.SemanticDocument.Document.GetLanguageService <ISemanticFactsService>();
                var typeChain     = State.TypeNode.Ancestors().OfType <TTypeDeclarationSyntax>();

                foreach (var node in typeChain)
                {
                    var symbol = (ITypeSymbol)State.SemanticDocument.SemanticModel.GetDeclaredSymbol(node, CancellationToken);
                    if (!semanticFacts.IsPartial(symbol, CancellationToken))
                    {
                        documentEditor.SetModifiers(node,
                                                    documentEditor.Generator.GetModifiers(node) | DeclarationModifiers.Partial);
                    }

                    if (removeAttributesAndComments)
                    {
                        documentEditor.RemoveAllAttributes(node);
                        documentEditor.RemoveAllComments(node);
                    }
                }

                documentEditor.ReplaceNode(State.TypeNode,
                                           (currentNode, generator) =>
                {
                    var currentTypeNode = (TTypeDeclarationSyntax)currentNode;

                    // Trim leading whitespace from the type so we don't have excessive
                    // leading blank lines.
                    return(RemoveLeadingWhitespace(currentTypeNode));
                });
            }
Beispiel #24
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            Document          doc = context.Document;
            CancellationToken cancellationToken = context.CancellationToken;
            SyntaxNode        root = await doc.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            if (root.FindNode(context.Span) is SyntaxNode expression)
            {
                string title = MicrosoftNetCoreAnalyzersResources.PreferTypedStringBuilderAppendOverloadsRemoveToString;
                context.RegisterCodeFix(
                    new MyCodeAction(title,
                                     async ct =>
                {
                    SemanticModel model = await doc.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
                    if (model.GetOperationWalkingUpParentChain(expression, cancellationToken) is IArgumentOperation arg &&
                        arg.Value is IInvocationOperation invoke &&
                        invoke.Instance?.Syntax is SyntaxNode replacement)
                    {
                        DocumentEditor editor = await DocumentEditor.CreateAsync(doc, ct).ConfigureAwait(false);
                        editor.ReplaceNode(expression, editor.Generator.Argument(replacement));
                        return(editor.GetChangedDocument());
                    }

                    return(doc);
                },
                                     equivalenceKey: title),
                    context.Diagnostics);
            }
        }
        private async Task <Document> ConvertToStringLengthComparison(CodeFixContext context, FixResolution fixResolution)
        {
            DocumentEditor editor = await DocumentEditor.CreateAsync(context.Document, context.CancellationToken).ConfigureAwait(false);

            SyntaxNode leftOperand  = GetLeftOperand(fixResolution.BinaryExpressionSyntax);
            SyntaxNode rightOperand = GetRightOperand(fixResolution.BinaryExpressionSyntax);

            // Take the below example:
            //   if (f == String.Empty) ...
            // The comparison operand, f, will now become 'f.Length' and a the other operand will become '0'
            SyntaxNode zeroLengthSyntax = editor.Generator.LiteralExpression(0);

            if (leftOperand == fixResolution.ComparisonOperand)
            {
                leftOperand  = editor.Generator.MemberAccessExpression(leftOperand, "Length");
                rightOperand = zeroLengthSyntax.WithTriviaFrom(rightOperand);
            }
            else
            {
                leftOperand  = zeroLengthSyntax;
                rightOperand = editor.Generator.MemberAccessExpression(rightOperand.WithoutTrivia(), "Length");
            }

            SyntaxNode replacementSyntax = fixResolution.UsesEqualsOperator ?
                                           editor.Generator.ValueEqualsExpression(leftOperand, rightOperand) :
                                           editor.Generator.ValueNotEqualsExpression(leftOperand, rightOperand);

            SyntaxNode replacementAnnotatedSyntax = replacementSyntax.WithAdditionalAnnotations(Formatter.Annotation);

            editor.ReplaceNode(fixResolution.BinaryExpressionSyntax, replacementAnnotatedSyntax);

            return(editor.GetChangedDocument());
        }
Beispiel #26
0
        protected override async Task <SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
        {
            var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);

            if (diagnostics.IsEmpty)
            {
                return(null);
            }

            DocumentEditor editor = await DocumentEditor.CreateAsync(document, fixAllContext.CancellationToken).ConfigureAwait(false);

            SyntaxNode root = editor.GetChangedRoot();

            ImmutableList <SyntaxNode> nodesToChange = ImmutableList.Create <SyntaxNode>();

            // Make sure all nodes we care about are tracked
            foreach (var diagnostic in diagnostics)
            {
                var location   = diagnostic.Location;
                var syntaxNode = root.FindNode(location.SourceSpan);
                if (syntaxNode != null)
                {
                    editor.TrackNode(syntaxNode);
                    nodesToChange = nodesToChange.Add(syntaxNode);
                }
            }

            foreach (var node in nodesToChange)
            {
                editor.ReplaceNode(node, node.WithLeadingTrivia(SyntaxFactory.ElasticCarriageReturnLineFeed));
            }

            return(editor.GetChangedRoot());
        }
Beispiel #27
0
        public virtual async Task <Solution> InlineAndRemoveAsync(
            SyntaxNode node,
            ExpressionSyntax expression,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (node.SyntaxTree == Declaration.SyntaxTree)
            {
                DocumentEditor editor = await DocumentEditor.CreateAsync(Document, cancellationToken).ConfigureAwait(false);

                ExpressionSyntax newExpression = RewriteExpression(node, expression);

                editor.ReplaceNode(node, newExpression);

                editor.RemoveNode(Declaration);

                return(editor.GetChangedDocument().Solution());
            }
            else
            {
                Document newDocument = await InlineAsync(node, expression, cancellationToken).ConfigureAwait(false);

                DocumentId documentId = Document.Solution().GetDocumentId(Declaration.SyntaxTree);

                newDocument = await newDocument.Solution().GetDocument(documentId).RemoveMemberAsync(Declaration, cancellationToken).ConfigureAwait(false);

                return(newDocument.Solution());
            }
        }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            Document      doc   = context.Document;
            SemanticModel model = await doc.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);

            SyntaxNode root = await doc.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            if (root.FindNode(context.Span, getInnermostNodeForTie: true) is SyntaxNode node &&
                model.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemEnvironment, out var environmentType) &&
                model.GetOperation(node, context.CancellationToken) is IPropertyReferenceOperation operation)
            {
                string title = MicrosoftNetCoreAnalyzersResources.UseEnvironmentProcessIdFix;
                context.RegisterCodeFix(
                    new MyCodeAction(title,
                                     async cancellationToken =>
                {
                    DocumentEditor editor = await DocumentEditor.CreateAsync(doc, cancellationToken).ConfigureAwait(false);
                    var replacement       = editor.Generator.MemberAccessExpression(editor.Generator.TypeExpressionForStaticMemberAccess(environmentType), "ProcessId");
                    editor.ReplaceNode(node, replacement.WithTriviaFrom(node));
                    return(editor.GetChangedDocument());
                },
                                     equivalenceKey: title),
                    context.Diagnostics);
            }
        }
        private static async Task <Document> ImplementIDisposable(Document document, SyntaxNode declaration, CancellationToken cancellationToken)
        {
            DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);

            SyntaxGenerator generator = editor.Generator;
            SemanticModel   model     = editor.SemanticModel;

            // Add the interface to the baselist.
            SyntaxNode interfaceType = generator.TypeExpression(WellKnownTypes.IDisposable(model.Compilation));

            editor.AddInterfaceType(declaration, interfaceType);

            // Find a Dispose method. If one exists make that implement IDisposable, else generate a new method.
            var           typeSymbol    = model.GetDeclaredSymbol(declaration) as INamedTypeSymbol;
            IMethodSymbol disposeMethod = (typeSymbol?.GetMembers("Dispose"))?.OfType <IMethodSymbol>()?.Where(m => m.Parameters.Length == 0).FirstOrDefault();

            if (disposeMethod != null && disposeMethod.DeclaringSyntaxReferences.Length == 1)
            {
                SyntaxNode memberPartNode = await disposeMethod.DeclaringSyntaxReferences.Single().GetSyntaxAsync(cancellationToken).ConfigureAwait(false);

                memberPartNode = generator.GetDeclaration(memberPartNode);
                editor.ReplaceNode(memberPartNode, generator.AsPublicInterfaceImplementation(memberPartNode, interfaceType));
            }
            else
            {
                SyntaxNode throwStatement = generator.ThrowStatement(generator.ObjectCreationExpression(WellKnownTypes.NotImplementedException(model.Compilation)));
                SyntaxNode member         = generator.MethodDeclaration(TypesThatOwnDisposableFieldsShouldBeDisposableAnalyzer <SyntaxNode> .Dispose, statements: new[] { throwStatement });
                member = generator.AsPublicInterfaceImplementation(member, interfaceType);
                editor.AddMember(declaration, member);
            }

            return(editor.GetChangedDocument());
        }
Beispiel #30
0
            public static void UpdateMethodBody(DocumentEditor editor, SyntaxNode syntaxNode, string src)
            {
                var methodBlock = syntaxNode.FirstAncestorOrSelf <MethodBlockSyntax>();
                var statements  = new SyntaxList <StatementSyntax>().AddRange(GetStatements(src));

                editor.ReplaceNode(methodBlock, methodBlock.WithStatements(statements));
            }