Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection.Runtime.General;
using System.Reflection.Runtime.TypeInfos;
using System.Reflection.Runtime.TypeInfos.NativeFormat;
Expand Down Expand Up @@ -206,14 +207,8 @@ public Type GetNamedTypeForHandle(RuntimeTypeHandle typeHandle, bool isGenericTy
}
else
{
if (ExecutionEnvironment.IsReflectionBlocked(typeHandle))
{
return RuntimeBlockedTypeInfo.GetRuntimeBlockedTypeInfo(typeHandle, isGenericTypeDefinition);
}
else
{
return RuntimeNoMetadataNamedTypeInfo.GetRuntimeNoMetadataNamedTypeInfo(typeHandle, isGenericTypeDefinition);
}
Debug.Assert(ExecutionEnvironment.IsReflectionBlocked(typeHandle));
return RuntimeBlockedTypeInfo.GetRuntimeBlockedTypeInfo(typeHandle, isGenericTypeDefinition);
}
}

Expand Down Expand Up @@ -285,23 +280,13 @@ public Type GetConstructedGenericTypeForHandle(RuntimeTypeHandle typeHandle)
}

//=======================================================================================
// MissingMetadataExceptions.
// Missing metadata exceptions.
//=======================================================================================
public Exception CreateMissingMetadataException(Type? pertainant)
{
return this.ReflectionDomainSetup.CreateMissingMetadataException(pertainant);
}

public Exception CreateMissingMetadataException(TypeInfo? pertainant)
{
return this.ReflectionDomainSetup.CreateMissingMetadataException(pertainant);
}

public Exception CreateMissingMetadataException(TypeInfo pertainant, string nestedTypeName)
{
return this.ReflectionDomainSetup.CreateMissingMetadataException(pertainant, nestedTypeName);
}

