protected void Render(IEnumerable <Dependency> edges, ItemMatch innerMatchOrNull, [NotNull] ITargetWriter output, int?labelWidthOrNull, bool withNotOkCt) { IDictionary <Item, IEnumerable <Dependency> > itemsAndDependencies = Dependency.Dependencies2ItemsAndDependencies(edges); var innerAndReachableOuterItems = new HashSet <Item>(itemsAndDependencies.Where(n => ItemMatch.IsMatch(innerMatchOrNull, n.Key)).SelectMany(kvp => new[] { kvp.Key }.Concat(kvp.Value.Select(e => e.UsedItem)))); IEnumerable <Item> sortedItems = MoreOrLessTopologicalSort(edges).Where(n => innerAndReachableOuterItems.Contains(n)); if (sortedItems.Any()) { int m = 0; Dictionary <Item, int> item2Index = sortedItems.ToDictionary(n => n, n => ++ m); IEnumerable <Item> topItems = sortedItems.Where(n => ItemMatch.IsMatch(innerMatchOrNull, n)); int labelWidth = labelWidthOrNull ?? Math.Max(Math.Min(sortedItems.Max(n => n.Name.Length), 30), 4); int colWidth = Math.Max(1 + ("" + edges.Max(e => e.Ct)).Length, // 1+ because of loop prefix 1 + ("" + sortedItems.Count()).Length); // 1+ because of ! or % marker string itemFormat = "{0," + (colWidth - 1) + ":" + Repeat('0', colWidth - 1) + "}"; string ctFormat = "{0}{1," + (colWidth - 1) + ":" + Repeat('#', colWidth) + "}"; Write(output, colWidth, labelWidth, topItems, itemFormat, item2Index, withNotOkCt, sortedItems, ctFormat, itemsAndDependencies); } else { Log.WriteError("No visible items and dependencies found for output"); } }
public override void Render([NotNull] GlobalContext globalContext, [NotNull, ItemNotNull] IEnumerable <Dependency> dependencies, Options options, [NotNull] WriteTarget target, bool ignoreCase) { int pathCount; using (ITargetWriter tw = GetMasterFileName(globalContext, options, target).CreateWriter()) { tw.WriteLine($"// Written {DateTime.Now} by {typeof(FlatPathWriter).Name} in Archichect {Program.VERSION}"); tw.WriteLine(); pathCount = WritePaths(dependencies, ignoreCase, options.MarkerMatchers, tw, options.ShowItemMarkers); } Log.WriteInfo($"... written {pathCount} paths"); }
public override void Render([NotNull] GlobalContext globalContext, [NotNull, ItemNotNull] IEnumerable <Dependency> dependencies, string options, [NotNull] WriteTarget target, bool ignoreCase) { int? labelWidthOrNull; bool withNotOkCt; ItemMatch itemMatchOrNull; ParseOptions(globalContext, options, ignoreCase, out labelWidthOrNull, out withNotOkCt, out itemMatchOrNull); using (ITargetWriter sw = GetCSVTarget(target).CreateWriter()) { Render(dependencies, null /*TODO: InnerMatch?*/, sw, labelWidthOrNull, withNotOkCt); } }
private static void WriteFormat2Line(ITargetWriter output, string id1, string name1, string id2, string name2, string cts) { output.Write(id1); output.Write(';'); output.Write(name1); output.Write(';'); output.Write(id2); output.Write(';'); output.Write(name2); output.Write(';'); output.WriteLine(cts); }
private static void WriteFormat1Line(ITargetWriter output, string index, string label, IEnumerable <string> columns) { char sep = ';'; output.Write(index); output.Write(sep); output.Write(label); foreach (var col in columns) { output.Write(sep); output.Write(col); } output.WriteLine(); }
protected override void Write(ITargetWriter output, int colWidth, int labelWidth, IEnumerable <Item> topItems, string itemFormat, Dictionary <Item, int> item2Index, bool withNotOkCt, IEnumerable <Item> sortedItems, string ctFormat, IDictionary <Item, IEnumerable <Dependency> > itemsAndDependencies) { WriteFormat1Line(output, Limit("Id", colWidth), Limit("Name", labelWidth), topItems.Select(n => GetItemId(n, itemFormat, item2Index) + (withNotOkCt ? ";" + Repeat(' ', colWidth) : ""))); IWithCt ZERO_EDGE = new ZeroDependency(); foreach (var used in sortedItems) { Item used1 = used; WriteFormat1Line(output, GetItemId(used, itemFormat, item2Index), Limit(used.Name, labelWidth), topItems.Select(@using => FormatCt(withNotOkCt, ctFormat, item2Index[@using] > item2Index[used1], itemsAndDependencies[@using].FirstOrDefault(e => e.UsedItem.Equals(used1)) ?? ZERO_EDGE))); } }
protected override void Write(ITargetWriter output, int colWidth, int labelWidth, IEnumerable <Item> topItems, string itemFormat, Dictionary <Item, int> item2Index, bool withNotOkCt, IEnumerable <Item> sortedItems, string ctFormat, IDictionary <Item, IEnumerable <Dependency> > itemsAndDependencies) { var emptyCtCols = Repeat(' ', colWidth) + (withNotOkCt ? ";" + Repeat(' ', colWidth) : ""); WriteFormat2Line(output, Limit("Id", colWidth), Limit("Name", labelWidth), Limit("Id", colWidth), Limit("Name", labelWidth), emptyCtCols); foreach (var @using in topItems) { WriteFormat2Line(output, GetItemId(@using, itemFormat, item2Index), Limit(@using.Name, labelWidth), Limit("", colWidth), Limit("", labelWidth), emptyCtCols); foreach (var used in sortedItems) { Dependency edge = itemsAndDependencies[@using].FirstOrDefault(e => e.UsedItem.Equals(used)); if (edge != null) { WriteFormat2Line(output, GetItemId(@using, itemFormat, item2Index), Limit(@using.Name, labelWidth), GetItemId(used, itemFormat, item2Index), Limit(used.Name, labelWidth), FormatCt(withNotOkCt, ctFormat, item2Index[@using] > item2Index[used], edge)); } } } }
private static int WritePaths([NotNull, ItemNotNull] IEnumerable <Dependency> dependencies, bool ignoreCase, IEnumerable <IMatcher> markerMatchers, ITargetWriter tw, bool showItemMarkers) { var paths = new SortedDictionary <string, List <Dependency> >(); foreach (var d in dependencies) { foreach (var marker in d.MarkerSet.MatchingMarkers(markerMatchers)) { List <Dependency> path; if (!paths.TryGetValue(marker, out path)) { paths.Add(marker, path = new List <Dependency>()); } path.Add(d); } } foreach (var kvp in paths) { string marker = kvp.Key; tw.WriteLine($"-- {marker}"); // If a path was backprojected from a projected (i.e., condensed) path, then // multiple dependencies might have the same marker value. For printing the path, // the items on the left and right of such a group of dependencies are considered to // be one item and printed below each other, with an indent from the second onwards. var groupedPath = kvp.Value .Select(d => new { d.UsingItem, MarkerValue = d.MarkerSet.GetValue(kvp.Key, ignoreCase), d.UsedItem }) .GroupBy(d => d.MarkerValue) .OrderBy(g1 => g1.Key) .ToArray(); string itemSeparator = Environment.NewLine + " & "; tw.WriteLine(string.Join(itemSeparator, new HashSet <string>(groupedPath[0] .Select(d => CreateString(showItemMarkers, d.UsingItem, 0, d.UsingItem.MarkerSet.GetValue(marker, ignoreCase))) .OrderBy(s => s)))); var usedItems = new HashSet <Item>(groupedPath[0].Select(d => d.UsedItem)); var previousKey = groupedPath[0].Key; foreach (var g in groupedPath.Skip(1)) { // Also, after backprojection, a path might be "torn", e.g. a -> b1; b2 -> c. // We want to see both b1 and b2 in the written result, hence, we add the b2 after a ">". IEnumerable <string> orderedUsedItems = GetOrderedUniqueItems(showItemMarkers, usedItems, previousKey); IEnumerable <string> additionalUsingItems = GetOrderedUniqueItems(showItemMarkers, g.Select(d => d.UsingItem).Except(usedItems), previousKey); tw.WriteLine(string.Join(itemSeparator, orderedUsedItems) + (additionalUsingItems.Any() ? Environment.NewLine + " > " + string.Join(itemSeparator, additionalUsingItems) : "")); usedItems = new HashSet <Item>(g.Select(d => d.UsedItem)); previousKey = g.Key; } { IEnumerable <string> orderedUsedItems = GetOrderedUniqueItems(showItemMarkers, usedItems, previousKey); tw.WriteLine(string.Join(itemSeparator, orderedUsedItems)); } tw.WriteLine(); } return(paths.Count); }
private void Render([NotNull, ItemNotNull] IEnumerable <Dependency> dependencies, [NotNull] ITargetWriter output, ItemMatch innerMatch, int?maxExampleLength) { IDictionary <Item, IEnumerable <Dependency> > itemsAndDependencies = Dependency.Dependencies2ItemsAndDependencies(dependencies); output.WriteLine("digraph D {"); output.WriteLine("ranksep = 1.5;"); foreach (var n in itemsAndDependencies.Keys.OrderBy(n => n.Name)) { output.WriteLine("\"" + n.Name + "\" [shape=" + (ItemMatch.IsMatch(innerMatch, n) ? "box,style=bold" : "oval") + "];"); } output.WriteLine(); foreach (var n in itemsAndDependencies.Keys.OrderBy(n => n.Name)) { foreach (var e in itemsAndDependencies[n].Where(e => ItemMatch.IsMatch(innerMatch, e.UsingItem) || ItemMatch.IsMatch(innerMatch, e.UsedItem))) { output.WriteLine(e.GetDotRepresentation(maxExampleLength)); } } output.WriteLine("}"); }
private static void WriteItemType(HashSet <ItemType> writtenTypes, ItemType itemType, ITargetWriter sw) { if (writtenTypes.Add(itemType)) { sw.WriteLine(); sw.Write("$ "); sw.WriteLine(itemType.ToString()); sw.WriteLine(); } }
public static int Write([NotNull, ItemNotNull] IEnumerable <Dependency> dependencies, ITargetWriter sw, bool withExampleInfo, IEnumerable <DependencyMatch> matches, IEnumerable <DependencyMatch> excludes) { var writtenTypes = new HashSet <ItemType>(); int n = 0; foreach (var d in dependencies.Where(d => d.IsMarkerMatch(matches, excludes))) { WriteItemType(writtenTypes, d.UsingItem.Type, sw); WriteItemType(writtenTypes, d.UsedItem.Type, sw); sw.WriteLine(d.AsLimitableStringWithTypes(withExampleInfo, threeLines: false, maxLength: int.MaxValue)); n++; } return(n); }
protected abstract void Write(ITargetWriter output, int colWidth, int labelWidth, IEnumerable <Item> topItems, string itemFormat, Dictionary <Item, int> item2Index, bool withNotOkCt, IEnumerable <Item> sortedItems, string ctFormat, IDictionary <Item, IEnumerable <Dependency> > itemsAndDependencies);
private static void RenderToTextWriter([NotNull, ItemNotNull] IEnumerable <Dependency> dependencies, ITargetWriter sw, bool simpleRuleOutput, bool newLine) { sw.WriteLine($"// Written {DateTime.Now} by {typeof(RuleViolationWriter).Name} in NDepCheck {Program.VERSION}"); foreach (var d in dependencies.Where(d => d.NotOkCt > 0)) { sw.WriteLine(d.NotOkMessage(simpleRuleOutput: simpleRuleOutput, newLine: newLine)); } }
private static void RenderToTextWriter([NotNull, ItemNotNull] IEnumerable <Dependency> dependencies, ITargetWriter sw, bool simpleRuleOutput, bool newLine) { sw.WriteLine($"// Written {DateTime.Now} by {typeof(RuleViolationWriter).Name} in Archichect {Program.VERSION}"); foreach (var d in GetQuestionableAndBadDependencies(dependencies)) { sw.WriteLine(d.NotOkMessage(simpleRuleOutput: simpleRuleOutput, newLine: newLine)); } }
private void Write([NotNull, ItemNotNull] IEnumerable <Dependency> dependencies, ITargetWriter sw, List <ItemMatch> itemMatches, List <ItemMatch> itemExcludes, List <DependencyMatch> indegreeMatches, List <DependencyMatch> indegreeExcludes, List <DependencyMatch> outdegreeMatches, List <DependencyMatch> outdegreeExcludes, bool writeOnlyIfIndegreeNotZero, bool writeOnlyIfOutdegreeNotZero, bool showMarkers, bool ignoreCase) { ISet <Item> items = Dependency.GetAllItems(dependencies, i => i.IsMatch(itemMatches, itemExcludes)); Dictionary <Item, Dependency[]> incoming = Item.CollectIncomingDependenciesMap(dependencies, i => items.Contains(i)); Dictionary <Item, Dependency[]> outgoing = Item.CollectOutgoingDependenciesMap(dependencies, i => items.Contains(i)); List <Item> itemsAsList = items.ToList(); itemsAsList.Sort( (i1, i2) => string.Compare(i1.AsFullString(), i2.AsFullString(), ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture)); var writtenTypes = new HashSet <ItemType>(); int n = 0; foreach (var i in itemsAsList) { ItemType itemType = i.Type; if (writtenTypes.Add(itemType)) { sw.Write("$ "); sw.WriteLine(itemType.ToString()); } int ict = GetCount(incoming, i, indegreeMatches, indegreeExcludes); int oct = GetCount(outgoing, i, outdegreeMatches, outdegreeExcludes); if (ict == 0 && writeOnlyIfIndegreeNotZero) { // dont write } else if (oct == 0 && writeOnlyIfOutdegreeNotZero) { // dont write } else { n++; sw.WriteLine($"{"--" + ict,7}->*--{oct + "->",-7} {(showMarkers ? i.AsFullString() : i.AsString())}"); } } Log.WriteInfo($"... written {n} items"); }