private static SyntaxToken GetNewStartToken(SyntaxToken startToken, Diagnostic diagnostic, AbstractSuppressionCodeFixProvider fixer)
            {
                var trivia = startToken.LeadingTrivia.ToImmutableArray();

                // Insert the #pragma disable directive after all leading new line trivia but before first trivia of any other kind.
                int index;
                SyntaxTrivia firstNonEOLTrivia = trivia.FirstOrDefault(t => !fixer.IsEndOfLine(t));
                if (firstNonEOLTrivia == default(SyntaxTrivia))
                {
                    index = trivia.Length;
                }
                else
                {
                    index = trivia.IndexOf(firstNonEOLTrivia);
                }

                bool needsLeadingEOL;
                if (index > 0)
                {
                    needsLeadingEOL = !fixer.IsEndOfLine(trivia[index - 1]);
                }
                else if (startToken.FullSpan.Start == 0)
                {
                    needsLeadingEOL = false;
                }
                else
                {
                    needsLeadingEOL = true;
                }

                var pragmaWarningTrivia = fixer.CreatePragmaDisableDirectiveTrivia(diagnostic, needsLeadingEOL);

                return startToken.WithLeadingTrivia(trivia.InsertRange(index, pragmaWarningTrivia));
            }
 public static AttributeRemoveAction Create(
     AttributeData attribute,
     Project project,
     Diagnostic diagnostic,
     AbstractSuppressionCodeFixProvider fixer)
 {
     return new AttributeRemoveAction(attribute, project, diagnostic, fixer);
 }
 protected RemoveSuppressionCodeAction(
     Diagnostic diagnostic,
     AbstractSuppressionCodeFixProvider fixer,
     bool forFixMultipleContext = false)
     : base(fixer, title: string.Format(FeaturesResources.Remove_Suppression_0, diagnostic.Id))
 {
     _diagnostic = diagnostic;
     _forFixMultipleContext = forFixMultipleContext;
 }
            public LocalSuppressMessageCodeAction(AbstractSuppressionCodeFixProvider fixer, ISymbol targetSymbol, SyntaxNode targetNode, Document document, Diagnostic diagnostic)
            {
                _fixer = fixer;
                _targetSymbol = targetSymbol;
                _targetNode = targetNode;
                _document = document;
                _diagnostic = diagnostic;

                _title = FeaturesResources.SuppressWithLocalSuppressMessage;
            }
 private PragmaRemoveAction(
     SuppressionTargetInfo suppressionTargetInfo,
     Document document,
     Diagnostic diagnostic,
     AbstractSuppressionCodeFixProvider fixer,
     bool forFixMultipleContext = false)
     : base(document, diagnostic, fixer, forFixMultipleContext)
 {
     _suppressionTargetInfo = suppressionTargetInfo;
 }
 private AttributeRemoveAction(
     AttributeData attribute,
     Project project,
     Diagnostic diagnostic,
     AbstractSuppressionCodeFixProvider fixer,
     bool forFixMultipleContext = false)
     : base(diagnostic, fixer, forFixMultipleContext)
 {
     _project = project;
     _attribute = attribute;
 }
            public static PragmaWarningCodeAction Create(
                SuppressionTargetInfo suppressionTargetInfo,
                Document document,
                Diagnostic diagnostic,
                AbstractSuppressionCodeFixProvider fixer)
            {
                // 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).
                PragmaHelpers.NormalizeTriviaOnTokens(fixer, ref document, ref suppressionTargetInfo);

                return(new PragmaWarningCodeAction(suppressionTargetInfo, document, diagnostic, fixer));
            }
 private GlobalSuppressMessageFixAllCodeAction(
     AbstractSuppressionCodeFixProvider fixer,
     INamedTypeSymbol suppressMessageAttribute,
     IEnumerable <KeyValuePair <ISymbol, ImmutableArray <Diagnostic> > > diagnosticsBySymbol,
     Project project,
     CodeActionOptionsProvider fallbackOptions)
     : base(fixer, project)
 {
     _suppressMessageAttribute = suppressMessageAttribute;
     _diagnosticsBySymbol      = diagnosticsBySymbol;
     _fallbackOptions          = fallbackOptions;
 }
예제 #9
0
 public GlobalSuppressMessageCodeAction(
     ISymbol targetSymbol, INamedTypeSymbol suppressMessageAttribute,
     Project project, Diagnostic diagnostic,
     AbstractSuppressionCodeFixProvider fixer,
     CodeActionOptionsProvider fallbackOptions)
     : base(fixer, project)
 {
     _targetSymbol             = targetSymbol;
     _suppressMessageAttribute = suppressMessageAttribute;
     _diagnostic      = diagnostic;
     _fallbackOptions = fallbackOptions;
 }
            public static PragmaWarningCodeAction Create(
                    SuppressionTargetInfo suppressionTargetInfo,
                    Document document,
                    Diagnostic diagnostic,
                    AbstractSuppressionCodeFixProvider fixer)
            {
                // 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).
                PragmaHelpers.NormalizeTriviaOnTokens(fixer, ref document, ref suppressionTargetInfo);

                return new PragmaWarningCodeAction(suppressionTargetInfo, document, diagnostic, fixer);
            }
 private PragmaWarningCodeAction(
     SuppressionTargetInfo suppressionTargetInfo,
     Document document,
     Diagnostic diagnostic,
     AbstractSuppressionCodeFixProvider fixer,
     bool forFixMultipleContext = false)
     : base(fixer, title: FeaturesResources.in_Source)
 {
     _suppressionTargetInfo = suppressionTargetInfo;
     _document              = document;
     _diagnostic            = diagnostic;
     _forFixMultipleContext = forFixMultipleContext;
 }
 private static bool IsEndOfLineOrHasTrailingEndOfLine(
     SyntaxTrivia trivia,
     AbstractSuppressionCodeFixProvider fixer
     )
 {
     return(fixer.IsEndOfLine(trivia) ||
            (
                trivia.HasStructure &&
                fixer.IsEndOfLine(
                    trivia.GetStructure().DescendantTrivia().LastOrDefault()
                    )
            ));
 }
 protected RemoveSuppressionCodeAction(
     Diagnostic diagnostic,
     AbstractSuppressionCodeFixProvider fixer,
     bool forFixMultipleContext = false
     )
     : base(
         fixer,
         title: string.Format(FeaturesResources.Remove_Suppression_0, diagnostic.Id)
         )
 {
     _diagnostic            = diagnostic;
     _forFixMultipleContext = forFixMultipleContext;
 }
