private static async Task <Document> FormatAccessorListAsync( Document document, AccessorListSyntax accessorList, CancellationToken cancellationToken) { SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); if (accessorList.Accessors.All(f => f.Body == null)) { var propertyDeclaration = (PropertyDeclarationSyntax)accessorList.Parent; TextSpan span = TextSpan.FromBounds( propertyDeclaration.Identifier.Span.End, accessorList.CloseBraceToken.Span.Start); PropertyDeclarationSyntax newPropertyDeclaration = SyntaxRemover.RemoveWhitespaceOrEndOfLine(propertyDeclaration, span); newPropertyDeclaration = newPropertyDeclaration .WithFormatterAnnotation(); root = root.ReplaceNode(propertyDeclaration, newPropertyDeclaration); } else { AccessorListSyntax newAccessorList = GetNewAccessorList(accessorList) .WithFormatterAnnotation(); root = root.ReplaceNode(accessorList, newAccessorList); } return(document.WithSyntaxRoot(root)); }
internal static TRoot?RemoveNodes <TRoot>(TRoot root, IEnumerable <SyntaxNode> nodes, SyntaxRemoveOptions options) where TRoot : SyntaxNode { if (nodes == null) { return(root); } var nodeArray = nodes.ToArray(); if (nodeArray.Length == 0) { return(root); } var remover = new SyntaxRemover(nodes.ToArray(), options); var result = remover.Visit(root); var residualTrivia = remover.ResidualTrivia; // the result of the SyntaxRemover will be null when the root node is removed. if (result != null && residualTrivia.Count > 0) { result = result.WithTrailingTrivia(result.GetTrailingTrivia().Concat(residualTrivia)); } return((TRoot?)result); }
private static PropertyDeclarationSyntax CreateAutoProperty(PropertyDeclarationSyntax property, EqualsValueClauseSyntax initializer) { AccessorListSyntax accessorList = CreateAccessorList(property); if (accessorList .DescendantTrivia() .All(f => f.IsWhitespaceOrEndOfLineTrivia())) { accessorList = SyntaxRemover.RemoveWhitespaceOrEndOfLine(accessorList); } PropertyDeclarationSyntax newProperty = property .WithIdentifier(property.Identifier.WithTrailingSpace()) .WithExpressionBody(null) .WithAccessorList(accessorList); if (initializer != null) { newProperty = newProperty .WithInitializer(initializer) .WithSemicolonToken(SemicolonToken()); } else { newProperty = newProperty.WithoutSemicolonToken(); } return(newProperty .WithTriviaFrom(property) .WithFormatterAnnotation()); }
public static void ComputeRefactorings(RefactoringContext context) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.RemoveAllRegionDirectives) && context.Root.IsKind(SyntaxKind.CompilationUnit)) { context.RegisterRefactoring( "Remove all region directives", cancellationToken => SyntaxRemover.RemoveRegionDirectivesAsync(context.Document, cancellationToken)); } }
public static void ComputeRefactorings(RefactoringContext context, RegionDirectiveTriviaSyntax regionDirective) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.RemoveRegion) && context.Root.IsKind(SyntaxKind.CompilationUnit)) { context.RegisterRefactoring( "Remove region", cancellationToken => SyntaxRemover.RemoveRegionAsync(context.Document, regionDirective, cancellationToken)); } }
private static SyntaxNode RemoveAllButMember(CompilationUnitSyntax compilationUnit, MemberDeclarationSyntax memberDeclaration) { IEnumerable <MemberDeclarationSyntax> membersToRemove = GetNonNestedTypeDeclarations(compilationUnit.Members) .Where(f => f != memberDeclaration); CompilationUnitSyntax newCompilationUnit = compilationUnit.RemoveNodes( membersToRemove, SyntaxRemoveOptions.KeepUnbalancedDirectives); return(SyntaxRemover.RemoveEmptyNamespaces(newCompilationUnit, SyntaxRemoveOptions.KeepUnbalancedDirectives)); }
private static ExpressionSyntax ProcessExpression(ExpressionSyntax expression) { if (expression .DescendantTrivia(expression.Span) .All(f => f.IsWhitespaceOrEndOfLineTrivia())) { expression = SyntaxRemover.RemoveWhitespaceOrEndOfLine(expression) .WithFormatterAnnotation(); } return(expression); }
private static PropertyDeclarationSyntax ExpandProperty(PropertyDeclarationSyntax propertyDeclaration) { AccessorListSyntax accessorList = AccessorList(List(CreateAccessors(propertyDeclaration))); accessorList = SyntaxRemover.RemoveWhitespaceOrEndOfLine(accessorList) .WithCloseBraceToken(accessorList.CloseBraceToken.WithLeadingTrivia(CSharpFactory.NewLineTrivia())); return(propertyDeclaration .WithoutInitializer() .WithoutSemicolonToken() .WithAccessorList(accessorList)); }
private static async Task <Document> RemoveCommentAsync( Document document, CommentRemoveOptions removeOptions, CancellationToken cancellationToken = default(CancellationToken)) { SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); SyntaxNode newRoot = SyntaxRemover.RemoveComment(root, removeOptions) .WithFormatterAnnotation(); return(document.WithSyntaxRoot(newRoot)); }
public static void ComputeRefactorings(RefactoringContext context) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.RemoveAllPreprocessorDirectives)) { context.RegisterRefactoring( "Remove all directives", cancellationToken => { return(SyntaxRemover.RemoveDirectivesAsync( context.Document, context.CancellationToken)); }); } }
public override SyntaxNode VisitAccessorDeclaration(AccessorDeclarationSyntax node) { if (node == null) { throw new ArgumentNullException(nameof(node)); } if (AccessorListDiagnosticAnalyzer.ShouldBeFormatted(node)) { return(SyntaxRemover.RemoveWhitespaceOrEndOfLine(node, node.Span)); } return(base.VisitAccessorDeclaration(node)); }
public static async Task <Document> FormatAllParametersOnSingleLineAsync( Document document, ParameterListSyntax parameterList, CancellationToken cancellationToken = default(CancellationToken)) { SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); ParameterListSyntax newParameterList = SyntaxRemover.RemoveWhitespaceOrEndOfLine(parameterList) .WithFormatterAnnotation(); SyntaxNode newRoot = oldRoot.ReplaceNode(parameterList, newParameterList); return(document.WithSyntaxRoot(newRoot)); }
private static async Task <Document> FormatExpressionChainOnSingleLineAsync( Document document, MemberAccessExpressionSyntax expression, CancellationToken cancellationToken = default(CancellationToken)) { SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); SyntaxNode newNode = SyntaxRemover.RemoveWhitespaceOrEndOfLine(expression) .WithFormatterAnnotation(); SyntaxNode newRoot = oldRoot.ReplaceNode(expression, newNode); return(document.WithSyntaxRoot(newRoot)); }
private static async Task <Document> FormatOnSingleLineAsync( Document document, BinaryExpressionSyntax condition, CancellationToken cancellationToken = default(CancellationToken)) { SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); BinaryExpressionSyntax newCondition = SyntaxRemover.RemoveWhitespaceOrEndOfLine(condition); root = root.ReplaceNode( condition, newCondition.WithFormatterAnnotation()); return(document.WithSyntaxRoot(root)); }
private static async Task <Document> RemoveParameterNameFromArgumentsAsync( Document document, ArgumentListSyntax argumentList, ImmutableArray <ArgumentSyntax> arguments, CancellationToken cancellationToken = default(CancellationToken)) { SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); ArgumentListSyntax newArgumentList = SyntaxRemover.RemoveNameColon(argumentList, arguments) .WithFormatterAnnotation(); SyntaxNode newRoot = oldRoot.ReplaceNode(argumentList, newArgumentList); return(document.WithSyntaxRoot(newRoot)); }
private static AccessorListSyntax GetNewAccessorList(AccessorListSyntax accessorList) { if (accessorList.IsSingleLine(includeExteriorTrivia: false)) { SyntaxTriviaList triviaList = accessorList.CloseBraceToken.LeadingTrivia .Add(CSharpFactory.NewLineTrivia()); return(SyntaxRemover.RemoveWhitespaceOrEndOfLine(accessorList) .WithCloseBraceToken(accessorList.CloseBraceToken.WithLeadingTrivia(triviaList))); } else { return(AccessorSyntaxRewriter.VisitNode(accessorList)); } }
public static async Task <Document> RefactorAsync( Document document, AccessorDeclarationSyntax accessor, CancellationToken cancellationToken = default(CancellationToken)) { SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); AccessorDeclarationSyntax newAccessor = SyntaxRemover.RemoveWhitespaceOrEndOfLine(accessor) .WithTriviaFrom(accessor) .WithFormatterAnnotation(); root = root.ReplaceNode(accessor, newAccessor); return(document.WithSyntaxRoot(root)); }
private static AccessorListSyntax CreateAccessorList(BlockSyntax block, bool singleline) { AccessorListSyntax accessorList = AccessorList( SingletonList( AccessorDeclaration( SyntaxKind.GetAccessorDeclaration, block))); if (singleline) { accessorList = SyntaxRemover.RemoveWhitespaceOrEndOfLine(accessorList); } return(accessorList); }
internal static TRoot RemoveNodes <TRoot>(TRoot root, IEnumerable <SyntaxNode> nodes, SyntaxRemoveOptions options) where TRoot : SyntaxNode { SyntaxNode[] nodesToRemove = nodes.ToArray(); if (nodesToRemove.Length == 0) { return(root); } var remover = new SyntaxRemover(nodes.ToArray(), options); var result = remover.Visit(root); var residualTrivia = remover.ResidualTrivia; if (residualTrivia.Count > 0) { result = result.WithTrailingTrivia(result.GetTrailingTrivia().Concat(residualTrivia)); } return((TRoot)result); }
private static AccessorListSyntax CreateAccessorList(BlockSyntax block, bool singleline) { AccessorListSyntax accessorList = AccessorList( SingletonList( AccessorDeclaration( SyntaxKind.GetAccessorDeclaration, block))); if (singleline) { accessorList = SyntaxRemover.RemoveWhitespaceOrEndOfLine(accessorList) .WithCloseBraceToken(accessorList.CloseBraceToken.WithLeadingTrivia(CSharpFactory.NewLineTrivia())); } return(accessorList); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.Document .GetSyntaxRootAsync(context.CancellationToken) .ConfigureAwait(false); ConstructorDeclarationSyntax constructor = root .FindNode(context.Span, getInnermostNodeForTie: true)? .FirstAncestorOrSelf <ConstructorDeclarationSyntax>(); if (constructor == null) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case DiagnosticIdentifiers.RemoveRedundantBaseConstructorCall: { CodeAction codeAction = CodeAction.Create( "Remove redundant base constructor call", cancellationToken => RemoveBaseConstructorCallAsync(context.Document, constructor, cancellationToken), diagnostic.Id + EquivalenceKeySuffix); context.RegisterCodeFix(codeAction, diagnostic); break; } case DiagnosticIdentifiers.RemoveRedundantConstructor: { CodeAction codeAction = CodeAction.Create( "Remove redundant constructor", cancellationToken => SyntaxRemover.RemoveMemberAsync(context.Document, constructor, cancellationToken), diagnostic.Id + EquivalenceKeySuffix); context.RegisterCodeFix(codeAction, diagnostic); break; } } } }
public static async Task <Solution> RefactorAsync( Document document, MemberDeclarationSyntax memberDeclaration, CancellationToken cancellationToken = default(CancellationToken)) { if (document == null) { throw new ArgumentNullException(nameof(document)); } if (memberDeclaration == null) { throw new ArgumentNullException(nameof(memberDeclaration)); } SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); SyntaxNode newRoot = root.RemoveNode(memberDeclaration, SyntaxRemoveOptions.KeepUnbalancedDirectives); newRoot = SyntaxRemover.RemoveEmptyNamespaces(newRoot, SyntaxRemoveOptions.KeepUnbalancedDirectives); document = document.WithSyntaxRoot(newRoot); newRoot = RemoveAllButMember((CompilationUnitSyntax)root, memberDeclaration); string documentName = GetDocumentName(memberDeclaration, semanticModel, cancellationToken); var folders = new List <string>(document.Folders.Count + 1); folders.Add(document.Project.Name); folders.AddRange(document.Folders); document = document.Project.AddDocument( documentName, newRoot, ImmutableArray.CreateRange(folders)); return(document.Project.Solution); }
private static EventDeclarationSyntax ExpandEvent(EventFieldDeclarationSyntax eventDeclaration) { AccessorListSyntax accessorList = AccessorList( List(new AccessorDeclarationSyntax[] { AccessorDeclaration(SyntaxKind.AddAccessorDeclaration, Block()), AccessorDeclaration(SyntaxKind.RemoveAccessorDeclaration, Block()), })); accessorList = SyntaxRemover.RemoveWhitespaceOrEndOfLine(accessorList) .WithCloseBraceToken(accessorList.CloseBraceToken.WithLeadingTrivia(CSharpFactory.NewLineTrivia())); VariableDeclaratorSyntax declarator = eventDeclaration.Declaration.Variables[0]; return(EventDeclaration( eventDeclaration.AttributeLists, eventDeclaration.Modifiers, eventDeclaration.Declaration.Type, null, declarator.Identifier, accessorList)); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.Document .GetSyntaxRootAsync(context.CancellationToken) .ConfigureAwait(false); RegionDirectiveTriviaSyntax region = root .FindNode(context.Span, findInsideTrivia: true, getInnermostNodeForTie: true)? .FirstAncestorOrSelf <RegionDirectiveTriviaSyntax>(); CodeAction codeAction = CodeAction.Create( "Remove empty region", cancellationToken => { return(SyntaxRemover.RemoveRegionAsync( context.Document, region, cancellationToken)); }, DiagnosticIdentifiers.RemoveEmptyRegion + EquivalenceKeySuffix); context.RegisterCodeFix(codeAction, context.Diagnostics); }
private static PropertyDeclarationSyntax ExpandPropertyAndAddBackingField(PropertyDeclarationSyntax propertyDeclaration, string name) { AccessorDeclarationSyntax getter = propertyDeclaration.Getter(); if (getter != null) { AccessorDeclarationSyntax newGetter = getter .WithBody(Block(ReturnStatement(IdentifierName(name)))) .WithoutSemicolonToken(); propertyDeclaration = propertyDeclaration .ReplaceNode(getter, newGetter) .WithoutInitializer() .WithoutSemicolonToken(); } AccessorDeclarationSyntax setter = propertyDeclaration.Setter(); if (setter != null) { AccessorDeclarationSyntax newSetter = setter .WithBody(Block( ExpressionStatement( SimpleAssignmentExpression( IdentifierName(name), IdentifierName("value"))))) .WithoutSemicolonToken(); propertyDeclaration = propertyDeclaration.ReplaceNode(setter, newSetter); } AccessorListSyntax accessorList = SyntaxRemover.RemoveWhitespaceOrEndOfLine(propertyDeclaration.AccessorList) .WithCloseBraceToken(propertyDeclaration.AccessorList.CloseBraceToken.WithLeadingTrivia(CSharpFactory.NewLineTrivia())); return(propertyDeclaration .WithAccessorList(accessorList)); }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, MemberDeclarationSyntax member) { switch (member.Kind()) { case SyntaxKind.MethodDeclaration: case SyntaxKind.IndexerDeclaration: case SyntaxKind.PropertyDeclaration: case SyntaxKind.OperatorDeclaration: case SyntaxKind.ConversionOperatorDeclaration: case SyntaxKind.ConstructorDeclaration: case SyntaxKind.EventDeclaration: case SyntaxKind.NamespaceDeclaration: case SyntaxKind.ClassDeclaration: case SyntaxKind.StructDeclaration: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.EnumDeclaration: { if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.RemoveMember, RefactoringIdentifiers.DuplicateMember, RefactoringIdentifiers.CommentOutMember) && BraceContainsSpan(context, member)) { if (member.Parent?.IsKind( SyntaxKind.NamespaceDeclaration, SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.InterfaceDeclaration, SyntaxKind.CompilationUnit) == true) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.RemoveMember)) { context.RegisterRefactoring( "Remove " + SyntaxHelper.GetSyntaxNodeTitle(member), cancellationToken => SyntaxRemover.RemoveMemberAsync(context.Document, member, cancellationToken)); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.DuplicateMember)) { context.RegisterRefactoring( "Duplicate " + SyntaxHelper.GetSyntaxNodeTitle(member), cancellationToken => DuplicateMemberDeclarationRefactoring.RefactorAsync(context.Document, member, cancellationToken)); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.CommentOutMember)) { CommentOutRefactoring.RegisterRefactoring(context, member); } } break; } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.RemoveAllStatements)) { RemoveAllStatementsRefactoring.ComputeRefactoring(context, member); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.RemoveAllMemberDeclarations)) { RemoveAllMemberDeclarationsRefactoring.ComputeRefactoring(context, member); } if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.SwapMemberDeclarations, RefactoringIdentifiers.RemoveMemberDeclarations) && !member.Span.IntersectsWith(context.Span)) { MemberDeclarationsRefactoring.ComputeRefactoring(context, member); } switch (member.Kind()) { case SyntaxKind.ClassDeclaration: { var classDeclaration = (ClassDeclarationSyntax)member; ExtractTypeDeclarationToNewFileRefactoring.ComputeRefactorings(context, classDeclaration); if (context.IsRefactoringEnabled(RefactoringIdentifiers.GenerateBaseConstructors)) { await GenerateBaseConstructorsRefactoring.ComputeRefactoringAsync(context, classDeclaration).ConfigureAwait(false); } break; } case SyntaxKind.StructDeclaration: { ExtractTypeDeclarationToNewFileRefactoring.ComputeRefactorings(context, (StructDeclarationSyntax)member); break; } case SyntaxKind.InterfaceDeclaration: { ExtractTypeDeclarationToNewFileRefactoring.ComputeRefactorings(context, (InterfaceDeclarationSyntax)member); break; } case SyntaxKind.EnumDeclaration: { ExtractTypeDeclarationToNewFileRefactoring.ComputeRefactorings(context, (EnumDeclarationSyntax)member); break; } case SyntaxKind.DelegateDeclaration: { ExtractTypeDeclarationToNewFileRefactoring.ComputeRefactorings(context, (DelegateDeclarationSyntax)member); break; } case SyntaxKind.MethodDeclaration: { await MethodDeclarationRefactoring.ComputeRefactoringsAsync(context, (MethodDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.ConstructorDeclaration: { await ConstructorDeclarationRefactoring.ComputeRefactoringsAsync(context, (ConstructorDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.IndexerDeclaration: { await IndexerDeclarationRefactoring.ComputeRefactoringsAsync(context, (IndexerDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.PropertyDeclaration: { await PropertyDeclarationRefactoring.ComputeRefactoringsAsync(context, (PropertyDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.OperatorDeclaration: { ComputeRefactorings(context, (OperatorDeclarationSyntax)member); break; } case SyntaxKind.ConversionOperatorDeclaration: { ComputeRefactorings(context, (ConversionOperatorDeclarationSyntax)member); break; } case SyntaxKind.FieldDeclaration: { await FieldDeclarationRefactoring.ComputeRefactoringsAsync(context, (FieldDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.EventDeclaration: { await EventDeclarationRefactoring.ComputeRefactoringsAsync(context, (EventDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.EventFieldDeclaration: { await EventFieldDeclarationRefactoring.ComputeRefactoringsAsync(context, (EventFieldDeclarationSyntax)member).ConfigureAwait(false); break; } } }
private static async Task <StatementListInfo> RefactorAsync <TStatement>( Document document, TStatement statement, StatementListInfo statementsInfo, Func <TStatement, TStatement> createNewStatement, int count, bool removeReturnStatement, CancellationToken cancellationToken) where TStatement : StatementSyntax { int index = statementsInfo.IndexOf(statement); var returnStatement = (ReturnStatementSyntax)statementsInfo[index + 1]; ExpressionSyntax expression = returnStatement.Expression; ExpressionSyntax newExpression = null; SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ISymbol symbol = semanticModel.GetSymbol(expression, cancellationToken); if (symbol.Kind == SymbolKind.Local && index > 0) { var localDeclarationStatement = statementsInfo[index - 1] as LocalDeclarationStatementSyntax; if (localDeclarationStatement?.ContainsDiagnostics == false && !localDeclarationStatement.SpanOrTrailingTriviaContainsDirectives() && !statement.GetLeadingTrivia().Any(f => f.IsDirective)) { SeparatedSyntaxList <VariableDeclaratorSyntax> declarators = localDeclarationStatement.Declaration.Variables; VariableDeclaratorSyntax declarator = declarators.FirstOrDefault(f => semanticModel.GetDeclaredSymbol(f, cancellationToken)?.Equals(symbol) == true); if (declarator != null) { ExpressionSyntax value = declarator.Initializer?.Value; if (removeReturnStatement || value != null) { IEnumerable <ReferencedSymbol> referencedSymbols = await SymbolFinder.FindReferencesAsync(symbol, document.Solution(), cancellationToken).ConfigureAwait(false); if (referencedSymbols.First().Locations.Count() == count + 1) { newExpression = value; if (declarators.Count == 1) { statementsInfo = statementsInfo.RemoveNode(localDeclarationStatement, SyntaxRemover.GetRemoveOptions(localDeclarationStatement)); index--; } else { statementsInfo = statementsInfo.ReplaceNode(localDeclarationStatement, localDeclarationStatement.RemoveNode(declarator, SyntaxRemover.GetRemoveOptions(declarator))); } returnStatement = (ReturnStatementSyntax)statementsInfo[index + 1]; } } } } } if (removeReturnStatement) { statementsInfo = statementsInfo.RemoveNode(returnStatement, SyntaxRemover.GetRemoveOptions(returnStatement)); } else if (newExpression != null) { statementsInfo = statementsInfo.ReplaceNode(returnStatement, returnStatement.WithExpression(newExpression.WithTriviaFrom(expression))); } StatementSyntax oldNode = statementsInfo[index]; TStatement newNode = createNewStatement((TStatement)oldNode).WithFormatterAnnotation(); return(statementsInfo.ReplaceNode(oldNode, newNode)); }
private static async Task <StatementListInfo> RefactorAsync( Document document, StatementListInfo statementsInfo, StatementSyntax statement, StatementSyntax newStatement, int index, int count, bool removeReturnStatement, SemanticModel semanticModel, CancellationToken cancellationToken) { ReturnStatementSyntax returnStatement = FindReturnStatementBelow(statementsInfo.Statements, index); ExpressionSyntax expression = returnStatement.Expression; ExpressionSyntax newExpression = null; ISymbol symbol = semanticModel.GetSymbol(expression, cancellationToken); if (symbol?.Kind == SymbolKind.Local && index > 0) { LocalDeclarationStatementSyntax localDeclarationStatement = FindLocalDeclarationStatementAbove(statementsInfo.Statements, index); if (localDeclarationStatement?.ContainsDiagnostics == false && !localDeclarationStatement.SpanOrTrailingTriviaContainsDirectives() && !statement.GetLeadingTrivia().Any(f => f.IsDirective)) { SeparatedSyntaxList <VariableDeclaratorSyntax> declarators = localDeclarationStatement.Declaration.Variables; VariableDeclaratorSyntax declarator = FindVariableDeclarator(semanticModel, symbol, declarators, cancellationToken); if (declarator != null) { ExpressionSyntax value = declarator.Initializer?.Value; if (removeReturnStatement || value != null) { IEnumerable <ReferencedSymbol> referencedSymbols = await SymbolFinder.FindReferencesAsync(symbol, document.Solution(), cancellationToken).ConfigureAwait(false); if (referencedSymbols.First().Locations.Count() == count + 1) { newExpression = value; if (declarators.Count == 1) { statementsInfo = statementsInfo.RemoveNode(localDeclarationStatement, SyntaxRemover.GetRemoveOptions(localDeclarationStatement)); index--; } else { statementsInfo = statementsInfo.ReplaceNode(localDeclarationStatement, localDeclarationStatement.RemoveNode(declarator, SyntaxRemover.GetRemoveOptions(declarator))); } returnStatement = FindReturnStatementBelow(statementsInfo.Statements, index); } } } } } if (removeReturnStatement) { statementsInfo = statementsInfo.RemoveNode(returnStatement, SyntaxRemover.GetRemoveOptions(returnStatement)); } else if (newExpression != null) { statementsInfo = statementsInfo.ReplaceNode(returnStatement, returnStatement.WithExpression(newExpression.WithTriviaFrom(expression))); } return(statementsInfo.ReplaceNode(statementsInfo[index], newStatement)); }
private static async Task <StatementListInfo> RefactorAsync <TStatement>( Document document, TStatement statement, StatementListInfo statementsInfo, Func <TStatement, TStatement> createNewStatement, int count, bool removeReturnStatement, CancellationToken cancellationToken) where TStatement : StatementSyntax { int statementIndex = statementsInfo.IndexOf(statement); var returnStatement = (ReturnStatementSyntax)statementsInfo[statementIndex + 1]; ExpressionSyntax returnExpression = returnStatement.Expression; ExpressionSyntax newReturnExpression = null; SyntaxTriviaList newTrailingTrivia = default; SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ISymbol symbol = semanticModel.GetSymbol(returnExpression, cancellationToken); if (symbol.Kind == SymbolKind.Local && statementIndex > 0 && statementsInfo[statementIndex - 1] is LocalDeclarationStatementSyntax localDeclarationStatement && !localDeclarationStatement.ContainsDiagnostics && !localDeclarationStatement.SpanOrTrailingTriviaContainsDirectives() && !statement.GetLeadingTrivia().Any(f => f.IsDirective)) { SeparatedSyntaxList <VariableDeclaratorSyntax> declarators = localDeclarationStatement.Declaration.Variables; VariableDeclaratorSyntax declarator = declarators.FirstOrDefault(f => semanticModel.GetDeclaredSymbol(f, cancellationToken)?.Equals(symbol) == true); if (declarator != null) { ExpressionSyntax value = declarator.Initializer?.Value; if (removeReturnStatement || value != null) { IEnumerable <ReferencedSymbol> referencedSymbols = await SymbolFinder.FindReferencesAsync(symbol, document.Solution(), cancellationToken).ConfigureAwait(false); if (referencedSymbols.First().Locations.Count() == count + 1) { newReturnExpression = value; if (declarators.Count == 1) { if (!removeReturnStatement && returnStatement.GetTrailingTrivia().IsEmptyOrWhitespace()) { SyntaxTriviaList trailingTrivia = localDeclarationStatement.GetTrailingTrivia(); if (trailingTrivia .SkipWhile(f => f.IsWhitespaceTrivia()) .FirstOrDefault() .IsKind(SyntaxKind.SingleLineCommentTrivia)) { newTrailingTrivia = trailingTrivia; } } SyntaxRemoveOptions removeOptions = SyntaxRemover.GetRemoveOptions(localDeclarationStatement); if (newTrailingTrivia.Any()) { removeOptions &= ~SyntaxRemoveOptions.KeepTrailingTrivia; } statementsInfo = statementsInfo.RemoveNode(localDeclarationStatement, removeOptions); statementIndex--; } else { statementsInfo = statementsInfo.ReplaceNode(localDeclarationStatement, localDeclarationStatement.RemoveNode(declarator, SyntaxRemover.GetRemoveOptions(declarator))); } returnStatement = (ReturnStatementSyntax)statementsInfo[statementIndex + 1]; } } } } if (removeReturnStatement) { statementsInfo = statementsInfo.RemoveNode(returnStatement, SyntaxRemover.GetRemoveOptions(returnStatement)); } else if (newReturnExpression != null) { ReturnStatementSyntax newReturnStatement = returnStatement.WithExpression(newReturnExpression.WithTriviaFrom(returnExpression)); if (newTrailingTrivia.Any()) { newReturnStatement = newReturnStatement.WithTrailingTrivia(newTrailingTrivia); } statementsInfo = statementsInfo.ReplaceNode(returnStatement, newReturnStatement); } StatementSyntax oldNode = statementsInfo[statementIndex]; TStatement newNode = createNewStatement((TStatement)oldNode).WithFormatterAnnotation(); return(statementsInfo.ReplaceNode(oldNode, newNode)); }