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:
authorSven Boemer <sbomer@gmail.com>2021-11-30 22:09:28 +0300
committerGitHub <noreply@github.com>2021-11-30 22:09:28 +0300
commitd8170a8f95a52267f0fc87d76eb97e724f13b3f7 (patch)
tree2c53bfed4a284c630b0806b51b00fb672bf3eb39
parent888fed7b56fbef827be1cdedb018153643613459 (diff)
[DAM analyzer] Add support for properties and enable more tests (#2390)
The IOperation tree represents properties as IPropertyReferenceOperation, so we need to handle properties specially (whereas the linker sees calls to the getter/setter directly).
-rw-r--r--src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs53
-rw-r--r--src/ILLink.RoslynAnalyzer/ISymbolExtensions.cs4
-rw-r--r--src/ILLink.RoslynAnalyzer/TrimAnalysis/SymbolValue.cs40
-rw-r--r--src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs37
-rw-r--r--test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs28
-rw-r--r--test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs24
-rw-r--r--test/ILLink.RoslynAnalyzer.Tests/TestChecker.cs7
-rw-r--r--test/Mono.Linker.Tests.Cases/DataFlow/ApplyTypeAnnotations.cs6
-rw-r--r--test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs8
-rw-r--r--test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs15
-rw-r--r--test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs46
-rw-r--r--test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs34
-rw-r--r--test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs120
-rw-r--r--test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresCapability.cs2
14 files changed, 328 insertions, 96 deletions
diff --git a/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs b/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs
index 959884fba..2769ff588 100644
--- a/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs
+++ b/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
+using System.Diagnostics;
using ILLink.RoslynAnalyzer.TrimAnalysis;
using ILLink.Shared.DataFlow;
using Microsoft.CodeAnalysis;
@@ -76,11 +77,15 @@ namespace ILLink.RoslynAnalyzer.DataFlow
public abstract void HandleAssignment (TValue source, TValue target, IOperation operation);
// This is called to handle instance method invocations, where "receiver" is the
- // analyzed value for the object on which the instance method is called.
- public abstract void HandleReceiverArgument (TValue receiver, IInvocationOperation operation);
+ // analyzed value for the object on which the instance method is called, and similarly
+ // for property references.
+ public abstract void HandleReceiverArgument (TValue receiver, IMethodSymbol targetMethod, IOperation operation);
public abstract void HandleArgument (TValue argument, IArgumentOperation operation);
+ // Called for property setters which are essentially like arguments passed to a method.
+ public abstract void HandlePropertySetterArgument (TValue value, IMethodSymbol setMethod, ISimpleAssignmentOperation operation);
+
// This takes an IOperation rather than an IReturnOperation because the return value
// may (must?) come from BranchValue of an operation whose FallThroughSuccessor is the exit block.
public abstract void HandleReturnValue (TValue returnValue, IOperation operation);
@@ -115,12 +120,19 @@ namespace ILLink.RoslynAnalyzer.DataFlow
// Doesn't get called for assignments to locals, which are handled above.
HandleAssignment (value, targetValue, operation);
break;
- case IPropertyReferenceOperation:
+ case IPropertyReferenceOperation propertyRef:
+ // A property assignment is really a call to the property setter.
+ var setMethod = propertyRef.Property.SetMethod;
+ Debug.Assert (setMethod != null);
+ HandlePropertySetterArgument (value, setMethod!, operation);
+ break;
// TODO: when setting a property in an attribute, target is an IPropertyReference.
case IArrayElementReferenceOperation:
// TODO
break;
- // TODO: DiscardOperation
+ case IDiscardOperation:
+ // Assignments like "_ = SomeMethod();" don't need dataflow tracking.
+ break;
default:
throw new NotImplementedException (operation.Target.GetType ().ToString ());
}
@@ -153,7 +165,7 @@ namespace ILLink.RoslynAnalyzer.DataFlow
{
if (operation.Instance != null) {
var instanceValue = Visit (operation.Instance, state);
- HandleReceiverArgument (instanceValue, operation);
+ HandleReceiverArgument (instanceValue, operation.TargetMethod, operation);
}
foreach (var argument in operation.Arguments)
@@ -162,6 +174,37 @@ namespace ILLink.RoslynAnalyzer.DataFlow
return TopValue;
}
+ public static IMethodSymbol GetPropertyMethod (IPropertyReferenceOperation operation)
+ {
+ // The IPropertyReferenceOperation doesn't tell us whether this reference is to the getter or setter.
+ // For this we need to look at the containing operation.
+ var parent = operation.Parent;
+ Debug.Assert (parent != null);
+ if (parent!.Kind == OperationKind.SimpleAssignment) {
+ var assignment = (ISimpleAssignmentOperation) parent;
+ if (assignment.Target == operation) {
+ var setMethod = operation.Property.SetMethod;
+ Debug.Assert (setMethod != null);
+ return setMethod!;
+ }
+ Debug.Assert (assignment.Value == operation);
+ }
+
+ var getMethod = operation.Property.GetMethod;
+ Debug.Assert (getMethod != null);
+ return getMethod!;
+ }
+
+ public override TValue VisitPropertyReference (IPropertyReferenceOperation operation, LocalState<TValue> state)
+ {
+ if (operation.Instance != null) {
+ var instanceValue = Visit (operation.Instance, state);
+ HandleReceiverArgument (instanceValue, GetPropertyMethod (operation), operation);
+ }
+
+ return TopValue;
+ }
+
public override TValue VisitArgument (IArgumentOperation operation, LocalState<TValue> state)
{
var value = Visit (operation.Value, state);
diff --git a/src/ILLink.RoslynAnalyzer/ISymbolExtensions.cs b/src/ILLink.RoslynAnalyzer/ISymbolExtensions.cs
index 71bb46141..fd22e7640 100644
--- a/src/ILLink.RoslynAnalyzer/ISymbolExtensions.cs
+++ b/src/ILLink.RoslynAnalyzer/ISymbolExtensions.cs
@@ -82,7 +82,9 @@ namespace ILLink.RoslynAnalyzer
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeExplicitInterface,
- parameterOptions: SymbolDisplayParameterOptions.IncludeType
+ parameterOptions:
+ SymbolDisplayParameterOptions.IncludeType |
+ SymbolDisplayParameterOptions.IncludeParamsRefOut
);
public static string GetDisplayName (this ISymbol symbol)
diff --git a/src/ILLink.RoslynAnalyzer/TrimAnalysis/SymbolValue.cs b/src/ILLink.RoslynAnalyzer/TrimAnalysis/SymbolValue.cs
index 037ed00a5..9eefd7f9c 100644
--- a/src/ILLink.RoslynAnalyzer/TrimAnalysis/SymbolValue.cs
+++ b/src/ILLink.RoslynAnalyzer/TrimAnalysis/SymbolValue.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
+using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using ILLink.Shared;
@@ -30,10 +31,41 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis
public SymbolValue (ITypeParameterSymbol typeParameter) => Source = typeParameter;
- public override DynamicallyAccessedMemberTypes DynamicallyAccessedMemberTypes =>
- IsMethodReturn
- ? ((IMethodSymbol) Source).GetDynamicallyAccessedMemberTypesOnReturnType ()
- : Source.GetDynamicallyAccessedMemberTypes ();
+ public override DynamicallyAccessedMemberTypes DynamicallyAccessedMemberTypes {
+ get {
+ if (IsMethodReturn) {
+ var method = (IMethodSymbol) Source;
+ var returnDamt = method.GetDynamicallyAccessedMemberTypesOnReturnType ();
+ // Is this a property getter?
+ // If there are conflicts between the getter and the property annotation,
+ // the getter annotation wins. (But DAMT.None is ignored)
+ if (method.MethodKind is MethodKind.PropertyGet && returnDamt == DynamicallyAccessedMemberTypes.None) {
+ var property = (IPropertySymbol) method.AssociatedSymbol!;
+ Debug.Assert (property != null);
+ returnDamt = property!.GetDynamicallyAccessedMemberTypes ();
+ }
+
+ return returnDamt;
+ }
+
+ var damt = Source.GetDynamicallyAccessedMemberTypes ();
+
+ // Is this a property setter parameter?
+ if (Source.Kind == SymbolKind.Parameter) {
+ var parameterMethod = (IMethodSymbol) Source.ContainingSymbol;
+ Debug.Assert (parameterMethod != null);
+ // If there are conflicts between the setter and the property annotation,
+ // the setter annotation wins. (But DAMT.None is ignored)
+ if (parameterMethod!.MethodKind == MethodKind.PropertySet && damt == DynamicallyAccessedMemberTypes.None) {
+ var property = (IPropertySymbol) parameterMethod.AssociatedSymbol!;
+ Debug.Assert (property != null);
+ damt = property!.GetDynamicallyAccessedMemberTypes ();
+ }
+ }
+
+ return damt;
+ }
+ }
public override string ToString ()
{
diff --git a/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs b/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs
index e00bf7ff6..1f9ebe300 100644
--- a/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs
+++ b/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs
@@ -15,7 +15,6 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis
{
public readonly TrimAnalysisPatternStore TrimAnalysisPatterns;
-
public TrimAnalysisVisitor (
LocalStateLattice<MultiValue, ValueSetLattice<SingleValue>> lattice,
OperationBlockAnalysisContext context
@@ -42,6 +41,21 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis
return new MultiValue (new SymbolValue (operation.TargetMethod, isMethodReturn: true));
}
+ // Just like VisitInvocation for a method call, we need to visit a property method invocation
+ // in case it has an annotated return value.
+ public override MultiValue VisitPropertyReference (IPropertyReferenceOperation operation, StateValue state)
+ {
+ // Base logic visits the receiver
+ base.VisitPropertyReference (operation, state);
+
+ var propertyMethod = GetPropertyMethod (operation);
+ // Only the getter has a return value that may be annotated.
+ if (propertyMethod.MethodKind == MethodKind.PropertyGet)
+ return new MultiValue (new SymbolValue (propertyMethod, isMethodReturn: true));
+
+ return TopValue;
+ }
+
public override MultiValue VisitConversion (IConversionOperation operation, StateValue state)
{
var value = base.VisitConversion (operation, state);
@@ -86,7 +100,7 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis
// Override handlers for situations where annotated locations may be involved in reflection access:
// - assignments
- // - arguments passed to method parameters
+ // - arguments passed to method parameters (or implicitly passed to property setters)
// this also needs to create the annotated value for parameters, because they are not represented
// as 'IParameterReferenceOperation' when passing arguments
// - instance passed as explicit or implicit receiver to a method invocation
@@ -118,16 +132,23 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis
));
}
- public override void HandleReceiverArgument (MultiValue receieverValue, IInvocationOperation operation)
+ // Similar to HandleArgument, for an assignment operation that is really passing an argument to a property setter.
+ public override void HandlePropertySetterArgument (MultiValue value, IMethodSymbol setMethod, ISimpleAssignmentOperation operation)
{
- if (operation.Instance == null)
- return;
+ var parameter = new MultiValue (new SymbolValue (setMethod.Parameters[0]));
- MultiValue implicitReceiverParameter = new MultiValue (new SymbolValue (operation.TargetMethod, isMethodReturn: false));
+ TrimAnalysisPatterns.Add (new TrimAnalysisPattern (value, parameter, operation));
+ }
+
+ // Can be called for an invocation or a propertyreference
+ // where the receiver is not null (so an instance method/property).
+ public override void HandleReceiverArgument (MultiValue receiverValue, IMethodSymbol targetMethod, IOperation operation)
+ {
+ MultiValue thisParameter = new MultiValue (new SymbolValue (targetMethod!, isMethodReturn: false));
TrimAnalysisPatterns.Add (new TrimAnalysisPattern (
- receieverValue,
- implicitReceiverParameter,
+ receiverValue,
+ thisParameter,
operation
));
}
diff --git a/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs b/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs
index ebe9145d7..54f69ab98 100644
--- a/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs
+++ b/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs
@@ -13,7 +13,7 @@ namespace ILLink.RoslynAnalyzer.Tests
return RunTest (nameof (AnnotatedMembersAccessedViaReflection));
}
- [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")]
+ [Fact]
public Task ApplyTypeAnnotations ()
{
return RunTest (nameof (ApplyTypeAnnotations));
@@ -25,37 +25,37 @@ namespace ILLink.RoslynAnalyzer.Tests
return RunTest (nameof (AssemblyQualifiedNameDataflow));
}
- [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")]
+ [Fact]
public Task AttributeConstructorDataflow ()
{
return RunTest (nameof (AttributeConstructorDataflow));
}
- [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")]
+ [Fact]
public Task AttributeFieldDataflow ()
{
return RunTest (nameof (AttributeFieldDataflow));
}
- [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")]
+ [Fact]
public Task AttributePropertyDataflow ()
{
return RunTest (nameof (AttributePropertyDataflow));
}
- [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")]
+ [Fact]
public Task ByRefDataflow ()
{
return RunTest (nameof (ByRefDataflow));
}
- [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")]
+ [Fact]
public Task ComplexTypeHandling ()
{
return RunTest (nameof (ComplexTypeHandling));
}
- [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")]
+ [Fact]
public Task DynamicDependencyDataflow ()
{
return RunTest (nameof (DynamicDependencyDataflow));
@@ -67,7 +67,7 @@ namespace ILLink.RoslynAnalyzer.Tests
return RunTest (nameof (EmptyArrayIntrinsicsDataFlow));
}
- [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")]
+ [Fact]
public Task FieldDataFlow ()
{
return RunTest (nameof (FieldDataFlow));
@@ -97,7 +97,7 @@ namespace ILLink.RoslynAnalyzer.Tests
return RunTest (nameof (GetTypeDataFlow));
}
- [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")]
+ [Fact]
public Task IReflectDataflow ()
{
return RunTest (nameof (IReflectDataflow));
@@ -109,19 +109,19 @@ namespace ILLink.RoslynAnalyzer.Tests
return RunTest (nameof (LocalDataFlow));
}
- [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")]
+ [Fact]
public Task LocalDataFlowKeptMembers ()
{
return RunTest (nameof (LocalDataFlowKeptMembers));
}
- [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")]
+ [Fact]
public Task MemberTypes ()
{
return RunTest (nameof (MemberTypes));
}
- [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")]
+ [Fact]
public Task MemberTypesAllOnCopyAssembly ()
{
return RunTest (nameof (MemberTypesAllOnCopyAssembly));
@@ -145,13 +145,13 @@ namespace ILLink.RoslynAnalyzer.Tests
return RunTest (nameof (MethodReturnParameterDataFlow));
}
- [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")]
+ [Fact]
public Task MethodThisDataFlow ()
{
return RunTest (nameof (MethodThisDataFlow));
}
- [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")]
+ [Fact]
public Task PropertyDataFlow ()
{
return RunTest (nameof (PropertyDataFlow));
diff --git a/test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs b/test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs
index 7d23f9713..481f3c7a4 100644
--- a/test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs
+++ b/test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs
@@ -65,14 +65,30 @@ namespace ILLink.RoslynAnalyzer.Tests
private static IEnumerable<string> GetTestDependencies (string rootSourceDir, SyntaxTree testSyntaxTree)
{
foreach (var attribute in testSyntaxTree.GetRoot ().DescendantNodes ().OfType<AttributeSyntax> ()) {
- if (attribute.Name.ToString () != "SetupCompileBefore")
+ var attributeName = attribute.Name.ToString ();
+ if (attributeName != "SetupCompileBefore" && attributeName != "SandboxDependency")
continue;
- var testNamespace = testSyntaxTree.GetRoot ().DescendantNodes ().OfType<NamespaceDeclarationSyntax> ().Single ().Name.ToString ();
+ var testNamespace = testSyntaxTree.GetRoot ().DescendantNodes ().OfType<NamespaceDeclarationSyntax> ().First ().Name.ToString ();
var testSuiteName = testNamespace.Substring (testNamespace.LastIndexOf ('.') + 1);
var args = LinkerTestBase.GetAttributeArguments (attribute);
- foreach (var sourceFile in ((ImplicitArrayCreationExpressionSyntax) args["#1"]).DescendantNodes ().OfType<LiteralExpressionSyntax> ())
- yield return Path.Combine (rootSourceDir, testSuiteName, LinkerTestBase.GetStringFromExpression (sourceFile));
+
+ switch (attributeName) {
+ case "SetupCompileBefore": {
+ foreach (var sourceFile in ((ImplicitArrayCreationExpressionSyntax) args["#1"]).DescendantNodes ().OfType<LiteralExpressionSyntax> ())
+ yield return Path.Combine (rootSourceDir, testSuiteName, LinkerTestBase.GetStringFromExpression (sourceFile));
+ break;
+ }
+ case "SandboxDependency": {
+ var sourceFile = LinkerTestBase.GetStringFromExpression (args["#0"]);
+ if (!sourceFile.EndsWith (".cs"))
+ throw new NotSupportedException ();
+ yield return Path.Combine (rootSourceDir, testSuiteName, sourceFile);
+ break;
+ }
+ default:
+ throw new InvalidOperationException ();
+ }
}
}
diff --git a/test/ILLink.RoslynAnalyzer.Tests/TestChecker.cs b/test/ILLink.RoslynAnalyzer.Tests/TestChecker.cs
index cd55b716f..deaafb950 100644
--- a/test/ILLink.RoslynAnalyzer.Tests/TestChecker.cs
+++ b/test/ILLink.RoslynAnalyzer.Tests/TestChecker.cs
@@ -11,7 +11,6 @@ using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Text;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Xunit;
@@ -116,7 +115,7 @@ namespace ILLink.RoslynAnalyzer.Tests
public override void VisitConstructorDeclaration (ConstructorDeclarationSyntax node)
{
base.VisitConstructorDeclaration (node);
- ValidateDiagnostics(node, node.AttributeLists);
+ ValidateDiagnostics (node, node.AttributeLists);
}
private void ValidateDiagnostics (CSharpSyntaxNode memberSyntax, SyntaxList<AttributeListSyntax> attrLists)
@@ -288,11 +287,11 @@ namespace ILLink.RoslynAnalyzer.Tests
}
}
- missingDiagnosticMessage = $"Could not find text:\n{text}\nIn diagnostics:\n{(string.Join (Environment.NewLine, _diagnostics))}";
+ missingDiagnosticMessage = $"Could not find text:\n{text}\nIn diagnostics:\n{string.Join (Environment.NewLine, _diagnostics)}";
return false;
}
- private void ValidateLogDoesNotContainAttribute (AttributeSyntax attribute, IReadOnlyList<Diagnostic> diagnosticMessages)
+ private static void ValidateLogDoesNotContainAttribute (AttributeSyntax attribute, IReadOnlyList<Diagnostic> diagnosticMessages)
{
var arg = Assert.Single (LinkerTestBase.GetAttributeArguments (attribute));
var text = LinkerTestBase.GetStringFromExpression (arg.Value);
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/ApplyTypeAnnotations.cs b/test/Mono.Linker.Tests.Cases/DataFlow/ApplyTypeAnnotations.cs
index 5863cf4a4..f02ea1cba 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/ApplyTypeAnnotations.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/ApplyTypeAnnotations.cs
@@ -50,6 +50,12 @@ namespace Mono.Linker.Tests.Cases.DataFlow
}
[Kept]
+ // Analyzer doesn't support intrinsics: https://github.com/dotnet/linker/issues/2374
+ [ExpectedWarning ("IL2026", "System.Type.GetType(String)",
+ ProducedBy = ProducedBy.Analyzer)]
+ // Analyzer doesn't track known types: https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2072", "'type'", nameof (ApplyTypeAnnotations) + "." + nameof (RequireCombination) + "(Type)", "System.Type.GetType(String)",
+ ProducedBy = ProducedBy.Analyzer)]
static void TestFromTypeGetTypeOverConstant ()
{
RequireCombination (Type.GetType ("Mono.Linker.Tests.Cases.DataFlow.ApplyTypeAnnotations+FromTypeGetTypeOverConstantTestType"));
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs
index 6cb0409cf..69d4e7959 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs
@@ -40,14 +40,18 @@ namespace Mono.Linker.Tests.Cases.DataFlow
static Type s_typeWithPublicParameterlessConstructor;
[Kept]
- [UnrecognizedReflectionAccessPattern (typeof (ByRefDataflow), nameof (MethodWithRefParameter), new string[] { "Type&" }, messageCode: "IL2077")]
+ // Trimmer and analyzer use different formats for ref parameters: https://github.com/dotnet/linker/issues/2406
+ [ExpectedWarning ("IL2077", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(Type&)", ProducedBy = ProducedBy.Trimmer)]
+ [ExpectedWarning ("IL2077", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(ref Type)", ProducedBy = ProducedBy.Analyzer)]
public static void PassRefToField ()
{
MethodWithRefParameter (ref s_typeWithPublicParameterlessConstructor);
}
[Kept]
- [UnrecognizedReflectionAccessPattern (typeof (ByRefDataflow), nameof (MethodWithRefParameter), new string[] { "Type&" }, messageCode: "IL2067")]
+ // Trimmer and analyzer use different formats for ref parameters: https://github.com/dotnet/linker/issues/2406
+ [ExpectedWarning ("IL2067", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(Type&)", ProducedBy = ProducedBy.Trimmer)]
+ [ExpectedWarning ("IL2067", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(ref Type)", ProducedBy = ProducedBy.Analyzer)]
public static void PassRefToParameter (Type parameter)
{
MethodWithRefParameter (ref parameter);
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs b/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs
index 7bcfbc70c..858d40088 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs
@@ -99,6 +99,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow
}
[Kept]
+ // Analyzer doesn't support intrinsics: https://github.com/dotnet/linker/issues/2374
+ [ExpectedWarning ("IL2072", "'type'", nameof (ComplexTypeHandling) + "." + nameof (RequirePublicMethods) + "(Type)", "System.Object.GetType()",
+ ProducedBy = ProducedBy.Analyzer)]
static void TestArrayGetTypeFromMethodParamHelper (ArrayGetTypeFromMethodParamElement[] p)
{
RequirePublicMethods (p.GetType ());
@@ -121,6 +124,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow
static ArrayGetTypeFromFieldElement[] _arrayGetTypeFromField;
[Kept]
+ // Analyzer doesn't support intrinsics: https://github.com/dotnet/linker/issues/2374
+ [ExpectedWarning ("IL2072", "'type'", nameof (ComplexTypeHandling) + "." + nameof (RequirePublicMethods) + "(Type)", "System.Object.GetType()",
+ ProducedBy = ProducedBy.Analyzer)]
static void TestArrayGetTypeFromField ()
{
RequirePublicMethods (_arrayGetTypeFromField.GetType ());
@@ -134,6 +140,12 @@ namespace Mono.Linker.Tests.Cases.DataFlow
}
[Kept]
+ // Analyzer doesn't support intrinsics: https://github.com/dotnet/linker/issues/2374
+ [ExpectedWarning ("IL2026", "System.Type.GetType(String)",
+ ProducedBy = ProducedBy.Analyzer)]
+ // Analyzer doesn't track known types: https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2072", "'type'", nameof (ComplexTypeHandling) + "." + nameof (RequirePublicMethods) + "(Type)", "System.Type.GetType(String)",
+ ProducedBy = ProducedBy.Analyzer)]
static void TestArrayTypeGetType ()
{
RequirePublicMethods (Type.GetType ("Mono.Linker.Tests.Cases.DataFlow.ComplexTypeHandling+ArrayTypeGetTypeElement[]"));
@@ -148,6 +160,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow
}
[Kept]
+ // Analyzer doesn't support intrinsics: https://github.com/dotnet/linker/issues/2374
+ [ExpectedWarning ("IL2026", "Activator.CreateInstance(String, String)",
+ ProducedBy = ProducedBy.Analyzer)]
static void TestArrayCreateInstanceByName ()
{
Activator.CreateInstance ("test", "Mono.Linker.Tests.Cases.DataFlow.ComplexTypeHandling+ArrayCreateInstanceByNameElement[]");
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs
index cb36d87a3..30b520ff7 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
@@ -43,7 +43,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow
static Type _staticTypeWithoutRequirements;
- [ExpectedWarning ("IL2097", nameof (_annotationOnWrongType))]
+ // TODO: warn about annotation on wrong type in analyzer: https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2097", nameof (_annotationOnWrongType),
+ ProducedBy = ProducedBy.Trimmer)]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)]
static object _annotationOnWrongType;
@@ -58,18 +60,14 @@ namespace Mono.Linker.Tests.Cases.DataFlow
RequireNothing (_typeWithPublicParameterlessConstructor);
}
- [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (_typeWithPublicParameterlessConstructor),
- messageCode: "IL2074", message: new string[] {
- nameof (GetUnkownType),
- nameof (_typeWithPublicParameterlessConstructor)
- })]
- [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (_typeWithPublicParameterlessConstructor), messageCode: "IL2074")]
+ [ExpectedWarning ("IL2074", nameof (FieldDataFlow) + "." + nameof (_typeWithPublicParameterlessConstructor), nameof (GetUnknownType))]
+ [ExpectedWarning ("IL2074", nameof (FieldDataFlow) + "." + nameof (_typeWithPublicParameterlessConstructor), nameof (GetTypeWithNonPublicConstructors))]
private void WriteToInstanceField ()
{
_typeWithPublicParameterlessConstructor = GetTypeWithPublicParameterlessConstructor ();
_typeWithPublicParameterlessConstructor = GetTypeWithPublicConstructors ();
_typeWithPublicParameterlessConstructor = GetTypeWithNonPublicConstructors ();
- _typeWithPublicParameterlessConstructor = GetUnkownType ();
+ _typeWithPublicParameterlessConstructor = GetUnknownType ();
}
[UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2077")]
@@ -84,8 +82,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow
RequireNothing (store._typeWithPublicParameterlessConstructor);
}
- [UnrecognizedReflectionAccessPattern (typeof (TypeStore), nameof (TypeStore._typeWithPublicParameterlessConstructor), messageCode: "IL2074")]
- [UnrecognizedReflectionAccessPattern (typeof (TypeStore), nameof (TypeStore._typeWithPublicParameterlessConstructor), messageCode: "IL2074")]
+ [ExpectedWarning ("IL2074", nameof (TypeStore) + "." + nameof (TypeStore._typeWithPublicParameterlessConstructor), nameof (GetUnknownType))]
+ [ExpectedWarning ("IL2074", nameof (TypeStore) + "." + nameof (TypeStore._typeWithPublicParameterlessConstructor), nameof (GetTypeWithNonPublicConstructors))]
private void WriteToInstanceFieldOnADifferentClass ()
{
var store = new TypeStore ();
@@ -93,7 +91,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
store._typeWithPublicParameterlessConstructor = GetTypeWithPublicParameterlessConstructor ();
store._typeWithPublicParameterlessConstructor = GetTypeWithPublicConstructors ();
store._typeWithPublicParameterlessConstructor = GetTypeWithNonPublicConstructors ();
- store._typeWithPublicParameterlessConstructor = GetUnkownType ();
+ store._typeWithPublicParameterlessConstructor = GetUnknownType ();
}
[UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2077")]
@@ -106,19 +104,15 @@ namespace Mono.Linker.Tests.Cases.DataFlow
RequireNothing (_staticTypeWithPublicParameterlessConstructor);
}
- [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (_staticTypeWithPublicParameterlessConstructor), messageCode: "IL2074")]
- [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (_staticTypeWithPublicParameterlessConstructor), messageCode: "IL2074")]
- [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (_staticTypeWithPublicParameterlessConstructor),
- messageCode: "IL2079", message: new string[] {
- nameof(_staticTypeWithoutRequirements),
- nameof(_staticTypeWithPublicParameterlessConstructor)
- })]
+ [ExpectedWarning ("IL2074", nameof (FieldDataFlow) + "." + nameof (_staticTypeWithPublicParameterlessConstructor), nameof (GetUnknownType))]
+ [ExpectedWarning ("IL2074", nameof (FieldDataFlow) + "." + nameof (_staticTypeWithPublicParameterlessConstructor), nameof (GetTypeWithNonPublicConstructors))]
+ [ExpectedWarning ("IL2079", nameof (FieldDataFlow) + "." + nameof (_staticTypeWithPublicParameterlessConstructor), nameof (_staticTypeWithoutRequirements))]
private void WriteToStaticField ()
{
_staticTypeWithPublicParameterlessConstructor = GetTypeWithPublicParameterlessConstructor ();
_staticTypeWithPublicParameterlessConstructor = GetTypeWithPublicConstructors ();
_staticTypeWithPublicParameterlessConstructor = GetTypeWithNonPublicConstructors ();
- _staticTypeWithPublicParameterlessConstructor = GetUnkownType ();
+ _staticTypeWithPublicParameterlessConstructor = GetUnknownType ();
_staticTypeWithPublicParameterlessConstructor = _staticTypeWithoutRequirements;
}
@@ -132,17 +126,19 @@ namespace Mono.Linker.Tests.Cases.DataFlow
RequireNothing (TypeStore._staticTypeWithPublicParameterlessConstructor);
}
- [UnrecognizedReflectionAccessPattern (typeof (TypeStore), nameof (TypeStore._staticTypeWithPublicParameterlessConstructor), messageCode: "IL2074")]
- [UnrecognizedReflectionAccessPattern (typeof (TypeStore), nameof (TypeStore._staticTypeWithPublicParameterlessConstructor), messageCode: "IL2074")]
+ [ExpectedWarning ("IL2074", nameof (TypeStore) + "." + nameof (TypeStore._staticTypeWithPublicParameterlessConstructor), nameof (GetUnknownType))]
+ [ExpectedWarning ("IL2074", nameof (TypeStore) + "." + nameof (TypeStore._staticTypeWithPublicParameterlessConstructor), nameof (GetTypeWithNonPublicConstructors))]
private void WriteToStaticFieldOnADifferentClass ()
{
TypeStore._staticTypeWithPublicParameterlessConstructor = GetTypeWithPublicParameterlessConstructor ();
TypeStore._staticTypeWithPublicParameterlessConstructor = GetTypeWithPublicConstructors ();
TypeStore._staticTypeWithPublicParameterlessConstructor = GetTypeWithNonPublicConstructors ();
- TypeStore._staticTypeWithPublicParameterlessConstructor = GetUnkownType ();
+ TypeStore._staticTypeWithPublicParameterlessConstructor = GetUnknownType ();
}
- [UnrecognizedReflectionAccessPattern (typeof (TypeStore), nameof (TypeStore._staticTypeWithPublicParameterlessConstructor), messageCode: "IL2064", message: new string[] { nameof (TypeStore._staticTypeWithPublicParameterlessConstructor) })]
+ // TODO: warn about unknown types in analyzer: https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2064", nameof (TypeStore) + "." + nameof (TypeStore._staticTypeWithPublicParameterlessConstructor),
+ ProducedBy = ProducedBy.Trimmer)]
private void WriteUnknownValue ()
{
var array = new object[1];
@@ -191,7 +187,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
return null;
}
- private static Type GetUnkownType ()
+ private static Type GetUnknownType ()
{
return null;
}
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs
index 5ca8b3181..56c0844d4 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
@@ -92,9 +92,10 @@ namespace Mono.Linker.Tests.Cases.DataFlow
t.GetMethod ("foo");
NonTypeType.StaticMethod ();
}
-
- [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (MethodThisDataFlowTypeTest.RequireThisNonPublicMethods), new Type[] { },
- messageCode: "IL2065", message: new string[] { nameof (MethodThisDataFlowTypeTest.RequireThisNonPublicMethods) })]
+ // Analyer doesn't warn about unknown values flowing into annotated locations
+ // https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2065", nameof (MethodThisDataFlowTypeTest) + "." + nameof (MethodThisDataFlowTypeTest.RequireThisNonPublicMethods), "'this'",
+ ProducedBy = ProducedBy.Trimmer)]
static void TestUnknownThis ()
{
var array = new object[1];
@@ -143,14 +144,18 @@ namespace Mono.Linker.Tests.Cases.DataFlow
class NonTypeType
{
- [ExpectedWarning ("IL2041")]
+ // Analyzer doesn't warn about annotations on unsupported types:
+ // https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2041", ProducedBy = ProducedBy.Trimmer)]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
public MethodInfo GetMethod (string name)
{
return null;
}
- [ExpectedWarning ("IL2041")]
+ // Analyzer doesn't warn about annotations on unsupported types:
+ // https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2041", ProducedBy = ProducedBy.Trimmer)]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
public static void StaticMethod ()
{
@@ -164,10 +169,9 @@ namespace System
class MethodThisDataFlowTypeTest : TestSystemTypeBase
{
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
- [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (RequireNonPublicMethods), new Type[] { typeof (Type) },
- messageCode: "IL2082", message: new string[] {
- "'type' argument ", "in call to 'System.MethodThisDataFlowTypeTest.RequireNonPublicMethods(Type)'",
- "implicit 'this' argument of method 'System.MethodThisDataFlowTypeTest.RequireThisPublicMethods()'" })]
+ [ExpectedWarning ("IL2082", nameof (MethodThisDataFlowTypeTest) + "." + nameof (RequireNonPublicMethods) + "(Type)",
+ "'type' argument ", "in call to 'System.MethodThisDataFlowTypeTest.RequireNonPublicMethods(Type)'",
+ "implicit 'this' argument of method 'System.MethodThisDataFlowTypeTest.RequireThisPublicMethods()'")]
public void RequireThisPublicMethods ()
{
RequirePublicMethods (this);
@@ -175,8 +179,7 @@ namespace System
}
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)]
- [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (RequirePublicMethods), new Type[] { typeof (Type) },
- messageCode: "IL2082")]
+ [ExpectedWarning ("IL2082", nameof (MethodThisDataFlowTypeTest) + "." + nameof (RequirePublicMethods) + "(Type)")]
public void RequireThisNonPublicMethods ()
{
RequirePublicMethods (this);
@@ -198,11 +201,8 @@ namespace System
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)]
Type _requiresPublicConstructors;
- [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (_requiresPublicConstructors),
- messageCode: "IL2084", message: new string[] {
- nameof (PropagateToField),
- nameof (_requiresPublicConstructors)
- })]
+ [ExpectedWarning ("IL2084", nameof (MethodThisDataFlowTypeTest) + "." + nameof (_requiresPublicConstructors),
+ nameof (PropagateToField))]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
public void PropagateToField ()
{
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs
index d1f6d57eb..685b6a296 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs
@@ -42,7 +42,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)]
static Type StaticPropertyWithPublicConstructor { get; set; }
- [ExpectedWarning ("IL2099", nameof (PropertyWithUnsupportedType))]
+ // Analyzer doesn't warn about annotations on unsupported types
+ // https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2099", nameof (PropertyWithUnsupportedType), ProducedBy = ProducedBy.Trimmer)]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)]
static object PropertyWithUnsupportedType { get; set; }
@@ -110,8 +112,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow
return _fieldWithPublicConstructors;
}
- [UnrecognizedReflectionAccessPattern (typeof (PropertyDataFlow), nameof (_fieldWithPublicConstructors),
- messageCode: "IL2069", message: new string[] { "value", nameof (PropertyPublicParameterlessConstructorWithExplicitAccessors) + ".set", nameof (_fieldWithPublicConstructors) })]
+ [ExpectedWarning ("IL2069", nameof (PropertyDataFlow) + "." + nameof (_fieldWithPublicConstructors),
+ "'value'",
+ nameof (PropertyPublicParameterlessConstructorWithExplicitAccessors) + ".set")]
[param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
set {
_fieldWithPublicConstructors = value;
@@ -129,7 +132,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow
return _fieldWithPublicConstructors;
}
- [UnrecognizedReflectionAccessPattern (typeof (PropertyDataFlow), nameof (_fieldWithPublicConstructors), messageCode: "IL2069")]
+ [ExpectedWarning ("IL2069", nameof (PropertyDataFlow) + "." + nameof (_fieldWithPublicConstructors),
+ "'value'",
+ nameof (PropertyNonPublicConstructorsWithExplicitAccessors) + ".set")]
[param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)]
set {
_fieldWithPublicConstructors = value;
@@ -145,6 +150,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow
instance.TestInstancePropertyWithStaticField ();
instance.TestPropertyWithDifferentBackingFields ();
instance.TestPropertyWithExistingAttributes ();
+ instance.TestPropertyWithConflictingAttributes ();
+ instance.TestPropertyWithConflictingNoneAttributes ();
instance.TestPropertyWithIndexerWithMatchingAnnotations (null);
instance.TestPropertyWithIndexerWithoutMatchingAnnotations (null);
}
@@ -185,6 +192,10 @@ namespace Mono.Linker.Tests.Cases.DataFlow
}
[RecognizedReflectionAccessPattern]
+ // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors) + "(Type)",
+ nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWhichLooksLikeCompilerGenerated_Field),
+ ProducedBy = ProducedBy.Analyzer)]
public void TestPropertyWhichLooksLikeCompilerGenerated ()
{
// If the property was correctly recognized both the property getter and the backing field should get the annotation.
@@ -197,6 +208,10 @@ namespace Mono.Linker.Tests.Cases.DataFlow
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)]
static Type PropertyWhichLooksLikeCompilerGenerated {
+ // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2078", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWhichLooksLikeCompilerGenerated) + ".get",
+ nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWhichLooksLikeCompilerGenerated_Field),
+ ProducedBy = ProducedBy.Analyzer)]
get {
return PropertyWhichLooksLikeCompilerGenerated_Field;
}
@@ -235,8 +250,14 @@ namespace Mono.Linker.Tests.Cases.DataFlow
[CompilerGenerated]
private Type PropertyWithDifferentBackingFields_SetterField;
+ // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273
[ExpectedWarning ("IL2042",
- "Mono.Linker.Tests.Cases.DataFlow.PropertyDataFlow.TestAutomaticPropagationType.PropertyWithDifferentBackingFields")]
+ "Mono.Linker.Tests.Cases.DataFlow.PropertyDataFlow.TestAutomaticPropagationType.PropertyWithDifferentBackingFields",
+ ProducedBy = ProducedBy.Trimmer)]
+ [ExpectedWarning ("IL2078",
+ nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithDifferentBackingFields) + ".get",
+ "Type",
+ ProducedBy = ProducedBy.Analyzer)]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)]
Type PropertyWithDifferentBackingFields {
get {
@@ -254,22 +275,95 @@ namespace Mono.Linker.Tests.Cases.DataFlow
PropertyWithExistingAttributes = null;
}
- [ExpectedWarning ("IL2056", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes_Field")]
+ // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2056", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes_Field",
+ ProducedBy = ProducedBy.Trimmer)]
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)]
[CompilerGenerated]
Type PropertyWithExistingAttributes_Field;
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)]
Type PropertyWithExistingAttributes {
- [ExpectedWarning ("IL2043", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes.get")]
+ // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2043", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes.get",
+ ProducedBy = ProducedBy.Trimmer)]
[return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)]
get { return PropertyWithExistingAttributes_Field; }
- [ExpectedWarning ("IL2043", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes.set")]
+ // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2043", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes.set",
+ ProducedBy = ProducedBy.Trimmer)]
[param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)]
set { PropertyWithExistingAttributes_Field = value; }
}
+ // When the property annotation conflicts with the getter/setter annotation,
+ // we issue a warning (IL2043 below) but respect the getter/setter annotations.
+ [ExpectedWarning ("IL2072", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithConflictingAttributes) + ".get",
+ nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors) + "(Type)")]
+ [ExpectedWarning ("IL2072", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithConflictingAttributes) + ".set",
+ nameof (PropertyDataFlow) + "." + nameof (GetTypeWithPublicConstructors) + "()")]
+ public void TestPropertyWithConflictingAttributes ()
+ {
+ PropertyWithConflictingAttributes.RequiresPublicConstructors ();
+ PropertyWithConflictingAttributes.RequiresNonPublicConstructors ();
+ PropertyWithConflictingAttributes = GetTypeWithPublicConstructors ();
+ PropertyWithConflictingAttributes = GetTypeWithNonPublicConstructors ();
+ }
+
+ // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2056", "PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes_Field",
+ ProducedBy = ProducedBy.Trimmer)]
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)]
+ [CompilerGenerated]
+ Type PropertyWithConflictingAttributes_Field;
+
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)]
+ Type PropertyWithConflictingAttributes {
+ // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2043", "PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes.get",
+ ProducedBy = ProducedBy.Trimmer)]
+ [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)]
+ get { return PropertyWithConflictingAttributes_Field; }
+
+ // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2043", "PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes.set",
+ ProducedBy = ProducedBy.Trimmer)]
+ [param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)]
+ set { PropertyWithConflictingAttributes_Field = value; }
+ }
+
+ // When the property annotation is DAMT.None and this conflicts with the getter/setter annotations,
+ // we don't produce a warning about the conflict, and just respect the property annotations.
+ [ExpectedWarning ("IL2072", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithConflictingNoneAttributes) + ".get",
+ nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors) + "(Type)")]
+ [ExpectedWarning ("IL2072", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithConflictingNoneAttributes) + ".set",
+ nameof (PropertyDataFlow) + "." + nameof (GetTypeWithNonPublicConstructors) + "()")]
+ public void TestPropertyWithConflictingNoneAttributes ()
+ {
+ PropertyWithConflictingNoneAttributes.RequiresPublicConstructors ();
+ PropertyWithConflictingNoneAttributes.RequiresNonPublicConstructors ();
+ PropertyWithConflictingNoneAttributes = GetTypeWithPublicConstructors ();
+ PropertyWithConflictingNoneAttributes = GetTypeWithNonPublicConstructors ();
+ }
+
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.None)]
+ [CompilerGenerated]
+ Type PropertyWithConflictingNoneAttributes_Field;
+
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)]
+ Type PropertyWithConflictingNoneAttributes {
+ // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2078", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithConflictingNoneAttributes) + ".get",
+ nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithConflictingNoneAttributes_Field),
+ ProducedBy = ProducedBy.Analyzer)]
+ [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.None)]
+ get { return PropertyWithConflictingNoneAttributes_Field; }
+
+ [param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.None)]
+ set { PropertyWithConflictingNoneAttributes_Field = value; }
+ }
+
[RecognizedReflectionAccessPattern]
public void TestPropertyWithIndexerWithMatchingAnnotations ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type myType)
{
@@ -278,8 +372,10 @@ namespace Mono.Linker.Tests.Cases.DataFlow
propclass[1].RequiresPublicConstructors ();
}
- [UnrecognizedReflectionAccessPattern (typeof (PropertyWithIndexer), "Item.set", new Type[] { typeof (Type) }, messageCode: "IL2067")]
- [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), "RequiresNonPublicConstructors", new Type[] { typeof (Type) }, messageCode: "IL2072")]
+ // Trimmer and analyzer handle formatting of indexers differently.
+ [ExpectedWarning ("IL2067", nameof (PropertyWithIndexer) + ".Item.set", ProducedBy = ProducedBy.Trimmer)]
+ [ExpectedWarning ("IL2067", nameof (PropertyWithIndexer) + ".this[Int32].set", ProducedBy = ProducedBy.Analyzer)]
+ [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors) + "(Type)")]
[LogDoesNotContain ("'Value passed to parameter 'index' of method 'Mono.Linker.Tests.Cases.DataFlow.PropertyDataFlow.TestAutomaticPropagationType.PropertyWithIndexer.Item.set'")]
public void TestPropertyWithIndexerWithoutMatchingAnnotations (Type myType)
{
@@ -295,7 +391,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)]
public Type this[int index] {
- [ExpectedWarning ("IL2063", "PropertyWithIndexer.Item.get")]
+ // TODO: warn about unknown types in analyzer: https://github.com/dotnet/linker/issues/2273
+ [ExpectedWarning ("IL2063", "PropertyWithIndexer.Item.get",
+ ProducedBy = ProducedBy.Trimmer)]
get => Property_Field[index];
set => Property_Field[index] = value;
}
diff --git a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresCapability.cs b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresCapability.cs
index 15cebd41b..832461a3f 100644
--- a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresCapability.cs
+++ b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresCapability.cs
@@ -1205,7 +1205,7 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability
// RequiresUnfereferencedCode on the type will suppress IL2072
// https://github.com/dotnet/linker/issues/2379
- [ExpectedWarning("IL2072", ProducedBy = ProducedBy.Analyzer)]
+ [ExpectedWarning ("IL2072", ProducedBy = ProducedBy.Analyzer)]
static ClassWithRequires ()
{
Instance = Activator.CreateInstance (Type.GetType ("SomeText"));