Element used to logically group other elements.
Inheritance: CodeElement
示例#1
0
        /// <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();
        }
示例#2
0
        /// <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));
        }
示例#8
0
        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);
            }
        }