예제 #14
0
 private PragmaRemoveAction(
     SuppressionTargetInfo suppressionTargetInfo,
     Document document,
     SyntaxFormattingOptions options,
     Diagnostic diagnostic,
     AbstractSuppressionCodeFixProvider fixer,
     bool forFixMultipleContext = false)
     : base(diagnostic, fixer, forFixMultipleContext)
 {
     _document = document;
     _options  = options;
     _suppressionTargetInfo = suppressionTargetInfo;
 }
 private PragmaWarningCodeAction(
     SuppressionTargetInfo suppressionTargetInfo,
     Document document,
     Diagnostic diagnostic,
     AbstractSuppressionCodeFixProvider fixer,
     bool forFixMultipleContext = false)
     : base(fixer, title: FeaturesResources.SuppressWithPragma)
 {
     _suppressionTargetInfo = suppressionTargetInfo;
     _document = document;
     _diagnostic = diagnostic;
     _forFixMultipleContext = forFixMultipleContext;
 }
            internal static SyntaxToken GetNewStartTokenWithAddedPragma(
                SyntaxToken startToken,
                TextSpan currentDiagnosticSpan,
                Diagnostic diagnostic,
                AbstractSuppressionCodeFixProvider fixer,
                Func <SyntaxNode, SyntaxNode> formatNode,
                bool isRemoveSuppression = false
                )
            {
                var trivia = startToken.LeadingTrivia.ToImmutableArray();
                var index  = GetPositionForPragmaInsertion(
                    trivia,
                    currentDiagnosticSpan,
                    fixer,
                    isStartToken: true,
                    triviaAtIndex: out var insertAfterTrivia
                    );

                index++;

                bool needsLeadingEOL;

                if (index > 0)
                {
                    needsLeadingEOL = !IsEndOfLineOrHasTrailingEndOfLine(insertAfterTrivia, fixer);
                }
                else if (startToken.FullSpan.Start == 0)
                {
                    needsLeadingEOL = false;
                }
                else
                {
                    needsLeadingEOL = true;
                }

                var pragmaTrivia = !isRemoveSuppression
                    ? fixer.CreatePragmaDisableDirectiveTrivia(
                    diagnostic,
                    formatNode,
                    needsLeadingEOL,
                    needsTrailingEndOfLine : true
                    )
                    : fixer.CreatePragmaRestoreDirectiveTrivia(
                    diagnostic,
                    formatNode,
                    needsLeadingEOL,
                    needsTrailingEndOfLine: true
                    );

                return(startToken.WithLeadingTrivia(trivia.InsertRange(index, pragmaTrivia)));
            }
예제 #17
0
            internal static async Task <SyntaxToken> GetNewEndTokenWithAddedPragmaAsync(
                SyntaxToken endToken,
                TextSpan currentDiagnosticSpan,
                Diagnostic diagnostic,
                AbstractSuppressionCodeFixProvider fixer,
                Func <SyntaxNode, Task <SyntaxNode> > formatNode,
                bool isRemoveSuppression = false)
            {
                ImmutableArray <SyntaxTrivia> trivia;
                var isEOF = fixer.IsEndOfFileToken(endToken);

                if (isEOF)
                {
                    trivia = endToken.LeadingTrivia.ToImmutableArray();
                }
                else
                {
                    trivia = endToken.TrailingTrivia.ToImmutableArray();
                }

                SyntaxTrivia insertBeforeTrivia;
                var          index = GetPositionForPragmaInsertion(trivia, currentDiagnosticSpan, fixer, isStartToken: false, triviaAtIndex: out insertBeforeTrivia);

                bool needsTrailingEOL;

                if (index < trivia.Length)
                {
                    needsTrailingEOL = !IsEndOfLineOrHasLeadingEndOfLine(insertBeforeTrivia, fixer);
                }
                else if (isEOF)
                {
                    needsTrailingEOL = false;
                }
                else
                {
                    needsTrailingEOL = true;
                }

                var pragmaTrivia = !isRemoveSuppression
                    ? await fixer.CreatePragmaRestoreDirectiveTriviaAsync(diagnostic, formatNode, needsLeadingEndOfLine : true, needsTrailingEndOfLine : needsTrailingEOL).ConfigureAwait(false)
                    : await fixer.CreatePragmaDisableDirectiveTriviaAsync(diagnostic, formatNode, needsLeadingEndOfLine : true, needsTrailingEndOfLine : needsTrailingEOL).ConfigureAwait(false);

                if (isEOF)
                {
                    return(endToken.WithLeadingTrivia(trivia.InsertRange(index, pragmaTrivia)));
                }
                else
                {
                    return(endToken.WithTrailingTrivia(trivia.InsertRange(index, pragmaTrivia)));
                };
            }
 internal static CodeAction Create(
     string title,
     AbstractSuppressionCodeFixProvider fixer,
     Project triggerProject,
     ImmutableDictionary <Project, ImmutableArray <Diagnostic> > diagnosticsByProject
     )
 {
     return(new GlobalSuppressionSolutionChangeAction(
                title,
                ct =>
                CreateChangedSolutionAsync(fixer, triggerProject, diagnosticsByProject, ct),
                equivalenceKey: title
                ));
 }
 public static CodeAction CreateBatchPragmaFix(
     AbstractSuppressionCodeFixProvider suppressionFixProvider,
     Document document,
     ImmutableArray <IPragmaBasedCodeAction> pragmaActions,
     ImmutableArray <Diagnostic> pragmaDiagnostics,
     FixAllState fixAllState,
     CancellationToken cancellationToken)
 {
     return(CodeAction.Create(
                ((CodeAction)pragmaActions[0]).Title,
                createChangedDocument: ct =>
                BatchPragmaFixesAsync(suppressionFixProvider, document, pragmaActions, pragmaDiagnostics, fixAllState.CodeActionOptionsProvider, cancellationToken),
                equivalenceKey: fixAllState.CodeActionEquivalenceKey));
 }
 public PragmaWarningCodeAction(
     AbstractSuppressionCodeFixProvider fixer,
     SyntaxToken startToken,
     SyntaxToken endToken,
     SyntaxNode nodeWithTokens,
     Document document,
     Diagnostic diagnostic)
     : base (fixer, title: FeaturesResources.SuppressWithPragma)
 {
     _startToken = startToken;
     _endToken = endToken;
     _nodeWithTokens = nodeWithTokens;
     _document = document;
     _diagnostic = diagnostic;
 }
