Context
BrilliantMessaging consumes a curated single-file export for netstandard2.0. Its generation script initially removed all JetBrains annotations, but ReSharper then reports PossibleMultipleEnumeration at every call site that applies a guard clause to an IEnumerable<T> and enumerates it afterwards:
public TopologyRuntimeHostedService(IEnumerable<ITopologyRuntime> runtimes)
{
runtimes.MustNotBeNull(); // ReSharper counts this as an enumeration
_runtimes = runtimes.ToArray();
}
Retaining [NoEnumeration] fixes this; InspectCode confirms all four occurrences in BrilliantMessaging disappear and no new issues surface. The export is therefore now generated with:
IncludeJetBrainsAnnotations true
IncludeJetBrainsAnnotationsUsing true
RemoveNoEnumeration false
RemoveContractAnnotations true
RemoveValidatedNotNull true and IncludeValidatedNotNullAttribute false
Problem
ReSharperAnnotations.cs is copied into the export wholesale — see CheckIfFileShouldBeProcessed and ShouldAlwaysProcessWholeFileInWhitelistMode in SourceFileMerger.cs. Enabling IncludeJetBrainsAnnotations to obtain a single attribute therefore also emits the other two, and with the configuration above neither of them is referenced by the generated code:
ContractAnnotationAttribute — all usages are removed by RemoveContractAnnotations.
NotNullAttribute — IncludeJetBrainsAnnotationsUsing also emits using NotNullAttribute = System.Diagnostics.CodeAnalysis.NotNullAttribute;, so every [NotNull] in the export resolves to the code-analysis attribute, not the JetBrains one.
This is harmless in practice: the types are internal, add roughly 40 lines, and produce no compiler or inspection warnings. It does however contradict the promise that a whitelisted export contains only the selected assertions and their transitive dependencies, and it forces consumers to carry dead attribute types they explicitly configured away.
Suggestion
Extend the existing reachability idea to annotation types: after the cleanup step has removed the disabled annotations, emit only those JetBrains annotation types that the generated file still references. That keeps the behavior correct for every combination of the removal flags without introducing per-attribute configuration options, and it makes IncludeJetBrainsAnnotations mean "provide the annotation types this export needs" rather than "provide all of them".
While looking at this, it is worth deciding whether the JetBrains NotNullAttribute should ever be emitted alongside the IncludeJetBrainsAnnotationsUsing alias, since the two options currently overlap.
Notes
Not urgent — BrilliantMessaging works fine with the extra types. Reported so the source export stays as deliberate as its whitelist suggests.
Context
BrilliantMessaging consumes a curated single-file export for
netstandard2.0. Its generation script initially removed all JetBrains annotations, but ReSharper then reportsPossibleMultipleEnumerationat every call site that applies a guard clause to anIEnumerable<T>and enumerates it afterwards:Retaining
[NoEnumeration]fixes this; InspectCode confirms all four occurrences in BrilliantMessaging disappear and no new issues surface. The export is therefore now generated with:IncludeJetBrainsAnnotations trueIncludeJetBrainsAnnotationsUsing trueRemoveNoEnumeration falseRemoveContractAnnotations trueRemoveValidatedNotNull trueandIncludeValidatedNotNullAttribute falseProblem
ReSharperAnnotations.csis copied into the export wholesale — seeCheckIfFileShouldBeProcessedandShouldAlwaysProcessWholeFileInWhitelistModeinSourceFileMerger.cs. EnablingIncludeJetBrainsAnnotationsto obtain a single attribute therefore also emits the other two, and with the configuration above neither of them is referenced by the generated code:ContractAnnotationAttribute— all usages are removed byRemoveContractAnnotations.NotNullAttribute—IncludeJetBrainsAnnotationsUsingalso emitsusing NotNullAttribute = System.Diagnostics.CodeAnalysis.NotNullAttribute;, so every[NotNull]in the export resolves to the code-analysis attribute, not the JetBrains one.This is harmless in practice: the types are
internal, add roughly 40 lines, and produce no compiler or inspection warnings. It does however contradict the promise that a whitelisted export contains only the selected assertions and their transitive dependencies, and it forces consumers to carry dead attribute types they explicitly configured away.Suggestion
Extend the existing reachability idea to annotation types: after the cleanup step has removed the disabled annotations, emit only those JetBrains annotation types that the generated file still references. That keeps the behavior correct for every combination of the removal flags without introducing per-attribute configuration options, and it makes
IncludeJetBrainsAnnotationsmean "provide the annotation types this export needs" rather than "provide all of them".While looking at this, it is worth deciding whether the JetBrains
NotNullAttributeshould ever be emitted alongside theIncludeJetBrainsAnnotationsUsingalias, since the two options currently overlap.Notes
Not urgent — BrilliantMessaging works fine with the extra types. Reported so the source export stays as deliberate as its whitelist suggests.