2011-11-18 23:55:54 +08:00
|
|
|
|
/*
|
2015-10-30 05:45:26 +08:00
|
|
|
|
Copyright (C) 2011-2015 de4dot@gmail.com
|
2011-11-18 23:55:54 +08:00
|
|
|
|
|
|
|
|
|
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;
|
2011-11-18 23:55:54 +08:00
|
|
|
|
|
2011-12-09 16:02:06 +08:00
|
|
|
|
namespace de4dot.code.renamer {
|
2015-05-17 19:29:48 +08:00
|
|
|
|
public abstract class TypeNames {
|
2011-11-22 15:14:34 +08:00
|
|
|
|
protected Dictionary<string, NameCreator> typeNames = new Dictionary<string, NameCreator>(StringComparer.Ordinal);
|
|
|
|
|
protected NameCreator genericParamNameCreator = new NameCreator("gparam_");
|
2012-11-05 09:42:48 +08:00
|
|
|
|
protected NameCreator fnPtrNameCreator = new NameCreator("fnptr_");
|
|
|
|
|
protected NameCreator unknownNameCreator = new NameCreator("unknown_");
|
2012-01-28 05:01:20 +08:00
|
|
|
|
protected Dictionary<string, string> fullNameToShortName;
|
|
|
|
|
protected Dictionary<string, string> fullNameToShortNamePrefix;
|
2011-11-18 23:55:54 +08:00
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
public string Create(TypeSig typeRef) {
|
2012-11-04 07:50:24 +08:00
|
|
|
|
typeRef = typeRef.RemovePinnedAndModifiers();
|
2012-11-05 09:42:48 +08:00
|
|
|
|
if (typeRef == null)
|
2013-01-19 20:03:57 +08:00
|
|
|
|
return unknownNameCreator.Create();
|
2012-11-04 07:50:24 +08:00
|
|
|
|
var gis = typeRef as GenericInstSig;
|
|
|
|
|
if (gis != null) {
|
|
|
|
|
if (gis.FullName == "System.Nullable`1" &&
|
|
|
|
|
gis.GenericArguments.Count == 1 && gis.GenericArguments[0] != null) {
|
|
|
|
|
typeRef = gis.GenericArguments[0];
|
2011-11-23 12:09:34 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
string prefix = GetPrefix(typeRef);
|
2011-11-24 12:25:04 +08:00
|
|
|
|
|
2014-03-24 14:43:31 +08:00
|
|
|
|
var elementType = Renamer.GetScopeType(typeRef);
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (elementType == null && IsFnPtrSig(typeRef))
|
|
|
|
|
return fnPtrNameCreator.Create();
|
|
|
|
|
if (IsGenericParam(elementType))
|
|
|
|
|
return genericParamNameCreator.Create();
|
2011-11-18 23:55:54 +08:00
|
|
|
|
|
2011-11-22 15:14:34 +08:00
|
|
|
|
NameCreator nc;
|
2011-12-02 05:30:43 +08:00
|
|
|
|
var typeFullName = typeRef.FullName;
|
|
|
|
|
if (typeNames.TryGetValue(typeFullName, out nc))
|
2013-01-19 20:03:57 +08:00
|
|
|
|
return nc.Create();
|
2011-11-18 23:55:54 +08:00
|
|
|
|
|
2012-11-06 02:21:33 +08:00
|
|
|
|
var fullName = elementType == null ? typeRef.FullName : elementType.FullName;
|
2012-01-28 05:01:20 +08:00
|
|
|
|
string shortName;
|
|
|
|
|
var dict = prefix == "" ? fullNameToShortName : fullNameToShortNamePrefix;
|
|
|
|
|
if (!dict.TryGetValue(fullName, out shortName)) {
|
|
|
|
|
fullName = fullName.Replace('/', '.');
|
|
|
|
|
int index = fullName.LastIndexOf('.');
|
|
|
|
|
shortName = index > 0 ? fullName.Substring(index + 1) : fullName;
|
|
|
|
|
|
|
|
|
|
index = shortName.LastIndexOf('`');
|
|
|
|
|
if (index > 0)
|
|
|
|
|
shortName = shortName.Substring(0, index);
|
|
|
|
|
}
|
2011-11-18 23:55:54 +08:00
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
return AddTypeName(typeFullName, shortName, prefix).Create();
|
2011-11-24 12:25:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
bool IsFnPtrSig(TypeSig sig) {
|
2012-11-05 09:42:48 +08:00
|
|
|
|
while (sig != null) {
|
|
|
|
|
if (sig is FnPtrSig)
|
|
|
|
|
return true;
|
|
|
|
|
sig = sig.Next;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
bool IsGenericParam(ITypeDefOrRef tdr) {
|
2012-11-04 07:50:24 +08:00
|
|
|
|
var ts = tdr as TypeSpec;
|
2012-11-05 05:41:45 +08:00
|
|
|
|
if (ts == null)
|
2012-11-04 07:50:24 +08:00
|
|
|
|
return false;
|
|
|
|
|
var sig = ts.TypeSig.RemovePinnedAndModifiers();
|
|
|
|
|
return sig is GenericSig;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
static string GetPrefix(TypeSig typeRef) {
|
2011-11-24 12:25:04 +08:00
|
|
|
|
string prefix = "";
|
2012-11-04 07:50:24 +08:00
|
|
|
|
while (typeRef != null) {
|
2012-01-28 05:01:20 +08:00
|
|
|
|
if (typeRef.IsPointer)
|
|
|
|
|
prefix += "p";
|
2012-11-04 07:50:24 +08:00
|
|
|
|
typeRef = typeRef.Next;
|
2011-11-24 12:25:04 +08:00
|
|
|
|
}
|
|
|
|
|
return prefix;
|
2011-11-18 23:55:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
protected INameCreator AddTypeName(string fullName, string newName, string prefix) {
|
|
|
|
|
newName = FixName(prefix, newName);
|
2011-11-18 23:55:54 +08:00
|
|
|
|
|
|
|
|
|
var name2 = " " + newName;
|
2011-11-22 15:14:34 +08:00
|
|
|
|
NameCreator nc;
|
2011-11-18 23:55:54 +08:00
|
|
|
|
if (!typeNames.TryGetValue(name2, out nc))
|
|
|
|
|
typeNames[name2] = nc = new NameCreator(newName + "_");
|
|
|
|
|
|
|
|
|
|
typeNames[fullName] = nc;
|
|
|
|
|
return nc;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
protected abstract string FixName(string prefix, string name);
|
2011-11-18 23:55:54 +08:00
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
public virtual TypeNames Merge(TypeNames other) {
|
2014-04-17 01:15:11 +08:00
|
|
|
|
if (this == other)
|
|
|
|
|
return this;
|
2011-11-22 15:14:34 +08:00
|
|
|
|
foreach (var pair in other.typeNames) {
|
2012-01-27 12:54:23 +08:00
|
|
|
|
NameCreator nc;
|
|
|
|
|
if (typeNames.TryGetValue(pair.Key, out nc))
|
2013-01-19 20:03:57 +08:00
|
|
|
|
nc.Merge(pair.Value);
|
2011-11-22 15:14:34 +08:00
|
|
|
|
else
|
2013-01-19 20:03:57 +08:00
|
|
|
|
typeNames[pair.Key] = pair.Value.Clone();
|
2011-11-22 15:14:34 +08:00
|
|
|
|
}
|
2013-01-19 20:03:57 +08:00
|
|
|
|
genericParamNameCreator.Merge(other.genericParamNameCreator);
|
|
|
|
|
fnPtrNameCreator.Merge(other.fnPtrNameCreator);
|
|
|
|
|
unknownNameCreator.Merge(other.unknownNameCreator);
|
2011-11-22 15:14:34 +08:00
|
|
|
|
return this;
|
2011-11-18 23:55:54 +08:00
|
|
|
|
}
|
2011-11-24 12:25:04 +08:00
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
protected static string UpperFirst(string s) {
|
2012-11-06 08:59:40 +08:00
|
|
|
|
if (string.IsNullOrEmpty(s))
|
|
|
|
|
return string.Empty;
|
2011-11-24 12:25:04 +08:00
|
|
|
|
return s.Substring(0, 1).ToUpperInvariant() + s.Substring(1);
|
|
|
|
|
}
|
2011-11-18 23:55:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 19:29:48 +08:00
|
|
|
|
public class VariableNameCreator : TypeNames {
|
2012-01-28 05:01:20 +08:00
|
|
|
|
static Dictionary<string, string> ourFullNameToShortName;
|
|
|
|
|
static Dictionary<string, string> ourFullNameToShortNamePrefix;
|
|
|
|
|
static VariableNameCreator() {
|
|
|
|
|
ourFullNameToShortName = new Dictionary<string, string>(StringComparer.Ordinal) {
|
|
|
|
|
{ "System.Boolean", "bool" },
|
|
|
|
|
{ "System.Byte", "byte" },
|
|
|
|
|
{ "System.Char", "char" },
|
|
|
|
|
{ "System.Double", "double" },
|
|
|
|
|
{ "System.Int16", "short" },
|
|
|
|
|
{ "System.Int32", "int" },
|
|
|
|
|
{ "System.Int64", "long" },
|
|
|
|
|
{ "System.IntPtr", "intptr" },
|
|
|
|
|
{ "System.SByte", "sbyte" },
|
|
|
|
|
{ "System.Single", "float" },
|
|
|
|
|
{ "System.String", "string" },
|
|
|
|
|
{ "System.UInt16", "ushort" },
|
|
|
|
|
{ "System.UInt32", "uint" },
|
|
|
|
|
{ "System.UInt64", "ulong" },
|
|
|
|
|
{ "System.UIntPtr", "uintptr" },
|
|
|
|
|
{ "System.Decimal", "decimal" },
|
|
|
|
|
};
|
|
|
|
|
ourFullNameToShortNamePrefix = new Dictionary<string, string>(StringComparer.Ordinal) {
|
|
|
|
|
{ "System.Boolean", "Bool" },
|
|
|
|
|
{ "System.Byte", "Byte" },
|
|
|
|
|
{ "System.Char", "Char" },
|
|
|
|
|
{ "System.Double", "Double" },
|
|
|
|
|
{ "System.Int16", "Short" },
|
|
|
|
|
{ "System.Int32", "Int" },
|
|
|
|
|
{ "System.Int64", "Long" },
|
|
|
|
|
{ "System.IntPtr", "IntPtr" },
|
|
|
|
|
{ "System.SByte", "SByte" },
|
|
|
|
|
{ "System.Single", "Float" },
|
|
|
|
|
{ "System.String", "String" },
|
|
|
|
|
{ "System.UInt16", "UShort" },
|
|
|
|
|
{ "System.UInt32", "UInt" },
|
|
|
|
|
{ "System.UInt64", "ULong" },
|
|
|
|
|
{ "System.UIntPtr", "UIntPtr" },
|
|
|
|
|
{ "System.Decimal", "Decimal" },
|
|
|
|
|
};
|
2011-12-02 05:30:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-01-28 05:01:20 +08:00
|
|
|
|
public VariableNameCreator() {
|
|
|
|
|
fullNameToShortName = ourFullNameToShortName;
|
|
|
|
|
fullNameToShortNamePrefix = ourFullNameToShortNamePrefix;
|
2011-11-22 15:14:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
static string LowerLeadingChars(string name) {
|
2011-11-18 23:55:54 +08:00
|
|
|
|
var s = "";
|
|
|
|
|
for (int i = 0; i < name.Length; i++) {
|
|
|
|
|
char c = char.ToLowerInvariant(name[i]);
|
|
|
|
|
if (c == name[i])
|
|
|
|
|
return s + name.Substring(i);
|
|
|
|
|
s += c;
|
|
|
|
|
}
|
|
|
|
|
return s;
|
|
|
|
|
}
|
2011-11-24 12:25:04 +08:00
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
protected override string FixName(string prefix, string name) {
|
|
|
|
|
name = LowerLeadingChars(name);
|
2011-11-24 12:25:04 +08:00
|
|
|
|
if (prefix == "")
|
|
|
|
|
return name;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
return prefix + UpperFirst(name);
|
2011-11-24 12:25:04 +08:00
|
|
|
|
}
|
2011-11-18 23:55:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 19:29:48 +08:00
|
|
|
|
public class PropertyNameCreator : TypeNames {
|
2012-01-28 05:01:20 +08:00
|
|
|
|
static Dictionary<string, string> ourFullNameToShortName = new Dictionary<string, string>(StringComparer.Ordinal);
|
|
|
|
|
static Dictionary<string, string> ourFullNameToShortNamePrefix = new Dictionary<string, string>(StringComparer.Ordinal);
|
|
|
|
|
|
|
|
|
|
public PropertyNameCreator() {
|
|
|
|
|
fullNameToShortName = ourFullNameToShortName;
|
|
|
|
|
fullNameToShortNamePrefix = ourFullNameToShortNamePrefix;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
protected override string FixName(string prefix, string name) {
|
|
|
|
|
return prefix.ToUpperInvariant() + UpperFirst(name);
|
2011-11-18 23:55:54 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|