예제 #21
0
 public PragmaWarningCodeAction(
     AbstractSuppressionCodeFixProvider fixer,
     SyntaxToken startToken,
     SyntaxToken endToken,
     SyntaxNode nodeWithTokens,
     Document document,
     Diagnostic diagnostic)
     : base(fixer, title: FeaturesResources.SuppressWithPragma)
 {
     _startToken     = startToken;
     _endToken       = endToken;
     _nodeWithTokens = nodeWithTokens;
     _document       = document;
     _diagnostic     = diagnostic;
 }
예제 #22
0
 public LocalSuppressMessageCodeAction(
     AbstractSuppressionCodeFixProvider fixer,
     ISymbol targetSymbol,
     INamedTypeSymbol suppressMessageAttribute,
     SyntaxNode targetNode,
     Document document,
     Diagnostic diagnostic)
     : base(fixer, FeaturesResources.in_Source_attribute)
 {
     _fixer                    = fixer;
     _targetSymbol             = targetSymbol;
     _suppressMessageAttribute = suppressMessageAttribute;
     _targetNode               = targetNode;
     _document                 = document;
     _diagnostic               = diagnostic;
 }
            public static CodeAction CreateBatchPragmaFix(
                AbstractSuppressionCodeFixProvider suppressionFixProvider,
                Document document,
                ImmutableArray<IPragmaBasedCodeAction> pragmaActions,
                ImmutableArray<Diagnostic> pragmaDiagnostics,
                FixAllContext fixAllContext)
            {
                // This is a temporary generated code action, which doesn't need telemetry, hence suppressing RS0005.
#pragma warning disable RS0005 // Do not use generic CodeAction.Create to create CodeAction
                return CodeAction.Create(
                    ((CodeAction)pragmaActions[0]).Title,
                    createChangedDocument: ct =>
                        BatchPragmaFixesAsync(suppressionFixProvider, document, pragmaActions, pragmaDiagnostics, fixAllContext.CancellationToken),
                    equivalenceKey: fixAllContext.CodeActionEquivalenceKey);
#pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction
            }
            private static async Task <Solution> CreateChangedSolutionAsync(
                AbstractSuppressionCodeFixProvider fixer,
                Document triggerDocument,
                ImmutableDictionary <Document, ImmutableArray <Diagnostic> > diagnosticsByDocument,
                CancellationToken cancellationToken
                )
            {
                var currentSolution = triggerDocument.Project.Solution;

                foreach (var grouping in diagnosticsByDocument.GroupBy(d => d.Key.Project))
                {
                    var oldProject     = grouping.Key;
                    var currentProject = currentSolution.GetProject(oldProject.Id);
                    var compilation    = await currentProject
                                         .GetCompilationAsync(cancellationToken)
                                         .ConfigureAwait(false);

                    var supressMessageAttribute = compilation.SuppressMessageAttributeType();

                    if (supressMessageAttribute != null)
                    {
                        var diagnosticsBySymbol = await CreateDiagnosticsBySymbolAsync(
                            fixer,
                            grouping,
                            cancellationToken
                            )
                                                  .ConfigureAwait(false);

                        if (diagnosticsBySymbol.Any())
                        {
                            var projectCodeAction = new GlobalSuppressMessageFixAllCodeAction(
                                fixer,
                                supressMessageAttribute,
                                diagnosticsBySymbol,
                                currentProject
                                );
                            var newDocument = await projectCodeAction
                                              .GetChangedSuppressionDocumentAsync(cancellationToken)
                                              .ConfigureAwait(false);

                            currentSolution = newDocument.Project.Solution;
                        }
                    }
                }

                return(currentSolution);
            }