public Exception CreateNonInvokabilityException(MemberInfo pertainant)
{
return this.ReflectionDomainSetup.CreateNonInvokabilityException(pertainant);
Expand Down Expand Up @@ -336,16 +321,13 @@ public bool SupportsReflection(Type type)
if (type is not RuntimeType)
return false;

RuntimeTypeInfo runtimeType = type.CastToRuntimeTypeInfo();
if (null == runtimeType.InternalNameIfAvailable)
return false;

if (ExecutionEnvironment.IsReflectionBlocked(type.TypeHandle))
{
// The type is an internal framework type and is blocked from reflection
return false;
}

RuntimeTypeInfo runtimeType = type.CastToRuntimeTypeInfo();
if (runtimeType.InternalFullNameOfAssembly == Internal.Runtime.Augments.RuntimeAugments.HiddenScopeAssemblyName)
{
// The type is an internal framework type but is reflectable for internal class library use
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ public abstract class ReflectionDomainSetup
{
protected ReflectionDomainSetup() { }
public abstract AssemblyBinder AssemblyBinder { get; }
public abstract Exception CreateMissingMetadataException(TypeInfo? pertainant);
public abstract Exception CreateMissingMetadataException(Type? pertainant);
public abstract Exception CreateMissingMetadataException(TypeInfo pertainant, string nestedTypeName);
public abstract Exception CreateNonInvokabilityException(MemberInfo pertainant);
public abstract Exception CreateMissingArrayTypeException(Type elementType, bool isMultiDim, int rank);
public abstract Exception CreateMissingConstructedGenericTypeException(Type genericTypeDefinition, Type[] genericTypeArguments);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,24 +45,7 @@ public IEnumerable<CustomAttributeData> GetMatchingCustomAttributes(E element, T
optionalAttributeTypeFilter.IsSubclassOf(typeof(Attribute))))
throw new ArgumentException(SR.Argument_MustHaveAttributeBaseClass);

try
{
typeFilterKnownToBeSealed = optionalAttributeTypeFilter.IsSealed;
}
catch (MissingMetadataException)
{
// If we got here, the custom attribute type itself was not opted into metadata. This can and does happen in the real world when an app
// contains a check for custom attributes that never actually appear on any entity within the app.
//
// Since "typeFilterKnownToBeSealed" is only used to enable an optimization, it's always safe to leave it "false".
//
// Because the NativeAOT toolchain removes any custom attribute that refuses to opt into metadata so at this point,
// we could simply return an empty enumeration and "be correct." However, the code paths following this already do that naturally.
// (i.e. the "passFilter" will never return true, thus we will never attempt to query the custom attribute type for its
// own AttributeUsage custom attribute.) If the toolchain behavior changes in the future, it's preferable that
// this shows up as new MissingMetadataExceptions rather than incorrect results from the api so we will not put
// in an explicit return here.
}
typeFilterKnownToBeSealed = optionalAttributeTypeFilter.IsSealed;
}

Func<Type, bool> passesFilter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@ TypesMustExist : Type 'System.MDArray' does not exist in the reference but it do
MembersMustExist : Member 'public void System.ModuleHandle..ctor(System.Reflection.Module)' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'System.RuntimeExceptionHelpers' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'System.RuntimeType' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public System.String System.Type.InternalNameIfAvailable.get()' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public System.Boolean System.TypedReference.IsNull.get()' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'System.Diagnostics.DebugAnnotations' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'System.Diagnostics.DebuggerGuidedStepThroughAttribute' does not exist in the reference but it does exist in the implementation.
Expand All @@ -229,7 +228,6 @@ TypesMustExist : Type 'System.Reflection.DynamicInvokeInfo' does not exist in th
TypesMustExist : Type 'System.Reflection.EnumInfo' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public System.Reflection.ParameterInfo[] System.Reflection.MethodBase.GetParametersNoCopy()' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public System.Reflection.MethodBase System.Reflection.MethodBase.MetadataDefinitionMethod.get()' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'System.Reflection.MissingMetadataException' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'protected System.ModuleHandle System.Reflection.Module.GetModuleHandleImpl()' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'System.Reflection.RuntimeAssembly' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'System.Reflection.RuntimeAssemblyName' does not exist in the reference but it does exist in the implementation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@
<Compile Include="System\MathF.NativeAot.cs" />
<Compile Include="System\MulticastDelegate.cs" />
<Compile Include="System\Object.NativeAot.cs" />
<Compile Include="System\Reflection\MissingMetadataException.cs" />
<Compile Include="System\Resources\ManifestBasedResourceGroveler.NativeAot.cs" />
<Compile Include="System\RuntimeArgumentHandle.cs" />
<Compile Include="System\RuntimeType.cs" />
Expand Down Expand Up @@ -461,7 +460,6 @@
<Compile Include="System\Reflection\Runtime\General\NativeFormat\DefaultValueParser.cs" />
<Compile Include="System\Reflection\Runtime\General\RuntimeTypeHandleKey.cs" />
<Compile Include="System\Reflection\Runtime\General\ThunkedApis.cs" />
<Compile Include="System\Reflection\Runtime\General\ToStringUtils.cs" />
<Compile Include="System\Reflection\Runtime\General\TypeContext.cs" />
<Compile Include="System\Reflection\Runtime\General\TypeForwardInfo.cs" />
<Compile Include="System\Reflection\Runtime\General\TypeResolver.cs" />
Expand Down Expand Up @@ -522,7 +520,6 @@
<Compile Include="System\Reflection\Runtime\TypeInfos\RuntimeHasElementTypeInfo.cs" />
<Compile Include="System\Reflection\Runtime\TypeInfos\RuntimeHasElementTypeInfo.UnificationKey.cs" />
<Compile Include="System\Reflection\Runtime\TypeInfos\RuntimeNamedTypeInfo.cs" />
<Compile Include="System\Reflection\Runtime\TypeInfos\RuntimeNoMetadataNamedTypeInfo.cs" />
<Compile Include="System\Reflection\Runtime\TypeInfos\RuntimePointerTypeInfo.cs" />
<Compile Include="System\Reflection\Runtime\TypeInfos\RuntimeBlockedTypeInfo.cs" />
<Compile Include="System\Reflection\Runtime\TypeInfos\RuntimeTypeDefinitionTypeInfo.cs" />
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,21 @@ private QueriedMemberList()
_allFlagsThatMustMatch = new BindingFlags[Grow];
}

