private static ByteEntry CreateByteEntryByFlatteningGraph( ByteGraphNode byteGraphNode, ByteEntry rootEntryToPopulate = null ) { byteGraphNode.Validate(); EnsureRootEntryExists(); PopulateFromChildNodes(); // use child data first PopulateFromRootNode(); // override/append our data second as the priority return(rootEntryToPopulate); void EnsureRootEntryExists() { rootEntryToPopulate ??= new ByteEntry { Parent = byteGraphNode.ByteSource.Bytes, ParentIndex = byteGraphNode.ByteEntry?.ParentIndex ?? byteGraphNode.SourceIndex, // several of our collection items (bytes, annotations, etc) will store // a reference to their parent container. since this new ByteEntry object we're making // is more of an aggregator, we don't want to modify the parents of the things we're storing. // we just store a reference, they really live elsewhere and hence, we're not their 'real' parent. // "YOU'RE NOT MY REAL DAD" DontSetParentOnCollectionItems = true, }; } void PopulateFromChildNodes() { // traverse any child nodes first. if (byteGraphNode.Children == null) { return; } foreach (var childNode in byteGraphNode.Children) { CreateByteEntryByFlatteningGraph(childNode, rootEntryToPopulate); } } void PopulateFromRootNode() { // annotations are concatenated together if (byteGraphNode.ByteEntry?.Annotations?.Count > 0) { rootEntryToPopulate.AppendAnnotationsFrom(byteGraphNode.ByteEntry); } } }
public static void TestSuccessfulUnrelatedMultipleCombine() { var entry1 = new ByteEntry(new AnnotationCollection { new Label { Name = "test1111" }, new ByteAnnotation(), new Comment() }) { DontSetParentOnCollectionItems = true }; var entry2 = new ByteEntry(new AnnotationCollection { new OpcodeAnnotation(), new ByteAnnotation(), new MarkAnnotation() }); Assert.True(entry1.DontSetParentOnCollectionItems); Assert.Null(Record.Exception(() => entry1.AppendAnnotationsFrom(entry2))); Assert.Equal(5, entry1.Annotations.Count); var expectedItemsCount = new List <Type> { typeof(Label), typeof(ByteAnnotation), typeof(Comment), typeof(OpcodeAnnotation), typeof(MarkAnnotation) }.ToDictionary(item => item, _ => 0); foreach (var item in entry1.Annotations) { var currentTotal = ++expectedItemsCount[item.GetType()]; Assert.True(currentTotal <= 1); } var anyNotOne = expectedItemsCount.Any(pair => pair.Value != 1); Assert.False(anyNotOne); }