예제 #25
0
            public PragmaWarningCodeAction(
                AbstractSuppressionCodeFixProvider fixer,
                SyntaxToken startToken,
                SyntaxToken endToken,
                SyntaxNode nodeWithTokens,
                Document document,
                Diagnostic diagnostic)
            {
                _fixer          = fixer;
                _startToken     = startToken;
                _endToken       = endToken;
                _nodeWithTokens = nodeWithTokens;
                _document       = document;
                _diagnostic     = diagnostic;

                _title = fixer.TitleForPragmaWarningSuppressionFix;
            }
            public PragmaWarningCodeAction(
                AbstractSuppressionCodeFixProvider fixer,
                SyntaxToken startToken,
                SyntaxToken endToken,
                SyntaxNode nodeWithTokens,
                Document document,
                Diagnostic diagnostic)
            {
                _fixer = fixer;
                _startToken = startToken;
                _endToken = endToken;
                _nodeWithTokens = nodeWithTokens;
                _document = document;
                _diagnostic = diagnostic;

                _title = fixer.TitleForPragmaWarningSuppressionFix;
            }
            public static CodeAction CreateBatchPragmaFix(
                AbstractSuppressionCodeFixProvider suppressionFixProvider,
                Document document,
                ImmutableArray <IPragmaBasedCodeAction> pragmaActions,
                ImmutableArray <Diagnostic> pragmaDiagnostics,
                FixAllContext fixAllContext)
            {
                // This is a temporary generated code action, which doesn't need telemetry, hence suppressing RS0005.
#pragma warning disable RS0005 // Do not use generic CodeAction.Create to create CodeAction
                return(CodeAction.Create(
                           ((CodeAction)pragmaActions[0]).Title,
                           createChangedDocument: ct =>
                           BatchPragmaFixesAsync(suppressionFixProvider, document, pragmaActions, pragmaDiagnostics, fixAllContext.CancellationToken),
                           equivalenceKey: fixAllContext.CodeActionEquivalenceKey));

#pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction
            }
 public static async Task<RemoveSuppressionCodeAction> CreateAsync(                
     SuppressionTargetInfo suppressionTargetInfo,
     Document document,
     Diagnostic diagnostic,
     AbstractSuppressionCodeFixProvider fixer,
     CancellationToken cancellationToken)
 {
     var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
     var attribute = diagnostic.GetSuppressionInfo(compilation).Attribute;
     if (attribute != null)
     {
         return AttributeRemoveAction.Create(attribute, document, diagnostic, fixer);
     }
     else
     {
         return PragmaRemoveAction.Create(suppressionTargetInfo, document, diagnostic, fixer);
     }
 }
            private static async Task<Solution> CreateChangedSolutionAsync(AbstractSuppressionCodeFixProvider fixer, Project triggerProject, ImmutableDictionary<Project, ImmutableArray<Diagnostic>> diagnosticsByProject, CancellationToken cancellationToken)
            {
                var currentSolution = triggerProject.Solution;
                foreach (var kvp in diagnosticsByProject)
                {
                    var oldProject = kvp.Key;
                    var currentProject = currentSolution.GetProject(oldProject.Id);
                    var diagnosticsBySymbol = await CreateDiagnosticsBySymbolAsync(fixer, oldProject, kvp.Value, cancellationToken).ConfigureAwait(false);
                    if (diagnosticsBySymbol.Any())
                    {
                        var projectCodeAction = new GlobalSuppressMessageFixAllCodeAction(fixer, diagnosticsBySymbol, currentProject);
                        var newDocument = await projectCodeAction.GetChangedSuppressionDocumentAsync(cancellationToken).ConfigureAwait(false);
                        currentSolution = newDocument.Project.Solution;
                    }
                }

                return currentSolution;
            }
            private static int GetPositionForPragmaInsertion(
                ImmutableArray <SyntaxTrivia> triviaList,
                TextSpan currentDiagnosticSpan,
                AbstractSuppressionCodeFixProvider fixer,
                bool isStartToken,
                out SyntaxTrivia triviaAtIndex
                )
            {
                // Start token: Insert the #pragma disable directive just **before** the first end of line trivia prior to diagnostic location.
                // End token: Insert the #pragma disable directive just **after** the first end of line trivia after diagnostic location.

                int getNextIndex(int cur) => isStartToken ? cur - 1 : cur + 1;
                bool shouldConsiderTrivia(SyntaxTrivia trivia) =>
                isStartToken
                        ? trivia.FullSpan.End <= currentDiagnosticSpan.Start
                        : trivia.FullSpan.Start >= currentDiagnosticSpan.End;

                var walkedPastDiagnosticSpan = false;
                var seenEndOfLineTrivia      = false;
                var index = isStartToken ? triviaList.Length - 1 : 0;

                while (index >= 0 && index < triviaList.Length)
                {
                    var trivia = triviaList[index];

                    walkedPastDiagnosticSpan =
                        walkedPastDiagnosticSpan || shouldConsiderTrivia(trivia);
                    seenEndOfLineTrivia =
                        seenEndOfLineTrivia || IsEndOfLineOrContainsEndOfLine(trivia, fixer);

                    if (walkedPastDiagnosticSpan && seenEndOfLineTrivia)
                    {
                        break;
                    }

                    index = getNextIndex(index);
                }

                triviaAtIndex =
                    index >= 0 && index < triviaList.Length ? triviaList[index] : default;

                return(index);
            }
                > CreateDiagnosticsBySymbolAsync(
                AbstractSuppressionCodeFixProvider fixer,
                IEnumerable <
                    KeyValuePair <Document, ImmutableArray <Diagnostic> >
                    > diagnosticsByDocument,
                CancellationToken cancellationToken
                )
            {
                var diagnosticsMapBuilder = ImmutableDictionary.CreateBuilder <
                    ISymbol,
                    List <Diagnostic>
                    >();

                foreach (var(document, diagnostics) in diagnosticsByDocument)
                {
                    foreach (var diagnostic in diagnostics)
                    {
                        Contract.ThrowIfFalse(diagnostic.Location.IsInSource);
                        var suppressionTargetInfo = await fixer
                                                    .GetSuppressionTargetInfoAsync(
                            document,
                            diagnostic.Location.SourceSpan,
                            cancellationToken
                            )
                                                    .ConfigureAwait(false);

                        if (suppressionTargetInfo != null)
                        {
                            var targetSymbol = suppressionTargetInfo.TargetSymbol;
                            Contract.ThrowIfNull(targetSymbol);
                            AddDiagnosticForSymbolIfNeeded(
                                targetSymbol,
                                diagnostic,
                                diagnosticsMapBuilder
                                );
                        }
                    }
                }

                return(CreateDiagnosticsBySymbol(diagnosticsMapBuilder));
            }
            private static async Task <Solution> CreateChangedSolutionAsync(AbstractSuppressionCodeFixProvider fixer, Project triggerProject, ImmutableDictionary <Project, ImmutableArray <Diagnostic> > diagnosticsByProject, CancellationToken cancellationToken)
            {
                var currentSolution = triggerProject.Solution;

                foreach (var kvp in diagnosticsByProject)
                {
                    var oldProject          = kvp.Key;
                    var currentProject      = currentSolution.GetProject(oldProject.Id);
                    var diagnosticsBySymbol = await CreateDiagnosticsBySymbolAsync(fixer, oldProject, kvp.Value, cancellationToken).ConfigureAwait(false);

                    if (diagnosticsBySymbol.Any())
                    {
                        var projectCodeAction = new GlobalSuppressMessageFixAllCodeAction(fixer, diagnosticsBySymbol, currentProject);
                        var newDocument       = await projectCodeAction.GetChangedSuppressionDocumentAsync(cancellationToken).ConfigureAwait(false);

                        currentSolution = newDocument.Project.Solution;
                    }
                }

                return(currentSolution);
            }
            private static async Task<IEnumerable<KeyValuePair<ISymbol, ImmutableArray<Diagnostic>>>> CreateDiagnosticsBySymbolAsync(AbstractSuppressionCodeFixProvider fixer, IEnumerable<KeyValuePair<Document, ImmutableArray<Diagnostic>>> diagnosticsByDocument, CancellationToken cancellationToken)
            {
                var diagnosticsMapBuilder = ImmutableDictionary.CreateBuilder<ISymbol, List<Diagnostic>>();
                foreach (var kvp in diagnosticsByDocument)
                {
                    var document = kvp.Key;
                    var diagnostics = kvp.Value;
                    foreach (var diagnostic in diagnostics)
                    {
                        Contract.ThrowIfFalse(diagnostic.Location.IsInSource);
                        var suppressionTargetInfo = await fixer.GetSuppressionTargetInfoAsync(document, diagnostic.Location.SourceSpan, cancellationToken).ConfigureAwait(false);
                        if (suppressionTargetInfo != null)
                        {
                            var targetSymbol = suppressionTargetInfo.TargetSymbol;
                            Contract.ThrowIfNull(targetSymbol);
                            AddDiagnosticForSymbolIfNeeded(targetSymbol, diagnostic, diagnosticsMapBuilder);
                        }
                    }
                }

                return CreateDiagnosticsBySymbol(diagnosticsMapBuilder);
            }
            private static int GetPositionForPragmaInsertion(ImmutableArray<SyntaxTrivia> triviaList, TextSpan currentDiagnosticSpan, AbstractSuppressionCodeFixProvider fixer, bool isStartToken, out SyntaxTrivia triviaAtIndex)
            {
                // Start token: Insert the #pragma disable directive just **before** the first end of line trivia prior to diagnostic location.
                // End token: Insert the #pragma disable directive just **after** the first end of line trivia after diagnostic location.

                Func<int, int> getNextIndex = cur => isStartToken ? cur - 1 : cur + 1;
                Func<SyntaxTrivia, bool> shouldConsiderTrivia = trivia =>
                    isStartToken ?
                    trivia.FullSpan.End <= currentDiagnosticSpan.Start :
                    trivia.FullSpan.Start >= currentDiagnosticSpan.End;

                var walkedPastDiagnosticSpan = false;
                var seenEndOfLineTrivia = false;
                var index = isStartToken ? triviaList.Length - 1 : 0;
                while (index >= 0 && index < triviaList.Length)
                {
                    var trivia = triviaList[index];

                    walkedPastDiagnosticSpan = walkedPastDiagnosticSpan || shouldConsiderTrivia(trivia);
                    seenEndOfLineTrivia = seenEndOfLineTrivia ||
                        (fixer.IsEndOfLine(trivia) || 
                         (trivia.HasStructure &&
                          trivia.GetStructure().DescendantTrivia().Any(t => fixer.IsEndOfLine(t))));

                    if (walkedPastDiagnosticSpan && seenEndOfLineTrivia)
                    {
                        break;
                    }

                    index = getNextIndex(index);
                }

                triviaAtIndex = index >= 0 && index < triviaList.Length ?
                    triviaList[index] :
                    default(SyntaxTrivia);

                return index;
            }
 public static async Task<RemoveSuppressionCodeAction> CreateAsync(
     SuppressionTargetInfo suppressionTargetInfo,
     Document documentOpt,
     Project project,
     Diagnostic diagnostic,
     AbstractSuppressionCodeFixProvider fixer,
     CancellationToken cancellationToken)
 {
     var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
     var attribute = diagnostic.GetSuppressionInfo(compilation).Attribute;
     if (attribute != null)
     {
         return AttributeRemoveAction.Create(attribute, project, diagnostic, fixer);
     }
     else if (documentOpt != null && !SuppressionHelpers.IsSynthesizedExternalSourceDiagnostic(diagnostic))
     {
         return PragmaRemoveAction.Create(suppressionTargetInfo, documentOpt, diagnostic, fixer);
     }
     else
     {
         return null;
     }
 }
 public static async Task<RemoveSuppressionCodeAction> CreateAsync(
     SuppressionTargetInfo suppressionTargetInfo,
     Document documentOpt,
     Project project,
     Diagnostic diagnostic,
     AbstractSuppressionCodeFixProvider fixer,
     CancellationToken cancellationToken)
 {
     var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
     var attribute = diagnostic.GetSuppressionInfo(compilation).Attribute;
     if (attribute != null)
     {
         return AttributeRemoveAction.Create(attribute, project, diagnostic, fixer);
     }
     else if (documentOpt != null && !SuppressionHelpers.IsSynthesizedExternalSourceDiagnostic(diagnostic))
     {
         return PragmaRemoveAction.Create(suppressionTargetInfo, documentOpt, diagnostic, fixer);
     }
     else
     {
         return null;
     }
 }
