diff --git a/docs/error-codes.md b/docs/error-codes.md
index ba6d39f93c5b..bd30cae42781 100644
--- a/docs/error-codes.md
+++ b/docs/error-codes.md
@@ -1689,7 +1689,7 @@ The only scopes supported on global unconditional suppressions are 'module', 'ty
it is assumed that the suppression is put on the module. Global unconditional suppressions using invalid scopes are ignored.
```C#
-// Invalid scope 'method' used in 'UnconditionalSuppressMessageAttribute' on module 'Warning' with target 'MyTarget'.
+// IL2108: Invalid scope 'method' used in 'UnconditionalSuppressMessageAttribute' on module 'Warning' with target 'MyTarget'.
[module: UnconditionalSuppressMessage ("Test suppression with invalid scope", "IL2026", Scope = "method", Target = "MyTarget")]
class Warning
@@ -1722,6 +1722,99 @@ class Warning
class Derived : UnsafeClass {}
```
+#### `IL2110`: Trim analysis: Field 'field' with 'DynamicallyAccessedMembersAttribute' is accessed via reflection. Trimmer can't guarantee availability of the requirements of the field.
+
+- Trimmer currently can't guarantee that all requirements of the `DynamicallyAccessedMembersAttribute` are fulfilled if the field is accessed via reflection.
+
+```C#
+[DynamicallyAccessedMembers(DynamicallyAccessedMemeberTypes.PublicMethods)]
+Type _field;
+
+void TestMethod()
+{
+ // IL2110: Field '_field' with 'DynamicallyAccessedMembersAttribute' is accessed via reflection. Trimmer can't guarantee availability of the requirements of the field.
+ typeof(Test).GetField("_field");
+}
+```
+
+#### `IL2111`: Trim analysis: Method 'method' with parameters or return value with `DynamicallyAccessedMembersAttribute` is accessed via reflection. Trimmer can't guarantee availability of the requirements of the method.
+
+- Trimmer currently can't guarantee that all requirements of the `DynamicallyAccessedMembersAttribute` are fulfilled if the method is accessed via reflection.
+
+```C#
+void MethodWithRequirements([DynamicallyAccessedMembers(DynamicallyAccessedMemeberTypes.PublicMethods)] Type type)
+{
+}
+
+void TestMethod()
+{
+ // IL2111: Method 'MethodWithRequirements' with parameters or return value with `DynamicallyAccessedMembersAttribute` is accessed via reflection. Trimmer can't guarantee availability of the requirements of the method.
+ typeof(Test).GetMethod("MethodWithRequirements");
+}
+```
+
+#### `IL2112` Trim analysis: 'DynamicallyAccessedMembersAttribute' on 'type' or one of its base types references 'member' which requires unreferenced code. [message]. [url]
+
+- A type is annotated with `DynamicallyAccessedMembersAttribute` indicating that the type may dynamically access some members declared on the type or its derived types. This instructs the trimmer to keep the specified members, but one of them is annotated with `RequiresUnreferencedCodeAttribute` which can break functionality when trimming. The `DynamicallyAccessedMembersAttribute` annotation may be directly on the type, or implied by an annotation on one of its base or interface types. This warning originates from the member with `RequiresUnreferencedCodeAttribute`.
+
+ ```C#
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
+ public class AnnotatedType {
+ // Trim analysis warning IL2112: AnnotatedType.Method(): 'DynamicallyAccessedMembersAttribute' on 'AnnotatedType' or one of its
+ // base types references 'AnnotatedType.Method()' which requires unreferenced code. Using this member is trim unsafe.
+ [RequiresUnreferencedCode("Using this member is trim unsafe")]
+ public static void Method() { }
+ }
+ ```
+
+#### `IL2113` Trim analysis: 'DynamicallyAccessedMembersAttribute' on 'type' or one of its base types references 'member' which requires unreferenced code. [message]. [url]
+
+- A type is annotated with `DynamicallyAccessedMembersAttribute` indicating that the type may dynamically access some members declared on the type or its derived types. This instructs the trimmer to keep the specified members, but a member of one of the base or interface types is annotated with `RequiresUnreferencedCodeAttribute` which can break functionality when trimming. The `DynamicallyAccessedMembersAttribute` annotation may be directly on the type, or implied by an annotation on one of its base or interface types. This warning originates from the type which has `DynamicallyAccessedMembersAttribute` requirements.
+
+ ```C#
+ public class BaseType {
+ [RequiresUnreferencedCode("Using this member is trim unsafe")]
+ public static void Method() { }
+ }
+
+ // Trim analysis warning IL2113: AnnotatedType: 'DynamicallyAccessedMembersAttribute' on 'AnnotatedType' or one of its
+ // base types references 'BaseType.Method()' which requires unreferenced code. Using this member is trim unsafe.
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
+ public class AnnotatedType : BaseType {
+ }
+ ```
+
+#### `IL2114 ` Trim analysis: 'DynamicallyAccessedMembersAttribute' on 'type' or one of its base types references 'member' which has 'DynamicallyAccessedMembersAttribute' requirements.
+
+- A type is annotated with `DynamicallyAccessedMembersAttribute` indicating that the type may dynamically access some members declared on the type or its derived types. This instructs the trimmer to keep the specified members, but one of them is annotated with `DynamicallyAccessedMembersAttribute` which can not be statically verified. The `DynamicallyAccessedMembersAttribute` annotation may be directly on the type, or implied by an annotation on one of its base or interface types. This warning originates from the member with `DynamicallyAccessedMembersAttribute` requirements.
+
+ ```C#
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)]
+ public class AnnotatedType {
+ // Trim analysis warning IL2114: System.Type AnnotatedType::Field: 'DynamicallyAccessedMembersAttribute' on 'AnnotatedType' or one of its
+ // base types references 'System.Type AnnotatedType::Field' which has 'DynamicallyAccessedMembersAttribute' requirements .
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)]
+ public static Type Field;
+ }
+ ```
+
+#### `IL2115 ` Trim analysis: 'DynamicallyAccessedMembersAttribute' on 'type' or one of its base types references 'member' which has 'DynamicallyAccessedMembersAttribute' requirements.
+
+- A type is annotated with `DynamicallyAccessedMembersAttribute` indicating that the type may dynamically access some members declared on the type or its derived types. This instructs the trimmer to keep the specified members, but a member of one of the base or interface types is annotated with `DynamicallyAccessedMembersAttribute` which can not be statically verified. The `DynamicallyAccessedMembersAttribute` annotation may be directly on the type, or implied by an annotation on one of its base or interface types. This warning originates from the type which has `DynamicallyAccessedMembersAttribute` requirements.
+
+ ```C#
+ public class BaseType {
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)]
+ public static Type Field;
+ }
+
+ // Trim analysis warning IL2115: AnnotatedType: 'DynamicallyAccessedMembersAttribute' on 'AnnotatedType' or one of its
+ // base types references 'System.Type BaseType::Field' which has 'DynamicallyAccessedMembersAttribute' requirements .
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)]
+ public class AnnotatedType : BaseType {
+ }
+ ```
+
## Single-File Warning Codes
#### `IL3000`: 'member' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 7ed546c8300e..b55e9771dccb 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -3,18 +3,18 @@
-
+
https://github.com/dotnet/arcade
- b03966cd85285e425ffe56003c0ab57e103dd14e
+ 62a8aafffd4c68ef887680f6837abdff906a662c
-
+
https://github.com/dotnet/arcade
- b03966cd85285e425ffe56003c0ab57e103dd14e
+ 62a8aafffd4c68ef887680f6837abdff906a662c
-
+
https://github.com/dotnet/runtime
- 95863758cd16c345d0b8fca067d5db5d6901e498
+ d90f6b6c86be7001dc839e147ab229dfd1c7d20d
- 6.0.0-rc.1.21375.2
+ 6.0.0-rc.1.21401.3
$(MicrosoftNETSdkILPackageVersion)
5.0.0
17.0.0-preview-21267-01
17.0.0-preview-21267-01
- 6.0.0-beta.21366.1
+ 6.0.0-beta.21379.2
6.0.0-beta.21271.1
3.10.0-2.final
3.10.0-2.final
diff --git a/eng/common/internal/Tools.csproj b/eng/common/internal/Tools.csproj
index f46d5efe2e32..2067b8df8d98 100644
--- a/eng/common/internal/Tools.csproj
+++ b/eng/common/internal/Tools.csproj
@@ -1,5 +1,5 @@
+
-
net472
diff --git a/eng/common/templates/steps/source-build.yml b/eng/common/templates/steps/source-build.yml
index e20637ed6a17..705b7a1c847b 100644
--- a/eng/common/templates/steps/source-build.yml
+++ b/eng/common/templates/steps/source-build.yml
@@ -29,6 +29,11 @@ steps:
officialBuildArgs='/p:DotNetPublishUsingPipelines=true /p:OfficialBuildId=$(BUILD.BUILDNUMBER)'
fi
+ internalRuntimeDownloadArgs=
+ if [ '$(dotnetclimsrc-read-sas-token-base64)' != '$''(dotnetclimsrc-read-sas-token-base64)' ]; then
+ internalRuntimeDownloadArgs='--runtimesourcefeed https://dotnetclimsrc.blob.core.windows.net/dotnet --runtimesourcefeedkey $(dotnetclimsrc-read-sas-token-base64)'
+ fi
+
targetRidArgs=
if [ '${{ parameters.platform.targetRID }}' != '' ]; then
targetRidArgs='/p:TargetRid=${{ parameters.platform.targetRID }}'
@@ -43,6 +48,7 @@ steps:
--configuration $buildConfig \
--restore --build --pack $publishArgs -bl \
$officialBuildArgs \
+ $internalRuntimeDownloadArgs \
$targetRidArgs \
/p:SourceBuildNonPortable=${{ parameters.platform.nonPortable }} \
/p:ArcadeBuildFromSource=true
diff --git a/global.json b/global.json
index 21becbdf6156..7cda318a0198 100644
--- a/global.json
+++ b/global.json
@@ -8,8 +8,8 @@
}
},
"msbuild-sdks": {
- "Microsoft.DotNet.Arcade.Sdk": "6.0.0-beta.21366.1",
+ "Microsoft.DotNet.Arcade.Sdk": "6.0.0-beta.21379.2",
"Microsoft.FIX-85B6-MERGE-9C38-CONFLICT": "1.0.0",
- "Microsoft.NET.Sdk.IL": "6.0.0-rc.1.21375.2"
+ "Microsoft.NET.Sdk.IL": "6.0.0-rc.1.21401.3"
}
}
diff --git a/illink.sln b/illink.sln
index 947101370e75..f8752fdc6d29 100644
--- a/illink.sln
+++ b/illink.sln
@@ -36,6 +36,11 @@ EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ILLink.Shared", "src\ILLink.Shared\ILLink.Shared.shproj", "{92F5E753-2179-46DC-BDCE-736858C18DC7}"
EndProject
Global
+ GlobalSection(SharedMSBuildProjectFiles) = preSolution
+ src\ILLink.Shared\ILLink.Shared.projitems*{92f5e753-2179-46dc-bdce-736858c18dc7}*SharedItemsImports = 13
+ src\ILLink.Shared\ILLink.Shared.projitems*{dd28e2b1-057b-4b4d-a04d-b2ebd9e76e46}*SharedItemsImports = 5
+ src\ILLink.Shared\ILLink.Shared.projitems*{f1a44a78-34ee-408b-8285-9a26f0e7d4f2}*SharedItemsImports = 5
+ EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
diff --git a/src/ILLink.CodeFix/BaseAttributeCodeFixProvider.cs b/src/ILLink.CodeFix/BaseAttributeCodeFixProvider.cs
index 491c02e74400..a5431142bc66 100644
--- a/src/ILLink.CodeFix/BaseAttributeCodeFixProvider.cs
+++ b/src/ILLink.CodeFix/BaseAttributeCodeFixProvider.cs
@@ -69,9 +69,9 @@ private static async Task AddAttribute (
CancellationToken cancellationToken)
{
var semanticModel = await document.GetSemanticModelAsync (cancellationToken).ConfigureAwait (false);
- if (semanticModel is null) {
+ if (semanticModel is null)
return document;
- }
+
var newAttribute = generator
.Attribute (generator.TypeExpression (AttributeSymbol), attrArgs)
.WithAdditionalAnnotations (
diff --git a/src/ILLink.CodeFix/RequiresAssemblyFilesCodeFixProvider.cs b/src/ILLink.CodeFix/RequiresAssemblyFilesCodeFixProvider.cs
index b172b7e51079..a4a65999dff4 100644
--- a/src/ILLink.CodeFix/RequiresAssemblyFilesCodeFixProvider.cs
+++ b/src/ILLink.CodeFix/RequiresAssemblyFilesCodeFixProvider.cs
@@ -5,9 +5,11 @@
using System;
using System.Collections.Immutable;
using System.Composition;
+using System.Linq;
using System.Threading.Tasks;
using ILLink.CodeFixProvider;
using ILLink.RoslynAnalyzer;
+using ILLink.Shared;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
@@ -18,8 +20,12 @@ namespace ILLink.CodeFix
[ExportCodeFixProvider (LanguageNames.CSharp, Name = nameof (RequiresAssemblyFilesCodeFixProvider)), Shared]
public class RequiresAssemblyFilesCodeFixProvider : BaseAttributeCodeFixProvider
{
- public sealed override ImmutableArray FixableDiagnosticIds
- => ImmutableArray.Create (RequiresAssemblyFilesAnalyzer.IL3000, RequiresAssemblyFilesAnalyzer.IL3001, RequiresAssemblyFilesAnalyzer.IL3002);
+ public ImmutableArray SupportedDiagnostics => ImmutableArray.Create (
+ DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.AvoidAssemblyLocationInSingleFile),
+ DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.AvoidAssemblyGetFilesInSingleFile),
+ DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.RequiresAssemblyFiles));
+
+ public sealed override ImmutableArray FixableDiagnosticIds => SupportedDiagnostics.Select (dd => dd.Id).ToImmutableArray ();
private protected override LocalizableString CodeFixTitle => new LocalizableResourceString (nameof (Resources.RequiresAssemblyFilesCodeFixTitle), Resources.ResourceManager, typeof (Resources));
diff --git a/src/ILLink.CodeFix/RequiresUnreferencedCodeCodeFixProvider.cs b/src/ILLink.CodeFix/RequiresUnreferencedCodeCodeFixProvider.cs
index 5f2a60605018..ba24b1ca2dd6 100644
--- a/src/ILLink.CodeFix/RequiresUnreferencedCodeCodeFixProvider.cs
+++ b/src/ILLink.CodeFix/RequiresUnreferencedCodeCodeFixProvider.cs
@@ -5,9 +5,11 @@
using System;
using System.Collections.Immutable;
using System.Composition;
+using System.Linq;
using System.Threading.Tasks;
using ILLink.CodeFixProvider;
using ILLink.RoslynAnalyzer;
+using ILLink.Shared;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
@@ -18,8 +20,9 @@ namespace ILLink.CodeFix
[ExportCodeFixProvider (LanguageNames.CSharp, Name = nameof (RequiresUnreferencedCodeCodeFixProvider)), Shared]
public class RequiresUnreferencedCodeCodeFixProvider : BaseAttributeCodeFixProvider
{
- public sealed override ImmutableArray FixableDiagnosticIds
- => ImmutableArray.Create (RequiresUnreferencedCodeAnalyzer.IL2026);
+ public ImmutableArray SupportedDiagnostics => ImmutableArray.Create (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.RequiresUnreferencedCode));
+
+ public sealed override ImmutableArray FixableDiagnosticIds => SupportedDiagnostics.Select (dd => dd.Id).ToImmutableArray ();
private protected override LocalizableString CodeFixTitle => new LocalizableResourceString (nameof (Resources.RequiresUnreferencedCodeCodeFixTitle), Resources.ResourceManager, typeof (Resources));
diff --git a/src/ILLink.CodeFix/UnconditionalSuppressMessageCodeFixProvider.cs b/src/ILLink.CodeFix/UnconditionalSuppressMessageCodeFixProvider.cs
index 1a7f57dd6512..2cdd032e4a70 100644
--- a/src/ILLink.CodeFix/UnconditionalSuppressMessageCodeFixProvider.cs
+++ b/src/ILLink.CodeFix/UnconditionalSuppressMessageCodeFixProvider.cs
@@ -5,9 +5,10 @@
using System.Collections.Immutable;
using System.Composition;
using System.Globalization;
+using System.Linq;
using System.Threading.Tasks;
using ILLink.CodeFixProvider;
-using ILLink.RoslynAnalyzer;
+using ILLink.Shared;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
@@ -22,7 +23,11 @@ public class UnconditionalSuppressMessageCodeFixProvider : BaseAttributeCodeFixP
public const string FullyQualifiedUnconditionalSuppressMessageAttribute = "System.Diagnostics.CodeAnalysis." + UnconditionalSuppressMessageAttribute;
public sealed override ImmutableArray FixableDiagnosticIds
- => ImmutableArray.Create (RequiresUnreferencedCodeAnalyzer.IL2026, RequiresAssemblyFilesAnalyzer.IL3000, RequiresAssemblyFilesAnalyzer.IL3001, RequiresAssemblyFilesAnalyzer.IL3002);
+ => (new DiagnosticId[] {
+ DiagnosticId.RequiresUnreferencedCode,
+ DiagnosticId.AvoidAssemblyLocationInSingleFile,
+ DiagnosticId.AvoidAssemblyGetFilesInSingleFile,
+ DiagnosticId.RequiresAssemblyFiles }).Select (d => d.AsString ()).ToImmutableArray ();
private protected override LocalizableString CodeFixTitle => new LocalizableResourceString (nameof (Resources.UconditionalSuppressMessageCodeFixTitle), Resources.ResourceManager, typeof (Resources));
diff --git a/src/ILLink.RoslynAnalyzer/DiagnosticDescriptors.cs b/src/ILLink.RoslynAnalyzer/DiagnosticDescriptors.cs
new file mode 100644
index 000000000000..4b955a0587d1
--- /dev/null
+++ b/src/ILLink.RoslynAnalyzer/DiagnosticDescriptors.cs
@@ -0,0 +1,68 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using ILLink.Shared;
+using Microsoft.CodeAnalysis;
+
+namespace ILLink.RoslynAnalyzer
+{
+ public static class DiagnosticDescriptors
+ {
+ public static DiagnosticDescriptor GetDiagnosticDescriptor (DiagnosticId diagnosticId)
+ {
+ var diagnosticString = new DiagnosticString (diagnosticId);
+ return new DiagnosticDescriptor (diagnosticId.AsString (),
+ diagnosticString.GetTitleFormat (),
+ diagnosticString.GetMessageFormat (),
+ GetDiagnosticCategory (diagnosticId),
+ DiagnosticSeverity.Warning,
+ true);
+ }
+
+ public static DiagnosticDescriptor GetDiagnosticDescriptor (DiagnosticId diagnosticId,
+ LocalizableResourceString? lrsTitle = null,
+ LocalizableResourceString? lrsMessage = null,
+ string? diagnosticCategory = null,
+ DiagnosticSeverity diagnosticSeverity = DiagnosticSeverity.Warning,
+ bool isEnabledByDefault = true,
+ string? helpLinkUri = null)
+ {
+ if (lrsTitle == null || lrsMessage == null) {
+ var diagnosticString = new DiagnosticString (diagnosticId);
+ return new DiagnosticDescriptor (diagnosticId.AsString (),
+ diagnosticString.GetTitleFormat (),
+ diagnosticString.GetMessageFormat (),
+ diagnosticCategory ?? GetDiagnosticCategory (diagnosticId),
+ diagnosticSeverity,
+ isEnabledByDefault,
+ helpLinkUri);
+ }
+
+ return new DiagnosticDescriptor (diagnosticId.AsString (),
+ lrsTitle!,
+ lrsMessage!,
+ diagnosticCategory ?? GetDiagnosticCategory (diagnosticId),
+ diagnosticSeverity,
+ isEnabledByDefault,
+ helpLinkUri);
+ }
+
+ static string GetDiagnosticCategory (DiagnosticId diagnosticId)
+ {
+ switch ((int) diagnosticId) {
+ case > 2000 and < 3000:
+ return DiagnosticCategory.Trimming;
+
+ case >= 3000 and <= 6000:
+ return DiagnosticCategory.SingleFile;
+
+ default:
+ break;
+ }
+
+ throw new ArgumentException ($"The provided diagnostic id '{diagnosticId}' does not fall into the range of supported warning codes 2001 to 6000 (inclusive).");
+ }
+ }
+}
diff --git a/src/ILLink.RoslynAnalyzer/RequiresAssemblyFilesAnalyzer.cs b/src/ILLink.RoslynAnalyzer/RequiresAssemblyFilesAnalyzer.cs
index dbce10d380db..3207cc2379f2 100644
--- a/src/ILLink.RoslynAnalyzer/RequiresAssemblyFilesAnalyzer.cs
+++ b/src/ILLink.RoslynAnalyzer/RequiresAssemblyFilesAnalyzer.cs
@@ -4,7 +4,6 @@
using System;
using System.Collections.Immutable;
-using System.Linq;
using ILLink.Shared;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
@@ -14,58 +13,21 @@ namespace ILLink.RoslynAnalyzer
[DiagnosticAnalyzer (LanguageNames.CSharp)]
public sealed class RequiresAssemblyFilesAnalyzer : RequiresAnalyzerBase
{
- public const string IL3000 = nameof (IL3000);
- public const string IL3001 = nameof (IL3001);
- public const string IL3002 = nameof (IL3002);
- public const string IL3003 = nameof (IL3003);
-
private const string RequiresAssemblyFilesAttribute = nameof (RequiresAssemblyFilesAttribute);
public const string RequiresAssemblyFilesAttributeFullyQualifiedName = "System.Diagnostics.CodeAnalysis." + RequiresAssemblyFilesAttribute;
- static readonly DiagnosticDescriptor s_locationRule = new DiagnosticDescriptor (
- IL3000,
- new LocalizableResourceString (nameof (SharedStrings.AvoidAssemblyLocationInSingleFileTitle),
- SharedStrings.ResourceManager, typeof (SharedStrings)),
- new LocalizableResourceString (nameof (SharedStrings.AvoidAssemblyLocationInSingleFileMessage),
- SharedStrings.ResourceManager, typeof (SharedStrings)),
- DiagnosticCategory.SingleFile,
- DiagnosticSeverity.Warning,
- isEnabledByDefault: true,
+ static readonly DiagnosticDescriptor s_locationRule = DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.AvoidAssemblyLocationInSingleFile,
helpLinkUri: "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/il3000");
- static readonly DiagnosticDescriptor s_getFilesRule = new DiagnosticDescriptor (
- IL3001,
- new LocalizableResourceString (nameof (SharedStrings.AvoidAssemblyGetFilesInSingleFileTitle),
- SharedStrings.ResourceManager, typeof (SharedStrings)),
- new LocalizableResourceString (nameof (SharedStrings.AvoidAssemblyGetFilesInSingleFileMessage),
- SharedStrings.ResourceManager, typeof (SharedStrings)),
- DiagnosticCategory.SingleFile,
- DiagnosticSeverity.Warning,
- isEnabledByDefault: true,
+ static readonly DiagnosticDescriptor s_getFilesRule = DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.AvoidAssemblyGetFilesInSingleFile,
helpLinkUri: "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/il3001");
- static readonly DiagnosticDescriptor s_requiresAssemblyFilesRule = new DiagnosticDescriptor (
- IL3002,
- new LocalizableResourceString (nameof (SharedStrings.RequiresAssemblyFilesTitle),
- SharedStrings.ResourceManager, typeof (SharedStrings)),
- new LocalizableResourceString (nameof (SharedStrings.RequiresAssemblyFilesMessage),
- SharedStrings.ResourceManager, typeof (SharedStrings)),
- DiagnosticCategory.SingleFile,
- DiagnosticSeverity.Warning,
- isEnabledByDefault: true,
+ static readonly DiagnosticDescriptor s_requiresAssemblyFilesRule = DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.RequiresAssemblyFiles,
helpLinkUri: "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/il3002");
- static readonly DiagnosticDescriptor s_requiresAttributeMismatch = new DiagnosticDescriptor (
- IL3003,
- new LocalizableResourceString (nameof (SharedStrings.RequiresAttributeMismatchTitle),
- SharedStrings.ResourceManager, typeof (SharedStrings)),
- new LocalizableResourceString (nameof (SharedStrings.RequiresAttributeMismatchMessage),
- SharedStrings.ResourceManager, typeof (SharedStrings)),
- DiagnosticCategory.Trimming,
- DiagnosticSeverity.Warning,
- isEnabledByDefault: true);
+ static readonly DiagnosticDescriptor s_requiresAssembyFilesAttributeMismatch = DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.RequiresAssembyFilesAttributeMismatch);
- public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create (s_locationRule, s_getFilesRule, s_requiresAssemblyFilesRule, s_requiresAttributeMismatch);
+ public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create (s_locationRule, s_getFilesRule, s_requiresAssemblyFilesRule, s_requiresAssembyFilesAttributeMismatch);
private protected override string RequiresAttributeName => RequiresAssemblyFilesAttribute;
@@ -75,16 +37,18 @@ public sealed class RequiresAssemblyFilesAnalyzer : RequiresAnalyzerBase
private protected override DiagnosticDescriptor RequiresDiagnosticRule => s_requiresAssemblyFilesRule;
- private protected override DiagnosticDescriptor RequiresAttributeMismatch => s_requiresAttributeMismatch;
+ private protected override DiagnosticDescriptor RequiresAttributeMismatch => s_requiresAssembyFilesAttributeMismatch;
protected override bool IsAnalyzerEnabled (AnalyzerOptions options, Compilation compilation)
{
var isSingleFileAnalyzerEnabled = options.GetMSBuildPropertyValue (MSBuildPropertyOptionNames.EnableSingleFileAnalyzer, compilation);
if (!string.Equals (isSingleFileAnalyzerEnabled?.Trim (), "true", StringComparison.OrdinalIgnoreCase))
return false;
+
var includesAllContent = options.GetMSBuildPropertyValue (MSBuildPropertyOptionNames.IncludeAllContentForSelfExtract, compilation);
if (string.Equals (includesAllContent?.Trim (), "true", StringComparison.OrdinalIgnoreCase))
return false;
+
return true;
}
@@ -94,10 +58,10 @@ protected override ImmutableArray GetSpecialIncompatibleMembers (Compil
var assemblyType = compilation.GetTypeByMetadataName ("System.Reflection.Assembly");
if (assemblyType != null) {
- // properties
+ // Properties
ImmutableArrayOperations.AddIfNotNull (dangerousPatternsBuilder, ImmutableArrayOperations.TryGetSingleSymbol (assemblyType.GetMembers ("Location")));
- // methods
+ // Methods
dangerousPatternsBuilder.AddRange (assemblyType.GetMembers ("GetFile").OfType ());
dangerousPatternsBuilder.AddRange (assemblyType.GetMembers ("GetFiles").OfType ());
}
@@ -120,6 +84,7 @@ protected override bool ReportSpecialIncompatibleMembersDiagnostic (OperationAna
operationContext.ReportDiagnostic (Diagnostic.Create (s_locationRule, operationContext.Operation.Syntax.GetLocation (), member.GetDisplayName ()));
return true;
}
+
return false;
}
diff --git a/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs b/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs
index 3e6cbc493d4d..53c91a8b85d0 100644
--- a/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs
+++ b/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs
@@ -13,32 +13,13 @@ namespace ILLink.RoslynAnalyzer
[DiagnosticAnalyzer (LanguageNames.CSharp)]
public sealed class RequiresUnreferencedCodeAnalyzer : RequiresAnalyzerBase
{
- public const string IL2026 = nameof (IL2026);
- public const string IL2046 = nameof (IL2046);
const string RequiresUnreferencedCodeAttribute = nameof (RequiresUnreferencedCodeAttribute);
public const string FullyQualifiedRequiresUnreferencedCodeAttribute = "System.Diagnostics.CodeAnalysis." + RequiresUnreferencedCodeAttribute;
- static readonly DiagnosticDescriptor s_requiresUnreferencedCodeRule = new DiagnosticDescriptor (
- IL2026,
- new LocalizableResourceString (nameof (SharedStrings.RequiresUnreferencedCodeTitle),
- SharedStrings.ResourceManager, typeof (SharedStrings)),
- new LocalizableResourceString (nameof (SharedStrings.RequiresUnreferencedCodeMessage),
- SharedStrings.ResourceManager, typeof (SharedStrings)),
- DiagnosticCategory.Trimming,
- DiagnosticSeverity.Warning,
- isEnabledByDefault: true);
+ static readonly DiagnosticDescriptor s_requiresUnreferencedCodeRule = DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.RequiresUnreferencedCode);
+ static readonly DiagnosticDescriptor s_requiresUnreferencedCodeAttributeMismatch = DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch);
- static readonly DiagnosticDescriptor s_requiresAttributeMismatch = new DiagnosticDescriptor (
- IL2046,
- new LocalizableResourceString (nameof (SharedStrings.RequiresAttributeMismatchTitle),
- SharedStrings.ResourceManager, typeof (SharedStrings)),
- new LocalizableResourceString (nameof (SharedStrings.RequiresAttributeMismatchMessage),
- SharedStrings.ResourceManager, typeof (SharedStrings)),
- DiagnosticCategory.Trimming,
- DiagnosticSeverity.Warning,
- isEnabledByDefault: true);
-
- public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create (s_requiresUnreferencedCodeRule, s_requiresAttributeMismatch);
+ public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create (s_requiresUnreferencedCodeRule, s_requiresUnreferencedCodeAttributeMismatch);
private protected override string RequiresAttributeName => RequiresUnreferencedCodeAttribute;
@@ -48,7 +29,7 @@ public sealed class RequiresUnreferencedCodeAnalyzer : RequiresAnalyzerBase
private protected override DiagnosticDescriptor RequiresDiagnosticRule => s_requiresUnreferencedCodeRule;
- private protected override DiagnosticDescriptor RequiresAttributeMismatch => s_requiresAttributeMismatch;
+ private protected override DiagnosticDescriptor RequiresAttributeMismatch => s_requiresUnreferencedCodeAttributeMismatch;
protected override bool IsAnalyzerEnabled (AnalyzerOptions options, Compilation compilation)
{
diff --git a/src/ILLink.RoslynAnalyzer/DiagnosticCategory.cs b/src/ILLink.Shared/DiagnosticCategory.cs
similarity index 91%
rename from src/ILLink.RoslynAnalyzer/DiagnosticCategory.cs
rename to src/ILLink.Shared/DiagnosticCategory.cs
index 28cf0f031436..1bbf868d954c 100644
--- a/src/ILLink.RoslynAnalyzer/DiagnosticCategory.cs
+++ b/src/ILLink.Shared/DiagnosticCategory.cs
@@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace ILLink.RoslynAnalyzer
+namespace ILLink.Shared
{
internal static class DiagnosticCategory
{
diff --git a/src/ILLink.Shared/DiagnosticId.cs b/src/ILLink.Shared/DiagnosticId.cs
new file mode 100644
index 000000000000..0dd728ed38bd
--- /dev/null
+++ b/src/ILLink.Shared/DiagnosticId.cs
@@ -0,0 +1,20 @@
+namespace ILLink.Shared
+{
+ public enum DiagnosticId
+ {
+ // Linker diagnostic ids.
+ RequiresUnreferencedCode = 2026,
+ RequiresUnreferencedCodeAttributeMismatch = 2046,
+
+ // Single-file diagnostic ids.
+ AvoidAssemblyLocationInSingleFile = 3000,
+ AvoidAssemblyGetFilesInSingleFile = 3001,
+ RequiresAssemblyFiles = 3002,
+ RequiresAssembyFilesAttributeMismatch = 3003
+ }
+
+ public static class DiagnosticIdExtensions
+ {
+ public static string AsString (this DiagnosticId diagnosticId) => $"IL{(int) diagnosticId}";
+ }
+}
diff --git a/src/ILLink.Shared/DiagnosticString.cs b/src/ILLink.Shared/DiagnosticString.cs
new file mode 100644
index 000000000000..dbd530207867
--- /dev/null
+++ b/src/ILLink.Shared/DiagnosticString.cs
@@ -0,0 +1,25 @@
+namespace ILLink.Shared
+{
+ public readonly struct DiagnosticString
+ {
+ readonly string _titleFormat;
+ readonly string _messageFormat;
+
+ public DiagnosticString (DiagnosticId diagnosticId)
+ {
+ var resourceManager = SharedStrings.ResourceManager;
+ _titleFormat = resourceManager.GetString ($"{diagnosticId}Title");
+ _messageFormat = resourceManager.GetString ($"{diagnosticId}Message");
+ }
+
+ public string GetMessage (params string[] args) =>
+ string.Format (_messageFormat, args);
+
+ public string GetMessageFormat () => _messageFormat;
+
+ public string GetTitle (params string[] args) =>
+ string.Format (_titleFormat, args);
+
+ public string GetTitleFormat () => _titleFormat;
+ }
+}
diff --git a/src/ILLink.Shared/ILLink.Shared.projitems b/src/ILLink.Shared/ILLink.Shared.projitems
index 227b6f712b89..8b672c98bd01 100644
--- a/src/ILLink.Shared/ILLink.Shared.projitems
+++ b/src/ILLink.Shared/ILLink.Shared.projitems
@@ -9,6 +9,9 @@
ILLink.Shared
+
+
+
diff --git a/src/ILLink.Shared/MessageFormat.cs b/src/ILLink.Shared/MessageFormat.cs
index 96bd7a78216d..e8ae020f7e73 100644
--- a/src/ILLink.Shared/MessageFormat.cs
+++ b/src/ILLink.Shared/MessageFormat.cs
@@ -6,21 +6,21 @@ internal static class MessageFormat
{
public static string FormatRequiresAttributeMessageArg (string? message)
{
- string arg1 = "";
if (!string.IsNullOrEmpty (message))
- arg1 = $" {message}{(message!.TrimEnd ().EndsWith (".") ? "" : ".")}";
- return arg1;
+ return $" {message}{(message!.TrimEnd ().EndsWith (".") ? "" : ".")}";
+
+ return string.Empty;
}
public static string FormatRequiresAttributeUrlArg (string? url)
{
- string arg2 = "";
if (!string.IsNullOrEmpty (url))
- arg2 = " " + url;
- return arg2;
+ return $" {url}";
+
+ return string.Empty;
}
- public static string FormatRequiresAttributeMismatch (bool memberHasAttribute, bool isInterface, string var0, string var1, string var2)
+ public static string FormatRequiresAttributeMismatch (bool memberHasAttribute, bool isInterface, params object[] args)
{
string format = (memberHasAttribute, isInterface) switch {
(false, true) => SharedStrings.InterfaceRequiresMismatchMessage,
@@ -28,7 +28,8 @@ public static string FormatRequiresAttributeMismatch (bool memberHasAttribute, b
(false, false) => SharedStrings.BaseRequiresMismatchMessage,
(true, false) => SharedStrings.DerivedRequiresMismatchMessage
};
- return string.Format (format, var0, var1, var2);
+
+ return string.Format (format, args);
}
}
}
\ No newline at end of file
diff --git a/src/ILLink.Shared/SharedStrings.resx b/src/ILLink.Shared/SharedStrings.resx
index a662c41cde94..d5015e17da41 100644
--- a/src/ILLink.Shared/SharedStrings.resx
+++ b/src/ILLink.Shared/SharedStrings.resx
@@ -141,11 +141,11 @@
Using member '{0}' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app.{1}{2}
-
- {0}. Attributes must match across all interface implementations or overrides.
+
+ {0}. 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
-
- RequiresAttribute must match across all interface implementations or overrides.
+
+ 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
Base member '{2}' with '{0}' has a derived member '{1}' without '{0}'
diff --git a/src/linker/Linker.Dataflow/DynamicallyAccessedMembersTypeHierarchy.cs b/src/linker/Linker.Dataflow/DynamicallyAccessedMembersTypeHierarchy.cs
index 4d310f192e3c..e3e871510520 100644
--- a/src/linker/Linker.Dataflow/DynamicallyAccessedMembersTypeHierarchy.cs
+++ b/src/linker/Linker.Dataflow/DynamicallyAccessedMembersTypeHierarchy.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
@@ -118,7 +118,8 @@ public DynamicallyAccessedMembersTypeHierarchy (LinkContext context, MarkStep ma
// so we need to apply the annotation to this type as well
using var _ = _scopeStack.PushScope (new MessageOrigin (type));
var reflectionMethodBodyScanner = new ReflectionMethodBodyScanner (_context, _markStep, _scopeStack);
- var reflectionPatternContext = new ReflectionPatternContext (_context, true, _scopeStack.CurrentScope.Origin, type);
+ // Set up a context to report warnings on access to annotated members, with the annotated type as the origin.
+ var reflectionPatternContext = new ReflectionPatternContext (_context, reportingEnabled: true, _scopeStack.CurrentScope.Origin, type);
reflectionMethodBodyScanner.ApplyDynamicallyAccessedMembersToType (ref reflectionPatternContext, type, annotation);
reflectionPatternContext.Dispose ();
}
@@ -128,7 +129,6 @@ public DynamicallyAccessedMembersTypeHierarchy (LinkContext context, MarkStep ma
public DynamicallyAccessedMemberTypes ApplyDynamicallyAccessedMembersToTypeHierarchy (
ReflectionMethodBodyScanner reflectionMethodBodyScanner,
- ref ReflectionPatternContext reflectionPatternContext,
TypeDefinition type)
{
Debug.Assert (_context.Annotations.IsMarked (type));
@@ -142,6 +142,9 @@ public DynamicallyAccessedMemberTypes ApplyDynamicallyAccessedMembersToTypeHiera
return annotation;
// Apply the effective annotation for the type
+ using var _ = _scopeStack.PushScope (new MessageOrigin (type));
+ // Set up a context to report warnings on access to annotated members, with the annotated type as the origin.
+ var reflectionPatternContext = new ReflectionPatternContext (_context, reportingEnabled: true, _scopeStack.CurrentScope.Origin, type);
reflectionMethodBodyScanner.ApplyDynamicallyAccessedMembersToType (ref reflectionPatternContext, type, annotation);
// Mark it as applied in the cache
@@ -174,7 +177,7 @@ public DynamicallyAccessedMemberTypes ApplyDynamicallyAccessedMembersToTypeHiera
break;
foreach (var candidateType in candidateTypes) {
- ApplyDynamicallyAccessedMembersToTypeHierarchyInner (reflectionMethodBodyScanner, ref reflectionPatternContext, candidateType);
+ ApplyDynamicallyAccessedMembersToTypeHierarchyInner (reflectionMethodBodyScanner, candidateType);
}
}
@@ -183,7 +186,6 @@ public DynamicallyAccessedMemberTypes ApplyDynamicallyAccessedMembersToTypeHiera
bool ApplyDynamicallyAccessedMembersToTypeHierarchyInner (
ReflectionMethodBodyScanner reflectionMethodBodyScanner,
- ref ReflectionPatternContext reflectionPatternContext,
TypeDefinition type)
{
(var annotation, var applied) = GetCachedInfoForTypeInHierarchy (type);
@@ -196,13 +198,13 @@ bool ApplyDynamicallyAccessedMembersToTypeHierarchyInner (
TypeDefinition baseType = type.BaseType?.Resolve ();
if (baseType != null)
- applied = ApplyDynamicallyAccessedMembersToTypeHierarchyInner (reflectionMethodBodyScanner, ref reflectionPatternContext, baseType);
+ applied = ApplyDynamicallyAccessedMembersToTypeHierarchyInner (reflectionMethodBodyScanner, baseType);
if (!applied && type.HasInterfaces) {
foreach (InterfaceImplementation iface in type.Interfaces) {
var interfaceType = iface.InterfaceType.Resolve ();
if (interfaceType != null) {
- if (ApplyDynamicallyAccessedMembersToTypeHierarchyInner (reflectionMethodBodyScanner, ref reflectionPatternContext, interfaceType)) {
+ if (ApplyDynamicallyAccessedMembersToTypeHierarchyInner (reflectionMethodBodyScanner, interfaceType)) {
applied = true;
break;
}
@@ -211,6 +213,9 @@ bool ApplyDynamicallyAccessedMembersToTypeHierarchyInner (
}
if (applied) {
+ using var _ = _scopeStack.PushScope (new MessageOrigin (type));
+ // Set up a context to report warnings on access to annotated members, with the annotated type as the origin.
+ var reflectionPatternContext = new ReflectionPatternContext (_context, reportingEnabled: true, _scopeStack.CurrentScope.Origin, type);
reflectionMethodBodyScanner.ApplyDynamicallyAccessedMembersToType (ref reflectionPatternContext, type, annotation);
_typesInDynamicallyAccessedMembersHierarchy[type] = (annotation, true);
}
diff --git a/src/linker/Linker.Dataflow/FlowAnnotations.cs b/src/linker/Linker.Dataflow/FlowAnnotations.cs
index 898c7074b92a..6fa50ed7b845 100644
--- a/src/linker/Linker.Dataflow/FlowAnnotations.cs
+++ b/src/linker/Linker.Dataflow/FlowAnnotations.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
@@ -23,20 +23,14 @@ public FlowAnnotations (LinkContext context)
_hierarchyInfo = new TypeHierarchyCache (context);
}
- public bool RequiresDataFlowAnalysis (MethodDefinition method)
- {
- return GetAnnotations (method.DeclaringType).TryGetAnnotation (method, out _);
- }
+ public bool RequiresDataFlowAnalysis (MethodDefinition method) =>
+ GetAnnotations (method.DeclaringType).TryGetAnnotation (method, out _);
- public bool RequiresDataFlowAnalysis (FieldDefinition field)
- {
- return GetAnnotations (field.DeclaringType).TryGetAnnotation (field, out _);
- }
+ public bool RequiresDataFlowAnalysis (FieldDefinition field) =>
+ GetAnnotations (field.DeclaringType).TryGetAnnotation (field, out _);
- public bool RequiresDataFlowAnalysis (GenericParameter genericParameter)
- {
- return GetGenericParameterAnnotation (genericParameter) != DynamicallyAccessedMemberTypes.None;
- }
+ public bool RequiresDataFlowAnalysis (GenericParameter genericParameter) =>
+ GetGenericParameterAnnotation (genericParameter) != DynamicallyAccessedMemberTypes.None;
///
/// Retrieves the annotations for the given parameter.
@@ -45,35 +39,38 @@ public bool RequiresDataFlowAnalysis (GenericParameter genericParameter)
///
public DynamicallyAccessedMemberTypes GetParameterAnnotation (MethodDefinition method, int parameterIndex)
{
- if (GetAnnotations (method.DeclaringType).TryGetAnnotation (method, out var annotation) && annotation.ParameterAnnotations != null) {
+ if (GetAnnotations (method.DeclaringType).TryGetAnnotation (method, out var annotation) &&
+ annotation.ParameterAnnotations != null)
return annotation.ParameterAnnotations[parameterIndex];
- }
return DynamicallyAccessedMemberTypes.None;
}
public DynamicallyAccessedMemberTypes GetReturnParameterAnnotation (MethodDefinition method)
{
- if (GetAnnotations (method.DeclaringType).TryGetAnnotation (method, out var annotation)) {
+ if (GetAnnotations (method.DeclaringType).TryGetAnnotation (method, out var annotation))
return annotation.ReturnParameterAnnotation;
- }
return DynamicallyAccessedMemberTypes.None;
}
public DynamicallyAccessedMemberTypes GetFieldAnnotation (FieldDefinition field)
{
- if (GetAnnotations (field.DeclaringType).TryGetAnnotation (field, out var annotation)) {
+ if (GetAnnotations (field.DeclaringType).TryGetAnnotation (field, out var annotation))
return annotation.Annotation;
- }
return DynamicallyAccessedMemberTypes.None;
}
- public DynamicallyAccessedMemberTypes GetTypeAnnotation (TypeDefinition type)
- {
- return GetAnnotations (type).TypeAnnotation;
- }
+ public DynamicallyAccessedMemberTypes GetTypeAnnotation (TypeDefinition type) =>
+ GetAnnotations (type).TypeAnnotation;
+
+ public bool ShouldWarnWhenAccessedForReflection (IMemberDefinition provider) =>
+ provider switch {
+ MethodDefinition method => ShouldWarnWhenAccessedForReflection (method),
+ FieldDefinition field => ShouldWarnWhenAccessedForReflection (field),
+ _ => false
+ };
public DynamicallyAccessedMemberTypes GetGenericParameterAnnotation (GenericParameter genericParameter)
{
@@ -93,6 +90,59 @@ public DynamicallyAccessedMemberTypes GetGenericParameterAnnotation (GenericPara
return DynamicallyAccessedMemberTypes.None;
}
+ public bool ShouldWarnWhenAccessedForReflection (MethodDefinition method)
+ {
+ if (!GetAnnotations (method.DeclaringType).TryGetAnnotation (method, out var annotation))
+ return false;
+
+ if (annotation.ParameterAnnotations == null && annotation.ReturnParameterAnnotation == DynamicallyAccessedMemberTypes.None)
+ return false;
+
+ // If the method only has annotation on the return value and it's not virtual avoid warning.
+ // Return value annotations are "consumed" by the caller of a method, and as such there is nothing
+ // wrong calling these dynamically. The only problem can happen if something overrides a virtual
+ // method with annotated return value at runtime - in this case the trimmer can't validate
+ // that the method will return only types which fulfill the annotation's requirements.
+ // For example:
+ // class BaseWithAnnotation
+ // {
+ // [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)]
+ // public abstract Type GetTypeWithFields();
+ // }
+ //
+ // class UsingTheBase
+ // {
+ // public void PrintFields(Base base)
+ // {
+ // // No warning here - GetTypeWithFields is correctly annotated to allow GetFields on the return value.
+ // Console.WriteLine(string.Join(" ", base.GetTypeWithFields().GetFields().Select(f => f.Name)));
+ // }
+ // }
+ //
+ // If at runtime (through ref emit) something generates code like this:
+ // class DerivedAtRuntimeFromBase
+ // {
+ // // No point in adding annotation on the return value - nothing will look at it anyway
+ // // Linker will not see this code, so there are no checks
+ // public override Type GetTypeWithFields() { return typeof(TestType); }
+ // }
+ //
+ // If TestType from above is trimmed, it may note have all its fields, and there would be no warnings generated.
+ // But there has to be code like this somewhere in the app, in order to generate the override:
+ // class RuntimeTypeGenerator
+ // {
+ // public MethodInfo GetBaseMethod()
+ // {
+ // // This must warn - that the GetTypeWithFields has annotation on the return value
+ // return typeof(BaseWithAnnotation).GetMethod("GetTypeWithFields");
+ // }
+ // }
+ return method.IsVirtual || annotation.ParameterAnnotations != null;
+ }
+
+ public bool ShouldWarnWhenAccessedForReflection (FieldDefinition field) =>
+ GetAnnotations (field.DeclaringType).TryGetAnnotation (field, out _);
+
TypeAnnotations GetAnnotations (TypeDefinition type)
{
if (!_annotations.TryGetValue (type, out TypeAnnotations value)) {
diff --git a/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs b/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs
index 282ffb5bf100..0fffc00318b0 100644
--- a/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs
+++ b/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs
@@ -128,7 +128,7 @@ public void ApplyDynamicallyAccessedMembersToType (ref ReflectionPatternContext
// Handle cases where a type has no members but annotations are to be applied to derived type members
reflectionPatternContext.RecordHandledPattern ();
- MarkTypeForDynamicallyAccessedMembers (ref reflectionPatternContext, type, annotation);
+ MarkTypeForDynamicallyAccessedMembers (ref reflectionPatternContext, type, annotation, DependencyKind.DynamicallyAccessedMemberOnType);
}
ValueNode GetValueNodeForCustomAttributeArgument (CustomAttributeArgument argument)
@@ -1032,7 +1032,7 @@ public override bool HandleCall (MethodBody callingMethodBody, MethodReference c
MarkType (ref reflectionContext, staticType);
var annotation = _markStep.DynamicallyAccessedMembersTypeHierarchy
- .ApplyDynamicallyAccessedMembersToTypeHierarchy (this, ref reflectionContext, staticType);
+ .ApplyDynamicallyAccessedMembersToTypeHierarchy (this, staticType);
reflectionContext.RecordHandledPattern ();
@@ -2230,7 +2230,7 @@ void RequireDynamicallyAccessedMembers (ref ReflectionPatternContext reflectionC
reflectionContext.RecordHandledPattern ();
}
} else if (uniqueValue is SystemTypeValue systemTypeValue) {
- MarkTypeForDynamicallyAccessedMembers (ref reflectionContext, systemTypeValue.TypeRepresented, requiredMemberTypes);
+ MarkTypeForDynamicallyAccessedMembers (ref reflectionContext, systemTypeValue.TypeRepresented, requiredMemberTypes, DependencyKind.DynamicallyAccessedMember);
} else if (uniqueValue is KnownStringValue knownStringValue) {
TypeReference typeRef = _context.TypeNameResolver.ResolveTypeName (knownStringValue.Contents, reflectionContext.Source, out AssemblyDefinition typeAssembly);
TypeDefinition foundType = ResolveToTypeDefinition (typeRef);
@@ -2239,7 +2239,7 @@ void RequireDynamicallyAccessedMembers (ref ReflectionPatternContext reflectionC
reflectionContext.RecordHandledPattern ();
} else {
MarkType (ref reflectionContext, typeRef);
- MarkTypeForDynamicallyAccessedMembers (ref reflectionContext, foundType, requiredMemberTypes);
+ MarkTypeForDynamicallyAccessedMembers (ref reflectionContext, foundType, requiredMemberTypes, DependencyKind.DynamicallyAccessedMember);
_context.MarkingHelpers.MarkMatchingExportedType (foundType, typeAssembly, new DependencyInfo (DependencyKind.DynamicallyAccessedMember, foundType));
}
} else if (uniqueValue == NullValue.Instance) {
@@ -2286,31 +2286,31 @@ void RequireDynamicallyAccessedMembers (ref ReflectionPatternContext reflectionC
static bool HasBindingFlag (BindingFlags? bindingFlags, BindingFlags? search) => bindingFlags != null && (bindingFlags & search) == search;
- void MarkTypeForDynamicallyAccessedMembers (ref ReflectionPatternContext reflectionContext, TypeDefinition typeDefinition, DynamicallyAccessedMemberTypes requiredMemberTypes)
+ void MarkTypeForDynamicallyAccessedMembers (ref ReflectionPatternContext reflectionContext, TypeDefinition typeDefinition, DynamicallyAccessedMemberTypes requiredMemberTypes, DependencyKind dependencyKind)
{
foreach (var member in typeDefinition.GetDynamicallyAccessedMembers (_context, requiredMemberTypes)) {
switch (member) {
case MethodDefinition method:
- MarkMethod (ref reflectionContext, method, DependencyKind.DynamicallyAccessedMember);
+ MarkMethod (ref reflectionContext, method, dependencyKind);
break;
case FieldDefinition field:
- MarkField (ref reflectionContext, field, DependencyKind.DynamicallyAccessedMember);
+ MarkField (ref reflectionContext, field, dependencyKind);
break;
case TypeDefinition nestedType:
- DependencyInfo nestedDependencyInfo = new DependencyInfo (DependencyKind.DynamicallyAccessedMember, reflectionContext.Source);
+ DependencyInfo nestedDependencyInfo = new DependencyInfo (dependencyKind, reflectionContext.Source);
reflectionContext.RecordRecognizedPattern (nestedType, () => _markStep.MarkEntireType (nestedType, includeBaseAndInterfaceTypes: true, nestedDependencyInfo));
break;
case PropertyDefinition property:
- MarkProperty (ref reflectionContext, property, DependencyKind.DynamicallyAccessedMember);
+ MarkProperty (ref reflectionContext, property, dependencyKind);
break;
case EventDefinition @event:
- MarkEvent (ref reflectionContext, @event, DependencyKind.DynamicallyAccessedMember);
+ MarkEvent (ref reflectionContext, @event, dependencyKind);
break;
case InterfaceImplementation interfaceImplementation:
- MarkInterfaceImplementation (ref reflectionContext, interfaceImplementation, DependencyKind.DynamicallyAccessedMember);
+ MarkInterfaceImplementation (ref reflectionContext, interfaceImplementation, dependencyKind);
break;
case null:
- DependencyInfo dependencyInfo = new DependencyInfo (DependencyKind.DynamicallyAccessedMember, reflectionContext.Source);
+ DependencyInfo dependencyInfo = new DependencyInfo (dependencyKind, reflectionContext.Source);
reflectionContext.RecordRecognizedPattern (typeDefinition, () => _markStep.MarkEntireType (typeDefinition, includeBaseAndInterfaceTypes: true, dependencyInfo));
break;
}
diff --git a/src/linker/Linker.Steps/MarkStep.cs b/src/linker/Linker.Steps/MarkStep.cs
index 0c18f77172c2..cf127007e5d6 100644
--- a/src/linker/Linker.Steps/MarkStep.cs
+++ b/src/linker/Linker.Steps/MarkStep.cs
@@ -72,6 +72,7 @@ internal DynamicallyAccessedMembersTypeHierarchy DynamicallyAccessedMembersTypeH
DependencyKind.AccessedViaReflection,
DependencyKind.BaseType,
DependencyKind.DynamicallyAccessedMember,
+ DependencyKind.DynamicallyAccessedMemberOnType,
DependencyKind.DynamicDependency,
DependencyKind.NestedType,
DependencyKind.TypeInAssembly,
@@ -85,6 +86,7 @@ internal DynamicallyAccessedMembersTypeHierarchy DynamicallyAccessedMembersTypeH
DependencyKind.Custom,
DependencyKind.CustomAttributeField,
DependencyKind.DynamicallyAccessedMember,
+ DependencyKind.DynamicallyAccessedMemberOnType,
DependencyKind.EventSourceProviderField,
DependencyKind.FieldAccess,
DependencyKind.FieldOnGenericInstance,
@@ -110,6 +112,7 @@ internal DynamicallyAccessedMembersTypeHierarchy DynamicallyAccessedMembersTypeH
DependencyKind.DeclaringType,
DependencyKind.DeclaringTypeOfCalledMethod,
DependencyKind.DynamicallyAccessedMember,
+ DependencyKind.DynamicallyAccessedMemberOnType,
DependencyKind.DynamicDependency,
DependencyKind.ElementType,
DependencyKind.FieldType,
@@ -146,6 +149,7 @@ internal DynamicallyAccessedMembersTypeHierarchy DynamicallyAccessedMembersTypeH
DependencyKind.DefaultCtorForNewConstrainedGenericArgument,
DependencyKind.DirectCall,
DependencyKind.DynamicallyAccessedMember,
+ DependencyKind.DynamicallyAccessedMemberOnType,
DependencyKind.DynamicDependency,
DependencyKind.ElementMethod,
DependencyKind.EventMethod,
@@ -329,7 +333,7 @@ void MarkEntireTypeInternal (TypeDefinition type, bool includeBaseAndInterfaceTy
_entireTypesMarked[type] = includeBaseAndInterfaceTypes;
- bool isDynamicDependencyReason = reason.Kind == DependencyKind.DynamicallyAccessedMember || reason.Kind == DependencyKind.DynamicDependency;
+ bool isDynamicDependencyReason = reason.Kind == DependencyKind.DynamicallyAccessedMember || reason.Kind == DependencyKind.DynamicDependency || reason.Kind == DependencyKind.DynamicallyAccessedMemberOnType;
if (type.HasNestedTypes) {
foreach (TypeDefinition nested in type.NestedTypes)
@@ -1540,6 +1544,57 @@ protected void MarkField (FieldReference reference, DependencyInfo reason)
MarkField (field, reason);
}
+ void ReportWarningsForTypeHierarchyReflectionAccess (IMemberDefinition member)
+ {
+ Debug.Assert (member is MethodDefinition or FieldDefinition);
+
+ // Don't check whether the current scope is a RUC type or RUC method because these warnings
+ // are not suppressed in RUC scopes. Here the scope represents the DynamicallyAccessedMembers
+ // annotation on a type, not a callsite which uses the annotation. We always want to warn about
+ // possible reflection access indicated by these annotations.
+
+ var type = _scopeStack.CurrentScope.Origin.MemberDefinition as TypeDefinition;
+ Debug.Assert (type != null);
+
+ static bool IsDeclaredWithinType (IMemberDefinition member, TypeDefinition type)
+ {
+ while ((member = member.DeclaringType) != null) {
+ if (member == type)
+ return true;
+ }
+ return false;
+ }
+
+ var reportOnMember = IsDeclaredWithinType (member, type);
+ var memberScope = reportOnMember ? _scopeStack.PushScope (new MessageOrigin (member)) : null;
+
+ try {
+ var origin = _scopeStack.CurrentScope.Origin;
+
+ if (member is MethodDefinition method && DoesMethodRequireUnreferencedCode (method, out RequiresUnreferencedCodeAttribute attribute)) {
+ var message = string.Format (
+ "'DynamicallyAccessedMembersAttribute' on '{0}' or one of its base types references '{1}' which requires unreferenced code.{2}{3}",
+ type.GetDisplayName (),
+ method.GetDisplayName (),
+ MessageFormat.FormatRequiresAttributeMessageArg (attribute.Message),
+ MessageFormat.FormatRequiresAttributeMessageArg (attribute.Url));
+ var code = reportOnMember ? 2112 : 2113;
+ _context.LogWarning (message, code, origin, MessageSubCategory.TrimAnalysis);
+ }
+
+ if (_context.Annotations.FlowAnnotations.ShouldWarnWhenAccessedForReflection (member)) {
+ var message = string.Format (
+ "'DynamicallyAccessedMembersAttribute' on '{0}' or one of its base types references '{1}' which has 'DynamicallyAccessedMembersAttribute' requirements.",
+ type.GetDisplayName (),
+ (member as MemberReference).GetDisplayName ());
+ var code = reportOnMember ? 2114 : 2115;
+ _context.LogWarning (message, code, origin, MessageSubCategory.TrimAnalysis);
+ }
+ } finally {
+ memberScope?.Dispose ();
+ }
+ }
+
void MarkField (FieldDefinition field, in DependencyInfo reason)
{
#if DEBUG
@@ -1553,6 +1608,25 @@ void MarkField (FieldDefinition field, in DependencyInfo reason)
Annotations.Mark (field, reason);
}
+ switch (reason.Kind) {
+ case DependencyKind.AccessedViaReflection:
+ case DependencyKind.DynamicDependency:
+ case DependencyKind.DynamicallyAccessedMember:
+ case DependencyKind.InteropMethodDependency:
+ if (_context.Annotations.FlowAnnotations.ShouldWarnWhenAccessedForReflection (field) &&
+ !ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode ())
+ _context.LogWarning (
+ $"Field '{field.GetDisplayName ()}' with 'DynamicallyAccessedMembersAttribute' is accessed via reflection. Trimmer can't guarantee availability of the requirements of the field.",
+ 2110,
+ _scopeStack.CurrentScope.Origin,
+ MessageSubCategory.TrimAnalysis);
+
+ break;
+ case DependencyKind.DynamicallyAccessedMemberOnType:
+ ReportWarningsForTypeHierarchyReflectionAccess (field);
+ break;
+ }
+
if (CheckProcessed (field))
return;
@@ -1671,8 +1745,13 @@ internal void MarkPropertyVisibleToReflection (PropertyDefinition property, in D
internal void MarkEventVisibleToReflection (EventDefinition @event, in DependencyInfo reason)
{
- // MarkEvent actually marks the add/remove/invoke methods as well, so no need to mark those explicitly
MarkEvent (@event, reason);
+ // MarkEvent already marks the add/remove/invoke methods, but we need to mark them with the
+ // DependencyInfo used to access the event from reflection, to produce warnings for annotated
+ // event methods.
+ MarkMethodIfNotNull (@event.AddMethod, reason);
+ MarkMethodIfNotNull (@event.InvokeMethod, reason);
+ MarkMethodIfNotNull (@event.InvokeMethod, reason);
MarkMethodsIf (@event.OtherMethods, m => true, reason);
}
@@ -2705,12 +2784,12 @@ protected virtual MethodDefinition MarkMethod (MethodReference reference, Depend
// Use the original reason as it's important to correctly generate warnings
// the updated reason is only useful for better tracking of dependencies.
- ProcessRequiresUnreferencedCode (method, originalReasonKind);
+ ProcessAnalysisAnnotationsForMethod (method, originalReasonKind);
return method;
}
- void ProcessRequiresUnreferencedCode (MethodDefinition method, DependencyKind dependencyKind)
+ void ProcessAnalysisAnnotationsForMethod (MethodDefinition method, DependencyKind dependencyKind)
{
switch (dependencyKind) {
// DirectCall, VirtualCall and NewObj are handled by ReflectionMethodBodyScanner
@@ -2766,25 +2845,52 @@ void ProcessRequiresUnreferencedCode (MethodDefinition method, DependencyKind de
case DependencyKind.KeptForSpecialAttribute:
return;
- default:
- // DirectCall, VirtualCall and NewObj are handled by ReflectionMethodBodyScanner
- // This is necessary since the ReflectionMethodBodyScanner has intrinsic handling for some
- // of the annotated methods annotated (for example Type.GetType)
- // and it knows when it's OK and when it needs a warning. In this place we don't know
- // and would have to warn every time
+ case DependencyKind.DynamicallyAccessedMember:
+ case DependencyKind.DynamicallyAccessedMemberOnType:
+ // All override methods should have the same annotations as their base methods
+ // (else we will produce warning IL2046 or IL2092 or some other warning).
+ // When marking override methods via DynamicallyAccessedMembers, we should only issue a warning for the base method.
+ if (method.IsVirtual && Annotations.GetBaseMethods (method) != null)
+ return;
+ break;
+ default:
// All other cases have the potential of us missing a warning if we don't report it
// It is possible that in some cases we may report the same warning twice, but that's better than not reporting it.
break;
}
- // All override methods should have the same annotations as their base methods (else we will produce warning IL2046.)
- // When marking override methods with RequiresUnreferencedCode on a type annotated with DynamicallyAccessedMembers,
- // we should only issue a warning for the base method.
- if (dependencyKind != DependencyKind.DynamicallyAccessedMember ||
- !method.IsVirtual ||
- Annotations.GetBaseMethods (method) == null)
- CheckAndReportRequiresUnreferencedCode (method);
+ if (dependencyKind == DependencyKind.DynamicallyAccessedMemberOnType) {
+ // DynamicallyAccessedMembers on type gets special treatment so that the warning origin
+ // is the type or the annotated member.
+ ReportWarningsForTypeHierarchyReflectionAccess (method);
+ return;
+ }
+
+ CheckAndReportRequiresUnreferencedCode (method);
+
+ if (_context.Annotations.FlowAnnotations.ShouldWarnWhenAccessedForReflection (method)) {
+ // If the current scope has analysis warnings suppressed, don't generate any
+ if (ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode ())
+ return;
+
+ // ReflectionMethodBodyScanner handles more cases for data flow annotations
+ // so don't warn for those.
+ switch (dependencyKind) {
+ case DependencyKind.AttributeConstructor:
+ case DependencyKind.AttributeProperty:
+ return;
+
+ default:
+ break;
+ }
+
+ _context.LogWarning (
+ $"Method '{method.GetDisplayName ()}' with parameters or return value with `DynamicallyAccessedMembersAttribute` is accessed via reflection. Trimmer can't guarantee availability of the requirements of the method.",
+ 2111,
+ _scopeStack.CurrentScope.Origin,
+ MessageSubCategory.TrimAnalysis);
+ }
}
internal bool ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode ()
@@ -2812,24 +2918,29 @@ internal bool ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode ()
return false;
}
- internal void CheckAndReportRequiresUnreferencedCode (MethodDefinition method)
+ bool DoesMethodRequireUnreferencedCode (MethodDefinition method, out RequiresUnreferencedCodeAttribute attribute)
{
- var currentOrigin = _scopeStack.CurrentScope.Origin;
+ if (Annotations.TryGetLinkerAttribute (method, out attribute))
+ return true;
+
+ if ((method.IsStatic || method.IsConstructor) &&
+ Annotations.TryGetEffectiveRequiresUnreferencedCodeAttributeOnType (method.DeclaringType, out attribute))
+ return true;
+
+ return false;
+ }
+ internal void CheckAndReportRequiresUnreferencedCode (MethodDefinition method)
+ {
// If the caller of a method is already marked with `RequiresUnreferencedCodeAttribute` a new warning should not
// be produced for the callee.
if (ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode ())
return;
- if (method.IsStatic || method.IsConstructor) {
- if (Annotations.TryGetEffectiveRequiresUnreferencedCodeAttributeOnType (method.DeclaringType, out RequiresUnreferencedCodeAttribute requiresUnreferencedCodeOnTypeHierarchy)) {
- ReportRequiresUnreferencedCode (method.GetDisplayName (), requiresUnreferencedCodeOnTypeHierarchy, currentOrigin);
- return;
- }
- }
+ if (!DoesMethodRequireUnreferencedCode (method, out RequiresUnreferencedCodeAttribute requiresUnreferencedCode))
+ return;
- if (Annotations.TryGetLinkerAttribute (method, out RequiresUnreferencedCodeAttribute requiresUnreferencedCode))
- ReportRequiresUnreferencedCode (method.GetDisplayName (), requiresUnreferencedCode, currentOrigin);
+ ReportRequiresUnreferencedCode (method.GetDisplayName (), requiresUnreferencedCode, _scopeStack.CurrentScope.Origin);
}
private void ReportRequiresUnreferencedCode (string displayName, RequiresUnreferencedCodeAttribute requiresUnreferencedCode, MessageOrigin currentOrigin)
diff --git a/src/linker/Linker.Steps/ValidateVirtualMethodAnnotationsStep.cs b/src/linker/Linker.Steps/ValidateVirtualMethodAnnotationsStep.cs
index a2696458777a..c3787a12e0e2 100644
--- a/src/linker/Linker.Steps/ValidateVirtualMethodAnnotationsStep.cs
+++ b/src/linker/Linker.Steps/ValidateVirtualMethodAnnotationsStep.cs
@@ -43,8 +43,10 @@ void ValidateMethodRequiresUnreferencedCodeAreSame (MethodDefinition method, Met
var annotations = Context.Annotations;
bool methodHasAttribute = annotations.HasLinkerAttribute (method);
if (methodHasAttribute != annotations.HasLinkerAttribute (baseMethod)) {
- string message = MessageFormat.FormatRequiresAttributeMismatch (methodHasAttribute, baseMethod.DeclaringType.IsInterface, nameof (RequiresUnreferencedCodeAttribute), method.GetDisplayName (), baseMethod.GetDisplayName ());
- Context.LogWarning (string.Format (SharedStrings.RequiresAttributeMismatchMessage, message), 2046, method, subcategory: MessageSubCategory.TrimAnalysis);
+ string message = MessageFormat.FormatRequiresAttributeMismatch (methodHasAttribute,
+ baseMethod.DeclaringType.IsInterface, nameof (RequiresUnreferencedCodeAttribute), method.GetDisplayName (), baseMethod.GetDisplayName ());
+ Context.LogWarning (new DiagnosticString (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).GetMessage (message),
+ 2046, method, subcategory: MessageSubCategory.TrimAnalysis);
}
}
}
diff --git a/src/linker/Linker/DependencyInfo.cs b/src/linker/Linker/DependencyInfo.cs
index 5ebaa2d81975..72ab233df3dc 100644
--- a/src/linker/Linker/DependencyInfo.cs
+++ b/src/linker/Linker/DependencyInfo.cs
@@ -137,7 +137,9 @@ public enum DependencyKind
SerializedRecursiveType = 85, // recursive type kept due to serialization handling
SerializedMember = 86, // field or property kept on a type for serialization
- PreservedOperator = 87 // operator method preserved on a type
+ PreservedOperator = 87, // operator method preserved on a type
+
+ DynamicallyAccessedMemberOnType = 88, // type with DynamicallyAccessedMembers annotations (including those inherited from base types and interfaces)
}
public readonly struct DependencyInfo : IEquatable
diff --git a/test/ILLink.RoslynAnalyzer.Tests/RequiresAssemblyFilesAnalyzerTests.cs b/test/ILLink.RoslynAnalyzer.Tests/RequiresAssemblyFilesAnalyzerTests.cs
index cf09be77e9d8..5d9801dd2b0c 100644
--- a/test/ILLink.RoslynAnalyzer.Tests/RequiresAssemblyFilesAnalyzerTests.cs
+++ b/test/ILLink.RoslynAnalyzer.Tests/RequiresAssemblyFilesAnalyzerTests.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using ILLink.Shared;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Testing;
@@ -73,7 +74,7 @@ void M()
}";
return VerifyRequiresAssemblyFilesAnalyzer (TestRequiresAssemblyFieldsOnEvent,
// (12,17): warning IL3002: Using member 'C.E' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (12, 17, 12, 18).WithArguments ("C.E", "", ""));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (12, 17, 12, 18).WithArguments ("C.E", "", ""));
}
[Fact]
@@ -96,7 +97,7 @@ void M2()
}";
return VerifyRequiresAssemblyFilesAnalyzer (TestRequiresAssemblyFilesOnMethod,
// (13,3): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (13, 3, 13, 7).WithArguments ("C.M1()", "", ""));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (13, 3, 13, 7).WithArguments ("C.M1()", "", ""));
}
[Fact]
@@ -119,9 +120,9 @@ void M()
}";
return VerifyRequiresAssemblyFilesAnalyzer (TestRequiresAssemblyFilesOnProperty,
// (11,3): warning IL3002: Using member 'C.P' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (12, 3, 12, 4).WithArguments ("C.P", "", ""),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (12, 3, 12, 4).WithArguments ("C.P", "", ""),
// (13,12): warning IL3002: Using member 'C.P' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (13, 35, 13, 36).WithArguments ("C.P", "", ""));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (13, 35, 13, 36).WithArguments ("C.P", "", ""));
}
[Fact]
@@ -155,7 +156,7 @@ void M ()
}";
return VerifyRequiresAssemblyFilesAnalyzer (TestRequiresAssemblyFilesOnMethodInsideProperty,
// (24,3): warning IL3002: Using member 'C.P' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (24, 3, 24, 4).WithArguments ("C.P", "", ""));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (24, 3, 24, 4).WithArguments ("C.P", "", ""));
}
[Fact]
@@ -178,7 +179,7 @@ void M2()
}";
return VerifyRequiresAssemblyFilesAnalyzer (TestRequiresAssemblyFilesWithMessageAndUrl,
// (13,3): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. Message from attribute. https://helpurl
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (13, 3, 13, 7).WithArguments ("C.M1()", " Message from attribute.", " https://helpurl"));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (13, 3, 13, 7).WithArguments ("C.M1()", " Message from attribute.", " https://helpurl"));
}
[Fact]
@@ -201,7 +202,7 @@ void M2()
}";
return VerifyRequiresAssemblyFilesAnalyzer (TestRequiresAssemblyFilesWithMessageAndUrl,
// (13,3): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. https://helpurl
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (13, 3, 13, 7).WithArguments ("C.M1()", "", " https://helpurl"));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (13, 3, 13, 7).WithArguments ("C.M1()", "", " https://helpurl"));
}
[Fact]
@@ -244,7 +245,7 @@ void M3()
}";
return VerifyRequiresAssemblyFilesAnalyzer (TestNoDiagnosticIsProducedIfCallerIsAnnotated,
// (8,3): warning IL3002: Using member 'C.M2()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. Warn from M2.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (8, 3, 8, 7).WithArguments ("C.M2()", " Warn from M2.", ""));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (8, 3, 8, 7).WithArguments ("C.M2()", " Warn from M2.", ""));
}
[Fact]
@@ -259,7 +260,7 @@ class C
return VerifyRequiresAssemblyFilesAnalyzer (src,
// (5,26): warning IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3000).WithSpan (5, 26, 5, 66).WithArguments ("System.Reflection.Assembly.Location"));
+ VerifyCS.Diagnostic (DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan (5, 26, 5, 66).WithArguments ("System.Reflection.Assembly.Location"));
}
[Fact]
@@ -280,7 +281,7 @@ public void M()
}";
return VerifyRequiresAssemblyFilesAnalyzer (src,
// (8,13): warning IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3000).WithSpan (8, 13, 8, 23).WithArguments ("System.Reflection.Assembly.Location")
+ VerifyCS.Diagnostic (DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan (8, 13, 8, 23).WithArguments ("System.Reflection.Assembly.Location")
);
}
@@ -300,9 +301,9 @@ public void M()
}";
return VerifyRequiresAssemblyFilesAnalyzer (src,
// (8,13): warning IL3001: Assemblies embedded in a single-file app cannot have additional files in the manifest.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3001).WithSpan (8, 13, 8, 41).WithArguments ("System.Reflection.Assembly.GetFile(string)"),
+ VerifyCS.Diagnostic (DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan (8, 13, 8, 41).WithArguments ("System.Reflection.Assembly.GetFile(string)"),
// (9,13): warning IL3001: Assemblies embedded in a single-file app cannot have additional files in the manifest.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3001).WithSpan (9, 13, 9, 25).WithArguments ("System.Reflection.Assembly.GetFiles()")
+ VerifyCS.Diagnostic (DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan (9, 13, 9, 25).WithArguments ("System.Reflection.Assembly.GetFiles()")
);
}
@@ -322,11 +323,11 @@ public void M()
}";
return VerifyRequiresAssemblyFilesAnalyzer (src,
// (8,13): warning IL3002: Using member 'System.Reflection.AssemblyName.CodeBase.get' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. The code will return an empty string for assemblies embedded in a single-file app.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (8, 13, 8, 23).WithArguments ("System.Reflection.AssemblyName.CodeBase.get", " The code will return an empty string for assemblies embedded in a single-file app.", ""),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (8, 13, 8, 23).WithArguments ("System.Reflection.AssemblyName.CodeBase.get", " The code will return an empty string for assemblies embedded in a single-file app.", ""),
// (8,13): warning IL3000: 'System.Reflection.AssemblyName.CodeBase' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3000).WithSpan (8, 13, 8, 23).WithArguments ("System.Reflection.AssemblyName.CodeBase"),
+ VerifyCS.Diagnostic (DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan (8, 13, 8, 23).WithArguments ("System.Reflection.AssemblyName.CodeBase"),
// (9,13): warning IL3000: 'System.Reflection.AssemblyName.EscapedCodeBase' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3000).WithSpan (9, 13, 9, 30).WithArguments ("System.Reflection.AssemblyName.EscapedCodeBase")
+ VerifyCS.Diagnostic (DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan (9, 13, 9, 30).WithArguments ("System.Reflection.AssemblyName.EscapedCodeBase")
);
}
@@ -348,9 +349,9 @@ public void M()
}";
return VerifyRequiresAssemblyFilesAnalyzer (src,
// (8,13): warning IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3000).WithSpan (8, 13, 8, 23).WithArguments ("System.Reflection.Assembly.Location"),
+ VerifyCS.Diagnostic (DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan (8, 13, 8, 23).WithArguments ("System.Reflection.Assembly.Location"),
// (9,13): warning IL3001: Assemblies embedded in a single-file app cannot have additional files in the manifest.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3001).WithSpan (9, 13, 9, 25).WithArguments ("System.Reflection.Assembly.GetFiles()")
+ VerifyCS.Diagnostic (DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan (9, 13, 9, 25).WithArguments ("System.Reflection.Assembly.GetFiles()")
);
}
@@ -413,7 +414,7 @@ public static C InitC() {
return VerifyRequiresAssemblyFilesAnalyzer (src,
// (6,50): warning IL3002: Using member 'C.InitC()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (6, 50, 6, 55).WithArguments ("C.InitC()", "", ""));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (6, 50, 6, 55).WithArguments ("C.InitC()", "", ""));
}
[Fact]
@@ -435,9 +436,9 @@ public static void M2()
return VerifyRequiresAssemblyFilesAnalyzer (src,
// (10,20): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (10, 20, 10, 22).WithArguments ("C.M1()", "", ""),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (10, 20, 10, 22).WithArguments ("C.M1()", "", ""),
// (11,26): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (11, 26, 11, 30).WithArguments ("C.M1()", "", ""));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (11, 26, 11, 30).WithArguments ("C.M1()", "", ""));
}
[Fact]
@@ -500,13 +501,13 @@ public class F
fixtest,
baselineExpected: new[] {
// /0/Test0.cs(7,17): warning IL3002: Using method 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when trimming application code. message.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (7, 17, 7, 21).WithArguments ("C.M1()", " message.", ""),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (7, 17, 7, 21).WithArguments ("C.M1()", " message.", ""),
// /0/Test0.cs(11,27): warning IL3002: Using method 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when trimming application code. message.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (11, 27, 11, 33).WithArguments ("C.M1()", " message.", ""),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (11, 27, 11, 33).WithArguments ("C.M1()", " message.", ""),
// /0/Test0.cs(14,31): warning IL3002: Using method 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when trimming application code. message.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (14, 31, 14, 37).WithArguments ("C.M1()", " message.", ""),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (14, 31, 14, 37).WithArguments ("C.M1()", " message.", ""),
// /0/Test0.cs(21,31): warning IL3002: Using method 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when trimming application code. message.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (21, 31, 21, 37).WithArguments ("C.M1()", " message.", "")
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (21, 31, 21, 37).WithArguments ("C.M1()", " message.", "")
},
fixedExpected: Array.Empty ());
}
@@ -547,9 +548,9 @@ public void M2() {
fixtest,
baselineExpected: new[] {
// /0/Test0.cs(7,27): warning IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3000).WithSpan (7, 27, 7, 44).WithArguments ("System.Reflection.Assembly.Location", "", ""),
+ VerifyCS.Diagnostic (DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan (7, 27, 7, 44).WithArguments ("System.Reflection.Assembly.Location", "", ""),
// /0/Test0.cs(9,13): warning IL3001: 'System.Reflection.Assembly.GetFiles()' will throw for assemblies embedded in a single-file app
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3001).WithSpan (9, 13, 9, 32).WithArguments("System.Reflection.Assembly.GetFiles()", "", ""),
+ VerifyCS.Diagnostic (DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan (9, 13, 9, 32).WithArguments("System.Reflection.Assembly.GetFiles()", "", ""),
},
fixedExpected: Array.Empty ());
}
@@ -585,7 +586,7 @@ public class C
fix,
baselineExpected: new[] {
// /0/Test0.cs(10,15): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message.
- VerifyCS.Diagnostic(RequiresAssemblyFilesAnalyzer.IL3002).WithSpan(10, 15, 10, 19).WithArguments("C.M1()", " message.", "")
+ VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(10, 15, 10, 19).WithArguments("C.M1()", " message.", "")
},
fixedExpected: Array.Empty ());
}
@@ -627,11 +628,11 @@ public static C InitC() {
fixtest,
baselineExpected: new[] {
// /0/Test0.cs(6,50): warning IL3002: Using member 'C.InitC()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (6, 50, 6, 55).WithArguments ("C.InitC()", "", ""),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (6, 50, 6, 55).WithArguments ("C.InitC()", "", ""),
},
fixedExpected: new[] {
// /0/Test0.cs(6,50): warning IL3002: Using member 'C.InitC()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (6, 50, 6, 55).WithArguments ("C.InitC()", "", ""),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (6, 50, 6, 55).WithArguments ("C.InitC()", "", ""),
});
}
@@ -675,7 +676,7 @@ Action M2()
fix,
baselineExpected: new[] {
// /0/Test0.cs(12,28): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message.
- VerifyCS.Diagnostic(RequiresAssemblyFilesAnalyzer.IL3002).WithSpan(12, 28, 12, 32).WithArguments("C.M1()", " message.", "")
+ VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(12, 28, 12, 32).WithArguments("C.M1()", " message.", "")
},
fixedExpected: Array.Empty (),
numberOfIterations: 2);
@@ -712,7 +713,7 @@ public class C
fix,
baselineExpected: new[] {
// /0/Test0.cs(10,15): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message.
- VerifyCS.Diagnostic(RequiresAssemblyFilesAnalyzer.IL3002).WithSpan(10, 20, 10, 24).WithArguments("C.M1()", " message.", "")
+ VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(10, 20, 10, 24).WithArguments("C.M1()", " message.", "")
},
fixedExpected: Array.Empty ());
}
@@ -762,7 +763,7 @@ public event EventHandler E1
fix,
baselineExpected: new[] {
// /0/Test0.cs(14,21): warning IL3002: Using method 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when trimming application code. message.
- VerifyCS.Diagnostic(RequiresAssemblyFilesAnalyzer.IL3002).WithSpan(14, 21, 14, 25).WithArguments("C.M1()", " message.", "")
+ VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(14, 21, 14, 25).WithArguments("C.M1()", " message.", "")
},
fixedExpected: Array.Empty ());
}
@@ -787,7 +788,7 @@ static void TestStaticCctorRequiresUnreferencedCode ()
}";
return VerifyRequiresAssemblyFilesAnalyzer (src,
// (13,7): warning IL3002: Using member 'StaticCtor.StaticCtor()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. Message for --TestStaticCtor--.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (13, 7, 13, 24).WithArguments ("StaticCtor.StaticCtor()", " Message for --TestStaticCtor--.", "")
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (13, 7, 13, 24).WithArguments ("StaticCtor.StaticCtor()", " Message for --TestStaticCtor--.", "")
);
}
@@ -816,7 +817,7 @@ static void TestStaticCtorMarkingIsTriggeredByFieldAccess ()
}";
return VerifyRequiresAssemblyFilesAnalyzer (src,
// (18,11): warning IL3002: Using member 'StaticCtorTriggeredByFieldAccess.StaticCtorTriggeredByFieldAccess()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app.. Message for --StaticCtorTriggeredByFieldAccess.Cctor--.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (18, 11, 18, 49).WithArguments ("StaticCtorTriggeredByFieldAccess.StaticCtorTriggeredByFieldAccess()", " Message for --StaticCtorTriggeredByFieldAccess.Cctor--.", "")
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (18, 11, 18, 49).WithArguments ("StaticCtorTriggeredByFieldAccess.StaticCtorTriggeredByFieldAccess()", " Message for --StaticCtorTriggeredByFieldAccess.Cctor--.", "")
);
}
@@ -848,9 +849,9 @@ static void TestStaticCtorTriggeredByMethodCall ()
}";
return VerifyRequiresAssemblyFilesAnalyzer (src,
// (21,3): warning IL3002: Using member 'StaticCtorTriggeredByMethodCall.TriggerStaticCtorMarking()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. Message for --StaticCtorTriggeredByMethodCall.TriggerStaticCtorMarking--.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (21, 3, 21, 69).WithArguments ("StaticCtorTriggeredByMethodCall.TriggerStaticCtorMarking()", " Message for --StaticCtorTriggeredByMethodCall.TriggerStaticCtorMarking--.", ""),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (21, 3, 21, 69).WithArguments ("StaticCtorTriggeredByMethodCall.TriggerStaticCtorMarking()", " Message for --StaticCtorTriggeredByMethodCall.TriggerStaticCtorMarking--.", ""),
// (21,3): warning IL3002: Using member 'StaticCtorTriggeredByMethodCall.StaticCtorTriggeredByMethodCall()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. Message for --StaticCtorTriggeredByMethodCall.Cctor--.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (21, 3, 21, 41).WithArguments ("StaticCtorTriggeredByMethodCall.StaticCtorTriggeredByMethodCall()", " Message for --StaticCtorTriggeredByMethodCall.Cctor--.", "")
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (21, 3, 21, 41).WithArguments ("StaticCtorTriggeredByMethodCall.StaticCtorTriggeredByMethodCall()", " Message for --StaticCtorTriggeredByMethodCall.Cctor--.", "")
);
}
@@ -891,11 +892,11 @@ public virtual void VirtualMethod ()
}";
return VerifyRequiresAssemblyFilesAnalyzer (src,
// (7,23): warning IL3003: Member 'DerivedClass.VirtualMethod()' with 'RequiresAssemblyFilesAttribute' overrides base member 'BaseClass.VirtualMethod()' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (7, 23, 7, 36).WithArguments ("Member 'DerivedClass.VirtualMethod()' with 'RequiresAssemblyFilesAttribute' overrides base member 'BaseClass.VirtualMethod()' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (7, 23, 7, 36).WithArguments ("Member 'DerivedClass.VirtualMethod()' with 'RequiresAssemblyFilesAttribute' overrides base member 'BaseClass.VirtualMethod()' without 'RequiresAssemblyFilesAttribute'"),
// (15,3): warning IL3003: Member 'DerivedClass.VirtualPropertyWithAnnotationInAccesor.get' with 'RequiresAssemblyFilesAttribute' overrides base member 'BaseClass.VirtualPropertyWithAnnotationInAccesor.get' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (15, 3, 15, 6).WithArguments ("Member 'DerivedClass.VirtualPropertyWithAnnotationInAccesor.get' with 'RequiresAssemblyFilesAttribute' overrides base member 'BaseClass.VirtualPropertyWithAnnotationInAccesor.get' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (15, 3, 15, 6).WithArguments ("Member 'DerivedClass.VirtualPropertyWithAnnotationInAccesor.get' with 'RequiresAssemblyFilesAttribute' overrides base member 'BaseClass.VirtualPropertyWithAnnotationInAccesor.get' without 'RequiresAssemblyFilesAttribute'"),
// (20,25): warning IL3003: Member 'DerivedClass.VirtualPropertyWithAnnotationInProperty' with 'RequiresAssemblyFilesAttribute' overrides base member 'BaseClass.VirtualPropertyWithAnnotationInProperty' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (20, 25, 20, 64).WithArguments ("Member 'DerivedClass.VirtualPropertyWithAnnotationInProperty' with 'RequiresAssemblyFilesAttribute' overrides base member 'BaseClass.VirtualPropertyWithAnnotationInProperty' without 'RequiresAssemblyFilesAttribute'"));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (20, 25, 20, 64).WithArguments ("Member 'DerivedClass.VirtualPropertyWithAnnotationInProperty' with 'RequiresAssemblyFilesAttribute' overrides base member 'BaseClass.VirtualPropertyWithAnnotationInProperty' without 'RequiresAssemblyFilesAttribute'"));
}
[Fact]
@@ -934,11 +935,11 @@ public virtual void VirtualMethod ()
}";
return VerifyRequiresAssemblyFilesAnalyzer (src,
// (6,23): warning IL3003: Base member 'BaseClass.VirtualMethod()' with 'RequiresAssemblyFilesAttribute' has a derived member 'DerivedClass.VirtualMethod()' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (6, 23, 6, 36).WithArguments ("Base member 'BaseClass.VirtualMethod()' with 'RequiresAssemblyFilesAttribute' has a derived member 'DerivedClass.VirtualMethod()' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (6, 23, 6, 36).WithArguments ("Base member 'BaseClass.VirtualMethod()' with 'RequiresAssemblyFilesAttribute' has a derived member 'DerivedClass.VirtualMethod()' without 'RequiresAssemblyFilesAttribute'"),
// (13,3): warning IL3003: Base member 'BaseClass.VirtualPropertyWithAnnotationInAccesor.get' with 'RequiresAssemblyFilesAttribute' has a derived member 'DerivedClass.VirtualPropertyWithAnnotationInAccesor.get' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (13, 3, 13, 6).WithArguments ("Base member 'BaseClass.VirtualPropertyWithAnnotationInAccesor.get' with 'RequiresAssemblyFilesAttribute' has a derived member 'DerivedClass.VirtualPropertyWithAnnotationInAccesor.get' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (13, 3, 13, 6).WithArguments ("Base member 'BaseClass.VirtualPropertyWithAnnotationInAccesor.get' with 'RequiresAssemblyFilesAttribute' has a derived member 'DerivedClass.VirtualPropertyWithAnnotationInAccesor.get' without 'RequiresAssemblyFilesAttribute'"),
// (17,25): warning IL3003: Base member 'BaseClass.VirtualPropertyWithAnnotationInProperty' with 'RequiresAssemblyFilesAttribute' has a derived member 'DerivedClass.VirtualPropertyWithAnnotationInProperty' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (17, 25, 17, 64).WithArguments ("Base member 'BaseClass.VirtualPropertyWithAnnotationInProperty' with 'RequiresAssemblyFilesAttribute' has a derived member 'DerivedClass.VirtualPropertyWithAnnotationInProperty' without 'RequiresAssemblyFilesAttribute'"));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (17, 25, 17, 64).WithArguments ("Base member 'BaseClass.VirtualPropertyWithAnnotationInProperty' with 'RequiresAssemblyFilesAttribute' has a derived member 'DerivedClass.VirtualPropertyWithAnnotationInProperty' without 'RequiresAssemblyFilesAttribute'"));
}
[Fact]
@@ -1020,17 +1021,17 @@ interface IRAF
}";
return VerifyRequiresAssemblyFilesAnalyzer (src,
// (7,14): warning IL3003: Member 'Implementation.Method()' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.Method()' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (7, 14, 7, 20).WithArguments ("Member 'Implementation.Method()' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.Method()' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (7, 14, 7, 20).WithArguments ("Member 'Implementation.Method()' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.Method()' without 'RequiresAssemblyFilesAttribute'"),
// (13,3): warning IL3003: Member 'Implementation.StringProperty.get' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.StringProperty.get' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (13, 3, 13, 6).WithArguments ("Member 'Implementation.StringProperty.get' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.StringProperty.get' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (13, 3, 13, 6).WithArguments ("Member 'Implementation.StringProperty.get' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.StringProperty.get' without 'RequiresAssemblyFilesAttribute'"),
// (19,13): warning IL3003: Member 'Implementation.NumProperty' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.NumProperty' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (19, 13, 19, 24).WithArguments ("Member 'Implementation.NumProperty' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.NumProperty' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (19, 13, 19, 24).WithArguments ("Member 'Implementation.NumProperty' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.NumProperty' without 'RequiresAssemblyFilesAttribute'"),
// (48,12): warning IL3003: Member 'ExplicitImplementation.IRAF.Method()' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.Method()' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (48, 12, 48, 18).WithArguments ("Member 'ExplicitImplementation.IRAF.Method()' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.Method()' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (48, 12, 48, 18).WithArguments ("Member 'ExplicitImplementation.IRAF.Method()' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.Method()' without 'RequiresAssemblyFilesAttribute'"),
// (54,3): warning IL3003: Member 'ExplicitImplementation.IRAF.StringProperty.get' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.StringProperty.get' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (54, 3, 54, 6).WithArguments ("Member 'ExplicitImplementation.IRAF.StringProperty.get' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.StringProperty.get' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (54, 3, 54, 6).WithArguments ("Member 'ExplicitImplementation.IRAF.StringProperty.get' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.StringProperty.get' without 'RequiresAssemblyFilesAttribute'"),
// (60,11): warning IL3003: Member 'ExplicitImplementation.IRAF.NumProperty' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.NumProperty' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (60, 11, 60, 22).WithArguments ("Member 'ExplicitImplementation.IRAF.NumProperty' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.NumProperty' without 'RequiresAssemblyFilesAttribute'"));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (60, 11, 60, 22).WithArguments ("Member 'ExplicitImplementation.IRAF.NumProperty' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.NumProperty' without 'RequiresAssemblyFilesAttribute'"));
}
[Fact]
@@ -1087,17 +1088,17 @@ interface IRAF
}";
return VerifyRequiresAssemblyFilesAnalyzer (src,
// (6,14): warning IL3003: Interface member 'IRAF.Method()' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.Method()' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (6, 14, 6, 20).WithArguments ("Interface member 'IRAF.Method()' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.Method()' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (6, 14, 6, 20).WithArguments ("Interface member 'IRAF.Method()' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.Method()' without 'RequiresAssemblyFilesAttribute'"),
// (11,3): warning IL3003: Interface member 'IRAF.StringProperty.get' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.StringProperty.get' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (11, 3, 11, 6).WithArguments ("Interface member 'IRAF.StringProperty.get' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.StringProperty.get' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (11, 3, 11, 6).WithArguments ("Interface member 'IRAF.StringProperty.get' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.StringProperty.get' without 'RequiresAssemblyFilesAttribute'"),
// (16,13): warning IL3003: Interface member 'IRAF.NumProperty' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.NumProperty' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (16, 13, 16, 24).WithArguments ("Interface member 'IRAF.NumProperty' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.NumProperty' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (16, 13, 16, 24).WithArguments ("Interface member 'IRAF.NumProperty' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.NumProperty' without 'RequiresAssemblyFilesAttribute'"),
// (25,14): warning IL3003: Interface member 'IRAF.Method()' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.Method()' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (25, 14, 25, 20).WithArguments ("Interface member 'IRAF.Method()' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.Method()' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (25, 14, 25, 20).WithArguments ("Interface member 'IRAF.Method()' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.Method()' without 'RequiresAssemblyFilesAttribute'"),
// (30,3): warning IL3003: Interface member 'IRAF.StringProperty.get' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.StringProperty.get' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (30, 3, 30, 6).WithArguments ("Interface member 'IRAF.StringProperty.get' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.StringProperty.get' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (30, 3, 30, 6).WithArguments ("Interface member 'IRAF.StringProperty.get' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.StringProperty.get' without 'RequiresAssemblyFilesAttribute'"),
// (35,13): warning IL3003: Interface member 'IRAF.NumProperty' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.NumProperty' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (35, 13, 35, 24).WithArguments ("Interface member 'IRAF.NumProperty' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.NumProperty' without 'RequiresAssemblyFilesAttribute'"));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (35, 13, 35, 24).WithArguments ("Interface member 'IRAF.NumProperty' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.NumProperty' without 'RequiresAssemblyFilesAttribute'"));
}
[Fact]
@@ -1158,17 +1159,17 @@ public int NumProperty
await VerifyRequiresAssemblyFilesAnalyzer (src, additionalReferences: new[] { compilation },
// (4,14): warning IL3003: Interface member 'IRAF.Method()' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.Method()' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (4, 14, 4, 20).WithArguments ("Interface member 'IRAF.Method()' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.Method()' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (4, 14, 4, 20).WithArguments ("Interface member 'IRAF.Method()' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.Method()' without 'RequiresAssemblyFilesAttribute'"),
// (9,3): warning IL3003: Interface member 'IRAF.StringProperty.get' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.StringProperty.get' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (9, 3, 9, 6).WithArguments ("Interface member 'IRAF.StringProperty.get' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.StringProperty.get' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (9, 3, 9, 6).WithArguments ("Interface member 'IRAF.StringProperty.get' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.StringProperty.get' without 'RequiresAssemblyFilesAttribute'"),
// (14,13): warning IL3003: Interface member 'IRAF.NumProperty' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.NumProperty' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (14, 13, 14, 24).WithArguments ("Interface member 'IRAF.NumProperty' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.NumProperty' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (14, 13, 14, 24).WithArguments ("Interface member 'IRAF.NumProperty' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.NumProperty' without 'RequiresAssemblyFilesAttribute'"),
// (23,14): warning IL3003: Interface member 'IRAF.Method()' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.Method()' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (23, 14, 23, 20).WithArguments ("Interface member 'IRAF.Method()' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.Method()' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (23, 14, 23, 20).WithArguments ("Interface member 'IRAF.Method()' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.Method()' without 'RequiresAssemblyFilesAttribute'"),
// (28,3): warning IL3003: Interface member 'IRAF.StringProperty.get' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.StringProperty.get' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (28, 3, 28, 6).WithArguments ("Interface member 'IRAF.StringProperty.get' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.StringProperty.get' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (28, 3, 28, 6).WithArguments ("Interface member 'IRAF.StringProperty.get' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.StringProperty.get' without 'RequiresAssemblyFilesAttribute'"),
// (33,13): warning IL3003: Interface member 'IRAF.NumProperty' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.NumProperty' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (33, 13, 33, 24).WithArguments ("Interface member 'IRAF.NumProperty' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.NumProperty' without 'RequiresAssemblyFilesAttribute'"));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (33, 13, 33, 24).WithArguments ("Interface member 'IRAF.NumProperty' with 'RequiresAssemblyFilesAttribute' has an implementation member 'AnotherImplementation.NumProperty' without 'RequiresAssemblyFilesAttribute'"));
}
[Fact]
@@ -1230,11 +1231,11 @@ public int NumProperty
await VerifyRequiresAssemblyFilesAnalyzer (src, additionalReferences: new[] { compilation },
// (7,14): warning IL3003: Member 'Implementation.Method()' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.Method()' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (7, 14, 7, 20).WithArguments ("Member 'Implementation.Method()' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.Method()' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (7, 14, 7, 20).WithArguments ("Member 'Implementation.Method()' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.Method()' without 'RequiresAssemblyFilesAttribute'"),
// (13,3): warning IL3003: Member 'Implementation.StringProperty.get' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.StringProperty.get' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (13, 3, 13, 6).WithArguments ("Member 'Implementation.StringProperty.get' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.StringProperty.get' without 'RequiresAssemblyFilesAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (13, 3, 13, 6).WithArguments ("Member 'Implementation.StringProperty.get' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.StringProperty.get' without 'RequiresAssemblyFilesAttribute'"),
// (19,13): warning IL3003: Member 'Implementation.NumProperty' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.NumProperty' without 'RequiresAssemblyFilesAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3003).WithSpan (19, 13, 19, 24).WithArguments ("Member 'Implementation.NumProperty' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.NumProperty' without 'RequiresAssemblyFilesAttribute'"));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresAssembyFilesAttributeMismatch).WithSpan (19, 13, 19, 24).WithArguments ("Member 'Implementation.NumProperty' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.NumProperty' without 'RequiresAssemblyFilesAttribute'"));
}
}
}
diff --git a/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs b/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs
index b387498414ff..4f26b6bb16ff 100644
--- a/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs
+++ b/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs
@@ -5,6 +5,8 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
+using ILLink.RoslynAnalyzer;
+using ILLink.Shared;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Testing;
using Microsoft.CodeAnalysis.Text;
@@ -65,7 +67,7 @@ class C
}";
return VerifyRequiresUnreferencedCodeAnalyzer (TestRequiresWithMessageOnlyOnMethod,
// (8,17): warning IL2026: Using method 'C.M1()' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. message.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (8, 17, 8, 21).WithArguments ("C.M1()", " message.", ""));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (8, 17, 8, 21).WithArguments ("C.M1()", " message.", ""));
}
[Fact]
@@ -133,13 +135,13 @@ public class F
await VerifyRequiresUnreferencedCodeCodeFix (test, fixtest, new[] {
// /0/Test0.cs(9,17): warning IL2026: Using method 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (9, 17, 9, 21).WithArguments ("C.M1()", " message.", ""),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (9, 17, 9, 21).WithArguments ("C.M1()", " message.", ""),
// /0/Test0.cs(13,27): warning IL2026: Using method 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message.
- VerifyCS.Diagnostic(RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan(13, 27, 13, 33).WithArguments("C.M1()", " message.", ""),
+ VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(13, 27, 13, 33).WithArguments("C.M1()", " message.", ""),
// /0/Test0.cs(17,31): warning IL2026: Using method 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (17, 31, 17, 37).WithArguments ("C.M1()", " message.", ""),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (17, 31, 17, 37).WithArguments ("C.M1()", " message.", ""),
// /0/Test0.cs(24,31): warning IL2026: Using method 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (24, 31, 24, 37).WithArguments ("C.M1()", " message.", "")
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (24, 31, 24, 37).WithArguments ("C.M1()", " message.", "")
}, new[] {
// /0/Test0.cs(27,10): error CS7036: There is no argument given that corresponds to the required formal parameter 'message' of 'RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)'
DiagnosticResult.CompilerError("CS7036").WithSpan(27, 10, 27, 36).WithArguments("message", "System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)"),
@@ -185,7 +187,7 @@ Action M2()
fix,
baselineExpected: new[] {
// /0/Test0.cs(12,22): warning IL2026: Using method 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message.
- VerifyCS.Diagnostic(RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan(12, 22, 12, 26).WithArguments("C.M1()", " message.", "")
+ VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(12, 22, 12, 26).WithArguments("C.M1()", " message.", "")
},
fixedExpected: Array.Empty ());
}
@@ -230,7 +232,7 @@ Action M2()
fix,
baselineExpected: new[] {
// /0/Test0.cs(12,28): warning IL2026: Using method 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message.
- VerifyCS.Diagnostic(RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan(12, 28, 12, 32).WithArguments("C.M1()", " message.", "")
+ VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(12, 28, 12, 32).WithArguments("C.M1()", " message.", "")
},
fixedExpected: Array.Empty (),
// The default iterations for the codefix is the number of diagnostics (1 in this case)
@@ -271,7 +273,7 @@ public class C
fix,
baselineExpected: new[] {
// /0/Test0.cs(10,19): warning IL2026: Using method 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message.
- VerifyCS.Diagnostic(RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan(10, 19, 10, 23).WithArguments("C.M1()", " message.", "")
+ VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(10, 19, 10, 23).WithArguments("C.M1()", " message.", "")
},
fixedExpected: new[] {
// /0/Test0.cs(10,6): error CS7036: There is no argument given that corresponds to the required formal parameter 'message' of 'RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)'
@@ -310,11 +312,11 @@ public class C
fix,
baselineExpected: new[] {
// /0/Test0.cs(10,15): warning IL2026: Using method 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message.
- VerifyCS.Diagnostic(RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan(10, 15, 10, 19).WithArguments("C.M1()", " message.", "")
+ VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(10, 15, 10, 19).WithArguments("C.M1()", " message.", "")
},
fixedExpected: new[] {
// /0/Test0.cs(10,15): warning IL2026: Using method 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message.
- VerifyCS.Diagnostic(RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan(10, 15, 10, 19).WithArguments("C.M1()", " message.", "")
+ VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(10, 15, 10, 19).WithArguments("C.M1()", " message.", "")
});
}
@@ -337,7 +339,7 @@ static void RequiresWithMessageAndUrl ()
}";
return VerifyRequiresUnreferencedCodeAnalyzer (MessageAndUrlOnMethod,
// (8,3): warning IL2026: Using method 'C.RequiresWithMessageAndUrl()' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. Message for --RequiresWithMessageAndUrl--. https://helpurl
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (8, 3, 8, 31).WithArguments ("C.RequiresWithMessageAndUrl()", " Message for --RequiresWithMessageAndUrl--.", " https://helpurl")
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (8, 3, 8, 31).WithArguments ("C.RequiresWithMessageAndUrl()", " Message for --RequiresWithMessageAndUrl--.", " https://helpurl")
);
}
@@ -367,8 +369,8 @@ static void Test ()
}";
return VerifyRequiresUnreferencedCodeAnalyzer (source,
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (18, 3, 18, 34).WithArguments ("C.MessageWithoutTrailingPeriod()", " Warning message.", string.Empty),
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (19, 3, 19, 31).WithArguments ("C.MessageWithTrailingPeriod()", " Warning message.", string.Empty));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (18, 3, 18, 34).WithArguments ("C.MessageWithoutTrailingPeriod()", " Warning message.", string.Empty),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (19, 3, 19, 31).WithArguments ("C.MessageWithTrailingPeriod()", " Warning message.", string.Empty));
}
[Fact]
@@ -391,7 +393,7 @@ static int PropertyRequires {
}";
return VerifyRequiresUnreferencedCodeAnalyzer (PropertyRequires,
// (8,7): warning IL2026: Using method 'C.PropertyRequires.get' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. Message for --getter PropertyRequires--.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (8, 7, 8, 23).WithArguments ("C.PropertyRequires.get", " Message for --getter PropertyRequires--.", "")
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (8, 7, 8, 23).WithArguments ("C.PropertyRequires.get", " Message for --getter PropertyRequires--.", "")
);
}
@@ -415,7 +417,7 @@ static int PropertyRequires {
}";
return VerifyRequiresUnreferencedCodeAnalyzer (PropertyRequires,
// (8,3): warning IL2026: Using method 'C.PropertyRequires.set' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. Message for --setter PropertyRequires--.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (8, 3, 8, 19).WithArguments ("C.PropertyRequires.set", " Message for --setter PropertyRequires--.", "")
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (8, 3, 8, 19).WithArguments ("C.PropertyRequires.set", " Message for --setter PropertyRequires--.", "")
);
}
@@ -439,7 +441,7 @@ static void TestStaticCctorRequiresUnreferencedCode ()
}";
return VerifyRequiresUnreferencedCodeAnalyzer (src,
// (13,7): warning IL2026: Using method 'StaticCtor.StaticCtor()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Message for --TestStaticCtor--.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (13, 7, 13, 24).WithArguments ("StaticCtor.StaticCtor()", " Message for --TestStaticCtor--.", "")
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (13, 7, 13, 24).WithArguments ("StaticCtor.StaticCtor()", " Message for --TestStaticCtor--.", "")
);
}
@@ -468,7 +470,7 @@ static void TestStaticCtorMarkingIsTriggeredByFieldAccess ()
}";
return VerifyRequiresUnreferencedCodeAnalyzer (src,
// (18,11): warning IL2026: Using method 'StaticCtorTriggeredByFieldAccess.StaticCtorTriggeredByFieldAccess()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Message for --StaticCtorTriggeredByFieldAccess.Cctor--.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (18, 11, 18, 49).WithArguments ("StaticCtorTriggeredByFieldAccess.StaticCtorTriggeredByFieldAccess()", " Message for --StaticCtorTriggeredByFieldAccess.Cctor--.", "")
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (18, 11, 18, 49).WithArguments ("StaticCtorTriggeredByFieldAccess.StaticCtorTriggeredByFieldAccess()", " Message for --StaticCtorTriggeredByFieldAccess.Cctor--.", "")
);
}
@@ -500,9 +502,9 @@ static void TestStaticCtorTriggeredByMethodCall ()
}";
return VerifyRequiresUnreferencedCodeAnalyzer (src,
// (21,3): warning IL2026: Using method 'StaticCtorTriggeredByMethodCall.TriggerStaticCtorMarking()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Message for --StaticCtorTriggeredByMethodCall.TriggerStaticCtorMarking--.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (21, 3, 21, 69).WithArguments ("StaticCtorTriggeredByMethodCall.TriggerStaticCtorMarking()", " Message for --StaticCtorTriggeredByMethodCall.TriggerStaticCtorMarking--.", ""),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (21, 3, 21, 69).WithArguments ("StaticCtorTriggeredByMethodCall.TriggerStaticCtorMarking()", " Message for --StaticCtorTriggeredByMethodCall.TriggerStaticCtorMarking--.", ""),
// (21,3): warning IL2026: Using method 'StaticCtorTriggeredByMethodCall.StaticCtorTriggeredByMethodCall()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Message for --StaticCtorTriggeredByMethodCall.Cctor--.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (21, 3, 21, 41).WithArguments ("StaticCtorTriggeredByMethodCall.StaticCtorTriggeredByMethodCall()", " Message for --StaticCtorTriggeredByMethodCall.Cctor--.", "")
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (21, 3, 21, 41).WithArguments ("StaticCtorTriggeredByMethodCall.StaticCtorTriggeredByMethodCall()", " Message for --StaticCtorTriggeredByMethodCall.Cctor--.", "")
);
}
@@ -529,7 +531,7 @@ static void TestTypeIsBeforeFieldInit ()
}";
return VerifyRequiresUnreferencedCodeAnalyzer (TypeIsBeforeFieldInit,
// (8,29): warning IL2026: Using method 'C.TypeIsBeforeFieldInit.AnnotatedMethod()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Message from --TypeIsBeforeFieldInit.AnnotatedMethod--.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (8, 29, 8, 47).WithArguments ("C.TypeIsBeforeFieldInit.AnnotatedMethod()", " Message from --TypeIsBeforeFieldInit.AnnotatedMethod--.", "")
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (8, 29, 8, 47).WithArguments ("C.TypeIsBeforeFieldInit.AnnotatedMethod()", " Message from --TypeIsBeforeFieldInit.AnnotatedMethod--.", "")
);
}
@@ -553,7 +555,7 @@ public static C InitC() {
return VerifyRequiresUnreferencedCodeAnalyzer (src,
// (6,50): warning IL2026: Using method 'C.InitC()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Message from --C.InitC--.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (6, 50, 6, 55).WithArguments ("C.InitC()", " Message from --C.InitC--.", ""));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (6, 50, 6, 55).WithArguments ("C.InitC()", " Message from --C.InitC--.", ""));
}
[Fact]
@@ -575,9 +577,9 @@ public static void M2()
return VerifyRequiresUnreferencedCodeAnalyzer (src,
// (10,20): warning IL2026: Using method 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Message from --C.M1--.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (10, 20, 10, 22).WithArguments ("C.M1()", " Message from --C.M1--.", ""),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (10, 20, 10, 22).WithArguments ("C.M1()", " Message from --C.M1--.", ""),
// (11,26): warning IL2026: Using method 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Message from --C.M1--.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (11, 26, 11, 30).WithArguments ("C.M1()", " Message from --C.M1--.", ""));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (11, 26, 11, 30).WithArguments ("C.M1()", " Message from --C.M1--.", ""));
}
[Fact]
@@ -612,9 +614,9 @@ public virtual void VirtualMethod ()
}";
return VerifyRequiresUnreferencedCodeAnalyzer (src,
// (7,23): warning IL2046: Member 'DerivedClass.VirtualMethod()' with 'RequiresUnreferencedCodeAttribute' overrides base member 'BaseClass.VirtualMethod()' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (7, 23, 7, 36).WithArguments ("Member 'DerivedClass.VirtualMethod()' with 'RequiresUnreferencedCodeAttribute' overrides base member 'BaseClass.VirtualMethod()' without 'RequiresUnreferencedCodeAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (7, 23, 7, 36).WithArguments ("Member 'DerivedClass.VirtualMethod()' with 'RequiresUnreferencedCodeAttribute' overrides base member 'BaseClass.VirtualMethod()' without 'RequiresUnreferencedCodeAttribute'"),
// (15,3): warning IL2046: Member 'DerivedClass.VirtualProperty.get' with 'RequiresUnreferencedCodeAttribute' overrides base member 'BaseClass.VirtualProperty.get' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (15, 3, 15, 6).WithArguments ("Member 'DerivedClass.VirtualProperty.get' with 'RequiresUnreferencedCodeAttribute' overrides base member 'BaseClass.VirtualProperty.get' without 'RequiresUnreferencedCodeAttribute'"));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (15, 3, 15, 6).WithArguments ("Member 'DerivedClass.VirtualProperty.get' with 'RequiresUnreferencedCodeAttribute' overrides base member 'BaseClass.VirtualProperty.get' without 'RequiresUnreferencedCodeAttribute'"));
}
[Fact]
@@ -648,9 +650,9 @@ public virtual void VirtualMethod ()
}";
return VerifyRequiresUnreferencedCodeAnalyzer (src,
// (13,3): warning IL2046: Base member 'BaseClass.VirtualProperty.get' with 'RequiresUnreferencedCodeAttribute' has a derived member 'DerivedClass.VirtualProperty.get' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (13, 3, 13, 6).WithArguments ("Base member 'BaseClass.VirtualProperty.get' with 'RequiresUnreferencedCodeAttribute' has a derived member 'DerivedClass.VirtualProperty.get' without 'RequiresUnreferencedCodeAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (13, 3, 13, 6).WithArguments ("Base member 'BaseClass.VirtualProperty.get' with 'RequiresUnreferencedCodeAttribute' has a derived member 'DerivedClass.VirtualProperty.get' without 'RequiresUnreferencedCodeAttribute'"),
// (6,23): warning IL2046: Base member 'BaseClass.VirtualMethod()' with 'RequiresUnreferencedCodeAttribute' has a derived member 'DerivedClass.VirtualMethod()' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (6, 23, 6, 36).WithArguments ("Base member 'BaseClass.VirtualMethod()' with 'RequiresUnreferencedCodeAttribute' has a derived member 'DerivedClass.VirtualMethod()' without 'RequiresUnreferencedCodeAttribute'"));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (6, 23, 6, 36).WithArguments ("Base member 'BaseClass.VirtualMethod()' with 'RequiresUnreferencedCodeAttribute' has a derived member 'DerivedClass.VirtualMethod()' without 'RequiresUnreferencedCodeAttribute'"));
}
[Fact]
@@ -706,13 +708,13 @@ interface IRUC
}";
return VerifyRequiresUnreferencedCodeAnalyzer (src,
// (7,14): warning IL2046: Member 'Implementation.RUC()' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRUC.RUC()' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (7, 14, 7, 17).WithArguments ("Member 'Implementation.RUC()' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRUC.RUC()' without 'RequiresUnreferencedCodeAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (7, 14, 7, 17).WithArguments ("Member 'Implementation.RUC()' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRUC.RUC()' without 'RequiresUnreferencedCodeAttribute'"),
// (13,3): warning IL2046: Member 'Implementation.Property.get' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRUC.Property.get' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (13, 3, 13, 6).WithArguments ("Member 'Implementation.Property.get' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRUC.Property.get' without 'RequiresUnreferencedCodeAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (13, 3, 13, 6).WithArguments ("Member 'Implementation.Property.get' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRUC.Property.get' without 'RequiresUnreferencedCodeAttribute'"),
// (33,12): warning IL2046: Member 'ExplicitImplementation.IRUC.RUC()' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRUC.RUC()' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (33, 12, 33, 15).WithArguments ("Member 'ExplicitImplementation.IRUC.RUC()' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRUC.RUC()' without 'RequiresUnreferencedCodeAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (33, 12, 33, 15).WithArguments ("Member 'ExplicitImplementation.IRUC.RUC()' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRUC.RUC()' without 'RequiresUnreferencedCodeAttribute'"),
// (39,3): warning IL2046: Member 'ExplicitImplementation.IRUC.Property.get' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRUC.Property.get' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (39, 3, 39, 6).WithArguments ("Member 'ExplicitImplementation.IRUC.Property.get' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRUC.Property.get' without 'RequiresUnreferencedCodeAttribute'"));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (39, 3, 39, 6).WithArguments ("Member 'ExplicitImplementation.IRUC.Property.get' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRUC.Property.get' without 'RequiresUnreferencedCodeAttribute'"));
}
[Fact]
@@ -753,13 +755,13 @@ interface IRUC
}";
return VerifyRequiresUnreferencedCodeAnalyzer (src,
// (6,14): warning IL2046: Interface member 'IRUC.RUC()' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'Implementation.RUC()' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (6, 14, 6, 17).WithArguments ("Interface member 'IRUC.RUC()' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'Implementation.RUC()' without 'RequiresUnreferencedCodeAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (6, 14, 6, 17).WithArguments ("Interface member 'IRUC.RUC()' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'Implementation.RUC()' without 'RequiresUnreferencedCodeAttribute'"),
// (11,3): warning IL2046: Interface member 'IRUC.Property.get' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'Implementation.Property.get' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (11, 3, 11, 6).WithArguments ("Interface member 'IRUC.Property.get' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'Implementation.Property.get' without 'RequiresUnreferencedCodeAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (11, 3, 11, 6).WithArguments ("Interface member 'IRUC.Property.get' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'Implementation.Property.get' without 'RequiresUnreferencedCodeAttribute'"),
// (18,14): warning IL2046: Interface member 'IRUC.RUC()' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'AnotherImplementation.RUC()' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (18, 14, 18, 17).WithArguments ("Interface member 'IRUC.RUC()' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'AnotherImplementation.RUC()' without 'RequiresUnreferencedCodeAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (18, 14, 18, 17).WithArguments ("Interface member 'IRUC.RUC()' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'AnotherImplementation.RUC()' without 'RequiresUnreferencedCodeAttribute'"),
// (23,3): warning IL2046: Interface member 'IRUC.Property.get' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'AnotherImplementation.Property.get' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (23, 3, 23, 6).WithArguments ("Interface member 'IRUC.Property.get' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'AnotherImplementation.Property.get' without 'RequiresUnreferencedCodeAttribute'"));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (23, 3, 23, 6).WithArguments ("Interface member 'IRUC.Property.get' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'AnotherImplementation.Property.get' without 'RequiresUnreferencedCodeAttribute'"));
}
[Fact]
@@ -804,13 +806,13 @@ public string StringProperty
await VerifyRequiresUnreferencedCodeAnalyzer (src, additionalReferences: new[] { compilation },
// (4,14): warning IL2046: Interface member 'IRAF.Method()' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'Implementation.Method()' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (4, 14, 4, 20).WithArguments ("Interface member 'IRAF.Method()' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'Implementation.Method()' without 'RequiresUnreferencedCodeAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (4, 14, 4, 20).WithArguments ("Interface member 'IRAF.Method()' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'Implementation.Method()' without 'RequiresUnreferencedCodeAttribute'"),
// (16,14): warning IL2046: Interface member 'IRAF.Method()' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'AnotherImplementation.Method()' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (16, 14, 16, 20).WithArguments ("Interface member 'IRAF.Method()' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'AnotherImplementation.Method()' without 'RequiresUnreferencedCodeAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (16, 14, 16, 20).WithArguments ("Interface member 'IRAF.Method()' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'AnotherImplementation.Method()' without 'RequiresUnreferencedCodeAttribute'"),
// (9,3): warning IL2046: Interface member 'IRAF.StringProperty.get' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'Implementation.StringProperty.get' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (9, 3, 9, 6).WithArguments ("Interface member 'IRAF.StringProperty.get' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'Implementation.StringProperty.get' without 'RequiresUnreferencedCodeAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (9, 3, 9, 6).WithArguments ("Interface member 'IRAF.StringProperty.get' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'Implementation.StringProperty.get' without 'RequiresUnreferencedCodeAttribute'"),
// (21,3): warning IL2046: Interface member 'IRAF.StringProperty.get' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'AnotherImplementation.StringProperty.get' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (21, 3, 21, 6).WithArguments ("Interface member 'IRAF.StringProperty.get' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'AnotherImplementation.StringProperty.get' without 'RequiresUnreferencedCodeAttribute'"));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (21, 3, 21, 6).WithArguments ("Interface member 'IRAF.StringProperty.get' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'AnotherImplementation.StringProperty.get' without 'RequiresUnreferencedCodeAttribute'"));
}
[Fact]
@@ -856,9 +858,9 @@ public string StringProperty
await VerifyRequiresUnreferencedCodeAnalyzer (src, additionalReferences: new[] { compilation },
// (7,14): warning IL2046: Member 'Implementation.Method()' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRAF.Method()' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (7, 14, 7, 20).WithArguments ("Member 'Implementation.Method()' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRAF.Method()' without 'RequiresUnreferencedCodeAttribute'"),
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (7, 14, 7, 20).WithArguments ("Member 'Implementation.Method()' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRAF.Method()' without 'RequiresUnreferencedCodeAttribute'"),
// (13,3): warning IL2046: Member 'Implementation.StringProperty.get' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRAF.StringProperty.get' without 'RequiresUnreferencedCodeAttribute'. Attributes must match across all interface implementations or overrides.
- VerifyCS.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2046).WithSpan (13, 3, 13, 6).WithArguments ("Member 'Implementation.StringProperty.get' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRAF.StringProperty.get' without 'RequiresUnreferencedCodeAttribute'"));
+ VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCodeAttributeMismatch).WithSpan (13, 3, 13, 6).WithArguments ("Member 'Implementation.StringProperty.get' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRAF.StringProperty.get' without 'RequiresUnreferencedCodeAttribute'"));
}
}
}
diff --git a/test/ILLink.RoslynAnalyzer.Tests/UnconditionalSuppressMessageCodeFixTests.cs b/test/ILLink.RoslynAnalyzer.Tests/UnconditionalSuppressMessageCodeFixTests.cs
index 05fe2ba10359..7d4aa24a6353 100644
--- a/test/ILLink.RoslynAnalyzer.Tests/UnconditionalSuppressMessageCodeFixTests.cs
+++ b/test/ILLink.RoslynAnalyzer.Tests/UnconditionalSuppressMessageCodeFixTests.cs
@@ -6,6 +6,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using ILLink.CodeFix;
+using ILLink.Shared;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Testing;
@@ -88,7 +89,7 @@ public class C
fixtest,
baselineExpected: new[] {
// /0/Test0.cs(7,17): warning IL2026: Using method 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message.
- VerifyCSUSMwithRUC.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan (7, 17, 7, 21).WithArguments ("C.M1()", " message.", ""),
+ VerifyCSUSMwithRUC.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (7, 17, 7, 21).WithArguments ("C.M1()", " message.", ""),
},
fixedExpected: Array.Empty ());
}
@@ -118,7 +119,7 @@ public class C
fixtest,
baselineExpected: new[] {
// /0/Test0.cs(7,17): warning IL2026: Using method 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message.
- VerifyCSUSMwithRAF.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (7, 17, 7, 21).WithArguments ("C.M1()", " message.", "")
+ VerifyCSUSMwithRAF.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (7, 17, 7, 21).WithArguments ("C.M1()", " message.", "")
},
fixedExpected: Array.Empty ());
}
@@ -159,9 +160,9 @@ public void M2() {
fixtest,
baselineExpected: new[] {
// /0/Test0.cs(7,27): warning IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.
- VerifyCSUSMwithRAF.Diagnostic(RequiresAssemblyFilesAnalyzer.IL3000).WithSpan (7, 27, 7, 44).WithArguments ("System.Reflection.Assembly.Location", "", ""),
+ VerifyCSUSMwithRAF.Diagnostic(DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan (7, 27, 7, 44).WithArguments ("System.Reflection.Assembly.Location", "", ""),
// /0/Test0.cs(9,13): warning IL3001: 'System.Reflection.Assembly.GetFiles()' will throw for assemblies embedded in a single-file app
- VerifyCSUSMwithRAF.Diagnostic(RequiresAssemblyFilesAnalyzer.IL3001).WithSpan (9, 13, 9, 32).WithArguments("System.Reflection.Assembly.GetFiles()", "", ""),
+ VerifyCSUSMwithRAF.Diagnostic(DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan (9, 13, 9, 32).WithArguments("System.Reflection.Assembly.GetFiles()", "", ""),
},
fixedExpected: Array.Empty ());
}
@@ -197,7 +198,7 @@ public class C
fix,
baselineExpected: new[] {
// /0/Test0.cs(10,15): warning IL2026: Using method 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message.
- VerifyCSUSMwithRUC.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan(10, 15, 10, 19).WithArguments("C.M1()", " message.", "")
+ VerifyCSUSMwithRUC.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan(10, 15, 10, 19).WithArguments("C.M1()", " message.", "")
},
fixedExpected: Array.Empty ());
}
@@ -239,7 +240,7 @@ public static C InitC() {
fixtest,
baselineExpected: new[] {
// /0/Test0.cs(6,50): warning IL3002: Using member 'C.InitC()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app.
- VerifyCSUSMwithRAF.Diagnostic (RequiresAssemblyFilesAnalyzer.IL3002).WithSpan (6, 50, 6, 55).WithArguments ("C.InitC()", "", ""),
+ VerifyCSUSMwithRAF.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (6, 50, 6, 55).WithArguments ("C.InitC()", "", ""),
},
fixedExpected: Array.Empty ());
}
@@ -283,7 +284,7 @@ Action M2()
fix,
baselineExpected: new[] {
// /0/Test0.cs(12,28): warning IL2026: Using method 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message.
- VerifyCSUSMwithRUC.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan(12, 28, 12, 32).WithArguments("C.M1()", " message.", "")
+ VerifyCSUSMwithRUC.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan(12, 28, 12, 32).WithArguments("C.M1()", " message.", "")
},
fixedExpected: Array.Empty ());
}
@@ -319,7 +320,7 @@ public class C
fix,
baselineExpected: new[] {
// /0/Test0.cs(10,15): warning IL2026: Using method 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message.
- VerifyCSUSMwithRUC.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan(10, 20, 10, 24).WithArguments("C.M1()", " message.", "")
+ VerifyCSUSMwithRUC.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan(10, 20, 10, 24).WithArguments("C.M1()", " message.", "")
},
fixedExpected: Array.Empty ());
}
@@ -369,7 +370,7 @@ public event EventHandler E1
fix,
baselineExpected: new[] {
// /0/Test0.cs(14,21): warning IL2026: Using method 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message.
- VerifyCSUSMwithRUC.Diagnostic (RequiresUnreferencedCodeAnalyzer.IL2026).WithSpan(14, 21, 14, 25).WithArguments("C.M1()", " message.", "")
+ VerifyCSUSMwithRUC.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan(14, 21, 14, 25).WithArguments("C.M1()", " message.", "")
},
fixedExpected: Array.Empty ());
}
diff --git a/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs b/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs
index bedb7541ea63..a5777675b8ca 100644
--- a/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs
+++ b/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs
@@ -8,6 +8,7 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using ILLink.Shared;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Testing;
@@ -234,7 +235,8 @@ private static string FormatDiagnostics (ImmutableArray anal
var applicableAnalyzer = analyzers.FirstOrDefault (a => a.SupportedDiagnostics.Any (dd => dd.Id == diagnosticsId));
if (applicableAnalyzer != null) {
var analyzerType = applicableAnalyzer.GetType ();
- var rule = diagnostics[i].HasLocation && applicableAnalyzer.SupportedDiagnostics.Length == 1 ? string.Empty : $"{analyzerType.Name}.{diagnosticsId}";
+ var rule = diagnostics[i].HasLocation &&
+ applicableAnalyzer.SupportedDiagnostics.Length == 1 ? string.Empty : GetDiagnosticIdArgumentString (diagnosticsId);
if (!diagnostics[i].HasLocation) {
builder.Append ($"new DiagnosticResult({rule})");
@@ -308,13 +310,13 @@ private static string FormatDiagnostics (ImmutableArray anal
var applicableAnalyzer = analyzers.FirstOrDefault (a => a.SupportedDiagnostics.Any (dd => dd.Id == diagnosticsId));
if (applicableAnalyzer != null) {
var analyzerType = applicableAnalyzer.GetType ();
- var rule = location != Location.None && location.IsInSource && applicableAnalyzer.SupportedDiagnostics.Length == 1 ? string.Empty : $"{analyzerType.Name}.{diagnosticsId}";
+ var rule = location != Location.None && location.IsInSource &&
+ applicableAnalyzer.SupportedDiagnostics.Length == 1 ? string.Empty : GetDiagnosticIdArgumentString (diagnosticsId);
if (location == Location.None || !location.IsInSource) {
builder.Append ($"new DiagnosticResult({rule})");
} else {
- var resultMethodName = location.SourceTree!.FilePath.EndsWith (".cs") ? "VerifyCS.Diagnostic" : "VerifyVB.Diagnostic";
- builder.Append ($"{resultMethodName}({rule})");
+ builder.Append ($"VerifyCS.Diagnostic({rule})");
}
} else {
builder.Append (
@@ -604,7 +606,7 @@ static bool IsMessageMatch (Diagnostic actual, ImmutableArray actualArgu
return string.Equals (expected.Message, actual.GetMessage ());
}
}
-
+ private static string GetDiagnosticIdArgumentString (string diagnosticId) => $"DiagnosticId.{(DiagnosticId) Int32.Parse (diagnosticId.Substring (2))}";
internal readonly struct MatchQuality : IComparable, IEquatable
{
diff --git a/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpCodeFixVerifier`2.cs b/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpCodeFixVerifier`2.cs
index 52fd90effe1f..9f68969a22b1 100644
--- a/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpCodeFixVerifier`2.cs
+++ b/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpCodeFixVerifier`2.cs
@@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using ILLink.Shared;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Testing;
@@ -47,6 +48,9 @@ public static DiagnosticResult Diagnostic ()
public static DiagnosticResult Diagnostic (string diagnosticId)
=> CSharpAnalyzerVerifier.Diagnostic (diagnosticId);
+ public static DiagnosticResult Diagnostic (DiagnosticId diagnosticId)
+ => CSharpAnalyzerVerifier.Diagnostic (DiagnosticDescriptors.GetDiagnosticDescriptor (diagnosticId));
+
///
public static DiagnosticResult Diagnostic (DiagnosticDescriptor descriptor)
=> CSharpAnalyzerVerifier.Diagnostic (descriptor);
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs b/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs
new file mode 100644
index 000000000000..f94b9a45867e
--- /dev/null
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs
@@ -0,0 +1,553 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Helpers;
+
+namespace Mono.Linker.Tests.Cases.DataFlow
+{
+ [SkipKeptItemsValidation]
+ [ExpectedNoWarnings]
+ class AnnotatedMembersAccessedViaReflection
+ {
+ public static void Main ()
+ {
+ AnnotatedField.Test ();
+ AnnotatedMethodParameters.Test ();
+ AnnotatedMethodReturnValue.Test ();
+ AnnotatedProperty.Test ();
+ AnnotatedGenerics.Test ();
+ AnnotationOnGenerics.Test ();
+ AnnotationOnInteropMethod.Test ();
+ AccessThroughLdToken.Test ();
+ }
+
+ class AnnotatedField
+ {
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ public static Type _annotatedField;
+
+ [ExpectedWarning ("IL2110", nameof (_annotatedField))]
+ static void Reflection ()
+ {
+ typeof (AnnotatedField).GetField ("_annotatedField").SetValue (null, typeof (TestType));
+ }
+
+ [RequiresUnreferencedCode ("test")]
+ static void ReflectionSuppressedByRUC ()
+ {
+ typeof (AnnotatedField).GetField ("_annotatedField").SetValue (null, typeof (TestType));
+ }
+
+ [ExpectedWarning ("IL2110", nameof (_annotatedField))]
+ static void ReflectionReadOnly ()
+ {
+ typeof (AnnotatedField).GetField ("_annotatedField").GetValue (null);
+ }
+
+ [ExpectedWarning ("IL2110", nameof (_annotatedField))]
+ [DynamicDependency (DynamicallyAccessedMemberTypes.PublicFields, typeof (AnnotatedField))]
+ static void DynamicDependency ()
+ {
+ }
+
+ [RequiresUnreferencedCode ("test")]
+ [DynamicDependency (DynamicallyAccessedMemberTypes.PublicFields, typeof (AnnotatedField))]
+ static void DynamicDependencySuppressedByRUC ()
+ {
+ }
+
+ [ExpectedWarning ("IL2110", nameof (_annotatedField))]
+ [DynamicDependency (nameof (_annotatedField), typeof (AnnotatedField))]
+ static void DynamicDependencyByName ()
+ {
+ }
+
+ [ExpectedWarning ("IL2110", nameof (_annotatedField))]
+ static void DynamicallyAccessedMembers ()
+ {
+ typeof (AnnotatedField).RequiresPublicFields ();
+ }
+
+ [RequiresUnreferencedCode ("test")]
+ static void DynamicallyAccessedMembersSuppressedByRUC ()
+ {
+ typeof (AnnotatedField).RequiresPublicFields ();
+ }
+
+ [UnconditionalSuppressMessage ("test", "IL2026")]
+ public static void Test ()
+ {
+ Reflection ();
+ ReflectionSuppressedByRUC ();
+ ReflectionReadOnly ();
+ DynamicDependency ();
+ DynamicDependencySuppressedByRUC ();
+ DynamicDependencyByName ();
+ DynamicallyAccessedMembers ();
+ DynamicallyAccessedMembersSuppressedByRUC ();
+ }
+ }
+
+ class AnnotatedMethodParameters
+ {
+ public static void MethodWithSingleAnnotatedParameter (
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type)
+ { }
+
+ class AttributeWithConstructorWithAnnotation : Attribute
+ {
+ public AttributeWithConstructorWithAnnotation (
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type)
+ { }
+ }
+
+ [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter))]
+ static void Reflection ()
+ {
+ typeof (AnnotatedMethodParameters).GetMethod (nameof (MethodWithSingleAnnotatedParameter)).Invoke (null, null);
+ }
+
+ [RequiresUnreferencedCode ("test")]
+ static void ReflectionSuppressedByRUC ()
+ {
+ typeof (AnnotatedMethodParameters).GetMethod (nameof (MethodWithSingleAnnotatedParameter)).Invoke (null, null);
+ }
+
+ // Should not warn, there's nothing wrong about this
+ [AttributeWithConstructorWithAnnotation (typeof (TestType))]
+ static void AnnotatedAttributeConstructor ()
+ {
+ }
+
+ [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter))]
+ [DynamicDependency (DynamicallyAccessedMemberTypes.PublicMethods, typeof (AnnotatedMethodParameters))]
+ static void DynamicDependency ()
+ {
+ }
+
+ [RequiresUnreferencedCode ("test")]
+ [DynamicDependency (DynamicallyAccessedMemberTypes.PublicMethods, typeof (AnnotatedMethodParameters))]
+ static void DynamicDependencySuppressedByRUC ()
+ {
+ }
+
+ [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter))]
+ [DynamicDependency (nameof (MethodWithSingleAnnotatedParameter), typeof (AnnotatedMethodParameters))]
+ static void DynamicDependencyByName ()
+ {
+ }
+
+ [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter))]
+ static void DynamicallyAccessedMembers ()
+ {
+ typeof (AnnotatedMethodParameters).RequiresPublicMethods ();
+ }
+
+ [RequiresUnreferencedCode ("test")]
+ static void DynamicallyAccessedMembersSuppressedByRUC ()
+ {
+ typeof (AnnotatedMethodParameters).RequiresPublicMethods ();
+ }
+
+ [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter))]
+ static void Ldftn ()
+ {
+ var _ = new Action (AnnotatedMethodParameters.MethodWithSingleAnnotatedParameter);
+ }
+
+ interface IWithAnnotatedMethod
+ {
+ public void AnnotatedMethod ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type type);
+ }
+
+ [ExpectedWarning ("IL2111", nameof (IWithAnnotatedMethod.AnnotatedMethod))]
+ static void Ldvirtftn ()
+ {
+ IWithAnnotatedMethod instance = null;
+ var _ = new Action (instance.AnnotatedMethod);
+ }
+
+ [UnconditionalSuppressMessage ("test", "IL2026")]
+ public static void Test ()
+ {
+ Reflection ();
+ ReflectionSuppressedByRUC ();
+ DynamicDependency ();
+ DynamicDependencySuppressedByRUC ();
+ DynamicDependencyByName ();
+ DynamicallyAccessedMembers ();
+ DynamicallyAccessedMembersSuppressedByRUC ();
+ Ldftn ();
+ Ldvirtftn ();
+ }
+ }
+
+ class AnnotatedMethodReturnValue
+ {
+ [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ public static Type StaticMethodWithAnnotatedReturnValue () => null;
+
+ [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ public Type InstanceMethodWithAnnotatedReturnValue () => null;
+
+ [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ public virtual Type VirtualMethodWithAnnotatedReturnValue () => null;
+
+ // Only virtual methods should warn - the problem is only possible if something overrides a virtual method.
+ // Getting an annotated value in itself is not dangerous in any way.
+
+ static void ReflectionOnStatic ()
+ {
+ typeof (AnnotatedMethodReturnValue).GetMethod (nameof (StaticMethodWithAnnotatedReturnValue)).Invoke (null, null);
+ }
+
+ static void ReflectionOnInstance ()
+ {
+ typeof (AnnotatedMethodReturnValue).GetMethod (nameof (InstanceMethodWithAnnotatedReturnValue)).Invoke (null, null);
+ }
+
+ [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue))]
+ static void ReflectionOnVirtual ()
+ {
+ typeof (AnnotatedMethodReturnValue).GetMethod (nameof (VirtualMethodWithAnnotatedReturnValue)).Invoke (null, null);
+ }
+
+ [RequiresUnreferencedCode ("test")]
+ static void ReflectionOnVirtualSuppressedByRUC ()
+ {
+ typeof (AnnotatedMethodReturnValue).GetMethod (nameof (VirtualMethodWithAnnotatedReturnValue)).Invoke (null, null);
+ }
+
+ [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue))]
+ [DynamicDependency (DynamicallyAccessedMemberTypes.PublicMethods, typeof (AnnotatedMethodReturnValue))]
+ static void DynamicDependency ()
+ {
+ }
+
+ [RequiresUnreferencedCode ("test")]
+ [DynamicDependency (DynamicallyAccessedMemberTypes.PublicMethods, typeof (AnnotatedMethodReturnValue))]
+ static void DynamicDependencySuppressedByRUC ()
+ {
+ }
+
+ [DynamicDependency (nameof (StaticMethodWithAnnotatedReturnValue), typeof (AnnotatedMethodReturnValue))]
+ static void DynamicDependencyByNameOnStatic ()
+ {
+ }
+
+ [DynamicDependency (nameof (InstanceMethodWithAnnotatedReturnValue), typeof (AnnotatedMethodReturnValue))]
+ static void DynamicDependencyByNameOnInstance ()
+ {
+ }
+
+ [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue))]
+ [DynamicDependency (nameof (VirtualMethodWithAnnotatedReturnValue), typeof (AnnotatedMethodReturnValue))]
+ static void DynamicDependencyByNameOnVirtual ()
+ {
+ }
+
+ [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue))]
+ static void DynamicallyAccessedMembers ()
+ {
+ typeof (AnnotatedMethodReturnValue).RequiresPublicMethods ();
+ }
+
+ [RequiresUnreferencedCode ("test")]
+ static void DynamicallyAccessedMembersSuppressedByRUC ()
+ {
+ typeof (AnnotatedMethodReturnValue).RequiresPublicMethods ();
+ }
+
+ static void LdftnOnStatic ()
+ {
+ var _ = new Func (AnnotatedMethodReturnValue.StaticMethodWithAnnotatedReturnValue);
+ }
+
+ static void LdftnOnInstance ()
+ {
+ var _ = new Func ((new AnnotatedMethodReturnValue ()).InstanceMethodWithAnnotatedReturnValue);
+ }
+
+ [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue))]
+ static void LdftnOnVirtual ()
+ {
+ var _ = new Func ((new AnnotatedMethodReturnValue ()).VirtualMethodWithAnnotatedReturnValue);
+ }
+
+ [UnconditionalSuppressMessage ("test", "IL2026")]
+ public static void Test ()
+ {
+ ReflectionOnStatic ();
+ ReflectionOnInstance ();
+ ReflectionOnVirtual ();
+ ReflectionOnVirtualSuppressedByRUC ();
+ DynamicDependency ();
+ DynamicDependencySuppressedByRUC ();
+ DynamicDependencyByNameOnStatic ();
+ DynamicDependencyByNameOnInstance ();
+ DynamicDependencyByNameOnVirtual ();
+ DynamicallyAccessedMembers ();
+ DynamicallyAccessedMembersSuppressedByRUC ();
+ LdftnOnStatic ();
+ LdftnOnInstance ();
+ LdftnOnVirtual ();
+ }
+ }
+
+ class AnnotatedProperty
+ {
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)]
+ public static Type PropertyWithAnnotation { get; set; }
+
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)]
+ public static Type PropertyWithAnnotationGetterOnly { get => null; }
+
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)]
+ public virtual Type VirtualPropertyWithAnnotationGetterOnly { get => null; }
+
+ class AttributeWithPropertyWithAnnotation : Attribute
+ {
+ public AttributeWithPropertyWithAnnotation () { }
+
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)]
+ public Type PropertyWithAnnotation { get; set; }
+ }
+
+ [ExpectedWarning ("IL2111", nameof (PropertyWithAnnotation))]
+ static void ReflectionOnPropertyItself ()
+ {
+ typeof (AnnotatedProperty).GetProperty (nameof (PropertyWithAnnotation));
+ }
+
+ [RequiresUnreferencedCode ("test")]
+ static void ReflectionOnPropertyItselfSuppressedByRUC ()
+ {
+ typeof (AnnotatedProperty).GetProperty (nameof (PropertyWithAnnotation));
+ }
+
+ static void ReflectionOnPropertyWithGetterOnly ()
+ {
+ typeof (AnnotatedProperty).GetProperty (nameof (PropertyWithAnnotationGetterOnly));
+ }
+
+ [ExpectedWarning ("IL2111", nameof (VirtualPropertyWithAnnotationGetterOnly))]
+ static void ReflectionOnPropertyWithGetterOnlyOnVirtual ()
+ {
+ typeof (AnnotatedProperty).GetProperty (nameof (VirtualPropertyWithAnnotationGetterOnly));
+ }
+
+ static void ReflectionOnGetter ()
+ {
+ typeof (AnnotatedProperty).GetMethod ("get_" + nameof (PropertyWithAnnotation));
+ }
+
+ [ExpectedWarning ("IL2111", nameof (PropertyWithAnnotation) + ".set")]
+ static void ReflectionOnSetter ()
+ {
+ typeof (AnnotatedProperty).GetMethod ("set_" + nameof (PropertyWithAnnotation));
+ }
+
+ [ExpectedWarning ("IL2111", nameof (VirtualPropertyWithAnnotationGetterOnly) + ".get")]
+ static void ReflectionOnVirtualGetter ()
+ {
+ typeof (AnnotatedProperty).GetMethod ("get_" + nameof (VirtualPropertyWithAnnotationGetterOnly));
+ }
+
+ // Should not warn - there's nothing wrong with this
+ [AttributeWithPropertyWithAnnotation (PropertyWithAnnotation = typeof (TestType))]
+ static void AnnotatedAttributeProperty ()
+ {
+ }
+
+ [ExpectedWarning ("IL2111", nameof (PropertyWithAnnotation) + ".set")]
+ [ExpectedWarning ("IL2111", nameof (VirtualPropertyWithAnnotationGetterOnly) + ".get")]
+ [DynamicDependency (DynamicallyAccessedMemberTypes.PublicProperties, typeof (AnnotatedProperty))]
+ static void DynamicDependency ()
+ {
+ }
+
+ [RequiresUnreferencedCode ("test")]
+ [DynamicDependency (DynamicallyAccessedMemberTypes.PublicProperties, typeof (AnnotatedProperty))]
+ static void DynamicDependencySuppressedByRUC ()
+ {
+ }
+
+ [ExpectedWarning ("IL2111", nameof (PropertyWithAnnotation) + ".set")]
+ [ExpectedWarning ("IL2111", nameof (VirtualPropertyWithAnnotationGetterOnly) + ".get")]
+ static void DynamicallyAccessedMembers ()
+ {
+ typeof (AnnotatedProperty).RequiresPublicProperties ();
+ }
+
+ [RequiresUnreferencedCode ("test")]
+ static void DynamicallyAccessedMembersSuppressedByRUC ()
+ {
+ typeof (AnnotatedProperty).RequiresPublicProperties ();
+ }
+
+ [UnconditionalSuppressMessage ("test", "IL2026")]
+ public static void Test ()
+ {
+ ReflectionOnPropertyItself ();
+ ReflectionOnPropertyItselfSuppressedByRUC ();
+ ReflectionOnPropertyWithGetterOnly ();
+ ReflectionOnPropertyWithGetterOnlyOnVirtual ();
+ ReflectionOnGetter ();
+ ReflectionOnSetter ();
+ ReflectionOnVirtualGetter ();
+ AnnotatedAttributeProperty ();
+ DynamicDependency ();
+ DynamicDependencySuppressedByRUC ();
+ DynamicallyAccessedMembers ();
+ DynamicallyAccessedMembersSuppressedByRUC ();
+ }
+ }
+
+ // Annotation on generic parameter
+ class AnnotatedGenerics
+ {
+ public static void GenericWithAnnotation<
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] T> ()
+ { }
+
+ static void ReflectionOnly ()
+ {
+ // Should not warn - there's nothing wrong with asking for MethodInfo alone
+ typeof (AnnotatedGenerics).GetMethod (nameof (GenericWithAnnotation));
+ }
+
+ // Similarly to direct reflection - no warning expected
+ [DynamicDependency (DynamicallyAccessedMemberTypes.PublicMethods, typeof (AnnotatedGenerics))]
+ static void DynamicDependency ()
+ {
+ }
+
+ // Similarly to direct reflection - no warning expected
+ static void DynamicallyAccessedMembers ()
+ {
+ typeof (AnnotatedGenerics).RequiresPublicMethods ();
+ }
+
+ // This should produce IL2071 https://github.com/mono/linker/issues/2144
+ [ExpectedWarning ("IL2070", "MakeGenericMethod")]
+ static void InstantiateGeneric (Type type = null)
+ {
+ // This should warn due to MakeGenericMethod - in this case the generic parameter is unannotated type
+ typeof (AnnotatedGenerics).GetMethod (nameof (GenericWithAnnotation)).MakeGenericMethod (type);
+ }
+
+ public static void Test ()
+ {
+ ReflectionOnly ();
+ DynamicDependency ();
+ DynamicallyAccessedMembers ();
+ InstantiateGeneric ();
+ }
+ }
+
+ // Annotation on non-generic parameter but on generic methods
+ class AnnotationOnGenerics
+ {
+ class GenericWithAnnotatedMethod
+ {
+ public static void AnnotatedMethod (
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type)
+ { }
+ }
+
+ public static void GenericMethodWithAnnotation (
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type)
+ { }
+
+ [ExpectedWarning ("IL2111", nameof (GenericWithAnnotatedMethod.AnnotatedMethod))]
+ public static void GenericTypeWithStaticMethodViaLdftn ()
+ {
+ var _ = new Action (GenericWithAnnotatedMethod.AnnotatedMethod);
+ }
+
+ [ExpectedWarning ("IL2111", nameof (GenericMethodWithAnnotation))]
+ public static void GenericMethodWithAnnotationReflection ()
+ {
+ typeof (AnnotationOnGenerics).GetMethod (nameof (GenericMethodWithAnnotation));
+ }
+
+ public static void GenericMethodWithAnnotationDirectCall ()
+ {
+ // Should not warn, nothing wrong about this
+ GenericMethodWithAnnotation (typeof (TestType));
+ }
+
+ [ExpectedWarning ("IL2111", nameof (GenericMethodWithAnnotation))]
+ public static void GenericMethodWithAnnotationViaLdftn ()
+ {
+ var _ = new Action (GenericMethodWithAnnotation);
+ }
+
+ [ExpectedWarning ("IL2111", nameof (GenericMethodWithAnnotation))]
+ public static void GenericMethodDynamicallyAccessedMembers ()
+ {
+ typeof (AnnotationOnGenerics).RequiresPublicMethods ();
+ }
+
+ public static void Test ()
+ {
+ GenericTypeWithStaticMethodViaLdftn ();
+ GenericMethodWithAnnotationReflection ();
+ GenericMethodWithAnnotationDirectCall ();
+ GenericMethodWithAnnotationViaLdftn ();
+ GenericMethodDynamicallyAccessedMembers ();
+ }
+ }
+
+ class AnnotationOnInteropMethod
+ {
+ struct ValueWithAnnotatedField
+ {
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ public Type _typeField;
+ }
+
+ [ExpectedWarning ("IL2110", nameof (ValueWithAnnotatedField._typeField))]
+ [DllImport ("nonexistent")]
+ static extern ValueWithAnnotatedField GetValueWithAnnotatedField ();
+
+ [ExpectedWarning ("IL2110", nameof (ValueWithAnnotatedField._typeField))]
+ [DllImport ("nonexistent")]
+ static extern void AcceptValueWithAnnotatedField (ValueWithAnnotatedField value);
+
+ public static void Test ()
+ {
+ GetValueWithAnnotatedField ();
+ AcceptValueWithAnnotatedField (default (ValueWithAnnotatedField));
+ }
+ }
+
+ class AccessThroughLdToken
+ {
+ public virtual Type PropertyWithLdToken {
+ [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ get {
+ return null;
+ }
+ }
+
+ [ExpectedWarning ("IL2111", nameof (PropertyWithLdToken))]
+ public static void Test ()
+ {
+ Expression> getter = () => (new AccessThroughLdToken ()).PropertyWithLdToken;
+ }
+ }
+
+ class TestType { }
+ }
+}
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/VirtualMethodHierarchyDataflowAnnotationValidation.cs b/test/Mono.Linker.Tests.Cases/DataFlow/VirtualMethodHierarchyDataflowAnnotationValidation.cs
index c21c32b1d29b..4e59e09b4938 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/VirtualMethodHierarchyDataflowAnnotationValidation.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/VirtualMethodHierarchyDataflowAnnotationValidation.cs
@@ -13,6 +13,10 @@ namespace Mono.Linker.Tests.Cases.DataFlow
{
[SkipKeptItemsValidation]
[SandboxDependency ("Dependencies/TestSystemTypeBase.cs")]
+
+ // Suppress warnings about accessing methods with annotations via reflection - the test below does that a LOT
+ // (The test accessed these methods through DynamicallyAccessedMembers annotations which is effectively the same reflection access)
+ [UnconditionalSuppressMessage ("test", "IL2111")]
class VirtualMethodHierarchyDataflowAnnotationValidation
{
public static void Main ()
@@ -267,9 +271,13 @@ public override void GenericBaseWithoutDerivedWithout () { }
// === RequiresUnreferencedCode ===
- [ExpectedWarning ("IL2046", "DerivedClass.RequiresUnreferencedCodeBaseWithDerivedWithout()", "BaseClass.RequiresUnreferencedCodeBaseWithDerivedWithout()")]
+ [ExpectedWarning ("IL2046", "DerivedClass.RequiresUnreferencedCodeBaseWithDerivedWithout()",
+ "BaseClass.RequiresUnreferencedCodeBaseWithDerivedWithout()",
+ "'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides")]
public override void RequiresUnreferencedCodeBaseWithDerivedWithout () { }
- [ExpectedWarning ("IL2046", "DerivedClass.RequiresUnreferencedCodeBaseWithoutDerivedWith_()", "BaseClass.RequiresUnreferencedCodeBaseWithoutDerivedWith_()")]
+ [ExpectedWarning ("IL2046", "DerivedClass.RequiresUnreferencedCodeBaseWithoutDerivedWith_()",
+ "BaseClass.RequiresUnreferencedCodeBaseWithoutDerivedWith_()",
+ "'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides")]
[RequiresUnreferencedCode ("")]
public override void RequiresUnreferencedCodeBaseWithoutDerivedWith_ () { }
[LogDoesNotContain ("DerivedClass.RequiresUnreferencedCodeBaseWithDerivedWith_")]
diff --git a/test/Mono.Linker.Tests.Cases/Reflection/ExpressionCallString.cs b/test/Mono.Linker.Tests.Cases/Reflection/ExpressionCallString.cs
index 142e82dd5720..b4b71d5ebfbf 100644
--- a/test/Mono.Linker.Tests.Cases/Reflection/ExpressionCallString.cs
+++ b/test/Mono.Linker.Tests.Cases/Reflection/ExpressionCallString.cs
@@ -117,21 +117,6 @@ static string GetUnknownString ()
[Kept]
class TestUnknownType
{
- [Kept]
- public static void PublicMethod ()
- {
- }
-
- [Kept]
- protected static void ProtectedMethod ()
- {
- }
-
- [Kept]
- private static void PrivateMethod ()
- {
- }
-
[Kept]
[UnrecognizedReflectionAccessPattern (typeof (Expression), nameof (Expression.Call),
new Type[] { typeof (Type), typeof (string), typeof (Type[]), typeof (Expression[]) }, messageCode: "IL2072")]
@@ -148,13 +133,13 @@ public static void Test ()
[return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
static Type GetUnknownType ()
{
- return typeof (TestUnknownType);
+ return typeof (TestType);
}
[Kept]
static Type TriggerUnrecognizedPattern ()
{
- return typeof (TestUnknownType);
+ return typeof (TestType);
}
}
@@ -355,5 +340,8 @@ public static void Test ()
[return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)]
static Type GetUnknownTypeWithRequrements () { return null; }
}
+
+ [Kept]
+ class TestType { }
}
}
diff --git a/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyLibraryModeSuppressions.cs b/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyLibraryModeSuppressions.cs
index 6d81d5b07bcd..b03b481a4e0e 100644
--- a/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyLibraryModeSuppressions.cs
+++ b/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyLibraryModeSuppressions.cs
@@ -26,24 +26,24 @@ public static void Main ()
[Kept]
[KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
- [ExpectedWarning ("IL2026", nameof (Unsuppressed))]
class Unsuppressed
{
[Kept]
[KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", "--RUC on Unsuppressed--")]
[RequiresUnreferencedCode ("--RUC on Unsuppressed--")]
public void RUCMethod () { }
}
[Kept]
[KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
- [KeptAttributeAttribute (typeof (UnconditionalSuppressMessageAttribute))]
- [UnconditionalSuppressMessage ("TrimAnalysis", "IL2026")]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
class Suppressed
{
[Kept]
[KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [KeptAttributeAttribute (typeof (UnconditionalSuppressMessageAttribute))]
+ [UnconditionalSuppressMessage ("TrimAnalysis", "IL2112")]
[RequiresUnreferencedCode ("--RUC on Suppressed--")]
public void RUCMethod () { }
}
diff --git a/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs b/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs
new file mode 100644
index 000000000000..3cbdf4b0e4e3
--- /dev/null
+++ b/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs
@@ -0,0 +1,481 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Text;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Helpers;
+using Mono.Linker.Tests.Cases.Expectations.Metadata;
+
+namespace Mono.Linker.Tests.Cases.Reflection
+{
+ [ExpectedNoWarnings]
+ public class TypeHierarchyReflectionWarnings
+ {
+ public static void Main ()
+ {
+ RequirePublicMethods (annotatedBase.GetType ());
+ // Reference to the derived type should apply base annotations
+ var t = typeof (DerivedFromAnnotatedBase);
+ RequirePublicMethods (annotatedDerivedFromBase.GetType ());
+ RequirePublicNestedTypes (annotatedPublicNestedTypes.GetType ());
+ RequirePublicFields (derivedFromAnnotatedDerivedFromBase.GetType ());
+ RequirePublicMethods (annotatedPublicMethods.GetType ());
+ RequirePublicFields (annotatedPublicFields.GetType ());
+ RequirePublicProperties (annotatedPublicProperties.GetType ());
+ RequirePublicEvents (annotatedPublicEvents.GetType ());
+ RequirePublicNestedTypes (annotatedPublicNestedTypes.GetType ());
+ RequireInterfaces (annotatedInterfaces.GetType ());
+ RequireAll (annotatedAll.GetType ());
+ RequirePublicMethods (annotatedRUCPublicMethods.GetType ());
+
+ // Instantiate this type just so its property getters are considered reachable
+ var b = new DerivedFromAnnotatedDerivedFromBase ();
+
+ // Check that this field doesn't produce a warning even if it is kept
+ // for some non-reflection access.
+ var f = AnnotatedPublicMethods.DAMField;
+ }
+
+ [Kept]
+ static AnnotatedAll annotatedAll;
+ [Kept]
+ static AnnotatedPublicMethods annotatedPublicMethods;
+ [Kept]
+ static AnnotatedPublicFields annotatedPublicFields;
+ [Kept]
+ static AnnotatedPublicProperties annotatedPublicProperties;
+ [Kept]
+ static AnnotatedPublicEvents annotatedPublicEvents;
+ [Kept]
+ static AnnotatedInterfaces annotatedInterfaces;
+ [Kept]
+ static AnnotatedBase annotatedBase;
+ [Kept]
+ static AnnotatedDerivedFromBase annotatedDerivedFromBase;
+ [Kept]
+ static AnnotatedPublicNestedTypes annotatedPublicNestedTypes;
+ [Kept]
+ static DerivedFromAnnotatedDerivedFromBase derivedFromAnnotatedDerivedFromBase;
+ [Kept]
+ static AnnotatedRUCPublicMethods annotatedRUCPublicMethods;
+
+ [Kept]
+ [KeptMember (".ctor()")]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)]
+ class AnnotatedAll
+ {
+ [Kept]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ [ExpectedWarning ("IL2114", nameof (AnnotatedAll), nameof (DAMField))]
+ public Type DAMField;
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", "--RUC on AnnotatedAll.RUCMethod--")]
+ [RequiresUnreferencedCode ("--RUC on AnnotatedAll.RUCMethod--")]
+ public void RUCMethod () { }
+
+ [Kept]
+ [ExpectedWarning ("IL2114", nameof (AnnotatedAll), nameof (DAMMethod))]
+ public void DAMMethod (
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ Type t
+ )
+ { }
+ }
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ class AnnotatedPublicMethods
+ {
+ [Kept]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", "--RUC on AnnotatedPublicMethods.RUCMethod--")]
+ [RequiresUnreferencedCode ("--RUC on AnnotatedPublicMethods.RUCMethod--")]
+ public void RUCMethod () { }
+
+ // No warning for members not selected by the type's annotation
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ public static Type UnusedDAMField;
+
+ // No warning for members not selected by the type's annotation, even if field is referenced statically
+ [Kept]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ public static Type DAMField;
+
+ [Kept]
+ [ExpectedWarning ("IL2114", nameof (AnnotatedPublicMethods), nameof (DAMMethod))]
+ public void DAMMethod (
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ Type t
+ )
+ { }
+
+ [Kept]
+ // No warning for non-virtual method which only has DAM on return parameter
+ [return: KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [return: DynamicallyAccessedMembersAttribute (DynamicallyAccessedMemberTypes.PublicMethods)]
+ public Type DAMReturnMethod () => null;
+
+ [Kept]
+ [ExpectedWarning ("IL2114", nameof (AnnotatedPublicMethods), nameof (DAMVirtualMethod))]
+ public virtual void DAMVirtualMethod (
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ Type type
+ )
+ { }
+
+ [Kept]
+ [ExpectedWarning ("IL2114", nameof (AnnotatedPublicMethods), nameof (DAMReturnVirtualMethod))]
+ [return: KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [return: DynamicallyAccessedMembersAttribute (DynamicallyAccessedMemberTypes.PublicMethods)]
+ public virtual Type DAMReturnVirtualMethod () => null;
+ }
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)]
+ class AnnotatedPublicFields
+ {
+ [Kept]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ [ExpectedWarning ("IL2114", nameof (AnnotatedPublicFields), nameof (DAMField))]
+ public Type DAMField;
+
+ }
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)]
+ class AnnotatedPublicProperties
+ {
+ [Kept]
+ [KeptBackingField]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ public static string DAMProperty {
+ [Kept]
+ // No warning for non-virtual getter since return value is not annotated
+ get;
+ [Kept]
+ // Property access reports warnings on getter/setter
+ [ExpectedWarning ("IL2114", nameof (AnnotatedPublicProperties), nameof (DAMProperty) + ".set")]
+ set;
+ }
+ }
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)]
+ class AnnotatedPublicEvents
+ {
+ [Kept]
+ [KeptMember (".ctor(System.Object,System.IntPtr)")]
+ [KeptMember ("Invoke(System.Object,System.Int32)")]
+ [KeptBaseType (typeof (MulticastDelegate))]
+ public delegate void MyEventHandler (object sender, int i);
+
+ [Kept]
+ // We always keep event methods when an event is kept, so this generates warnings
+ // on the event itself (since an event access is considered to reference the annotated add method),
+ // and on the add method (if it is accessed through reflection).
+ [ExpectedWarning ("IL2026", "--RUC on add_RUCEvent--")]
+ public event MyEventHandler RUCEvent {
+ [Kept]
+ [ExpectedWarning ("IL2112", nameof (AnnotatedPublicEvents), "--RUC on add_RUCEvent--")]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [RequiresUnreferencedCode ("--RUC on add_RUCEvent--")]
+ add { }
+ [Kept]
+ remove { }
+ }
+ }
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ interface RequiredInterface
+ {
+ // Removed, because keeping the interface on its own
+ // doesn't apply its type annotations
+ [RequiresUnreferencedCode ("--RUC on RequiredInterface.UnusedMethod--")]
+ void RUCMethod ();
+ }
+
+ [Kept]
+ [KeptInterface (typeof (RequiredInterface))]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)]
+ class AnnotatedInterfaces : RequiredInterface
+ {
+ [Kept]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ // This should produce a warning: https://github.com/mono/linker/issues/2161
+ [RequiresUnreferencedCode ("--RUC on AnnotatedInterfaces.UnusedMethod--")]
+ public void RUCMethod () { }
+ }
+
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ class AnnotatedBase
+ {
+ [Kept]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", "--RUC on AnnotatedBase--")]
+ [RequiresUnreferencedCode ("--RUC on AnnotatedBase--")]
+ public void RUCMethod () { }
+ }
+
+ [KeptBaseType (typeof (AnnotatedBase))]
+ // Warning about base member could go away with https://github.com/mono/linker/issues/2175
+ [ExpectedWarning ("IL2113", "--RUC on AnnotatedBase--")]
+ class DerivedFromAnnotatedBase : AnnotatedBase
+ {
+ [Kept]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", "--RUC on DerivedFromAnnotatedBase--")]
+ [RequiresUnreferencedCode ("--RUC on DerivedFromAnnotatedBase--")]
+ public void RUCMethod () { }
+ }
+
+ [KeptMember (".ctor()")]
+ class Base
+ {
+ [Kept]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [RequiresUnreferencedCode ("--RUCBaseMethod--")]
+ public void RUCBaseMethod () { }
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [RequiresUnreferencedCode ("--Base.RUCVirtualMethod--")]
+ public virtual void RUCVirtualMethod () { }
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)]
+ public string DAMField1;
+
+ [Kept]
+ [KeptBackingField]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)]
+ public virtual string DAMVirtualProperty { [Kept] get; }
+ }
+
+ [KeptBaseType (typeof (Base))]
+ [KeptMember (".ctor()")]
+ [ExpectedWarning ("IL2113", "--RUCBaseMethod--")]
+ [ExpectedWarning ("IL2113", "--Base.RUCVirtualMethod--")]
+ [ExpectedWarning ("IL2115", nameof (Base), nameof (Base.DAMVirtualProperty) + ".get")]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ class AnnotatedDerivedFromBase : Base
+ {
+ [Kept]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", "--RUC on AnnotatedDerivedFromBase--")]
+ [RequiresUnreferencedCode ("--RUC on AnnotatedDerivedFromBase--")]
+ public void RUCMethod () { }
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ // shouldn't warn because we warn on the base method instead
+ [RequiresUnreferencedCode ("--AnnotatedDerivedFromBase.RUCVirtualMethod--")]
+ public override void RUCVirtualMethod () { }
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)]
+ public string DAMField2;
+
+ [Kept]
+ [KeptBackingField]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ // shouldn't warn because we warn on the base getter instead
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)]
+ public override string DAMVirtualProperty { [Kept] get; }
+
+ }
+
+ [KeptBaseType (typeof (AnnotatedDerivedFromBase))]
+ [KeptMember (".ctor()")]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)]
+ // Warnings about base members could go away with https://github.com/mono/linker/issues/2175
+ [ExpectedWarning ("IL2115", nameof (Base), nameof (DAMField1))]
+ [ExpectedWarning ("IL2115", nameof (AnnotatedDerivedFromBase), nameof (DAMField2))]
+ [ExpectedWarning ("IL2113", "--RUCBaseMethod--")]
+ [ExpectedWarning ("IL2113", "--Base.RUCVirtualMethod--")]
+ [ExpectedWarning ("IL2113", "--RUC on AnnotatedDerivedFromBase--")]
+ [ExpectedWarning ("IL2115", nameof (Base), nameof (Base.DAMVirtualProperty) + ".get")]
+ class DerivedFromAnnotatedDerivedFromBase : AnnotatedDerivedFromBase
+ {
+ [Kept]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", "--RUC on AnnotatedDerivedFromBase--")]
+ [RequiresUnreferencedCode ("--RUC on AnnotatedDerivedFromBase--")]
+ public void RUCMethod () { }
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ // shouldn't warn because we warn on the base method instead
+ [RequiresUnreferencedCode ("--DerivedFromAnnotatedDerivedFromBase.RUCVirtualMethod--")]
+ public override void RUCVirtualMethod () { }
+
+ [Kept]
+ [ExpectedWarning ("IL2114", nameof (DerivedFromAnnotatedDerivedFromBase), nameof (DAMField3))]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)]
+ public string DAMField3;
+
+ [Kept]
+ [KeptBackingField]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ // shouldn't warn because we warn on the base getter instead
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)]
+ public override string DAMVirtualProperty { [Kept] get; }
+ }
+
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)]
+ class AnnotatedPublicNestedTypes
+ {
+ [KeptMember (".ctor()")]
+ public class NestedType
+ {
+ [Kept]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", "--RUC on NestedType.RUCMethod--")]
+ [RequiresUnreferencedCode ("--RUC on NestedType.RUCMethod--")]
+ void RUCMethod () { }
+ }
+
+ [KeptMember (".ctor()")]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ public class NestedAnnotatedType
+ {
+ [Kept]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", "--RUC on NestedAnnotatedType.RUCMethod--")]
+ [RequiresUnreferencedCode ("--RUC on NestedAnnotatedType.RUCMethod--")]
+ void RUCMethod () { }
+ }
+
+ [KeptMember (".ctor()")]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [RequiresUnreferencedCode ("--RUC on NestedRUCType--")]
+ public class NestedRUCType
+ {
+ [Kept]
+ [ExpectedWarning ("IL2112", "--RUC on NestedRUCType--")]
+ public NestedRUCType () { }
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", "--RUC on NestedRUCType.RUCMethod--")]
+ [RequiresUnreferencedCode ("--RUC on NestedRUCType.RUCMethod--")]
+ void RUCMethod () { }
+
+ [Kept]
+ void Method () { }
+
+ [Kept]
+ [ExpectedWarning ("IL2112", "--RUC on NestedRUCType--")]
+ static void StaticMethod () { }
+ }
+
+ [KeptMember (".ctor()")]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", nameof (NestedRUCTypeWithDefaultConstructor) + "()", "--RUC on NestedRUCTypeWithDefaultConstructor--", CompilerGeneratedCode = true)]
+ [RequiresUnreferencedCode ("--RUC on NestedRUCTypeWithDefaultConstructor--")]
+ public class NestedRUCTypeWithDefaultConstructor
+ {
+ }
+ }
+
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ [RequiresUnreferencedCode ("--AnnotatedRUCPublicMethods--")]
+ public class AnnotatedRUCPublicMethods
+ {
+ public AnnotatedRUCPublicMethods () { }
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", "--RUC on AnnotatedRUCPublicMethods.RUCMethod--")]
+ [RequiresUnreferencedCode ("--RUC on AnnotatedRUCPublicMethods.RUCMethod--")]
+ public void RUCMethod () { }
+
+ [Kept]
+ public void Method () { }
+
+ [Kept]
+ [ExpectedWarning ("IL2112", "--AnnotatedRUCPublicMethods--")]
+ public static void StaticMethod () { }
+ }
+
+ [Kept]
+ static void RequirePublicMethods (
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ Type type)
+ { }
+
+ [Kept]
+ static void RequirePublicFields (
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)]
+ Type type)
+ { }
+
+ [Kept]
+ static void RequirePublicProperties (
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)]
+ Type type)
+ { }
+
+ [Kept]
+ static void RequirePublicEvents (
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)]
+ Type type)
+ { }
+
+ [Kept]
+ static void RequireAll (
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)]
+ Type type)
+ { }
+
+ [Kept]
+ static void RequirePublicNestedTypes (
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)]
+ Type type)
+ { }
+
+ [Kept]
+ static void RequireInterfaces (
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)]
+ Type type)
+ { }
+ }
+}
diff --git a/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchySuppressions.cs b/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchySuppressions.cs
index 67c9e4efcb4e..fe9a44c3b092 100644
--- a/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchySuppressions.cs
+++ b/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchySuppressions.cs
@@ -15,33 +15,25 @@ namespace Mono.Linker.Tests.Cases.Reflection
[ExpectedNoWarnings]
public class TypeHierarchySuppressions
{
- // https://github.com/mono/linker/issues/2136
- // Warnings should originate from the types (or rather their members, with the
- // proposed behavior), and the type suppressions should silence the relevant
- // warnings.
-
- // Should originate from types instead
- [ExpectedWarning ("IL2026", "--RUC on Unsuppressed--")]
- [ExpectedWarning ("IL2026", "--RUC on DerivedFromUnsuppressed1--")]
-
- // Should be suppressed by type-level suppression
- [ExpectedWarning ("IL2026", "--RUC on Suppressed--")]
- [ExpectedWarning ("IL2026", "--RUC on SuppressedOnDerived1--")]
- [ExpectedWarning ("IL2026", "--RUC on DerivedFromSuppressed1--")]
public static void Main ()
{
RequireMethods (unsuppressed.GetType ());
RequireMethods (suppressed.GetType ());
+ RequireAll (annotatedAllSuppressed.GetType ());
var t = typeof (DerivedFromSuppressed1);
var t2 = typeof (DerivedFromUnsuppressed1);
var t3 = typeof (SuppressedOnDerived1);
+ var t4 = typeof (SuppressedBaseWarningsOnDerived);
UseDerivedTypes ();
+
+ // Suppressing type hierarchy warnings is unsafe because it allows
+ // derived types to access annotated methods without any warnings:
+ derivedFromSuppressed.GetType ().GetMethod ("RUCDerivedMethod");
+
}
- // Referencing these types in a separate method ensures that they get
- // marked after applying annotations on the base type.
[Kept]
static void UseDerivedTypes ()
{
@@ -52,9 +44,12 @@ static void UseDerivedTypes ()
[Kept]
static Unsuppressed unsuppressed;
-
[Kept]
static Suppressed suppressed;
+ [Kept]
+ static DerivedFromSuppressed1 derivedFromSuppressed;
+ [Kept]
+ static AnnotatedAllSuppressed annotatedAllSuppressed;
[Kept]
static void RequireMethods (
@@ -63,41 +58,45 @@ static void RequireMethods (
Type type)
{ }
+ [Kept]
+ static void RequireAll (
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)]
+ Type type)
+ { }
+
[Kept]
[KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
- // https://github.com/mono/linker/issues/2136
- // [ExpectedWarning ("IL2026", "--RUC on Unsuppressed--")]
class Unsuppressed
{
[Kept]
[KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", "--RUC on Unsuppressed--")]
[RequiresUnreferencedCode ("--RUC on Unsuppressed--")]
public void RUCMethod () { }
}
[Kept]
[KeptBaseType (typeof (Unsuppressed))]
- // https://github.com/mono/linker/issues/2136
- // [ExpectedWarning ("IL2026", "--RUC on DerivedFromUnsuppressed1--")]
+ [ExpectedWarning ("IL2113", "--RUC on Unsuppressed--")]
class DerivedFromUnsuppressed1 : Unsuppressed
{
[Kept]
[KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", "--RUC on DerivedFromUnsuppressed1--")]
[RequiresUnreferencedCode ("--RUC on DerivedFromUnsuppressed1--")]
public void DerivedRUCMethod () { }
}
[Kept]
[KeptBaseType (typeof (Unsuppressed))]
- [ExpectedWarning ("IL2026", "--RUC on DerivedFromUnsuppressed2")]
- // https://github.com/mono/linker/issues/2136
- // Should originate from the base type instead
- [ExpectedWarning ("IL2026", "--RUC on Unsuppressed--")]
+ [ExpectedWarning ("IL2113", "--RUC on Unsuppressed--")]
class DerivedFromUnsuppressed2 : Unsuppressed
{
[Kept]
[KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", "--RUC on DerivedFromUnsuppressed2")]
[RequiresUnreferencedCode ("--RUC on DerivedFromUnsuppressed2--")]
public void DerivedRUCMethod () { }
}
@@ -105,7 +104,7 @@ public void DerivedRUCMethod () { }
[Kept]
[KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
[KeptAttributeAttribute (typeof (UnconditionalSuppressMessageAttribute))]
- [UnconditionalSuppressMessage ("TrimAnalysis", "IL2026")]
+ [UnconditionalSuppressMessage ("TrimAnalysis", "IL2112")]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
class Suppressed
{
@@ -117,51 +116,99 @@ public void RUCMethod () { }
[Kept]
[KeptBaseType (typeof (Suppressed))]
- // https://github.com/mono/linker/issues/2136
- // [ExpectedWarning ("IL2026", "--RUC on DerivedFromSuppressed1--")]
+ // Base method should warn even though it was suppressed on the base
+ [ExpectedWarning ("IL2113", "--RUC on Suppressed--")]
class DerivedFromSuppressed1 : Suppressed
{
[Kept]
[KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", "--RUC on DerivedFromSuppressed1--")]
[RequiresUnreferencedCode ("--RUC on DerivedFromSuppressed1--")]
public void RUCDerivedMethod () { }
}
[Kept]
[KeptBaseType (typeof (Suppressed))]
- [ExpectedWarning ("IL2026", "--RUC on DerivedFromSuppressed2--")]
- // https://github.com/mono/linker/issues/2136
- [ExpectedWarning ("IL2026", "--RUC on Suppressed--")]
+ // Base method should warn even though it was suppressed on the base
+ [ExpectedWarning ("IL2113", "--RUC on Suppressed--")]
class DerivedFromSuppressed2 : Suppressed
{
[Kept]
[KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", "--RUC on DerivedFromSuppressed2--")]
[RequiresUnreferencedCode ("--RUC on DerivedFromSuppressed2--")]
public void RUCDerivedMethod () { }
}
[Kept]
[KeptBaseType (typeof (Unsuppressed))]
- [KeptAttributeAttribute (typeof (UnconditionalSuppressMessageAttribute))]
- [UnconditionalSuppressMessage ("TrimAnalysis", "IL2026")]
+ [ExpectedWarning ("IL2113", "--RUC on Unsuppressed--")]
class SuppressedOnDerived1 : Unsuppressed
{
[Kept]
[KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [KeptAttributeAttribute (typeof (UnconditionalSuppressMessageAttribute))]
+ [UnconditionalSuppressMessage ("TrimAnalysis", "IL2112")]
[RequiresUnreferencedCode ("--RUC on SuppressedOnDerived1--")]
public void DerivedRUCMethod () { }
}
[Kept]
[KeptBaseType (typeof (Unsuppressed))]
- [KeptAttributeAttribute (typeof (UnconditionalSuppressMessageAttribute))]
- [UnconditionalSuppressMessage ("TrimAnalysis", "IL2026")]
+ [ExpectedWarning ("IL2113", "--RUC on Unsuppressed--")]
class SuppressedOnDerived2 : Unsuppressed
{
[Kept]
[KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [KeptAttributeAttribute (typeof (UnconditionalSuppressMessageAttribute))]
+ [UnconditionalSuppressMessage ("TrimAnalysis", "IL2112")]
[RequiresUnreferencedCode ("--RUC on SuppressedOnDerived2--")]
public void DerivedRUCMethod () { }
}
+
+ [Kept]
+ [KeptBaseType (typeof (Unsuppressed))]
+ [KeptAttributeAttribute (typeof (UnconditionalSuppressMessageAttribute))]
+ // Suppress warnings about base members
+ [UnconditionalSuppressMessage ("TrimAnalysis", "IL2113")]
+ class SuppressedBaseWarningsOnDerived : Unsuppressed
+ {
+ [Kept]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [ExpectedWarning ("IL2112", "--RUC on SuppressedBaseWarningsOnDerived")]
+ [RequiresUnreferencedCode ("--RUC on SuppressedBaseWarningsOnDerived--")]
+ public void DerivedRUCMethod () { }
+ }
+
+ [Kept]
+ [KeptMember (".ctor()")]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)]
+ class AnnotatedAllSuppressed
+ {
+ [Kept]
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [KeptAttributeAttribute (typeof (UnconditionalSuppressMessageAttribute))]
+ [UnconditionalSuppressMessage ("TrimAnalysis", "IL2114")]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ public Type DAMTField;
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
+ [KeptAttributeAttribute (typeof (UnconditionalSuppressMessageAttribute))]
+ [UnconditionalSuppressMessage ("TrimAnalysis", "IL2112")]
+ [RequiresUnreferencedCode ("--RUC on AnnotatedAllSuppresed.RUCMethod--")]
+ public static void RUCMethod () { }
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (UnconditionalSuppressMessageAttribute))]
+ [UnconditionalSuppressMessage ("TrimAnalysis", "IL2114")]
+ public void DAMTMethod (
+ [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ Type t
+ )
+ { }
+ }
}
}
diff --git a/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs b/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs
index 7c71f3270a03..e03e732f8a6d 100644
--- a/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs
+++ b/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using Mono.Cecil;
@@ -761,6 +762,9 @@ void VerifyLoggedMessages (AssemblyDefinition original, LinkerTestLogger logger,
if (actualName.StartsWith (attrProvider.DeclaringType.FullName) &&
actualName.Contains ("<" + attrProvider.Name + ">"))
return true;
+ if (methodDefinition.Name == ".ctor" &&
+ methodDefinition.DeclaringType.FullName == attrProvider.FullName)
+ return true;
}
return false;