/// <summary> /// Arranges the code elements according to the configuration supplied /// in the constructor. /// </summary> /// <param name="originalElements">Original elements</param> /// <returns>An arranged collection of code elements.</returns> public ReadOnlyCollection<ICodeElement> Arrange(ReadOnlyCollection<ICodeElement> originalElements) { GroupElement rootElement = new GroupElement(); if (originalElements != null) { List<ICodeElement> elements = new List<ICodeElement>(); NamespaceElement firstNamespace = null; for (int elementIndex = 0; elementIndex < originalElements.Count; elementIndex++) { ICodeElement element = originalElements[elementIndex]; ICodeElement elementClone = element.Clone() as ICodeElement; elements.Add(elementClone); if (firstNamespace == null) { Action<ICodeElement> findFirstNamespace = delegate(ICodeElement processElement) { if (firstNamespace == null) { NamespaceElement namespaceElement = processElement as NamespaceElement; if (namespaceElement != null) { firstNamespace = namespaceElement; } } }; ElementUtilities.ProcessElementTree(elementClone, findFirstNamespace); } } MoveUsings(elements, firstNamespace); foreach (ICodeElement element in elements) { ArrangerChain.ArrangeElement(rootElement, element); } } List<ICodeElement> arranged = new List<ICodeElement>(rootElement.Children); foreach (ICodeElement arrangedElement in arranged) { // Remove the root element as the parent. arrangedElement.Parent = null; } return arranged.AsReadOnly(); }
/// <summary> /// Processes a group element. /// </summary> /// <param name="element">Group element.</param> public virtual void VisitGroupElement(GroupElement element) { // // Process all children // for (int childIndex = 0; childIndex < element.Children.Count; childIndex++) { ICodeElement childElement = element.Children[childIndex]; FieldElement childFieldElement = childElement as FieldElement; if (childIndex > 0 && childFieldElement != null && childFieldElement.HeaderComments.Count > 0) { WriteIndentedLine(); } childElement.Accept(this); if (childIndex < element.Children.Count - 1) { if (element.SeparatorType == GroupSeparatorType.Custom) { WriteIndentedLine(element.CustomSeparator); } else { WriteIndentedLine(); } if (childElement is GroupElement) { WriteIndentedLine(); } } } }
public void NestedGroupSortTest() { GroupBy groupBy = new GroupBy(); groupBy.By = ElementAttributeType.Type; groupBy.Direction = SortDirection.Ascending; GroupBy innerGroupBy = new GroupBy(); innerGroupBy.By = ElementAttributeType.Name; innerGroupBy.AttributeCapture = "^(.*?)(\\.|$)"; innerGroupBy.Direction = SortDirection.Ascending; groupBy.InnerGroupBy = innerGroupBy; SortBy sortBy = new SortBy(); sortBy.By = ElementAttributeType.Name; SortedInserter sortedInserter = new SortedInserter(ElementType.NotSpecified, sortBy); GroupedInserter groupedInserter = new GroupedInserter( groupBy, new GroupedInserter(groupBy.InnerGroupBy, sortedInserter)); // // Create a parent element // GroupElement groupElement = new GroupElement(); Assert.AreEqual(0, groupElement.Children.Count, "Parent element should not have any children."); // Insert elements groupedInserter.InsertElement(groupElement, new UsingElement("NUnit.Framework")); groupedInserter.InsertElement(groupElement, new UsingElement("NArrange.Core")); groupedInserter.InsertElement(groupElement, new UsingElement("NArrange.CSharp")); groupedInserter.InsertElement(groupElement, new UsingElement("NArrange.Core.Configuration")); groupedInserter.InsertElement(groupElement, new UsingElement("System")); groupedInserter.InsertElement(groupElement, new UsingElement("System.IO")); groupedInserter.InsertElement(groupElement, new UsingElement("MyClass2", "NArrange.Core.CodeArranger")); groupedInserter.InsertElement(groupElement, new UsingElement("MyClass1", "NArrange.Core.ElementFilter")); Assert.AreEqual(2, groupElement.Children.Count, "Unexpected number of child groups."); GroupElement childGroup; GroupElement grandchildGroup; // Namespace usings should come before alias usings childGroup = groupElement.Children[0] as GroupElement; Assert.IsNotNull(childGroup, "Expected a child group."); Assert.AreEqual(3, childGroup.Children.Count, "Unexpected number of group children."); // System usings should always come first grandchildGroup = childGroup.Children[0] as GroupElement; Assert.IsNotNull(grandchildGroup, "Expected a child group."); Assert.AreEqual(2, grandchildGroup.Children.Count, "Unexpected number of group children."); Assert.AreEqual("System", grandchildGroup.Children[0].Name); Assert.AreEqual("System.IO", grandchildGroup.Children[1].Name); grandchildGroup = childGroup.Children[1] as GroupElement; Assert.IsNotNull(grandchildGroup, "Expected a child group."); Assert.AreEqual(3, grandchildGroup.Children.Count, "Unexpected number of group children."); Assert.AreEqual("NArrange.Core", grandchildGroup.Children[0].Name); Assert.AreEqual("NArrange.Core.Configuration", grandchildGroup.Children[1].Name); Assert.AreEqual("NArrange.CSharp", grandchildGroup.Children[2].Name); grandchildGroup = childGroup.Children[2] as GroupElement; Assert.IsNotNull(grandchildGroup, "Expected a child group."); Assert.AreEqual(1, grandchildGroup.Children.Count, "Unexpected number of group children."); Assert.AreEqual("NUnit.Framework", grandchildGroup.Children[0].Name); // Alias using directives childGroup = groupElement.Children[1] as GroupElement; Assert.IsNotNull(childGroup, "Expected a child group."); Assert.AreEqual(2, childGroup.Children.Count, "Unexpected number of group children."); grandchildGroup = childGroup.Children[0] as GroupElement; Assert.AreEqual(1, grandchildGroup.Children.Count, "Unexpected number of group children."); Assert.AreEqual("MyClass1", grandchildGroup.Children[0].Name); grandchildGroup = childGroup.Children[1] as GroupElement; Assert.AreEqual(1, grandchildGroup.Children.Count, "Unexpected number of group children."); Assert.AreEqual("MyClass2", grandchildGroup.Children[0].Name); }
public void GroupSortByAccessTest() { GroupBy groupBy = new GroupBy(); groupBy.By = ElementAttributeType.Access; groupBy.Direction = SortDirection.Ascending; GroupedInserter groupedInserter = new GroupedInserter(groupBy); // // Create a parent element // GroupElement groupElement = new GroupElement(); Assert.AreEqual(0, groupElement.Children.Count, "Parent element should not have any children."); // Insert elements PropertyElement property1 = new PropertyElement(); property1.Access = CodeAccess.Internal; property1.Name = "Property1"; property1.Type = "string"; groupedInserter.InsertElement(groupElement, property1); PropertyElement property2 = new PropertyElement(); property2.Access = CodeAccess.Public; property2.Name = "Property2"; property2.Type = "string"; groupedInserter.InsertElement(groupElement, property2); PropertyElement property3 = new PropertyElement(); property3.Access = CodeAccess.Protected | CodeAccess.Internal; property3.Name = "Property3"; property3.Type = "string"; groupedInserter.InsertElement(groupElement, property3); PropertyElement property4 = new PropertyElement(); property4.Access = CodeAccess.Private; property4.Name = "Property4"; property4.Type = "string"; groupedInserter.InsertElement(groupElement, property4); PropertyElement property5 = new PropertyElement(); property5.Access = CodeAccess.Public; property5.Name = "Property5"; property5.Type = "string"; groupedInserter.InsertElement(groupElement, property5); Assert.AreEqual(4, groupElement.Children.Count, "Unexpected number of child groups."); GroupElement childGroup; childGroup = groupElement.Children[0] as GroupElement; Assert.IsNotNull(childGroup, "Expected a child group."); Assert.AreEqual(1, childGroup.Children.Count, "Unexpected number of group children."); Assert.AreEqual("Property4", childGroup.Children[0].Name); childGroup = groupElement.Children[1] as GroupElement; Assert.IsNotNull(childGroup, "Expected a child group."); Assert.AreEqual(1, childGroup.Children.Count, "Unexpected number of group children."); Assert.AreEqual("Property1", childGroup.Children[0].Name); childGroup = groupElement.Children[2] as GroupElement; Assert.IsNotNull(childGroup, "Expected a child group."); Assert.AreEqual(1, childGroup.Children.Count, "Unexpected number of group children."); Assert.AreEqual("Property3", childGroup.Children[0].Name); childGroup = groupElement.Children[3] as GroupElement; Assert.IsNotNull(childGroup, "Expected a child group."); Assert.AreEqual(2, childGroup.Children.Count, "Unexpected number of group children."); Assert.AreEqual("Property2", childGroup.Children[0].Name); Assert.AreEqual("Property5", childGroup.Children[1].Name); }
public void InsertTest() { GroupBy groupBy = new GroupBy(); groupBy.By = ElementAttributeType.Name; groupBy.AttributeCapture = "^(.*?)(\\.|$)"; GroupedInserter groupedInserter = new GroupedInserter(groupBy); // // Create a parent element // GroupElement groupElement = new GroupElement(); Assert.AreEqual(0, groupElement.Children.Count, "Parent element should not have any children."); // // With no criteria specified, elements should just be inserted // at the end of the collection. // UsingElement using1 = new UsingElement(); using1.Name = "System.IO"; groupedInserter.InsertElement(groupElement, using1); Assert.AreEqual(1, groupElement.Children.Count, "Group element was not inserted into the parent."); Assert.IsTrue(groupElement.Children[0] is GroupElement, "Group element was not inserted into the parent."); Assert.AreEqual(1, groupElement.Children[0].Children.Count, "Element was not inserted into the parent."); Assert.AreEqual(0, groupElement.Children[0].Children.IndexOf(using1), "Element was not inserted at the correct index."); UsingElement using2 = new UsingElement(); using2.Name = "System"; groupedInserter.InsertElement(groupElement, using2); Assert.AreEqual(1, groupElement.Children.Count, "Group element was not inserted into the parent."); Assert.IsTrue(groupElement.Children[0] is GroupElement, "Group element was not inserted into the parent."); Assert.AreEqual(2, groupElement.Children[0].Children.Count, "Element was not inserted into the parent."); Assert.AreEqual(0, groupElement.Children[0].Children.IndexOf(using1), "Element is not at the correct index."); Assert.AreEqual(1, groupElement.Children[0].Children.IndexOf(using2), "Element is not at the correct index."); UsingElement using3 = new UsingElement(); using3.Name = "System.Text"; groupedInserter.InsertElement(groupElement, using3); Assert.AreEqual(1, groupElement.Children.Count, "Group element was not inserted into the parent."); Assert.IsTrue(groupElement.Children[0] is GroupElement, "Group element was not inserted into the parent."); Assert.AreEqual(3, groupElement.Children[0].Children.Count, "Element was not inserted into the parent."); Assert.AreEqual(0, groupElement.Children[0].Children.IndexOf(using1), "Element is not at the correct index[0].Children."); Assert.AreEqual(1, groupElement.Children[0].Children.IndexOf(using2), "Element is not at the correct index."); Assert.AreEqual(2, groupElement.Children[0].Children.IndexOf(using3), "Element is not at the correct index."); }
public void GroupSortByNameTest() { GroupBy groupBy = new GroupBy(); groupBy.By = ElementAttributeType.Name; groupBy.AttributeCapture = "^(.*?)(\\.|$)"; groupBy.Direction = SortDirection.Ascending; GroupedInserter groupedInserter = new GroupedInserter(groupBy); // // Create a parent element // GroupElement groupElement = new GroupElement(); Assert.AreEqual(0, groupElement.Children.Count, "Parent element should not have any children."); // Insert elements groupedInserter.InsertElement(groupElement, new UsingElement("NUnit.Framework")); groupedInserter.InsertElement(groupElement, new UsingElement("NArrange.Core")); groupedInserter.InsertElement(groupElement, new UsingElement("NArrange.Core.Configuration")); groupedInserter.InsertElement(groupElement, new UsingElement("System")); groupedInserter.InsertElement(groupElement, new UsingElement("System.IO")); Assert.AreEqual(3, groupElement.Children.Count, "Unexpected number of child groups."); GroupElement childGroup; // System usings should always come first childGroup = groupElement.Children[0] as GroupElement; Assert.IsNotNull(childGroup, "Expected a child group."); Assert.AreEqual(2, childGroup.Children.Count, "Unexpected number of group children."); Assert.AreEqual("System", childGroup.Children[0].Name); Assert.AreEqual("System.IO", childGroup.Children[1].Name); childGroup = groupElement.Children[1] as GroupElement; Assert.IsNotNull(childGroup, "Expected a child group."); Assert.AreEqual(2, childGroup.Children.Count, "Unexpected number of group children."); Assert.AreEqual("NArrange.Core", childGroup.Children[0].Name); Assert.AreEqual("NArrange.Core.Configuration", childGroup.Children[1].Name); childGroup = groupElement.Children[2] as GroupElement; Assert.IsNotNull(childGroup, "Expected a child group."); Assert.AreEqual(1, childGroup.Children.Count, "Unexpected number of group children."); Assert.AreEqual("NUnit.Framework", childGroup.Children[0].Name); }
public void UnsupportedArrangeWithParentTest() { GroupElement parentElement = new GroupElement(); ChainElementArranger chain = new ChainElementArranger(); FieldElement fieldElement = new FieldElement(); // // Add an arranger that can't arrange the element // TestElementArranger disabledArranger = new TestElementArranger(false); chain.AddArranger(disabledArranger); Assert.IsFalse(chain.CanArrange(fieldElement), "Unexpected return value from CanArrange."); chain.ArrangeElement(parentElement, fieldElement); Assert.IsTrue(parentElement.Children.Contains(fieldElement)); }
public void MoveUsingsToNamespaceTest() { List<ICodeElement> codeElements = new List<ICodeElement>(); UsingElement using1 = new UsingElement(); using1.Name = "System"; using1.IsMovable = true; codeElements.Add(using1); // Nested region and groups RegionElement region = new RegionElement(); region.Name = "Region"; codeElements.Add(region); GroupElement group = new GroupElement(); group.Name = "Group"; region.AddChild(group); UsingElement using2 = new UsingElement(); using2.Name = "System.IO"; using2.IsMovable = true; group.AddChild(using2); NamespaceElement namespaceElement = new NamespaceElement(); namespaceElement.Name = "TestNamespace"; codeElements.Add(namespaceElement); UsingElement using3 = new UsingElement(); using3.Name = "System.Collections"; using3.IsMovable = true; namespaceElement.AddChild(using3); TypeElement class1 = new TypeElement(); class1.Name = "Class1"; namespaceElement.AddChild(class1); TypeElement class2 = new TypeElement(); class2.Name = "Class2"; namespaceElement.AddChild(class2); CodeConfiguration configuration = CodeConfiguration.Default.Clone() as CodeConfiguration; CodeArranger arranger; // // Move to namespace. // configuration.Formatting.Usings.MoveTo = CodeLevel.Namespace; arranger = new CodeArranger(configuration); ReadOnlyCollection<ICodeElement> arranged = arranger.Arrange(codeElements.AsReadOnly()); Assert.AreEqual(2, arranged.Count, "After arranging, an unexpected number of elements were returned."); NamespaceElement namespaceElementTest = arranged[1] as NamespaceElement; Assert.IsNotNull(namespaceElementTest, "Expected a namespace element."); Assert.AreEqual(2, namespaceElementTest.Children.Count, "After arranging, an unexpected number of namespace elements were returned."); GroupElement namespaceGroup = namespaceElementTest.Children[0] as GroupElement; Assert.IsNotNull(namespaceGroup); GroupElement innerGroup = namespaceGroup.Children[0] as GroupElement; Assert.AreEqual("System", innerGroup.Children[0].Name); Assert.AreEqual("System.Collections", innerGroup.Children[1].Name); Assert.AreEqual("System.IO", innerGroup.Children[2].Name); RegionElement typeRegion = namespaceElementTest.Children[1] as RegionElement; Assert.IsNotNull(typeRegion); Assert.AreEqual("Class1", typeRegion.Children[0].Name); Assert.AreEqual("Class2", typeRegion.Children[1].Name); }
/// <summary> /// Inserts the element within the parent. /// </summary> /// <param name="parentElement">Parent element to insert into.</param> /// <param name="codeElement">Code element to insert.</param> public void InsertElement(ICodeElement parentElement, ICodeElement codeElement) { GroupElement group = null; string groupName = GetGroupName(_groupBy.By, codeElement); foreach (ICodeElement childElement in parentElement.Children) { GroupElement groupElement = childElement as GroupElement; if (groupElement != null && groupElement.Name == groupName) { group = groupElement; break; } } if (group == null) { group = new GroupElement(); group.Name = groupName; group.SeparatorType = _groupBy.SeparatorType; group.CustomSeparator = _groupBy.CustomSeparator; int insertIndex = parentElement.Children.Count; if (_groupBy.Direction != SortDirection.None) { // Sort the groups by the attribute selected for grouping for (int compareIndex = parentElement.Children.Count - 1; compareIndex >= 0; compareIndex--) { GroupElement siblingGroup = parentElement.Children[insertIndex - 1] as GroupElement; if (siblingGroup != null && siblingGroup.Children.Count > 0) { // This may not be the most accurate way to do this, but just compare // against the first element in the sibling group. ICodeElement compareElement = siblingGroup.Children[0]; // For nested groups, we need to drill down to find the first element. while (compareElement is GroupElement && compareElement.Children.Count > 0) { compareElement = compareElement.Children[0]; } // Create the element comparer if necessary if (_sortComparer == null) { _sortComparer = new ElementComparer(_groupBy.By, _groupBy.Direction); } int compareValue = _sortComparer.Compare(codeElement, compareElement); // System using directives should always be placed first in the file. if (compareValue < 0 && (!(codeElement is UsingElement) || siblingGroup.Name != "System") || (codeElement is UsingElement && groupName == "System")) { insertIndex = compareIndex; } } } } if (insertIndex < parentElement.Children.Count) { parentElement.InsertChild(insertIndex, group); } else { parentElement.AddChild(group); } } if (_innerInserter != null) { _innerInserter.InsertElement(group, codeElement); } else { group.AddChild(codeElement); } }