2012-11-01 04:07:57 +08:00
|
|
|
|
/*
|
|
|
|
|
Copyright (C) 2011-2012 de4dot@gmail.com
|
|
|
|
|
|
|
|
|
|
This file is part of de4dot.
|
|
|
|
|
|
|
|
|
|
de4dot is free software: you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
de4dot is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2012-12-20 09:06:09 +08:00
|
|
|
|
using dnlib.DotNet;
|
2012-11-01 04:07:57 +08:00
|
|
|
|
|
|
|
|
|
namespace de4dot.blocks {
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public class TypeDefDict<TValue> {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
Dictionary<ScopeAndTokenKey, TValue> tokenToValue = new Dictionary<ScopeAndTokenKey, TValue>();
|
|
|
|
|
Dictionary<ScopeAndTokenKey, TypeDef> tokenToKey = new Dictionary<ScopeAndTokenKey, TypeDef>();
|
|
|
|
|
Dictionary<IType, TValue> refToValue = new Dictionary<IType, TValue>(TypeEqualityComparer.Instance);
|
2012-11-18 10:02:12 +08:00
|
|
|
|
Dictionary<IType, TypeDef> refToKey = new Dictionary<IType, TypeDef>(TypeEqualityComparer.Instance);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
|
|
|
|
|
public int Count {
|
|
|
|
|
get { return tokenToValue.Count; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerable<TypeDef> getKeys() {
|
|
|
|
|
return tokenToKey.Values;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerable<TValue> getValues() {
|
|
|
|
|
return tokenToValue.Values;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ScopeAndTokenKey getTokenKey(TypeDef typeDef) {
|
|
|
|
|
return new ScopeAndTokenKey(typeDef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TValue find(IType typeRef) {
|
|
|
|
|
TValue value;
|
|
|
|
|
var typeDef = typeRef as TypeDef;
|
|
|
|
|
if (typeDef != null)
|
|
|
|
|
tokenToValue.TryGetValue(getTokenKey(typeDef), out value);
|
|
|
|
|
else if (typeRef != null)
|
|
|
|
|
refToValue.TryGetValue(typeRef, out value);
|
|
|
|
|
else
|
|
|
|
|
value = default(TValue);
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TValue findAny(IType type) {
|
|
|
|
|
TValue value;
|
|
|
|
|
var typeDef = type as TypeDef;
|
|
|
|
|
if (typeDef != null && tokenToValue.TryGetValue(getTokenKey(typeDef), out value))
|
|
|
|
|
return value;
|
|
|
|
|
|
|
|
|
|
refToValue.TryGetValue(type, out value);
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void add(TypeDef typeDef, TValue value) {
|
|
|
|
|
var tokenKey = getTokenKey(typeDef);
|
|
|
|
|
tokenToValue[tokenKey] = value;
|
|
|
|
|
tokenToKey[tokenKey] = typeDef;
|
|
|
|
|
|
|
|
|
|
if (!refToValue.ContainsKey(typeDef) ||
|
|
|
|
|
getAccessibilityOrder(typeDef) < getAccessibilityOrder(refToKey[typeDef])) {
|
|
|
|
|
refToKey[typeDef] = typeDef;
|
|
|
|
|
refToValue[typeDef] = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Order: public, family, assembly, private
|
|
|
|
|
static int[] accessibilityOrder = new int[8] {
|
|
|
|
|
40, // NotPublic
|
|
|
|
|
0, // Public
|
|
|
|
|
10, // NestedPublic
|
|
|
|
|
70, // NestedPrivate
|
|
|
|
|
20, // NestedFamily
|
|
|
|
|
50, // NestedAssembly
|
|
|
|
|
60, // NestedFamANDAssem
|
|
|
|
|
30, // NestedFamORAssem
|
|
|
|
|
};
|
|
|
|
|
static int getAccessibilityOrder(TypeDef typeDef) {
|
2012-11-17 06:50:52 +08:00
|
|
|
|
return accessibilityOrder[(int)typeDef.Attributes & 7];
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void onTypesRenamed() {
|
|
|
|
|
var newTypeRefToValue = new Dictionary<IType, TValue>(refToValue.Count);
|
|
|
|
|
foreach (var kvp in refToValue)
|
|
|
|
|
newTypeRefToValue[kvp.Key] = kvp.Value;
|
|
|
|
|
refToValue = newTypeRefToValue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public abstract class FieldDefDictBase<TValue> {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
Dictionary<ScopeAndTokenKey, TValue> tokenToValue = new Dictionary<ScopeAndTokenKey, TValue>();
|
|
|
|
|
Dictionary<ScopeAndTokenKey, FieldDef> tokenToKey = new Dictionary<ScopeAndTokenKey, FieldDef>();
|
2012-11-22 16:14:51 +08:00
|
|
|
|
Dictionary<IFieldRefKey, TValue> refToValue = new Dictionary<IFieldRefKey, TValue>();
|
|
|
|
|
Dictionary<IFieldRefKey, FieldDef> refToKey = new Dictionary<IFieldRefKey, FieldDef>();
|
2012-11-01 04:07:57 +08:00
|
|
|
|
|
|
|
|
|
public int Count {
|
|
|
|
|
get { return tokenToValue.Count; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerable<FieldDef> getKeys() {
|
|
|
|
|
return tokenToKey.Values;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerable<TValue> getValues() {
|
|
|
|
|
return tokenToValue.Values;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ScopeAndTokenKey getTokenKey(FieldDef fieldDef) {
|
|
|
|
|
return new ScopeAndTokenKey(fieldDef);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
internal abstract IFieldRefKey getRefKey(IField fieldRef);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
|
|
|
|
|
public TValue find(IField fieldRef) {
|
|
|
|
|
TValue value;
|
|
|
|
|
var fieldDef = fieldRef as FieldDef;
|
|
|
|
|
if (fieldDef != null)
|
|
|
|
|
tokenToValue.TryGetValue(getTokenKey(fieldDef), out value);
|
|
|
|
|
else
|
2012-11-22 16:14:51 +08:00
|
|
|
|
refToValue.TryGetValue(getRefKey(fieldRef), out value);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TValue findAny(IField fieldRef) {
|
|
|
|
|
TValue value;
|
|
|
|
|
var fieldDef = fieldRef as FieldDef;
|
|
|
|
|
if (fieldDef != null && tokenToValue.TryGetValue(getTokenKey(fieldDef), out value))
|
|
|
|
|
return value;
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
refToValue.TryGetValue(getRefKey(fieldRef), out value);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void add(FieldDef fieldDef, TValue value) {
|
|
|
|
|
var tokenKey = getTokenKey(fieldDef);
|
|
|
|
|
tokenToValue[tokenKey] = value;
|
|
|
|
|
tokenToKey[tokenKey] = fieldDef;
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
var refKey = getRefKey(fieldDef);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
if (!refToValue.ContainsKey(refKey) ||
|
|
|
|
|
getAccessibilityOrder(fieldDef) < getAccessibilityOrder(refToKey[refKey])) {
|
|
|
|
|
refToKey[refKey] = fieldDef;
|
|
|
|
|
refToValue[refKey] = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Order: public, family, assembly, private
|
|
|
|
|
static int[] accessibilityOrder = new int[8] {
|
2012-11-03 05:53:24 +08:00
|
|
|
|
60, // PrivateScope
|
2012-11-01 04:07:57 +08:00
|
|
|
|
50, // Private
|
|
|
|
|
40, // FamANDAssem
|
|
|
|
|
30, // Assembly
|
|
|
|
|
10, // Family
|
|
|
|
|
20, // FamORAssem
|
|
|
|
|
0, // Public
|
|
|
|
|
70, // <reserved>
|
|
|
|
|
};
|
2012-11-22 16:14:51 +08:00
|
|
|
|
static int getAccessibilityOrder(FieldDef fieldDef) {
|
|
|
|
|
return accessibilityOrder[(int)fieldDef.Attributes & 7];
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void onTypesRenamed() {
|
2012-11-22 16:14:51 +08:00
|
|
|
|
var newFieldRefToDef = new Dictionary<IFieldRefKey, TValue>(refToValue.Count);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
foreach (var kvp in refToValue)
|
2012-11-22 16:14:51 +08:00
|
|
|
|
newFieldRefToDef[getRefKey((FieldDef)kvp.Key.FieldRef)] = kvp.Value;
|
2012-11-01 04:07:57 +08:00
|
|
|
|
refToValue = newFieldRefToDef;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public class FieldDefDict<TValue> : FieldDefDictBase<TValue> {
|
|
|
|
|
internal override IFieldRefKey getRefKey(IField fieldRef) {
|
|
|
|
|
return new FieldRefKey(fieldRef);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public class FieldDefAndDeclaringTypeDict<TValue> : FieldDefDictBase<TValue> {
|
|
|
|
|
internal override IFieldRefKey getRefKey(IField fieldRef) {
|
|
|
|
|
return new FieldRefAndDeclaringTypeKey(fieldRef);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public abstract class MethodDefDictBase<TValue> {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
Dictionary<ScopeAndTokenKey, TValue> tokenToValue = new Dictionary<ScopeAndTokenKey, TValue>();
|
|
|
|
|
Dictionary<ScopeAndTokenKey, MethodDef> tokenToKey = new Dictionary<ScopeAndTokenKey, MethodDef>();
|
2012-11-22 16:14:51 +08:00
|
|
|
|
Dictionary<IMethodRefKey, TValue> refToValue = new Dictionary<IMethodRefKey, TValue>();
|
|
|
|
|
Dictionary<IMethodRefKey, MethodDef> refToKey = new Dictionary<IMethodRefKey, MethodDef>();
|
2012-11-01 04:07:57 +08:00
|
|
|
|
|
|
|
|
|
public int Count {
|
|
|
|
|
get { return tokenToValue.Count; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerable<MethodDef> getKeys() {
|
|
|
|
|
return tokenToKey.Values;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerable<TValue> getValues() {
|
|
|
|
|
return tokenToValue.Values;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ScopeAndTokenKey getTokenKey(MethodDef methodDef) {
|
|
|
|
|
return new ScopeAndTokenKey(methodDef);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
internal abstract IMethodRefKey getRefKey(IMethod methodRef);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
|
|
|
|
|
public TValue find(IMethod methodRef) {
|
|
|
|
|
TValue value;
|
|
|
|
|
var methodDef = methodRef as MethodDef;
|
|
|
|
|
if (methodDef != null)
|
|
|
|
|
tokenToValue.TryGetValue(getTokenKey(methodDef), out value);
|
|
|
|
|
else
|
2012-11-22 16:14:51 +08:00
|
|
|
|
refToValue.TryGetValue(getRefKey(methodRef), out value);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TValue findAny(IMethod methodRef) {
|
|
|
|
|
TValue value;
|
|
|
|
|
var methodDef = methodRef as MethodDef;
|
|
|
|
|
if (methodDef != null && tokenToValue.TryGetValue(getTokenKey(methodDef), out value))
|
|
|
|
|
return value;
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
refToValue.TryGetValue(getRefKey(methodRef), out value);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void add(MethodDef methodDef, TValue value) {
|
|
|
|
|
var tokenKey = getTokenKey(methodDef);
|
|
|
|
|
tokenToValue[tokenKey] = value;
|
|
|
|
|
tokenToKey[tokenKey] = methodDef;
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
var refKey = getRefKey(methodDef);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
if (!refToValue.ContainsKey(refKey) ||
|
|
|
|
|
getAccessibilityOrder(methodDef) < getAccessibilityOrder(refToKey[refKey])) {
|
|
|
|
|
refToKey[refKey] = methodDef;
|
|
|
|
|
refToValue[refKey] = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Order: public, family, assembly, private
|
|
|
|
|
static int[] accessibilityOrder = new int[8] {
|
2012-11-03 05:53:24 +08:00
|
|
|
|
60, // PrivateScope
|
2012-11-01 04:07:57 +08:00
|
|
|
|
50, // Private
|
|
|
|
|
40, // FamANDAssem
|
|
|
|
|
30, // Assembly
|
|
|
|
|
10, // Family
|
|
|
|
|
20, // FamORAssem
|
|
|
|
|
0, // Public
|
|
|
|
|
70, // <reserved>
|
|
|
|
|
};
|
2012-11-22 16:14:51 +08:00
|
|
|
|
static int getAccessibilityOrder(MethodDef methodDef) {
|
|
|
|
|
return accessibilityOrder[(int)methodDef.Attributes & 7];
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void onTypesRenamed() {
|
2012-11-22 16:14:51 +08:00
|
|
|
|
var newFieldRefToDef = new Dictionary<IMethodRefKey, TValue>(refToValue.Count);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
foreach (var kvp in refToValue)
|
2012-11-22 16:14:51 +08:00
|
|
|
|
newFieldRefToDef[getRefKey((MethodDef)kvp.Key.MethodRef)] = kvp.Value;
|
2012-11-01 04:07:57 +08:00
|
|
|
|
refToValue = newFieldRefToDef;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public class MethodDefDict<TValue> : MethodDefDictBase<TValue> {
|
|
|
|
|
internal override IMethodRefKey getRefKey(IMethod methodRef) {
|
|
|
|
|
return new MethodRefKey(methodRef);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public class MethodDefAndDeclaringTypeDict<TValue> : MethodDefDictBase<TValue> {
|
|
|
|
|
internal override IMethodRefKey getRefKey(IMethod methodRef) {
|
|
|
|
|
return new MethodRefAndDeclaringTypeKey(methodRef);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public abstract class EventDefDictBase<TValue> {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
Dictionary<ScopeAndTokenKey, TValue> tokenToValue = new Dictionary<ScopeAndTokenKey, TValue>();
|
|
|
|
|
Dictionary<ScopeAndTokenKey, EventDef> tokenToKey = new Dictionary<ScopeAndTokenKey, EventDef>();
|
2012-11-22 16:14:51 +08:00
|
|
|
|
Dictionary<IEventRefKey, TValue> refToValue = new Dictionary<IEventRefKey, TValue>();
|
2012-11-01 04:07:57 +08:00
|
|
|
|
|
|
|
|
|
public int Count {
|
|
|
|
|
get { return tokenToValue.Count; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerable<EventDef> getKeys() {
|
|
|
|
|
return tokenToKey.Values;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerable<TValue> getValues() {
|
|
|
|
|
return tokenToValue.Values;
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
ScopeAndTokenKey getTokenKey(EventDef eventRef) {
|
|
|
|
|
return new ScopeAndTokenKey(eventRef);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
internal abstract IEventRefKey getRefKey(EventDef eventRef);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
|
|
|
|
|
public TValue find(EventDef eventRef) {
|
|
|
|
|
TValue value;
|
|
|
|
|
tokenToValue.TryGetValue(getTokenKey(eventRef), out value);
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TValue findAny(EventDef eventRef) {
|
|
|
|
|
TValue value;
|
|
|
|
|
if (tokenToValue.TryGetValue(getTokenKey(eventRef), out value))
|
|
|
|
|
return value;
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
refToValue.TryGetValue(getRefKey(eventRef), out value);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void add(EventDef eventDef, TValue value) {
|
|
|
|
|
var tokenKey = getTokenKey(eventDef);
|
|
|
|
|
tokenToValue[tokenKey] = value;
|
|
|
|
|
tokenToKey[tokenKey] = eventDef;
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
refToValue[getRefKey(eventDef)] = value;
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void onTypesRenamed() {
|
2012-11-22 16:14:51 +08:00
|
|
|
|
var newFieldRefToDef = new Dictionary<IEventRefKey, TValue>(refToValue.Count);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
foreach (var kvp in refToValue)
|
2012-11-22 16:14:51 +08:00
|
|
|
|
newFieldRefToDef[getRefKey((EventDef)kvp.Key.EventDef)] = kvp.Value;
|
2012-11-01 04:07:57 +08:00
|
|
|
|
refToValue = newFieldRefToDef;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public class EventDefDict<TValue> : EventDefDictBase<TValue> {
|
|
|
|
|
internal override IEventRefKey getRefKey(EventDef eventRef) {
|
|
|
|
|
return new EventRefKey(eventRef);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public class EventDefAndDeclaringTypeDict<TValue> : EventDefDictBase<TValue> {
|
|
|
|
|
internal override IEventRefKey getRefKey(EventDef eventRef) {
|
|
|
|
|
return new EventRefAndDeclaringTypeKey(eventRef);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public abstract class PropertyDefDictBase<TValue> {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
Dictionary<ScopeAndTokenKey, TValue> tokenToValue = new Dictionary<ScopeAndTokenKey, TValue>();
|
|
|
|
|
Dictionary<ScopeAndTokenKey, PropertyDef> tokenToKey = new Dictionary<ScopeAndTokenKey, PropertyDef>();
|
2012-11-22 16:14:51 +08:00
|
|
|
|
Dictionary<IPropertyRefKey, TValue> refToValue = new Dictionary<IPropertyRefKey, TValue>();
|
2012-11-01 04:07:57 +08:00
|
|
|
|
|
|
|
|
|
public int Count {
|
|
|
|
|
get { return tokenToValue.Count; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerable<PropertyDef> getKeys() {
|
|
|
|
|
return tokenToKey.Values;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerable<TValue> getValues() {
|
|
|
|
|
return tokenToValue.Values;
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
ScopeAndTokenKey getTokenKey(PropertyDef propertyRef) {
|
|
|
|
|
return new ScopeAndTokenKey(propertyRef);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
internal abstract IPropertyRefKey getRefKey(PropertyDef propertyRef);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
|
|
|
|
|
public TValue find(PropertyDef propRef) {
|
|
|
|
|
TValue value;
|
|
|
|
|
tokenToValue.TryGetValue(getTokenKey(propRef), out value);
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TValue findAny(PropertyDef propRef) {
|
|
|
|
|
TValue value;
|
|
|
|
|
if (tokenToValue.TryGetValue(getTokenKey(propRef), out value))
|
|
|
|
|
return value;
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
refToValue.TryGetValue(getRefKey(propRef), out value);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void add(PropertyDef propDef, TValue value) {
|
|
|
|
|
var tokenKey = getTokenKey(propDef);
|
|
|
|
|
tokenToValue[tokenKey] = value;
|
|
|
|
|
tokenToKey[tokenKey] = propDef;
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
refToValue[getRefKey(propDef)] = value;
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void onTypesRenamed() {
|
2012-11-22 16:14:51 +08:00
|
|
|
|
var newFieldRefToDef = new Dictionary<IPropertyRefKey, TValue>(refToValue.Count);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
foreach (var kvp in refToValue)
|
2012-11-22 16:14:51 +08:00
|
|
|
|
newFieldRefToDef[getRefKey((PropertyDef)kvp.Key.PropertyDef)] = kvp.Value;
|
2012-11-01 04:07:57 +08:00
|
|
|
|
refToValue = newFieldRefToDef;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public class PropertyDefDict<TValue> : PropertyDefDictBase<TValue> {
|
|
|
|
|
internal override IPropertyRefKey getRefKey(PropertyDef propRef) {
|
|
|
|
|
return new PropertyRefKey(propRef);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public class PropertyDefAndDeclaringTypeDict<TValue> : PropertyDefDictBase<TValue> {
|
|
|
|
|
internal override IPropertyRefKey getRefKey(PropertyDef propRef) {
|
|
|
|
|
return new PropertyRefAndDeclaringTypeKey(propRef);
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-03 05:53:24 +08:00
|
|
|
|
sealed class ScopeAndTokenKey {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
readonly IScope scope;
|
|
|
|
|
readonly uint token;
|
|
|
|
|
|
|
|
|
|
public ScopeAndTokenKey(TypeDef type)
|
2012-11-17 06:50:52 +08:00
|
|
|
|
: this(type.Module, type.MDToken.Raw) {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ScopeAndTokenKey(FieldDef field)
|
2012-11-17 06:50:52 +08:00
|
|
|
|
: this(field.DeclaringType == null ? null : field.DeclaringType.Module, field.MDToken.Raw) {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ScopeAndTokenKey(MethodDef method)
|
2012-11-17 06:50:52 +08:00
|
|
|
|
: this(method.DeclaringType == null ? null : method.DeclaringType.Module, method.MDToken.Raw) {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ScopeAndTokenKey(PropertyDef prop)
|
2012-11-17 06:50:52 +08:00
|
|
|
|
: this(prop.DeclaringType == null ? null : prop.DeclaringType.Module, prop.MDToken.Raw) {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ScopeAndTokenKey(EventDef evt)
|
2012-11-17 06:50:52 +08:00
|
|
|
|
: this(evt.DeclaringType == null ? null : evt.DeclaringType.Module, evt.MDToken.Raw) {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ScopeAndTokenKey(IScope scope, uint token) {
|
|
|
|
|
this.scope = scope;
|
|
|
|
|
this.token = token;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int GetHashCode() {
|
|
|
|
|
return (int)token + GetHashCode(scope);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool Equals(object obj) {
|
|
|
|
|
var other = obj as ScopeAndTokenKey;
|
|
|
|
|
if (other == null)
|
|
|
|
|
return false;
|
|
|
|
|
return token == other.token &&
|
|
|
|
|
Equals(scope, other.scope);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string ToString() {
|
|
|
|
|
return string.Format("{0:X8} {1}", token, scope);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool Equals(IScope a, IScope b) {
|
|
|
|
|
if (a == b)
|
|
|
|
|
return true;
|
|
|
|
|
if (a == null || b == null)
|
|
|
|
|
return false;
|
|
|
|
|
return getCanonicalizedScopeName(a) == getCanonicalizedScopeName(b);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int GetHashCode(IScope a) {
|
|
|
|
|
if (a == null)
|
|
|
|
|
return 0;
|
|
|
|
|
return getCanonicalizedScopeName(a).GetHashCode();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static string getAssemblyName(IScope a) {
|
|
|
|
|
switch (a.ScopeType) {
|
|
|
|
|
case ScopeType.AssemblyRef:
|
|
|
|
|
return ((AssemblyRef)a).Name.String;
|
|
|
|
|
case ScopeType.ModuleDef:
|
|
|
|
|
var asm = ((ModuleDef)a).Assembly;
|
|
|
|
|
if (asm != null)
|
|
|
|
|
return asm.Name.String;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static string getCanonicalizedScopeName(IScope a) {
|
|
|
|
|
if (a == null)
|
|
|
|
|
return string.Empty;
|
|
|
|
|
var asmName = getAssemblyName(a);
|
|
|
|
|
if (asmName != null) {
|
|
|
|
|
// The version number should be ignored. Older code may reference an old version of
|
|
|
|
|
// the assembly, but if the newer one has been loaded, that one is used.
|
|
|
|
|
return asmName.ToUpperInvariant();
|
|
|
|
|
}
|
|
|
|
|
return a.ScopeName.ToUpperInvariant();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
interface IFieldRefKey {
|
|
|
|
|
IField FieldRef { get; }
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
interface IMethodRefKey {
|
|
|
|
|
IMethod MethodRef { get; }
|
2012-11-01 04:07:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
interface IEventRefKey {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
EventDef EventDef { get; }
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
interface IPropertyRefKey {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
PropertyDef PropertyDef { get; }
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
sealed class FieldRefKey : IFieldRefKey {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
readonly IField fieldRef;
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public IField FieldRef {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
get { return fieldRef; }
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public FieldRefKey(IField fieldRef) {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
this.fieldRef = fieldRef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int GetHashCode() {
|
|
|
|
|
return new SigComparer().GetHashCode(fieldRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool Equals(object obj) {
|
2012-11-22 16:14:51 +08:00
|
|
|
|
var other = obj as FieldRefKey;
|
2012-11-01 04:07:57 +08:00
|
|
|
|
if (other == null)
|
|
|
|
|
return false;
|
|
|
|
|
return new SigComparer().Equals(fieldRef, other.fieldRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string ToString() {
|
|
|
|
|
return fieldRef.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
sealed class MethodRefKey : IMethodRefKey {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
readonly IMethod methodRef;
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public IMethod MethodRef {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
get { return methodRef; }
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public MethodRefKey(IMethod methodRef) {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
this.methodRef = methodRef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int GetHashCode() {
|
|
|
|
|
return new SigComparer().GetHashCode(methodRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool Equals(object obj) {
|
2012-11-22 16:14:51 +08:00
|
|
|
|
var other = obj as MethodRefKey;
|
2012-11-01 04:07:57 +08:00
|
|
|
|
if (other == null)
|
|
|
|
|
return false;
|
|
|
|
|
return new SigComparer().Equals(methodRef, other.methodRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string ToString() {
|
|
|
|
|
return methodRef.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
sealed class FieldRefAndDeclaringTypeKey : IFieldRefKey {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
readonly IField fieldRef;
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public IField FieldRef {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
get { return fieldRef; }
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public FieldRefAndDeclaringTypeKey(IField fieldRef) {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
this.fieldRef = fieldRef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int GetHashCode() {
|
|
|
|
|
return new SigComparer(SigComparerOptions.CompareMethodFieldDeclaringType).GetHashCode(fieldRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool Equals(object obj) {
|
2012-11-22 16:14:51 +08:00
|
|
|
|
var other = obj as FieldRefAndDeclaringTypeKey;
|
2012-11-01 04:07:57 +08:00
|
|
|
|
if (other == null)
|
|
|
|
|
return false;
|
|
|
|
|
return new SigComparer(SigComparerOptions.CompareMethodFieldDeclaringType).Equals(fieldRef, other.fieldRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string ToString() {
|
|
|
|
|
return fieldRef.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
sealed class MethodRefAndDeclaringTypeKey : IMethodRefKey {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
readonly IMethod methodRef;
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public IMethod MethodRef {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
get { return methodRef; }
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public MethodRefAndDeclaringTypeKey(IMethod methodRef) {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
this.methodRef = methodRef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int GetHashCode() {
|
|
|
|
|
return new SigComparer(SigComparerOptions.CompareMethodFieldDeclaringType).GetHashCode(methodRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool Equals(object obj) {
|
2012-11-22 16:14:51 +08:00
|
|
|
|
var other = obj as MethodRefAndDeclaringTypeKey;
|
2012-11-01 04:07:57 +08:00
|
|
|
|
if (other == null)
|
|
|
|
|
return false;
|
|
|
|
|
return new SigComparer(SigComparerOptions.CompareMethodFieldDeclaringType).Equals(methodRef, other.methodRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string ToString() {
|
|
|
|
|
return methodRef.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
sealed class EventRefKey : IEventRefKey {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
readonly EventDef eventRef;
|
|
|
|
|
|
|
|
|
|
public EventDef EventDef {
|
|
|
|
|
get { return eventRef; }
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public EventRefKey(EventDef eventRef) {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
this.eventRef = eventRef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int GetHashCode() {
|
|
|
|
|
return new SigComparer().GetHashCode(eventRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool Equals(object obj) {
|
2012-11-22 16:14:51 +08:00
|
|
|
|
var other = obj as EventRefKey;
|
2012-11-01 04:07:57 +08:00
|
|
|
|
if (other == null)
|
|
|
|
|
return false;
|
|
|
|
|
return new SigComparer().Equals(eventRef, other.eventRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string ToString() {
|
|
|
|
|
return eventRef.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
sealed class EventRefAndDeclaringTypeKey : IEventRefKey {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
readonly EventDef eventRef;
|
|
|
|
|
|
|
|
|
|
public EventDef EventDef {
|
|
|
|
|
get { return eventRef; }
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public EventRefAndDeclaringTypeKey(EventDef eventRef) {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
this.eventRef = eventRef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int GetHashCode() {
|
|
|
|
|
return new SigComparer(SigComparerOptions.CompareEventDeclaringType).GetHashCode(eventRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool Equals(object obj) {
|
2012-11-22 16:14:51 +08:00
|
|
|
|
var other = obj as EventRefAndDeclaringTypeKey;
|
2012-11-01 04:07:57 +08:00
|
|
|
|
if (other == null)
|
|
|
|
|
return false;
|
|
|
|
|
return new SigComparer(SigComparerOptions.CompareEventDeclaringType).Equals(eventRef, other.eventRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string ToString() {
|
|
|
|
|
return eventRef.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
sealed class PropertyRefKey : IPropertyRefKey {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
readonly PropertyDef propRef;
|
|
|
|
|
|
|
|
|
|
public PropertyDef PropertyDef {
|
|
|
|
|
get { return propRef; }
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public PropertyRefKey(PropertyDef propRef) {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
this.propRef = propRef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int GetHashCode() {
|
|
|
|
|
return new SigComparer().GetHashCode(propRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool Equals(object obj) {
|
2012-11-22 16:14:51 +08:00
|
|
|
|
var other = obj as PropertyRefKey;
|
2012-11-01 04:07:57 +08:00
|
|
|
|
if (other == null)
|
|
|
|
|
return false;
|
|
|
|
|
return new SigComparer().Equals(propRef, other.propRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string ToString() {
|
|
|
|
|
return propRef.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
sealed class PropertyRefAndDeclaringTypeKey : IPropertyRefKey {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
readonly PropertyDef propRef;
|
|
|
|
|
|
|
|
|
|
public PropertyDef PropertyDef {
|
|
|
|
|
get { return propRef; }
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 16:14:51 +08:00
|
|
|
|
public PropertyRefAndDeclaringTypeKey(PropertyDef propRef) {
|
2012-11-01 04:07:57 +08:00
|
|
|
|
this.propRef = propRef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int GetHashCode() {
|
|
|
|
|
return new SigComparer(SigComparerOptions.ComparePropertyDeclaringType).GetHashCode(propRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool Equals(object obj) {
|
2012-11-22 16:14:51 +08:00
|
|
|
|
var other = obj as PropertyRefAndDeclaringTypeKey;
|
2012-11-01 04:07:57 +08:00
|
|
|
|
if (other == null)
|
|
|
|
|
return false;
|
|
|
|
|
return new SigComparer(SigComparerOptions.ComparePropertyDeclaringType).Equals(propRef, other.propRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string ToString() {
|
|
|
|
|
return propRef.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|