Esempio n. 1
0
 public static DisposeAnalysisKind GetDisposeAnalysisKindOption(
     this AnalyzerOptions options,
     DiagnosticDescriptor rule,
     SyntaxTree tree,
     Compilation compilation,
     DisposeAnalysisKind defaultValue)
 => options.GetNonFlagsEnumOptionValue(EditorConfigOptionNames.DisposeAnalysisKind, rule, tree, compilation, defaultValue);
        private static void ComputeDiagnostics(
            ImmutableDictionary <AbstractLocation, DisposeAbstractValue> disposeData,
            ArrayBuilder <Diagnostic> notDisposedDiagnostics,
            ArrayBuilder <Diagnostic> mayBeNotDisposedDiagnostics,
            DisposeAnalysisResult disposeAnalysisResult,
            PointsToAnalysisResult pointsToAnalysisResult,
            DisposeAnalysisKind disposeAnalysisKind,
            bool isDisposeDataForExceptionPaths)
        {
            foreach (var kvp in disposeData)
            {
                AbstractLocation     location     = kvp.Key;
                DisposeAbstractValue disposeValue = kvp.Value;
                if (disposeValue.Kind == DisposeAbstractValueKind.NotDisposable ||
                    location.CreationOpt == null)
                {
                    continue;
                }

                var isNotDisposed = disposeValue.Kind == DisposeAbstractValueKind.NotDisposed ||
                                    (disposeValue.DisposingOrEscapingOperations.Count > 0 &&
                                     disposeValue.DisposingOrEscapingOperations.All(d => d.IsInsideCatchRegion(disposeAnalysisResult.ControlFlowGraph)));
                var isMayBeNotDisposed = !isNotDisposed && (disposeValue.Kind == DisposeAbstractValueKind.MaybeDisposed || disposeValue.Kind == DisposeAbstractValueKind.NotDisposedOrEscaped);

                if (isNotDisposed ||
                    (isMayBeNotDisposed && disposeAnalysisKind.AreMayBeNotDisposedViolationsEnabled()))
                {
                    var syntax = location.TryGetNodeToReportDiagnostic(pointsToAnalysisResult);
                    if (syntax == null)
                    {
                        continue;
                    }

                    // CA2000: Call System.IDisposable.Dispose on object created by '{0}' before all references to it are out of scope.
                    var rule       = GetRule(isNotDisposed);
                    var argument   = syntax.ToString();
                    var diagnostic = syntax.CreateDiagnostic(rule, argument);
                    if (isNotDisposed)
                    {
                        notDisposedDiagnostics.Add(diagnostic);
                    }
                    else
                    {
                        mayBeNotDisposedDiagnostics.Add(diagnostic);
                    }
                }
            }

            DiagnosticDescriptor GetRule(bool isNotDisposed)
            {
                if (isNotDisposed)
                {
                    return(isDisposeDataForExceptionPaths ? NotDisposedOnExceptionPathsRule : NotDisposedRule);
                }
                else
                {
                    return(isDisposeDataForExceptionPaths ? MayBeDisposedOnExceptionPathsRule : MayBeDisposedRule);
                }
            }
        }
 public static bool AreExceptionPathsEnabled(this DisposeAnalysisKind disposeAnalysisKind)
 {
     return(disposeAnalysisKind switch
     {
         DisposeAnalysisKind.NonExceptionPaths
         or DisposeAnalysisKind.NonExceptionPathsOnlyNotDisposed => false,
         _ => true,
     });
Esempio n. 4
0
 public static DisposeAnalysisKind GetDisposeAnalysisKindOption(
     this AnalyzerOptions options,
     DiagnosticDescriptor rule,
     ISymbol symbol,
     Compilation compilation,
     DisposeAnalysisKind defaultValue,
     CancellationToken cancellationToken)
 => options.GetDisposeAnalysisKindOption(rule, symbol.Locations[0].SourceTree, compilation, defaultValue, cancellationToken);
Esempio n. 5
0
 public static DisposeAnalysisKind GetDisposeAnalysisKindOption(
     this AnalyzerOptions options,
     DiagnosticDescriptor rule,
     ISymbol symbol,
     Compilation compilation,
     DisposeAnalysisKind defaultValue)
 => TryGetSyntaxTreeForOption(symbol, out var tree)
     ? options.GetDisposeAnalysisKindOption(rule, tree, compilation, defaultValue)
     : defaultValue;
Esempio n. 6
0
        public static bool AreMayBeNotDisposedViolationsEnabled(this DisposeAnalysisKind disposeAnalysisKind)
        {
            switch (disposeAnalysisKind)
            {
            case DisposeAnalysisKind.AllPathsOnlyNotDisposed:
            case DisposeAnalysisKind.NonExceptionPathsOnlyNotDisposed:
                return(false);

            default:
                return(true);
            }
        }
 public static DisposeAnalysisKind GetDisposeAnalysisKindOption(
     this AnalyzerOptions options,
     DiagnosticDescriptor rule,
     DisposeAnalysisKind defaultValue,
     CancellationToken cancellationToken)
 => options.GetNonFlagsEnumOptionValue(EditorConfigOptionNames.DisposeAnalysisKind, rule, defaultValue, cancellationToken);
Esempio n. 8
0
        private static void ComputeDiagnostics(
            ImmutableDictionary <AbstractLocation, DisposeAbstractValue> disposeData,
            ArrayBuilder <Diagnostic> notDisposedDiagnostics,
            ArrayBuilder <Diagnostic> mayBeNotDisposedDiagnostics,
            DisposeAnalysisResult disposeAnalysisResult,
            PointsToAnalysisResult pointsToAnalysisResult,
            DisposeAnalysisKind disposeAnalysisKind,
            bool isDisposeDataForExceptionPaths)
        {
            foreach (var kvp in disposeData)
            {
                AbstractLocation     location     = kvp.Key;
                DisposeAbstractValue disposeValue = kvp.Value;
                if (disposeValue.Kind == DisposeAbstractValueKind.NotDisposable ||
                    location.Creation == null)
                {
                    continue;
                }

                var isNotDisposed = disposeValue.Kind == DisposeAbstractValueKind.NotDisposed ||
                                    (!disposeValue.DisposingOrEscapingOperations.IsEmpty &&
                                     disposeValue.DisposingOrEscapingOperations.All(d => d.IsInsideCatchRegion(disposeAnalysisResult.ControlFlowGraph) && !location.GetTopOfCreationCallStackOrCreation().IsInsideCatchRegion(disposeAnalysisResult.ControlFlowGraph)));
                var isMayBeNotDisposed = !isNotDisposed && (disposeValue.Kind == DisposeAbstractValueKind.MaybeDisposed || disposeValue.Kind == DisposeAbstractValueKind.NotDisposedOrEscaped);

                if (isNotDisposed ||
                    (isMayBeNotDisposed && disposeAnalysisKind.AreMayBeNotDisposedViolationsEnabled()))
                {
                    var syntax = location.TryGetNodeToReportDiagnostic(pointsToAnalysisResult);
                    if (syntax == null)
                    {
                        continue;
                    }

                    // CA2000: Call System.IDisposable.Dispose on object created by '{0}' before all references to it are out of scope.
                    var rule = GetRule(isNotDisposed);

                    // Ensure that we do not include multiple lines for the object creation expression in the diagnostic message.
                    var argument       = syntax.ToString();
                    var indexOfNewLine = argument.IndexOf(Environment.NewLine, StringComparison.Ordinal);
                    if (indexOfNewLine > 0)
                    {
                        argument = argument.Substring(0, indexOfNewLine);
                    }

                    var diagnostic = syntax.CreateDiagnostic(rule, argument);
                    if (isNotDisposed)
                    {
                        notDisposedDiagnostics.Add(diagnostic);
                    }
                    else
                    {
                        mayBeNotDisposedDiagnostics.Add(diagnostic);
                    }
                }
            }

            DiagnosticDescriptor GetRule(bool isNotDisposed)
            {
                if (isNotDisposed)
                {
                    return(isDisposeDataForExceptionPaths ? NotDisposedOnExceptionPathsRule : NotDisposedRule);
                }
                else
                {
                    return(isDisposeDataForExceptionPaths ? MayBeDisposedOnExceptionPathsRule : MayBeDisposedRule);
                }
            }
        }
Esempio n. 9
0
 public static bool AreExceptionPathsAndMayBeNotDisposedViolationsEnabled(this DisposeAnalysisKind disposeAnalysisKind)
 => disposeAnalysisKind.AreExceptionPathsEnabled() && disposeAnalysisKind.AreMayBeNotDisposedViolationsEnabled();