forked from dnSpy/ILSpy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CecilTypeResolver.cs
104 lines (83 loc) · 2.79 KB
/
CecilTypeResolver.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System;
using System.Linq;
using ICSharpCode.ILSpy;
using Mono.Cecil;
using Ricciolo.StylesExplorer.MarkupReflection;
namespace ILSpy.BamlDecompiler
{
/// <summary>
/// Description of CecilTypeResolver.
/// </summary>
public class CecilTypeResolver : ITypeResolver
{
IAssemblyResolver resolver;
AssemblyDefinition thisAssembly;
public CecilTypeResolver(IAssemblyResolver resolver, AssemblyDefinition asm)
{
this.resolver = resolver;
this.thisAssembly = asm;
}
public bool IsLocalAssembly(string name)
{
return MakeShort(name) == this.thisAssembly.Name.Name;
}
string MakeShort(string name)
{
int endOffset = name.IndexOf(',');
if (endOffset == -1)
return name;
return name.Substring(0, endOffset);
}
public IType GetTypeByAssemblyQualifiedName(string name)
{
int bracket = name.LastIndexOf(']');
int comma = bracket > -1 ? name.IndexOf(',', bracket) : name.IndexOf(',');
if (comma == -1)
throw new ArgumentException("invalid name");
string fullName = bracket > -1 ? name.Substring(0, name.IndexOf('[')) : name.Substring(0, comma);
string assemblyName = name.Substring(comma + 1).Trim();
var type = thisAssembly.MainModule.GetType(fullName);
if (type == null) {
type = TryFindInExportedTypes(fullName, thisAssembly);
}
if (type == null) {
var otherAssembly = resolver.Resolve(AssemblyNameReference.Parse(assemblyName));
if (otherAssembly == null)
return new UnresolvableType(name);
type = otherAssembly.MainModule.GetType(fullName.Replace('+', '/'));
if (type == null) {
type = TryFindInExportedTypes(fullName, otherAssembly);
}
}
if (type == null)
return new UnresolvableType(name);
return new CecilType(type);
}
TypeDefinition TryFindInExportedTypes(string fullName, AssemblyDefinition asm)
{
foreach (var exportedType in asm.MainModule.ExportedTypes) {
if (exportedType.IsForwarder && exportedType.FullName == fullName) {
return exportedType.Resolve();
}
}
return null;
}
public IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IType ownerType, IType targetType)
{
if (ownerType == null)
throw new ArgumentNullException("ownerType");
if (ownerType is CecilType)
return new CecilDependencyPropertyDescriptor(name, ((CecilType)ownerType).type);
if (ownerType is UnresolvableType)
return new UnresolvableDependencyPropertyDescriptor();
throw new ArgumentException("Invalid IType: " + ownerType.GetType());
}
public string RuntimeVersion {
get {
return thisAssembly.MainModule.Runtime.ToString();
}
}
}
}