diff --git a/src/tools/illink/illink.sln b/src/tools/illink/illink.sln index 9e29ce206c9a25..5cf19d14719c69 100644 --- a/src/tools/illink/illink.sln +++ b/src/tools/illink/illink.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30524.135 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.33209.295 MinimumVisualStudioVersion = 15.0.26124.0 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Linker", "src\linker\Mono.Linker.csproj", "{DD28E2B1-057B-4B4D-A04D-B2EBD9E76E46}" EndProject @@ -33,16 +33,21 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "tlens", "src\tlens\tlens.cs EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILLink.CodeFixProvider", "src\ILLink.CodeFix\ILLink.CodeFixProvider.csproj", "{6D20F334-B7E4-4585-854B-8A0E2B29B4AA}" EndProject -Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ILLink.Shared", "src\ILLink.Shared\ILLink.Shared.shproj", "{92F5E753-2179-46DC-BDCE-736858C18DC7}" +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ILLink.Shared", "src\ILLink.Shared\ILLink.Shared.shproj", "{FF598E93-8E9E-4091-9F50-61A7572663AE}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILLink.RoslynAnalyzer.Tests.Generator", "test\ILLink.RoslynAnalyzer.Tests.Generator\ILLink.RoslynAnalyzer.Tests.Generator.csproj", "{3DDE7064-4B68-4979-8843-FDF4CE5A5140}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "external", "external", "{8FD57ADB-B449-4960-A141-845C1E2E26EC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil", "external\cecil\Mono.Cecil.csproj", "{7C068318-84AF-4861-9E5F-6F8A3BF38C9D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cecil", "cecil", "{223B8007-F26C-4E28-B28D-E43C97F7EE23}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "symbols", "symbols", "{19C783E3-B710-4F25-A977-0ADDA4D2CFEE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.Pdb", "external\cecil\symbols\pdb\Mono.Cecil.Pdb.csproj", "{AF7722A0-D1A7-4294-A181-B88B6BD67C6E}" +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 @@ -208,6 +213,30 @@ Global {3DDE7064-4B68-4979-8843-FDF4CE5A5140}.Release|x64.Build.0 = Release|Any CPU {3DDE7064-4B68-4979-8843-FDF4CE5A5140}.Release|x86.ActiveCfg = Release|Any CPU {3DDE7064-4B68-4979-8843-FDF4CE5A5140}.Release|x86.Build.0 = Release|Any CPU + {7C068318-84AF-4861-9E5F-6F8A3BF38C9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7C068318-84AF-4861-9E5F-6F8A3BF38C9D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7C068318-84AF-4861-9E5F-6F8A3BF38C9D}.Debug|x64.ActiveCfg = Debug|Any CPU + {7C068318-84AF-4861-9E5F-6F8A3BF38C9D}.Debug|x64.Build.0 = Debug|Any CPU + {7C068318-84AF-4861-9E5F-6F8A3BF38C9D}.Debug|x86.ActiveCfg = Debug|Any CPU + {7C068318-84AF-4861-9E5F-6F8A3BF38C9D}.Debug|x86.Build.0 = Debug|Any CPU + {7C068318-84AF-4861-9E5F-6F8A3BF38C9D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7C068318-84AF-4861-9E5F-6F8A3BF38C9D}.Release|Any CPU.Build.0 = Release|Any CPU + {7C068318-84AF-4861-9E5F-6F8A3BF38C9D}.Release|x64.ActiveCfg = Release|Any CPU + {7C068318-84AF-4861-9E5F-6F8A3BF38C9D}.Release|x64.Build.0 = Release|Any CPU + {7C068318-84AF-4861-9E5F-6F8A3BF38C9D}.Release|x86.ActiveCfg = Release|Any CPU + {7C068318-84AF-4861-9E5F-6F8A3BF38C9D}.Release|x86.Build.0 = Release|Any CPU + {AF7722A0-D1A7-4294-A181-B88B6BD67C6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF7722A0-D1A7-4294-A181-B88B6BD67C6E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF7722A0-D1A7-4294-A181-B88B6BD67C6E}.Debug|x64.ActiveCfg = Debug|Any CPU + {AF7722A0-D1A7-4294-A181-B88B6BD67C6E}.Debug|x64.Build.0 = Debug|Any CPU + {AF7722A0-D1A7-4294-A181-B88B6BD67C6E}.Debug|x86.ActiveCfg = Debug|Any CPU + {AF7722A0-D1A7-4294-A181-B88B6BD67C6E}.Debug|x86.Build.0 = Debug|Any CPU + {AF7722A0-D1A7-4294-A181-B88B6BD67C6E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF7722A0-D1A7-4294-A181-B88B6BD67C6E}.Release|Any CPU.Build.0 = Release|Any CPU + {AF7722A0-D1A7-4294-A181-B88B6BD67C6E}.Release|x64.ActiveCfg = Release|Any CPU + {AF7722A0-D1A7-4294-A181-B88B6BD67C6E}.Release|x64.Build.0 = Release|Any CPU + {AF7722A0-D1A7-4294-A181-B88B6BD67C6E}.Release|x86.ActiveCfg = Release|Any CPU + {AF7722A0-D1A7-4294-A181-B88B6BD67C6E}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -223,8 +252,17 @@ Global {8DA71B3B-5809-44E5-A018-5DE5C6FF6C2A} = {03EB085F-3E2E-4A68-A7DF-951ADF59A0CC} {6D20F334-B7E4-4585-854B-8A0E2B29B4AA} = {AA0569FB-73E9-4B42-9A19-714BB1229DAE} {3DDE7064-4B68-4979-8843-FDF4CE5A5140} = {C2969923-7BAA-4FE4-853C-F670B0D3C6C8} + {7C068318-84AF-4861-9E5F-6F8A3BF38C9D} = {8FD57ADB-B449-4960-A141-845C1E2E26EC} + {223B8007-F26C-4E28-B28D-E43C97F7EE23} = {8FD57ADB-B449-4960-A141-845C1E2E26EC} + {19C783E3-B710-4F25-A977-0ADDA4D2CFEE} = {223B8007-F26C-4E28-B28D-E43C97F7EE23} + {AF7722A0-D1A7-4294-A181-B88B6BD67C6E} = {19C783E3-B710-4F25-A977-0ADDA4D2CFEE} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E43A3901-42B0-48CA-BB36-5CD40A99A6EE} EndGlobalSection + GlobalSection(SharedMSBuildProjectFiles) = preSolution + 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 + src\ILLink.Shared\ILLink.Shared.projitems*{ff598e93-8e9e-4091-9f50-61a7572663ae}*SharedItemsImports = 13 + EndGlobalSection EndGlobal diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ParameterProxy.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ParameterProxy.cs index fe01aeaf5187ae..27b47d4f3b4e98 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ParameterProxy.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ParameterProxy.cs @@ -11,7 +11,7 @@ partial struct ParameterProxy { public ParameterProxy (IParameterSymbol parameter) { - Method = (new ((IMethodSymbol) parameter.ContainingSymbol)); + Method = new ((IMethodSymbol) parameter.ContainingSymbol); Index = (ParameterIndex) parameter.Ordinal + (Method.HasImplicitThis () ? 1 : 0); } diff --git a/src/tools/illink/src/ILLink.Shared/DataFlow/DefaultValueDictionary.cs b/src/tools/illink/src/ILLink.Shared/DataFlow/DefaultValueDictionary.cs index 599e7d3b9871c5..0c2ce21ad67018 100644 --- a/src/tools/illink/src/ILLink.Shared/DataFlow/DefaultValueDictionary.cs +++ b/src/tools/illink/src/ILLink.Shared/DataFlow/DefaultValueDictionary.cs @@ -108,5 +108,8 @@ public DefaultValueDictionary Clone () // Prevent warning CS0659 https://docs.microsoft.com/en-us/dotnet/csharp/misc/cs0659. // This type should never be used as a dictionary key. public override int GetHashCode () => throw new NotImplementedException (); + + public static bool operator == (DefaultValueDictionary left, DefaultValueDictionary right) => left.Equals (right); + public static bool operator != (DefaultValueDictionary left, DefaultValueDictionary right) => !(left == right); } } diff --git a/src/tools/illink/src/ILLink.Shared/DataFlow/MaybeLattice.cs b/src/tools/illink/src/ILLink.Shared/DataFlow/MaybeLattice.cs index 4e77f96347ef0a..6c2e6d60309c1b 100644 --- a/src/tools/illink/src/ILLink.Shared/DataFlow/MaybeLattice.cs +++ b/src/tools/illink/src/ILLink.Shared/DataFlow/MaybeLattice.cs @@ -26,6 +26,9 @@ public Maybe Clone () return new (copyValue.DeepCopy ()); return new (value); } + + public static bool operator == (Maybe left, Maybe right) => left.Equals (right); + public static bool operator != (Maybe left, Maybe right) => !(left == right); } public struct MaybeLattice : ILattice> diff --git a/src/tools/illink/src/ILLink.Shared/DataFlow/ValueSet.cs b/src/tools/illink/src/ILLink.Shared/DataFlow/ValueSet.cs index c47397d5af258a..d4d5af4a362c69 100644 --- a/src/tools/illink/src/ILLink.Shared/DataFlow/ValueSet.cs +++ b/src/tools/illink/src/ILLink.Shared/DataFlow/ValueSet.cs @@ -120,6 +120,9 @@ public bool Equals (ValueSet other) } } + public static bool operator == (ValueSet left, ValueSet right) => left.Equals (right); + public static bool operator != (ValueSet left, ValueSet right) => !(left == right); + public override int GetHashCode () { if (_values == null) diff --git a/src/tools/illink/src/ILLink.Shared/TypeSystemProxy/WellKnownType.cs b/src/tools/illink/src/ILLink.Shared/TypeSystemProxy/WellKnownType.cs index 999f8f4dc95f2a..d673f5c0b3e242 100644 --- a/src/tools/illink/src/ILLink.Shared/TypeSystemProxy/WellKnownType.cs +++ b/src/tools/illink/src/ILLink.Shared/TypeSystemProxy/WellKnownType.cs @@ -38,6 +38,7 @@ public static (string Namespace, string Name) GetNamespaceAndName (this WellKnow WellKnownType.System_NotSupportedException => ("System", "NotSupportedException"), WellKnownType.System_Runtime_CompilerServices_DisablePrivateReflectionAttribute => ("System.Runtime.CompilerServices", "DisablePrivateReflectionAttribute"), WellKnownType.System_Void => ("System", "Void"), + _ => throw new System.ArgumentException (type.ToString ()) }; } public static string GetNamespace (this WellKnownType type) => GetNamespaceAndName (type).Namespace; diff --git a/src/tools/illink/src/linker/Linker.Dataflow/HoistedLocalKey.cs b/src/tools/illink/src/linker/Linker.Dataflow/HoistedLocalKey.cs index b721df288b408b..503bdc6bbb840e 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/HoistedLocalKey.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/HoistedLocalKey.cs @@ -26,5 +26,8 @@ public HoistedLocalKey (FieldDefinition field) public override bool Equals (object? obj) => obj is HoistedLocalKey other && Equals (other); public override int GetHashCode () => Field.GetHashCode (); + + public static bool operator == (HoistedLocalKey left, HoistedLocalKey right) => left.Equals (right); + public static bool operator != (HoistedLocalKey left, HoistedLocalKey right) => !(left == right); } } \ No newline at end of file diff --git a/src/tools/illink/src/linker/Linker.Dataflow/ValueNode.cs b/src/tools/illink/src/linker/Linker.Dataflow/ValueNode.cs index 81d5e0581c2f9f..3374ca3317af94 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/ValueNode.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/ValueNode.cs @@ -64,5 +64,8 @@ public ValueBasicBlockPair (MultiValue value, int basicBlockIndex) public override bool Equals (object? obj) => obj is ValueBasicBlockPair other && Equals (other); public override int GetHashCode () => HashUtils.Combine (Value.GetHashCode (), BasicBlockIndex); + + public static bool operator == (ValueBasicBlockPair left, ValueBasicBlockPair right) => left.Equals (right); + public static bool operator != (ValueBasicBlockPair left, ValueBasicBlockPair right) => !(left == right); } } diff --git a/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs b/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs index ecfc6a1168821d..26bafe5a4e7915 100644 --- a/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs +++ b/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs @@ -1610,7 +1610,7 @@ protected void MarkField (FieldReference reference, DependencyInfo reason, in Me Debug.Assert (reason.Kind == DependencyKind.FieldAccess || reason.Kind == DependencyKind.Ldtoken); // Blame the field reference (without actually marking) on the original reason. Tracer.AddDirectDependency (reference, reason, marked: false); - MarkType (reference.DeclaringType, new DependencyInfo (DependencyKind.DeclaringType, reference), new MessageOrigin (Context.TryResolve (reference))); + MarkType (reference.DeclaringType, new DependencyInfo (DependencyKind.DeclaringType, reference)); // Blame the field definition that we will resolve on the field reference. reason = new DependencyInfo (DependencyKind.FieldOnGenericInstance, reference); diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs index 17e3a1fa27b7bf..32f60660d3fd7b 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs @@ -585,9 +585,7 @@ static bool IsMessageMatch (Diagnostic actual, ImmutableArray actualArgu public MatchQuality (int value) { - if (value < 0) { - throw new ArgumentOutOfRangeException (nameof (value)); - } + ArgumentOutOfRangeException.ThrowIfNegative (value); _value = value; } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedInstructionSequenceAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedInstructionSequenceAttribute.cs index 35ead6966a4f62..101e1be0288cc1 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedInstructionSequenceAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedInstructionSequenceAttribute.cs @@ -10,8 +10,7 @@ public class ExpectedInstructionSequenceAttribute : BaseInAssemblyAttribute { public ExpectedInstructionSequenceAttribute (string[] opCodes) { - if (opCodes == null) - throw new ArgumentNullException (nameof (opCodes)); + ArgumentNullException.ThrowIfNull (opCodes); } } } \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedInstructionSequenceOnMemberInAssemblyAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedInstructionSequenceOnMemberInAssemblyAttribute.cs index 899b979c5211e8..124bbab5bac753 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedInstructionSequenceOnMemberInAssemblyAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedInstructionSequenceOnMemberInAssemblyAttribute.cs @@ -12,12 +12,10 @@ public ExpectedInstructionSequenceOnMemberInAssemblyAttribute (string assemblyFi { if (string.IsNullOrEmpty (assemblyFileName)) throw new ArgumentNullException (nameof (assemblyFileName)); - if (type == null) - throw new ArgumentNullException (nameof (type)); + ArgumentNullException.ThrowIfNull (type); if (string.IsNullOrEmpty (memberName)) throw new ArgumentNullException (nameof (memberName)); - if (opCodes == null) - throw new ArgumentNullException (nameof (opCodes)); + ArgumentNullException.ThrowIfNull (opCodes); } public ExpectedInstructionSequenceOnMemberInAssemblyAttribute (string assemblyFileName, string typeName, string memberName, string[] opCodes) @@ -28,8 +26,7 @@ public ExpectedInstructionSequenceOnMemberInAssemblyAttribute (string assemblyFi throw new ArgumentNullException (nameof (typeName)); if (string.IsNullOrEmpty (memberName)) throw new ArgumentNullException (nameof (memberName)); - if (opCodes == null) - throw new ArgumentNullException (nameof (opCodes)); + ArgumentNullException.ThrowIfNull (opCodes); } } } \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedLocalsSequenceAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedLocalsSequenceAttribute.cs index fdd3441b71f44f..2016d26a0dbd10 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedLocalsSequenceAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedLocalsSequenceAttribute.cs @@ -10,14 +10,12 @@ public class ExpectedLocalsSequenceAttribute : BaseInAssemblyAttribute { public ExpectedLocalsSequenceAttribute (string[] types) { - if (types == null) - throw new ArgumentNullException (nameof (types)); + ArgumentNullException.ThrowIfNull (types); } public ExpectedLocalsSequenceAttribute (Type[] types) { - if (types == null) - throw new ArgumentNullException (nameof (types)); + ArgumentNullException.ThrowIfNull (types); } } } \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/IgnoreTestCaseAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/IgnoreTestCaseAttribute.cs index 78fd0e45374232..a9b11ebd3f32b5 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/IgnoreTestCaseAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/IgnoreTestCaseAttribute.cs @@ -11,8 +11,7 @@ public class IgnoreTestCaseAttribute : Attribute public IgnoreTestCaseAttribute (string reason) { - if (reason == null) - throw new ArgumentNullException (nameof (reason)); + ArgumentNullException.ThrowIfNull (reason); } } } \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeAttribute.cs index 0b5943a5a1a5e8..e558f304720aa9 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeAttribute.cs @@ -17,8 +17,7 @@ public KeptAttributeAttribute (string attributeName) public KeptAttributeAttribute (Type type) { - if (type == null) - throw new ArgumentNullException (nameof (type)); + ArgumentNullException.ThrowIfNull (type); } } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeOnFixedBufferTypeAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeOnFixedBufferTypeAttribute.cs index 0fc56741a8ca42..559e81bdad164c 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeOnFixedBufferTypeAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeOnFixedBufferTypeAttribute.cs @@ -16,8 +16,7 @@ public KeptAttributeOnFixedBufferTypeAttribute (string attributeName) public KeptAttributeOnFixedBufferTypeAttribute (Type type) { - if (type == null) - throw new ArgumentNullException (nameof (type)); + ArgumentNullException.ThrowIfNull (type); } } } \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBaseOnTypeInAssemblyAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBaseOnTypeInAssemblyAttribute.cs index acac5d575bbcea..5d454d806eec93 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBaseOnTypeInAssemblyAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBaseOnTypeInAssemblyAttribute.cs @@ -10,8 +10,7 @@ public class KeptBaseOnTypeInAssemblyAttribute : BaseInAssemblyAttribute { public KeptBaseOnTypeInAssemblyAttribute (string assemblyFileName, Type type, string baseAssemblyFileName, Type baseType) { - if (type == null) - throw new ArgumentNullException (nameof (type)); + ArgumentNullException.ThrowIfNull (type); if (string.IsNullOrEmpty (assemblyFileName)) throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBaseTypeAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBaseTypeAttribute.cs index c4e4a24889542c..c98ad9abcbe39c 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBaseTypeAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBaseTypeAttribute.cs @@ -10,16 +10,13 @@ public sealed class KeptBaseTypeAttribute : KeptAttribute { public KeptBaseTypeAttribute (Type baseType) { - if (baseType == null) - throw new ArgumentNullException (nameof (baseType)); + ArgumentNullException.ThrowIfNull (baseType); } public KeptBaseTypeAttribute (Type baseType, params object[] typeArguments) { - if (baseType == null) - throw new ArgumentNullException (nameof (baseType)); - if (typeArguments == null) - throw new ArgumentNullException (nameof (typeArguments)); + ArgumentNullException.ThrowIfNull (baseType); + ArgumentNullException.ThrowIfNull (typeArguments); } } } \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptExportedTypeAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptExportedTypeAttribute.cs index 76dbe921c94572..2e4ba1903e1a7a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptExportedTypeAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptExportedTypeAttribute.cs @@ -13,8 +13,7 @@ public class KeptExportedTypeAttribute : KeptAttribute { public KeptExportedTypeAttribute (Type type) { - if (type is null) - throw new ArgumentNullException (nameof (type)); + ArgumentNullException.ThrowIfNull (type); } } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInitializerData.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInitializerData.cs index 25b8c8261f16ce..9b98ef46e4515c 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInitializerData.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInitializerData.cs @@ -15,8 +15,7 @@ public KeptInitializerData () public KeptInitializerData (int occurrenceIndexInBody) { - if (occurrenceIndexInBody < 0) - throw new ArgumentOutOfRangeException (nameof (occurrenceIndexInBody)); + ArgumentOutOfRangeException.ThrowIfNegative (occurrenceIndexInBody); } } } \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInterfaceAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInterfaceAttribute.cs index 85279abcd83f6d..abbf5784e99bfc 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInterfaceAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInterfaceAttribute.cs @@ -11,16 +11,13 @@ public class KeptInterfaceAttribute : KeptAttribute public KeptInterfaceAttribute (Type interfaceType) { - if (interfaceType == null) - throw new ArgumentNullException (nameof (interfaceType)); + ArgumentNullException.ThrowIfNull (interfaceType); } public KeptInterfaceAttribute (Type interfaceType, params object[] typeArguments) { - if (interfaceType == null) - throw new ArgumentNullException (nameof (interfaceType)); - if (typeArguments == null) - throw new ArgumentNullException (nameof (typeArguments)); + ArgumentNullException.ThrowIfNull (interfaceType); + ArgumentNullException.ThrowIfNull (typeArguments); } } } \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInterfaceOnTypeInAssemblyAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInterfaceOnTypeInAssemblyAttribute.cs index 2741439facc88d..88bfd654ad75c3 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInterfaceOnTypeInAssemblyAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInterfaceOnTypeInAssemblyAttribute.cs @@ -10,8 +10,7 @@ public class KeptInterfaceOnTypeInAssemblyAttribute : BaseInAssemblyAttribute { public KeptInterfaceOnTypeInAssemblyAttribute (string assemblyFileName, Type type, string interfaceAssemblyFileName, Type interfaceType) { - if (type == null) - throw new ArgumentNullException (nameof (type)); + ArgumentNullException.ThrowIfNull (type); if (string.IsNullOrEmpty (assemblyFileName)) throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptMemberInAssemblyAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptMemberInAssemblyAttribute.cs index b8e38f5788c051..a756d8d24704f5 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptMemberInAssemblyAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptMemberInAssemblyAttribute.cs @@ -13,20 +13,16 @@ public KeptMemberInAssemblyAttribute (string assemblyFileName, Type type, params { if (string.IsNullOrEmpty (assemblyFileName)) throw new ArgumentNullException (nameof (assemblyFileName)); - if (type == null) - throw new ArgumentNullException (nameof (type)); - if (memberNames == null) - throw new ArgumentNullException (nameof (memberNames)); + ArgumentNullException.ThrowIfNull (type); + ArgumentNullException.ThrowIfNull (memberNames); } public KeptMemberInAssemblyAttribute (string assemblyFileName, string typeName, params string[] memberNames) { if (string.IsNullOrEmpty (assemblyFileName)) throw new ArgumentNullException (nameof (assemblyFileName)); - if (typeName == null) - throw new ArgumentNullException (nameof (typeName)); - if (memberNames == null) - throw new ArgumentNullException (nameof (memberNames)); + ArgumentNullException.ThrowIfNull (typeName); + ArgumentNullException.ThrowIfNull (memberNames); } public string ExpectationAssemblyName { get; set; } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptOverrideAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptOverrideAttribute.cs index 62bfd0c157947e..3c02278ea91429 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptOverrideAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptOverrideAttribute.cs @@ -19,8 +19,7 @@ public class KeptOverrideAttribute : KeptAttribute public KeptOverrideAttribute (Type typeWithOverriddenMethod) { - if (typeWithOverriddenMethod == null) - throw new ArgumentNullException (nameof (typeWithOverriddenMethod)); + ArgumentNullException.ThrowIfNull (typeWithOverriddenMethod); TypeWithOverriddenMethodDeclaration = typeWithOverriddenMethod; } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptReferencesInAssemblyAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptReferencesInAssemblyAttribute.cs index 0265b9f3a40d9f..e046c3935df9bf 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptReferencesInAssemblyAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptReferencesInAssemblyAttribute.cs @@ -13,8 +13,7 @@ public KeptReferencesInAssemblyAttribute (string assemblyFileName, string[] expe if (string.IsNullOrEmpty (assemblyFileName)) throw new ArgumentNullException (nameof (assemblyFileName)); - if (expectedReferenceAssemblyNames == null) - throw new ArgumentNullException (nameof (expectedReferenceAssemblyNames)); + ArgumentNullException.ThrowIfNull (expectedReferenceAssemblyNames); } } } \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptSecurityAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptSecurityAttribute.cs index 05519377252dc6..828bc4b64a0c3c 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptSecurityAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptSecurityAttribute.cs @@ -16,8 +16,7 @@ public KeptSecurityAttribute (string attributeName) public KeptSecurityAttribute (Type type) { - if (type == null) - throw new ArgumentNullException (nameof (type)); + ArgumentNullException.ThrowIfNull (type); } } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptTypeInAssemblyAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptTypeInAssemblyAttribute.cs index 5be0adc4aa1089..a9eb31c5bc81a0 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptTypeInAssemblyAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptTypeInAssemblyAttribute.cs @@ -10,8 +10,7 @@ public class KeptTypeInAssemblyAttribute : BaseInAssemblyAttribute { public KeptTypeInAssemblyAttribute (string assemblyFileName, Type type) { - if (type == null) - throw new ArgumentNullException (nameof (type)); + ArgumentNullException.ThrowIfNull (type); if (string.IsNullOrEmpty (assemblyFileName)) throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedInterfaceOnTypeInAssemblyAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedInterfaceOnTypeInAssemblyAttribute.cs index 70465fc3d6035f..a733a9a1800865 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedInterfaceOnTypeInAssemblyAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedInterfaceOnTypeInAssemblyAttribute.cs @@ -10,8 +10,7 @@ public class RemovedInterfaceOnTypeInAssemblyAttribute : BaseInAssemblyAttribute { public RemovedInterfaceOnTypeInAssemblyAttribute (string assemblyFileName, Type type, string interfaceAssemblyFileName, Type interfaceType) { - if (type == null) - throw new ArgumentNullException (nameof (type)); + ArgumentNullException.ThrowIfNull (type); if (string.IsNullOrEmpty (assemblyFileName)) throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedMemberInAssemblyAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedMemberInAssemblyAttribute.cs index fe0deb6374aaf2..bd54db71ba8113 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedMemberInAssemblyAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedMemberInAssemblyAttribute.cs @@ -13,20 +13,16 @@ public RemovedMemberInAssemblyAttribute (string assemblyFileName, Type type, par { if (string.IsNullOrEmpty (assemblyFileName)) throw new ArgumentNullException (nameof (assemblyFileName)); - if (type == null) - throw new ArgumentNullException (nameof (type)); - if (memberNames == null) - throw new ArgumentNullException (nameof (memberNames)); + ArgumentNullException.ThrowIfNull (type); + ArgumentNullException.ThrowIfNull (memberNames); } public RemovedMemberInAssemblyAttribute (string assemblyFileName, string typeName, params string[] memberNames) { if (string.IsNullOrEmpty (assemblyFileName)) throw new ArgumentNullException (nameof (assemblyFileName)); - if (typeName == null) - throw new ArgumentNullException (nameof (typeName)); - if (memberNames == null) - throw new ArgumentNullException (nameof (memberNames)); + ArgumentNullException.ThrowIfNull (typeName); + ArgumentNullException.ThrowIfNull (memberNames); } } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedTypeInAssemblyAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedTypeInAssemblyAttribute.cs index 079ba5d1f0b7d2..fe98db51bfc0fd 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedTypeInAssemblyAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedTypeInAssemblyAttribute.cs @@ -10,8 +10,7 @@ public class RemovedTypeInAssemblyAttribute : BaseInAssemblyAttribute { public RemovedTypeInAssemblyAttribute (string assemblyFileName, Type type) { - if (type == null) - throw new ArgumentNullException (nameof (type)); + ArgumentNullException.ThrowIfNull (type); if (string.IsNullOrEmpty (assemblyFileName)) throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/TestCaseRequirementsAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/TestCaseRequirementsAttribute.cs index 9e766c9ce05c67..caf60a23abe0fd 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/TestCaseRequirementsAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/TestCaseRequirementsAttribute.cs @@ -10,8 +10,7 @@ public class TestCaseRequirementsAttribute : BaseExpectedLinkedBehaviorAttribute { public TestCaseRequirementsAttribute (TestRunCharacteristics targetFrameworkCharacteristics, string reason) { - if (reason == null) - throw new ArgumentNullException (nameof (reason)); + ArgumentNullException.ThrowIfNull (reason); } } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAfterAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAfterAttribute.cs index 71f9f7a3854bb5..a81898225225b0 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAfterAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAfterAttribute.cs @@ -13,8 +13,7 @@ public class SetupCompileAfterAttribute : BaseMetadataAttribute { public SetupCompileAfterAttribute (string outputName, string[] sourceFiles, string[] references = null, string[] defines = null, object[] resources = null, string additionalArguments = null, string compilerToUse = null, bool addAsReference = true, bool removeFromLinkerInput = false) { - if (sourceFiles == null) - throw new ArgumentNullException (nameof (sourceFiles)); + ArgumentNullException.ThrowIfNull (sourceFiles); if (string.IsNullOrEmpty (outputName)) throw new ArgumentException ("Value cannot be null or empty.", nameof (outputName)); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileBeforeAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileBeforeAttribute.cs index 0021300c8403ec..73e5c69c20ca05 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileBeforeAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileBeforeAttribute.cs @@ -13,8 +13,7 @@ public class SetupCompileBeforeAttribute : BaseMetadataAttribute { public SetupCompileBeforeAttribute (string outputName, string[] sourceFiles, string[] references = null, string[] defines = null, object[] resources = null, string additionalArguments = null, string compilerToUse = null, bool addAsReference = true, bool removeFromLinkerInput = false, string outputSubFolder = null) { - if (sourceFiles == null) - throw new ArgumentNullException (nameof (sourceFiles)); + ArgumentNullException.ThrowIfNull (sourceFiles); if (string.IsNullOrEmpty (outputName)) throw new ArgumentException ("Value cannot be null or empty.", nameof (outputName)); @@ -35,8 +34,7 @@ public SetupCompileBeforeAttribute (string outputName, string[] sourceFiles, str public SetupCompileBeforeAttribute (string outputName, Type[] typesToIncludeSourceFor, string[] references = null, string[] defines = null, object[] resources = null, string additionalArguments = null, string compilerToUse = null, bool addAsReference = true, bool removeFromLinkerInput = false) { - if (typesToIncludeSourceFor == null) - throw new ArgumentNullException (nameof (typesToIncludeSourceFor)); + ArgumentNullException.ThrowIfNull (typesToIncludeSourceFor); if (string.IsNullOrEmpty (outputName)) throw new ArgumentException ("Value cannot be null or empty.", nameof (outputName)); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs index 1b82d33abbf85e..6b34dfc799517a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics.CodeAnalysis; +using System.Linq.Expressions; using System.Security.Policy; using Mono.Linker.Tests.Cases.Expectations.Assertions; @@ -25,7 +26,12 @@ public static void Main () class TypeInheritance { class BaseWithPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> - { } + { + public static void GetMethods () + { + typeof (TPublicMethods).GetMethods (); + } + } class BaseWithTwo< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, @@ -61,6 +67,18 @@ class DerivedWithTwoMatching< : BaseWithTwo { } + [ExpectedWarning ("IL2091")] + class DerivedWithOnlyStaticMethodReference : BaseWithPublicMethods + { + // The method body in this case looks like: + // BaseWithPublicMethods.GetMethods () + // The type instantiation needs to be validated and in this case it produces a warning. + // This is no different from the same code being part of a completely unrelated method/class. + // So the fact that this is in derived class has no impact on the validation in this case. + [ExpectedWarning ("IL2091")] + public static void GetDerivedMethods () => GetMethods (); + } + public static void Test () { Type t; @@ -70,6 +88,8 @@ public static void Test () t = typeof (DerivedWithMismatchAnnotation<>); t = typeof (DerivedWithOneMismatch<>); t = typeof (DerivedWithTwoMatching<,>); + + DerivedWithOnlyStaticMethodReference.GetDerivedMethods (); } } @@ -115,6 +135,13 @@ public static void Test () } } + // Method parameter instantiation doesn't technically need to be validated on its own + // Especially in AOT compiler the type of the method parameter won't even exist in the compilation + // unless something passes a real value to it, in which case that value creation will do all the necessary + // validations. So the declaration of the parameter type alone doesn't create an analysis hole + // it only becomes one if something tries to create an instance of such type. + // Similarly for statics - since we do validate accesses to static members, the static .ctor is covered through + // those as well. class MethodParametersAndReturn { class TypeWithPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> @@ -127,11 +154,11 @@ interface IWithTwo< static void MethodWithSpecificType (TypeWithPublicMethods one, IWithTwo two) { } - [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] static void MethodWithOneMismatch (TypeWithPublicMethods one) { } - [ExpectedWarning ("IL2091", nameof (IWithTwo))] - [ExpectedWarning ("IL2091", nameof (TypeWithPublicMethods))] + [ExpectedWarning ("IL2091", nameof (IWithTwo), ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] + [ExpectedWarning ("IL2091", nameof (TypeWithPublicMethods), ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] static void MethodWithTwoMismatches< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> @@ -142,11 +169,11 @@ static void MethodWithTwoMismatches< static TypeWithPublicMethods MethodWithMatchingReturn<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () => null; - [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] static TypeWithPublicMethods MethodWithOneMismatchReturn () => null; - [ExpectedWarning ("IL2091")] - [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] static IWithTwo MethodWithTwoMismatchesInReturn< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> @@ -165,6 +192,9 @@ public static void Test () } } + // Same as for method parameters - declaring a field with a specific type in itself is not problematic + // for the field to be "dangerous" it would need to have a non-null value and thus the instance has to be created somewhere + // and that point of creation is the place where the validation happens. class FieldDefinition { class TypeWithPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> @@ -197,10 +227,10 @@ public static void Test () class MultipleReferencesToTheSameType<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, TUnknown> { - [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] static TypeWithPublicMethods _field1; static TypeWithPublicMethods _field2; - [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] static TypeWithPublicMethods _field3; public static void Test () @@ -215,8 +245,8 @@ class TwoMismatchesInOne< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> { - [ExpectedWarning ("IL2091")] - [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] static IWithTwo _field; public static void Test () @@ -267,12 +297,12 @@ public static void Test () class MultipleReferencesToTheSameType<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, TUnknown> { // The warning is generated on the backing field - [ExpectedWarning ("IL2091", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2091", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] static TypeWithPublicMethods Property1 { - [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] get; - [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] set; } @@ -282,12 +312,12 @@ static TypeWithPublicMethods Property2 { } // The warning is generated on the backing field - [ExpectedWarning ("IL2091", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2091", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] static TypeWithPublicMethods Property3 { - [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] get; - [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] set; } @@ -304,14 +334,14 @@ class TwoMismatchesInOne< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> { // The warnings are generated on the backing field - [ExpectedWarning ("IL2091", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL2091", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2091", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] + [ExpectedWarning ("IL2091", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] static IWithTwo Property { // Getter is trimmed and doesn't produce any warning get; - [ExpectedWarning ("IL2091")] - [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)] set; } @@ -335,6 +365,10 @@ class MethodBody class TypeWithPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> : Exception { public static void Method () { } + + public static string Field; + + public static string Property { get; set; } } interface IWithTwo< @@ -342,6 +376,10 @@ interface IWithTwo< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> { public static void Method () { } + + public static string Field; + + public static string Property { get; set; } } class TypeWithTwo< @@ -358,6 +396,13 @@ static void MethodWithTwo< class TypeOf { + static void AccessOpenTypeDefinition () + { + // Accessing the open type definition should not do anything on its own - just validating that it doesn't break anything + Type t = typeof (TypeWithPublicMethods<>); + t = typeof (IWithTwo<,>); + } + static void SpecificType () { Type t = typeof (TypeWithPublicMethods); @@ -392,6 +437,7 @@ static void TwoMismatchesInOneStatement< public static void Test () { + AccessOpenTypeDefinition (); SpecificType (); OneMatchingAnnotation (); MultipleReferencesToTheSameType (); @@ -485,6 +531,49 @@ public static void Test () } } + class FieldAccessOnGenericType + { + static void SpecificType () + { + _ = TypeWithPublicMethods.Field; + IWithTwo.Field = ""; + } + + static void OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () + { + _ = TypeWithPublicMethods.Field; + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void MultipleReferencesToTheSameField< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + TUnknown> () + { + _ = TypeWithPublicMethods.Field; // Warn + TypeWithPublicMethods.Field = ""; // No warn + TypeWithPublicMethods.Field = ""; // Warn + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void TwoMismatchesInOneStatement< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + () + { + _ = IWithTwo.Field; + } + + public static void Test () + { + SpecificType (); + OneMatchingAnnotation (); + MultipleReferencesToTheSameField (); + TwoMismatchesInOneStatement (); + } + } + class LocalVariable { static void SpecificType () @@ -612,6 +701,210 @@ public static void Test () } } + class LdTokenOnGenericMethod + { + static void SpecificType () + { + Expression a = () => MethodWithPublicMethods (); + } + + static void OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () + { + Expression a = () => MethodWithPublicMethods (); + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void MultipleReferencesToTheSameMethod< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + TUnknown> () + { + Expression a = () => MethodWithPublicMethods (); // Warn + a = () => MethodWithPublicMethods (); // No warn + a = () => MethodWithPublicMethods (); // Warn + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void TwoMismatchesInOneStatement< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + () + { + Expression a = () => MethodWithTwo (); + } + + public static void Test () + { + SpecificType (); + OneMatchingAnnotation (); + MultipleReferencesToTheSameMethod (); + TwoMismatchesInOneStatement (); + } + } + + class LdTokenOfMethodOnGenericType + { + static void SpecificType () + { + Expression a = () => TypeWithPublicMethods.Method (); + } + + static void OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () + { + Expression a = () => TypeWithPublicMethods.Method (); + } + + // There are two warnings per "callsite" in this case because the generated IL does + // ldtoken method + // ldtoken owningtype + // In order to call the right Expression APIs. + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)] + static void MultipleReferencesToTheSameMethod< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + TUnknown> () + { + Expression a = () => TypeWithPublicMethods.Method (); // Warn + a = () => TypeWithPublicMethods.Method (); // No warn + a = () => TypeWithPublicMethods.Method (); // Warn + } + + // There are two warnings per "callsite" in this case because the generated IL does + // ldtoken method + // ldtoken owningtype + // In order to call the right Expression APIs. + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)] + static void TwoMismatchesInOneStatement< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + () + { + Expression a = () => IWithTwo.Method (); + } + + public static void Test () + { + SpecificType (); + OneMatchingAnnotation (); + MultipleReferencesToTheSameMethod (); + TwoMismatchesInOneStatement (); + } + } + + class LdTokenOfFieldOnGenericType + { + static void SpecificType () + { + Expression> a = () => TypeWithPublicMethods.Field; + } + + static void OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () + { + Expression> a = () => TypeWithPublicMethods.Field; + } + + // There are two warnings per "callsite" in this case because the generated IL does + // ldtoken field + // ldtoken owningtype + // In order to call the right Expression APIs. + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)] + static void MultipleReferencesToTheSameField< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + TUnknown> () + { + Expression> a = () => TypeWithPublicMethods.Field; // Warn + a = () => TypeWithPublicMethods.Field; // No warn + a = () => TypeWithPublicMethods.Field; // Warn + } + + // There are two warnings per "callsite" in this case because the generated IL does + // ldtoken field + // ldtoken owningtype + // In order to call the right Expression APIs. + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)] + static void TwoMismatchesInOneStatement< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + () + { + Expression> a = () => IWithTwo.Field; + } + + public static void Test () + { + SpecificType (); + OneMatchingAnnotation (); + MultipleReferencesToTheSameField (); + TwoMismatchesInOneStatement (); + } + } + + class LdTokenOfPropertyOnGenericType + { + static void SpecificType () + { + Expression> a = () => TypeWithPublicMethods.Property; + } + + static void OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () + { + Expression> a = () => TypeWithPublicMethods.Property; + } + + // There are two warnings per "callsite" in this case because the generated IL does + // ldtoken method (getter) + // ldtoken owningtype + // In order to call the right Expression APIs. + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)] + static void MultipleReferencesToTheSameProperty< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + TUnknown> () + { + Expression> a = () => TypeWithPublicMethods.Property; // Warn + a = () => TypeWithPublicMethods.Property; // No warn + a = () => TypeWithPublicMethods.Property; // Warn + } + + // There are two warnings per "callsite" in this case because the generated IL does + // ldtoken method (getter) + // ldtoken owningtype + // In order to call the right Expression APIs. + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)] + static void TwoMismatchesInOneStatement< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + () + { + Expression> a = () => IWithTwo.Property; + } + + public static void Test () + { + SpecificType (); + OneMatchingAnnotation (); + MultipleReferencesToTheSameProperty (); + TwoMismatchesInOneStatement (); + } + } + class CreateInstance { static void SpecificType () @@ -871,9 +1164,14 @@ public static void Test () TypeOf.Test (); MethodCallOnGenericMethod.Test (); MethodCallOnGenericType.Test (); + FieldAccessOnGenericType.Test (); LocalVariable.Test (); DelegateUsageOnGenericMethod.Test (); DelegateUsageOnGenericType.Test (); + LdTokenOnGenericMethod.Test (); + LdTokenOfMethodOnGenericType.Test (); + LdTokenOfFieldOnGenericType.Test (); + LdTokenOfPropertyOnGenericType.Test (); CreateInstance.Test (); IsInstance.Test (); AsType.Test (); diff --git a/src/tools/illink/test/Mono.Linker.Tests/Extensions/NiceIO.cs b/src/tools/illink/test/Mono.Linker.Tests/Extensions/NiceIO.cs index ffc24695eb8035..4fde1084de42da 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/Extensions/NiceIO.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/Extensions/NiceIO.cs @@ -47,8 +47,7 @@ public class NPath : IEquatable, IComparable public NPath (string path) { - if (path == null) - throw new ArgumentNullException (nameof (path)); + ArgumentNullException.ThrowIfNull (path); path = ParseDriveLetter (path, out _driveLetter); diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/AssemblyChecker.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/AssemblyChecker.cs index cfe3a7cfe89da2..9fd10eef351d6a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/AssemblyChecker.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/AssemblyChecker.cs @@ -325,7 +325,7 @@ void VerifyOverrides (MethodDefinition original, MethodDefinition linked) Assert.True (linked.DeclaringType.Interfaces.Select (i => i.InterfaceType).Contains (overriddenMethod.DeclaringType), $"Method {linked} overrides method {overriddenMethod}, but {linked.DeclaringType} does not implement interface {overriddenMethod.DeclaringType}"); } else { - TypeReference baseType = linked.DeclaringType; + TypeDefinition baseType = linked.DeclaringType; TypeReference overriddenType = overriddenMethod.DeclaringType; while (baseType is not null) { if (baseType.Equals (overriddenType)) diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs index e41c2b8e74618a..04f56ef3f3d037 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs @@ -106,7 +106,7 @@ protected virtual CompilerOptions CreateOptionsForSupportingAssembly (SetupCompi }; } - private IEnumerable CompileBeforeTestCaseAssemblies (NPath outputDirectory, NPath[] references, string[] defines, IList removeFromLinkerInputAssemblies) + private IEnumerable CompileBeforeTestCaseAssemblies (NPath outputDirectory, NPath[] references, string[] defines, List removeFromLinkerInputAssemblies) { foreach (var setupCompileInfo in _metadataProvider.GetSetupCompileAssembliesBefore ()) { NPath outputFolder; @@ -134,7 +134,7 @@ private IEnumerable CompileBeforeTestCaseAssemblies (NPath outputDirector } } - private void CompileAfterTestCaseAssemblies (NPath outputDirectory, NPath[] references, string[] defines, IList removeFromLinkerInputAssemblies) + private void CompileAfterTestCaseAssemblies (NPath outputDirectory, NPath[] references, string[] defines, List removeFromLinkerInputAssemblies) { foreach (var setupCompileInfo in _metadataProvider.GetSetupCompileAssembliesAfter ()) { var options = CreateOptionsForSupportingAssembly (