Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Annotate more of CoreLib for trimming #38265

Merged
merged 5 commits into from
Jun 24, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ public static partial class Activator

[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern",
Justification = "Implementation detail of Activator that linker intrinsically recognizes")]
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:UnrecognizedReflectionPattern",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are IL2006 and IL2026 both UnrecognizedReflectionPattern ? Shouldn't different warning numbers have different titles/names?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mateoatr to comment on the second parameter values...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anything that is put after the colon in the CheckId parameter is used only for documentation purposes (this is, the warning suppression mechanism completely ignores what the user puts after the colon, it only cares for the four numbers of the warning id).
We sometimes put a subcategory on the warnings to further categorize them, although this specific warning does not have the UnrecognizedReflectionPattern subcategory, I don't know if we should add it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is super confusing as a reader to see 2 warning numbers with the same string. What is the title of IL2026? RequiresUnreferencedCode? We should update it here so this doesn't look like duplicated attributes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to RequiresUnreferencedCode.

Justification = "Implementation detail of Activator that linker intrinsically recognizes")]
private static ObjectHandle? CreateInstanceInternal(string assemblyString,
string typeName,
bool ignoreCase,
Expand Down Expand Up @@ -143,7 +145,7 @@ public static partial class Activator
}

[System.Runtime.CompilerServices.Intrinsic]
public static T CreateInstance<T>()
public static T CreateInstance<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T>()
{
return (T)((RuntimeType)typeof(T)).CreateInstanceDefaultCtor(publicOnly: true, skipCheckThis: true, fillCache: true, wrapExceptions: true)!;
}
Expand Down
4 changes: 2 additions & 2 deletions src/libraries/System.Private.CoreLib/src/System/Lazy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ internal static LazyHelper Create(LazyThreadSafetyMode mode, bool useDefaultCons
}
}