예제 #37
0
 public static BatchFixAllProvider GetBatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider)
 {
     return(new BatchFixer(suppressionFixProvider));
 }
 public PragmaWarningBatchFixAllProvider(AbstractSuppressionCodeFixProvider suppressionFixProvider)
 {
     _suppressionFixProvider = suppressionFixProvider;
 }
            internal static async Task<SyntaxToken> GetNewStartTokenWithAddedPragmaAsync(
                SyntaxToken startToken,
                TextSpan currentDiagnosticSpan,
                Diagnostic diagnostic,
                AbstractSuppressionCodeFixProvider fixer,
                Func<SyntaxNode, Task<SyntaxNode>> formatNode,
                bool isRemoveSuppression = false)
            {
                var trivia = startToken.LeadingTrivia.ToImmutableArray();
                SyntaxTrivia insertAfterTrivia;
                var index = GetPositionForPragmaInsertion(trivia, currentDiagnosticSpan, fixer, isStartToken: true, triviaAtIndex: out insertAfterTrivia);
                index++;

                bool needsLeadingEOL;
                if (index > 0)
                {
                    needsLeadingEOL = !IsEndOfLineOrHasTrailingEndOfLine(insertAfterTrivia, fixer);
                }
                else if (startToken.FullSpan.Start == 0)
                {
                    needsLeadingEOL = false;
                }
                else
                {
                    needsLeadingEOL = true;
                }

                var pragmaTrivia = !isRemoveSuppression
                    ? await fixer.CreatePragmaDisableDirectiveTriviaAsync(diagnostic, formatNode, needsLeadingEOL, needsTrailingEndOfLine: true).ConfigureAwait(false)
                    : await fixer.CreatePragmaRestoreDirectiveTriviaAsync(diagnostic, formatNode, needsLeadingEOL, needsTrailingEndOfLine: true).ConfigureAwait(false);

                return startToken.WithLeadingTrivia(trivia.InsertRange(index, pragmaTrivia));
            }
