Skip to content

Commit

Permalink
[One .NET] fix remaining Mono.Android.Export linker warning
Browse files Browse the repository at this point in the history
Context: dotnet#5652

If you build an app with:

    > dotnet build -c Release -p:SuppressTrimAnalysisWarnings=false

You get the linker warning:

    src\Mono.Android\Android.Runtime\AndroidRuntime.cs(296,5): warning IL2026: Android.Runtime.AndroidTypeManager.CreateDynamicCallback(MethodInfo): Using method 'System.Reflection.Assembly.GetType(String)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types might be removed.

We can simply suppress the warning:

    [UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "DynamicDependency should preserve the Create() method.")]

If we applied this, every app would preserve
`Mono.Android.Export.dll`, so we should not do this:

    [DynamicDependency ("Create", "Java.Interop.DynamicCallbackCodeGenerator", "Mono.Android.Export")]

This is already preserved because we have a `DynamicDependency` in
`ExportAttribute.cs`:

    [DynamicDependency (DynamicallyAccessedMemberTypes.All, "Java.Interop.DynamicCallbackCodeGenerator", "Mono.Android.Export")]

I also had to bring in the source for `UnconditionalSuppressMessage`
for `monoandroid10` or `netstandard2.0` assemblies. I also changed an
MSBuild `Condition`, so it will continue to work in .NET 7.
  • Loading branch information
jonathanpeppers committed Aug 27, 2021
1 parent 8460867 commit a957180
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/Mono.Android/Android.Runtime/AndroidRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
Expand Down Expand Up @@ -285,6 +286,8 @@ protected override IEnumerable<string> GetSimpleReferences (Type type)

static MethodInfo? dynamic_callback_gen;

// See ExportAttribute.cs
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "Mono.Android.Export.dll is preserved when [Export] is used via [DynamicDependency].")]
static Delegate CreateDynamicCallback (MethodInfo method)
{
if (dynamic_callback_gen == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable enable

namespace System.Diagnostics.CodeAnalysis
{
/// <summary>
/// Suppresses reporting of a specific rule violation, allowing multiple suppressions on a
/// single code artifact.
/// </summary>
/// <remarks>
/// <see cref="UnconditionalSuppressMessageAttribute"/> is different than
/// <see cref="SuppressMessageAttribute"/> in that it doesn't have a
/// <see cref="ConditionalAttribute"/>. So it is always preserved in the compiled assembly.
/// </remarks>
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
#if SYSTEM_PRIVATE_CORELIB
public
#else
internal
#endif
sealed class UnconditionalSuppressMessageAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="UnconditionalSuppressMessageAttribute"/>
/// class, specifying the category of the tool and the identifier for an analysis rule.
/// </summary>
/// <param name="category">The category for the attribute.</param>
/// <param name="checkId">The identifier of the analysis rule the attribute applies to.</param>
public UnconditionalSuppressMessageAttribute(string category, string checkId)
{
Category = category;
CheckId = checkId;
}

/// <summary>
/// Gets the category identifying the classification of the attribute.
/// </summary>
/// <remarks>
/// The <see cref="Category"/> property describes the tool or tool analysis category
/// for which a message suppression attribute applies.
/// </remarks>
public string Category { get; }

/// <summary>
/// Gets the identifier of the analysis tool rule to be suppressed.
/// </summary>
/// <remarks>
/// Concatenated together, the <see cref="Category"/> and <see cref="CheckId"/>
/// properties form a unique check identifier.
/// </remarks>
public string CheckId { get; }

/// <summary>
/// Gets or sets the scope of the code that is relevant for the attribute.
/// </summary>
/// <remarks>
/// The Scope property is an optional argument that specifies the metadata scope for which
/// the attribute is relevant.
/// </remarks>
public string? Scope { get; set; }

/// <summary>
/// Gets or sets a fully qualified path that represents the target of the attribute.
/// </summary>
/// <remarks>
/// The <see cref="Target"/> property is an optional argument identifying the analysis target
/// of the attribute. An example value is "System.IO.Stream.ctor():System.Void".
/// Because it is fully qualified, it can be long, particularly for targets such as parameters.
/// The analysis tool user interface should be capable of automatically formatting the parameter.
/// </remarks>
public string? Target { get; set; }

/// <summary>
/// Gets or sets an optional argument expanding on exclusion criteria.
/// </summary>
/// <remarks>
/// The <see cref="MessageId "/> property is an optional argument that specifies additional
/// exclusion where the literal metadata target is not sufficiently precise. For example,
/// the <see cref="UnconditionalSuppressMessageAttribute"/> cannot be applied within a method,
/// and it may be desirable to suppress a violation against a statement in the method that will
/// give a rule violation, but not against all statements in the method.
/// </remarks>
public string? MessageId { get; set; }

/// <summary>
/// Gets or sets the justification for suppressing the code analysis message.
/// </summary>
public string? Justification { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
<Compile Include="$(MSBuildThisFileDirectory)Android.App\LayoutAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Java.Interop\IJniNameProviderAttribute.cs" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' != 'net6.0' ">
<ItemGroup Condition=" '$(TargetFramework)' == 'monoandroid10' or '$(TargetFramework)' == 'netstandard2.0' ">
<Compile Include="$(MSBuildThisFileDirectory)System.Diagnostics.CodeAnalysis/DynamicallyAccessedMemberTypes.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System.Diagnostics.CodeAnalysis/DynamicDependencyAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System.Runtime.CompilerServices/UnconditionalSuppressMessageAttribute.cs" />
</ItemGroup>
</Project>

0 comments on commit a957180

Please sign in to comment.