From d75fbf50bf6a331acbf10434de66176c27b27767 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 5 Aug 2024 08:32:17 -0700 Subject: [PATCH] Clean up DiagnosticContext (#105848) Removes an overload from `DiagnosticContext` that makes it possible to pass in a `Diagnostic`. This overload is undesirable because we want the `Location` stored in `DiagnosticContext` to always match the location of the diagnostic. --- .../Compiler/Dataflow/DiagnosticContext.cs | 2 +- .../RequiresAssemblyFilesCodeFixProvider.cs | 2 +- ...RequiresUnreferencedCodeCodeFixProvider.cs | 2 +- .../DataFlow/FeatureChecksVisitor.cs | 4 +- .../DataFlowAnalyzerContext.cs | 2 +- .../DynamicallyAccessedMembersAnalyzer.cs | 2 +- .../RequiresAnalyzerBase.cs | 50 ++++++++----------- .../RequiresAssemblyFilesAnalyzer.cs | 10 ++-- .../RequiresDynamicCodeAnalyzer.cs | 2 + .../RequiresUnreferencedCodeAnalyzer.cs | 6 +-- .../TrimAnalysis/DiagnosticContext.cs | 10 +--- .../FeatureCheckReturnValuePattern.cs | 2 +- .../TrimAnalysis/ReflectionAccessAnalyzer.cs | 11 ++-- .../TrimAnalysisAssignmentPattern.cs | 2 +- .../TrimAnalysisFieldAccessPattern.cs | 9 ++-- ...TrimAnalysisGenericInstantiationPattern.cs | 2 +- .../TrimAnalysisMethodCallPattern.cs | 9 ++-- .../TrimAnalysis/TrimAnalysisPatternStore.cs | 6 +-- .../TrimAnalysisReflectionAccessPattern.cs | 12 ++--- .../TrimAnalysis/TrimAnalysisVisitor.cs | 2 +- .../TrimAnalysis/TrimDataFlowAnalysis.cs | 2 +- .../TrimAnalysis/DiagnosticContext.cs | 2 +- .../src/linker/CompatibilitySuppressions.xml | 6 +++ .../Linker.Dataflow/DiagnosticContext.cs | 2 +- 24 files changed, 69 insertions(+), 90 deletions(-) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/DiagnosticContext.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/DiagnosticContext.cs index 32db4d14b01a5..146e49ab747c7 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/DiagnosticContext.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/DiagnosticContext.cs @@ -8,7 +8,7 @@ namespace ILLink.Shared.TrimAnalysis { - internal readonly partial struct DiagnosticContext + public readonly partial struct DiagnosticContext { public readonly MessageOrigin Origin; private readonly bool _diagnosticsEnabled; diff --git a/src/tools/illink/src/ILLink.CodeFix/RequiresAssemblyFilesCodeFixProvider.cs b/src/tools/illink/src/ILLink.CodeFix/RequiresAssemblyFilesCodeFixProvider.cs index f55258251b660..844896aefc444 100644 --- a/src/tools/illink/src/ILLink.CodeFix/RequiresAssemblyFilesCodeFixProvider.cs +++ b/src/tools/illink/src/ILLink.CodeFix/RequiresAssemblyFilesCodeFixProvider.cs @@ -15,7 +15,7 @@ namespace ILLink.CodeFix { [ExportCodeFixProvider (LanguageNames.CSharp, Name = nameof (RequiresAssemblyFilesCodeFixProvider)), Shared] - public class RequiresAssemblyFilesCodeFixProvider : BaseAttributeCodeFixProvider + public sealed class RequiresAssemblyFilesCodeFixProvider : BaseAttributeCodeFixProvider { public static ImmutableArray SupportedDiagnostics => ImmutableArray.Create ( DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.AvoidAssemblyLocationInSingleFile), diff --git a/src/tools/illink/src/ILLink.CodeFix/RequiresUnreferencedCodeCodeFixProvider.cs b/src/tools/illink/src/ILLink.CodeFix/RequiresUnreferencedCodeCodeFixProvider.cs index 4fe9096839996..d3a93a0274a5b 100644 --- a/src/tools/illink/src/ILLink.CodeFix/RequiresUnreferencedCodeCodeFixProvider.cs +++ b/src/tools/illink/src/ILLink.CodeFix/RequiresUnreferencedCodeCodeFixProvider.cs @@ -15,7 +15,7 @@ namespace ILLink.CodeFix { [ExportCodeFixProvider (LanguageNames.CSharp, Name = nameof (RequiresUnreferencedCodeCodeFixProvider)), Shared] - public class RequiresUnreferencedCodeCodeFixProvider : BaseAttributeCodeFixProvider + public sealed class RequiresUnreferencedCodeCodeFixProvider : BaseAttributeCodeFixProvider { public static ImmutableArray SupportedDiagnostics => ImmutableArray.Create (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.RequiresUnreferencedCode)); diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/FeatureChecksVisitor.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/FeatureChecksVisitor.cs index 6a927f74fd15b..f037ffdc6cde0 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/FeatureChecksVisitor.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/FeatureChecksVisitor.cs @@ -24,7 +24,7 @@ namespace ILLink.RoslynAnalyzer.DataFlow // (a set features that are checked to be enabled or disabled). // The visitor takes a LocalDataFlowState as an argument, allowing for checks that // depend on the current dataflow state. - public class FeatureChecksVisitor : OperationVisitor + internal sealed class FeatureChecksVisitor : OperationVisitor { DataFlowAnalyzerContext _dataFlowAnalyzerContext; @@ -77,7 +77,7 @@ public override FeatureChecksValue VisitLiteral (ILiteralOperation operation, St return FeatureChecksValue.None; } - public bool? GetLiteralBool (IOperation operation) + public static bool? GetLiteralBool (IOperation operation) { if (operation is not ILiteralOperation literal) return null; diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlowAnalyzerContext.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlowAnalyzerContext.cs index 406992551a60c..8cfd88693c029 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlowAnalyzerContext.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlowAnalyzerContext.cs @@ -8,7 +8,7 @@ namespace ILLink.RoslynAnalyzer { - public readonly struct DataFlowAnalyzerContext + internal readonly struct DataFlowAnalyzerContext { private readonly Dictionary> _enabledAnalyzers; diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs index 43eb4c95152f4..c407ac62c4b25 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs @@ -15,7 +15,7 @@ namespace ILLink.RoslynAnalyzer { [DiagnosticAnalyzer (LanguageNames.CSharp)] - public class DynamicallyAccessedMembersAnalyzer : DiagnosticAnalyzer + public sealed class DynamicallyAccessedMembersAnalyzer : DiagnosticAnalyzer { internal const string DynamicallyAccessedMembers = nameof (DynamicallyAccessedMembers); internal const string DynamicallyAccessedMembersAttribute = nameof (DynamicallyAccessedMembersAttribute); diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs index b104fc7dd8ead..87852fc54cd68 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs @@ -8,6 +8,7 @@ using ILLink.RoslynAnalyzer.DataFlow; using ILLink.Shared; using ILLink.Shared.DataFlow; +using ILLink.Shared.TrimAnalysis; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -27,6 +28,8 @@ public abstract class RequiresAnalyzerBase : DiagnosticAnalyzer private protected abstract DiagnosticDescriptor RequiresDiagnosticRule { get; } + private protected abstract DiagnosticId RequiresDiagnosticId { get; } + private protected abstract DiagnosticDescriptor RequiresAttributeMismatch { get; } private protected abstract DiagnosticDescriptor RequiresOnStaticCtor { get; } @@ -144,33 +147,30 @@ void CheckMatchingAttributesInInterfaces ( }); } - public bool CheckAndCreateRequiresDiagnostic ( - IOperation operation, + internal void CheckAndCreateRequiresDiagnostic ( ISymbol member, ISymbol containingSymbol, ImmutableArray incompatibleMembers, - [NotNullWhen (true)] out Diagnostic? diagnostic) + in DiagnosticContext diagnosticContext) { - diagnostic = null; // Do not emit any diagnostic if caller is annotated with the attribute too. if (containingSymbol.IsInRequiresScope (RequiresAttributeName, out _)) - return false; + return; - if (CreateSpecialIncompatibleMembersDiagnostic (operation, incompatibleMembers, member, out diagnostic)) - return diagnostic != null; + if (CreateSpecialIncompatibleMembersDiagnostic (incompatibleMembers, member, diagnosticContext)) + return; // Warn on the most derived base method taking into account covariant returns while (member is IMethodSymbol method && method.OverriddenMethod != null && SymbolEqualityComparer.Default.Equals (method.ReturnType, method.OverriddenMethod.ReturnType)) member = method.OverriddenMethod; if (!member.DoesMemberRequire (RequiresAttributeName, out var requiresAttribute)) - return false; + return; if (!VerifyAttributeArguments (requiresAttribute)) - return false; + return; - diagnostic = CreateRequiresDiagnostic (operation, member, requiresAttribute); - return true; + CreateRequiresDiagnostic (member, requiresAttribute, diagnosticContext); } [Flags] @@ -223,16 +223,11 @@ protected static ISymbol FindContainingSymbol (OperationAnalysisContext operatio /// Analyzer operation context to be able to report the diagnostic. /// Information about the member that generated the diagnostic. /// Requires attribute data to print attribute arguments. - private Diagnostic CreateRequiresDiagnostic (IOperation operation, ISymbol member, AttributeData requiresAttribute) + private void CreateRequiresDiagnostic (ISymbol member, AttributeData requiresAttribute, in DiagnosticContext diagnosticContext) { var message = GetMessageFromAttribute (requiresAttribute); var url = GetUrlFromAttribute (requiresAttribute); - return Diagnostic.Create ( - RequiresDiagnosticRule, - operation.Syntax.GetLocation (), - member.GetDisplayName (), - message, - url); + diagnosticContext.AddDiagnostic (RequiresDiagnosticId, member.GetDisplayName (), message, url); } private void ReportRequiresOnStaticCtorDiagnostic (SymbolAnalysisContext symbolAnalysisContext, IMethodSymbol ctor) @@ -285,12 +280,10 @@ public static string GetUrlFromAttribute (AttributeData? requiresAttribute) /// Member to compare. /// True if the function generated a diagnostic; otherwise, returns false protected virtual bool CreateSpecialIncompatibleMembersDiagnostic ( - IOperation operation, ImmutableArray specialIncompatibleMembers, ISymbol member, - out Diagnostic? incompatibleMembersDiagnostic) + in DiagnosticContext diagnosticContext) { - incompatibleMembersDiagnostic = null; return false; } @@ -333,29 +326,26 @@ internal bool IsFeatureGuard (IPropertySymbol propertySymbol, Compilation compil || IsRequiresCheck (propertySymbol, compilation); } - internal bool CheckAndCreateRequiresDiagnostic ( + internal void CheckAndCreateRequiresDiagnostic ( IOperation operation, ISymbol member, ISymbol owningSymbol, DataFlowAnalyzerContext context, FeatureContext featureContext, - [NotNullWhen (true)] out Diagnostic? diagnostic) + in DiagnosticContext diagnosticContext) { // Warnings are not emitted if the featureContext says the feature is available. - if (featureContext.IsEnabled (RequiresAttributeFullyQualifiedName)) { - diagnostic = null; - return false; - } + if (featureContext.IsEnabled (RequiresAttributeFullyQualifiedName)) + return; ISymbol containingSymbol = operation.FindContainingSymbol (owningSymbol); var incompatibleMembers = context.GetSpecialIncompatibleMembers (this); - return CheckAndCreateRequiresDiagnostic ( - operation, + CheckAndCreateRequiresDiagnostic ( member, containingSymbol, incompatibleMembers, - out diagnostic); + diagnosticContext); } internal virtual bool IsIntrinsicallyHandled ( diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAssemblyFilesAnalyzer.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAssemblyFilesAnalyzer.cs index d3331d1137437..99aa5b0e7f58c 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAssemblyFilesAnalyzer.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAssemblyFilesAnalyzer.cs @@ -42,6 +42,8 @@ public sealed class RequiresAssemblyFilesAnalyzer : RequiresAnalyzerBase private protected override DiagnosticDescriptor RequiresDiagnosticRule => s_requiresAssemblyFilesRule; + private protected override DiagnosticId RequiresDiagnosticId => DiagnosticId.RequiresAssemblyFiles; + private protected override DiagnosticDescriptor RequiresAttributeMismatch => s_requiresAssemblyFilesAttributeMismatch; private protected override DiagnosticDescriptor RequiresOnStaticCtor => s_requiresAssemblyFilesOnStaticCtor; @@ -98,20 +100,18 @@ internal override ImmutableArray GetSpecialIncompatibleMembers (Compila } protected override bool CreateSpecialIncompatibleMembersDiagnostic ( - IOperation operation, ImmutableArray dangerousPatterns, ISymbol member, - out Diagnostic? diagnostic) + in DiagnosticContext diagnosticContext) { - diagnostic = null; if (member is IMethodSymbol method) { if (ImmutableArrayOperations.Contains (dangerousPatterns, member, SymbolEqualityComparer.Default)) { - diagnostic = Diagnostic.Create (s_getFilesRule, operation.Syntax.GetLocation (), member.GetDisplayName ()); + diagnosticContext.AddDiagnostic (DiagnosticId.AvoidAssemblyGetFilesInSingleFile, member.GetDisplayName ()); return true; } else if (method.AssociatedSymbol is ISymbol associatedSymbol && ImmutableArrayOperations.Contains (dangerousPatterns, associatedSymbol, SymbolEqualityComparer.Default)) { - diagnostic = Diagnostic.Create (s_locationRule, operation.Syntax.GetLocation (), member.GetDisplayName ()); + diagnosticContext.AddDiagnostic (DiagnosticId.AvoidAssemblyLocationInSingleFile, member.GetDisplayName ()); // The getters for CodeBase and EscapedCodeBase have RAF attribute on them // so our caller will produce the RAF warning (IL3002) by default. Since we handle these properties specifically // here and produce different warning (IL3000) we don't want the caller to produce IL3002. diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresDynamicCodeAnalyzer.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresDynamicCodeAnalyzer.cs index d84891678706f..bf10fde55a0aa 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresDynamicCodeAnalyzer.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresDynamicCodeAnalyzer.cs @@ -34,6 +34,8 @@ public sealed class RequiresDynamicCodeAnalyzer : RequiresAnalyzerBase private protected override DiagnosticDescriptor RequiresDiagnosticRule => s_requiresDynamicCodeRule; + private protected override DiagnosticId RequiresDiagnosticId => DiagnosticId.RequiresDynamicCode; + private protected override DiagnosticDescriptor RequiresAttributeMismatch => s_requiresDynamicCodeAttributeMismatch; private protected override DiagnosticDescriptor RequiresOnStaticCtor => s_requiresDynamicCodeOnStaticCtor; diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs index 69c38629c43e1..b39d7b22c8ba1 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs @@ -55,6 +55,8 @@ private Action typeDerivesFromRucBase { private protected override DiagnosticDescriptor RequiresDiagnosticRule => s_requiresUnreferencedCodeRule; + private protected override DiagnosticId RequiresDiagnosticId => DiagnosticId.RequiresUnreferencedCode; + private protected override DiagnosticDescriptor RequiresAttributeMismatch => s_requiresUnreferencedCodeAttributeMismatch; private protected override DiagnosticDescriptor RequiresOnStaticCtor => s_requiresUnreferencedCodeOnStaticCtor; @@ -78,12 +80,10 @@ private protected override bool IsRequiresCheck (IPropertySymbol propertySymbol, } protected override bool CreateSpecialIncompatibleMembersDiagnostic ( - IOperation operation, ImmutableArray specialIncompatibleMembers, ISymbol member, - out Diagnostic? incompatibleMembersDiagnostic) + in DiagnosticContext diagnosticContext) { - incompatibleMembersDiagnostic = null; // Some RUC-annotated APIs are intrinsically handled by the trimmer if (member is IMethodSymbol method && Intrinsics.GetIntrinsicIdForMethod (new MethodProxy (method)) != IntrinsicId.None) { return true; diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/DiagnosticContext.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/DiagnosticContext.cs index f292252c160b6..b59ebf3749a51 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/DiagnosticContext.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/DiagnosticContext.cs @@ -10,7 +10,7 @@ namespace ILLink.Shared.TrimAnalysis { - internal readonly partial struct DiagnosticContext + public readonly partial struct DiagnosticContext { public List Diagnostics { get; } = new (); @@ -28,14 +28,6 @@ public Diagnostic CreateDiagnostic (DiagnosticId id, params string[] args) return Diagnostic.Create (DiagnosticDescriptors.GetDiagnosticDescriptor (id), Location, args); } - public void AddDiagnostic (Diagnostic diagnostic) - { - if (Location == null) - return; - - Diagnostics.Add (diagnostic); - } - public partial void AddDiagnostic (DiagnosticId id, params string[] args) { if (Location == null) diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/FeatureCheckReturnValuePattern.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/FeatureCheckReturnValuePattern.cs index fe81dbb79ec39..c9d9bd6bd218f 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/FeatureCheckReturnValuePattern.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/FeatureCheckReturnValuePattern.cs @@ -10,7 +10,7 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis { - public readonly record struct FeatureCheckReturnValuePattern + internal readonly record struct FeatureCheckReturnValuePattern { public FeatureChecksValue ReturnValue { get; init; } public ValueSet FeatureCheckAnnotations { get; init; } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ReflectionAccessAnalyzer.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ReflectionAccessAnalyzer.cs index b36f4eb97789b..6fd225bdbe31b 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ReflectionAccessAnalyzer.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ReflectionAccessAnalyzer.cs @@ -85,20 +85,19 @@ internal static void GetReflectionAccessDiagnosticsForMethod (in DiagnosticConte if (methodSymbol.IsInRequiresUnreferencedCodeAttributeScope (out var requiresUnreferencedCodeAttributeData)) { ReportRequiresUnreferencedCodeDiagnostic (diagnosticContext, requiresUnreferencedCodeAttributeData, methodSymbol); } else { - foreach (var diagnostic in GetDiagnosticsForReflectionAccessToDAMOnMethod (diagnosticContext, methodSymbol)) - diagnosticContext.AddDiagnostic (diagnostic); + GetDiagnosticsForReflectionAccessToDAMOnMethod (diagnosticContext, methodSymbol); } } - internal static IEnumerable GetDiagnosticsForReflectionAccessToDAMOnMethod (DiagnosticContext diagnosticContext, IMethodSymbol methodSymbol) + internal static void GetDiagnosticsForReflectionAccessToDAMOnMethod (DiagnosticContext diagnosticContext, IMethodSymbol methodSymbol) { if (methodSymbol.IsVirtual && FlowAnnotations.GetMethodReturnValueAnnotation (methodSymbol) != DynamicallyAccessedMemberTypes.None) { - yield return diagnosticContext.CreateDiagnostic (DiagnosticId.DynamicallyAccessedMembersMethodAccessedViaReflection, methodSymbol.GetDisplayName ()); + diagnosticContext.AddDiagnostic (DiagnosticId.DynamicallyAccessedMembersMethodAccessedViaReflection, methodSymbol.GetDisplayName ()); } else { foreach (var parameter in methodSymbol.GetParameters ()) { if (FlowAnnotations.GetMethodParameterAnnotation (parameter) != DynamicallyAccessedMemberTypes.None) { - yield return diagnosticContext.CreateDiagnostic (DiagnosticId.DynamicallyAccessedMembersMethodAccessedViaReflection, methodSymbol.GetDisplayName ()); - yield break; + diagnosticContext.AddDiagnostic (DiagnosticId.DynamicallyAccessedMembersMethodAccessedViaReflection, methodSymbol.GetDisplayName ()); + break; } } } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisAssignmentPattern.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisAssignmentPattern.cs index 2ffcbc43ae884..3517ee4ddc5a2 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisAssignmentPattern.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisAssignmentPattern.cs @@ -15,7 +15,7 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis { - public readonly record struct TrimAnalysisAssignmentPattern + internal readonly record struct TrimAnalysisAssignmentPattern { public MultiValue Source { get; init; } public MultiValue Target { get; init; } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisFieldAccessPattern.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisFieldAccessPattern.cs index 61a925bef7e33..a9037e95d1a1c 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisFieldAccessPattern.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisFieldAccessPattern.cs @@ -11,7 +11,7 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis { - public readonly record struct TrimAnalysisFieldAccessPattern + internal readonly record struct TrimAnalysisFieldAccessPattern { public IFieldSymbol Field { get; init; } public IFieldReferenceOperation Operation { get; init; } @@ -31,7 +31,6 @@ public TrimAnalysisFieldAccessPattern ( } public TrimAnalysisFieldAccessPattern Merge ( - ValueSetLattice lattice, FeatureContextLattice featureContextLattice, TrimAnalysisFieldAccessPattern other) { @@ -49,10 +48,8 @@ public TrimAnalysisFieldAccessPattern Merge ( public IEnumerable CollectDiagnostics (DataFlowAnalyzerContext context) { DiagnosticContext diagnosticContext = new (Operation.Syntax.GetLocation ()); - foreach (var requiresAnalyzer in context.EnabledRequiresAnalyzers) { - if (requiresAnalyzer.CheckAndCreateRequiresDiagnostic (Operation, Field, OwningSymbol, context, FeatureContext, out Diagnostic? diag)) - diagnosticContext.AddDiagnostic (diag); - } + foreach (var requiresAnalyzer in context.EnabledRequiresAnalyzers) + requiresAnalyzer.CheckAndCreateRequiresDiagnostic (Operation, Field, OwningSymbol, context, FeatureContext, in diagnosticContext); return diagnosticContext.Diagnostics; } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisGenericInstantiationPattern.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisGenericInstantiationPattern.cs index 26f275085fa8b..82d48c54618f8 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisGenericInstantiationPattern.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisGenericInstantiationPattern.cs @@ -9,7 +9,7 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis { - public readonly record struct TrimAnalysisGenericInstantiationPattern + internal readonly record struct TrimAnalysisGenericInstantiationPattern { public ISymbol GenericInstantiation { get; init; } public IOperation Operation { get; init; } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisMethodCallPattern.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisMethodCallPattern.cs index 845ac7e884a91..09fc7d80458e5 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisMethodCallPattern.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisMethodCallPattern.cs @@ -15,7 +15,7 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis { - public readonly record struct TrimAnalysisMethodCallPattern + internal readonly record struct TrimAnalysisMethodCallPattern { public IMethodSymbol CalledMethod { get; init; } public MultiValue Instance { get; init; } @@ -84,11 +84,8 @@ public IEnumerable CollectDiagnostics (DataFlowAnalyzerContext conte foreach (var requiresAnalyzer in context.EnabledRequiresAnalyzers) { - if (requiresAnalyzer.CheckAndCreateRequiresDiagnostic (Operation, CalledMethod, OwningSymbol, context, FeatureContext, out Diagnostic? diag) - && !requiresAnalyzer.IsIntrinsicallyHandled (CalledMethod, Instance, Arguments)) - { - diagnosticContext.AddDiagnostic (diag); - } + if (!requiresAnalyzer.IsIntrinsicallyHandled (CalledMethod, Instance, Arguments)) + requiresAnalyzer.CheckAndCreateRequiresDiagnostic (Operation, CalledMethod, OwningSymbol, context, FeatureContext, in diagnosticContext); } return diagnosticContext.Diagnostics; diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisPatternStore.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisPatternStore.cs index dd66d802934be..17f2e755f9083 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisPatternStore.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisPatternStore.cs @@ -10,7 +10,7 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis { - public readonly struct TrimAnalysisPatternStore + internal readonly struct TrimAnalysisPatternStore { readonly Dictionary<(IOperation, bool), TrimAnalysisAssignmentPattern> AssignmentPatterns; readonly Dictionary FieldAccessPatterns; @@ -60,7 +60,7 @@ public void Add (TrimAnalysisFieldAccessPattern pattern) return; } - FieldAccessPatterns[pattern.Operation] = pattern.Merge (Lattice, FeatureContextLattice, existingPattern); + FieldAccessPatterns[pattern.Operation] = pattern.Merge (FeatureContextLattice, existingPattern); } public void Add (TrimAnalysisGenericInstantiationPattern pattern) @@ -90,7 +90,7 @@ public void Add (TrimAnalysisReflectionAccessPattern pattern) return; } - ReflectionAccessPatterns[pattern.Operation] = pattern.Merge (Lattice, FeatureContextLattice, existingPattern); + ReflectionAccessPatterns[pattern.Operation] = pattern.Merge (FeatureContextLattice, existingPattern); } public void Add (FeatureCheckReturnValuePattern pattern) diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisReflectionAccessPattern.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisReflectionAccessPattern.cs index 85897420596f4..b599d79270d63 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisReflectionAccessPattern.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisReflectionAccessPattern.cs @@ -10,7 +10,7 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis { - public readonly record struct TrimAnalysisReflectionAccessPattern + internal readonly record struct TrimAnalysisReflectionAccessPattern { public IMethodSymbol ReferencedMethod { get; init; } public IOperation Operation { get; init; } @@ -30,7 +30,6 @@ public TrimAnalysisReflectionAccessPattern ( } public TrimAnalysisReflectionAccessPattern Merge ( - ValueSetLattice lattice, FeatureContextLattice featureContextLattice, TrimAnalysisReflectionAccessPattern other) { @@ -51,14 +50,11 @@ public IEnumerable CollectDiagnostics (DataFlowAnalyzerContext conte if (context.EnableTrimAnalyzer && !OwningSymbol.IsInRequiresUnreferencedCodeAttributeScope (out _) && !FeatureContext.IsEnabled (RequiresUnreferencedCodeAnalyzer.FullyQualifiedRequiresUnreferencedCodeAttribute)) { - foreach (var diagnostic in ReflectionAccessAnalyzer.GetDiagnosticsForReflectionAccessToDAMOnMethod (diagnosticContext, ReferencedMethod)) - diagnosticContext.AddDiagnostic (diagnostic); + ReflectionAccessAnalyzer.GetDiagnosticsForReflectionAccessToDAMOnMethod (diagnosticContext, ReferencedMethod); } - foreach (var requiresAnalyzer in context.EnabledRequiresAnalyzers) { - if (requiresAnalyzer.CheckAndCreateRequiresDiagnostic (Operation, ReferencedMethod, OwningSymbol, context, FeatureContext, out Diagnostic? diag)) - diagnosticContext.AddDiagnostic (diag); - } + foreach (var requiresAnalyzer in context.EnabledRequiresAnalyzers) + requiresAnalyzer.CheckAndCreateRequiresDiagnostic (Operation, ReferencedMethod, OwningSymbol, context, FeatureContext, diagnosticContext); return diagnosticContext.Diagnostics; } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs index ef504c72238a7..b882a681bf89f 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs @@ -25,7 +25,7 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis { - public class TrimAnalysisVisitor : LocalDataFlowVisitor< + internal sealed class TrimAnalysisVisitor : LocalDataFlowVisitor< MultiValue, FeatureContext, ValueSetLattice, diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimDataFlowAnalysis.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimDataFlowAnalysis.cs index cb669462f354a..dd0865b12cd2e 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimDataFlowAnalysis.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimDataFlowAnalysis.cs @@ -21,7 +21,7 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis { - public class TrimDataFlowAnalysis : LocalDataFlowAnalysis< + internal sealed class TrimDataFlowAnalysis : LocalDataFlowAnalysis< MultiValue, FeatureContext, ValueSetLattice, diff --git a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/DiagnosticContext.cs b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/DiagnosticContext.cs index 42220a0307f05..bfb7ab5c0fd32 100644 --- a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/DiagnosticContext.cs +++ b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/DiagnosticContext.cs @@ -15,7 +15,7 @@ namespace ILLink.Shared.TrimAnalysis /// - Single-file warnings (suppressed by RequiresAssemblyFilesAttribute) /// Note that not all categories are used/supported by all tools, for example the ILLink only handles trimmer warnings and ignores the rest. /// - internal readonly partial struct DiagnosticContext + public readonly partial struct DiagnosticContext { /// The diagnostic ID, this will be used to determine the category of diagnostic (trimmer, AOT, single-file) /// The arguments for diagnostic message. diff --git a/src/tools/illink/src/linker/CompatibilitySuppressions.xml b/src/tools/illink/src/linker/CompatibilitySuppressions.xml index c027ee4c6681a..662392bff785c 100644 --- a/src/tools/illink/src/linker/CompatibilitySuppressions.xml +++ b/src/tools/illink/src/linker/CompatibilitySuppressions.xml @@ -553,6 +553,12 @@ CP0001 T:System.Reflection.RuntimeAssemblyName + + CP0001 + T:ILLink.Shared.TrimAnalysis.DiagnosticContext + ref/net9.0/illink.dll + lib/net9.0/illink.dll + CP0002 F:Mono.Linker.AnnotationStore.assembly_actions diff --git a/src/tools/illink/src/linker/Linker.Dataflow/DiagnosticContext.cs b/src/tools/illink/src/linker/Linker.Dataflow/DiagnosticContext.cs index f68404e727e97..51997c92b6b1b 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/DiagnosticContext.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/DiagnosticContext.cs @@ -5,7 +5,7 @@ namespace ILLink.Shared.TrimAnalysis { - internal readonly partial struct DiagnosticContext + public readonly partial struct DiagnosticContext { public readonly MessageOrigin Origin; public readonly bool DiagnosticsEnabled;