internal static T CreateViaDefaultConstructor<T>()
internal static T CreateViaDefaultConstructor<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T>()
{
try
{
Expand Down Expand Up @@ -184,7 +184,7 @@ internal static LazyThreadSafetyMode GetModeFromIsThreadSafe(bool isThreadSafe)
/// </remarks>
[DebuggerTypeProxy(typeof(LazyDebugView<>))]
[DebuggerDisplay("ThreadSafetyMode={Mode}, IsValueCreated={IsValueCreated}, IsValueFaulted={IsValueFaulted}, Value={ValueForDebugDisplay}")]
public class Lazy<T>
public class Lazy<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T>
{
private static T CreateViaDefaultConstructor() => LazyHelper.CreateViaDefaultConstructor<T>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Diagnostics.CodeAnalysis;
using System.Threading;

namespace System
{
public class Lazy<T, TMetadata> : Lazy<T>
public class Lazy<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T, TMetadata> : Lazy<T>
{
private readonly TMetadata _metadata;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ protected Assembly() { }

public virtual IEnumerable<TypeInfo> DefinedTypes
{
[RequiresUnreferencedCode("Types might be removed")]
get
{
Type[] types = GetTypes();
Expand All @@ -41,6 +42,7 @@ public virtual IEnumerable<TypeInfo> DefinedTypes
}
}

[RequiresUnreferencedCode("Types might be removed")]
public virtual Type[] GetTypes()
{
Module[] m = GetModules(false);
Expand Down Expand Up @@ -70,8 +72,14 @@ public virtual Type[] GetTypes()
return ret;
}

public virtual IEnumerable<Type> ExportedTypes => GetExportedTypes();
public virtual IEnumerable<Type> ExportedTypes
{
[RequiresUnreferencedCode("Types might be removed")]
get => GetExportedTypes();
}
[RequiresUnreferencedCode("Types might be removed")]
public virtual Type[] GetExportedTypes() { throw NotImplemented.ByDesign; }
[RequiresUnreferencedCode("Types might be removed")]
public virtual Type[] GetForwardedTypes() { throw NotImplemented.ByDesign; }

public virtual string? CodeBase => throw NotImplemented.ByDesign;
Expand All @@ -93,8 +101,11 @@ public virtual Type[] GetTypes()
public virtual AssemblyName GetName() => GetName(copiedName: false);
public virtual AssemblyName GetName(bool copiedName) { throw NotImplemented.ByDesign; }

[RequiresUnreferencedCode("Types might be removed")]
public virtual Type? GetType(string name) => GetType(name, throwOnError: false, ignoreCase: false);
[RequiresUnreferencedCode("Types might be removed")]
public virtual Type? GetType(string name, bool throwOnError) => GetType(name, throwOnError: throwOnError, ignoreCase: false);
[RequiresUnreferencedCode("Types might be removed")]
public virtual Type? GetType(string name, bool throwOnError, bool ignoreCase) { throw NotImplemented.ByDesign; }

public virtual bool IsDefined(Type attributeType, bool inherit) { throw NotImplemented.ByDesign; }
Expand Down Expand Up @@ -135,6 +146,7 @@ public virtual Type[] GetTypes()
public Module[] GetLoadedModules() => GetLoadedModules(getResourceModules: false);
public virtual Module[] GetLoadedModules(bool getResourceModules) { throw NotImplemented.ByDesign; }

[RequiresUnreferencedCode("Assembly references might be removed")]
public virtual AssemblyName[] GetReferencedAssemblies() { throw NotImplemented.ByDesign; }

public virtual Assembly GetSatelliteAssembly(CultureInfo culture) { throw NotImplemented.ByDesign; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.

using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Tracing;
using System.Reflection;
using System.Threading;
Expand Down Expand Up @@ -92,6 +93,8 @@ internal static bool TrackAsyncMethodCompletion
/// <summary>Gets a description of the state of the state machine object, suitable for debug purposes.</summary>
/// <param name="stateMachine">The state machine object.</param>
/// <returns>A description of the state machine.</returns>
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we close #32921 with this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup

Justification = "It's okay if unused fields disappear from debug views")]
internal static string GetAsyncStateMachineDescription(IAsyncStateMachine stateMachine)
{
Debug.Assert(stateMachine != null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace System.Runtime.CompilerServices
{
public sealed class ConditionalWeakTable<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
public sealed class ConditionalWeakTable<TKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
where TKey : class
where TValue : class?
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ public static void PtrToStructure<T>(IntPtr ptr, [DisallowNull] T structure)
}

[return: MaybeNull]
public static T PtrToStructure<T>(IntPtr ptr) => (T)PtrToStructure(ptr, typeof(T))!;
public static T PtrToStructure<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T>(IntPtr ptr) => (T)PtrToStructure(ptr, typeof(T))!;

public static void DestroyStructure<T>(IntPtr ptr) => DestroyStructure(ptr, typeof(T));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,8 @@ private static void OnAssemblyLoad(RuntimeAssembly assembly)
}
#endif // !CORERT

[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:UnrecognizedReflectionPattern",
Justification = "Satellite assemblies have no code in them and loading is not a problem")]
private Assembly? ResolveSatelliteAssembly(AssemblyName assemblyName)
{
// Called by native runtime when CultureName is not empty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public override IList<CustomAttributeData> GetCustomAttributesData()

// GetDefaultMembers
// This will return a MemberInfo that has been marked with the [DefaultMemberAttribute]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why All? The doc says it can be only constructor, method, property, or field and I think they have to be public

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doc says it can be only constructor, method, property, or field and I think they have to be public

Couldn't find that mention in the doc - the impl also works for events and nested types. It's a janky API.

It was forced by the annotation on GetMember. I've fixed that up.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the attribute have any effect here when the type is sealed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The attribute is on the "this" - which is a special case - it annotates the type this RuntimeType represents. So for example calling typeof<MyType>.GetDefaultMembers() would end up (due to this attribute) marking the entire MyType.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure but as this is C# code there won't be any call (IL reference) to this method

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that the same annotation is on Type.GetDefaultMembers() - the current data flow implementation in the linker assumes that the entire inheritance hierarchy for a given method has the same annotations (We're missing the validation in the linker for now dotnet/linker#1028).

Other than the above rule, this also means that when analyzing the method body of this method the linker can make assumptions about the this and won't generate warnings...

public override MemberInfo[] GetDefaultMembers()
{
// See if we have cached the default member name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public static class LazyInitializer
/// if an object was not used and to then dispose of the object appropriately.
/// </para>
/// </remarks>
public static T EnsureInitialized<T>([NotNull] ref T? target) where T : class =>
public static T EnsureInitialized<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T>([NotNull] ref T? target) where T : class =>
Volatile.Read(ref target!) ?? EnsureInitializedCore(ref target);

/// <summary>
Expand All @@ -57,7 +57,7 @@ public static T EnsureInitialized<T>([NotNull] ref T? target) where T : class =>
/// <typeparam name="T">The reference type of the reference to be initialized.</typeparam>
/// <param name="target">The variable that need to be initialized</param>
/// <returns>The initialized variable</returns>
private static T EnsureInitializedCore<T>([NotNull] ref T? target) where T : class
private static T EnsureInitializedCore<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T>([NotNull] ref T? target) where T : class
{
try
{
Expand Down Expand Up @@ -136,7 +136,7 @@ private static T EnsureInitializedCore<T>([NotNull] ref T? target, Func<T> value
/// <paramref name="target"/>. If <paramref name="syncLock"/> is null, and if the target hasn't already
/// been initialized, a new object will be instantiated.</param>
/// <returns>The initialized value of type <typeparamref name="T"/>.</returns>
public static T EnsureInitialized<T>([AllowNull] ref T target, ref bool initialized, [NotNullIfNotNull("syncLock")] ref object? syncLock)
public static T EnsureInitialized<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T>([AllowNull] ref T target, ref bool initialized, [NotNullIfNotNull("syncLock")] ref object? syncLock)
{
// Fast path.
if (Volatile.Read(ref initialized))
Expand All @@ -158,7 +158,7 @@ public static T EnsureInitialized<T>([AllowNull] ref T target, ref bool initiali
/// a new object will be instantiated.
/// </param>
/// <returns>The initialized object.</returns>
private static T EnsureInitializedCore<T>([AllowNull] ref T target, ref bool initialized, [NotNull] ref object? syncLock)
private static T EnsureInitializedCore<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]T>([AllowNull] ref T target, ref bool initialized, [NotNull] ref object? syncLock)
{
// Lazily initialize the lock if necessary and then double check if initialization is still required.
lock (EnsureLockInitialized(ref syncLock))
Expand Down
1 change: 1 addition & 0 deletions src/libraries/System.Private.CoreLib/src/System/Type.cs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ public ConstructorInfo? TypeInitializer
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
public abstract PropertyInfo[] GetProperties(BindingFlags bindingAttr);

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why All (that includes NestedTypes as well) ? The doc says it can be only constructor, method, property, or field and I think they have to be public

public virtual MemberInfo[] GetDefaultMembers() => throw NotImplemented.ByDesign;

public virtual RuntimeTypeHandle TypeHandle => throw new NotSupportedException();
Expand Down
12 changes: 10 additions & 2 deletions src/libraries/System.Runtime/ref/System.Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4125,6 +4125,7 @@ protected Type() { }
public System.Reflection.ConstructorInfo[] GetConstructors() { throw null; }
[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)]
public abstract System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr);
[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)]
public virtual System.Reflection.MemberInfo[] GetDefaultMembers() { throw null; }
public abstract System.Type? GetElementType();
public virtual string? GetEnumName(object value) { throw null; }
Expand Down Expand Up @@ -7499,10 +7500,10 @@ public abstract partial class Assembly : System.Reflection.ICustomAttributeProvi
protected Assembly() { }
public virtual string? CodeBase { get { throw null; } }
public virtual System.Collections.Generic.IEnumerable<System.Reflection.CustomAttributeData> CustomAttributes { get { throw null; } }
public virtual System.Collections.Generic.IEnumerable<System.Reflection.TypeInfo> DefinedTypes { get { throw null; } }
public virtual System.Collections.Generic.IEnumerable<System.Reflection.TypeInfo> DefinedTypes { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] get { throw null; } }
public virtual System.Reflection.MethodInfo? EntryPoint { get { throw null; } }
public virtual string EscapedCodeBase { get { throw null; } }
public virtual System.Collections.Generic.IEnumerable<System.Type> ExportedTypes { get { throw null; } }
public virtual System.Collections.Generic.IEnumerable<System.Type> ExportedTypes { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] get { throw null; } }
public virtual string? FullName { get { throw null; } }
public virtual bool GlobalAssemblyCache { get { throw null; } }
public virtual long HostContext { get { throw null; } }
Expand Down Expand Up @@ -7531,10 +7532,12 @@ public virtual event System.Reflection.ModuleResolveEventHandler? ModuleResolve
public virtual System.Collections.Generic.IList<System.Reflection.CustomAttributeData> GetCustomAttributesData() { throw null; }
public static System.Reflection.Assembly? GetEntryAssembly() { throw null; }
public static System.Reflection.Assembly GetExecutingAssembly() { throw null; }
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")]
public virtual System.Type[] GetExportedTypes() { throw null; }
public virtual System.IO.FileStream? GetFile(string name) { throw null; }
public virtual System.IO.FileStream[] GetFiles() { throw null; }
public virtual System.IO.FileStream[] GetFiles(bool getResourceModules) { throw null; }
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")]
public virtual System.Type[] GetForwardedTypes() { throw null; }
public override int GetHashCode() { throw null; }
public System.Reflection.Module[] GetLoadedModules() { throw null; }
Expand All @@ -7549,12 +7552,17 @@ public virtual event System.Reflection.ModuleResolveEventHandler? ModuleResolve
public virtual System.Reflection.AssemblyName GetName() { throw null; }
public virtual System.Reflection.AssemblyName GetName(bool copiedName) { throw null; }
public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Assembly references might be removed")]
public virtual System.Reflection.AssemblyName[] GetReferencedAssemblies() { throw null; }
public virtual System.Reflection.Assembly GetSatelliteAssembly(System.Globalization.CultureInfo culture) { throw null; }
public virtual System.Reflection.Assembly GetSatelliteAssembly(System.Globalization.CultureInfo culture, System.Version? version) { throw null; }
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")]
public virtual System.Type? GetType(string name) { throw null; }
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")]
public virtual System.Type? GetType(string name, bool throwOnError) { throw null; }
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")]
public virtual System.Type? GetType(string name, bool throwOnError, bool ignoreCase) { throw null; }
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")]
public virtual System.Type[] GetTypes() { throw null; }
public virtual bool IsDefined(System.Type attributeType, bool inherit) { throw null; }
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types and members the loaded assembly depends on might be removed")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

using System.Diagnostics.CodeAnalysis;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -106,6 +107,7 @@ bool IsResource()
return is_resource;
}

[RequiresUnreferencedCode("Types might be removed")]
public override
Type[] FindTypes(TypeFilter? filter, object? filterCriteria)
{
Expand All @@ -128,6 +130,7 @@ object[] GetCustomAttributes(Type attributeType, bool inherit)
return CustomAttribute.GetCustomAttributes(this, attributeType, inherit);
}

[RequiresUnreferencedCode("Fields might be removed")]
public override
FieldInfo? GetField(string name, BindingFlags bindingAttr)
{
Expand All @@ -141,6 +144,7 @@ public override
return globalType?.GetField(name, bindingAttr);
}

[RequiresUnreferencedCode("Fields might be removed")]
public override
FieldInfo[] GetFields(BindingFlags bindingFlags)
{
Expand All @@ -160,6 +164,7 @@ int MetadataToken
}
}

[RequiresUnreferencedCode("Methods might be removed")]
protected
override
MethodInfo? GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers)
Expand All @@ -175,6 +180,7 @@ int MetadataToken
return globalType.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers);
}

[RequiresUnreferencedCode("Methods might be removed")]
public
override
MethodInfo[] GetMethods(BindingFlags bindingFlags)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ public void Add(T item)

#region Internal

[RequiresUnreferencedCode("Types might be removed")]
internal static RuntimeType? GetType(string typeName, bool throwOnError, bool ignoreCase, bool reflectionOnly,
ref StackCrawlMark stackMark)
{
Expand Down Expand Up @@ -800,11 +801,13 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr)

#endregion

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
protected override MethodInfo? GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers)
{
return GetMethodImpl(name, -1, bindingAttr, binder, callConvention, types, modifiers);
}

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
protected override MethodInfo? GetMethodImpl(string name, int genericParamCount,
BindingFlags bindingAttr, Binder? binder, CallingConventions callConv,
Type[]? types, ParameterModifier[]? modifiers)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ internal static bool IsTypeDefinition(RuntimeType type)
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern RuntimeType internal_from_name(string name, ref StackCrawlMark stackMark, Assembly? callerAssembly, bool throwOnError, bool ignoreCase, bool reflectionOnly);

[RequiresUnreferencedCode("Types might be removed")]
internal static RuntimeType? GetTypeByName(string typeName, bool throwOnError, bool ignoreCase, bool reflectionOnly, ref StackCrawlMark stackMark,
bool loadTypeFromPartialName)
{
Expand Down
Loading