Refactor TypeInfo names and fix out/in
Replace the deeply nested ternaries in TypeInfo with if-statements for clarity. Remove in/out from CSharpName, keeping it only on immediate type params in CSharpTypeDeclarationName (refactored to a method). Rearrange name-related properties and methods to group them all together into a region for easier navigation.
This commit is contained in:
@@ -549,7 +549,7 @@ namespace Il2CppInspector.Outputs
|
|||||||
//sb.Append(del.ReturnType.CustomAttributes.ToString(prefix, "return: ", emitPointer: !SuppressMetadata, mustCompile: MustCompile));
|
//sb.Append(del.ReturnType.CustomAttributes.ToString(prefix, "return: ", emitPointer: !SuppressMetadata, mustCompile: MustCompile));
|
||||||
if (del.RequiresUnsafeContext)
|
if (del.RequiresUnsafeContext)
|
||||||
sb.Append("unsafe ");
|
sb.Append("unsafe ");
|
||||||
sb.Append($"delegate {del.ReturnType.GetScopedCSharpName(scope)} {type.CSharpTypeDeclarationName}(");
|
sb.Append($"delegate {del.ReturnType.GetScopedCSharpName(scope)} {type.GetCSharpTypeDeclarationName()}(");
|
||||||
sb.Append(del.GetParametersString(scope, !SuppressMetadata) + ");");
|
sb.Append(del.GetParametersString(scope, !SuppressMetadata) + ");");
|
||||||
if (!SuppressMetadata)
|
if (!SuppressMetadata)
|
||||||
sb.Append($" // TypeDefIndex: {type.Index}; {del.VirtualAddress.ToAddressString()}");
|
sb.Append($" // TypeDefIndex: {type.Index}; {del.VirtualAddress.ToAddressString()}");
|
||||||
@@ -566,7 +566,7 @@ namespace Il2CppInspector.Outputs
|
|||||||
@base.Insert(0, type.GetEnumUnderlyingType().GetScopedCSharpName(scope));
|
@base.Insert(0, type.GetEnumUnderlyingType().GetScopedCSharpName(scope));
|
||||||
var baseText = @base.Count > 0 ? " : " + string.Join(", ", @base) : string.Empty;
|
var baseText = @base.Count > 0 ? " : " + string.Join(", ", @base) : string.Empty;
|
||||||
|
|
||||||
sb.Append($"{type.CSharpTypeDeclarationName}{baseText}");
|
sb.Append($"{type.GetCSharpTypeDeclarationName()}{baseText}");
|
||||||
if (!SuppressMetadata)
|
if (!SuppressMetadata)
|
||||||
sb.Append($" // TypeDefIndex: {type.Index}");
|
sb.Append($" // TypeDefIndex: {type.Index}");
|
||||||
sb.Append("\n");
|
sb.Append("\n");
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ namespace Il2CppInspector.Reflection
|
|||||||
((Func<string>)(() => {
|
((Func<string>)(() => {
|
||||||
// This is some shenanigans because IL2CPP does not use a consistent naming scheme for explicit interface implementation method names
|
// This is some shenanigans because IL2CPP does not use a consistent naming scheme for explicit interface implementation method names
|
||||||
var implementingInterface = DeclaringType.ImplementedInterfaces.FirstOrDefault(i => Name.StartsWith(i.Namespace + "." + i.CSharpName + "."))
|
var implementingInterface = DeclaringType.ImplementedInterfaces.FirstOrDefault(i => Name.StartsWith(i.Namespace + "." + i.CSharpName + "."))
|
||||||
?? DeclaringType.ImplementedInterfaces.FirstOrDefault(i => Name.StartsWith(i.Namespace + "." + i.CSharpTypeDeclarationName.Replace(" ", "") + "."));
|
?? DeclaringType.ImplementedInterfaces.FirstOrDefault(i => Name.StartsWith(i.Namespace + "." + i.GetCSharpTypeDeclarationName().Replace(" ", "") + "."));
|
||||||
// TODO: There are some combinations we haven't dealt with so use this test as a safety valve
|
// TODO: There are some combinations we haven't dealt with so use this test as a safety valve
|
||||||
if (implementingInterface == null)
|
if (implementingInterface == null)
|
||||||
return Name;
|
return Name;
|
||||||
|
|||||||
@@ -34,51 +34,6 @@ namespace Il2CppInspector.Reflection {
|
|||||||
// True if the type contains unresolved generic type parameters
|
// True if the type contains unresolved generic type parameters
|
||||||
public bool ContainsGenericParameters => IsGenericParameter || genericArguments.Any(ga => ga.ContainsGenericParameters);
|
public bool ContainsGenericParameters => IsGenericParameter || genericArguments.Any(ga => ga.ContainsGenericParameters);
|
||||||
|
|
||||||
public string BaseName => base.Name;
|
|
||||||
|
|
||||||
// Get rid of generic backticks
|
|
||||||
public string UnmangledBaseName => base.Name.IndexOf("`", StringComparison.Ordinal) == -1 ? base.Name : base.Name.Remove(base.Name.IndexOf("`", StringComparison.Ordinal));
|
|
||||||
|
|
||||||
// C# colloquial name of the type (if available)
|
|
||||||
public string CSharpName {
|
|
||||||
get {
|
|
||||||
var s = Namespace + "." + base.Name;
|
|
||||||
var i = Il2CppConstants.FullNameTypeString.IndexOf(s);
|
|
||||||
var n = (i != -1 ? Il2CppConstants.CSharpTypeString[i] : base.Name);
|
|
||||||
if (n?.IndexOf("`", StringComparison.Ordinal) != -1)
|
|
||||||
n = n?.Remove(n.IndexOf("`", StringComparison.Ordinal));
|
|
||||||
n += (GetGenericArguments().Any()? "<" + string.Join(", ", GetGenericArguments().Select(x => x.CSharpName)) + ">" : "");
|
|
||||||
if (s == "System.Nullable`1" && GetGenericArguments().Any())
|
|
||||||
n = GetGenericArguments()[0].CSharpName + "?";
|
|
||||||
if (HasElementType)
|
|
||||||
n = ElementType.CSharpName;
|
|
||||||
if ((GenericParameterAttributes & GenericParameterAttributes.Covariant) == GenericParameterAttributes.Covariant)
|
|
||||||
n = "out " + n;
|
|
||||||
if ((GenericParameterAttributes & GenericParameterAttributes.Contravariant) == GenericParameterAttributes.Contravariant)
|
|
||||||
n = "in " + n;
|
|
||||||
if (IsByRef)
|
|
||||||
n = "ref " + n;
|
|
||||||
return n + (IsArray ? "[" + new string(',', GetArrayRank() - 1) + "]" : "") + (IsPointer ? "*" : "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// C# name as it would be written in a type declaration
|
|
||||||
public string CSharpTypeDeclarationName {
|
|
||||||
get {
|
|
||||||
var ga = IsNested ? GetGenericArguments().Where(p => DeclaringType.GetGenericArguments().All(dp => dp.Name != p.Name)) : GetGenericArguments();
|
|
||||||
|
|
||||||
return (IsByRef ? "ref " : "")
|
|
||||||
+ (HasElementType
|
|
||||||
? ElementType.CSharpTypeDeclarationName
|
|
||||||
: ((GenericParameterAttributes & GenericParameterAttributes.Contravariant) == GenericParameterAttributes.Contravariant ? "in " : "")
|
|
||||||
+ ((GenericParameterAttributes & GenericParameterAttributes.Covariant) == GenericParameterAttributes.Covariant ? "out " : "")
|
|
||||||
+ (base.Name.IndexOf("`", StringComparison.Ordinal) == -1 ? base.Name : base.Name.Remove(base.Name.IndexOf("`", StringComparison.Ordinal)))
|
|
||||||
+ (ga.Any()? "<" + string.Join(", ", ga.Select(x => (!x.IsGenericTypeParameter ? x.Namespace + "." : "") + x.CSharpTypeDeclarationName)) + ">" : ""))
|
|
||||||
+ (IsArray ? "[" + new string(',', GetArrayRank() - 1) + "]" : "")
|
|
||||||
+ (IsPointer ? "*" : "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Custom attributes for this member
|
// Custom attributes for this member
|
||||||
public override IEnumerable<CustomAttributeData> CustomAttributes => CustomAttributeData.GetCustomAttributes(this);
|
public override IEnumerable<CustomAttributeData> CustomAttributes => CustomAttributeData.GetCustomAttributes(this);
|
||||||
|
|
||||||
@@ -156,17 +111,125 @@ namespace Il2CppInspector.Reflection {
|
|||||||
// Gets the type of the object encompassed or referred to by the current array, pointer or reference type
|
// Gets the type of the object encompassed or referred to by the current array, pointer or reference type
|
||||||
public TypeInfo ElementType { get; }
|
public TypeInfo ElementType { get; }
|
||||||
|
|
||||||
|
#region Names
|
||||||
|
public string BaseName => base.Name;
|
||||||
|
|
||||||
|
private static string unmangleName(string name) {
|
||||||
|
var index = name.IndexOf("`", StringComparison.Ordinal);
|
||||||
|
if (index != -1)
|
||||||
|
name = name.Remove(index);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get rid of generic backticks
|
||||||
|
public string UnmangledBaseName => unmangleName(base.Name);
|
||||||
|
|
||||||
|
// C# colloquial name of the type (if available)
|
||||||
|
public string CSharpName {
|
||||||
|
get {
|
||||||
|
if (HasElementType) {
|
||||||
|
var n = ElementType.CSharpName;
|
||||||
|
if (IsByRef)
|
||||||
|
n = "ref " + n;
|
||||||
|
if (IsArray)
|
||||||
|
n += "[" + new string(',', GetArrayRank() - 1) + "]";
|
||||||
|
if (IsPointer)
|
||||||
|
n += "*";
|
||||||
|
return n;
|
||||||
|
} else {
|
||||||
|
var s = Namespace + "." + base.Name;
|
||||||
|
var i = Il2CppConstants.FullNameTypeString.IndexOf(s);
|
||||||
|
var n = (i != -1 ? Il2CppConstants.CSharpTypeString[i] : base.Name);
|
||||||
|
n = unmangleName(n);
|
||||||
|
var ga = GetGenericArguments();
|
||||||
|
if (ga.Any())
|
||||||
|
n += "<" + string.Join(", ", ga.Select(x => x.CSharpName)) + ">";
|
||||||
|
if (s == "System.Nullable`1" && ga.Any())
|
||||||
|
n = ga[0].CSharpName + "?";
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// C# name as it would be written in a type declaration
|
||||||
|
public string GetCSharpTypeDeclarationName(bool includeVariance = false) {
|
||||||
|
if (HasElementType) {
|
||||||
|
var n = ElementType.GetCSharpTypeDeclarationName();
|
||||||
|
if (IsByRef)
|
||||||
|
n = "ref " + n;
|
||||||
|
if (IsArray)
|
||||||
|
n += "[" + new string(',', GetArrayRank() - 1) + "]";
|
||||||
|
if (IsPointer)
|
||||||
|
n += "*";
|
||||||
|
return n;
|
||||||
|
} else {
|
||||||
|
var n = unmangleName(base.Name);
|
||||||
|
var ga = IsNested ? GetGenericArguments().Where(p => DeclaringType.GetGenericArguments().All(dp => dp.Name != p.Name)) : GetGenericArguments();
|
||||||
|
if (ga.Any())
|
||||||
|
n += "<" + string.Join(", ", ga.Select(x => (!x.IsGenericTypeParameter ? x.Namespace + "." : "") + x.GetCSharpTypeDeclarationName(includeVariance: true))) + ">";
|
||||||
|
if (includeVariance) {
|
||||||
|
if ((GenericParameterAttributes & GenericParameterAttributes.Covariant) == GenericParameterAttributes.Covariant)
|
||||||
|
n = "out " + n;
|
||||||
|
if ((GenericParameterAttributes & GenericParameterAttributes.Contravariant) == GenericParameterAttributes.Contravariant)
|
||||||
|
n = "in " + n;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display name of object
|
||||||
|
public override string Name {
|
||||||
|
get {
|
||||||
|
if (IsGenericParameter)
|
||||||
|
return base.Name;
|
||||||
|
if (HasElementType) {
|
||||||
|
var n = ElementType.Name;
|
||||||
|
if (IsArray)
|
||||||
|
n += "[" + new string(',', GetArrayRank() - 1) + "]";
|
||||||
|
if (IsByRef)
|
||||||
|
n += "&";
|
||||||
|
if (IsPointer)
|
||||||
|
n += "*";
|
||||||
|
return n;
|
||||||
|
} else {
|
||||||
|
var n = base.Name;
|
||||||
|
if (DeclaringType != null)
|
||||||
|
n = DeclaringType.Name + "+" + n;
|
||||||
|
var ga = GetGenericArguments();
|
||||||
|
if (ga.Any())
|
||||||
|
n += "[" + string.Join(",", ga.Select(x => x.Namespace != Namespace ? x.FullName ?? x.Name : x.Name)) + "]";
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Type name including namespace
|
// Type name including namespace
|
||||||
// Fully qualified generic type names from the C# compiler use backtick and arity rather than a list of generic arguments
|
// Fully qualified generic type names from the C# compiler use backtick and arity rather than a list of generic arguments
|
||||||
public string FullName =>
|
public string FullName {
|
||||||
IsGenericParameter? null :
|
get {
|
||||||
HasElementType && ElementType.IsGenericParameter? null :
|
if (IsGenericParameter)
|
||||||
(HasElementType? ElementType.FullName :
|
return null;
|
||||||
(DeclaringType != null? DeclaringType.FullName + "+" : Namespace + (Namespace.Length > 0? "." : ""))
|
if (HasElementType) {
|
||||||
+ base.Name)
|
var n = ElementType.FullName;
|
||||||
+ (IsArray? "[" + new string(',', GetArrayRank() - 1) + "]" : "")
|
if(n == null)
|
||||||
+ (IsByRef? "&" : "")
|
return null;
|
||||||
+ (IsPointer? "*" : "");
|
if (IsArray)
|
||||||
|
n += "[" + new string(',', GetArrayRank() - 1) + "]";
|
||||||
|
if (IsByRef)
|
||||||
|
n += "&";
|
||||||
|
if (IsPointer)
|
||||||
|
n += "*";
|
||||||
|
return n;
|
||||||
|
} else {
|
||||||
|
var n = base.Name;
|
||||||
|
if (DeclaringType != null)
|
||||||
|
n = DeclaringType.FullName + "+" + n;
|
||||||
|
else if (Namespace.Length > 0)
|
||||||
|
n = Namespace + "." + n;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the minimally qualified type name required to refer to this type within the specified scope
|
// Returns the minimally qualified type name required to refer to this type within the specified scope
|
||||||
private string getScopedFullName(Scope scope) {
|
private string getScopedFullName(Scope scope) {
|
||||||
@@ -315,10 +378,7 @@ namespace Il2CppInspector.Reflection {
|
|||||||
// Built-in keyword type names do not require a scope
|
// Built-in keyword type names do not require a scope
|
||||||
var i = Il2CppConstants.FullNameTypeString.IndexOf(s);
|
var i = Il2CppConstants.FullNameTypeString.IndexOf(s);
|
||||||
var n = i != -1 ? Il2CppConstants.CSharpTypeString[i] : getScopedFullName(usingScope);
|
var n = i != -1 ? Il2CppConstants.CSharpTypeString[i] : getScopedFullName(usingScope);
|
||||||
|
n = unmangleName(n);
|
||||||
// Unmangle generic type names
|
|
||||||
if (n?.IndexOf("`", StringComparison.Ordinal) != -1)
|
|
||||||
n = n?.Remove(n.IndexOf("`", StringComparison.Ordinal));
|
|
||||||
|
|
||||||
// Generic type parameters and type arguments
|
// Generic type parameters and type arguments
|
||||||
// Inheriting from a base class or implementing an interface use the type's declaring scope, not the type's scope itself
|
// Inheriting from a base class or implementing an interface use the type's declaring scope, not the type's scope itself
|
||||||
@@ -341,6 +401,7 @@ namespace Il2CppInspector.Reflection {
|
|||||||
|
|
||||||
return (IsByRef && !omitRef? "ref " : "") + n + (IsArray ? "[" + new string(',', GetArrayRank() - 1) + "]" : "") + (IsPointer ? "*" : "");
|
return (IsByRef && !omitRef? "ref " : "") + n + (IsArray ? "[" + new string(',', GetArrayRank() - 1) + "]" : "") + (IsPointer ? "*" : "");
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
// Get the generic type parameters for a specific usage of this type based on its scope,
|
// Get the generic type parameters for a specific usage of this type based on its scope,
|
||||||
// or all generic type parameters if no scope specified
|
// or all generic type parameters if no scope specified
|
||||||
@@ -860,16 +921,6 @@ namespace Il2CppInspector.Reflection {
|
|||||||
return refList.ToList();
|
return refList.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display name of object
|
|
||||||
public override string Name => IsGenericParameter ? base.Name :
|
|
||||||
(HasElementType? ElementType.Name :
|
|
||||||
(DeclaringType != null ? DeclaringType.Name + "+" : "")
|
|
||||||
+ base.Name
|
|
||||||
+ (GetGenericArguments().Any()? "[" + string.Join(",", GetGenericArguments().Select(x => x.Namespace != Namespace? x.FullName ?? x.Name : x.Name)) + "]" : ""))
|
|
||||||
+ (IsArray ? "[" + new string(',', GetArrayRank() - 1) + "]" : "")
|
|
||||||
+ (IsByRef ? "&" : "")
|
|
||||||
+ (IsPointer ? "*" : "");
|
|
||||||
|
|
||||||
public string GetAccessModifierString() => this switch {
|
public string GetAccessModifierString() => this switch {
|
||||||
{ IsPublic: true } => "public ",
|
{ IsPublic: true } => "public ",
|
||||||
{ IsNotPublic: true } => "internal ",
|
{ IsNotPublic: true } => "internal ",
|
||||||
|
|||||||
Reference in New Issue
Block a user