diff --git a/eng/pipelines/runtime-linker-tests.yml b/eng/pipelines/runtime-linker-tests.yml
index 9df8042e7af0af..eaf4c68ec9799c 100644
--- a/eng/pipelines/runtime-linker-tests.yml
+++ b/eng/pipelines/runtime-linker-tests.yml
@@ -82,7 +82,11 @@ extends:
or(
eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_illink.containsChange'], true),
eq(variables['isRollingBuild'], true))
- buildArgs: -s tools.illinktests -test -c $(_BuildConfig)
+ # Build libs.sfx subset first so that Roslyn analyzer tests can use live ref pack
+ buildArgs: -s libs.sfx -c $(_BuildConfig)
+ postBuildSteps:
+ - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -ci -arch ${{ parameters.archType }} $(_osParameter) -s tools.illinktests -test -c $(_BuildConfig) $(crossArg) $(_officialBuildParameter)
+ displayName: Run ILLink Tests
#
# Build Release config vertical for Windows, Linux, and OSX
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/Directory.Build.props b/src/libraries/System.Runtime.InteropServices.JavaScript/Directory.Build.props
index 4733ac5e517b31..d68d22c1b917f8 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/Directory.Build.props
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/Directory.Build.props
@@ -3,6 +3,5 @@
Microsoft
true
- false
\ No newline at end of file
diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/MSBuildPropertyOptionNames.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/MSBuildPropertyOptionNames.cs
index e86d0b9d8486e2..51a5645b4318c6 100644
--- a/src/tools/illink/src/ILLink.RoslynAnalyzer/MSBuildPropertyOptionNames.cs
+++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/MSBuildPropertyOptionNames.cs
@@ -9,5 +9,7 @@ public static class MSBuildPropertyOptionNames
public const string IncludeAllContentForSelfExtract = nameof(IncludeAllContentForSelfExtract);
public const string EnableTrimAnalyzer = nameof(EnableTrimAnalyzer);
public const string EnableAotAnalyzer = nameof(EnableAotAnalyzer);
+ public const string VerifyReferenceAotCompatibility = nameof(VerifyReferenceAotCompatibility);
+ public const string VerifyReferenceTrimCompatibility = nameof(VerifyReferenceTrimCompatibility);
}
}
diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs
index 444c0ff3ff7a0f..a8b010bdc292d7 100644
--- a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs
+++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs
@@ -36,6 +36,7 @@ public abstract class RequiresAnalyzerBase : DiagnosticAnalyzer
private protected virtual ImmutableArray<(Action Action, SyntaxKind[] SyntaxKind)> ExtraSyntaxNodeActions { get; } = ImmutableArray<(Action Action, SyntaxKind[] SyntaxKind)>.Empty;
private protected virtual ImmutableArray<(Action Action, SymbolKind[] SymbolKind)> ExtraSymbolActions { get; } = ImmutableArray<(Action Action, SymbolKind[] SymbolKind)>.Empty;
+ private protected virtual ImmutableArray> ExtraCompilationActions { get; } = ImmutableArray>.Empty;
public override void Initialize(AnalysisContext context)
{
@@ -165,6 +166,9 @@ void CheckMatchingAttributesInInterfaces(
}
}
});
+
+ foreach (var extraCompilationAction in ExtraCompilationActions)
+ context.RegisterCompilationAction(extraCompilationAction);
}
internal void CheckAndCreateRequiresDiagnostic(
@@ -386,5 +390,38 @@ ImmutableArray arguments
{
return false;
}
+
+ protected void CheckReferencedAssemblies(
+ CompilationAnalysisContext context,
+ string msbuildPropertyName,
+ string assemblyMetadataName,
+ DiagnosticDescriptor diagnosticDescriptor)
+ {
+ var options = context.Options;
+ if (!IsAnalyzerEnabled(options))
+ return;
+
+ if (!options.IsMSBuildPropertyValueTrue(msbuildPropertyName))
+ return;
+
+ foreach (var reference in context.Compilation.References)
+ {
+ var refAssembly = context.Compilation.GetAssemblyOrModuleSymbol(reference) as IAssemblySymbol;
+ if (refAssembly is null)
+ continue;
+
+ var assemblyMetadata = refAssembly.GetAttributes().FirstOrDefault(attr =>
+ attr.AttributeClass?.Name == "AssemblyMetadataAttribute" &&
+ attr.ConstructorArguments.Length == 2 &&
+ attr.ConstructorArguments[0].Value?.ToString() == assemblyMetadataName &&
+ string.Equals(attr.ConstructorArguments[1].Value?.ToString(), "True", StringComparison.OrdinalIgnoreCase));
+
+ if (assemblyMetadata is null)
+ {
+ var diag = Diagnostic.Create(diagnosticDescriptor, Location.None, refAssembly.Name);
+ context.ReportDiagnostic(diag);
+ }
+ }
+ }
}
}
diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresDynamicCodeAnalyzer.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresDynamicCodeAnalyzer.cs
index 8e089da80d58ea..a8b6714fb8a282 100644
--- a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresDynamicCodeAnalyzer.cs
+++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresDynamicCodeAnalyzer.cs
@@ -23,9 +23,10 @@ public sealed class RequiresDynamicCodeAnalyzer : RequiresAnalyzerBase
private static readonly DiagnosticDescriptor s_requiresDynamicCodeOnEntryPoint = DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.RequiresDynamicCodeOnEntryPoint);
private static readonly DiagnosticDescriptor s_requiresDynamicCodeRule = DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.RequiresDynamicCode);
private static readonly DiagnosticDescriptor s_requiresDynamicCodeAttributeMismatch = DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.RequiresDynamicCodeAttributeMismatch);
+ private static readonly DiagnosticDescriptor s_referenceNotMarkedIsAotCompatibleRule = DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.ReferenceNotMarkedIsAotCompatible);
public override ImmutableArray SupportedDiagnostics =>
- ImmutableArray.Create(s_requiresDynamicCodeRule, s_requiresDynamicCodeAttributeMismatch, s_requiresDynamicCodeOnStaticCtor, s_requiresDynamicCodeOnEntryPoint);
+ ImmutableArray.Create(s_requiresDynamicCodeRule, s_requiresDynamicCodeAttributeMismatch, s_requiresDynamicCodeOnStaticCtor, s_requiresDynamicCodeOnEntryPoint, s_referenceNotMarkedIsAotCompatibleRule);
private protected override string RequiresAttributeName => RequiresDynamicCodeAttribute;
@@ -163,6 +164,16 @@ private protected override bool IsRequiresCheck(IPropertySymbol propertySymbol,
return SymbolEqualityComparer.Default.Equals(propertySymbol, isDynamicCodeSupportedProperty);
}
+ private protected override ImmutableArray> ExtraCompilationActions =>
+ ImmutableArray.Create>((context) =>
+ {
+ CheckReferencedAssemblies(
+ context,
+ MSBuildPropertyOptionNames.VerifyReferenceAotCompatibility,
+ "IsAotCompatible",
+ s_referenceNotMarkedIsAotCompatibleRule);
+ });
+
protected override bool VerifyAttributeArguments(AttributeData attribute) =>
attribute.ConstructorArguments.Length >= 1 && attribute.ConstructorArguments is [{ Type.SpecialType: SpecialType.System_String }, ..];
diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs
index e60eb128484b0d..09d2625d56b0aa 100644
--- a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs
+++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs
@@ -25,8 +25,10 @@ public sealed class RequiresUnreferencedCodeAnalyzer : RequiresAnalyzerBase
private static readonly DiagnosticDescriptor s_requiresUnreferencedCodeOnStaticCtor = DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.RequiresUnreferencedCodeOnStaticConstructor);
private static readonly DiagnosticDescriptor s_requiresUnreferencedCodeOnEntryPoint = DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.RequiresUnreferencedCodeOnEntryPoint);
+ private static readonly DiagnosticDescriptor s_referenceNotMarkedIsTrimmableRule = DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.ReferenceNotMarkedIsTrimmable);
+
public override ImmutableArray SupportedDiagnostics =>
- ImmutableArray.Create(s_makeGenericMethodRule, s_makeGenericTypeRule, s_requiresUnreferencedCodeRule, s_requiresUnreferencedCodeAttributeMismatch, s_requiresUnreferencedCodeOnStaticCtor, s_requiresUnreferencedCodeOnEntryPoint);
+ ImmutableArray.Create(s_makeGenericMethodRule, s_makeGenericTypeRule, s_requiresUnreferencedCodeRule, s_requiresUnreferencedCodeAttributeMismatch, s_requiresUnreferencedCodeOnStaticCtor, s_requiresUnreferencedCodeOnEntryPoint, s_referenceNotMarkedIsTrimmableRule);
private protected override string RequiresAttributeName => RequiresUnreferencedCodeAttribute;
@@ -76,6 +78,16 @@ protected override bool CreateSpecialIncompatibleMembersDiagnostic(
return false;
}
+ private protected override ImmutableArray> ExtraCompilationActions =>
+ ImmutableArray.Create>((context) =>
+ {
+ CheckReferencedAssemblies(
+ context,
+ MSBuildPropertyOptionNames.VerifyReferenceTrimCompatibility,
+ "IsTrimmable",
+ s_referenceNotMarkedIsTrimmableRule);
+ });
+
protected override bool VerifyAttributeArguments(AttributeData attribute) =>
RequiresUnreferencedCodeUtils.VerifyRequiresUnreferencedCodeAttributeArguments(attribute);
diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/build/Microsoft.NET.ILLink.Analyzers.props b/src/tools/illink/src/ILLink.RoslynAnalyzer/build/Microsoft.NET.ILLink.Analyzers.props
index 3284f19567179d..18ae6cb8fd5e8b 100644
--- a/src/tools/illink/src/ILLink.RoslynAnalyzer/build/Microsoft.NET.ILLink.Analyzers.props
+++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/build/Microsoft.NET.ILLink.Analyzers.props
@@ -1,8 +1,10 @@
-
-
-
-
+
+
+
+
+
+
diff --git a/src/tools/illink/src/ILLink.Shared/DiagnosticId.cs b/src/tools/illink/src/ILLink.Shared/DiagnosticId.cs
index 415f7b6812c56d..364a7974700a98 100644
--- a/src/tools/illink/src/ILLink.Shared/DiagnosticId.cs
+++ b/src/tools/illink/src/ILLink.Shared/DiagnosticId.cs
@@ -189,6 +189,7 @@ public enum DiagnosticId
TypeNameIsNotAssemblyQualified = 2122,
RequiresUnreferencedCodeOnEntryPoint = 2123,
TypeMapGroupTypeCannotBeStaticallyDetermined = 2124,
+ ReferenceNotMarkedIsTrimmable = 2125,
_EndTrimAnalysisWarningsSentinel,
// Single-file diagnostic ids.
@@ -208,6 +209,7 @@ public enum DiagnosticId
CorrectnessOfAbstractDelegatesCannotBeGuaranteed = 3055,
RequiresDynamicCodeOnStaticConstructor = 3056,
RequiresDynamicCodeOnEntryPoint = 3057,
+ ReferenceNotMarkedIsAotCompatible = 3058,
_EndAotAnalysisWarningsSentinel,
// Feature guard diagnostic ids.
diff --git a/src/tools/illink/src/ILLink.Shared/SharedStrings.resx b/src/tools/illink/src/ILLink.Shared/SharedStrings.resx
index 40c921ca706cde..aaa57abe34b60b 100644
--- a/src/tools/illink/src/ILLink.Shared/SharedStrings.resx
+++ b/src/tools/illink/src/ILLink.Shared/SharedStrings.resx
@@ -1239,4 +1239,16 @@
Type name is not assembly qualified.
+
+ Referenced assembly is not marked as trimmable.
+
+
+ Referenced assembly '{0}' is not built with `true` and may not be compatible with trimming.
+
+
+ Referenced assembly is not marked as AOT-compatible.
+
+
+ Referenced assembly '{0}' is not built with `true` and may not be compatible with AOT.
+
diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ILLink.RoslynAnalyzer.Tests.csproj b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ILLink.RoslynAnalyzer.Tests.csproj
index 8323dd02f82afd..184616fc012c10 100644
--- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ILLink.RoslynAnalyzer.Tests.csproj
+++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ILLink.RoslynAnalyzer.Tests.csproj
@@ -37,16 +37,12 @@
-
-
-
-
-
+
+
+
diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceAotCompatibilityTests.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceAotCompatibilityTests.cs
new file mode 100644
index 00000000000000..e52afef7b692d2
--- /dev/null
+++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceAotCompatibilityTests.cs
@@ -0,0 +1,76 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Threading.Tasks;
+using ILLink.Shared;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Testing;
+using Xunit;
+using System.IO;
+using VerifyCS = ILLink.RoslynAnalyzer.Tests.CSharpCodeFixVerifier<
+ ILLink.RoslynAnalyzer.RequiresDynamicCodeAnalyzer,
+ ILLink.CodeFix.RequiresDynamicCodeCodeFixProvider>;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using ILLink.CodeFix;
+
+namespace ILLink.RoslynAnalyzer.Tests
+{
+ public class ReferenceAotCompatibilityTests
+ {
+ [Fact]
+ public async Task EmitsWarningForReferenceWithoutIsAotCompatible_WhenPropertyEnabled()
+ {
+ var referencedSource = "public class ReferencedClass { }";
+ var testSource = "public class MainClass { ReferencedClass c; }";
+
+ var test = ReferenceCompatibilityTestUtils.CreateTestWithReference(
+ testSource, referencedSource);
+ test.TestState.AnalyzerConfigFiles.Add(("/.editorconfig", Microsoft.CodeAnalysis.Text.SourceText.From($"""
+ is_global = true
+ build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.EnableAotAnalyzer} = true
+ build_property.VerifyReferenceAotCompatibility = true
+ """)));
+ test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DiagnosticId.ReferenceNotMarkedIsAotCompatible).WithArguments("ReferencedAssembly"));
+ await test.RunAsync();
+ }
+
+ [Fact]
+ public async Task DoesNotEmitWarning_WhenVerifyReferenceAotCompatibilityDisabled()
+ {
+ var referencedSource = "public class ReferencedClass { }";
+ var testSource = "public class MainClass { ReferencedClass c; }";
+
+ var test = ReferenceCompatibilityTestUtils.CreateTestWithReference(
+ testSource, referencedSource);
+ test.TestState.AnalyzerConfigFiles.Add(("/.editorconfig", Microsoft.CodeAnalysis.Text.SourceText.From($"""
+ is_global = true
+ build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.EnableAotAnalyzer} = true
+ build_property.VerifyReferenceAotCompatibility = false
+ """)));
+ await test.RunAsync();
+ }
+
+ [Fact]
+ public async Task DoesNotEmitWarning_WhenReferenceMarkedIsAotCompatible()
+ {
+ var referencedSource = """
+ [assembly: System.Reflection.AssemblyMetadata("IsAotCompatible", "True")]
+ public class ReferencedClass { }
+ """;
+ var testSource = "public class MainClass { ReferencedClass c; }";
+
+ var test = ReferenceCompatibilityTestUtils.CreateTestWithReference(
+ testSource, referencedSource);
+ test.TestState.AnalyzerConfigFiles.Add(("/.editorconfig", Microsoft.CodeAnalysis.Text.SourceText.From($"""
+ is_global = true
+ build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.EnableAotAnalyzer} = true
+ build_property.VerifyReferenceAotCompatibility = true
+ """)));
+ await test.RunAsync();
+ }
+ }
+}
diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceCompatibilityTestUtils.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceCompatibilityTestUtils.cs
new file mode 100644
index 00000000000000..a5169775cc45bc
--- /dev/null
+++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceCompatibilityTestUtils.cs
@@ -0,0 +1,55 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Threading.Tasks;
+using ILLink.Shared;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.CodeAnalysis.Testing;
+using Xunit;
+using System.IO;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace ILLink.RoslynAnalyzer.Tests
+{
+ public class ReferenceCompatibilityTestUtils
+ {
+ public static CSharpCodeFixVerifier.Test CreateTestWithReference(string mainSource, string referenceSource)
+ where TAnalyzer : DiagnosticAnalyzer, new()
+ where TCodeFix : Microsoft.CodeAnalysis.CodeFixes.CodeFixProvider, new()
+ {
+ var referencedMetadata = CreateReferencedMetadata(referenceSource);
+ var test = new CSharpCodeFixVerifier.Test
+ {
+ TestCode = mainSource
+ };
+ test.SolutionTransforms.Add((solution, projectId) =>
+ {
+ var project = solution.GetProject(projectId);
+ if (project is null)
+ return solution;
+ project = project.AddMetadataReference(referencedMetadata);
+ return project.Solution;
+ });
+ return test;
+
+ static MetadataReference CreateReferencedMetadata(string referencedSource)
+ {
+ var refs = SourceGenerators.Tests.LiveReferencePack.GetMetadataReferences();
+ var referencedCompilation = CSharpCompilation.Create(
+ "ReferencedAssembly",
+ new[] { SyntaxFactory.ParseSyntaxTree(referencedSource) },
+ refs,
+ new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
+ var referencedImage = new MemoryStream();
+ referencedCompilation.Emit(referencedImage);
+ referencedImage.Position = 0;
+ return MetadataReference.CreateFromStream(referencedImage);
+ }
+ }
+ }
+}
diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceTrimCompatibilityTests.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceTrimCompatibilityTests.cs
new file mode 100644
index 00000000000000..0a0951e51afc77
--- /dev/null
+++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceTrimCompatibilityTests.cs
@@ -0,0 +1,78 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Threading.Tasks;
+using ILLink.Shared;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Testing;
+using Xunit;
+using System.IO;
+using ILLink.CodeFix;
+using VerifyCS = ILLink.RoslynAnalyzer.Tests.CSharpCodeFixVerifier<
+ ILLink.RoslynAnalyzer.RequiresUnreferencedCodeAnalyzer,
+ ILLink.CodeFix.RequiresUnreferencedCodeCodeFixProvider>;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace ILLink.RoslynAnalyzer.Tests
+{
+ public class ReferenceTrimCompatibilityTests
+ {
+ [Fact]
+ public async Task EmitsWarningForReferenceWithoutIsTrimmable_WhenPropertyEnabled()
+ {
+ var referencedSource = "public class ReferencedClass { }";
+ var testSource = "public class MainClass { ReferencedClass c; }";
+
+ var test = ReferenceCompatibilityTestUtils.CreateTestWithReference(
+ testSource, referencedSource);
+ test.TestState.AnalyzerConfigFiles.Add(("/.editorconfig", Microsoft.CodeAnalysis.Text.SourceText.From($"""
+ is_global = true
+ build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.EnableTrimAnalyzer} = true
+ build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.VerifyReferenceTrimCompatibility} = true
+ """)));
+ test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DiagnosticId.ReferenceNotMarkedIsTrimmable).WithArguments("ReferencedAssembly"));
+ await test.RunAsync();
+ }
+
+ [Fact]
+ public async Task DoesNotEmitWarning_WhenVerifyReferenceTrimCompatibilityDisabled()
+ {
+ var referencedSource = "public class ReferencedClass { }";
+ var testSource = "public class MainClass { ReferencedClass c; }";
+
+ var test = ReferenceCompatibilityTestUtils.CreateTestWithReference(
+ testSource, referencedSource);
+ test.TestState.AnalyzerConfigFiles.Add(("/.editorconfig", Microsoft.CodeAnalysis.Text.SourceText.From($"""
+ is_global = true
+ build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.EnableTrimAnalyzer} = true
+ build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.VerifyReferenceTrimCompatibility} = false
+ """)));
+
+ await test.RunAsync();
+ }
+
+ [Fact]
+ public async Task DoesNotEmitWarning_WhenReferenceMarkedIsTrimmable()
+ {
+ var referencedSource = """
+ [assembly: System.Reflection.AssemblyMetadata("IsTrimmable", "True")]
+ public class ReferencedClass { }
+ """;
+ var testSource = "public class MainClass { ReferencedClass c; }";
+
+ var test = ReferenceCompatibilityTestUtils.CreateTestWithReference(
+ testSource, referencedSource);
+ test.TestState.AnalyzerConfigFiles.Add(("/.editorconfig", Microsoft.CodeAnalysis.Text.SourceText.From($"""
+ is_global = true
+ build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.EnableTrimAnalyzer} = true
+ build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.VerifyReferenceTrimCompatibility} = true
+ """)));
+
+ await test.RunAsync();
+ }
+ }
+}