/* * Moves all private types of the given class into the new namespace. */ public static bool MovePrivateTypesToNamespace(this IRClass irClass, IRNamespace targetNamespace, IRNamespace sourceNamespace) { var types = irClass.PrivateTypes; var privateEnums = types.Where(t => t is IREnum).Cast <IREnum>().ToList(); var privateClasses = types.Where(t => t is IRClass).Cast <IRClass>().ToList(); // Remove all types from the old namespace. sourceNamespace.Classes.RemoveAll(c => privateClasses.Contains(c)); sourceNamespace.Enums.RemoveAll(e => privateEnums.Contains(e)); // Add all types into the new namespace. targetNamespace.Classes.AddRange(privateClasses); targetNamespace.Enums.AddRange(privateEnums); foreach (var movedType in types) { movedType.UpdateTypeReferences(targetNamespace, sourceNamespace); } // Private types can also be IRClasses, so recursively perform the same operation on each // private class. foreach (var privateClass in privateClasses) { privateClass.MovePrivateTypesToNamespace(targetNamespace, sourceNamespace); } return(true); }
/* * Updates the parent for non private types. */ public static void UpdateParent(this IRTypeNode type, IRNamespace newNS) { if (type.IsPrivate == false) { type.Parent = newNS; } else { // We leave private types alone because they must keep referencing their parent class. } }
/* * MoveTypeToNamespace retrieves the type matching typeFullName and moves it from the original namespace * into the target namespace. * * Returns true if the type was found and moved. False if the type was not found. */ public static bool MovePublicTypeToNamespace(this IRProgram program, string typeFullName, IRNamespace targetNamespace, StringComparison casing = StringComparison.Ordinal) { bool found = false; IRNamespace sourceNS = null; IRClass foundClass = null; IREnum foundEnum = null; // Locate the type - could be class or enum. foreach (var ns in program.Namespaces) { foundClass = ns.Classes.FirstOrDefault(c => c.FullName.Equals(typeFullName, casing)); foundEnum = ns.Enums.FirstOrDefault(e => e.FullName.Equals(typeFullName, casing)); // If found, remove it from the parent namespace. if (foundClass != null || foundEnum != null) { // We don't move private types! if (foundClass?.IsPrivate == true || foundEnum?.IsPrivate == true) { throw new IRMoveException("This method does not move private types!"); } ns.Classes.Remove(foundClass); ns.Enums.Remove(foundEnum); found = true; sourceNS = ns; break; } } // Add the type to the target namespace. if (found) { if (foundClass != null) { targetNamespace.Classes.Add(foundClass); foundClass.UpdateTypeReferences(targetNamespace, sourceNS); // And move all private types under the new namespace. foundClass.MovePrivateTypesToNamespace(targetNamespace, sourceNS); } else if (foundEnum != null) { targetNamespace.Enums.Add(foundEnum); foundEnum.UpdateTypeReferences(targetNamespace, sourceNS); } } return(found); }
/* * GetCreateNamespace looks through the program for the namespace object matching the * given fullname. * If no namespace object is found, it is created and inserted into program. */ public static IRNamespace GetCreateNamespace(this IRProgram program, string nsFullName) { var targetNS = program.Namespaces.FirstOrDefault(ns => ns.FullName.Equals(nsFullName, StringComparison.OrdinalIgnoreCase)); if (targetNS == null) { // Namespace names should always be lowercased! targetNS = new IRNamespace(nsFullName.ToLower(), null); program.Namespaces.Add(targetNS); } return(targetNS); }
/* * Updates the naming of the given type. */ public static void UpdateTypeName(this IRTypeNode type, IRNamespace newNS) { // Only update the full name. type.FullName = newNS.FullName.Trim('.') + "." + type.ShortName; // Don't touch the shortname! }
/* * Updates all references made from the given type to other types. */ public static void UpdateTypeReferences(this IRTypeNode type, IRNamespace newNS, IRNamespace oldNS) { type.UpdateTypeName(newNS); type.UpdateParent(newNS); }