[dotnet-linker] Add a StoreAttributesStep to store attributes that are removed by the linker.
Add a StoreAttributesStep to store attributes that are removed by the linker, but that the static registrar needs. In particular, in .NET 6 the linker removes the System.Runtime.CompilerServices.ExtensionAttribute, which the static registrar needs to handle category methods properly. This involved copying and slightly modifying the RemoveAttributesBase code.
This commit is contained in:
Родитель
8f0ca7508a
Коммит
831f55796e
|
@ -80,6 +80,7 @@ namespace Xamarin {
|
|||
prelink_substeps.Add (new MarkNSObjects ());
|
||||
prelink_substeps.Add (new PreserveSmartEnumConversionsSubStep ());
|
||||
prelink_substeps.Add (new CollectUnmarkedMembersSubStep ());
|
||||
prelink_substeps.Add (new StoreAttributesStep ());
|
||||
|
||||
post_sweep_substeps.Add (new RemoveAttributesStep ());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
|
||||
using Mono.Linker;
|
||||
using Mono.Linker.Steps;
|
||||
|
||||
using Mono.Cecil;
|
||||
using Xamarin.Tuner;
|
||||
|
||||
namespace Xamarin.Linker.Steps {
|
||||
|
||||
public abstract class AttributeIteratorBaseStep : BaseSubStep {
|
||||
|
||||
protected DerivedLinkContext LinkContext {
|
||||
get {
|
||||
return LinkerConfiguration.GetInstance (Context).DerivedLinkContext;
|
||||
}
|
||||
}
|
||||
|
||||
public override SubStepTargets Targets {
|
||||
get {
|
||||
return SubStepTargets.Assembly
|
||||
| SubStepTargets.Type
|
||||
| SubStepTargets.Field
|
||||
| SubStepTargets.Method
|
||||
| SubStepTargets.Property
|
||||
| SubStepTargets.Event;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsActiveFor (AssemblyDefinition assembly)
|
||||
{
|
||||
return Annotations.GetAction (assembly) == AssemblyAction.Link;
|
||||
}
|
||||
|
||||
public override void ProcessAssembly (AssemblyDefinition assembly)
|
||||
{
|
||||
ProcessAttributeProvider (assembly);
|
||||
ProcessAttributeProvider (assembly.MainModule);
|
||||
}
|
||||
|
||||
public override void ProcessType (TypeDefinition type)
|
||||
{
|
||||
ProcessAttributeProvider (type);
|
||||
|
||||
if (type.HasGenericParameters)
|
||||
ProcessAttributeProviderCollection (type.GenericParameters);
|
||||
}
|
||||
|
||||
void ProcessAttributeProviderCollection (IList list)
|
||||
{
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
ProcessAttributeProvider ((ICustomAttributeProvider) list [i]);
|
||||
}
|
||||
|
||||
public override void ProcessField (FieldDefinition field)
|
||||
{
|
||||
ProcessAttributeProvider (field);
|
||||
}
|
||||
|
||||
public override void ProcessMethod (MethodDefinition method)
|
||||
{
|
||||
ProcessMethodAttributeProvider (method);
|
||||
}
|
||||
|
||||
void ProcessMethodAttributeProvider (MethodDefinition method)
|
||||
{
|
||||
ProcessAttributeProvider (method);
|
||||
ProcessAttributeProvider (method.MethodReturnType);
|
||||
|
||||
if (method.HasParameters)
|
||||
ProcessAttributeProviderCollection (method.Parameters);
|
||||
|
||||
if (method.HasGenericParameters)
|
||||
ProcessAttributeProviderCollection (method.GenericParameters);
|
||||
}
|
||||
|
||||
public override void ProcessProperty (PropertyDefinition property)
|
||||
{
|
||||
ProcessAttributeProvider (property);
|
||||
}
|
||||
|
||||
public override void ProcessEvent (EventDefinition @event)
|
||||
{
|
||||
ProcessAttributeProvider (@event);
|
||||
}
|
||||
|
||||
void ProcessAttributeProvider (ICustomAttributeProvider provider)
|
||||
{
|
||||
if (!provider.HasCustomAttributes)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < provider.CustomAttributes.Count; i++) {
|
||||
var attrib = provider.CustomAttributes [i];
|
||||
ProcessAttribute (provider, attrib, out var remove);
|
||||
|
||||
if (remove)
|
||||
provider.CustomAttributes.RemoveAt (i--);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void ProcessAttribute (ICustomAttributeProvider provider, CustomAttribute attribute, out bool remove);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
using System;
|
||||
|
||||
using Mono.Cecil;
|
||||
using Mono.Tuner;
|
||||
using Xamarin.Tuner;
|
||||
|
||||
namespace Xamarin.Linker.Steps {
|
||||
// The .NET linker comes with a way to remove attributes (by passing '--link-attributes
|
||||
|
@ -22,14 +20,16 @@ namespace Xamarin.Linker.Steps {
|
|||
//
|
||||
// The end result is that a custom step is the best solution for now.
|
||||
|
||||
public class RemoveAttributesStep : RemoveAttributesBase {
|
||||
protected DerivedLinkContext LinkContext {
|
||||
get {
|
||||
return LinkerConfiguration.GetInstance (Context).DerivedLinkContext;
|
||||
}
|
||||
public class RemoveAttributesStep : AttributeIteratorBaseStep {
|
||||
protected override void ProcessAttribute (ICustomAttributeProvider provider, CustomAttribute attribute, out bool remove)
|
||||
{
|
||||
remove = IsRemovedAttribute (attribute);
|
||||
|
||||
if (remove)
|
||||
LinkContext.StoreCustomAttribute (provider, attribute);
|
||||
}
|
||||
|
||||
protected override bool IsRemovedAttribute (CustomAttribute attribute)
|
||||
bool IsRemovedAttribute (CustomAttribute attribute)
|
||||
{
|
||||
// this avoids calling FullName (which allocates a string)
|
||||
var attr_type = attribute.Constructor.DeclaringType;
|
||||
|
@ -51,11 +51,5 @@ namespace Xamarin.Linker.Steps {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void WillRemoveAttribute (ICustomAttributeProvider provider, CustomAttribute attribute)
|
||||
{
|
||||
LinkContext.StoreCustomAttribute (provider, attribute);
|
||||
base.WillRemoveAttribute (provider, attribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace Xamarin.Linker.Steps {
|
||||
// The registrar needs some of the system attributes that the linker might remove, so store those elsewhere for the static registrar's use.
|
||||
public class StoreAttributesStep : AttributeIteratorBaseStep {
|
||||
protected override void ProcessAttribute (ICustomAttributeProvider provider, CustomAttribute attribute, out bool remove)
|
||||
{
|
||||
// don't remove any of these
|
||||
remove = false;
|
||||
|
||||
// this avoids calling FullName (which allocates a string)
|
||||
var attr_type = attribute.Constructor.DeclaringType;
|
||||
var store = false;
|
||||
switch (attr_type.Namespace) {
|
||||
case "System.Runtime.CompilerServices":
|
||||
switch (attr_type.Name) {
|
||||
case "ExtensionAttribute":
|
||||
store = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (store)
|
||||
LinkContext.StoreCustomAttribute (provider, attribute);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -176,9 +176,6 @@
|
|||
<Compile Include="..\..\builds\mono-ios-sdk-destdir\ios-sources\external\linker\src\tuner\Mono.Tuner\CecilRocks.cs">
|
||||
<Link>external\mono-archive\Mono.Tuner\CecilRocks.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\builds\mono-ios-sdk-destdir\ios-sources\external\linker\src\tuner\Mono.Tuner\RemoveAttributesBase.cs">
|
||||
<Link>external\mono-archive\Mono.Tuner\RemoveAttributesBase.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\external\Xamarin.MacDev\Xamarin.MacDev\PListObject.cs">
|
||||
<Link>external\Xamarin.MacDev\Xamarin.MacDev\PListObject.cs</Link>
|
||||
</Compile>
|
||||
|
|
Загрузка…
Ссылка в новой задаче