mirror of
https://github.com/VSadov/Satori.git
synced 2025-06-09 17:44:48 +09:00
Proper type name parser for native AOT compiler (#83657)
* Proper type name parser for native AOT compiler * Track failure of CA search rules in the type name parser * Fix tests * Suppress new native AOT warning for libraries tests Co-authored-by: vitek-karas <10670590+vitek-karas@users.noreply.github.com> Fixes #72833
This commit is contained in:
parent
6b0a0f3dd4
commit
c1049390d5
13 changed files with 206 additions and 150 deletions
|
@ -29,7 +29,7 @@
|
|||
<IlcSdkPath>$(CoreCLRAotSdkDir)</IlcSdkPath>
|
||||
<IlcFrameworkPath>$(NetCoreAppCurrentTestHostSharedFrameworkPath)</IlcFrameworkPath>
|
||||
<IlcFrameworkNativePath>$(NetCoreAppCurrentTestHostSharedFrameworkPath)</IlcFrameworkNativePath>
|
||||
<NoWarn>$(NoWarn);IL1005;IL3000;IL3001;IL3002;IL3003</NoWarn>
|
||||
<NoWarn>$(NoWarn);IL1005;IL2105;IL3000;IL3001;IL3002;IL3003</NoWarn>
|
||||
<TrimMode>partial</TrimMode>
|
||||
<SuppressTrimAnalysisWarnings>true</SuppressTrimAnalysisWarnings>
|
||||
<SuppressAotAnalysisWarnings>true</SuppressAotAnalysisWarnings>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reflection;
|
||||
|
@ -70,7 +71,7 @@ namespace ILCompiler.Dataflow
|
|||
MarkEvent(origin, @event, reason);
|
||||
break;
|
||||
// case InterfaceImplementation
|
||||
// Nothing to do currently as Native AOT will presere all interfaces on a preserved type
|
||||
// Nothing to do currently as Native AOT will preserve all interfaces on a preserved type
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,19 +79,26 @@ namespace ILCompiler.Dataflow
|
|||
{
|
||||
ModuleDesc? callingModule = ((diagnosticContext.Origin.MemberDefinition as MethodDesc)?.OwningType as MetadataType)?.Module;
|
||||
|
||||
// NativeAOT doesn't have a fully capable type name resolver yet
|
||||
// Once this is implemented don't forget to wire up marking of type forwards which are used in generic parameters
|
||||
if (!DependencyAnalysis.ReflectionMethodBodyScanner.ResolveType(typeName, callingModule, diagnosticContext.Origin.MemberDefinition!.Context, out TypeDesc foundType, out ModuleDesc referenceModule))
|
||||
List<ModuleDesc> referencedModules = new();
|
||||
TypeDesc foundType = System.Reflection.TypeNameParser.ResolveType(typeName, callingModule, diagnosticContext.Origin.MemberDefinition!.Context,
|
||||
referencedModules, out bool typeWasNotFoundInAssemblyNorBaseLibrary);
|
||||
if (foundType == null)
|
||||
{
|
||||
if (needsAssemblyName && typeWasNotFoundInAssemblyNorBaseLibrary)
|
||||
diagnosticContext.AddDiagnostic(DiagnosticId.TypeWasNotFoundInAssemblyNorBaseLibrary, typeName);
|
||||
|
||||
type = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_enabled)
|
||||
{
|
||||
// Also add module metadata in case this reference was through a type forward
|
||||
if (Factory.MetadataManager.CanGenerateMetadata(referenceModule.GetGlobalModuleType()))
|
||||
_dependencies.Add(Factory.ModuleMetadata(referenceModule), reason);
|
||||
foreach (ModuleDesc referencedModule in referencedModules)
|
||||
{
|
||||
// Also add module metadata in case this reference was through a type forward
|
||||
if (Factory.MetadataManager.CanGenerateMetadata(referencedModule.GetGlobalModuleType()))
|
||||
_dependencies.Add(Factory.ModuleMetadata(referencedModule), reason);
|
||||
}
|
||||
|
||||
MarkType(diagnosticContext.Origin, foundType, reason);
|
||||
}
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using Internal.TypeSystem;
|
||||
|
||||
using AssemblyName = System.Reflection.AssemblyName;
|
||||
using StringBuilder = System.Text.StringBuilder;
|
||||
|
||||
namespace ILCompiler.DependencyAnalysis
|
||||
{
|
||||
internal static class ReflectionMethodBodyScanner
|
||||
{
|
||||
public static bool ResolveType(string name, ModuleDesc callingModule, TypeSystemContext context, out TypeDesc type, out ModuleDesc referenceModule)
|
||||
{
|
||||
// This can do enough resolution to resolve "Foo" or "Foo, Assembly, PublicKeyToken=...".
|
||||
// The reflection resolution rules are complicated. This is only needed for a heuristic,
|
||||
// not for correctness, so this shortcut is okay.
|
||||
|
||||
type = null;
|
||||
int i = 0;
|
||||
|
||||
// Consume type name part
|
||||
StringBuilder typeName = new StringBuilder();
|
||||
StringBuilder typeNamespace = new StringBuilder();
|
||||
string containingTypeName = null;
|
||||
while (i < name.Length && (char.IsLetterOrDigit(name[i]) || name[i] == '.' || name[i] == '_' || name[i] == '`' || name[i] == '+'))
|
||||
{
|
||||
if (name[i] == '.')
|
||||
{
|
||||
if (typeNamespace.Length > 0)
|
||||
typeNamespace.Append('.');
|
||||
typeNamespace.Append(typeName);
|
||||
typeName.Clear();
|
||||
}
|
||||
else if (name[i] == '+')
|
||||
{
|
||||
containingTypeName = typeName.ToString();
|
||||
typeName.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
typeName.Append(name[i]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
string nestedTypeName = null;
|
||||
if (containingTypeName != null)
|
||||
{
|
||||
nestedTypeName = typeName.ToString();
|
||||
typeName = new StringBuilder(containingTypeName);
|
||||
}
|
||||
|
||||
// Consume any comma or white space
|
||||
while (i < name.Length && (name[i] == ' ' || name[i] == ','))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
// Consume assembly name
|
||||
StringBuilder assemblyName = new StringBuilder();
|
||||
while (i < name.Length && (char.IsLetterOrDigit(name[i]) || name[i] == '.' || name[i] == '_'))
|
||||
{
|
||||
assemblyName.Append(name[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
// If the name was assembly-qualified, resolve the assembly
|
||||
// If it wasn't qualified, we resolve in the calling assembly
|
||||
|
||||
referenceModule = callingModule;
|
||||
if (assemblyName.Length > 0)
|
||||
{
|
||||
referenceModule = context.ResolveAssembly(new AssemblyName(assemblyName.ToString()), false);
|
||||
}
|
||||
|
||||
if (referenceModule == null)
|
||||
return false;
|
||||
|
||||
// Resolve type in the assembly
|
||||
MetadataType mdType = referenceModule.GetType(typeNamespace.ToString(), typeName.ToString(), throwIfNotFound: false);
|
||||
if (mdType != null && nestedTypeName != null)
|
||||
mdType = mdType.GetNestedType(nestedTypeName);
|
||||
|
||||
// If it didn't resolve and wasn't assembly-qualified, we also try core library
|
||||
if (mdType == null && assemblyName.Length == 0)
|
||||
{
|
||||
referenceModule = context.SystemModule;
|
||||
mdType = referenceModule.GetType(typeNamespace.ToString(), typeName.ToString(), throwIfNotFound: false);
|
||||
if (mdType != null && nestedTypeName != null)
|
||||
mdType = mdType.GetNestedType(nestedTypeName);
|
||||
}
|
||||
|
||||
type = mdType;
|
||||
|
||||
return type != null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
using Internal.TypeSystem;
|
||||
|
||||
namespace System.Reflection
|
||||
{
|
||||
internal unsafe ref partial struct TypeNameParser
|
||||
{
|
||||
private TypeSystemContext _context;
|
||||
private ModuleDesc _callingModule;
|
||||
private List<ModuleDesc> _referencedModules;
|
||||
private bool _typeWasNotFoundInAssemblyNorBaseLibrary;
|
||||
|
||||
public static TypeDesc ResolveType(string name, ModuleDesc callingModule,
|
||||
TypeSystemContext context, List<ModuleDesc> referencedModules, out bool typeWasNotFoundInAssemblyNorBaseLibrary)
|
||||
{
|
||||
var parser = new System.Reflection.TypeNameParser(name)
|
||||
{
|
||||
_context = context,
|
||||
_callingModule = callingModule,
|
||||
_referencedModules = referencedModules
|
||||
};
|
||||
|
||||
TypeDesc result = parser.Parse()?.Value;
|
||||
|
||||
typeWasNotFoundInAssemblyNorBaseLibrary = parser._typeWasNotFoundInAssemblyNorBaseLibrary;
|
||||
return result;
|
||||
}
|
||||
|
||||
private sealed class Type
|
||||
{
|
||||
public Type(TypeDesc type) => Value = type;
|
||||
public TypeDesc Value { get; }
|
||||
|
||||
public Type MakeArrayType() => new Type(Value.MakeArrayType());
|
||||
public Type MakeArrayType(int rank) => new Type(Value.MakeArrayType(rank));
|
||||
public Type MakePointerType() => new Type(Value.MakePointerType());
|
||||
public Type MakeByRefType() => new Type(Value.MakeByRefType());
|
||||
|
||||
public Type MakeGenericType(Type[] typeArguments)
|
||||
{
|
||||
TypeDesc[] instantiation = new TypeDesc[typeArguments.Length];
|
||||
for (int i = 0; i < typeArguments.Length; i++)
|
||||
instantiation[i] = typeArguments[i].Value;
|
||||
return new Type(((MetadataType)Value).MakeInstantiatedType(instantiation));
|
||||
}
|
||||
}
|
||||
|
||||
private static bool CheckTopLevelAssemblyQualifiedName() => true;
|
||||
|
||||
private Type GetType(string typeName, ReadOnlySpan<string> nestedTypeNames, string assemblyNameIfAny)
|
||||
{
|
||||
ModuleDesc module;
|
||||
|
||||
if (assemblyNameIfAny != null)
|
||||
{
|
||||
module = (TryParseAssemblyName(assemblyNameIfAny) is AssemblyName an) ?
|
||||
_context.ResolveAssembly(an, throwIfNotFound: false) : null;
|
||||
}
|
||||
else
|
||||
{
|
||||
module = _callingModule;
|
||||
}
|
||||
|
||||
Type type;
|
||||
|
||||
if (module != null)
|
||||
{
|
||||
type = GetTypeCore(module, typeName, nestedTypeNames);
|
||||
if (type != null)
|
||||
{
|
||||
_referencedModules?.Add(module);
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
// If it didn't resolve and wasn't assembly-qualified, we also try core library
|
||||
if (assemblyNameIfAny == null)
|
||||
{
|
||||
type = GetTypeCore(_context.SystemModule, typeName, nestedTypeNames);
|
||||
if (type != null)
|
||||
{
|
||||
_referencedModules?.Add(_context.SystemModule);
|
||||
return type;
|
||||
}
|
||||
|
||||
_typeWasNotFoundInAssemblyNorBaseLibrary = true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static AssemblyName TryParseAssemblyName(string assemblyName)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new AssemblyName(assemblyName);
|
||||
}
|
||||
catch (FileLoadException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Type GetTypeCore(ModuleDesc module, string typeName, ReadOnlySpan<string> nestedTypeNames)
|
||||
{
|
||||
string typeNamespace, name;
|
||||
|
||||
int separator = typeName.LastIndexOf('.');
|
||||
if (separator <= 0)
|
||||
{
|
||||
typeNamespace = "";
|
||||
name = typeName;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (typeName[separator - 1] == '.')
|
||||
separator--;
|
||||
typeNamespace = typeName.Substring(0, separator);
|
||||
name = typeName.Substring(separator + 1);
|
||||
}
|
||||
|
||||
MetadataType type = module.GetType(typeNamespace, name, throwIfNotFound: false);
|
||||
if (type == null)
|
||||
return null;
|
||||
|
||||
for (int i = 0; i < nestedTypeNames.Length; i++)
|
||||
{
|
||||
type = type.GetNestedType(nestedTypeNames[i]);
|
||||
if (type == null)
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Type(type);
|
||||
}
|
||||
|
||||
private static void ParseError()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,6 +30,12 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\..\..\libraries\Common\src\System\Reflection\TypeNameParser.cs">
|
||||
<Link>TypeNameParser.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\..\..\libraries\Common\src\System\Text\ValueStringBuilder.cs">
|
||||
<Link>ValueStringBuilder.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\Common\TypeSystem\IL\DelegateInfo.cs">
|
||||
<Link>IL\DelegateInfo.cs</Link>
|
||||
</Compile>
|
||||
|
@ -406,7 +412,6 @@
|
|||
<Compile Include="Compiler\DependencyAnalysis\ReflectedFieldNode.cs" />
|
||||
<Compile Include="Compiler\DependencyAnalysis\ReflectedTypeNode.cs" />
|
||||
<Compile Include="Compiler\DependencyAnalysis\ReflectionInvokeSupportDependencyAlgorithm.cs" />
|
||||
<Compile Include="Compiler\DependencyAnalysis\ReflectionMethodBodyScanner.cs" />
|
||||
<Compile Include="Compiler\DependencyAnalysis\StructMarshallingDataNode.cs" />
|
||||
<Compile Include="Compiler\DependencyAnalysis\Target_ARM64\ARM64TentativeMethodNode.cs" />
|
||||
<Compile Include="Compiler\DependencyAnalysis\Target_ARM\ARMTentativeMethodNode.cs" />
|
||||
|
@ -416,6 +421,7 @@
|
|||
<Compile Include="Compiler\DependencyAnalysis\TentativeInstanceMethodNode.cs" />
|
||||
<Compile Include="Compiler\DependencyAnalysis\TentativeMethodNode.cs" />
|
||||
<Compile Include="Compiler\DependencyAnalysis\TrimmingDescriptorNode.cs" />
|
||||
<Compile Include="Compiler\DependencyAnalysis\TypeNameParser.cs" />
|
||||
<Compile Include="Compiler\DependencyAnalysis\VariantInterfaceMethodUseNode.cs" />
|
||||
<Compile Include="Compiler\DependencyAnalysis\CustomAttributeBasedDependencyAlgorithm.cs" />
|
||||
<Compile Include="Compiler\DependencyAnalysis\FieldMetadataNode.cs" />
|
||||
|
|
|
@ -83,29 +83,22 @@ namespace System.Net.Http
|
|||
// the latter can't in turn have an explicit dependency on the former.
|
||||
|
||||
// Get the relevant types needed.
|
||||
Type? socketsHttpHandlerType = Type.GetType("System.Net.Http.SocketsHttpHandler, System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
|
||||
Type? httpMessageHandlerType = Type.GetType("System.Net.Http.HttpMessageHandler, System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
|
||||
Type? httpClientType = Type.GetType("System.Net.Http.HttpClient, System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
|
||||
Type? httpRequestMessageType = Type.GetType("System.Net.Http.HttpRequestMessage, System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
|
||||
Type? httpResponseMessageType = Type.GetType("System.Net.Http.HttpResponseMessage, System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
|
||||
Type? httpResponseHeadersType = Type.GetType("System.Net.Http.Headers.HttpResponseHeaders, System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
|
||||
Type? httpContentType = Type.GetType("System.Net.Http.HttpContent, System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
|
||||
Type? socketsHttpHandlerType = Type.GetType("System.Net.Http.SocketsHttpHandler, System.Net.Http", throwOnError: false);
|
||||
Type? httpMessageHandlerType = Type.GetType("System.Net.Http.HttpMessageHandler, System.Net.Http", throwOnError: false);
|
||||
Type? httpClientType = Type.GetType("System.Net.Http.HttpClient, System.Net.Http", throwOnError: false);
|
||||
Type? httpRequestMessageType = Type.GetType("System.Net.Http.HttpRequestMessage, System.Net.Http", throwOnError: false);
|
||||
Type? httpResponseMessageType = Type.GetType("System.Net.Http.HttpResponseMessage, System.Net.Http", throwOnError: false);
|
||||
Type? httpResponseHeadersType = Type.GetType("System.Net.Http.Headers.HttpResponseHeaders, System.Net.Http", throwOnError: false);
|
||||
Type? httpContentType = Type.GetType("System.Net.Http.HttpContent, System.Net.Http", throwOnError: false);
|
||||
Type? taskOfHttpResponseMessageType = Type.GetType("System.Threading.Tasks.Task`1[[System.Net.Http.HttpResponseMessage, System.Net.Http]], System.Runtime", throwOnError: false);
|
||||
|
||||
if (socketsHttpHandlerType == null || httpMessageHandlerType == null || httpClientType == null || httpRequestMessageType == null ||
|
||||
httpResponseMessageType == null || httpResponseHeadersType == null || httpContentType == null)
|
||||
httpResponseMessageType == null || httpResponseHeadersType == null || httpContentType == null || taskOfHttpResponseMessageType == null)
|
||||
{
|
||||
Debug.Fail("Unable to load required type.");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Workaround until https://github.com/dotnet/runtime/issues/72833 is fixed
|
||||
[UnconditionalSuppressMessage("AotAnalysis", "IL3050:RequiresDynamicCode",
|
||||
Justification = "The type HttpResponseMessage is a reference type")]
|
||||
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
|
||||
static Type GetTaskOfHttpResponseMessageType([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? httpResponseMessageType) => typeof(Task<>).MakeGenericType(httpResponseMessageType!);
|
||||
|
||||
Type taskOfHttpResponseMessageType = GetTaskOfHttpResponseMessageType(httpResponseMessageType);
|
||||
|
||||
// Get the methods on those types.
|
||||
ConstructorInfo? socketsHttpHandlerCtor = socketsHttpHandlerType.GetConstructor(Type.EmptyTypes);
|
||||
PropertyInfo? pooledConnectionIdleTimeoutProp = socketsHttpHandlerType.GetProperty("PooledConnectionIdleTimeout");
|
||||
|
|
|
@ -6,6 +6,8 @@ using System.Diagnostics.CodeAnalysis;
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace System.Reflection
|
||||
{
|
||||
//
|
||||
|
@ -622,10 +624,12 @@ namespace System.Reflection
|
|||
return fullName;
|
||||
}
|
||||
|
||||
#if SYSTEM_PRIVATE_CORELIB
|
||||
private void ParseError()
|
||||
{
|
||||
if (_throwOnError)
|
||||
throw new ArgumentException(SR.Arg_ArgumentException, $"typeName@{_errorIndex}");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ using System.Diagnostics;
|
|||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace System.Text
|
||||
{
|
||||
internal ref partial struct ValueStringBuilder
|
||||
|
|
|
@ -238,10 +238,10 @@ namespace System.Reflection.Tests
|
|||
[ActiveIssue("https://github.com/mono/mono/issues/15318", TestRuntimes.Mono)]
|
||||
public void Invoke_LargeDimensionalArrayConstructor()
|
||||
{
|
||||
Type type = Type.GetType("System.Type[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]");
|
||||
Type type = Type.GetType($"System.Type[{new string(',', 31)}]");
|
||||
ConstructorInfo[] cia = TypeExtensions.GetConstructors(type);
|
||||
Assert.Equal(2, cia.Length);
|
||||
Assert.Throws<TypeLoadException>(() => Type.GetType("System.Type[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]"));
|
||||
Assert.Throws<TypeLoadException>(() => Type.GetType($"System.Type[{new string(',', 42)}]"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
@ -82,6 +82,10 @@ namespace System.Reflection.Tests
|
|||
[InlineData(typeof(string), new Type[] { typeof(char), typeof(int) })]
|
||||
public void Properties(Type type, Type[] typeParameters)
|
||||
{
|
||||
// Trick trimming into keeping the string ctor
|
||||
if (string.Empty.Length > 0)
|
||||
typeof(string).GetConstructors();
|
||||
|
||||
ConstructorInfo constructor = TypeExtensions.GetConstructor(type, typeParameters);
|
||||
|
||||
Assert.Equal(type, constructor.DeclaringType);
|
||||
|
|
|
@ -128,9 +128,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
|
|||
{
|
||||
}
|
||||
|
||||
// https://github.com/dotnet/runtime/issues/72833
|
||||
// NativeAOT doesn't implement full type name parser yet
|
||||
[Kept (By = Tool.Trimmer)]
|
||||
[Kept]
|
||||
class FromStringConstantWithGenericInner
|
||||
{
|
||||
}
|
||||
|
@ -143,9 +141,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
|
|||
public T GetValue () { return default (T); }
|
||||
}
|
||||
|
||||
// https://github.com/dotnet/runtime/issues/72833
|
||||
// NativeAOT doesn't implement full type name parser yet
|
||||
[Kept (By = Tool.Trimmer)]
|
||||
[Kept]
|
||||
class FromStringConstantWithGenericInnerInner
|
||||
{
|
||||
[Kept (By = Tool.Trimmer)]
|
||||
|
@ -156,7 +152,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
|
|||
int unusedField;
|
||||
}
|
||||
|
||||
[Kept (By = Tool.Trimmer)]
|
||||
[Kept]
|
||||
class FromStringConstantWithGenericInnerOne<
|
||||
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
|
||||
[KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute), By = Tool.Trimmer)]
|
||||
|
@ -164,9 +160,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
|
|||
{
|
||||
}
|
||||
|
||||
// https://github.com/dotnet/runtime/issues/72833
|
||||
// NativeAOT doesn't implement full type name parser yet
|
||||
[Kept (By = Tool.Trimmer)]
|
||||
[Kept]
|
||||
class FromStringConstantWithGenericInnerTwo
|
||||
{
|
||||
void UnusedMethod ()
|
||||
|
@ -174,22 +168,14 @@ namespace Mono.Linker.Tests.Cases.DataFlow
|
|||
}
|
||||
}
|
||||
|
||||
// https://github.com/dotnet/runtime/issues/72833
|
||||
// NativeAOT doesn't implement full type name parser yet
|
||||
[Kept (By = Tool.Trimmer)]
|
||||
[Kept]
|
||||
class FromStringConstantWitGenericInnerMultiDimArray
|
||||
{
|
||||
}
|
||||
|
||||
// https://github.com/dotnet/runtime/issues/72833
|
||||
// NativeAOT actually preserves this, but for a slightly wrong reason - it completely ignores the array notations
|
||||
[Kept]
|
||||
[KeptMember (".ctor()", By = Tool.NativeAot)]
|
||||
class FromStringConstantWithMultiDimArray
|
||||
{
|
||||
// https://github.com/dotnet/runtime/issues/72833
|
||||
// NativeAOT actually preserves this, but for a slightly wrong reason - it completely ignores the array notations
|
||||
[Kept (By = Tool.NativeAot)]
|
||||
public void UnusedMethod () { }
|
||||
}
|
||||
|
||||
|
@ -200,6 +186,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow
|
|||
}
|
||||
|
||||
[Kept]
|
||||
[KeptAttributeAttribute(typeof(UnconditionalSuppressMessageAttribute))]
|
||||
[UnconditionalSuppressMessage("test", "IL3050", Justification = "The test applies DAM on System.Array, which contains CreateInstance method which has RDC on it.")]
|
||||
static void TestFromStringConstantWithGeneric ()
|
||||
{
|
||||
RequireCombinationOnString ("Mono.Linker.Tests.Cases.DataFlow.ApplyTypeAnnotations+FromStringConstantWithGeneric`1[[Mono.Linker.Tests.Cases.DataFlow.ApplyTypeAnnotations+FromStringConstantWithGenericInner]]");
|
||||
|
|
|
@ -60,11 +60,10 @@ namespace Mono.Linker.Tests.Cases.DataFlow
|
|||
RequireNothing (type);
|
||||
}
|
||||
|
||||
// NativeAOT doesn't implement this yet: https://github.com/dotnet/runtime/issues/72833
|
||||
[ExpectedWarning ("IL2105",
|
||||
"Type 'System.Invalid.TypeName' was not found in the caller assembly nor in the base library. " +
|
||||
"Type name strings used for dynamically accessing a type should be assembly qualified.",
|
||||
ProducedBy = Tool.Trimmer)]
|
||||
ProducedBy = Tool.Trimmer | Tool.NativeAot)]
|
||||
static void TestUnqualifiedTypeNameWarns ()
|
||||
{
|
||||
RequirePublicConstructors ("System.Invalid.TypeName");
|
||||
|
|
|
@ -191,18 +191,18 @@ namespace Mono.Linker.Tests
|
|||
}
|
||||
|
||||
[DisplayName ("Mono.Linker.Tests.GetDisplayNameTests.MethodWithGenericTypeArgument(IList<GetDisplayNameTests.GenericClassOneParameter<Byte*[]>>)")]
|
||||
public static void MethodWithGenericTypeArgument (IList<GenericClassOneParameter<byte*[]>> p)
|
||||
public static unsafe void MethodWithGenericTypeArgument (IList<GenericClassOneParameter<byte*[]>> p)
|
||||
{
|
||||
}
|
||||
|
||||
[DisplayName ("Mono.Linker.Tests.GetDisplayNameTests.MethodWithGenericTypeArguments(GetDisplayNameTests.GenericClassMultipleParameters<Char*[],Int32[,][]>)")]
|
||||
public static void MethodWithGenericTypeArguments (GenericClassMultipleParameters<char*[], int[,][]> p)
|
||||
public static unsafe void MethodWithGenericTypeArguments (GenericClassMultipleParameters<char*[], int[,][]> p)
|
||||
{
|
||||
}
|
||||
|
||||
[DisplayName ("Mono.Linker.Tests.GetDisplayNameTests.MethodWithNestedGenericTypeArguments" +
|
||||
"(GetDisplayNameTests.GenericClassMultipleParameters<Char*[],Int32[,][]>.NestedGenericClassMultipleParameters<Char*[],Int32[,][]>)")]
|
||||
public static void MethodWithNestedGenericTypeArguments (GenericClassMultipleParameters<char*[], int[,][]>.NestedGenericClassMultipleParameters<char*[], int[,][]> p)
|
||||
public static unsafe void MethodWithNestedGenericTypeArguments (GenericClassMultipleParameters<char*[], int[,][]>.NestedGenericClassMultipleParameters<char*[], int[,][]> p)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue