internal static SyntaxToken GetNewEndTokenWithAddedPragma( SyntaxToken endToken, TextSpan currentDiagnosticSpan, Diagnostic diagnostic, AbstractSuppressionCodeFixProvider fixer, Func <SyntaxNode, SyntaxNode> formatNode, bool isRemoveSuppression = false) { ImmutableArray <SyntaxTrivia> trivia; var isEOF = fixer.IsEndOfFileToken(endToken); if (isEOF) { trivia = endToken.LeadingTrivia.ToImmutableArray(); } else { trivia = endToken.TrailingTrivia.ToImmutableArray(); } var index = GetPositionForPragmaInsertion(trivia, currentDiagnosticSpan, fixer, isStartToken: false, triviaAtIndex: out var insertBeforeTrivia); bool needsTrailingEOL; if (index < trivia.Length) { needsTrailingEOL = !IsEndOfLineOrHasLeadingEndOfLine(insertBeforeTrivia, fixer); } else if (isEOF) { needsTrailingEOL = false; } else { needsTrailingEOL = true; } var pragmaTrivia = !isRemoveSuppression ? fixer.CreatePragmaRestoreDirectiveTrivia(diagnostic, formatNode, needsLeadingEndOfLine : true, needsTrailingEndOfLine : needsTrailingEOL) : fixer.CreatePragmaDisableDirectiveTrivia(diagnostic, formatNode, needsLeadingEndOfLine: true, needsTrailingEndOfLine: needsTrailingEOL); if (isEOF) { return(endToken.WithLeadingTrivia(trivia.InsertRange(index, pragmaTrivia))); } else { return(endToken.WithTrailingTrivia(trivia.InsertRange(index, pragmaTrivia))); }; }
internal static void NormalizeTriviaOnTokens(AbstractSuppressionCodeFixProvider fixer, ref Document document, ref SuppressionTargetInfo suppressionTargetInfo) { // For pragma suppression fixes, we need to normalize the leading trivia on start token to account for // the trailing trivia on its previous token (and similarly normalize trailing trivia for end token). var startToken = suppressionTargetInfo.StartToken; var endToken = suppressionTargetInfo.EndToken; var nodeWithTokens = suppressionTargetInfo.NodeWithTokens; var startAndEndTokensAreSame = startToken == endToken; var isEndTokenEOF = fixer.IsEndOfFileToken(endToken); var previousOfStart = startToken.GetPreviousToken(includeZeroWidth: true); var nextOfEnd = !isEndTokenEOF?endToken.GetNextToken(includeZeroWidth : true) : default; if (!previousOfStart.HasTrailingTrivia && !nextOfEnd.HasLeadingTrivia) { return; } var root = nodeWithTokens.SyntaxTree.GetRoot(); var spanEnd = !isEndTokenEOF ? nextOfEnd.FullSpan.End : endToken.FullSpan.End; var subtreeRoot = root.FindNode(new TextSpan(previousOfStart.FullSpan.Start, spanEnd - previousOfStart.FullSpan.Start)); var currentStartToken = startToken; var currentEndToken = endToken; var newStartToken = startToken.WithLeadingTrivia(previousOfStart.TrailingTrivia.Concat(startToken.LeadingTrivia)); SyntaxToken newEndToken = currentEndToken; if (startAndEndTokensAreSame) { newEndToken = newStartToken; } newEndToken = newEndToken.WithTrailingTrivia(endToken.TrailingTrivia.Concat(nextOfEnd.LeadingTrivia)); var newPreviousOfStart = previousOfStart.WithTrailingTrivia(); var newNextOfEnd = nextOfEnd.WithLeadingTrivia(); var newSubtreeRoot = subtreeRoot.ReplaceTokens(new[] { startToken, previousOfStart, endToken, nextOfEnd }, (o, n) => { if (o == currentStartToken) { return(startAndEndTokensAreSame ? newEndToken : newStartToken); } else if (o == previousOfStart) { return(newPreviousOfStart); } else if (o == currentEndToken) { return(newEndToken); } else if (o == nextOfEnd) { return(newNextOfEnd); } else { return(n); } }); root = root.ReplaceNode(subtreeRoot, newSubtreeRoot); document = document.WithSyntaxRoot(root); suppressionTargetInfo.StartToken = root.FindToken(startToken.SpanStart); suppressionTargetInfo.EndToken = root.FindToken(endToken.SpanStart); suppressionTargetInfo.NodeWithTokens = fixer.GetNodeWithTokens(suppressionTargetInfo.StartToken, suppressionTargetInfo.EndToken, root); }
private static SyntaxToken UpdateTriviaList(SyntaxToken token, bool isStartToken, SyntaxTriviaList triviaList, AbstractSuppressionCodeFixProvider fixer) { return(isStartToken || fixer.IsEndOfFileToken(token) ? token.WithLeadingTrivia(triviaList) : token.WithTrailingTrivia(triviaList)); }
private static SyntaxTriviaList GetTriviaListForSuppression(SyntaxToken token, bool isStartToken, AbstractSuppressionCodeFixProvider fixer) { return(isStartToken || fixer.IsEndOfFileToken(token) ? token.LeadingTrivia : token.TrailingTrivia); }