private QueriedMemberList(int totalCount, int declaredOnlyCount, M[] members, BindingFlags[] allFlagsThatMustMatch, RuntimeTypeInfo typeThatBlockedBrowsing)
private QueriedMemberList(int totalCount, int declaredOnlyCount, M[] members, BindingFlags[] allFlagsThatMustMatch)
{
_totalCount = totalCount;
_declaredOnlyCount = declaredOnlyCount;
_members = members;
_allFlagsThatMustMatch = allFlagsThatMustMatch;
_typeThatBlockedBrowsing = typeThatBlockedBrowsing;
}

/// <summary>
/// Returns the # of candidates for a non-DeclaredOnly search. Caution: Can throw MissingMetadataException. Use DeclaredOnlyCount if you don't want to search base classes.
/// Returns the # of candidates for a non-DeclaredOnly search. Use DeclaredOnlyCount if you don't want to search base classes.
/// </summary>
public int TotalCount
{
get
{
if (_typeThatBlockedBrowsing != null)
throw ReflectionCoreExecution.ExecutionDomain.CreateMissingMetadataException(_typeThatBlockedBrowsing);
return _totalCount;
}
}
Expand Down Expand Up @@ -93,7 +90,7 @@ public QueriedMemberList<M> Filter(Func<M, bool> predicate)
}
}

return new QueriedMemberList<M>(newTotalCount, newDeclaredOnlyCount, newMembers, newAllFlagsThatMustMatch, _typeThatBlockedBrowsing);
return new QueriedMemberList<M>(newTotalCount, newDeclaredOnlyCount, newMembers, newAllFlagsThatMustMatch);
}

//
Expand Down Expand Up @@ -151,16 +148,6 @@ public static QueriedMemberList<M> Create(RuntimeTypeInfo type, string optionalN
}

type = type.BaseType.CastToRuntimeTypeInfo();

if (type != null && !type.CanBrowseWithoutMissingMetadataExceptions)
{
// If we got here, one of the base classes is missing metadata. We don't want to throw a MissingMetadataException now because we may be
// building a cached result for a caller who passed BindingFlags.DeclaredOnly. So we'll mark the results in a way that
// it will throw a MissingMetadataException if a caller attempts to iterate past the declared-only subset.
queriedMembers._typeThatBlockedBrowsing = type;
queriedMembers._totalCount = queriedMembers._declaredOnlyCount;
break;
}
}

return queriedMembers;
Expand Down Expand Up @@ -196,7 +183,6 @@ private void Add(M member, BindingFlags allFlagsThatMustMatch)
private int _declaredOnlyCount; // # of entries for members only in the most derived class.
private M[] _members; // Length is equal to or greater than _totalCount. Entries beyond _totalCount contain null or garbage and should be read.
private BindingFlags[] _allFlagsThatMustMatch; // Length will be equal to _members.Length
private RuntimeTypeInfo _typeThatBlockedBrowsing; // If non-null, one of the base classes was missing metadata.

private const int Grow = 64;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,8 @@ public sealed override ConstructorInfo Constructor
}
}

internal sealed override string AttributeTypeString
{
get
{
return new QTypeDefRefOrSpec(_reader, _customAttribute.GetAttributeTypeHandle(_reader)).FormatTypeName(new TypeContext(null, null));
}
}

//
// If throwIfMissingMetadata is false, returns null rather than throwing a MissingMetadataException.
// If throwIfMissingMetadata is false, returns null rather than throwing a missing metadata exception.
//
internal sealed override IList<CustomAttributeTypedArgument> GetConstructorArguments(bool throwIfMissingMetadata)
{
Expand Down Expand Up @@ -158,7 +150,7 @@ internal sealed override IList<CustomAttributeTypedArgument> GetConstructorArgum
}

//
// If throwIfMissingMetadata is false, returns null rather than throwing a MissingMetadataException.
// If throwIfMissingMetadata is false, returns null rather than throwing a missing metadata exception.
//
internal sealed override IList<CustomAttributeNamedArgument> GetNamedArguments(bool throwIfMissingMetadata)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,39 +37,32 @@ public sealed override IList<CustomAttributeNamedArgument> NamedArguments

