From d97142bf2eb07334dfd15499a3940bbdd4a91ab9 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 13 Aug 2024 09:28:46 -0700 Subject: [PATCH] Revert "Implement type name resolution for ILLink analyzer (#106209)" This reverts commit e5b1d021938d41b589feeb5b6e9dcb55035dfda9. --- .../DynamicallyAccessedMembersAnalyzer.cs | 6 +- .../ILLink.RoslynAnalyzer.csproj | 4 - .../TrimAnalysis/GenericArgumentDataFlow.cs | 23 ++- .../TrimAnalysis/HandleCallAction.cs | 5 +- .../TrimAnalysis/ReflectionAccessAnalyzer.cs | 14 +- ...RequireDynamicallyAccessedMembersAction.cs | 31 +--- .../TrimAnalysisAssignmentPattern.cs | 7 +- ...TrimAnalysisGenericInstantiationPattern.cs | 7 +- .../TrimAnalysisMethodCallPattern.cs | 5 +- .../TrimAnalysisReflectionAccessPattern.cs | 3 +- .../TrimAnalysis/TrimAnalysisVisitor.cs | 8 +- .../TrimAnalysis/TypeNameResolver.cs | 149 ------------------ .../DynamicallyAccessedMembersCodeFixTests.cs | 28 ++-- .../TestCaseCompilation.cs | 2 +- .../DataFlow/AssemblyQualifiedNameDataflow.cs | 2 +- .../DataFlow/AttributeConstructorDataflow.cs | 2 +- .../DataFlow/AttributeFieldDataflow.cs | 2 +- .../DataFlow/AttributePropertyDataflow.cs | 8 +- .../GenericParameterWarningLocation.cs | 8 +- .../DataFlow/GetTypeDataFlow.cs | 6 +- .../Reflection/TypeUsedViaReflection.cs | 145 +---------------- .../TestCasesRunner/ResultChecker.cs | 8 +- 22 files changed, 80 insertions(+), 393 deletions(-) delete mode 100644 src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TypeNameResolver.cs diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs index c9342122aa6de4..66b71ab4f9c385 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs @@ -52,7 +52,6 @@ public static ImmutableArray GetSupportedDiagnostics () diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.UnrecognizedTypeNameInTypeGetType)); diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.UnrecognizedParameterInMethodCreateInstance)); diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.ParametersOfAssemblyCreateInstanceCannotBeAnalyzed)); - diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.TypeNameIsNotAssemblyQualified)); diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.ReturnValueDoesNotMatchFeatureGuards)); diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.InvalidFeatureGuard)); @@ -118,12 +117,11 @@ public override void Initialize (AnalysisContext context) var location = GetPrimaryLocation (type.Locations); - var typeNameResolver = new TypeNameResolver (context.Compilation); if (type.BaseType is INamedTypeSymbol baseType) - GenericArgumentDataFlow.ProcessGenericArgumentDataFlow (typeNameResolver, location, baseType, context.ReportDiagnostic); + GenericArgumentDataFlow.ProcessGenericArgumentDataFlow (location, baseType, context.ReportDiagnostic); foreach (var interfaceType in type.Interfaces) - GenericArgumentDataFlow.ProcessGenericArgumentDataFlow (typeNameResolver, location, interfaceType, context.ReportDiagnostic); + GenericArgumentDataFlow.ProcessGenericArgumentDataFlow (location, interfaceType, context.ReportDiagnostic); }, SymbolKind.NamedType); context.RegisterSymbolAction (context => { VerifyMemberOnlyApplyToTypesOrStrings (context, context.Symbol); diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/ILLink.RoslynAnalyzer.csproj b/src/tools/illink/src/ILLink.RoslynAnalyzer/ILLink.RoslynAnalyzer.csproj index c3b0b1d1847b48..bc410523d5d716 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/ILLink.RoslynAnalyzer.csproj +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/ILLink.RoslynAnalyzer.csproj @@ -15,13 +15,10 @@ optimize the analyzer even in Debug builds. Note: we still use the Debug configuration to get Debug asserts. --> true - true - - @@ -31,7 +28,6 @@ all contentfiles - diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/GenericArgumentDataFlow.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/GenericArgumentDataFlow.cs index 84a6d31d3fa85b..8eac76a2993396 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/GenericArgumentDataFlow.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/GenericArgumentDataFlow.cs @@ -12,29 +12,28 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis { internal static class GenericArgumentDataFlow { - public static void ProcessGenericArgumentDataFlow (TypeNameResolver typeNameResolver, Location location, INamedTypeSymbol type, Action? reportDiagnostic) + public static void ProcessGenericArgumentDataFlow (Location location, INamedTypeSymbol type, Action reportDiagnostic) { - ProcessGenericArgumentDataFlow (typeNameResolver, location, type.TypeArguments, type.TypeParameters, reportDiagnostic); + ProcessGenericArgumentDataFlow (location, type.TypeArguments, type.TypeParameters, reportDiagnostic); } - public static void ProcessGenericArgumentDataFlow (TypeNameResolver typeNameResolver, Location location, IMethodSymbol method, Action? reportDiagnostic) + public static void ProcessGenericArgumentDataFlow (Location location, IMethodSymbol method, Action reportDiagnostic) { - ProcessGenericArgumentDataFlow (typeNameResolver, location, method.TypeArguments, method.TypeParameters, reportDiagnostic); + ProcessGenericArgumentDataFlow (location, method.TypeArguments, method.TypeParameters, reportDiagnostic); - ProcessGenericArgumentDataFlow (typeNameResolver, location, method.ContainingType, reportDiagnostic); + ProcessGenericArgumentDataFlow (location, method.ContainingType, reportDiagnostic); } - public static void ProcessGenericArgumentDataFlow (TypeNameResolver typeNameResolver, Location location, IFieldSymbol field, Action? reportDiagnostic) + public static void ProcessGenericArgumentDataFlow (Location location, IFieldSymbol field, Action reportDiagnostic) { - ProcessGenericArgumentDataFlow (typeNameResolver, location, field.ContainingType, reportDiagnostic); + ProcessGenericArgumentDataFlow (location, field.ContainingType, reportDiagnostic); } static void ProcessGenericArgumentDataFlow ( - TypeNameResolver typeNameResolver, Location location, ImmutableArray typeArguments, ImmutableArray typeParameters, - Action? reportDiagnostic) + Action reportDiagnostic) { var diagnosticContext = new DiagnosticContext (location, reportDiagnostic); for (int i = 0; i < typeArguments.Length; i++) { @@ -43,14 +42,14 @@ static void ProcessGenericArgumentDataFlow ( var genericParameterValue = new GenericParameterValue (typeParameters[i]); if (genericParameterValue.DynamicallyAccessedMemberTypes != DynamicallyAccessedMemberTypes.None) { SingleValue genericArgumentValue = SingleValueExtensions.FromTypeSymbol (typeArgument)!; - var reflectionAccessAnalyzer = new ReflectionAccessAnalyzer (reportDiagnostic, typeNameResolver); - var requireDynamicallyAccessedMembersAction = new RequireDynamicallyAccessedMembersAction (typeNameResolver, location, reportDiagnostic, reflectionAccessAnalyzer); + var reflectionAccessAnalyzer = new ReflectionAccessAnalyzer (reportDiagnostic); + var requireDynamicallyAccessedMembersAction = new RequireDynamicallyAccessedMembersAction (diagnosticContext, reflectionAccessAnalyzer); requireDynamicallyAccessedMembersAction.Invoke (genericArgumentValue, genericParameterValue); } // Recursively process generic argument data flow on the generic argument if it itself is generic if (typeArgument is INamedTypeSymbol namedTypeArgument && namedTypeArgument.IsGenericType) - ProcessGenericArgumentDataFlow (typeNameResolver, location, namedTypeArgument, reportDiagnostic); + ProcessGenericArgumentDataFlow (location, namedTypeArgument, reportDiagnostic); } } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/HandleCallAction.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/HandleCallAction.cs index 53294dc3c32a9e..3e8d00d5d050f8 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/HandleCallAction.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/HandleCallAction.cs @@ -28,7 +28,6 @@ internal partial struct HandleCallAction ValueSetLattice _multiValueLattice; public HandleCallAction ( - TypeNameResolver typeNameResolver, Location location, ISymbol owningSymbol, IOperation operation, @@ -40,8 +39,8 @@ public HandleCallAction ( _isNewObj = operation.Kind == OperationKind.ObjectCreation; _diagnosticContext = new DiagnosticContext (location, reportDiagnostic); _annotations = FlowAnnotations.Instance; - _reflectionAccessAnalyzer = new (reportDiagnostic, typeNameResolver); - _requireDynamicallyAccessedMembersAction = new (typeNameResolver, location, reportDiagnostic, _reflectionAccessAnalyzer); + _reflectionAccessAnalyzer = new (reportDiagnostic); + _requireDynamicallyAccessedMembersAction = new (_diagnosticContext, _reflectionAccessAnalyzer); _multiValueLattice = multiValueLattice; } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ReflectionAccessAnalyzer.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ReflectionAccessAnalyzer.cs index c53e28ff336fdb..51d684816418d3 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ReflectionAccessAnalyzer.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ReflectionAccessAnalyzer.cs @@ -15,15 +15,8 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis readonly struct ReflectionAccessAnalyzer { readonly Action? _reportDiagnostic; - readonly TypeNameResolver _typeNameResolver; - public ReflectionAccessAnalyzer ( - Action? reportDiagnostic, - TypeNameResolver typeNameResolver) - { - _reportDiagnostic = reportDiagnostic; - _typeNameResolver = typeNameResolver; - } + public ReflectionAccessAnalyzer (Action? reportDiagnostic) => _reportDiagnostic = reportDiagnostic; #pragma warning disable CA1822 // Mark members as static - the other partial implementations might need to be instance methods internal void GetReflectionAccessDiagnostics (Location location, ITypeSymbol typeSymbol, DynamicallyAccessedMemberTypes requiredMemberTypes, bool declaredOnly = false) @@ -145,10 +138,5 @@ void GetDiagnosticsForField (Location location, IFieldSymbol fieldSymbol) diagnosticContext.AddDiagnostic (DiagnosticId.DynamicallyAccessedMembersFieldAccessedViaReflection, fieldSymbol.GetDisplayName ()); } } - - internal bool TryResolveTypeNameAndMark (string typeName, in DiagnosticContext diagnosticContext, bool needsAssemblyName, [NotNullWhen (true)] out ITypeSymbol? type) - { - return _typeNameResolver.TryResolveTypeName (typeName, diagnosticContext, out type, needsAssemblyName); - } } } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/RequireDynamicallyAccessedMembersAction.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/RequireDynamicallyAccessedMembersAction.cs index 91fdb54ef83944..5226aad4f0320b 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/RequireDynamicallyAccessedMembersAction.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/RequireDynamicallyAccessedMembersAction.cs @@ -1,55 +1,40 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Reflection.Metadata; -using Microsoft.CodeAnalysis; using ILLink.RoslynAnalyzer.TrimAnalysis; using ILLink.Shared.TypeSystemProxy; -using System.Collections.Immutable; namespace ILLink.Shared.TrimAnalysis { internal partial struct RequireDynamicallyAccessedMembersAction { - readonly Location _location; - readonly Action? _reportDiagnostic; readonly ReflectionAccessAnalyzer _reflectionAccessAnalyzer; - readonly TypeNameResolver _typeNameResolver; #pragma warning disable CA1822 // Mark members as static - the other partial implementations might need to be instance methods #pragma warning disable IDE0060 // Unused parameters - should be removed once methods are actually implemented public RequireDynamicallyAccessedMembersAction ( - TypeNameResolver typeNameResolver, - Location location, - Action? reportDiagnostic, + DiagnosticContext diagnosticContext, ReflectionAccessAnalyzer reflectionAccessAnalyzer) { - _typeNameResolver = typeNameResolver; - _location = location; - _reportDiagnostic = reportDiagnostic; + _diagnosticContext = diagnosticContext; _reflectionAccessAnalyzer = reflectionAccessAnalyzer; - _diagnosticContext = new (location, reportDiagnostic); } public partial bool TryResolveTypeNameAndMark (string typeName, bool needsAssemblyName, out TypeProxy type) { - var diagnosticContext = new DiagnosticContext (_location, _reportDiagnostic); - if (_reflectionAccessAnalyzer.TryResolveTypeNameAndMark (typeName, diagnosticContext, needsAssemblyName, out ITypeSymbol? foundType)) { - if (foundType is INamedTypeSymbol namedType && namedType.IsGenericType) - GenericArgumentDataFlow.ProcessGenericArgumentDataFlow (_typeNameResolver, _location, namedType, _reportDiagnostic); + // TODO: Implement type name resolution to type symbol + // https://github.com/dotnet/runtime/issues/95118 - type = new TypeProxy (foundType); - return true; - } + // Important corner cases: + // IL2105 (see it's occurences in the tests) - non-assembly qualified type name which doesn't resolve warns + // - will need to figure out what analyzer should do around this. type = default; return false; } private partial void MarkTypeForDynamicallyAccessedMembers (in TypeProxy type, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes) => - _reflectionAccessAnalyzer.GetReflectionAccessDiagnostics (_location, type.Type, dynamicallyAccessedMemberTypes); + _reflectionAccessAnalyzer.GetReflectionAccessDiagnostics (_diagnosticContext.Location, type.Type, dynamicallyAccessedMemberTypes); } } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisAssignmentPattern.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisAssignmentPattern.cs index 7f410b7e7c4bcf..46793d6b448c61 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisAssignmentPattern.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisAssignmentPattern.cs @@ -55,7 +55,7 @@ public TrimAnalysisAssignmentPattern Merge ( public void ReportDiagnostics (DataFlowAnalyzerContext context, Action reportDiagnostic) { - var location = Operation.Syntax.GetLocation (); + var diagnosticContext = new DiagnosticContext (Operation.Syntax.GetLocation (), reportDiagnostic); if (context.EnableTrimAnalyzer && !OwningSymbol.IsInRequiresUnreferencedCodeAttributeScope (out _) && !FeatureContext.IsEnabled (RequiresUnreferencedCodeAnalyzer.FullyQualifiedRequiresUnreferencedCodeAttribute)) { @@ -66,9 +66,8 @@ public void ReportDiagnostics (DataFlowAnalyzerContext context, Action reportDiagnostic) { var location = Operation.Syntax.GetLocation (); - var typeNameResolver = new TypeNameResolver (context.Compilation); - var reflectionAccessAnalyzer = new ReflectionAccessAnalyzer (reportDiagnostic, typeNameResolver); + var reflectionAccessAnalyzer = new ReflectionAccessAnalyzer (reportDiagnostic); if (context.EnableTrimAnalyzer && !OwningSymbol.IsInRequiresUnreferencedCodeAttributeScope (out _) && !FeatureContext.IsEnabled (RequiresUnreferencedCodeAnalyzer.FullyQualifiedRequiresUnreferencedCodeAttribute)) { diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs index d98d172296aae8..58c3c97c550202 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs @@ -43,8 +43,6 @@ internal sealed class TrimAnalysisVisitor : LocalDataFlowVisitor< FeatureChecksVisitor _featureChecksVisitor; - readonly TypeNameResolver _typeNameResolver; - public TrimAnalysisVisitor ( Compilation compilation, LocalStateAndContextLattice, FeatureContextLattice> lattice, @@ -59,7 +57,6 @@ public TrimAnalysisVisitor ( _multiValueLattice = lattice.LocalStateLattice.Lattice.ValueLattice; TrimAnalysisPatterns = trimAnalysisPatterns; _featureChecksVisitor = new FeatureChecksVisitor (dataFlowAnalyzerContext); - _typeNameResolver = new TypeNameResolver (compilation); } public override FeatureChecksValue GetConditionValue (IOperation branchValueOperation, StateValue state) @@ -294,7 +291,7 @@ public override MultiValue HandleMethodCall ( // Especially with DAM on type, this can lead to incorrectly analyzed code (as in unknown type which leads // to noise). ILLink has the same problem currently: https://github.com/dotnet/linker/issues/1952 - HandleCall (_typeNameResolver, operation, OwningSymbol, calledMethod, instance, arguments, Location.None, null, _multiValueLattice, out MultiValue methodReturnValue); + HandleCall (operation, OwningSymbol, calledMethod, instance, arguments, Location.None, null, _multiValueLattice, out MultiValue methodReturnValue); // This will copy the values if necessary TrimAnalysisPatterns.Add (new TrimAnalysisMethodCallPattern ( @@ -318,7 +315,6 @@ public override MultiValue HandleMethodCall ( } internal static void HandleCall( - TypeNameResolver typeNameResolver, IOperation operation, ISymbol owningSymbol, IMethodSymbol calledMethod, @@ -329,7 +325,7 @@ internal static void HandleCall( ValueSetLattice multiValueLattice, out MultiValue methodReturnValue) { - var handleCallAction = new HandleCallAction (typeNameResolver, location, owningSymbol, operation, multiValueLattice, reportDiagnostic); + var handleCallAction = new HandleCallAction (location, owningSymbol, operation, multiValueLattice, reportDiagnostic); MethodProxy method = new (calledMethod); var intrinsicId = Intrinsics.GetIntrinsicIdForMethod (method); if (!handleCallAction.Invoke (method, instance, arguments, intrinsicId, out methodReturnValue)) diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TypeNameResolver.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TypeNameResolver.cs deleted file mode 100644 index a91797e4316ebc..00000000000000 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TypeNameResolver.cs +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Reflection.Metadata; -using Microsoft.CodeAnalysis; -using ILLink.RoslynAnalyzer.TrimAnalysis; -using ILLink.Shared.TypeSystemProxy; -using System.Collections.Immutable; - -namespace ILLink.Shared.TrimAnalysis -{ - internal struct TypeNameResolver - { - readonly Compilation _compilation; - - static readonly TypeNameParseOptions s_typeNameParseOptions = new () { MaxNodes = int.MaxValue }; - - public TypeNameResolver (Compilation compilation) - { - _compilation = compilation; - } - - public bool TryResolveTypeName ( - string typeNameString, - in DiagnosticContext diagnosticContext, - out ITypeSymbol? type, - bool needsAssemblyName) - { - type = null; - if (!TypeName.TryParse (typeNameString.AsSpan (), out TypeName? typeName, s_typeNameParseOptions)) - return false; - - if (needsAssemblyName && !IsFullyQualified (typeName)) { - diagnosticContext.AddDiagnostic (DiagnosticId.TypeNameIsNotAssemblyQualified, typeNameString); - return false; - } - - type = ResolveTypeName (_compilation.Assembly, typeName); - return type != null; - - static bool IsFullyQualified (TypeName typeName) - { - if (typeName.AssemblyName is null) - return false; - - if (typeName.IsArray || typeName.IsPointer || typeName.IsByRef) - return IsFullyQualified (typeName.GetElementType ()); - - if (typeName.IsConstructedGenericType) { - foreach (var arg in typeName.GetGenericArguments ()) { - if (!IsFullyQualified (arg)) - return false; - } - } - - return true; - } - } - - ITypeSymbol? ResolveTypeName (IAssemblySymbol assembly, TypeName typeName) - { - if (typeName.IsSimple) - return GetSimpleType (assembly, typeName); - - if (typeName.IsConstructedGenericType) - return GetGenericType (assembly, typeName); - - if (typeName.IsArray || typeName.IsPointer || typeName.IsByRef) - { - if (ResolveTypeName (assembly, typeName.GetElementType ()) is not ITypeSymbol type) - return null; - - if (typeName.IsArray) - return typeName.IsSZArray ? _compilation.CreateArrayTypeSymbol (type) : _compilation.CreateArrayTypeSymbol (type, typeName.GetArrayRank ()); - - // Roslyn doesn't have a representation for byref types - // (the byrefness is considered part of the symbol, not its type) - if (typeName.IsByRef) - return null; - - if (typeName.IsPointer) - return _compilation.CreatePointerTypeSymbol (type); - - Debug.Fail ("Unreachable"); - return null; - } - - return null; - } - - private ITypeSymbol? GetSimpleType (IAssemblySymbol assembly, TypeName typeName) - { - IAssemblySymbol module = assembly; - if (typeName.AssemblyName is AssemblyNameInfo assemblyName) { - if (ResolveAssembly (assemblyName) is not IAssemblySymbol resolvedAssembly) - return null; - module = resolvedAssembly; - } - - if (GetSimpleTypeFromModule (typeName, module) is ITypeSymbol type) - return type; - - // The analyzer doesn't see the core library, so can't fall back to lookup up types in corelib. - return null; - } - - private static ITypeSymbol? GetSimpleTypeFromModule (TypeName typeName, IAssemblySymbol module) - { - string fullName = TypeNameHelpers.Unescape (typeName.FullName); - return module.GetTypeByMetadataName (fullName); - } - - private ITypeSymbol? GetGenericType (IAssemblySymbol assembly, TypeName typeName) - { - if (ResolveTypeName (assembly, typeName.GetGenericTypeDefinition ()) is not INamedTypeSymbol typeDefinition) - return null; - - ImmutableArray typeArguments = typeName.GetGenericArguments (); - ITypeSymbol[] instantiation = new ITypeSymbol[typeArguments.Length]; - for (int i = 0; i < typeArguments.Length; i++) - { - if (ResolveTypeName (assembly, typeArguments[i]) is not ITypeSymbol type) - return null; - instantiation[i] = type; - } - return typeDefinition.Construct (instantiation); - } - - IAssemblySymbol? ResolveAssembly (AssemblyNameInfo? assemblyName) - { - if (assemblyName is null) - return null; - - if (_compilation.Assembly.Name == assemblyName.Name) - return _compilation.Assembly; - - foreach (var metadataReference in _compilation.References) { - if (_compilation.GetAssemblyOrModuleSymbol (metadataReference) is not IAssemblySymbol asmSym) - continue; - if (asmSym.Name == assemblyName.Name) - return asmSym; - } - return null; - } - } -} diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersCodeFixTests.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersCodeFixTests.cs index 9468360d241119..1f7017bff311b4 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersCodeFixTests.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersCodeFixTests.cs @@ -101,7 +101,7 @@ class C [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] static string M(Type t) { M2(t); - return "Foo, test"; + return "Foo"; } static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) {} @@ -117,7 +117,7 @@ class C [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] static string M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) { M2(t); - return "Foo, test"; + return "Foo"; } static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) {} @@ -187,7 +187,7 @@ class C [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] static string M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { M2(t); - return "Foo, test"; + return "Foo"; } static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) {} @@ -1067,7 +1067,7 @@ await VerifyDynamicallyAccessedMembersCodeFix ( } [Fact] - public async Task CodeFix_IL2075_ReturnAttributeLeavesOnCodeFix () + public async Task CodeFix_IL2075_ReutrnAttributeLeavesOnCodeFix () { var test = $$$""" namespace System @@ -1078,7 +1078,7 @@ class C : TestSystemTypeBase public static string Main() { GetC().GetMethod("Foo"); - return "Foo, test"; + return "Foo"; } private static Type GetC () @@ -1097,7 +1097,7 @@ class C : TestSystemTypeBase public static string Main() { GetC().GetMethod("Foo"); - return "Foo, test"; + return "Foo"; } [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] @@ -1608,7 +1608,7 @@ public static void Main() private string M1() { M2(this); - return "Foo, test"; + return "Foo"; } private static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) @@ -1633,7 +1633,7 @@ public static void Main() private string M1() { M2(this); - return "Foo, test"; + return "Foo"; } private static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) @@ -1676,7 +1676,7 @@ class C : TestSystemTypeBase { public static void Main() { - new C().M1("Foo, test"); + new C().M1("Foo"); } [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] @@ -1700,7 +1700,7 @@ class C : TestSystemTypeBase { public static void Main() { - new C().M1("Foo, test"); + new C().M1("Foo"); } [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] @@ -1736,7 +1736,7 @@ await VerifyDynamicallyAccessedMembersCodeFix ( // /0/Test0.cs(193,4): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) - .WithSpan(193, 4, 193, 27) + .WithSpan(193, 4, 193, 21) .WithArguments("System.C.M1(String)") }); } @@ -1858,7 +1858,7 @@ class C : TestSystemTypeBase { public static void Main() { - new C().M1("Foo, test"); + new C().M1("Foo"); } [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] @@ -1878,7 +1878,7 @@ class C : TestSystemTypeBase { public static void Main() { - new C().M1("Foo, test"); + new C().M1("Foo"); } [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] @@ -1907,7 +1907,7 @@ await VerifyDynamicallyAccessedMembersCodeFix ( // /0/Test0.cs(193,4): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) - .WithSpan(193, 4, 193, 27) + .WithSpan(193, 4, 193, 21) .WithArguments("System.C.M1(String)") }); } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestCaseCompilation.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestCaseCompilation.cs index 58c57155aaada7..1a51ba84083287 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestCaseCompilation.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestCaseCompilation.cs @@ -44,7 +44,7 @@ public static (CompilationWithAnalyzers Compilation, SemanticModel SemanticModel var sources = new List () { src }; sources.AddRange (additionalSources ?? Array.Empty ()); var comp = CSharpCompilation.Create ( - assemblyName: "test", + assemblyName: Guid.NewGuid ().ToString ("N"), syntaxTrees: sources, references: SourceGenerators.Tests.LiveReferencePack.GetMetadataReferences().Add(mdRef).AddRange(additionalReferences), new CSharpCompilationOptions (consoleApplication ? OutputKind.ConsoleApplication : OutputKind.DynamicallyLinkedLibrary)); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs index 85330b4b7e60f1..c32a472e625bcc 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs @@ -58,7 +58,7 @@ static void TestConstructors () RequireNothing (type); } - [ExpectedWarning ("IL2122", "Type 'System.Invalid.TypeName' is not assembly qualified. Type name strings used for dynamically accessing a type should be assembly qualified.")] + [ExpectedWarning ("IL2122", "Type 'System.Invalid.TypeName' is not assembly qualified. " + "Type name strings used for dynamically accessing a type should be assembly qualified.", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] static void TestUnqualifiedTypeNameWarns () { RequirePublicConstructors ("System.Invalid.TypeName"); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs index 04746ae30a4ddf..b6d5eed8170f16 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs @@ -25,7 +25,7 @@ class AttributeConstructorDataflow [KeepsPublicMethods ("Mono.Linker.Tests.Cases.DataFlow.AttributeConstructorDataflow+ClassWithKeptPublicMethods, test")] [KeepsPublicFields (null, null)] [TypeArray (new Type[] { typeof (AttributeConstructorDataflow) })] - [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--")] + [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/linker/issues/2273")] public static void Main () { typeof (AttributeConstructorDataflow).GetMethod ("Main").GetCustomAttribute (typeof (KeepsPublicConstructorAttribute)); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs index bb3c1d4bebb1aa..e7683d1f33806a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs @@ -40,7 +40,7 @@ public static void TestKeepsPublicMethods () [Kept] [KeptAttributeAttribute (typeof (KeepsPublicMethodsAttribute))] - [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--")] + [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] [KeepsPublicMethods (TypeName = "Mono.Linker.Tests.Cases.DataFlow.AttributeFieldDataflow+ClassWithKeptPublicMethods, test")] public static void TestKeepsPublicMethodsString () { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs index ba094199740ea1..de7186fc7f54a4 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs @@ -55,7 +55,8 @@ public static void TestKeepsPublicMethods () [Kept] [KeptAttributeAttribute (typeof (KeepsPublicMethodsAttribute))] - [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethodsKeptByName--")] + // Trimmer/NativeAot only for now + [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethodsKeptByName--", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] [KeepsPublicMethods (TypeName = "Mono.Linker.Tests.Cases.DataFlow.AttributePropertyDataflow+AttributesOnMethod+ClassWithKeptPublicMethodsKeptByName, test")] public static void TestKeepsPublicMethodsByName () { @@ -210,7 +211,8 @@ class AttributeWithConditionalExpression { [Kept] [KeptAttributeAttribute (typeof (KeepsPublicMethodsAttribute))] - [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--")] + // Trimmer/NativeAot only for now + [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] [KeepsPublicMethods (TypeName = 1 + 1 == 2 ? "Mono.Linker.Tests.Cases.DataFlow.AttributePropertyDataflow+AttributeWithConditionalExpression+ClassWithKeptPublicMethodsKeptByName, test" : null)] public static void Test () { @@ -222,7 +224,7 @@ public static void Test () // where the owning symbol is not a method. [Kept] [KeptAttributeAttribute (typeof (KeepsPublicMethodsAttribute))] - [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--")] + [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] [KeepsPublicMethods (TypeName = 1 + 1 == 2 ? "Mono.Linker.Tests.Cases.DataFlow.AttributePropertyDataflow+AttributeWithConditionalExpression+ClassWithKeptPublicMethodsKeptByName, test" : null)] public static int field; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs index 5809d062835327..f28802c174d116 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs @@ -1372,7 +1372,7 @@ class AnnotatedString { static void MethodWithAnnotatedParameter ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] string typeName) { } - [ExpectedWarning ("IL2026", "TypeWithRUCMethod.PrivateRUCMethod")] + [ExpectedWarning ("IL2026", "TypeWithRUCMethod.PrivateRUCMethod", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] static void AnnotatedParameter () { MethodWithAnnotatedParameter ("Mono.Linker.Tests.Cases.DataFlow.GenericParameterWarningLocation+MethodBody+TypeWithPrivateMethods`1[[" @@ -1380,7 +1380,7 @@ static void AnnotatedParameter () + "]], test"); } - [ExpectedWarning ("IL2026", "TypeWithRUCMethod.PrivateRUCMethod")] + [ExpectedWarning ("IL2026", "TypeWithRUCMethod.PrivateRUCMethod", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] static string AnnotatedReturnValue () { @@ -1392,7 +1392,7 @@ static string AnnotatedReturnValue () [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] static string _annotatedField; - [ExpectedWarning ("IL2026", "TypeWithRUCMethod.PrivateRUCMethod")] + [ExpectedWarning ("IL2026", "TypeWithRUCMethod.PrivateRUCMethod", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] static void AnnotatedField () { _annotatedField = "Mono.Linker.Tests.Cases.DataFlow.GenericParameterWarningLocation+MethodBody+TypeWithPrivateMethods`1[[" @@ -1410,7 +1410,7 @@ public static void Test () class TypeGetType { - [ExpectedWarning ("IL2026", "TypeWithRUCMethod.PrivateRUCMethod")] + [ExpectedWarning ("IL2026", "TypeWithRUCMethod.PrivateRUCMethod", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] static void SpecificType () { Type.GetType ("Mono.Linker.Tests.Cases.DataFlow.GenericParameterWarningLocation+MethodBody+TypeWithPrivateMethods`1[[" diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs index 5bb64c5e9c2cf5..31ef05ef3e55bf 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs @@ -168,8 +168,8 @@ public void Method1 () { } [RequiresUnreferencedCode ("--Method2--")] public void Method2 () { } - [ExpectedWarning ("IL2026", "--Method1--")] - [ExpectedWarning ("IL2026", "--Method2--")] + [ExpectedWarning ("IL2026", "--Method1--", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning ("IL2026", "--Method2--", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] public static void Test () { Type.GetType ("Mono.Linker.Tests.Cases.DataFlow." + nameof (GetTypeDataFlow) + "+" + nameof (TypeWithWarnings)).RequiresPublicMethods (); @@ -183,7 +183,7 @@ class OverConstTypeName [RequiresUnreferencedCode ("--Method1--")] public void Method1 () { } - [ExpectedWarning ("IL2026", "--Method1--")] + [ExpectedWarning ("IL2026", "--Method1--", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] public static void Test () { Type.GetType (s_ConstTypeName).RequiresPublicMethods (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs index 2d0e72e03af832..9dc4df8ff039cd 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs @@ -67,7 +67,6 @@ public static void TestNull () { const string reflectionTypeKeptString = null; var typeKept = Type.GetType (reflectionTypeKeptString, false); - RequireConstructor (typeKept); } [Kept] @@ -75,180 +74,119 @@ public static void TestEmptyString () { const string reflectionTypeKeptString = ""; var typeKept = Type.GetType (reflectionTypeKeptString, false); - RequireConstructor (typeKept); } [Kept] - [KeptMember (".ctor()")] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (Full))] public class Full { } [Kept] - [ExpectedWarning ("IL2026", nameof (Full))] public static void TestFullString () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+Full, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; var typeKept = Type.GetType (reflectionTypeKeptString, false); - RequireConstructor (typeKept); } [Kept] - [KeptMember (".ctor()")] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (Generic))] public class Generic { } [Kept] - [ExpectedWarning ("IL2026", "Generic")] public static void TestGenericString () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+Generic`1, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; var typeKept = Type.GetType (reflectionTypeKeptString, false); - RequireConstructor (typeKept); } [Kept] - [KeptMember (".ctor()")] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (GenericInstantiation))] public class GenericInstantiation { } [Kept] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (GenericArgument))] public class GenericArgument { } [Kept] - [ExpectedWarning ("IL2026", "GenericInstantiation")] public static void TestGenericInstantiation () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericInstantiation`1[[Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericArgument]]"; var typeKept = Type.GetType (reflectionTypeKeptString, false); - RequireConstructor (typeKept); } [Kept] - [KeptMember (".ctor()")] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (GenericInstantiationFullString))] public class GenericInstantiationFullString { } [Kept] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (GenericArgumentFullString))] public class GenericArgumentFullString { } [Kept] - [ExpectedWarning ("IL2026", "GenericInstantiationFullString")] public static void TestGenericInstantiationFullString () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericInstantiationFullString`1[" + "[Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericArgumentFullString, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]" + "], test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; var typeKept = Type.GetType (reflectionTypeKeptString, false); - RequireConstructor (typeKept); } [Kept] - [KeptMember (".ctor()")] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (GenericInstantiationOverCoreLib))] public class GenericInstantiationOverCoreLib { } [Kept] - [ExpectedWarning ("IL2026", "GenericInstantiationOverCoreLib", Tool.Trimmer | Tool.NativeAot, "Analyzer can't resolve type names from corelib")] public static void TestGenericInstantiationOverCoreLib () { // Note: the argument type should not be assembly-qualified for this test, which is checking that // we can resolve non-assembly-qualified generic argument types from corelib. const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericInstantiationOverCoreLib`1[[System.String]], test"; var typeKept = Type.GetType (reflectionTypeKeptString, false); - RequireConstructor (typeKept); } [Kept] - [KeptMember (".ctor()")] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (FullConst))] public class FullConst { } [Kept] - [ExpectedWarning ("IL2026", nameof (FullConst))] public static void TestFullStringConst () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+FullConst, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; var typeKept = Type.GetType (reflectionTypeKeptString, false); - RequireConstructor (typeKept); } [Kept] - [KeptMember (".ctor()")] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (TypeAsmName))] public class TypeAsmName { } [Kept] - [ExpectedWarning ("IL2026", nameof (TypeAsmName))] public static void TestTypeAsmName () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+TypeAsmName, test"; var typeKept = Type.GetType (reflectionTypeKeptString, false); - RequireConstructor (typeKept); } [Kept] - [KeptMember (".ctor()")] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (AType))] public class AType { } [Kept] - [ExpectedWarning ("IL2026", nameof (AType))] public static void TestType () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+AType"; var typeKept = Type.GetType (reflectionTypeKeptString, false); - RequireConstructor (typeKept); } [Kept] -#if !NATIVEAOT - [KeptMember (".ctor()")] -#endif - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (Pointer))] public class Pointer { } [Kept] - [ExpectedWarning ("IL2026", nameof (Pointer), Tool.Trimmer, "https://github.com/dotnet/runtime/issues/106214")] public static void TestPointer () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+Pointer*"; var typeKept = Type.GetType (reflectionTypeKeptString, false); - RequireConstructor (typeKept); } [Kept] -#if !NATIVEAOT - [KeptMember (".ctor()")] -#endif - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (Reference))] public class Reference { } [Kept] - [ExpectedWarning ("IL2026", nameof (Reference), Tool.Trimmer, "https://github.com/dotnet/runtime/issues/106214")] public static void TestReference () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+Reference&"; var typeKept = Type.GetType (reflectionTypeKeptString, false); - RequireConstructor (typeKept); } [Kept] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (Array))] public class Array { } [Kept] @@ -256,12 +194,9 @@ public static void TestArray () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+Array[]"; var typeKept = Type.GetType (reflectionTypeKeptString, false); - RequireConstructor (typeKept); } [Kept] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (ArrayOfArray))] public class ArrayOfArray { } [Kept] @@ -269,13 +204,10 @@ public static void TestArrayOfArray () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+ArrayOfArray[][]"; var typeKept = Type.GetType (reflectionTypeKeptString, false); - RequireConstructor (typeKept); } [Kept] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (MultiDimensionalArray))] public class MultiDimensionalArray { } [Kept] @@ -283,12 +215,9 @@ public static void TestMultiDimensionalArray () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+MultiDimensionalArray[,]"; var typeKept = Type.GetType (reflectionTypeKeptString, false); - RequireConstructor (typeKept); } [Kept] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (MultiDimensionalArrayFullString))] public class MultiDimensionalArrayFullString { } [Kept] @@ -296,12 +225,9 @@ public static void TestMultiDimensionalArrayFullString () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+MultiDimensionalArrayFullString[,], test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; var typeKept = Type.GetType (reflectionTypeKeptString, false); - RequireConstructor (typeKept); } [Kept] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (MultiDimensionalArrayAsmName))] public class MultiDimensionalArrayAsmName { } [Kept] @@ -309,7 +235,6 @@ public static void TestMultiDimensionalArrayAsmName () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+MultiDimensionalArrayAsmName[,], test"; var typeKept = Type.GetType (reflectionTypeKeptString, false); - RequireConstructor (typeKept); } [Kept] @@ -319,9 +244,6 @@ class Nested1 class N2 { [Kept] - [KeptMember (".ctor()")] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (N3))] class N3 { } @@ -329,39 +251,26 @@ class N3 } [Kept] - [ExpectedWarning ("IL2026", "N3")] static void TestDeeplyNested () { var typeKept = Type.GetType ("Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+Nested1+N2+N3"); - RequireConstructor (typeKept); } [Kept] - [KeptMember (".ctor()")] class TypeOfToKeep { } [Kept] static void TestTypeOf () { var typeKept = typeof (TypeOfToKeep); - RequireConstructor (typeKept); } [Kept] - [KeptMember (".ctor()")] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (TypeFromBranchA))] class TypeFromBranchA { } - [Kept] - [KeptMember (".ctor()")] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (TypeFromBranchB))] class TypeFromBranchB { } [Kept] - [ExpectedWarning ("IL2026", nameof (TypeFromBranchA))] - [ExpectedWarning ("IL2026", nameof (TypeFromBranchB))] static void TestTypeFromBranch (int b) { string name = null; @@ -377,7 +286,6 @@ static void TestTypeFromBranch (int b) } var typeKept = Type.GetType (name); - RequireConstructor (typeKept); } public class CaseInsensitive { } @@ -400,7 +308,6 @@ static void TestTypeUsingCaseUnknownByTheLinker () bool hideCase = GetCase (); const string reflectionTypeKeptString = "mono.linker.tests.cases.reflection.TypeUsedViaReflection+CaseUnknown, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; var typeKept = Type.GetType (reflectionTypeKeptString, false, hideCase); - RequireConstructor (typeKept); } [Kept] @@ -420,38 +327,27 @@ static void TestTypeUsingCaseUnknownByTheLinker2 () { const string reflectionTypeKeptString = "mono.linker.tests.cases.reflection.TypeUsedViaReflection+CaseUnknown2, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; var typeKept = Type.GetType (reflectionTypeKeptString, false, fieldHideCase); - RequireConstructor (typeKept); } [Kept] - [KeptMember (".ctor()")] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (OverloadWith3Parameters))] public class OverloadWith3Parameters { } [Kept] - [ExpectedWarning ("IL2026", nameof (OverloadWith3Parameters))] static void TestTypeOverloadWith3Parameters () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+OverloadWith3Parameters"; var typeKept = Type.GetType (reflectionTypeKeptString, AssemblyResolver, GetTypeFromAssembly); - RequireConstructor (typeKept); } [Kept] - [KeptMember (".ctor()")] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (OverloadWith4Parameters))] public class OverloadWith4Parameters { } [Kept] - [ExpectedWarning ("IL2026", nameof (OverloadWith4Parameters))] static void TestTypeOverloadWith4Parameters () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+OverloadWith4Parameters"; var typeKept = Type.GetType (reflectionTypeKeptString, AssemblyResolver, GetTypeFromAssembly, false); - RequireConstructor (typeKept); } public class OverloadWith5ParametersWithIgnoreCase { } @@ -465,22 +361,16 @@ static void TestTypeOverloadWith5ParametersWithIgnoreCase () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+OverloadWith5ParametersWithIgnoreCase"; var typeKept = Type.GetType (reflectionTypeKeptString, AssemblyResolver, GetTypeFromAssembly, false, true); - RequireConstructor (typeKept); } [Kept] - [KeptMember (".ctor()")] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (OverloadWith5ParametersWithIgnoreCase))] public class OverloadWith5ParametersWithoutIgnoreCase { } [Kept] - [ExpectedWarning ("IL2026", nameof (OverloadWith5ParametersWithIgnoreCase))] static void TestTypeOverloadWith5ParametersWithoutIgnoreCase () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+OverloadWith5ParametersWithoutIgnoreCase"; var typeKept = Type.GetType (reflectionTypeKeptString, AssemblyResolver, GetTypeFromAssembly, false, false); - RequireConstructor (typeKept); } /// @@ -525,22 +415,16 @@ static void TestUnknownIgnoreCase5Params (int num) const string reflectionTypeKeptString = "mono.linker.tests.cases.reflection.TypeUsedViaReflection+CaseUnknown2, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; bool unknownValue = num + 1 == 1; var typeKept = Type.GetType (reflectionTypeKeptString, AssemblyResolver, GetTypeFromAssembly, false, unknownValue); - RequireConstructor (typeKept); } [Kept] - [KeptMember (".ctor()")] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode ("GenericTypeWithAnnotations_OuterType")] public class GenericTypeWithAnnotations_OuterType< [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicProperties)] T> + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicProperties)] T> { } [Kept] - [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode (nameof (GenericTypeWithAnnotations_InnerType))] public class GenericTypeWithAnnotations_InnerType { [Kept] @@ -551,16 +435,12 @@ private static void PrivateMethod () { } } [Kept] - [ExpectedWarning ("IL2026", "GenericTypeWithAnnotations_OuterType")] - [ExpectedWarning ("IL2026", nameof (GenericTypeWithAnnotations_InnerType), "PrivateProperty.get")] - [ExpectedWarning ("IL2026", nameof (GenericTypeWithAnnotations_InnerType), "PrivateProperty.set")] static void TestGenericTypeWithAnnotations () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericTypeWithAnnotations_OuterType`1[" + "[Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericTypeWithAnnotations_InnerType, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]" + "], test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; - var typeKept = Type.GetType (reflectionTypeKeptString); - RequireConstructor (typeKept); + Type.GetType (reflectionTypeKeptString); } [Kept] @@ -613,36 +493,33 @@ static void TestInvalidTypeCombination () static void TestEscapedTypeName () { var typeKept = Type.GetType ("Library.Not\\+Nested, EscapedTypeNames"); - RequireConstructor (typeKept); typeKept = Type.GetType ("Library.Not\\+Nested+Nes\\\\ted, EscapedTypeNames"); - RequireConstructor (typeKept); typeKept = Type.GetType ("Library.Not\\+Nested+Nes/ted, EscapedTypeNames"); - RequireConstructor (typeKept); } [Kept] class AssemblyTypeResolutionBehavior { [Kept] - [ExpectedWarning ("IL2122")] + [ExpectedWarning ("IL2122", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] static void TestRequireTypeInSameAssemblyAsGetType () { RequireHelper.RequireType ("Mono.Linker.Tests.Cases.Reflection.Dependencies.TypeDefinedInSameAssemblyAsGetType"); } [Kept] - [ExpectedWarning ("IL2122")] + [ExpectedWarning ("IL2122", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] static void TestRequireTypeInSameAssemblyAsCallToRequireType () { RequireHelper.RequireType ("Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+AssemblyTypeResolutionBehavior+TypeDefinedInSameAssemblyAsCallToRequireType"); } [Kept] - [ExpectedWarning ("IL2122")] + [ExpectedWarning ("IL2122", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] static void TestRequireTypeWithNonAssemblyQualifiedGenericArguments () { RequireHelper.RequireType ("Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+AssemblyTypeResolutionBehavior+Generic`1[[System.Int32]], test"); } [Kept] - [ExpectedWarning ("IL2122")] + [ExpectedWarning ("IL2122", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] static void TestRequireTypeWithNonAssemblyQualifiedArrayType () { RequireHelper.RequireType ("Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+AssemblyTypeResolutionBehavior+Generic`1[" + "[Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+AssemblyTypeResolutionBehavior+ArrayElementGenericArgumentType]" @@ -650,7 +527,7 @@ static void TestRequireTypeWithNonAssemblyQualifiedArrayType () { } [Kept] - [ExpectedWarning ("IL2122")] + [ExpectedWarning ("IL2122", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] static void TestRequireTypeWithNonAssemblyQualifiedPointerType () { RequireHelper.RequireType ("Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+AssemblyTypeResolutionBehavior+Generic`1[" + "[Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+AssemblyTypeResolutionBehavior+PointerElementGenericArgumentType]" @@ -658,7 +535,7 @@ static void TestRequireTypeWithNonAssemblyQualifiedPointerType () { } [Kept] - [ExpectedWarning ("IL2122")] + [ExpectedWarning ("IL2122", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] static void TestRequireTypeWithNonAssemblyQualifiedByRefType () { RequireHelper.RequireType ("Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+AssemblyTypeResolutionBehavior+Generic`1[" + "[Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+AssemblyTypeResolutionBehavior+ByRefElementGenericArgumentType]" @@ -685,11 +562,5 @@ class PointerElementGenericArgumentType {} class ByRefElementGenericArgumentType {} } - - [Kept] - static void RequireConstructor ( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] - Type type) { } } } diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs index 71f4b173eb30b0..acf9bf7a2b14d9 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs @@ -1045,6 +1045,7 @@ void VerifyLoggedMessages (AssemblyDefinition original, TrimmingTestLogger logge int? unexpectedWarningCodeNumber = unexpectedWarningCode == null ? null : int.Parse (unexpectedWarningCode.Substring (2)); + MessageContainer? unexpectedWarningMessage = null; foreach (var mc in unmatchedMessages) { if (mc.Category != MessageCategory.Warning) continue; @@ -1056,7 +1057,12 @@ void VerifyLoggedMessages (AssemblyDefinition original, TrimmingTestLogger logge if (attrProvider is IMemberDefinition attrMember && (mc.Origin?.Provider is IMemberDefinition member) && member.FullName.Contains (attrMember.FullName) != true) continue; - unexpectedMessageWarnings.Add ($"Unexpected warning found: {mc}"); + unexpectedWarningMessage = mc; + break; + } + + if (unexpectedWarningMessage is not null) { + unexpectedMessageWarnings.Add ($"Unexpected warning found: {unexpectedWarningMessage}"); } }