diff --git a/eng/Versions.props b/eng/Versions.props
index 1546badd1132137f782fd4ce7bd774f60609ec09..c08e4d5cbe73637bd129cc16b98d8e5e71652ae1 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -47,7 +47,7 @@
2.0.17
$(MicrosoftCodeAnalysisTestingVersion)
$(CodeStyleAnalyzerVersion)
- 2.9.3-beta1.19271.2+23ca1e2d
+ 2.9.3-beta1.19301.2+4c8365b9
$(RoslynDiagnosticsNugetPackageVersion)
1.0.31
4.3.0
diff --git a/src/EditorFeatures/VisualBasicTest/DisposeAnalysis/DisposeObjectsBeforeLosingScopeTests.vb b/src/EditorFeatures/VisualBasicTest/DisposeAnalysis/DisposeObjectsBeforeLosingScopeTests.vb
index 6f714a05ee5321a1b28e5b6f85a33c0cbaff52c2..625006b5ddb6ee6047e016b43c5daa3c4b14298a 100644
--- a/src/EditorFeatures/VisualBasicTest/DisposeAnalysis/DisposeObjectsBeforeLosingScopeTests.vb
+++ b/src/EditorFeatures/VisualBasicTest/DisposeAnalysis/DisposeObjectsBeforeLosingScopeTests.vb
@@ -1943,8 +1943,8 @@ End Module")
End Function
- Public Async Function DisposableCreationNotAssignedToAVariable_Diagnostic() As Task
- Await TestDiagnosticsAsync(
+ Public Async Function DisposableCreationNotAssignedToAVariable_BailOut_NoDiagnostic() As Task
+ Await TestDiagnosticMissingAsync(
"Imports System
Class A
@@ -1967,8 +1967,7 @@ Class Test
New A(2).M() ' Error
Dim x = New A(3).X
End Sub|]
-End Class",
- Diagnostic(IDEDiagnosticIds.DisposeObjectsBeforeLosingScopeDiagnosticId, "New A(3)").WithLocation(21, 17))
+End Class")
End Function
diff --git a/src/Features/Core/Portable/DisposeAnalysis/DisposableFieldsShouldBeDisposedDiagnosticAnalyzer.cs b/src/Features/Core/Portable/DisposeAnalysis/DisposableFieldsShouldBeDisposedDiagnosticAnalyzer.cs
index c780f3f50c6079e7829b8b79254a88a1948f0a59..c29948d0916de57c73cfee4585ad5fb9f9ef2a14 100644
--- a/src/Features/Core/Portable/DisposeAnalysis/DisposableFieldsShouldBeDisposedDiagnosticAnalyzer.cs
+++ b/src/Features/Core/Portable/DisposeAnalysis/DisposableFieldsShouldBeDisposedDiagnosticAnalyzer.cs
@@ -55,6 +55,7 @@ private sealed class SymbolAnalyzer
private readonly ImmutableHashSet _disposableFields;
private readonly ConcurrentDictionary _fieldDisposeValueMap;
private readonly DisposeAnalysisHelper _disposeAnalysisHelper;
+ private bool _hasErrors;
public SymbolAnalyzer(ImmutableHashSet disposableFields, DisposeAnalysisHelper disposeAnalysisHelper)
{
@@ -110,6 +111,11 @@ private void AddOrUpdateFieldDisposedValue(IFieldSymbol field, bool disposed)
private void OnSymbolEnd(SymbolAnalysisContext symbolEndContext)
{
+ if (_hasErrors)
+ {
+ return;
+ }
+
foreach (var kvp in _fieldDisposeValueMap)
{
IFieldSymbol field = kvp.Key;
@@ -126,6 +132,13 @@ private void OnSymbolEnd(SymbolAnalysisContext symbolEndContext)
[MethodImpl(MethodImplOptions.NoInlining)]
private void OnOperationBlockStart(OperationBlockStartAnalysisContext operationBlockStartContext)
{
+ if (_hasErrors)
+ {
+ return;
+ }
+
+ operationBlockStartContext.RegisterOperationAction(_ => _hasErrors = true, OperationKind.Invalid);
+
switch (operationBlockStartContext.OwningSymbol)
{
case IFieldSymbol _:
@@ -182,7 +195,8 @@ void AnalyzeFieldReference(OperationAnalysisContext operationContext)
// Check if this is a Disposable field that is not currently being tracked.
if (_fieldDisposeValueMap.ContainsKey(field) ||
- !_disposableFields.Contains(field))
+ !_disposableFields.Contains(field) ||
+ _hasErrors)
{
return;
}
@@ -209,6 +223,11 @@ void AnalyzeFieldReference(OperationAnalysisContext operationContext)
{
Interlocked.CompareExchange(ref lazyPointsToAnalysisResult, pointsToAnalysisResult, null);
}
+ else
+ {
+ _hasErrors = true;
+ return;
+ }
}
PointsToAbstractValue assignedPointsToValue = lazyPointsToAnalysisResult[simpleAssignmentOperation.Value.Kind, simpleAssignmentOperation.Value.Syntax];
@@ -225,6 +244,11 @@ void AnalyzeFieldReference(OperationAnalysisContext operationContext)
void AnalyzeDisposeMethod()
{
+ if (_hasErrors)
+ {
+ return;
+ }
+
// Perform dataflow analysis to compute dispose value of disposable fields at the end of dispose method.
if (_disposeAnalysisHelper.TryGetOrComputeResult(operationBlockStartContext, containingMethod,
s_disposableFieldsShouldBeDisposedRule, trackInstanceFields: true,
@@ -268,6 +292,10 @@ void AnalyzeDisposeMethod()
}
}
}
+ else
+ {
+ _hasErrors = true;
+ }
}
}
}
diff --git a/src/Features/Core/Portable/DisposeAnalysis/DisposeAnalysisHelper.cs b/src/Features/Core/Portable/DisposeAnalysis/DisposeAnalysisHelper.cs
index 92e4ab753599ce2d537945fadc9af3e58224e987..b01d9a7c74af8f4ad57d88c8d54d50d5b3521831 100644
--- a/src/Features/Core/Portable/DisposeAnalysis/DisposeAnalysisHelper.cs
+++ b/src/Features/Core/Portable/DisposeAnalysis/DisposeAnalysisHelper.cs
@@ -109,12 +109,15 @@ private void EnsureDisposableFieldsMap()
if (cfg != null)
{
var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(context.Compilation);
- disposeAnalysisResult = FlowAnalysis.DataFlow.DisposeAnalysis.DisposeAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider,
+ disposeAnalysisResult = FlowAnalysis.DataFlow.DisposeAnalysis.DisposeAnalysis.TryGetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider,
context.Options, rule, _disposeOwnershipTransferLikelyTypes, trackInstanceFields,
exceptionPathsAnalysis: false, context.CancellationToken, out pointsToAnalysisResult,
interproceduralAnalysisPredicateOpt: interproceduralAnalysisPredicateOpt,
defaultDisposeOwnershipTransferAtConstructor: true);
- return true;
+ if (disposeAnalysisResult != null)
+ {
+ return true;
+ }
}
}
@@ -140,12 +143,15 @@ private void EnsureDisposableFieldsMap()
if (cfg != null)
{
var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(context.Compilation);
- disposeAnalysisResult = FlowAnalysis.DataFlow.DisposeAnalysis.DisposeAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider,
+ disposeAnalysisResult = FlowAnalysis.DataFlow.DisposeAnalysis.DisposeAnalysis.TryGetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider,
context.Options, rule, _disposeOwnershipTransferLikelyTypes, trackInstanceFields,
exceptionPathsAnalysis: false, context.CancellationToken, out pointsToAnalysisResult,
interproceduralAnalysisPredicateOpt: interproceduralAnalysisPredicateOpt,
defaultDisposeOwnershipTransferAtConstructor: true);
- return true;
+ if (disposeAnalysisResult != null)
+ {
+ return true;
+ }
}
}
diff --git a/src/Features/Core/Portable/Microsoft.CodeAnalysis.Features.csproj b/src/Features/Core/Portable/Microsoft.CodeAnalysis.Features.csproj
index baeafaa817c1237f3b05b82de8f31cb8f75b6506..b742add2a28cfc794f8b50b257b51ed2c733781d 100644
--- a/src/Features/Core/Portable/Microsoft.CodeAnalysis.Features.csproj
+++ b/src/Features/Core/Portable/Microsoft.CodeAnalysis.Features.csproj
@@ -125,7 +125,7 @@
-
+
diff --git a/src/Setup/DevDivInsertionFiles/DevDivInsertionFiles.csproj b/src/Setup/DevDivInsertionFiles/DevDivInsertionFiles.csproj
index e4b990e07b2a2a9cdf42371ae69c5f6dedf71b08..63fa023b81887f05ec498f3e16ca5acf7db0d8b4 100644
--- a/src/Setup/DevDivInsertionFiles/DevDivInsertionFiles.csproj
+++ b/src/Setup/DevDivInsertionFiles/DevDivInsertionFiles.csproj
@@ -48,6 +48,7 @@
-->
+