Update getScopedFullName for generic params + update README

This commit is contained in:
LukeFZ
2024-02-25 11:32:20 +01:00
parent 0f7cd027c3
commit 2a492e02ba
2 changed files with 26 additions and 14 deletions

View File

@@ -412,9 +412,14 @@ namespace Il2CppInspector.Reflection
}
// 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)
{
// Generic type parameters take precedence over all other names, so if FullName is null (== generic) we can just return the name itself
if (IsGenericParameter)
return this.Name;
// This is the type to be used (generic type parameters have a null FullName)
var usedType = FullName?.Replace('+', '.') ?? Name;
var usedType = FullName.Replace('+', '.');
// This is the scope in which this type is currently being used
// If Scope.Current is null, our scope is at the assembly level
@@ -439,14 +444,14 @@ namespace Il2CppInspector.Reflection
declaringScope += ".";
while (usingScope.IndexOf('.', diff) == declaringScope.IndexOf('.', diff)
&& usingScope.IndexOf('.', diff) != -1
&& usingScope.Substring(0, usingScope.IndexOf('.', diff))
== declaringScope.Substring(0, declaringScope.IndexOf('.', diff)))
&& usingScope[..usingScope.IndexOf('.', diff)]
== declaringScope[..declaringScope.IndexOf('.', diff)])
diff = usingScope.IndexOf('.', diff) + 1;
usingScope = usingScope.Remove(usingScope.Length - 1);
declaringScope = declaringScope.Remove(declaringScope.Length - 1);
// This is the mutual root namespace and optionally nested types that the two scopes share
var mutualRootScope = usingScope.Substring(0, diff - 1);
var mutualRootScope = usingScope[..(diff - 1)];
// Determine if the using scope is a child of the declaring scope (always a child if declaring scope is empty)
var usingScopeIsChildOfDeclaringScope = string.IsNullOrEmpty(declaringScope) || (usingScope + ".").StartsWith(declaringScope + ".");
@@ -472,7 +477,7 @@ namespace Il2CppInspector.Reflection
var minimallyScopedName =
declaringScope == mutualRootScope ? base.Name :
string.IsNullOrEmpty(mutualRootScope) ? declaringScope + '.' + base.Name :
declaringScope.Substring(mutualRootScope.Length + 1) + '.' + base.Name;
string.Concat(declaringScope.AsSpan(mutualRootScope.Length + 1), ".", base.Name);
// Find the outermost type name if the wanted type is a nested type (if we need it below)
string outerTypeName = "";
@@ -487,7 +492,7 @@ namespace Il2CppInspector.Reflection
// Otherwise, we just try the unqualified outer (least nested) type name to make sure it's accessible
// and revert to the fully qualified name if it's hidden
var nsAndTypeHierarchy = usingScopeIsChildOfDeclaringScope ?
usingDirective.Split('.').Append(minimallyScopedName).ToArray()
[.. usingDirective.Split('.'), minimallyScopedName]
: new[] { outerTypeName };
var hidden = true;
@@ -548,24 +553,24 @@ namespace Il2CppInspector.Reflection
.Select(ns => (!string.IsNullOrEmpty(ns)? ns + "." : "") + minimallyScopedName).ToList() ?? new List<string>();
if (Assembly.Model.Namespaces.Intersect(checkNamespaces).Any())
minimallyScopedName = mutualRootScope.Length > 0 ? usedType.Substring(mutualRootScope.Length + 1) : usedType;
minimallyScopedName = mutualRootScope.Length > 0 ? usedType[(mutualRootScope.Length + 1)..] : usedType;
// Check current namespace and all ancestors too
else {
checkNamespaces.Clear();
var ancestorUsingScope = "." + usingScope;
while (ancestorUsingScope.IndexOf(".", StringComparison.Ordinal) != -1) {
ancestorUsingScope = ancestorUsingScope.Substring(0, ancestorUsingScope.LastIndexOf(".", StringComparison.Ordinal));
checkNamespaces.Add((ancestorUsingScope.Length > 0 ? ancestorUsingScope.Substring(1) + "." : "") + minimallyScopedName);
while (ancestorUsingScope.Contains('.')) {
ancestorUsingScope = ancestorUsingScope[..ancestorUsingScope.LastIndexOf('.')];
checkNamespaces.Add((ancestorUsingScope.Length > 0 ? ancestorUsingScope[1..] + "." : "") + minimallyScopedName);
}
if (Assembly.Model.Namespaces.Intersect(checkNamespaces).Any())
minimallyScopedName = mutualRootScope.Length > 0 ? usedType.Substring(mutualRootScope.Length + 1) : "global::" + usedType;
minimallyScopedName = mutualRootScope.Length > 0 ? usedType[(mutualRootScope.Length + 1)..] : "global::" + usedType;
}
// If the final name starts with ".", it's a reference to the global namespace (ie. unnamed root namespace)
if (minimallyScopedName.StartsWith("."))
minimallyScopedName = "global::" + minimallyScopedName.Substring(1);
if (minimallyScopedName.StartsWith('.'))
minimallyScopedName = "global::" + minimallyScopedName[1..];
return minimallyScopedName;
}

View File

@@ -20,6 +20,13 @@ This is a continuation of [Il2CppInspector, by djkaty](https://github.com/djkaty
- Made ValueTypes use their non-boxed variants when used as the this parameter
- Added labeling of FieldInfo/FieldRva MetadataUsages and their respective values as comments
- Implemented name mangling to properly display generics and other normally-replaced characters
* Overhauled IDA script:
- Added a progress indicator box with the current step, progress, and elapsed time
- Much faster processing compared to the old version
- Automatic disabling and re-enabling of autoanalysis
- Automatic unloading of conflicting type libraries
- Addition of custom fake string segment to show string literal contents in decompiler
- A fake xref between MethodInfo instances and their corresponding method to quickly get the correct function
### Main features