예제 #40
0
 private static SyntaxTriviaList GetTriviaListForSuppression(SyntaxToken token, bool isStartToken, AbstractSuppressionCodeFixProvider fixer)
 {
     return(isStartToken || fixer.IsEndOfFileToken(token) ?
            token.LeadingTrivia :
            token.TrailingTrivia);
 }
 private GlobalSuppressMessageFixAllCodeAction(AbstractSuppressionCodeFixProvider fixer, IEnumerable <KeyValuePair <ISymbol, ImmutableArray <Diagnostic> > > diagnosticsBySymbol, Project project)
     : base(fixer, project)
 {
     _diagnosticsBySymbol = diagnosticsBySymbol;
 }
예제 #42
0
            private static async Task <Document> BatchPragmaFixesAsync(
                AbstractSuppressionCodeFixProvider suppressionFixProvider,
                Document document,
                ImmutableArray <IPragmaBasedCodeAction> pragmaActions,
                ImmutableArray <Diagnostic> diagnostics,
                CancellationToken cancellationToken)
            {
                // We apply all the pragma suppression fixes sequentially.
                // At every application, we track the updated locations for remaining diagnostics in the document.
                var currentDiagnosticSpans = new Dictionary <Diagnostic, TextSpan>();

                foreach (var diagnostic in diagnostics)
                {
                    currentDiagnosticSpans.Add(diagnostic, diagnostic.Location.SourceSpan);
                }

                var currentDocument = document;

                for (int i = 0; i < pragmaActions.Length; i++)
                {
                    var originalpragmaAction = pragmaActions[i];
                    var diagnostic           = diagnostics[i];

                    // Get the diagnostic span for the diagnostic in latest document snapshot.
                    TextSpan currentDiagnosticSpan;
                    if (!currentDiagnosticSpans.TryGetValue(diagnostic, out currentDiagnosticSpan))
                    {
                        // Diagnostic whose location conflicts with a prior fix.
                        continue;
                    }

                    // Compute and apply pragma suppression fix.
                    var currentTree = await currentDocument.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

                    var currentLocation = Location.Create(currentTree, currentDiagnosticSpan);
                    diagnostic = Diagnostic.Create(
                        id: diagnostic.Id,
                        category: diagnostic.Descriptor.Category,
                        message: diagnostic.GetMessage(),
                        severity: diagnostic.Severity,
                        defaultSeverity: diagnostic.DefaultSeverity,
                        isEnabledByDefault: diagnostic.Descriptor.IsEnabledByDefault,
                        warningLevel: diagnostic.WarningLevel,
                        title: diagnostic.Descriptor.Title,
                        description: diagnostic.Descriptor.Description,
                        helpLink: diagnostic.Descriptor.HelpLinkUri,
                        location: currentLocation,
                        additionalLocations: diagnostic.AdditionalLocations,
                        customTags: diagnostic.Descriptor.CustomTags,
                        properties: diagnostic.Properties,
                        isSuppressed: diagnostic.IsSuppressed);

                    var newSuppressionFixes = await suppressionFixProvider.GetSuppressionsAsync(currentDocument, currentDiagnosticSpan, SpecializedCollections.SingletonEnumerable(diagnostic), cancellationToken).ConfigureAwait(false);

                    var newSuppressionFix = newSuppressionFixes.SingleOrDefault();
                    if (newSuppressionFix != null)
                    {
                        var newPragmaAction = newSuppressionFix.Action as IPragmaBasedCodeAction ??
                                              newSuppressionFix.Action.NestedCodeActions.OfType <IPragmaBasedCodeAction>().SingleOrDefault();
                        if (newPragmaAction != null)
                        {
                            // Get the text changes with pragma suppression add/removals.
                            // Note: We do it one token at a time to ensure we get single text change in the new document, otherwise UpdateDiagnosticSpans won't function as expected.
                            // Update the diagnostics spans based on the text changes.
                            var startTokenChanges = await GetTextChangesAsync(newPragmaAction, currentDocument, diagnostics, currentDiagnosticSpans,
                                                                              includeStartTokenChange : true, includeEndTokenChange : false, cancellationToken : cancellationToken).ConfigureAwait(false);

                            var endTokenChanges = await GetTextChangesAsync(newPragmaAction, currentDocument, diagnostics, currentDiagnosticSpans,
                                                                            includeStartTokenChange : false, includeEndTokenChange : true, cancellationToken : cancellationToken).ConfigureAwait(false);

                            var currentText = await currentDocument.GetTextAsync(cancellationToken).ConfigureAwait(false);

                            var orderedChanges = startTokenChanges.Concat(endTokenChanges).OrderBy(change => change.Span).Distinct();
                            var newText        = currentText.WithChanges(orderedChanges);
                            currentDocument = currentDocument.WithText(newText);

                            // Update the diagnostics spans based on the text changes.
                            UpdateDiagnosticSpans(diagnostics, currentDiagnosticSpans, orderedChanges);
                        }
                    }
                }

                return(currentDocument);
            }
                private static bool CanRemovePragmaTrivia(SyntaxToken token, Diagnostic diagnostic, AbstractSuppressionCodeFixProvider fixer, bool isStartToken, out int indexOfTriviaToRemove)
                {
                    indexOfTriviaToRemove = -1;

                    var triviaList = GetTriviaListForSuppression(token, isStartToken, fixer);

                    var diagnosticSpan = diagnostic.Location.SourceSpan;
                    Func<SyntaxTrivia, bool> shouldIncludeTrivia = t => isStartToken ? t.FullSpan.End <= diagnosticSpan.Start : t.FullSpan.Start >= diagnosticSpan.End;
                    var filteredTriviaList = triviaList.Where(shouldIncludeTrivia);
                    if (isStartToken)
                    {
                        // Walk bottom up for leading trivia.
                        filteredTriviaList = filteredTriviaList.Reverse();
                    }

                    foreach (var trivia in filteredTriviaList)
                    {
                        bool isEnableDirective, hasMultipleIds;
                        if (fixer.IsAnyPragmaDirectiveForId(trivia, diagnostic.Id, out isEnableDirective, out hasMultipleIds))
                        {
                            if (hasMultipleIds)
                            {
                                // Handle only simple cases where we have a single pragma directive with single ID matching ours in the trivia.
                                return false;
                            }

                            // We want to look for leading disable directive and trailing enable directive.
                            if ((isStartToken && !isEnableDirective) ||
                                (!isStartToken && isEnableDirective))
                            {
                                indexOfTriviaToRemove = triviaList.IndexOf(trivia);
                                return true;
                            }

                            return false;
                        }
                    }

                    return false;
                }
            private static async Task<Document> BatchPragmaFixesAsync(
                AbstractSuppressionCodeFixProvider suppressionFixProvider,
                Document document,
                ImmutableArray<IPragmaBasedCodeAction> pragmaActions,
                ImmutableArray<Diagnostic> diagnostics,
                CancellationToken cancellationToken)
            {
                // We apply all the pragma suppression fixes sequentially.
                // At every application, we track the updated locations for remaining diagnostics in the document.
                var currentDiagnosticSpans = new Dictionary<Diagnostic, TextSpan>();
                foreach (var diagnostic in diagnostics)
                {
                    currentDiagnosticSpans.Add(diagnostic, diagnostic.Location.SourceSpan);
                }

                var currentDocument = document;
                for (int i = 0; i < pragmaActions.Length; i++)
                {
                    var originalpragmaAction = pragmaActions[i];
                    var diagnostic = diagnostics[i];

                    // Get the diagnostic span for the diagnostic in latest document snapshot.
                    TextSpan currentDiagnosticSpan;
                    if (!currentDiagnosticSpans.TryGetValue(diagnostic, out currentDiagnosticSpan))
                    {
                        // Diagnostic whose location conflicts with a prior fix.
                        continue;
                    }

                    // Compute and apply pragma suppression fix.
                    var currentTree = await currentDocument.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
                    var currentLocation = Location.Create(currentTree, currentDiagnosticSpan);
                    diagnostic = Diagnostic.Create(
                        id: diagnostic.Id,
                        category: diagnostic.Descriptor.Category,
                        message: diagnostic.GetMessage(),
                        severity: diagnostic.Severity,
                        defaultSeverity: diagnostic.DefaultSeverity,
                        isEnabledByDefault: diagnostic.Descriptor.IsEnabledByDefault,
                        warningLevel: diagnostic.WarningLevel,
                        title: diagnostic.Descriptor.Title,
                        description: diagnostic.Descriptor.Description,
                        helpLink: diagnostic.Descriptor.HelpLinkUri,
                        location: currentLocation,
                        additionalLocations: diagnostic.AdditionalLocations,
                        customTags: diagnostic.Descriptor.CustomTags,
                        properties: diagnostic.Properties,
                        isSuppressed: diagnostic.IsSuppressed);

                    var newSuppressionFixes = await suppressionFixProvider.GetSuppressionsAsync(currentDocument, currentDiagnosticSpan, SpecializedCollections.SingletonEnumerable(diagnostic), cancellationToken).ConfigureAwait(false);
                    var newSuppressionFix = newSuppressionFixes.SingleOrDefault();
                    if (newSuppressionFix != null)
                    {
                        var newPragmaAction = newSuppressionFix.Action as IPragmaBasedCodeAction ??
                            newSuppressionFix.Action.GetCodeActions().OfType<IPragmaBasedCodeAction>().SingleOrDefault();
                        if (newPragmaAction != null)
                        {
                            // Get the text changes with pragma suppression add/removals.
                            // Note: We do it one token at a time to ensure we get single text change in the new document, otherwise UpdateDiagnosticSpans won't function as expected.
                            // Update the diagnostics spans based on the text changes.
                            var startTokenChanges = await GetTextChangesAsync(newPragmaAction, currentDocument, diagnostics, currentDiagnosticSpans,
                                includeStartTokenChange: true, includeEndTokenChange: false, cancellationToken: cancellationToken).ConfigureAwait(false);

                            var endTokenChanges = await GetTextChangesAsync(newPragmaAction, currentDocument, diagnostics, currentDiagnosticSpans,
                                includeStartTokenChange: false, includeEndTokenChange: true, cancellationToken: cancellationToken).ConfigureAwait(false);

                            var currentText = await currentDocument.GetTextAsync(cancellationToken).ConfigureAwait(false);
                            var orderedChanges = startTokenChanges.Concat(endTokenChanges).OrderBy(change => change.Span).Distinct();
                            var newText = currentText.WithChanges(orderedChanges);
                            currentDocument = currentDocument.WithText(newText);

                            // Update the diagnostics spans based on the text changes.
                            UpdateDiagnosticSpans(diagnostics, currentDiagnosticSpans, orderedChanges);
                        }
                    }
                }

                return currentDocument;
            }
 private static SyntaxTriviaList GetTriviaListForSuppression(SyntaxToken token, bool isStartToken, AbstractSuppressionCodeFixProvider fixer)
 {
     return isStartToken || fixer.IsEndOfFileToken(token) ?
         token.LeadingTrivia :
         token.TrailingTrivia;
 }
 public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider)
 {
     _suppressionFixProvider = suppressionFixProvider;
 }
 public static BatchFixAllProvider GetBatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider)
 {
     return new BatchFixer(suppressionFixProvider);
 }
                private static SyntaxToken GetNewTokenWithPragmaUnsuppress(SyntaxToken token, int indexOfTriviaToRemoveOrToggle, Diagnostic diagnostic, AbstractSuppressionCodeFixProvider fixer, bool isStartToken, bool toggle)
                {
                    Contract.ThrowIfFalse(indexOfTriviaToRemoveOrToggle >= 0);

                    var triviaList = GetTriviaListForSuppression(token, isStartToken, fixer);

                    if (toggle)
                    {
                        var triviaToToggle = triviaList.ElementAt(indexOfTriviaToRemoveOrToggle);
                        Contract.ThrowIfFalse(triviaToToggle != default(SyntaxTrivia));
                        var toggledTrivia = fixer.TogglePragmaDirective(triviaToToggle);
                        triviaList = triviaList.Replace(triviaToToggle, toggledTrivia);
                    }
                    else
                    {
                        triviaList = triviaList.RemoveAt(indexOfTriviaToRemoveOrToggle);
                    }

                    return UpdateTriviaList(token, isStartToken, triviaList, fixer);
                }
