Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more tests that have been enabled by recent changes #73175

Merged
merged 1 commit into from
Aug 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;

namespace Mono.Linker.Tests.Cases.RequiresCapability.Dependencies
{
public class RequiresInCopyAssembly
{
public RequiresInCopyAssembly ()
{
}

[RequiresUnreferencedCode ("Message for --Method--")]
[RequiresAssemblyFiles ("Message for --Method--")]
[RequiresDynamicCode ("Message for --Method--")]
public void Method ()
{
}

[RequiresUnreferencedCode ("Message for --UncalledMethod--")]
[RequiresAssemblyFiles ("Message for --UncalledMethod--")]
[RequiresDynamicCode ("Message for --UncalledMethod--")]
public void UncalledMethod ()
{
}

[RequiresUnreferencedCode ("Message for --MethodCalledThroughReflection--")]
[RequiresAssemblyFiles ("Message for --MethodCalledThroughReflection--")]
[RequiresDynamicCode ("Message for --MethodCalledThroughReflection--")]
static void MethodCalledThroughReflection ()
{
}

public int UnusedProperty {
[RequiresUnreferencedCode ("Message for --getter UnusedProperty--")]
[RequiresAssemblyFiles ("Message for --getter UnusedProperty--")]
[RequiresDynamicCode ("Message for --getter UnusedProperty--")]
get { return 42; }

[RequiresUnreferencedCode ("Message for --setter UnusedProperty--")]
[RequiresAssemblyFiles ("Message for --setter UnusedProperty--")]
[RequiresDynamicCode ("Message for --setter UnusedProperty--")]
set { }
}

class UnusedBaseType
{
[RequiresUnreferencedCode ("Message for --UnusedBaseTypeCctor--")]
[RequiresAssemblyFiles ("Message for --UnusedBaseTypeCctor--")]
[RequiresDynamicCode ("Message for --UnusedBaseTypeCctor--")]
static UnusedBaseType ()
{
}

[RequiresUnreferencedCode ("Message for --UnusedVirtualMethod1--")]
[RequiresAssemblyFiles ("Message for --UnusedVirtualMethod1--")]
[RequiresDynamicCode ("Message for --UnusedVirtualMethod1--")]
public virtual void UnusedVirtualMethod1 ()
{
}

[RequiresUnreferencedCode ("Message for --UnusedVirtualMethod2--")]
[RequiresAssemblyFiles ("Message for --UnusedVirtualMethod2--")]
[RequiresDynamicCode ("Message for --UnusedVirtualMethod2--")]
public virtual void UnusedVirtualMethod2 ()
{
}
}

class UnusedDerivedType : UnusedBaseType
{
[RequiresUnreferencedCode ("Message for --UnusedVirtualMethod1--")]
[RequiresAssemblyFiles ("Message for --UnusedVirtualMethod1--")]
[RequiresDynamicCode ("Message for --UnusedVirtualMethod1--")]
public override void UnusedVirtualMethod1 ()
{
}

// Should not warn when this is part of a copied assembly.
public override void UnusedVirtualMethod2 ()
{
}
}

interface IUnusedInterface
{
[RequiresUnreferencedCode ("Message for --IUnusedInterface.UnusedMethod--")]
[RequiresAssemblyFiles ("Message for --IUnusedInterface.UnusedMethod--")]
[RequiresDynamicCode ("Message for --IUnusedInterface.UnusedMethod--")]
public void UnusedMethod ();
}

class UnusedImplementationClass : IUnusedInterface
{
[RequiresUnreferencedCode ("Message for --UnusedImplementationClass.UnusedMethod--")]
[RequiresAssemblyFiles ("Message for --UnusedImplementationClass.UnusedMethod--")]
[RequiresDynamicCode ("Message for --UnusedImplementationClass.UnusedMethod--")]
public void UnusedMethod ()
{
}
}

public interface IBaseInterface
{
[RequiresUnreferencedCode ("Message for --IBaseInterface.MethodInBaseInterface--")]
[RequiresAssemblyFiles ("Message for --IBaseInterface.MethodInBaseInterface--")]
[RequiresDynamicCode ("Message for --IBaseInterface.MethodInBaseInterface--")]
void MethodInBaseInterface ();
}

public interface IDerivedInterface : IBaseInterface
{
[RequiresUnreferencedCode ("Message for --IDerivedInterface.MethodInDerivedInterface--")]
[RequiresAssemblyFiles ("Message for --IDerivedInterface.MethodInDerivedInterface--")]
[RequiresDynamicCode ("Message for --IDerivedInterface.MethodInDerivedInterface--")]
void MethodInDerivedInterface ();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
using Mono.Linker.Tests.Cases.RequiresCapability.Dependencies;

namespace Mono.Linker.Tests.Cases.RequiresCapability
{
[SetupLinkerAction ("copy", "lib")]
[SetupCompileBefore ("lib.dll", new[] { "Dependencies/RequiresInCopyAssembly.cs" })]
[KeptAllTypesAndMembersInAssembly ("lib.dll")]
[LogDoesNotContain ("IL2026")]
[LogDoesNotContain ("IL3002")]
[LogDoesNotContain ("IL2027")]
public class RequiresCapabilityFromCopiedAssembly
{
public static void Main ()
{
Test ();
}

[Kept]
static void Test ()
{
var x = new RequiresInCopyAssembly ();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
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.RequiresCapability
{
[ExpectedNoWarnings]
public class RequiresCapabilityReflectionAnalysisEnabled
{
[LogContains ("-- DynamicallyAccessedMembersEnabled --")]
[LogContains ("-- ReflectionPattern --")]
[LogContains ("-- DynamicallyAccessedMembersOnGenericsEnabled --")]
public static void Main ()
{
TestRequiresAttributeWithDynamicallyAccessedMembersEnabled ();
TestRequiresAttributeWithReflectionPattern ();
TestRequiresAttributeWithDynamicallyAccessedMembersOnGenericsEnabled ();
TestRequiresAndDynamicallyAccessedMembers.Test ();
}

[Kept]
[KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
[RequiresUnreferencedCode ("-- DynamicallyAccessedMembersEnabled --")]
static void TestRequiresAttributeWithDynamicallyAccessedMembersEnabled ()
{
typeof (TypeWithPublicFieldsAccessed).RequiresPublicFields ();
}

[Kept]
class TypeWithPublicFieldsAccessed
{
[Kept]
public int _publicField;

private int _privateField;
}

[Kept]
[KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
[RequiresUnreferencedCode ("-- ReflectionPattern --")]
static void TestRequiresAttributeWithReflectionPattern ()
{
typeof (TypeWithMethodAccessed).GetMethod ("PublicMethod");
}

[Kept]
class TypeWithMethodAccessed
{
[Kept]
public void PublicMethod () { }

public void PublicMethod2 () { }
}

[Kept]
[KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
[RequiresUnreferencedCode ("-- DynamicallyAccessedMembersOnGenericsEnabled --")]
static void TestRequiresAttributeWithDynamicallyAccessedMembersOnGenericsEnabled ()
{
TypeRequiresPublicFields<TypeWithPublicFieldsForGenericType>.Method ();
MethodRequiresPublicFields<TypeWithPublicFieldsForGenericMethod> ();
}

[Kept]
class TypeRequiresPublicFields<
[KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)]
T>
{
[Kept]
public static void Method () { }
}

[Kept]
class TypeWithPublicFieldsForGenericType
{
[Kept]
public int _publicField;

private int _privateField;
}

[Kept]
static void MethodRequiresPublicFields<
[KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)]
T> ()
{
}

[Kept]
class TypeWithPublicFieldsForGenericMethod
{
[Kept]
public int _publicField;

private int _privateField;
}

[Kept]
class TestRequiresAndDynamicallyAccessedMembers
{
[Kept]
[KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))]
[RequiresUnreferencedCode ("--- RequiresAndPublicMethods ---")]
static void RequiresAndPublicMethods (
[KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
Type type)
{
// This should not produce a warning since the method is annotated with Requires
type.RequiresPublicFields ();

// This will still "work" in that it will apply the PublicFields requirement onto the specified type
typeof (TestRequiresAndDynamicallyAccessedMembers).RequiresPublicFields ();
}

[Kept]
public void PublicInstanceMethod () { }

[Kept]
public static void PublicStaticMethod () { }

static void PrivateInstanceMethod () { }

[Kept]
public static int PublicStaticField;

static int PrivateStaticField;

[Kept]
[ExpectedWarning ("IL2026", "--- RequiresAndPublicMethods ---")]
public static void Test ()
{
RequiresAndPublicMethods (typeof (TestRequiresAndDynamicallyAccessedMembers));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Mono.Linker.Tests.Cases.Expectations.Assertions;

namespace Mono.Linker.Tests.Cases.RequiresCapability
{
[SkipKeptItemsValidation]
[ExpectedNoWarnings]
class RequiresViaDataflow
{
// Base/Derived and Implementation/Interface differs between linker and analyzer https://github.com/dotnet/linker/issues/2533
[ExpectedWarning ("IL2026", "--DynamicallyAccessedTypeWithRequires.MethodWithRequires--")]
[ExpectedWarning ("IL2026", "TypeWhichOverridesMethod.VirtualMethodRequires()", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a bug tracking the NativeAOT side of this? Or this really a linker-only bug (probably due to override resolution being broken in Cecil) - probably worth a comment either way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue is marked in the comment. It doesn't have to do with Cecil, by choice we decide to print the warnings in a particular way. Basically for linker no matter if we use the base or derived/interface or implementation, we always print a warning in the base/interface because IL only points to base/interface. Analyzer implementation got more complicated because it does point to the derived/implementation and interface resolution based on implementation was expensive. NativeAOT just happens to use the same approach as the analyzer.

[ExpectedWarning ("IL2026", "BaseType.VirtualMethodRequires()", "--BaseType.VirtualMethodRequires--")]
public static void Main ()
{
TestDynamicallyAccessedMembersWithRequires (typeof (DynamicallyAccessedTypeWithRequires));
TestDynamicallyAccessedMembersWithRequires (typeof (TypeWhichOverridesMethod));
TestRequiresInDynamicDependency ();
}

class BaseType
{
[RequiresUnreferencedCode ("Message for --BaseType.VirtualMethodRequires--")]
[RequiresAssemblyFiles ("Message for --BaseType.VirtualMethodRequires--")]
[RequiresDynamicCode ("Message for --BaseType.VirtualMethodRequires--")]
public virtual void VirtualMethodRequires ()
{
}
}

class TypeWhichOverridesMethod : BaseType
{
[RequiresUnreferencedCode ("Message for --TypeWhichOverridesMethod.VirtualMethodRequires--")]
[RequiresAssemblyFiles ("Message for --TypeWhichOverridesMethod.VirtualMethodRequires--")]
[RequiresDynamicCode ("Message for --TypeWhichOverridesMethod.VirtualMethodRequires--")]
public override void VirtualMethodRequires ()
{
}
}

public class DynamicallyAccessedTypeWithRequires
{
[RequiresUnreferencedCode ("Message for --DynamicallyAccessedTypeWithRequires.MethodWithRequires--")]
public void MethodWithRequires ()
{
}
}

static void TestDynamicallyAccessedMembersWithRequires (
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type)
{
}

[RequiresUnreferencedCode ("Message for --RequiresInDynamicDependency--")]
[RequiresAssemblyFiles ("Message for --RequiresInDynamicDependency--")]
[RequiresDynamicCode ("Message for --RequiresInDynamicDependency--")]
static void RequiresInDynamicDependency ()
{
}

[ExpectedWarning ("IL2026", "--RequiresInDynamicDependency--")]
[ExpectedWarning ("IL2026", "--RequiresInDynamicDependency--", ProducedBy = ProducedBy.Trimmer)]
[ExpectedWarning ("IL3002", "--RequiresInDynamicDependency--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
[ExpectedWarning ("IL3050", "--RequiresInDynamicDependency--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
[DynamicDependency ("RequiresInDynamicDependency")]
static void TestRequiresInDynamicDependency ()
{
RequiresInDynamicDependency ();
}
}
}
Loading