public sealed override string ToString()
{
try
{
string ctorArgs = "";
IList<CustomAttributeTypedArgument> constructorArguments = GetConstructorArguments(throwIfMissingMetadata: false);
if (constructorArguments == null)
return LastResortToString;
for (int i = 0; i < constructorArguments.Count; i++)
ctorArgs += string.Format(i == 0 ? "{0}" : ", {0}", ComputeTypedArgumentString(constructorArguments[i], typed: false));

string namedArgs = "";
IList<CustomAttributeNamedArgument> namedArguments = GetNamedArguments(throwIfMissingMetadata: false);
if (namedArguments == null)
return LastResortToString;
for (int i = 0; i < namedArguments.Count; i++)
{
CustomAttributeNamedArgument namedArgument = namedArguments[i];

// Legacy: Desktop sets "typed" to "namedArgument.ArgumentType != typeof(Object)" - on Project N, this property is not available
// (nor conveniently computable as it's not captured in the Project N metadata.) The only consequence is that for
// the rare case of fields and properties typed "Object", we won't decorate the argument value with its actual type name.
bool typed = true;
namedArgs += string.Format(
i == 0 && ctorArgs.Length == 0 ? "{0} = {1}" : ", {0} = {1}",
namedArgument.MemberName,
ComputeTypedArgumentString(namedArgument.TypedValue, typed));
}
string ctorArgs = "";
IList<CustomAttributeTypedArgument> constructorArguments = GetConstructorArguments(throwIfMissingMetadata: false);
if (constructorArguments == null)
return LastResortToString;
for (int i = 0; i < constructorArguments.Count; i++)
ctorArgs += string.Format(i == 0 ? "{0}" : ", {0}", ComputeTypedArgumentString(constructorArguments[i], typed: false));

return string.Format("[{0}({1}{2})]", AttributeTypeString, ctorArgs, namedArgs);
}
catch (MissingMetadataException)
{
string namedArgs = "";
IList<CustomAttributeNamedArgument> namedArguments = GetNamedArguments(throwIfMissingMetadata: false);
if (namedArguments == null)
return LastResortToString;
for (int i = 0; i < namedArguments.Count; i++)
{
CustomAttributeNamedArgument namedArgument = namedArguments[i];

// Legacy: Desktop sets "typed" to "namedArgument.ArgumentType != typeof(Object)" - on Project N, this property is not available
// (nor conveniently computable as it's not captured in the Project N metadata.) The only consequence is that for
// the rare case of fields and properties typed "Object", we won't decorate the argument value with its actual type name.
bool typed = true;
namedArgs += string.Format(
i == 0 && ctorArgs.Length == 0 ? "{0} = {1}" : ", {0} = {1}",
namedArgument.MemberName,
ComputeTypedArgumentString(namedArgument.TypedValue, typed));
}

return string.Format("[{0}({1}{2})]", AttributeType.FormatTypeNameForReflection(), ctorArgs, namedArgs);
}

protected static ConstructorInfo ResolveAttributeConstructor(
Expand All @@ -95,15 +88,13 @@ protected static ConstructorInfo ResolveAttributeConstructor(
throw new MissingMethodException();
}

internal abstract string AttributeTypeString { get; }

//
// If throwIfMissingMetadata is false, returns null rather than throwing a MissingMetadataException.
// If throwIfMissingMetadata is false, returns null rather than throwing a missing metadata exception.
//
internal abstract IList<CustomAttributeTypedArgument> GetConstructorArguments(bool throwIfMissingMetadata);

//
// If throwIfMissingMetadata is false, returns null rather than throwing a MissingMetadataException.
// If throwIfMissingMetadata is false, returns null rather than throwing a missing metadata exception.
//
internal abstract IList<CustomAttributeNamedArgument> GetNamedArguments(bool throwIfMissingMetadata);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,6 @@ public sealed override ConstructorInfo Constructor
}
}

internal sealed override string AttributeTypeString
{
get
{
return _attributeType.FormatTypeNameForReflection();
}
}

internal sealed override IList<CustomAttributeTypedArgument> GetConstructorArguments(bool throwIfMissingMetadata)
{
return _constructorArguments;
Expand Down
Loading