-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add star into link attributes (#81407)
One of the functionalities of the LinkAttributes files is to occurrences of custom attributes on the current assembly, on top of this functionality there is a special functionality that is only permitted if it's embedded in an XML inside the System.Private.CorLib module that allows the deletion of custom attributes from all the assemblies. Given that NativeAOT is multithreaded it cannot process all the assemblies to remove attributes as ILLink does, it also does not have a shared storage in which it can store the information about the removed attributes from System.Private.CoreLib. This PR adds logic to process the special functionality in the embedded System.Private.CoreLib XML every time an assembly is being processed. In order to make this more performant, an extra argument is passed to the XML reader to only look at the assembly="*" to get the set of attributes that need to be deleted from all assemblies. * Handle the star argument in LinkAttributes files for NativeAOT * Minor fixes to print more warnings * Add a way to only process star/nonstar assemblies in ProcessLinkerXmlBase * Add smoke test
- Loading branch information
Showing
6 changed files
with
209 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
src/tests/nativeaot/SmokeTests/TrimmingBehaviors/ILLink.LinkAttributes.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<linker> | ||
<!-- IL2049 --> | ||
<type fullname="ILLinkLinkAttributes/TestRemoveAttribute"> | ||
<attribute internal="RemoveAttributeInstances"/> | ||
<attribute internal="InvalidInternal"/> | ||
</type> | ||
<!-- IL2048 --> | ||
<type fullname="ILLinkLinkAttributes"> | ||
<method signature="_fieldWithCustomAttribute"> | ||
<attribute internal="RemoveAttributeInstances"/> | ||
</method> | ||
</type> | ||
<type fullname="ILLinkLinkAttributes/TestMarkAllRemoveAttribute"> | ||
<attribute internal="RemoveAttributeInstances"/> | ||
</type> | ||
</linker> |
98 changes: 98 additions & 0 deletions
98
src/tests/nativeaot/SmokeTests/TrimmingBehaviors/ILLinkLinkAttributes.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System; | ||
using System.Diagnostics.CodeAnalysis; | ||
|
||
using BindingFlags = System.Reflection.BindingFlags; | ||
|
||
class ILLinkLinkAttributes | ||
{ | ||
public static int Run() | ||
{ | ||
ThrowIfTypeNotPresent(typeof(ILLinkLinkAttributes), nameof(TestDontRemoveAttribute)); | ||
ThrowIfTypePresent(typeof(ILLinkLinkAttributes), nameof(TestRemoveAttribute)); | ||
ThrowIfTypePresent(typeof(ILLinkLinkAttributes), nameof(TestMarkAllRemoveAttribute)); | ||
ThrowIfAttributePresent(typeof(ILLinkLinkAttributes), nameof(_fieldWithCustomAttribute), nameof(TestRemoveAttribute)); | ||
ThrowIfAttributeNotPresent(typeof(ILLinkLinkAttributes), nameof(_fieldWithCustomAttribute), nameof(TestDontRemoveAttribute)); | ||
ThrowIfAttributePresent(typeof(ILLinkLinkAttributes), nameof(_fieldWithCustomAttribute), nameof(AllowNullAttribute)); | ||
return 100; | ||
} | ||
|
||
[TestDontRemoveAttribute] | ||
[TestRemoveAttribute] | ||
[AllowNullAttribute] | ||
private string _fieldWithCustomAttribute = "Hello world"; | ||
|
||
class TestDontRemoveAttribute : Attribute | ||
{ | ||
public TestDontRemoveAttribute() | ||
{ | ||
} | ||
} | ||
|
||
class TestRemoveAttribute : Attribute | ||
{ | ||
public TestRemoveAttribute() | ||
{ | ||
} | ||
} | ||
|
||
class TestMarkAllRemoveAttribute : Attribute | ||
{ | ||
} | ||
|
||
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern", | ||
Justification = "That's the point")] | ||
private static bool IsTypePresent(Type testType, string typeName) => testType.GetNestedType(typeName, BindingFlags.NonPublic | BindingFlags.Public) != null; | ||
|
||
private static void ThrowIfTypeNotPresent(Type testType, string typeName) | ||
{ | ||
if (!IsTypePresent(testType, typeName)) | ||
{ | ||
throw new Exception(typeName); | ||
} | ||
} | ||
|
||
private static void ThrowIfTypePresent(Type testType, string typeName) | ||
{ | ||
if (IsTypePresent(testType, typeName)) | ||
{ | ||
throw new Exception(typeName); | ||
} | ||
} | ||
|
||
private static bool IsAttributePresent(Type testType, string memberName, string attributeName) | ||
{ | ||
foreach (var member in testType.GetMembers()) | ||
{ | ||
if (member.Name == memberName) | ||
{ | ||
foreach (var attribute in member.GetCustomAttributes(false)) | ||
{ | ||
if (attribute.GetType().Name == attributeName) | ||
{ | ||
return true; | ||
} | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
private static void ThrowIfAttributeNotPresent(Type testType, string memberName, string attributeName) | ||
{ | ||
if (!IsAttributePresent(testType, memberName, attributeName)) | ||
{ | ||
throw new Exception(attributeName); | ||
} | ||
} | ||
|
||
private static void ThrowIfAttributePresent(Type testType, string memberName, string attributeName) | ||
{ | ||
if (IsAttributePresent(testType, memberName, attributeName)) | ||
{ | ||
throw new Exception(attributeName); | ||
} | ||
} | ||
} |
Oops, something went wrong.