private static SyntaxList <StatementSyntax> InsertWithinTriviaOfNext( SyntaxList <StatementSyntax> oldStatements, StatementSyntax newStatement, int statementIndex) { var nextStatement = oldStatements.ElementAtOrDefault(statementIndex); if (nextStatement == null) { return(oldStatements.Insert(statementIndex, newStatement)); } // Grab all the trivia before the line the next statement is on and move it to the new node. var nextStatementLeading = nextStatement.GetLeadingTrivia(); var precedingEndOfLine = nextStatementLeading.LastOrDefault(t => t.Kind() == SyntaxKind.EndOfLineTrivia); if (precedingEndOfLine == default) { return(oldStatements.ReplaceRange( nextStatement, new[] { newStatement, nextStatement })); } var endOfLineIndex = nextStatementLeading.IndexOf(precedingEndOfLine) + 1; return(oldStatements.ReplaceRange( nextStatement, new[] { newStatement.WithLeadingTrivia(nextStatementLeading.Take(endOfLineIndex)), nextStatement.WithLeadingTrivia(nextStatementLeading.Skip(endOfLineIndex)), })); }
private static Task <Document> ConvertWhileStatementToForStatementAsync( Document document, WhileStatementSyntax whileStatement, CancellationToken cancellationToken) { StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(whileStatement); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int index = statements.IndexOf(whileStatement); SingleLocalDeclarationStatementInfo localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo((LocalDeclarationStatementSyntax)statements[index - 1]); var block = (BlockSyntax)whileStatement.Statement; var expressionStatement = (ExpressionStatementSyntax)block.Statements.Last(); var postIncrementExpression = (PostfixUnaryExpressionSyntax)expressionStatement.Expression; BlockSyntax newBlock = block.WithStatements(block.Statements.Remove(expressionStatement)); ForStatementSyntax forStatement = CSharpFactory.ForStatement( declaration: localInfo.Declaration.TrimTrivia(), condition: whileStatement.Condition, incrementor: postIncrementExpression.TrimTrivia(), statement: newBlock); forStatement = forStatement .WithLeadingTrivia(localInfo.Statement.GetLeadingTrivia().AddRange(whileStatement.GetLeadingTrivia().EmptyIfWhitespace())) .WithFormatterAnnotation(); SyntaxList <StatementSyntax> newStatements = statements.ReplaceRange(index - 1, 2, new StatementSyntax[] { forStatement }); return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken)); }
private static async Task <Document> SplitAttributesAsync( Document document, MemberDeclarationSyntax member, AttributeListSyntax[] attributeLists, CancellationToken cancellationToken) { SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken); SyntaxList <AttributeListSyntax> lists = member.GetAttributeLists(); int index = lists.IndexOf(attributeLists[attributeLists.Length - 1]); for (int i = attributeLists.Length - 1; i >= 0; i--) { lists = lists.ReplaceRange( lists[index], AttributeRefactoring.SplitAttributes(attributeLists[i]) .Select(f => f.WithAdditionalAnnotations(Formatter.Annotation))); index--; } SyntaxNode newRoot = oldRoot.ReplaceNode(member, member.SetAttributeLists(lists)); return(document.WithSyntaxRoot(newRoot)); }
private static Task <Document> RefactorAsync( Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken) { StatementSyntax newStatement; if (ifStatement.Parent is IfStatementSyntax parentIf) { newStatement = ifStatement.Statement; } else { var parentBlock = (BlockSyntax)ifStatement.Parent; parentIf = (IfStatementSyntax)parentBlock.Parent; SyntaxList <StatementSyntax> statements = parentBlock.Statements; SyntaxList <StatementSyntax> newStatements = (ifStatement.Statement is BlockSyntax block) ? block.Statements : SyntaxFactory.SingletonList(ifStatement.Statement); newStatements = statements.ReplaceRange(ifStatement, newStatements); newStatement = parentBlock.WithStatements(newStatements); } IfStatementSyntax newNode = parentIf .WithStatement(newStatement) .WithCondition(LogicalAndExpression(parentIf.Condition.Parenthesize(), ifStatement.Condition.Parenthesize())) .WithFormatterAnnotation(); return(document.ReplaceNodeAsync(parentIf, newNode, cancellationToken)); }
private static SyntaxList<StatementSyntax> InsertWithinTriviaOfNext( SyntaxList<StatementSyntax> oldStatements, StatementSyntax newStatement, int statementIndex) { var nextStatement = oldStatements.ElementAtOrDefault(statementIndex); return nextStatement == null ? oldStatements.Insert(statementIndex, newStatement) : oldStatements.ReplaceRange(nextStatement, new[] { newStatement.WithLeadingTrivia(nextStatement.GetLeadingTrivia()), nextStatement.WithoutLeadingTrivia() }); }
private static async Task <Document> RefactorAsync( Document document, StatementSyntax statement, CancellationToken cancellationToken) { StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(statement); var methodDeclaration = (MethodDeclarationSyntax)statementsInfo.Parent.Parent; SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); string name = methodDeclaration.Identifier.ValueText; if (!name.EndsWith("Iterator", StringComparison.Ordinal)) { name += "Iterator"; } name = NameGenerator.Default.EnsureUniqueLocalName(name, semanticModel, statement.SpanStart, cancellationToken: cancellationToken); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int index = statements.IndexOf(statement); List <StatementSyntax> localFunctionStatements = statements.Skip(index).ToList(); int lastIndex = localFunctionStatements.Count - 1; localFunctionStatements[lastIndex] = localFunctionStatements[lastIndex].WithoutTrailingTrivia(); LocalFunctionStatementSyntax localFunction = LocalFunctionStatement( default(SyntaxTokenList), methodDeclaration.ReturnType.WithoutTrivia(), Identifier(name).WithRenameAnnotation(), ParameterList(), Block(localFunctionStatements).WithTrailingTrivia(statements.Last().GetTrailingTrivia())); localFunction = localFunction.WithFormatterAnnotation(); ReturnStatementSyntax returnStatement = ReturnStatement( Token(SyntaxKind.ReturnKeyword).WithLeadingTrivia(statement.GetLeadingTrivia()), InvocationExpression(IdentifierName(name)), SemicolonToken()); SyntaxList <StatementSyntax> newStatements = statements.ReplaceRange( index, statements.Count - index, new StatementSyntax[] { returnStatement, localFunction }); return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false)); }
private static async Task <Document> SplitFieldDeclarationAsync( Document document, FieldDeclarationSyntax declaration, CancellationToken cancellationToken) { var containingMember = (MemberDeclarationSyntax)declaration.Parent; SyntaxList <MemberDeclarationSyntax> members = containingMember.GetMembers(); SyntaxList <MemberDeclarationSyntax> newMembers = members.ReplaceRange( declaration, SplitFieldDeclaration(declaration)); MemberDeclarationSyntax newNode = containingMember.SetMembers(newMembers); return(await document.ReplaceNodeAsync(containingMember, newNode, cancellationToken).ConfigureAwait(false)); }
private static Task <Document> SplitEventFieldDeclarationAsync( Document document, EventFieldDeclarationSyntax declaration, CancellationToken cancellationToken) { var containingMember = (TypeDeclarationSyntax)declaration.Parent; SyntaxList <MemberDeclarationSyntax> members = containingMember.Members; SyntaxList <MemberDeclarationSyntax> newMembers = members.ReplaceRange( declaration, SplitEventFieldDeclaration(declaration)); MemberDeclarationSyntax newNode = containingMember.WithMembers(newMembers); return(document.ReplaceNodeAsync(containingMember, newNode, cancellationToken)); }
private void DoTestAddInsertRemoveReplaceOnEmptyList(SyntaxList <SyntaxNode> list) { Assert.Equal(0, list.Count); SyntaxNode nodeD = SyntaxFactory.ParseExpression("D "); SyntaxNode nodeE = SyntaxFactory.ParseExpression("E "); var newList = list.Add(nodeD); Assert.Equal(1, newList.Count); Assert.Equal("D ", newList.ToFullString()); newList = list.AddRange(new[] { nodeD, nodeE }); Assert.Equal(2, newList.Count); Assert.Equal("D E ", newList.ToFullString()); newList = list.Insert(0, nodeD); Assert.Equal(1, newList.Count); Assert.Equal("D ", newList.ToFullString()); newList = list.InsertRange(0, new[] { nodeD, nodeE }); Assert.Equal(2, newList.Count); Assert.Equal("D E ", newList.ToFullString()); newList = list.Remove(nodeD); Assert.Equal(0, newList.Count); Assert.Equal(-1, list.IndexOf(nodeD)); Assert.Throws <ArgumentOutOfRangeException>(() => list.RemoveAt(0)); Assert.Throws <ArgumentOutOfRangeException>(() => list.Insert(1, nodeD)); Assert.Throws <ArgumentOutOfRangeException>(() => list.Insert(-1, nodeD)); Assert.Throws <ArgumentOutOfRangeException>(() => list.InsertRange(1, new[] { nodeD })); Assert.Throws <ArgumentOutOfRangeException>(() => list.InsertRange(-1, new[] { nodeD })); Assert.Throws <ArgumentException>(() => list.Replace(nodeD, nodeE)); Assert.Throws <ArgumentException>(() => list.ReplaceRange(nodeD, new[] { nodeE })); Assert.Throws <ArgumentNullException>(() => list.Add(null)); Assert.Throws <ArgumentNullException>( () => list.AddRange((IEnumerable <SyntaxNode>)null) ); Assert.Throws <ArgumentNullException>(() => list.Insert(0, null)); Assert.Throws <ArgumentNullException>( () => list.InsertRange(0, (IEnumerable <SyntaxNode>)null) ); }
private static Task <Document> RefactorAsync( Document document, SyntaxListSelection <SwitchLabelSyntax> selectedLabels, IComparer <SwitchLabelSyntax> comparer, CancellationToken cancellationToken = default) { SyntaxList <SwitchLabelSyntax> labels = selectedLabels.UnderlyingList; SyntaxList <SwitchLabelSyntax> newLabels = labels.ReplaceRange( selectedLabels.FirstIndex, selectedLabels.Count, selectedLabels.OrderBy(f => f, comparer)); var section = (SwitchSectionSyntax)labels[0].Parent; SwitchSectionSyntax newSection = section.WithLabels(newLabels); return(document.ReplaceNodeAsync(section, newSection, cancellationToken)); }
private static async Task <Document> RefactorAsync( Document document, StatementSyntax statement, CancellationToken cancellationToken) { StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(statement); var methodDeclaration = (MethodDeclarationSyntax)statementsInfo.Parent.Parent; SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); string name = methodDeclaration.Identifier.ValueText; name = NameGenerator.Default.EnsureUniqueLocalName(name, semanticModel, statement.SpanStart, cancellationToken: cancellationToken); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int index = statements.IndexOf(statement); List <StatementSyntax> localFunctionStatements = statements.Skip(index).ToList(); localFunctionStatements[0] = localFunctionStatements[0].TrimLeadingTrivia(); LocalFunctionStatementSyntax localFunction = LocalFunctionStatement( default(SyntaxTokenList), methodDeclaration.ReturnType.WithoutTrivia(), Identifier(name).WithRenameAnnotation(), ParameterList(), Block(localFunctionStatements)); ReturnStatementSyntax returnStatement = ReturnStatement( Token(TriviaList(NewLine()), SyntaxKind.ReturnKeyword, TriviaList()), InvocationExpression(IdentifierName(name)), Token(SyntaxTriviaList.Empty, SyntaxKind.SemicolonToken, TriviaList(NewLine(), NewLine()))); SyntaxList <StatementSyntax> newStatements = statements.ReplaceRange( index, statements.Count - index, new StatementSyntax[] { returnStatement.WithFormatterAnnotation(), localFunction.WithFormatterAnnotation() }); return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false)); }
public override SyntaxList <TNode> VisitList <TNode>(SyntaxList <TNode> list) { list = base.VisitList(list); var index = 0; while (index < list.Count) { var element = list[index]; if (element.HasAnnotation(NodeToReplaceAnnotation)) { list = list.ReplaceRange(element, RemovePlaceHolder(element as XmlElementSyntax).Cast <TNode>()); } else { index++; } } return(list); }
private static async Task <Document> SplitEventFieldDeclarationAsync( Document document, EventFieldDeclarationSyntax declaration, CancellationToken cancellationToken) { SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var containingMember = (MemberDeclarationSyntax)declaration.Parent; SyntaxList <MemberDeclarationSyntax> members = containingMember.GetMembers(); SyntaxList <MemberDeclarationSyntax> newMembers = members.ReplaceRange( declaration, SplitEventFieldDeclaration(declaration)); MemberDeclarationSyntax newNode = containingMember.SetMembers(newMembers); SyntaxNode newRoot = oldRoot.ReplaceNode(containingMember, newNode); return(document.WithSyntaxRoot(newRoot)); }
private static async Task <Document> SplitVariablesIntoMultipleDeclarationsAsync( Document document, FieldDeclarationSyntax declaration, CancellationToken cancellationToken) { SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken); var containingMember = (MemberDeclarationSyntax)declaration.Parent; SyntaxList <MemberDeclarationSyntax> members = containingMember.GetMembers(); SyntaxList <MemberDeclarationSyntax> newMembers = members.ReplaceRange( declaration, CreateFieldDeclarations(declaration)); MemberDeclarationSyntax newNode = containingMember.SetMembers(newMembers); SyntaxNode newRoot = oldRoot.ReplaceNode(containingMember, newNode); return(document.WithSyntaxRoot(newRoot)); }
public override SyntaxList <TNode> VisitList <TNode>(SyntaxList <TNode> list) { if (_originalNode is TNode) { var index = list.IndexOf((TNode)_originalNode); if (index >= 0 && index < list.Count) { switch (_editKind) { case ListEditKind.Replace: return(list.ReplaceRange((TNode)_originalNode, _newNodes.Cast <TNode>())); case ListEditKind.InsertAfter: return(list.InsertRange(index + 1, _newNodes.Cast <TNode>())); case ListEditKind.InsertBefore: return(list.InsertRange(index, _newNodes.Cast <TNode>())); } } } return(base.VisitList <TNode>(list)); }
private SyntaxNode RemoveUnnecessaryParagraphs(XmlElementSyntax originalNode, XmlElementSyntax rewrittenNode) { bool hasUnnecessary = false; SyntaxList <XmlNodeSyntax> content = rewrittenNode.Content; for (int i = 0; i < content.Count; i++) { if (content[i].HasAnnotation(UnnecessaryParagraphAnnotation)) { hasUnnecessary = true; XmlElementSyntax unnecessaryElement = (XmlElementSyntax)content[i]; content = content.ReplaceRange(unnecessaryElement, unnecessaryElement.Content); i += unnecessaryElement.Content.Count; } } if (!hasUnnecessary) { return(rewrittenNode); } return(rewrittenNode.WithContent(content)); }
private static SyntaxList <XmlNodeSyntax> SortElements <TNode>( SeparatedSyntaxList <TNode> nodes, SyntaxList <XmlNodeSyntax> content, int firstIndex, XmlElementKind kind, Func <SeparatedSyntaxList <TNode>, string, int> indexOf) where TNode : SyntaxNode { var xmlNodes = new List <XmlNodeSyntax>(); var ranks = new Dictionary <XmlNodeSyntax, int>(); for (int i = firstIndex; i < content.Count; i++) { XmlElementInfo elementInfo = SyntaxInfo.XmlElementInfo(content[i]); if (elementInfo.Success) { if (elementInfo.IsElementKind(kind)) { XmlNodeSyntax element = elementInfo.Element; string value = (element.IsKind(SyntaxKind.XmlElement)) ? ((XmlElementSyntax)element).GetAttributeValue("name") : ((XmlEmptyElementSyntax)element).GetAttributeValue("name"); if (value != null) { ranks[element] = indexOf(nodes, value); } else { break; } } else { break; } } xmlNodes.Add(content[i]); } for (int i = 0; i < xmlNodes.Count - 1; i++) { for (int j = 0; j < xmlNodes.Count - i - 1; j++) { XmlNodeSyntax node1 = xmlNodes[j]; if (ranks.TryGetValue(node1, out int rank1)) { int k = j + 1; while (k < xmlNodes.Count - i - 1) { XmlNodeSyntax node2 = xmlNodes[k]; if (ranks.TryGetValue(node2, out int rank2)) { if (rank1 > rank2) { xmlNodes[k] = node1; xmlNodes[j] = node2; } break; } k++; } } } } return(content.ReplaceRange(firstIndex, xmlNodes.Count, xmlNodes)); }
public static async Task <Document> InvertIfAsync( Document document, IfStatementSyntax ifStatement, bool recursive = false, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); StatementSyntax statement = ifStatement.Statement; StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(ifStatement); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; InvertIfAnalysis analysis = InvertIfAnalysis.Create(ifStatement, statement); int ifStatementIndex = statements.IndexOf(ifStatement); StatementSyntax lastStatement = analysis.LastStatement; int lastStatementIndex = statements.IndexOf(lastStatement); bool isLastStatementRedundant = IsLastStatementRedundant(); bool shouldUseElseClause = !CSharpFacts.IsJumpStatement(lastStatement.Kind()); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); SyntaxList <StatementSyntax> newStatements = statements; if (!recursive) { Refactor(); } else { IfStatementSyntax lastIfStatement; InvertIfAnalysis a = analysis.AnalyzeNextStatement(); do { lastIfStatement = a.IfStatement; a = a.AnalyzeNextStatement(); } while (a.Success); int firstLastStatementIndex = lastStatementIndex; int index = statements.IndexOf(lastIfStatement); int firstIndex = ifStatementIndex; while (index >= firstIndex) { ifStatementIndex = index; ifStatement = (IfStatementSyntax)statements[ifStatementIndex]; statement = ifStatement.Statement; Refactor(); lastStatementIndex = firstLastStatementIndex + newStatements.Count - statements.Count; lastStatement = (statement is BlockSyntax block) ? block.Statements.Last() : statement; index--; } } return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false)); void Refactor() { cancellationToken.ThrowIfCancellationRequested(); SyntaxList <StatementSyntax> nextStatements = newStatements .Skip(ifStatementIndex + 1) .Take(lastStatementIndex - ifStatementIndex) .ToSyntaxList() .TrimTrivia(); BlockSyntax newStatement; SyntaxList <StatementSyntax> newNextStatements; if (statement is BlockSyntax block) { newStatement = block.WithStatements(nextStatements); newNextStatements = block.Statements; } else { newStatement = Block(nextStatements); newNextStatements = SingletonList(statement); } if (isLastStatementRedundant) { newNextStatements = newNextStatements.RemoveAt(newNextStatements.Count - 1); } ElseClauseSyntax elseClause = null; if (newNextStatements.Any() && shouldUseElseClause) { elseClause = ElseClause(Block(newNextStatements)); newNextStatements = default; } IfStatementSyntax newIfStatement = ifStatement.Update( ifKeyword: ifStatement.IfKeyword, openParenToken: ifStatement.OpenParenToken, condition: SyntaxInverter.LogicallyInvert(ifStatement.Condition, semanticModel, cancellationToken), closeParenToken: ifStatement.CloseParenToken, statement: newStatement, @else: elseClause); newIfStatement = newIfStatement.WithFormatterAnnotation(); SyntaxList <StatementSyntax> newNodes = newNextStatements.Insert(0, newIfStatement); newStatements = newStatements.ReplaceRange(ifStatementIndex, lastStatementIndex - ifStatementIndex + 1, newNodes); } bool IsLastStatementRedundant() { StatementSyntax jumpStatement = analysis.JumpStatement; switch (jumpStatement.Kind()) { case SyntaxKind.ReturnStatement: { if (((ReturnStatementSyntax)jumpStatement).Expression == null && RemoveRedundantStatementAnalysis.IsFixable(lastStatement, SyntaxKind.ReturnStatement)) { return(true); } break; } case SyntaxKind.ContinueStatement: { if (RemoveRedundantStatementAnalysis.IsFixable(lastStatement, SyntaxKind.ContinueStatement)) { return(true); } break; } } return(false); } }