提交 860e3edd 编写于 作者: J Jason Malinowski

Add CancellationToken parameters to SyntaxTreeOptionsProvider

This threads through CancellationTokens to those parameters as long as
one was 'obviously' available for me to use; I didn't chase it too far
if it wasn't obvious to me.
上级 14731c81
......@@ -102,7 +102,7 @@ protected sealed override void InitializeWorker(AnalysisContext context)
ReportDiagnostic severity;
if (
compilationWithAnalyzers.Compilation.Options.SyntaxTreeOptionsProvider != null &&
compilationWithAnalyzers.Compilation.Options.SyntaxTreeOptionsProvider.TryGetDiagnosticValue(tree, IDEDiagnosticIds.RemoveUnnecessarySuppressionDiagnosticId, out severity) ||
compilationWithAnalyzers.Compilation.Options.SyntaxTreeOptionsProvider.TryGetDiagnosticValue(tree, IDEDiagnosticIds.RemoveUnnecessarySuppressionDiagnosticId, cancellationToken, out severity) ||
compilationWithAnalyzers.Compilation.Options.SpecificDiagnosticOptions.TryGetValue(IDEDiagnosticIds.RemoveUnnecessarySuppressionDiagnosticId, out severity))
{
if (severity == ReportDiagnostic.Suppress)
......
......@@ -244,7 +244,7 @@ internal bool AreNullableAnnotationsEnabled(SyntaxTree syntaxTree, int position)
Syntax.NullableContextState.State.Disabled => false,
Syntax.NullableContextState.State.ExplicitlyRestored => GetGlobalAnnotationState(),
Syntax.NullableContextState.State.Unknown =>
!csTree.IsGeneratedCode(this.Compilation.Options.SyntaxTreeOptionsProvider)
!csTree.IsGeneratedCode(this.Compilation.Options.SyntaxTreeOptionsProvider, CancellationToken.None)
&& AreNullableAnnotationsGloballyEnabled(),
_ => throw ExceptionUtilities.UnexpectedValue(context.AnnotationsState)
};
......@@ -259,7 +259,7 @@ internal bool AreNullableAnnotationsEnabled(SyntaxToken token)
internal bool IsGeneratedCode(SyntaxToken token)
{
var tree = (CSharpSyntaxTree)token.SyntaxTree!;
return tree.IsGeneratedCode(Compilation.Options.SyntaxTreeOptionsProvider);
return tree.IsGeneratedCode(Compilation.Options.SyntaxTreeOptionsProvider, CancellationToken.None);
}
internal virtual bool AreNullableAnnotationsGloballyEnabled()
......
......@@ -9,6 +9,7 @@
using System.Collections.Immutable;
using System.ComponentModel;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
......@@ -755,7 +756,7 @@ public override int GetHashCode()
Hash.Combine(TopLevelBinderFlags.GetHashCode(), this.NullableContextOptions.GetHashCode()))));
}
internal override Diagnostic? FilterDiagnostic(Diagnostic diagnostic)
internal override Diagnostic? FilterDiagnostic(Diagnostic diagnostic, CancellationToken cancellationToken)
{
return CSharpDiagnosticFilter.Filter(
diagnostic,
......@@ -763,7 +764,8 @@ public override int GetHashCode()
NullableContextOptions,
GeneralDiagnosticOption,
SpecificDiagnosticOptions,
SyntaxTreeOptionsProvider);
SyntaxTreeOptionsProvider,
cancellationToken);
}
protected override CompilationOptions CommonWithModuleName(string? moduleName)
......
......@@ -2544,7 +2544,7 @@ internal override void GetDiagnostics(CompilationStage stage, bool includeEarlie
// Before returning diagnostics, we filter warnings
// to honor the compiler options (e.g., /nowarn, /warnaserror and /warn) and the pragmas.
FilterAndAppendAndFreeDiagnostics(diagnostics, ref builder);
FilterAndAppendAndFreeDiagnostics(diagnostics, ref builder, cancellationToken);
}
private static void AppendLoadDirectiveDiagnostics(DiagnosticBag builder, SyntaxAndDeclarationManager syntaxAndDeclarations, SyntaxTree syntaxTree, Func<IEnumerable<Diagnostic>, IEnumerable<Diagnostic>>? locationFilterOpt = null)
......@@ -2748,7 +2748,7 @@ private static IEnumerable<Diagnostic> FilterDiagnosticsByLocation(IEnumerable<D
// Before returning diagnostics, we filter warnings
// to honor the compiler options (/nowarn, /warnaserror and /warn) and the pragmas.
var result = DiagnosticBag.GetInstance();
FilterAndAppendAndFreeDiagnostics(result, ref builder);
FilterAndAppendAndFreeDiagnostics(result, ref builder, cancellationToken);
return result.ToReadOnlyAndFree<Diagnostic>();
}
......@@ -2876,7 +2876,7 @@ internal override StrongNameKeys StrongNameKeys
excludeDiagnostics = PooledHashSet<int>.GetInstance();
excludeDiagnostics.Add((int)ErrorCode.ERR_ConcreteMissingBody);
}
bool hasDeclarationErrors = !FilterAndAppendDiagnostics(diagnostics, GetDiagnostics(CompilationStage.Declare, true, cancellationToken), excludeDiagnostics);
bool hasDeclarationErrors = !FilterAndAppendDiagnostics(diagnostics, GetDiagnostics(CompilationStage.Declare, true, cancellationToken), excludeDiagnostics, cancellationToken);
excludeDiagnostics?.Free();
// TODO (tomat): NoPIA:
......@@ -2931,7 +2931,7 @@ internal override StrongNameKeys StrongNameKeys
GenerateModuleInitializer(moduleBeingBuilt, methodBodyDiagnosticBag);
}
bool hasMethodBodyError = !FilterAndAppendAndFreeDiagnostics(diagnostics, ref methodBodyDiagnosticBag);
bool hasMethodBodyError = !FilterAndAppendAndFreeDiagnostics(diagnostics, ref methodBodyDiagnosticBag, cancellationToken);
if (hasDeclarationErrors || hasMethodBodyError)
{
......@@ -2985,7 +2985,7 @@ private void GenerateModuleInitializer(PEModuleBuilder moduleBeingBuilt, Diagnos
AddedModulesResourceNames(resourceDiagnostics),
resourceDiagnostics);
if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref resourceDiagnostics))
if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref resourceDiagnostics, cancellationToken))
{
return false;
}
......@@ -2998,7 +2998,7 @@ private void GenerateModuleInitializer(PEModuleBuilder moduleBeingBuilt, Diagnos
string? assemblyName = FileNameUtilities.ChangeExtension(outputNameOverride, extension: null);
DocumentationCommentCompiler.WriteDocumentationCommentXml(this, assemblyName, xmlDocStream, xmlDiagnostics, cancellationToken);
return FilterAndAppendAndFreeDiagnostics(diagnostics, ref xmlDiagnostics);
return FilterAndAppendAndFreeDiagnostics(diagnostics, ref xmlDiagnostics, cancellationToken);
}
private IEnumerable<string> AddedModulesResourceNames(DiagnosticBag diagnostics)
......@@ -3061,7 +3061,7 @@ private IEnumerable<string> AddedModulesResourceNames(DiagnosticBag diagnostics)
DiagnosticBag? runtimeMDVersionDiagnostics = DiagnosticBag.GetInstance();
runtimeMDVersionDiagnostics.Add(ErrorCode.WRN_NoRuntimeMetadataVersion, NoLocation.Singleton);
if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref runtimeMDVersionDiagnostics))
if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref runtimeMDVersionDiagnostics, CancellationToken.None))
{
return null;
}
......
......@@ -8,6 +8,7 @@
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp
......@@ -38,7 +39,8 @@ internal static class CSharpDiagnosticFilter
NullableContextOptions nullableOption,
ReportDiagnostic generalDiagnosticOption,
IDictionary<string, ReportDiagnostic> specificDiagnosticOptions,
SyntaxTreeOptionsProvider? syntaxTreeOptions)
SyntaxTreeOptionsProvider? syntaxTreeOptions,
CancellationToken cancellationToken)
{
if (d == null)
{
......@@ -86,6 +88,7 @@ internal static class CSharpDiagnosticFilter
generalDiagnosticOption,
specificDiagnosticOptions,
syntaxTreeOptions,
cancellationToken,
out hasPragmaSuppression);
}
else
......@@ -101,6 +104,7 @@ internal static class CSharpDiagnosticFilter
generalDiagnosticOption,
specificDiagnosticOptions,
syntaxTreeOptions,
cancellationToken,
out hasPragmaSuppression);
}
......@@ -137,6 +141,7 @@ internal static class CSharpDiagnosticFilter
ReportDiagnostic generalDiagnosticOption,
IDictionary<string, ReportDiagnostic> specificDiagnosticOptions,
SyntaxTreeOptionsProvider? syntaxTreeOptions,
CancellationToken cancellationToken,
out bool hasPragmaSuppression)
{
hasPragmaSuppression = false;
......@@ -155,7 +160,7 @@ internal static class CSharpDiagnosticFilter
Syntax.NullableContextState.State.Disabled => false,
Syntax.NullableContextState.State.ExplicitlyRestored => nullableOption.WarningsEnabled(),
Syntax.NullableContextState.State.Unknown =>
tree?.IsGeneratedCode(syntaxTreeOptions) != true && nullableOption.WarningsEnabled(),
tree?.IsGeneratedCode(syntaxTreeOptions, cancellationToken) != true && nullableOption.WarningsEnabled(),
null => nullableOption.WarningsEnabled(),
_ => throw ExceptionUtilities.UnexpectedValue(warningsState)
};
......@@ -176,7 +181,7 @@ internal static class CSharpDiagnosticFilter
bool isSpecified = false;
if (tree != null && syntaxTreeOptions != null &&
syntaxTreeOptions.TryGetDiagnosticValue(tree, id, out report))
syntaxTreeOptions.TryGetDiagnosticValue(tree, id, cancellationToken, out report))
{
// 2. Syntax tree level
isSpecified = true;
......
......@@ -5262,7 +5262,7 @@ public sealed override NullableContext GetNullableContext(int position)
{
var syntaxTree = (CSharpSyntaxTree)Root.SyntaxTree;
NullableContextState contextState = syntaxTree.GetNullableContextState(position);
var defaultState = syntaxTree.IsGeneratedCode(Compilation.Options.SyntaxTreeOptionsProvider)
var defaultState = syntaxTree.IsGeneratedCode(Compilation.Options.SyntaxTreeOptionsProvider, CancellationToken.None)
? NullableContextOptions.Disable
: Compilation.Options.NullableContextOptions;
......
......@@ -5,6 +5,7 @@
using System;
using System.Collections.Immutable;
using System.Globalization;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Roslyn.Utilities;
......@@ -129,6 +130,7 @@ public override ReportDiagnostic GetDiagnosticReport(DiagnosticInfo diagnosticIn
options.GeneralDiagnosticOption,
options.SpecificDiagnosticOptions,
options.SyntaxTreeOptionsProvider,
CancellationToken.None, // We don't have a tree so there's no need to pass cancellation to the SyntaxTreeOptionsProvider
out hasPragmaSuppression);
}
......
......@@ -720,9 +720,9 @@ internal NullableContextState GetNullableContextState(int position)
/// </summary>
internal bool HasNullableEnables() => GetNullableContextStateMap().HasNullableEnables();
internal bool IsGeneratedCode(SyntaxTreeOptionsProvider? provider)
internal bool IsGeneratedCode(SyntaxTreeOptionsProvider? provider, CancellationToken cancellationToken)
{
return provider?.IsGenerated(this) ?? isGeneratedHeuristic();
return provider?.IsGenerated(this, cancellationToken) ?? isGeneratedHeuristic();
bool isGeneratedHeuristic()
{
......
......@@ -240,9 +240,9 @@ class C
var comp = cmd.Compilation;
var tree = comp.SyntaxTrees.Single();
var compilerTreeOptions = comp.Options.SyntaxTreeOptionsProvider;
Assert.True(compilerTreeOptions.TryGetDiagnosticValue(tree, "cs0169", out var severity));
Assert.True(compilerTreeOptions.TryGetDiagnosticValue(tree, "cs0169", CancellationToken.None, out var severity));
Assert.Equal(ReportDiagnostic.Suppress, severity);
Assert.True(compilerTreeOptions.TryGetDiagnosticValue(tree, "warning01", out severity));
Assert.True(compilerTreeOptions.TryGetDiagnosticValue(tree, "warning01", CancellationToken.None, out severity));
Assert.Equal(ReportDiagnostic.Suppress, severity);
var analyzerOptions = cmd.AnalyzerOptions.AnalyzerConfigOptionsProvider;
......
......@@ -5633,7 +5633,7 @@ static void G(object x)
}
}", options: null, path: "", encoding: null, diagnosticOptions: null, isGeneratedCode: true, cancellationToken: default);
Assert.False(((CSharpSyntaxTree)source1).IsGeneratedCode(null));
Assert.False(((CSharpSyntaxTree)source1).IsGeneratedCode(null, cancellationToken: default));
var source2 = CSharpSyntaxTree.ParseText(@"
partial class Program
......@@ -5647,7 +5647,7 @@ static void H(object x)
}
}", options: null, path: "", encoding: null, diagnosticOptions: null, isGeneratedCode: false, cancellationToken: default);
Assert.False(((CSharpSyntaxTree)source2).IsGeneratedCode(null));
Assert.False(((CSharpSyntaxTree)source2).IsGeneratedCode(null, cancellationToken: default));
var source3 = CSharpSyntaxTree.ParseText(
@"
......@@ -5660,7 +5660,7 @@ static void I(object x)
}
}", options: null, path: "", encoding: null, diagnosticOptions: null, isGeneratedCode: null /* use heuristic */, cancellationToken: default);
Assert.False(((CSharpSyntaxTree)source3).IsGeneratedCode(null));
Assert.False(((CSharpSyntaxTree)source3).IsGeneratedCode(null, cancellationToken: default));
var source4 = SyntaxFactory.ParseSyntaxTree(@"
partial class Program
......@@ -5672,7 +5672,7 @@ static void J(object x)
}
}", options: null, path: "", encoding: null, diagnosticOptions: null, isGeneratedCode: true, cancellationToken: default);
Assert.False(((CSharpSyntaxTree)source4).IsGeneratedCode(null));
Assert.False(((CSharpSyntaxTree)source4).IsGeneratedCode(null, cancellationToken: default));
#pragma warning restore CS0618
......@@ -1531,10 +1531,10 @@ internal void CompleteCompilationEventQueue_NoLock()
/// <param name="accumulator">Bag to which filtered diagnostics will be added.</param>
/// <param name="incoming">Diagnostics to be filtered.</param>
/// <returns>True if there are no unsuppressed errors (i.e., no errors which fail compilation).</returns>
internal bool FilterAndAppendAndFreeDiagnostics(DiagnosticBag accumulator, [DisallowNull] ref DiagnosticBag? incoming)
internal bool FilterAndAppendAndFreeDiagnostics(DiagnosticBag accumulator, [DisallowNull] ref DiagnosticBag? incoming, CancellationToken cancellationToken)
{
RoslynDebug.Assert(incoming is object);
bool result = FilterAndAppendDiagnostics(accumulator, incoming.AsEnumerableWithoutResolution(), exclude: null);
bool result = FilterAndAppendDiagnostics(accumulator, incoming.AsEnumerableWithoutResolution(), exclude: null, cancellationToken);
incoming.Free();
incoming = null;
return result;
......@@ -1544,7 +1544,7 @@ internal bool FilterAndAppendAndFreeDiagnostics(DiagnosticBag accumulator, [Disa
/// Filter out warnings based on the compiler options (/nowarn, /warn and /warnaserror) and the pragma warning directives.
/// </summary>
/// <returns>True if there are no unsuppressed errors (i.e., no errors which fail compilation).</returns>
internal bool FilterAndAppendDiagnostics(DiagnosticBag accumulator, IEnumerable<Diagnostic> incoming, HashSet<int>? exclude)
internal bool FilterAndAppendDiagnostics(DiagnosticBag accumulator, IEnumerable<Diagnostic> incoming, HashSet<int>? exclude, CancellationToken cancellationToken)
{
bool hasError = false;
bool reportSuppressedDiagnostics = Options.ReportSuppressedDiagnostics;
......@@ -1556,7 +1556,7 @@ internal bool FilterAndAppendDiagnostics(DiagnosticBag accumulator, IEnumerable<
continue;
}
var filtered = Options.FilterDiagnostic(d);
var filtered = Options.FilterDiagnostic(d, cancellationToken);
if (filtered == null ||
(!reportSuppressedDiagnostics && filtered.IsSuppressed))
{
......@@ -2912,7 +2912,7 @@ internal void EnsureAnonymousTypeTemplates(CancellationToken cancellationToken)
}
// translate metadata errors.
if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref metadataDiagnostics))
if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref metadataDiagnostics, cancellationToken))
{
return false;
}
......
......@@ -9,6 +9,7 @@
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
......@@ -196,7 +197,7 @@ public abstract class CompilationOptions
/// </summary>
/// <param name="diagnostic"></param>
/// <returns>The modified diagnostic, or null</returns>
internal abstract Diagnostic? FilterDiagnostic(Diagnostic diagnostic);
internal abstract Diagnostic? FilterDiagnostic(Diagnostic diagnostic, CancellationToken cancellationToken);
/// <summary>
/// Warning report option for each warning.
......
......@@ -5,18 +5,19 @@
#nullable enable
using System.Collections.Immutable;
using System.Threading;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis
{
public abstract class SyntaxTreeOptionsProvider
{
public abstract bool? IsGenerated(SyntaxTree tree);
public abstract bool? IsGenerated(SyntaxTree tree, CancellationToken cancellationToken);
/// <summary>
/// Get diagnostic severity setting or a given diagnostic identifier in a given tree.
/// </summary>
public abstract bool TryGetDiagnosticValue(SyntaxTree tree, string diagnosticId, out ReportDiagnostic severity);
public abstract bool TryGetDiagnosticValue(SyntaxTree tree, string diagnosticId, CancellationToken cancellationToken, out ReportDiagnostic severity);
}
internal sealed class CompilerSyntaxTreeOptionsProvider : SyntaxTreeOptionsProvider
......@@ -60,10 +61,10 @@ public Options(AnalyzerConfigOptionsResult? result)
_options = builder.ToImmutableDictionary();
}
public override bool? IsGenerated(SyntaxTree tree)
public override bool? IsGenerated(SyntaxTree tree, CancellationToken _)
=> _options.TryGetValue(tree, out var value) ? value.IsGenerated : null;
public override bool TryGetDiagnosticValue(SyntaxTree tree, string diagnosticId, out ReportDiagnostic severity)
public override bool TryGetDiagnosticValue(SyntaxTree tree, string diagnosticId, CancellationToken _, out ReportDiagnostic severity)
{
if (_options.TryGetValue(tree, out var value))
{
......
......@@ -7,6 +7,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading;
using Microsoft.CodeAnalysis.Diagnostics;
using Roslyn.Utilities;
......@@ -220,7 +221,7 @@ public ReportDiagnostic GetEffectiveSeverity(CompilationOptions compilationOptio
// Create a dummy diagnostic to compute the effective diagnostic severity for given compilation options
// TODO: Once https://github.com/dotnet/roslyn/issues/3650 is fixed, we can avoid creating a no-location diagnostic here.
var effectiveDiagnostic = compilationOptions.FilterDiagnostic(Diagnostic.Create(this, Location.None));
var effectiveDiagnostic = compilationOptions.FilterDiagnostic(Diagnostic.Create(this, Location.None), CancellationToken.None);
return effectiveDiagnostic != null ? MapSeverityToReport(effectiveDiagnostic.Severity) : ReportDiagnostic.Suppress;
}
......
......@@ -449,18 +449,18 @@ private void Initialize(AnalyzerExecutor analyzerExecutor, DiagnosticQueue diagn
Action<Diagnostic, DiagnosticAnalyzer>? addCategorizedNonLocalDiagnostic = null;
if (categorizeDiagnostics)
{
addCategorizedLocalDiagnostic = GetDiagnosticSink(diagnosticQueue.EnqueueLocal, compilation, analysisOptions.Options, _severityFilter);
addCategorizedNonLocalDiagnostic = GetDiagnosticSink(diagnosticQueue.EnqueueNonLocal, compilation, analysisOptions.Options, _severityFilter);
addCategorizedLocalDiagnostic = GetDiagnosticSink(diagnosticQueue.EnqueueLocal, compilation, analysisOptions.Options, _severityFilter, cancellationToken);
addCategorizedNonLocalDiagnostic = GetDiagnosticSink(diagnosticQueue.EnqueueNonLocal, compilation, analysisOptions.Options, _severityFilter, cancellationToken);
}
else
{
addNotCategorizedDiagnostic = GetDiagnosticSink(diagnosticQueue.Enqueue, compilation, analysisOptions.Options, _severityFilter);
addNotCategorizedDiagnostic = GetDiagnosticSink(diagnosticQueue.Enqueue, compilation, analysisOptions.Options, _severityFilter, cancellationToken);
}
// Wrap onAnalyzerException to pass in filtered diagnostic.
Action<Exception, DiagnosticAnalyzer, Diagnostic> newOnAnalyzerException = (ex, analyzer, diagnostic) =>
{
var filteredDiagnostic = GetFilteredDiagnostic(diagnostic, compilation, analysisOptions.Options, _severityFilter);
var filteredDiagnostic = GetFilteredDiagnostic(diagnostic, compilation, analysisOptions.Options, _severityFilter, cancellationToken);
if (filteredDiagnostic != null)
{
if (analysisOptions.OnAnalyzerException != null)
......@@ -1247,7 +1247,7 @@ private ImmutableHashSet<DiagnosticAnalyzer> ComputeSuppressedAnalyzersForTree(S
var hasUnsuppressedDiagnostic = false;
foreach (var descriptor in descriptors)
{
if (!options.TryGetDiagnosticValue(tree, descriptor.Id, out var configuredSeverity) ||
if (!options.TryGetDiagnosticValue(tree, descriptor.Id, AnalyzerExecutor.CancellationToken, out var configuredSeverity) ||
configuredSeverity != ReportDiagnostic.Suppress)
{
// Analyzer reports a diagnostic that is not suppressed by the diagnostic options for this tree.
......@@ -1881,11 +1881,11 @@ private bool TryProcessCompilationCompleted(CompilationCompletedEvent endEvent,
}
}
internal static Action<Diagnostic> GetDiagnosticSink(Action<Diagnostic> addDiagnosticCore, Compilation compilation, AnalyzerOptions? analyzerOptions, SeverityFilter severityFilter)
internal static Action<Diagnostic> GetDiagnosticSink(Action<Diagnostic> addDiagnosticCore, Compilation compilation, AnalyzerOptions? analyzerOptions, SeverityFilter severityFilter, CancellationToken cancellationToken)
{
return diagnostic =>
{
var filteredDiagnostic = GetFilteredDiagnostic(diagnostic, compilation, analyzerOptions, severityFilter);
var filteredDiagnostic = GetFilteredDiagnostic(diagnostic, compilation, analyzerOptions, severityFilter, cancellationToken);
if (filteredDiagnostic != null)
{
addDiagnosticCore(filteredDiagnostic);
......@@ -1893,11 +1893,11 @@ internal static Action<Diagnostic> GetDiagnosticSink(Action<Diagnostic> addDiagn
};
}
internal static Action<Diagnostic, DiagnosticAnalyzer, bool> GetDiagnosticSink(Action<Diagnostic, DiagnosticAnalyzer, bool> addLocalDiagnosticCore, Compilation compilation, AnalyzerOptions? analyzerOptions, SeverityFilter severityFilter)
internal static Action<Diagnostic, DiagnosticAnalyzer, bool> GetDiagnosticSink(Action<Diagnostic, DiagnosticAnalyzer, bool> addLocalDiagnosticCore, Compilation compilation, AnalyzerOptions? analyzerOptions, SeverityFilter severityFilter, CancellationToken cancellationToken)
{
return (diagnostic, analyzer, isSyntaxDiagnostic) =>
{
var filteredDiagnostic = GetFilteredDiagnostic(diagnostic, compilation, analyzerOptions, severityFilter);
var filteredDiagnostic = GetFilteredDiagnostic(diagnostic, compilation, analyzerOptions, severityFilter, cancellationToken);
if (filteredDiagnostic != null)
{
addLocalDiagnosticCore(filteredDiagnostic, analyzer, isSyntaxDiagnostic);
......@@ -1905,11 +1905,11 @@ internal static Action<Diagnostic> GetDiagnosticSink(Action<Diagnostic> addDiagn
};
}
internal static Action<Diagnostic, DiagnosticAnalyzer> GetDiagnosticSink(Action<Diagnostic, DiagnosticAnalyzer> addDiagnosticCore, Compilation compilation, AnalyzerOptions? analyzerOptions, SeverityFilter severityFilter)
internal static Action<Diagnostic, DiagnosticAnalyzer> GetDiagnosticSink(Action<Diagnostic, DiagnosticAnalyzer> addDiagnosticCore, Compilation compilation, AnalyzerOptions? analyzerOptions, SeverityFilter severityFilter, CancellationToken cancellationToken)
{
return (diagnostic, analyzer) =>
{
var filteredDiagnostic = GetFilteredDiagnostic(diagnostic, compilation, analyzerOptions, severityFilter);
var filteredDiagnostic = GetFilteredDiagnostic(diagnostic, compilation, analyzerOptions, severityFilter, cancellationToken);
if (filteredDiagnostic != null)
{
addDiagnosticCore(filteredDiagnostic, analyzer);
......@@ -1917,16 +1917,16 @@ internal static Action<Diagnostic> GetDiagnosticSink(Action<Diagnostic> addDiagn
};
}
private static Diagnostic? GetFilteredDiagnostic(Diagnostic diagnostic, Compilation compilation, AnalyzerOptions? analyzerOptions, SeverityFilter severityFilter)
private static Diagnostic? GetFilteredDiagnostic(Diagnostic diagnostic, Compilation compilation, AnalyzerOptions? analyzerOptions, SeverityFilter severityFilter, CancellationToken cancellationToken)
{
var filteredDiagnostic = compilation.Options.FilterDiagnostic(diagnostic);
var filteredDiagnostic = compilation.Options.FilterDiagnostic(diagnostic, cancellationToken);
return applyFurtherFiltering(filteredDiagnostic);
Diagnostic? applyFurtherFiltering(Diagnostic? diagnostic)
{
// Apply bulk configuration from analyzer options for analyzer diagnostics, if applicable.
if (diagnostic?.Location.SourceTree is { } tree &&
analyzerOptions.TryGetSeverityFromBulkConfiguration(tree, compilation, diagnostic.Descriptor, out ReportDiagnostic severity))
analyzerOptions.TryGetSeverityFromBulkConfiguration(tree, compilation, diagnostic.Descriptor, cancellationToken, out ReportDiagnostic severity))
{
diagnostic = diagnostic.WithReportDiagnostic(severity);
}
......
......@@ -8,6 +8,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
......@@ -341,7 +342,7 @@ internal bool IsSupportedDiagnostic(DiagnosticAnalyzer analyzer, Diagnostic diag
// Editorconfig user settings override compilation wide settings.
if (isSuppressed &&
isEnabledWithAnalyzerConfigOptions(diag, severityFilter, compilation, analyzerOptions))
isEnabledWithAnalyzerConfigOptions(diag, severityFilter, compilation, analyzerOptions, analyzerExecutor.CancellationToken))
{
isSuppressed = false;
}
......@@ -369,15 +370,16 @@ internal bool IsSupportedDiagnostic(DiagnosticAnalyzer analyzer, Diagnostic diag
DiagnosticDescriptor descriptor,
SeverityFilter severityFilter,
Compilation? compilation,
AnalyzerOptions? analyzerOptions)
AnalyzerOptions? analyzerOptions,
CancellationToken cancellationToken)
{
if (compilation != null && compilation.Options.SyntaxTreeOptionsProvider is { } treeOptions)
{
foreach (var tree in compilation.SyntaxTrees)
{
// Check if diagnostic is enabled by SyntaxTree.DiagnosticOptions or Bulk configuration from AnalyzerConfigOptions.
if (treeOptions.TryGetDiagnosticValue(tree, descriptor.Id, out var configuredValue) ||
analyzerOptions.TryGetSeverityFromBulkConfiguration(tree, compilation, descriptor, out configuredValue))
if (treeOptions.TryGetDiagnosticValue(tree, descriptor.Id, cancellationToken, out var configuredValue) ||
analyzerOptions.TryGetSeverityFromBulkConfiguration(tree, compilation, descriptor, cancellationToken, out configuredValue))
{
if (configuredValue != ReportDiagnostic.Suppress && !severityFilter.Contains(configuredValue))
{
......
......@@ -6,6 +6,7 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Diagnostics
......@@ -33,6 +34,7 @@ private static string GetCategoryBasedDotnetAnalyzerDiagnosticSeverityKey(string
SyntaxTree tree,
Compilation compilation,
DiagnosticDescriptor descriptor,
CancellationToken cancellationToken,
out ReportDiagnostic severity)
{
// Analyzer bulk configuration does not apply to:
......@@ -51,7 +53,7 @@ private static string GetCategoryBasedDotnetAnalyzerDiagnosticSeverityKey(string
// bulk configuration should not be applied.
// For example, 'dotnet_diagnostic.CA1000.severity = error'
if (compilation.Options.SpecificDiagnosticOptions.ContainsKey(descriptor.Id) ||
compilation.Options.SyntaxTreeOptionsProvider?.TryGetDiagnosticValue(tree, descriptor.Id, out _) == true)
compilation.Options.SyntaxTreeOptionsProvider?.TryGetDiagnosticValue(tree, descriptor.Id, cancellationToken, out _) == true)
{
severity = default;
return false;
......
......@@ -1287,7 +1287,7 @@ private static IEnumerable<Diagnostic> GetEffectiveDiagnosticsImpl(ImmutableArra
{
if (diagnostic != null)
{
var effectiveDiagnostic = compilation.Options.FilterDiagnostic(diagnostic);
var effectiveDiagnostic = compilation.Options.FilterDiagnostic(diagnostic, CancellationToken.None);
if (effectiveDiagnostic != null)
{
yield return suppressMessageState.ApplySourceSuppressions(effectiveDiagnostic);
......
......@@ -22,8 +22,8 @@ Microsoft.CodeAnalysis.GeneratorDriverRunResult.GeneratedTrees.get -> System.Col
Microsoft.CodeAnalysis.GeneratorDriverRunResult.Results.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.GeneratorRunResult>
Microsoft.CodeAnalysis.SyntaxTreeOptionsProvider
Microsoft.CodeAnalysis.SyntaxTreeOptionsProvider.SyntaxTreeOptionsProvider() -> void
abstract Microsoft.CodeAnalysis.SyntaxTreeOptionsProvider.IsGenerated(Microsoft.CodeAnalysis.SyntaxTree tree) -> bool?
abstract Microsoft.CodeAnalysis.SyntaxTreeOptionsProvider.TryGetDiagnosticValue(Microsoft.CodeAnalysis.SyntaxTree tree, string diagnosticId, out Microsoft.CodeAnalysis.ReportDiagnostic severity) -> bool
abstract Microsoft.CodeAnalysis.SyntaxTreeOptionsProvider.IsGenerated(Microsoft.CodeAnalysis.SyntaxTree tree, System.Threading.CancellationToken cancellationToken) -> bool?
abstract Microsoft.CodeAnalysis.SyntaxTreeOptionsProvider.TryGetDiagnosticValue(Microsoft.CodeAnalysis.SyntaxTree tree, string diagnosticId, System.Threading.CancellationToken cancellationToken, out Microsoft.CodeAnalysis.ReportDiagnostic severity) -> bool
Microsoft.CodeAnalysis.GeneratorRunResult.GeneratedSources.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.GeneratedSourceResult>
const Microsoft.CodeAnalysis.WellKnownMemberNames.TopLevelStatementsEntryPointMethodName = "<Main>$" -> string
const Microsoft.CodeAnalysis.WellKnownMemberNames.TopLevelStatementsEntryPointTypeName = "<Program>$" -> string
......
......@@ -2143,7 +2143,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' Before returning diagnostics, we filter some of them
' to honor the compiler options (e.g., /nowarn and /warnaserror)
FilterAndAppendAndFreeDiagnostics(diagnostics, builder)
FilterAndAppendAndFreeDiagnostics(diagnostics, builder, cancellationToken)
End Sub
Private Function GetClsComplianceDiagnostics(cancellationToken As CancellationToken, Optional filterTree As SyntaxTree = Nothing, Optional filterSpanWithinTree As TextSpan? = Nothing) As ImmutableArray(Of Diagnostic)
......@@ -2216,7 +2216,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
Dim result = DiagnosticBag.GetInstance()
FilterAndAppendAndFreeDiagnostics(result, builder)
FilterAndAppendAndFreeDiagnostics(result, builder, cancellationToken)
Return result.ToReadOnlyAndFree(Of Diagnostic)()
End Function
......@@ -2391,7 +2391,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' The diagnostics should include syntax and declaration errors. We insert these before calling Emitter.Emit, so that we don't emit
' metadata if there are declaration errors or method body errors (but we do insert all errors from method body binding...)
Dim hasDeclarationErrors = Not FilterAndAppendDiagnostics(diagnostics, GetDiagnostics(CompilationStage.Declare, True, cancellationToken), exclude:=Nothing)
Dim hasDeclarationErrors = Not FilterAndAppendDiagnostics(diagnostics, GetDiagnostics(CompilationStage.Declare, True, cancellationToken), exclude:=Nothing, cancellationToken)
Dim moduleBeingBuilt = DirectCast(moduleBuilder, PEModuleBuilder)
......@@ -2440,7 +2440,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
methodBodyDiagnosticBag,
cancellationToken)
Dim hasMethodBodyErrors As Boolean = Not FilterAndAppendAndFreeDiagnostics(diagnostics, methodBodyDiagnosticBag)
Dim hasMethodBodyErrors As Boolean = Not FilterAndAppendAndFreeDiagnostics(diagnostics, methodBodyDiagnosticBag, cancellationToken)
If hasDeclarationErrors OrElse hasMethodBodyErrors Then
Return False
End If
......@@ -2472,7 +2472,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
AddedModulesResourceNames(resourceDiagnostics),
resourceDiagnostics)
If Not FilterAndAppendAndFreeDiagnostics(diagnostics, resourceDiagnostics) Then
If Not FilterAndAppendAndFreeDiagnostics(diagnostics, resourceDiagnostics, cancellationToken) Then
Return False
End If
......@@ -2484,7 +2484,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim assemblyName = FileNameUtilities.ChangeExtension(outputNameOverride, extension:=Nothing)
DocumentationCommentCompiler.WriteDocumentationCommentXml(Me, assemblyName, xmlDocStream, xmlDiagnostics, cancellationToken)
Return FilterAndAppendAndFreeDiagnostics(diagnostics, xmlDiagnostics)
Return FilterAndAppendAndFreeDiagnostics(diagnostics, xmlDiagnostics, cancellationToken)
End Function
Private Iterator Function AddedModulesResourceNames(diagnostics As DiagnosticBag) As IEnumerable(Of String)
......
......@@ -3,8 +3,8 @@
' See the LICENSE file in the project root for more information.
Imports System.Collections.Immutable
Imports System.Threading
Imports System.Runtime.InteropServices
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.VisualBasic
Namespace Microsoft.CodeAnalysis.VisualBasic
......@@ -29,7 +29,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
diagnostic As Diagnostic,
generalDiagnosticOption As ReportDiagnostic,
specificDiagnosticOptions As IDictionary(Of String, ReportDiagnostic),
syntaxTreeOptions As SyntaxTreeOptionsProvider) As Diagnostic
syntaxTreeOptions As SyntaxTreeOptionsProvider,
cancellationToken As CancellationToken) As Diagnostic
' Diagnostic ids must be processed in case-insensitive fashion in VB.
Dim caseInsensitiveSpecificDiagnosticOptions =
......@@ -67,14 +68,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
If (s_alinkWarnings.Contains(CType(diagnostic.Code, ERRID)) AndAlso
caseInsensitiveSpecificDiagnosticOptions.Keys.Contains(VisualBasic.MessageProvider.Instance.GetIdForErrorCode(ERRID.WRN_AssemblyGeneration1))) Then
report = GetDiagnosticReport(VisualBasic.MessageProvider.Instance.GetSeverity(ERRID.WRN_AssemblyGeneration1),
diagnostic.IsEnabledByDefault,
VisualBasic.MessageProvider.Instance.GetIdForErrorCode(ERRID.WRN_AssemblyGeneration1),
diagnostic.Location,
diagnostic.Category,
generalDiagnosticOption,
caseInsensitiveSpecificDiagnosticOptions,
syntaxTreeOptions,
hasSourceSuppression)
diagnostic.IsEnabledByDefault,
VisualBasic.MessageProvider.Instance.GetIdForErrorCode(ERRID.WRN_AssemblyGeneration1),
diagnostic.Location,
diagnostic.Category,
generalDiagnosticOption,
caseInsensitiveSpecificDiagnosticOptions,
syntaxTreeOptions,
cancellationToken,
hasSourceSuppression)
Else
report = GetDiagnosticReport(
diagnostic.Severity,
......@@ -85,6 +87,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
generalDiagnosticOption,
caseInsensitiveSpecificDiagnosticOptions,
syntaxTreeOptions,
cancellationToken,
hasSourceSuppression)
End If
......@@ -123,6 +126,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
generalDiagnosticOption As ReportDiagnostic,
caseInsensitiveSpecificDiagnosticOptions As IDictionary(Of String, ReportDiagnostic),
syntaxTreeOptions As SyntaxTreeOptionsProvider,
cancellationToken As CancellationToken,
<Out> ByRef hasDisableDirectiveSuppression As Boolean) As ReportDiagnostic
hasDisableDirectiveSuppression = False
......@@ -132,7 +136,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' Global options depend on other options, so calculate those first
If tree IsNot Nothing AndAlso syntaxTreeOptions IsNot Nothing AndAlso
syntaxTreeOptions.TryGetDiagnosticValue(tree, id, report) Then
syntaxTreeOptions.TryGetDiagnosticValue(tree, id, cancellationToken, report) Then
' 2. Syntax tree level
isSpecified = True
ElseIf caseInsensitiveSpecificDiagnosticOptions.TryGetValue(id, report) Then
......
......@@ -3,6 +3,7 @@
' See the LICENSE file in the project root for more information.
Imports System.Globalization
Imports System.Threading
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
......@@ -133,6 +134,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
options.GeneralDiagnosticOption,
options.SpecificDiagnosticOptions,
options.SyntaxTreeOptionsProvider,
CancellationToken.None, ' We don't have a tree so there's no need to pass cancellation to the SyntaxTreeOptionsProvider
hasSourceSuppression)
End Function
......
......@@ -4,6 +4,7 @@
Imports System.Collections.Immutable
Imports System.ComponentModel
Imports System.Threading
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.PooledObjects
......@@ -1126,12 +1127,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Hash.Combine(Me.ParseOptions, 0)))))))))))
End Function
Friend Overrides Function FilterDiagnostic(diagnostic As Diagnostic) As Diagnostic
Friend Overrides Function FilterDiagnostic(diagnostic As Diagnostic, cancellationToken As CancellationToken) As Diagnostic
Return VisualBasicDiagnosticFilter.Filter(
diagnostic,
GeneralDiagnosticOption,
SpecificDiagnosticOptions,
SyntaxTreeOptionsProvider)
SyntaxTreeOptionsProvider,
cancellationToken)
End Function
'' 1.1 BACKCOMPAT OVERLOAD -- DO NOT TOUCH
......
......@@ -129,13 +129,13 @@ my_option2 = my_val2")
Dim tree = comp.SyntaxTrees.Single()
Dim syntaxTreeOptions = comp.Options.SyntaxTreeOptionsProvider
Dim report As ReportDiagnostic
Assert.True(syntaxTreeOptions.TryGetDiagnosticValue(tree, "BC42024", report))
Assert.True(syntaxTreeOptions.TryGetDiagnosticValue(tree, "BC42024", CancellationToken.None, report))
Assert.Equal(ReportDiagnostic.Suppress, report)
Assert.True(syntaxTreeOptions.TryGetDiagnosticValue(tree, "warning01", report))
Assert.True(syntaxTreeOptions.TryGetDiagnosticValue(tree, "warning01", CancellationToken.None, report))
Assert.Equal(ReportDiagnostic.Suppress, report)
Assert.True(syntaxTreeOptions.TryGetDiagnosticValue(tree, "warning03", report))
Assert.True(syntaxTreeOptions.TryGetDiagnosticValue(tree, "warning03", CancellationToken.None, report))
Assert.Equal(ReportDiagnostic.Suppress, report)
Assert.False(syntaxTreeOptions.TryGetDiagnosticValue(tree, "warning02", report))
Assert.False(syntaxTreeOptions.TryGetDiagnosticValue(tree, "warning02", CancellationToken.None, report))
Dim provider = cmd.AnalyzerOptions.AnalyzerConfigOptionsProvider
Dim options = provider.GetOptions(tree)
......
......@@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis;
namespace Roslyn.Utilities
......@@ -50,12 +51,13 @@ public sealed class TestSyntaxTreeOptionsProvider : SyntaxTreeOptionsProvider
);
}
public override bool? IsGenerated(SyntaxTree tree)
public override bool? IsGenerated(SyntaxTree tree, CancellationToken cancellationToken)
=> _isGenerated != null && _isGenerated.TryGetValue(tree, out var val) ? val : null;
public override bool TryGetDiagnosticValue(
SyntaxTree tree,
string diagnosticId,
CancellationToken cancellationToken,
out ReportDiagnostic severity)
{
if (_options != null &&
......
......@@ -341,17 +341,17 @@ private sealed class WorkspaceSyntaxTreeOptionsProvider : SyntaxTreeOptionsProvi
public WorkspaceSyntaxTreeOptionsProvider(ValueSource<CachingAnalyzerConfigSet> lazyAnalyzerConfigSet)
=> _lazyAnalyzerConfigSet = lazyAnalyzerConfigSet;
public override bool? IsGenerated(SyntaxTree tree)
public override bool? IsGenerated(SyntaxTree tree, CancellationToken cancellationToken)
{
var options = _lazyAnalyzerConfigSet
.GetValue(CancellationToken.None).GetOptionsForSourcePath(tree.FilePath);
.GetValue(cancellationToken).GetOptionsForSourcePath(tree.FilePath);
return GeneratedCodeUtilities.GetIsGeneratedCodeFromOptions(options.AnalyzerOptions);
}
public override bool TryGetDiagnosticValue(SyntaxTree tree, string diagnosticId, out ReportDiagnostic severity)
public override bool TryGetDiagnosticValue(SyntaxTree tree, string diagnosticId, CancellationToken cancellationToken, out ReportDiagnostic severity)
{
var options = _lazyAnalyzerConfigSet
.GetValue(CancellationToken.None).GetOptionsForSourcePath(tree.FilePath);
.GetValue(cancellationToken).GetOptionsForSourcePath(tree.FilePath);
return options.TreeOptions.TryGetValue(diagnosticId, out severity);
}
......
......@@ -298,7 +298,7 @@ public async Task WithDocumentSyntaxRoot_AnalyzerConfigWithoutFilePath()
var compilation = (await project.GetCompilationAsync())!;
var tree = compilation.SyntaxTrees.Single();
var provider = compilation.Options.SyntaxTreeOptionsProvider!;
Assert.Throws<ArgumentException>(() => provider.TryGetDiagnosticValue(tree, "CA1234", out _));
Assert.Throws<ArgumentException>(() => provider.TryGetDiagnosticValue(tree, "CA1234", CancellationToken.None, out _));
}
[Fact]
......@@ -2846,7 +2846,7 @@ public async Task TestAddingEditorConfigFileWithDiagnosticSeverity([Combinatoria
Assert.NotEqual(originalCompilation.Options, newCompilation.Options);
var provider = project.CompilationOptions.SyntaxTreeOptionsProvider;
Assert.True(provider.TryGetDiagnosticValue(newSyntaxTree, "CA1234", out var severity));
Assert.True(provider.TryGetDiagnosticValue(newSyntaxTree, "CA1234", CancellationToken.None, out var severity));
Assert.Equal(ReportDiagnostic.Error, severity);
}
......@@ -2876,7 +2876,7 @@ public async Task TestAddingAndRemovingEditorConfigFileWithDiagnosticSeverity([C
var project = solution.GetProject(projectId);
var provider = project.CompilationOptions.SyntaxTreeOptionsProvider;
Assert.True(provider.TryGetDiagnosticValue(syntaxTreeAfterAddingEditorConfig, "CA1234", out var severity));
Assert.True(provider.TryGetDiagnosticValue(syntaxTreeAfterAddingEditorConfig, "CA1234", CancellationToken.None, out var severity));
Assert.Equal(ReportDiagnostic.Error, severity);
solution = solution.RemoveAnalyzerConfigDocument(editorConfigDocumentId);
......@@ -2885,7 +2885,7 @@ public async Task TestAddingAndRemovingEditorConfigFileWithDiagnosticSeverity([C
var syntaxTreeAfterRemovingEditorConfig = await solution.GetDocument(sourceDocumentId).GetSyntaxTreeAsync();
provider = project.CompilationOptions.SyntaxTreeOptionsProvider;
Assert.False(provider.TryGetDiagnosticValue(syntaxTreeAfterAddingEditorConfig, "CA1234", out _));
Assert.False(provider.TryGetDiagnosticValue(syntaxTreeAfterAddingEditorConfig, "CA1234", CancellationToken.None, out _));
var finalCompilation = await project.GetCompilationAsync();
......@@ -2918,7 +2918,7 @@ public async Task TestChangingAnEditorConfigFile([CombinatorialValues(LanguageNa
var project = solution.GetProject(projectId);
var provider = project.CompilationOptions.SyntaxTreeOptionsProvider;
Assert.Equal(provider, (await project.GetCompilationAsync()).Options.SyntaxTreeOptionsProvider);
Assert.True(provider.TryGetDiagnosticValue(syntaxTreeBeforeEditorConfigChange, "CA1234", out var severity));
Assert.True(provider.TryGetDiagnosticValue(syntaxTreeBeforeEditorConfigChange, "CA1234", CancellationToken.None, out var severity));
Assert.Equal(ReportDiagnostic.Error, severity);
solution = solution.WithAnalyzerConfigDocumentTextLoader(
......@@ -2931,7 +2931,7 @@ public async Task TestChangingAnEditorConfigFile([CombinatorialValues(LanguageNa
project = solution.GetProject(projectId);
provider = project.CompilationOptions.SyntaxTreeOptionsProvider;
Assert.Equal(provider, (await project.GetCompilationAsync()).Options.SyntaxTreeOptionsProvider);
Assert.True(provider.TryGetDiagnosticValue(syntaxTreeBeforeEditorConfigChange, "CA6789", out severity));
Assert.True(provider.TryGetDiagnosticValue(syntaxTreeBeforeEditorConfigChange, "CA6789", CancellationToken.None, out severity));
Assert.Equal(ReportDiagnostic.Error, severity);
var finalCompilation = await project.GetCompilationAsync();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册