123 lines
3.9 KiB
C#
123 lines
3.9 KiB
C#
using System;
|
|
using Mono.Cecil;
|
|
|
|
namespace Mono.Documentation.Updater.Frameworks
|
|
{
|
|
public class MDocMetadataResolver : MetadataResolver
|
|
{
|
|
public MDocMetadataResolver (CachedResolver r) : base (r) { }
|
|
|
|
ReaderParameters parameters = new ReaderParameters ();
|
|
|
|
public override TypeDefinition Resolve (TypeReference type)
|
|
{
|
|
type = type.GetElementType ();
|
|
|
|
var scope = type.Scope;
|
|
|
|
if (scope == null)
|
|
return null;
|
|
|
|
CachedResolver assembly_resolver = this.AssemblyResolver as CachedResolver;
|
|
parameters.AssemblyResolver = assembly_resolver;
|
|
parameters.MetadataResolver = this;
|
|
|
|
try {
|
|
|
|
switch (scope.MetadataScopeType)
|
|
{
|
|
case MetadataScopeType.AssemblyNameReference:
|
|
var assembly = assembly_resolver.ResolveCore ((AssemblyNameReference)scope, parameters, type);
|
|
if (assembly == null)
|
|
return null;
|
|
|
|
return GetType (assembly.MainModule, type);
|
|
case MetadataScopeType.ModuleDefinition:
|
|
return GetType ((ModuleDefinition)scope, type);
|
|
case MetadataScopeType.ModuleReference:
|
|
var modules = type.Module.Assembly.Modules;
|
|
var module_ref = (ModuleReference)scope;
|
|
for (int i = 0; i < modules.Count; i++)
|
|
{
|
|
var netmodule = modules[i];
|
|
if (netmodule.Name == module_ref.Name)
|
|
return GetType (netmodule, type);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
catch(AssemblyResolutionException are)
|
|
{
|
|
throw new MDocException ($"Failed to resolve type '{type.FullName}'", are);
|
|
}
|
|
catch
|
|
{
|
|
throw;
|
|
}
|
|
|
|
throw new NotSupportedException ($"metadata scope type {scope.MetadataScopeType.ToString("G")} is not supported");
|
|
}
|
|
static TypeDefinition GetType (ModuleDefinition module, TypeReference reference)
|
|
{
|
|
var type = GetTypeDefinition (module, reference);
|
|
if (type != null)
|
|
return type;
|
|
|
|
if (!module.HasExportedTypes)
|
|
return null;
|
|
|
|
var exported_types = module.ExportedTypes;
|
|
|
|
for (int i = 0; i < exported_types.Count; i++)
|
|
{
|
|
var exported_type = exported_types[i];
|
|
if (exported_type.Name != reference.Name)
|
|
continue;
|
|
|
|
if (exported_type.Namespace != reference.Namespace)
|
|
continue;
|
|
|
|
return exported_type.Resolve ();
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
static TypeDefinition GetTypeDefinition (ModuleDefinition module, TypeReference type)
|
|
{
|
|
if (!type.IsNested)
|
|
return module.GetType (type.Namespace, type.Name);
|
|
|
|
var declaring_type = type.DeclaringType.Resolve ();
|
|
if (declaring_type == null)
|
|
return null;
|
|
|
|
return GetNestedType (declaring_type, TypeFullName(type));
|
|
}
|
|
|
|
public static TypeDefinition GetNestedType (TypeDefinition self, string fullname)
|
|
{
|
|
if (!self.HasNestedTypes)
|
|
return null;
|
|
|
|
var nested_types = self.NestedTypes;
|
|
|
|
for (int i = 0; i < nested_types.Count; i++)
|
|
{
|
|
var nested_type = nested_types[i];
|
|
|
|
if (TypeFullName(nested_type) == fullname)
|
|
return nested_type;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
public static string TypeFullName (TypeReference self)
|
|
{
|
|
return string.IsNullOrEmpty (self.Namespace)
|
|
? self.Name
|
|
: self.Namespace + '.' + self.Name;
|
|
}
|
|
}
|
|
}
|