예제 #49
0
 public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider)
 {
     _suppressionFixProvider = suppressionFixProvider;
 }
 public PragmaWarningBatchFixAllProvider(AbstractSuppressionCodeFixProvider suppressionFixProvider)
 {
     _suppressionFixProvider = suppressionFixProvider;
 }
 private static bool IsEndOfLineOrHasTrailingEndOfLine(SyntaxTrivia trivia, AbstractSuppressionCodeFixProvider fixer)
 {
     return fixer.IsEndOfLine(trivia) ||
         (trivia.HasStructure && fixer.IsEndOfLine(trivia.GetStructure().DescendantTrivia().LastOrDefault()));
 }
 private static SyntaxToken UpdateTriviaList(SyntaxToken token, bool isStartToken, SyntaxTriviaList triviaList, AbstractSuppressionCodeFixProvider fixer)
 {
     return isStartToken || fixer.IsEndOfFileToken(token)
         ? token.WithLeadingTrivia(triviaList)
         : token.WithTrailingTrivia(triviaList);
 }
예제 #53
0
            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(SyntaxToken);

                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 bool IsEndOfLineOrContainsEndOfLine(SyntaxTrivia trivia, AbstractSuppressionCodeFixProvider fixer)
 {
     return fixer.IsEndOfLine(trivia) ||
         (trivia.HasStructure && trivia.GetStructure().DescendantTrivia().Any(t => fixer.IsEndOfLine(t)));
 }
