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()); }
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()); }