From 42310483afc52229d5a56db591bc95547386a376 Mon Sep 17 00:00:00 2001 From: Katy Coe Date: Mon, 22 Jun 2020 22:35:32 +0200 Subject: [PATCH] CS: Fix "Namespace used like type" (CS0118) (needs additional work) --- .../Reflection/Il2CppModel.cs | 6 ++++++ Il2CppInspector.Common/Reflection/TypeInfo.cs | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/Il2CppInspector.Common/Reflection/Il2CppModel.cs b/Il2CppInspector.Common/Reflection/Il2CppModel.cs index 72f3e89..84300bd 100644 --- a/Il2CppInspector.Common/Reflection/Il2CppModel.cs +++ b/Il2CppInspector.Common/Reflection/Il2CppModel.cs @@ -16,6 +16,9 @@ namespace Il2CppInspector.Reflection public Il2CppInspector Package { get; } public List Assemblies { get; } = new List(); + // List of all namespaces defined by the application + public List Namespaces { get; } + // List of all types from TypeDefs ordered by their TypeDefinitionIndex public TypeInfo[] TypesByDefinitionIndex { get; } @@ -113,6 +116,9 @@ namespace Il2CppInspector.Reflection GenericMethods[spec] = method; } + // Generate a list of all namespaces used + Namespaces = Assemblies.SelectMany(x => x.DefinedTypes).GroupBy(t => t.Namespace).Select(n => n.Key).Distinct().ToList(); + // Find all custom attribute generators (populate AttributesByIndices) (use ToList() to force evaluation) var allAssemblyAttributes = Assemblies.Select(a => a.CustomAttributes).ToList(); var allTypeAttributes = TypesByDefinitionIndex.Select(t => t.CustomAttributes).ToList(); diff --git a/Il2CppInspector.Common/Reflection/TypeInfo.cs b/Il2CppInspector.Common/Reflection/TypeInfo.cs index afb50db..49d6c21 100644 --- a/Il2CppInspector.Common/Reflection/TypeInfo.cs +++ b/Il2CppInspector.Common/Reflection/TypeInfo.cs @@ -524,6 +524,27 @@ namespace Il2CppInspector.Reflection if (matchingNamespaces.Count == 0 && !hidden && string.IsNullOrEmpty(mutualRootScope) && usingDirective == null) minimallyScopedName = usedType; } + + // Finally, check if the selected name has ambiguity with any available namespaces in the current scope + // If so, use the full name with the mutual root scope cut off from the start + var checkNamespaces = scope.Namespaces.Select(ns => (!string.IsNullOrEmpty(ns)? ns + "." : "") + minimallyScopedName).ToList(); + + if (Assembly.Model.Namespaces.Intersect(checkNamespaces).Any()) + minimallyScopedName = mutualRootScope.Length > 0 ? usedType.Substring(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); + } + + if (Assembly.Model.Namespaces.Intersect(checkNamespaces).Any()) + minimallyScopedName = mutualRootScope.Length > 0 ? usedType.Substring(mutualRootScope.Length + 1) : "global::" + usedType; + } + return minimallyScopedName; }