Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/linker.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTlakaelel Axayakatl Ceja <tlakaelel.ceja@microsoft.com>2021-12-15 22:26:39 +0300
committerGitHub <noreply@github.com>2021-12-15 22:26:39 +0300
commit426918d44f6bb3b14cb545cbe2ed20d86a031661 (patch)
treeaa40d41d55c3d256130b19dad16b970f792f4f18
parent779dacee7c24795017190df9ea017b93813028e2 (diff)
Add TargetHasRequiresAttribute to RequiresISymbolExtensions file (#2445)
* Add TargetHasRequiresAttribute to RequiresISymbolExtensions file * Add a RequiresUnreferencedCodeUtils file so other analyzers dont have to pass the RUC name everytime they use the RequiresISymbolExtensions * Refactor the RequiresAnalyzerBase to not have to verify the arguments while getting the attribute since the specific details on how to validate the attribute arguments are specific of the attribute implementation * Change COMAnalyzer to use the RequiresUnreferencedCodeUtils instead of the RequiresISymbolExtensions
-rw-r--r--src/ILLink.RoslynAnalyzer/COMAnalyzer.cs3
-rw-r--r--src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs27
-rw-r--r--src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs38
-rw-r--r--src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs2
-rw-r--r--src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeUtils.cs35
5 files changed, 79 insertions, 26 deletions
diff --git a/src/ILLink.RoslynAnalyzer/COMAnalyzer.cs b/src/ILLink.RoslynAnalyzer/COMAnalyzer.cs
index 6f153aa76..ea6f2f3f8 100644
--- a/src/ILLink.RoslynAnalyzer/COMAnalyzer.cs
+++ b/src/ILLink.RoslynAnalyzer/COMAnalyzer.cs
@@ -18,7 +18,6 @@ namespace ILLink.RoslynAnalyzer
private const string StructLayoutAttribute = nameof (StructLayoutAttribute);
private const string DllImportAttribute = nameof (DllImportAttribute);
private const string MarshalAsAttribute = nameof (MarshalAsAttribute);
- private const string RequiresUnreferencedCodeAttribute = nameof (RequiresUnreferencedCodeAttribute);
static readonly DiagnosticDescriptor s_correctnessOfCOMCannotBeGuaranteed = DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.CorrectnessOfCOMCannotBeGuaranteed,
helpLinkUri: "https://docs.microsoft.com/en-us/dotnet/core/deploying/trim-warnings/il2050");
@@ -40,7 +39,7 @@ namespace ILLink.RoslynAnalyzer
if (!targetMethod.HasAttribute (DllImportAttribute))
return;
- if (operationContext.ContainingSymbol.IsInRequiresScope (RequiresUnreferencedCodeAttribute))
+ if (operationContext.ContainingSymbol.IsInRequiresUnreferencedCodeAttributeScope ())
return;
bool comDangerousMethod = IsComInterop (targetMethod.ReturnType);
diff --git a/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs b/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs
index b9032ee22..ed825cd20 100644
--- a/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs
+++ b/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs
@@ -230,7 +230,10 @@ namespace ILLink.RoslynAnalyzer
while (member is IMethodSymbol method && method.OverriddenMethod != null && SymbolEqualityComparer.Default.Equals (method.ReturnType, method.OverriddenMethod.ReturnType))
member = method.OverriddenMethod;
- if (!TargetHasRequiresAttribute (member, out var requiresAttribute))
+ if (!member.TargetHasRequiresAttribute (RequiresAttributeName, out var requiresAttribute))
+ return;
+
+ if (!VerifyAttributeArguments (requiresAttribute))
return;
ReportRequiresDiagnostic (operationContext, member, requiresAttribute);
@@ -342,28 +345,6 @@ namespace ILLink.RoslynAnalyzer
return member1HasAttribute ^ member2HasAttribute;
}
- // TODO: Consider sharing with linker DoesMethodRequireUnreferencedCode method
- /// <summary>
- /// True if the target of a call is considered to be annotated with the Requires... attribute
- /// </summary>
- protected bool TargetHasRequiresAttribute (ISymbol member, [NotNullWhen (returnValue: true)] out AttributeData? requiresAttribute)
- {
- requiresAttribute = null;
- if (member.IsStaticConstructor ()) {
- return false;
- }
-
- if (TryGetRequiresAttribute (member, out requiresAttribute)) {
- return true;
- }
-
- // Also check the containing type
- if (member.IsStatic || member.IsConstructor ()) {
- return TryGetRequiresAttribute (member.ContainingType, out requiresAttribute);
- }
- return false;
- }
-
protected abstract string GetMessageFromAttribute (AttributeData requiresAttribute);
public static string GetUrlFromAttribute (AttributeData? requiresAttribute)
diff --git a/src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs b/src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs
index 24f8a0623..f4593a1a9 100644
--- a/src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs
+++ b/src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs
@@ -1,12 +1,33 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis;
namespace ILLink.RoslynAnalyzer
{
public static class RequiresISymbolExtensions
{
+ // TODO: Consider sharing with linker DoesMethodRequireUnreferencedCode method
+ /// <summary>
+ /// True if the target of a call is considered to be annotated with the Requires... attribute
+ /// </summary>
+ public static bool TargetHasRequiresAttribute (this ISymbol member, string requiresAttribute, [NotNullWhen (returnValue: true)] out AttributeData? requiresAttributeData)
+ {
+ requiresAttributeData = null;
+ if (member.IsStaticConstructor ())
+ return false;
+
+ if (TryGetRequiresAttribute (member, requiresAttribute, out requiresAttributeData))
+ return true;
+
+ // Also check the containing type
+ if (member.IsStatic || member.IsConstructor ())
+ return TryGetRequiresAttribute (member.ContainingType, requiresAttribute, out requiresAttributeData);
+
+ return false;
+ }
+
// TODO: Consider sharing with linker IsMethodInRequiresUnreferencedCodeScope method
/// <summary>
/// True if the source of a call is considered to be annotated with the Requires... attribute
@@ -43,5 +64,22 @@ namespace ILLink.RoslynAnalyzer
return false;
}
+
+ /// <summary>
+ /// This method determines if the member has a Requires attribute and returns it in the variable requiresAttribute.
+ /// </summary>
+ /// <param name="member">Symbol of the member to search attribute.</param>
+ /// <param name="requiresAttribute">Output variable in case of matching Requires attribute.</param>
+ /// <returns>True if the member contains a Requires attribute; otherwise, returns false.</returns>
+ private static bool TryGetRequiresAttribute (ISymbol member, string requiresAttribute, [NotNullWhen (returnValue: true)] out AttributeData? requiresAttributeData)
+ {
+ requiresAttributeData = null;
+
+ if (!member.TryGetAttribute (requiresAttribute, out var attribute))
+ return false;
+
+ requiresAttributeData = attribute;
+ return true;
+ }
}
}
diff --git a/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs b/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs
index 7e4f7e5a2..c1469c9a5 100644
--- a/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs
+++ b/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs
@@ -81,7 +81,7 @@ namespace ILLink.RoslynAnalyzer
ImmutableArray.Create ((s_dynamicTypeInvocation, new OperationKind[] { OperationKind.DynamicInvocation }));
protected override bool VerifyAttributeArguments (AttributeData attribute) =>
- attribute.ConstructorArguments.Length >= 1 && attribute.ConstructorArguments[0] is { Type: { SpecialType: SpecialType.System_String } } ctorArg;
+ RequiresUnreferencedCodeUtils.VerifyRequiresUnreferencedCodeAttributeArguments (attribute);
protected override string GetMessageFromAttribute (AttributeData? requiresAttribute)
{
diff --git a/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeUtils.cs b/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeUtils.cs
new file mode 100644
index 000000000..4e21419e4
--- /dev/null
+++ b/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeUtils.cs
@@ -0,0 +1,35 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics.CodeAnalysis;
+using Microsoft.CodeAnalysis;
+
+namespace ILLink.RoslynAnalyzer
+{
+ public static class RequiresUnreferencedCodeUtils
+ {
+ private const string RequiresUnreferencedCodeAttribute = nameof (RequiresUnreferencedCodeAttribute);
+
+ // TODO: Consider sharing with linker DoesMethodRequireUnreferencedCode method
+ /// <summary>
+ /// True if the target of a call is considered to be annotated with the RequiresUnreferencedCode attribute
+ /// </summary>
+ public static bool TargetHasRequiresUnreferencedCodeAttribute (this ISymbol member, [NotNullWhen (returnValue: true)] out AttributeData? requiresAttributeData)
+ => member.TargetHasRequiresAttribute (RequiresUnreferencedCodeAttribute, out requiresAttributeData);
+
+ // TODO: Consider sharing with linker IsMethodInRequiresUnreferencedCodeScope method
+ /// <summary>
+ /// True if the source of a call is considered to be annotated with the RequiresUnreferencedCode attribute
+ /// </summary>
+ public static bool IsInRequiresUnreferencedCodeAttributeScope (this ISymbol member)
+ => member.IsInRequiresScope (RequiresUnreferencedCodeAttribute);
+
+ /// <summary>
+ /// This method verifies that the arguments in an attribute have certain structure.
+ /// </summary>
+ /// <param name="attribute">Attribute data to compare.</param>
+ /// <returns>True if the validation was successfull; otherwise, returns false.</returns>
+ public static bool VerifyRequiresUnreferencedCodeAttributeArguments (AttributeData attribute)
+ => attribute.ConstructorArguments.Length >= 1 && attribute.ConstructorArguments[0] is { Type: { SpecialType: SpecialType.System_String } } ctorArg;
+ }
+}