private void CombineRootElementsAndSort(XNodeSection section, CsProjArrange.ArrangeOptions options) { var combineGroups = section.Nodes .Where(x => x is XElement) .Cast <XElement>() .GroupBy( x => { var combGroup = new CombineGroups { Name = x.Name.Namespace.ToString() + ":" + x.Name.LocalName, Attributes = string.Join(Environment.NewLine, x.Attributes() .Select(y => y.Name.Namespace.ToString() + ":" + y.Name.LocalName + ":" + y.Value)), }; combGroup.Name += this.TryAddSubNodeSuffix(x, "PropertyGroup", "VSToolsPath"); combGroup.Name += this.TryAddSubNodeSuffix(x, "PropertyGroup", "PostBuildEvent"); combGroup.Name += this.TryAddSubNodeSuffix(x, "ItemGroup", "Folder"); return(combGroup); }); foreach (var elementGroup in combineGroups) { if (options.HasFlag(CsProjArrange.ArrangeOptions.CombineRootElements)) { CombineIdenticalRootElements(section, elementGroup); } ArrangeAllElementsInGroup(elementGroup); } }
private void SplitItemGroups(XNodeSection section, IList <string> stickyElementNames) { foreach (var group in section.Nodes.Where(x => x is XElement).Cast <XElement>().Where(x => x.Name.LocalName == "ItemGroup").ToList()) { var uniqueTypes = @group.Elements() .Select(x => x.Name) .Distinct() .OrderBy( x => stickyElementNames.IndexOf(x.LocalName) == -1 ? int.MaxValue : stickyElementNames.IndexOf(x.LocalName)) .ThenBy(x => x.LocalName) ; // Split into multiple item groups if there are multiple types included. if (uniqueTypes.Count() > 1) { var firstType = uniqueTypes.First(); var restTypes = uniqueTypes.Skip(1).Reverse(); foreach (var type in restTypes) { var newElement = new XElement(@group.Name, @group.Attributes(), @group.Elements(type)); // Insert node after. section.Nodes.Insert(section.Nodes.IndexOf(@group) + 1, newElement); } @group.ReplaceNodes(@group.Elements(firstType)); } } }
private void CombineRootElementsAndSort(XNodeSection section, CsProjArrange.ArrangeOptions options) { var combineGroups = section.Nodes .Where(x => x is XElement) .Cast <XElement>() .GroupBy( x => new CombineGroups { Name = x.Name.Namespace.ToString() + ":" + x.Name.LocalName, Attributes = string.Join(Environment.NewLine, x.Attributes() .Select(y => y.Name.Namespace.ToString() + ":" + y.Name.LocalName + ":" + y.Value)), } ); foreach (var elementGroup in combineGroups) { if (options.HasFlag(CsProjArrange.ArrangeOptions.CombineRootElements)) { CombineIdenticalRootElements(section, elementGroup); } ArrangeAllElementsInGroup(elementGroup); } }
private void ArrangeSection(XNodeSection section, CsProjArrange.ArrangeOptions options) { CombineRootElementsAndSort(section, options); if (options.HasFlag(CsProjArrange.ArrangeOptions.SplitItemGroups)) { SplitItemGroups(section, _stickyElementNames); } if (options.HasFlag(CsProjArrange.ArrangeOptions.SortRootElements)) { SortRootElements(section); } }
private void CombineIdenticalRootElements(XNodeSection section, IGrouping <CombineGroups, XElement> elementGroup) { XElement first = elementGroup.First(); // Combine multiple elements if they have the same name and attributes. if (elementGroup.Count() > 1) { var restGroup = elementGroup.Skip(1); first.Add(restGroup.SelectMany(x => x.Elements())); foreach (var rest in restGroup) { section.Nodes.Remove(rest); } } }
private void SortRootElements(XNodeSection section) { // Sort the elements in root. if (_options.HasFlag(CsProjArrange.ArrangeOptions.KeepCommentWithNext)) { section.Nodes = UnfoldComments( FoldComments(section.Nodes) .OrderBy(x => x.Element, _nodeNameComparer) .ThenBy(x => x.Element.NodeType == XmlNodeType.Element ? x.Element.Attributes() : null, _attributeKeyComparer) ) .ToList(); } else { section.Nodes = section.Nodes .OrderBy(x => x, _nodeNameComparer) .ThenBy(x => x.NodeType == XmlNodeType.Element ? ((XElement)x).Attributes() : null, _attributeKeyComparer) .ToList(); } }
private IEnumerable <XNodeSection> FoldSections(IEnumerable <XNode> nodes) { XNodeSection none = new XNodeSection(); XNodeSection current = none; bool section = false; foreach (var node in nodes) { switch (node.NodeType) { case XmlNodeType.Comment: var comment = (node as XComment).Value; if (section) { if (Regex.IsMatch(comment, _optionsCloseCommentRegexString)) { current.CloseComment = node as XComment; yield return(current); current = none; section = false; } else { current.Nodes.Add(node); } } else { var match = Regex.Match(comment, _optionsOpenCommentRegexString); if (match.Success) { if (current != none) { // Missing closing comment for previous section. yield return(current); } current = new XNodeSection(); current.OpenComment = node as XComment; current.Options = (CsProjArrange.ArrangeOptions)Enum.Parse(typeof(CsProjArrange.ArrangeOptions), match.Groups[2].Value); current.OptionSection = true; section = true; } else { current.Nodes.Add(node); } } break; default: current.Nodes.Add(node); break; } } if (current != none) { yield return(current); } yield return(none); }