예제 #55
0
 public GlobalSuppressMessageCodeAction(ISymbol targetSymbol, Project project, Diagnostic diagnostic, AbstractSuppressionCodeFixProvider fixer)
     : base(fixer, project)
 {
     _targetSymbol = targetSymbol;
     _diagnostic   = diagnostic;
 }
            internal static async Task<SyntaxToken> GetNewEndTokenWithAddedPragmaAsync(
                SyntaxToken endToken,
                TextSpan currentDiagnosticSpan,
                Diagnostic diagnostic,
                AbstractSuppressionCodeFixProvider fixer,
                Func<SyntaxNode, Task<SyntaxNode>> formatNode,
                bool isRemoveSuppression = false)
            {
                ImmutableArray<SyntaxTrivia> trivia;
                var isEOF = fixer.IsEndOfFileToken(endToken);
                if (isEOF)
                {
                    trivia = endToken.LeadingTrivia.ToImmutableArray();
                }
                else
                {
                    trivia = endToken.TrailingTrivia.ToImmutableArray();
                }

                SyntaxTrivia insertBeforeTrivia;
                var index = GetPositionForPragmaInsertion(trivia, currentDiagnosticSpan, fixer, isStartToken: false, triviaAtIndex: out insertBeforeTrivia);

                bool needsTrailingEOL;
                if (index < trivia.Length)
                {
                    needsTrailingEOL = !IsEndOfLineOrHasLeadingEndOfLine(insertBeforeTrivia, fixer);
                }
                else if (isEOF)
                {
                    needsTrailingEOL = false;
                }
                else
                {
                    needsTrailingEOL = true;
                }

                var pragmaTrivia = !isRemoveSuppression
                    ? await fixer.CreatePragmaRestoreDirectiveTriviaAsync(diagnostic, formatNode, needsLeadingEndOfLine: true, needsTrailingEndOfLine: needsTrailingEOL).ConfigureAwait(false)
                    : await fixer.CreatePragmaDisableDirectiveTriviaAsync(diagnostic, formatNode, needsLeadingEndOfLine: true, needsTrailingEndOfLine: needsTrailingEOL).ConfigureAwait(false);

                if (isEOF)
                {
                    return endToken.WithLeadingTrivia(trivia.InsertRange(index, pragmaTrivia));
                }
                else
                {
                    return endToken.WithTrailingTrivia(trivia.InsertRange(index, pragmaTrivia));
                };
            }
            private static async Task <IEnumerable <KeyValuePair <ISymbol, ImmutableArray <Diagnostic> > > > CreateDiagnosticsBySymbolAsync(AbstractSuppressionCodeFixProvider fixer, Project project, ImmutableArray <Diagnostic> diagnostics, CancellationToken cancellationToken)
            {
                var diagnosticsMapBuilder = ImmutableDictionary.CreateBuilder <ISymbol, List <Diagnostic> >();
                var compilation           = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                if (compilation != null)
                {
                    foreach (var diagnostic in diagnostics)
                    {
                        Contract.ThrowIfFalse(!diagnostic.Location.IsInSource);
                        var targetSymbol = compilation.Assembly;
                        AddDiagnosticForSymbolIfNeeded(targetSymbol, diagnostic, diagnosticsMapBuilder);
                    }
                }

                return(CreateDiagnosticsBySymbol(diagnosticsMapBuilder));
            }
            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(SyntaxToken);
                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);
            }
 public GlobalSuppressMessageCodeAction(ISymbol targetSymbol, Project project, Diagnostic diagnostic, AbstractSuppressionCodeFixProvider fixer)
     : base(fixer, project)
 {
     _targetSymbol = targetSymbol;
     _diagnostic = diagnostic;
 }
예제 #60
0
                private static SyntaxToken GetNewTokenWithPragmaUnsuppress(SyntaxToken token, int indexOfTriviaToRemoveOrToggle, AbstractSuppressionCodeFixProvider fixer, bool isStartToken, bool toggle)
                {
                    Contract.ThrowIfFalse(indexOfTriviaToRemoveOrToggle >= 0);

                    var triviaList = GetTriviaListForSuppression(token, isStartToken, fixer);

                    if (toggle)
                    {
                        var triviaToToggle = triviaList.ElementAt(indexOfTriviaToRemoveOrToggle);
                        Contract.ThrowIfFalse(triviaToToggle != default);
                        var toggledTrivia = fixer.TogglePragmaDirective(triviaToToggle);
                        triviaList = triviaList.Replace(triviaToToggle, toggledTrivia);
                    }
                    else
                    {
                        triviaList = triviaList.RemoveAt(indexOfTriviaToRemoveOrToggle);
                    }

                    return(UpdateTriviaList(token, isStartToken, triviaList, fixer));
                }