Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAtsushi Kanamori <AtsushiKan@users.noreply.github.com>2017-06-22 23:43:22 +0300
committerGitHub <noreply@github.com>2017-06-22 23:43:22 +0300
commit919f5ed26ad78940d126d25368d036e6cdb44f00 (patch)
tree2dbc3592a4ccf8f136d05558311c0b1d0aef0a5a /src/System.Private.Reflection.Core
parent6b34633f22161063a311605d830742363f105926 (diff)
Implement Assembly.GetForwardedTypes() on CoreRT/ProjectN (#3967)
See https://github.com/dotnet/corefx/issues/19789 for specifications.
Diffstat (limited to 'src/System.Private.Reflection.Core')
-rw-r--r--src/System.Private.Reflection.Core/src/System.Private.Reflection.Core.csproj1
-rw-r--r--src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/EcmaFormat/EcmaFormatRuntimeAssembly.cs24
-rw-r--r--src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.cs31
-rw-r--r--src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/RuntimeAssembly.cs63
-rw-r--r--src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeForwardInfo.cs26
5 files changed, 145 insertions, 0 deletions
diff --git a/src/System.Private.Reflection.Core/src/System.Private.Reflection.Core.csproj b/src/System.Private.Reflection.Core/src/System.Private.Reflection.Core.csproj
index 30f3206ea..8e87be884 100644
--- a/src/System.Private.Reflection.Core/src/System.Private.Reflection.Core.csproj
+++ b/src/System.Private.Reflection.Core/src/System.Private.Reflection.Core.csproj
@@ -124,6 +124,7 @@
<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" />
<Compile Include="System\Reflection\Runtime\General\TypeResolver.NativeFormat.cs" />
<Compile Include="System\Reflection\Runtime\General\TypeUnifier.cs" />
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/EcmaFormat/EcmaFormatRuntimeAssembly.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/EcmaFormat/EcmaFormatRuntimeAssembly.cs
index 1885a7731..0b27a36d4 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/EcmaFormat/EcmaFormatRuntimeAssembly.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/EcmaFormat/EcmaFormatRuntimeAssembly.cs
@@ -96,6 +96,30 @@ namespace System.Reflection.Runtime.Assemblies.EcmaFormat
}
}
+ protected sealed override IEnumerable<TypeForwardInfo> TypeForwardInfos
+ {
+ get
+ {
+ MetadataReader reader = MetadataReader;
+ foreach (ExportedTypeHandle exportedTypeHandle in reader.ExportedTypes)
+ {
+ ExportedType exportedType = reader.GetExportedType(exportedTypeHandle);
+ if (!exportedType.IsForwarder)
+ continue;
+
+ EntityHandle implementation = exportedType.Implementation;
+ if (implementation.Kind != HandleKind.AssemblyReference) // This check also weeds out nested types. This is intentional.
+ continue;
+ RuntimeAssemblyName redirectedAssemblyName = ((AssemblyReferenceHandle)implementation).ToRuntimeAssemblyName(reader);
+
+ string typeName = exportedType.Name.GetString(reader);
+ string namespaceName = exportedType.Namespace.GetString(reader);
+
+ yield return new TypeForwardInfo(redirectedAssemblyName, namespaceName, typeName);
+ }
+ }
+ }
+
private unsafe struct InternalManifestResourceInfo
{
public bool Found;
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.cs
index b8ff628fb..317e44ebe 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.cs
@@ -120,6 +120,37 @@ namespace System.Reflection.Runtime.Assemblies.NativeFormat
}
}
+ protected sealed override IEnumerable<TypeForwardInfo> TypeForwardInfos
+ {
+ get
+ {
+ foreach (QScopeDefinition scope in AllScopes)
+ {
+ 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)
+ {
+ string namespaceName = null;
+ foreach (TypeForwarderHandle typeForwarderHandle in namespaceHandle.GetNamespaceDefinition(reader).TypeForwarders)
+ {
+ if (namespaceName == null)
+ {
+ namespaceName = namespaceHandle.ToNamespaceName(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);
+ }
+ }
+ }
+ }
+ }
+
public sealed override ManifestResourceInfo GetManifestResourceInfo(String resourceName)
{
return ReflectionCoreExecution.ExecutionEnvironment.GetManifestResourceInfo(this, resourceName);
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/RuntimeAssembly.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/RuntimeAssembly.cs
index 3e5b3b86a..353a3757c 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/RuntimeAssembly.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/RuntimeAssembly.cs
@@ -125,6 +125,69 @@ namespace System.Reflection.Runtime.Assemblies
return RuntimeAssemblyName.ToAssemblyName();
}
+ public sealed override Type[] GetForwardedTypes()
+ {
+ List<Type> types = new List<Type>();
+ List<Exception> exceptions = null;
+
+ foreach (TypeForwardInfo typeForwardInfo in TypeForwardInfos)
+ {
+ string fullTypeName = typeForwardInfo.NamespaceName.Length == 0 ? typeForwardInfo.TypeName : typeForwardInfo.NamespaceName + "." + typeForwardInfo.TypeName;
+ RuntimeAssemblyName redirectedAssemblyName = typeForwardInfo.RedirectedAssemblyName;
+
+ Type type = null;
+ RuntimeAssembly redirectedAssembly;
+ Exception exception = RuntimeAssembly.TryGetRuntimeAssembly(redirectedAssemblyName, out redirectedAssembly);
+ if (exception == null)
+ {
+ type = redirectedAssembly.GetTypeCore(fullTypeName, ignoreCase: false); // GetTypeCore() will follow any further type-forwards if needed.
+ if (type == null)
+ exception = Helpers.CreateTypeLoadException(fullTypeName.EscapeTypeNameIdentifier(), redirectedAssembly);
+ }
+
+ Debug.Assert((type != null) != (exception != null)); // Exactly one of these must be non-null.
+
+ if (type != null)
+ {
+ types.Add(type);
+ AddPublicNestedTypes(type, types);
+ }
+ else
+ {
+ if (exceptions == null)
+ {
+ exceptions = new List<Exception>();
+ }
+ exceptions.Add(exception);
+ }
+ }
+
+ if (exceptions != null)
+ {
+ int numTypes = types.Count;
+ int numExceptions = exceptions.Count;
+ types.AddRange(new Type[numExceptions]); // add one null Type for each exception.
+ exceptions.InsertRange(0, new Exception[numTypes]); // align the Exceptions with the null Types.
+ throw new ReflectionTypeLoadException(types.ToArray(), exceptions.ToArray());
+ }
+
+ return types.ToArray();
+ }
+
+ /// <summary>
+ /// Intentionally excludes forwards to nested types.
+ /// </summary>
+ protected abstract IEnumerable<TypeForwardInfo> TypeForwardInfos { get; }
+
+ private static void AddPublicNestedTypes(Type type, List<Type> types)
+ {
+ foreach (Type nestedType in type.GetNestedTypes(BindingFlags.Public))
+ {
+ types.Add(nestedType);
+ AddPublicNestedTypes(nestedType, types);
+ }
+ }
+
/// <summary>
/// Helper routine for the more general Type.GetType() family of apis.
///
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeForwardInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeForwardInfo.cs
new file mode 100644
index 000000000..600eaaad4
--- /dev/null
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeForwardInfo.cs
@@ -0,0 +1,26 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// 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;
+
+namespace System.Reflection.Runtime.General
+{
+ internal struct TypeForwardInfo
+ {
+ public TypeForwardInfo(RuntimeAssemblyName redirectedAssemblyName, string namespaceName, string typeName)
+ {
+ Debug.Assert(redirectedAssemblyName != null);
+ Debug.Assert(namespaceName != null);
+ Debug.Assert(typeName != null);
+
+ RedirectedAssemblyName = redirectedAssemblyName;
+ NamespaceName = namespaceName;
+ TypeName = typeName;
+ }
+
+ public RuntimeAssemblyName RedirectedAssemblyName { get; }
+ public string NamespaceName { get; }
+ public string TypeName { get; }
+ }
+}