Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -469,10 +469,6 @@
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Internal.Metadata.NativeFormat.NamespaceDefinitionHandle</Target>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Internal.Metadata.NativeFormat.NamespaceDefinitionHandleCollection</Target>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Internal.Metadata.NativeFormat.NamespaceReference</Target>
Expand Down Expand Up @@ -597,6 +593,10 @@
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Internal.Metadata.NativeFormat.TypeDefinitionHandleCollection</Target>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Internal.Metadata.NativeFormat.TypeDefinitionHandleHashtable</Target>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Internal.Metadata.NativeFormat.TypeForwarder</Target>
Expand All @@ -609,6 +609,10 @@
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Internal.Metadata.NativeFormat.TypeForwarderHandleCollection</Target>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Internal.Metadata.NativeFormat.TypeForwarderHandleHashtable</Target>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Internal.Metadata.NativeFormat.TypeInstantiationSignature</Target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@

<!-- Sources -->
<ItemGroup>
<Compile Include="$(CommonPath)Internal\VersionResilientHashCode.cs">
<Link>Common\Internal\VersionResilientHashCode.cs</Link>
</Compile>
<Compile Include="$(CompilerCommonPath)\Internal\Runtime\DehydratedData.cs">
<Link>Internal\Runtime\DehydratedData.cs</Link>
</Compile>
Expand Down Expand Up @@ -416,7 +419,6 @@
<Compile Include="System\Reflection\Runtime\General\IRuntimeMemberInfoWithNoMetadataDefinition.cs" />
<Compile Include="System\Reflection\Runtime\General\MetadataReaderExtensions.cs" />
<Compile Include="System\Reflection\Runtime\General\MetadataReaderExtensions.NativeFormat.cs" />
<Compile Include="System\Reflection\Runtime\General\NamespaceChain.cs" />
<Compile Include="System\Reflection\Runtime\General\NativeFormat\DefaultValueParser.cs" />
<Compile Include="System\Reflection\Runtime\General\ThunkedApis.cs" />
<Compile Include="System\Reflection\Runtime\General\TypeContext.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ internal sealed override RuntimeTypeInfo GetTypeCoreCaseInsensitive(string fullN
case HandleType.TypeForwarder:
{
TypeForwarder typeForwarder = typeDefOrForwarderHandle.ToTypeForwarderHandle(reader).GetTypeForwarder(reader);
ScopeReferenceHandle destinationScope = typeForwarder.Scope;
ScopeReferenceHandle destinationScope = typeForwarder.Namespace.GetNamespaceReference(reader).Scope;
RuntimeAssemblyName destinationAssemblyName = destinationScope.ToRuntimeAssemblyName(reader);
RuntimeAssemblyInfo destinationAssembly = RuntimeAssemblyInfo.GetRuntimeAssemblyIfExists(destinationAssemblyName);
if (destinationAssembly == null)
Expand Down Expand Up @@ -74,32 +74,27 @@ private LowLevelDictionary<string, QHandle> CreateCaseInsensitiveTypeDictionary(

MetadataReader reader = Scope.Reader;
ScopeDefinition scopeDefinition = Scope.ScopeDefinition;
IEnumerable<NamespaceDefinitionHandle> topLevelNamespaceHandles = new NamespaceDefinitionHandle[] { scopeDefinition.RootNamespaceDefinition };
IEnumerable<NamespaceDefinitionHandle> allNamespaceHandles = reader.GetTransitiveNamespaces(topLevelNamespaceHandles);
foreach (NamespaceDefinitionHandle namespaceHandle in allNamespaceHandles)
foreach (TypeDefinitionHandle typeDefinitionHandle in scopeDefinition.TypeDefinitions)
{
TypeDefinition typeDefinition = typeDefinitionHandle.GetTypeDefinition(reader);
NamespaceDefinitionHandle namespaceHandle = typeDefinition.NamespaceOrEnclosingType.ToNamespaceDefinitionHandle(reader);
string ns = namespaceHandle.ToNamespaceName(reader);
if (ns.Length != 0)
ns += ".";
ns = ns.ToLowerInvariant();

NamespaceDefinition namespaceDefinition = namespaceHandle.GetNamespaceDefinition(reader);
foreach (TypeDefinitionHandle typeDefinitionHandle in namespaceDefinition.TypeDefinitions)
string fullName = (ns + typeDefinition.Name.GetString(reader)).ToLowerInvariant();
if (!dict.TryGetValue(fullName, out _))
{
string fullName = ns + typeDefinitionHandle.GetTypeDefinition(reader).Name.GetString(reader).ToLowerInvariant();
if (!dict.TryGetValue(fullName, out _))
{
dict.Add(fullName, new QHandle(reader, typeDefinitionHandle));
}
dict.Add(fullName, new QHandle(reader, typeDefinitionHandle));
}
}

foreach (TypeForwarderHandle typeForwarderHandle in namespaceDefinition.TypeForwarders)
foreach (TypeForwarderHandle typeForwarderHandle in scopeDefinition.TypeForwarders)
{
TypeForwarder typeForwarder = typeForwarderHandle.GetTypeForwarder(reader);
string fullName = typeForwarder.Namespace.ToFullyQualifiedTypeName(typeForwarder.Name.GetString(reader), reader).ToLowerInvariant();
if (!dict.TryGetValue(fullName, out _))
{
string fullName = ns + typeForwarderHandle.GetTypeForwarder(reader).Name.GetString(reader).ToLowerInvariant();
if (!dict.TryGetValue(fullName, out _))
{
dict.Add(fullName, new QHandle(reader, typeForwarderHandle));
}
dict.Add(fullName, new QHandle(reader, typeForwarderHandle));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Reflection.Runtime.General;
using System.Reflection.Runtime.TypeInfos;

using Internal;
using Internal.Metadata.NativeFormat;
using Internal.Reflection.Core;

Expand All @@ -14,76 +15,50 @@ internal partial class NativeFormatRuntimeAssembly
{
internal sealed override RuntimeTypeInfo UncachedGetTypeCoreCaseSensitive(string fullName)
{
string[] parts = fullName.Split('.');
int numNamespaceParts = parts.Length - 1;
string[] namespaceParts = new string[numNamespaceParts];
for (int i = 0; i < numNamespaceParts; i++)
namespaceParts[numNamespaceParts - i - 1] = parts[i];
string name = parts[numNamespaceParts];
int separator = fullName.LastIndexOf('.');
ReadOnlySpan<char> namespaceName = separator < 0 ? default : fullName.AsSpan(0, separator);
ReadOnlySpan<char> name = fullName.AsSpan(separator + 1);
int hashCode = VersionResilientHashCode.NameHashCode(
VersionResilientHashCode.NameHashCode(namespaceName),
VersionResilientHashCode.NameHashCode(name));

MetadataReader reader = Scope.Reader;
ScopeDefinitionHandle scopeDefinitionHandle = Scope.Handle;
ScopeDefinition scopeDefinition = Scope.ScopeDefinition;

NamespaceDefinition namespaceDefinition;
if (TryResolveNamespaceDefinitionCaseSensitive(reader, namespaceParts, scopeDefinitionHandle, out namespaceDefinition))
foreach (TypeDefinitionHandle candidateType in scopeDefinition.TypeDefinitions.Lookup(hashCode))
{
// We've successfully drilled down the namespace chain. Now look for a top-level type matching the type name.
TypeDefinitionHandleCollection candidateTypes = namespaceDefinition.TypeDefinitions;
foreach (TypeDefinitionHandle candidateType in candidateTypes)
TypeDefinition typeDefinition = candidateType.GetTypeDefinition(reader);
if (typeDefinition.Name.StringEquals(name, reader))
{
TypeDefinition typeDefinition = candidateType.GetTypeDefinition(reader);
if (typeDefinition.Name.StringEquals(name, reader))
NamespaceDefinition namespaceDefinition = typeDefinition.NamespaceOrEnclosingType.ToNamespaceDefinitionHandle(reader).GetNamespaceDefinition(reader);
if (namespaceDefinition.Name.IsNil != (separator < 0))
continue;
if (separator < 0 || namespaceDefinition.Name.StringEquals(namespaceName, reader))
return candidateType.ResolveTypeDefinition(reader);
}

// No match found in this assembly - see if there's a matching type forwarder.
TypeForwarderHandleCollection candidateTypeForwarders = namespaceDefinition.TypeForwarders;
foreach (TypeForwarderHandle typeForwarderHandle in candidateTypeForwarders)
{
TypeForwarder typeForwarder = typeForwarderHandle.GetTypeForwarder(reader);
if (typeForwarder.Name.StringEquals(name, reader))
{
RuntimeAssemblyName redirectedAssemblyName = typeForwarder.Scope.ToRuntimeAssemblyName(reader);
RuntimeAssemblyInfo redirectedAssembly = RuntimeAssemblyInfo.GetRuntimeAssemblyIfExists(redirectedAssemblyName);
if (redirectedAssembly == null)
return null;
return redirectedAssembly.GetTypeCoreCaseSensitive(fullName);
}
}
}

return null;
}

private static bool TryResolveNamespaceDefinitionCaseSensitive(MetadataReader reader, string[] namespaceParts, ScopeDefinitionHandle scopeDefinitionHandle, out NamespaceDefinition namespaceDefinition)
{
namespaceDefinition = scopeDefinitionHandle.GetScopeDefinition(reader).RootNamespaceDefinition.GetNamespaceDefinition(reader);
NamespaceDefinitionHandleCollection candidates = namespaceDefinition.NamespaceDefinitions;
int idx = namespaceParts.Length;
while (idx-- != 0)
// No match found in this assembly - see if there's a matching type forwarder.
foreach (TypeForwarderHandle typeForwarderHandle in scopeDefinition.TypeForwarders.Lookup(hashCode))
{
// Each iteration finds a match for one segment of the namespace chain.
string expected = namespaceParts[idx];
bool foundMatch = false;
foreach (NamespaceDefinitionHandle candidate in candidates)
TypeForwarder typeForwarder = typeForwarderHandle.GetTypeForwarder(reader);
if (typeForwarder.Name.StringEquals(name, reader))
{
namespaceDefinition = candidate.GetNamespaceDefinition(reader);
if (namespaceDefinition.Name.StringOrNullEquals(expected, reader))
{
// Found a match for this segment of the namespace chain. Move on to the next level.
foundMatch = true;
candidates = namespaceDefinition.NamespaceDefinitions;
break;
}
}
NamespaceReference namespaceReference = typeForwarder.Namespace.GetNamespaceReference(reader);
if (namespaceReference.Name.IsNil != (separator < 0))
continue;
if (separator >= 0 && !namespaceReference.Name.StringEquals(namespaceName, reader))
continue;

if (!foundMatch)
{
return false;
RuntimeAssemblyName redirectedAssemblyName = namespaceReference.Scope.ToRuntimeAssemblyName(reader);
RuntimeAssemblyInfo redirectedAssembly = RuntimeAssemblyInfo.GetRuntimeAssemblyIfExists(redirectedAssemblyName);
if (redirectedAssembly is null)
return null;
return redirectedAssembly.GetTypeCoreCaseSensitive(fullName);
}
}

return true;
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,7 @@ public sealed override IEnumerable<TypeInfo> DefinedTypes
get
{
MetadataReader reader = Scope.Reader;
ScopeDefinition scopeDefinition = Scope.ScopeDefinition;
IEnumerable<NamespaceDefinitionHandle> topLevelNamespaceHandles = new NamespaceDefinitionHandle[] { scopeDefinition.RootNamespaceDefinition };
IEnumerable<NamespaceDefinitionHandle> allNamespaceHandles = reader.GetTransitiveNamespaces(topLevelNamespaceHandles);
IEnumerable<TypeDefinitionHandle> allTopLevelTypes = reader.GetTopLevelTypes(allNamespaceHandles);
IEnumerable<TypeDefinitionHandle> allTopLevelTypes = Scope.ScopeDefinition.TypeDefinitions.AsEnumerable();
IEnumerable<TypeDefinitionHandle> allTypes = reader.GetTransitiveTypes(allTopLevelTypes, publicOnly: false);
foreach (TypeDefinitionHandle typeDefinitionHandle in allTypes)
yield return (TypeInfo)typeDefinitionHandle.GetNamedType(reader).ToType();
Expand All @@ -50,10 +47,7 @@ public sealed override IEnumerable<Type> ExportedTypes
get
{
MetadataReader reader = Scope.Reader;
ScopeDefinition scopeDefinition = Scope.ScopeDefinition;
IEnumerable<NamespaceDefinitionHandle> topLevelNamespaceHandles = new NamespaceDefinitionHandle[] { scopeDefinition.RootNamespaceDefinition };
IEnumerable<NamespaceDefinitionHandle> allNamespaceHandles = reader.GetTransitiveNamespaces(topLevelNamespaceHandles);
IEnumerable<TypeDefinitionHandle> allTopLevelTypes = reader.GetTopLevelTypes(allNamespaceHandles);
IEnumerable<TypeDefinitionHandle> allTopLevelTypes = Scope.ScopeDefinition.TypeDefinitions.AsEnumerable();
IEnumerable<TypeDefinitionHandle> allTypes = reader.GetTransitiveTypes(allTopLevelTypes, publicOnly: true);
foreach (TypeDefinitionHandle typeDefinitionHandle in allTypes)
yield return typeDefinitionHandle.ResolveTypeDefinition(reader).ToType();
Expand Down Expand Up @@ -85,22 +79,15 @@ protected sealed override IEnumerable<TypeForwardInfo> TypeForwardInfos
get
{
MetadataReader reader = Scope.Reader;
ScopeDefinition scopeDefinition = Scope.ScopeDefinition;
IEnumerable<NamespaceDefinitionHandle> topLevelNamespaceHandles = new NamespaceDefinitionHandle[] { scopeDefinition.RootNamespaceDefinition };
IEnumerable<NamespaceDefinitionHandle> allNamespaceHandles = reader.GetTransitiveNamespaces(topLevelNamespaceHandles);
foreach (NamespaceDefinitionHandle namespaceHandle in allNamespaceHandles)
foreach (TypeForwarderHandle typeForwarderHandle in Scope.ScopeDefinition.TypeForwarders)
{
string? namespaceName = null;
foreach (TypeForwarderHandle typeForwarderHandle in namespaceHandle.GetNamespaceDefinition(reader).TypeForwarders)
{
namespaceName ??= namespaceHandle.ToNamespaceName(reader);
TypeForwarder typeForwarder = typeForwarderHandle.GetTypeForwarder(reader);
NamespaceReference namespaceReference = typeForwarder.Namespace.GetNamespaceReference(reader);
string namespaceName = namespaceReference.Name.GetStringOrNull(reader) ?? string.Empty;
string typeName = typeForwarder.Name.GetString(reader);
RuntimeAssemblyName redirectedAssemblyName = namespaceReference.Scope.ToRuntimeAssemblyName(reader);

TypeForwarder typeForwarder = typeForwarderHandle.GetTypeForwarder(reader);
string typeName = typeForwarder.Name.GetString(reader);
RuntimeAssemblyName redirectedAssemblyName = typeForwarder.Scope.ToRuntimeAssemblyName(reader);

yield return new TypeForwardInfo(redirectedAssemblyName, namespaceName, typeName);
}
yield return new TypeForwardInfo(redirectedAssemblyName, namespaceName, typeName);
}
}
}
Expand Down
Loading