Browse Source

Annotate intentional analyzer-violations with [SuppressMessage].

Four cases where the analyzer rule conflicts with intentional design:

* EmptyList<T>.IDisposable.Dispose (CA1063) — explicit IDisposable on
  IEnumerator<T>; making it public would conflict with the rest of the
  IList<T> / IEnumerator<T> surface.
* MetadataFile.SectionHeaders (CA1065) — throw documents that this
  MetadataFileKind has no PE sections; PE-like derived kinds override.
* LongSet.GetHashCode + LongSet itself (CA1065 + CA2231) — explicit
  guards against using LongSet in hash containers / via equality
  operators; SetEquals is the supported comparison and
  IEquatable<LongSet>.Equals is itself [Obsolete].
* AnnotationList.Clone (CA2002) — AnnotationList is a private nested
  type; the surrounding Annotatable class deliberately locks on the
  AnnotationList instance to serialize annotation reads/writes, and
  external code cannot obtain a reference to it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pull/3732/head
Siegfried Pammer 4 months ago
parent
commit
784379d012
  1. 3
      ICSharpCode.Decompiler/CSharp/Syntax/IAnnotatable.cs
  2. 3
      ICSharpCode.Decompiler/Metadata/MetadataFile.cs
  3. 3
      ICSharpCode.Decompiler/Util/EmptyList.cs
  4. 5
      ICSharpCode.Decompiler/Util/LongSet.cs

3
ICSharpCode.Decompiler/CSharp/Syntax/IAnnotatable.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
@ -115,6 +116,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -115,6 +116,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{
}
[SuppressMessage("Reliability", "CA2002:Do not lock on objects with weak identity",
Justification = "AnnotationList is a private nested type — the surrounding Annotatable class deliberately locks on the AnnotationList instance to serialize annotation reads/writes; external code cannot obtain a reference to it.")]
public object Clone()
{
lock (this)

3
ICSharpCode.Decompiler/Metadata/MetadataFile.cs

@ -22,6 +22,7 @@ using System; @@ -22,6 +22,7 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
@ -285,6 +286,8 @@ namespace ICSharpCode.Decompiler.Metadata @@ -285,6 +286,8 @@ namespace ICSharpCode.Decompiler.Metadata
throw new BadImageFormatException("This metadata file does not support sections.");
}
[SuppressMessage("Design", "CA1065:Do not raise exceptions in unexpected locations",
Justification = "Throw signals that this MetadataFileKind has no PE sections; derived PE-like kinds override.")]
public virtual ImmutableArray<SectionHeader> SectionHeaders => throw new BadImageFormatException("This metadata file does not support sections.");
/// <summary>

3
ICSharpCode.Decompiler/Util/EmptyList.cs

@ -20,6 +20,7 @@ @@ -20,6 +20,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace ICSharpCode.Decompiler.Util
{
@ -99,6 +100,8 @@ namespace ICSharpCode.Decompiler.Util @@ -99,6 +100,8 @@ namespace ICSharpCode.Decompiler.Util
get { throw new NotSupportedException(); }
}
[SuppressMessage("Usage", "CA1063:Implement IDisposable Correctly",
Justification = "Explicit IDisposable implementation for IEnumerator<T>; intentional no-op for the singleton.")]
void IDisposable.Dispose()
{
}

5
ICSharpCode.Decompiler/Util/LongSet.cs

@ -21,6 +21,7 @@ using System; @@ -21,6 +21,7 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
namespace ICSharpCode.Decompiler.Util
@ -28,6 +29,8 @@ namespace ICSharpCode.Decompiler.Util @@ -28,6 +29,8 @@ namespace ICSharpCode.Decompiler.Util
/// <summary>
/// An immutable set of longs, that is implemented as a list of intervals.
/// </summary>
[SuppressMessage("Usage", "CA2231:Overload operator equals on overriding value type Equals",
Justification = "Equality on LongSet is intentionally only available via SetEquals — the IEquatable<LongSet>.Equals overload is itself [Obsolete] in favor of SetEquals.")]
public struct LongSet : IEquatable<LongSet>
{
/// <summary>
@ -362,6 +365,8 @@ namespace ICSharpCode.Decompiler.Util @@ -362,6 +365,8 @@ namespace ICSharpCode.Decompiler.Util
return obj is LongSet && SetEquals((LongSet)obj);
}
[SuppressMessage("Design", "CA1065:Do not raise exceptions in unexpected locations",
Justification = "Throw is an explicit guard against using LongSet in hash-based containers; use SetEquals for comparison.")]
public override int GetHashCode()
{
throw new NotImplementedException();

Loading…
Cancel
Save