@@ -726,38 +726,117 @@ public void InsertBytes(int length)
726726 }
727727 }
728728
729- public void ReplaceSelectedNodesWithType ( Type type )
729+ /// <summary>Groups the selected nodes in blocks if the nodes are continues.</summary>
730+ /// <param name="selection">The selection to partition.</param>
731+ /// <returns>An enumeration with blocks of continues nodes.</returns>
732+ private static IEnumerable < List < HotSpot > > PartitionSelectedNodes ( IEnumerable < HotSpot > selection )
730733 {
731- Contract . Requires ( type != null ) ;
732- Contract . Requires ( type . IsSubclassOf ( typeof ( BaseNode ) ) ) ;
734+ Contract . Requires ( selection != null ) ;
733735
734- var newSelected = new List < HotSpot > ( selectedNodes . Count ) ;
736+ var it = selection . GetEnumerator ( ) ;
737+ if ( ! it . MoveNext ( ) )
738+ {
739+ yield break ;
740+ }
741+
742+ var partition = new List < HotSpot > ( ) ;
743+ partition . Add ( it . Current ) ;
735744
736- foreach ( var selected in selectedNodes . Where ( s => ! ( s . Node is ClassNode ) ) )
745+ var last = it . Current ;
746+
747+ while ( it . MoveNext ( ) )
737748 {
738- var node = Activator . CreateInstance ( type ) as BaseNode ;
749+ if ( it . Current . Address != last . Address + last . Node . MemorySize )
750+ {
751+ yield return partition ;
752+
753+ partition = new List < HotSpot > ( ) ;
754+ }
755+
756+ partition . Add ( it . Current ) ;
739757
740- node . Intialize ( ) ;
758+ last = it . Current ;
759+ }
741760
742- if ( selected . Node . ParentNode . ReplaceChildNode ( selected . Node , node ) )
761+ if ( partition . Count != 0 )
762+ {
763+ yield return partition ;
764+ }
765+ }
766+
767+ private static IEnumerable < HotSpot > RecursiveReplaceNodes ( BaseContainerNode parentNode , Type type , IEnumerable < BaseNode > nodesToReplace )
768+ {
769+ Contract . Requires ( parentNode != null ) ;
770+ Contract . Requires ( type != null ) ;
771+ Contract . Requires ( nodesToReplace != null ) ;
772+
773+ foreach ( var nodeToReplace in nodesToReplace )
774+ {
775+ var temp = new List < BaseNode > ( ) ;
776+ if ( parentNode . ReplaceChildNode ( nodeToReplace , type , ref temp ) )
743777 {
778+ var node = temp . First ( ) ;
779+
744780 node . IsSelected = true ;
745781
746- var hotspot = new HotSpot
782+ yield return new HotSpot
747783 {
748784 Address = node . ParentNode . Offset . Add ( node . Offset ) ,
749785 Node = node
750786 } ;
751787
752- newSelected . Add ( hotspot ) ;
753-
754- if ( selectionAnchor . Node == selected . Node )
788+ if ( temp . Count > 1 )
755789 {
756- selectionAnchor = hotspot ;
790+ foreach ( var hs in RecursiveReplaceNodes ( parentNode , type , temp ) )
791+ {
792+ yield return hs ;
793+ }
757794 }
758- if ( selectionCaret . Node == selected . Node )
795+ }
796+ }
797+ }
798+
799+ public void ReplaceSelectedNodesWithType ( Type type )
800+ {
801+ Contract . Requires ( type != null ) ;
802+ Contract . Requires ( type . IsSubclassOf ( typeof ( BaseNode ) ) ) ;
803+
804+ var newSelected = new List < HotSpot > ( selectedNodes . Count ) ;
805+
806+ // Group the selected nodes in continues selected blocks.
807+ foreach ( var selectedPartition in PartitionSelectedNodes ( selectedNodes . Where ( s => ! ( s . Node is ClassNode ) ) ) )
808+ {
809+ foreach ( var selected in selectedPartition )
810+ {
811+ var createdNodes = new List < BaseNode > ( ) ;
812+ if ( selected . Node . ParentNode . ReplaceChildNode ( selected . Node , type , ref createdNodes ) )
759813 {
760- selectionCaret = hotspot ;
814+ var node = createdNodes . First ( ) ;
815+
816+ node . IsSelected = true ;
817+
818+ var hotspot = new HotSpot
819+ {
820+ Address = node . ParentNode . Offset . Add ( node . Offset ) ,
821+ Node = node
822+ } ;
823+
824+ newSelected . Add ( hotspot ) ;
825+
826+ if ( selectionAnchor . Node == selected . Node )
827+ {
828+ selectionAnchor = hotspot ;
829+ }
830+ if ( selectionCaret . Node == selected . Node )
831+ {
832+ selectionCaret = hotspot ;
833+ }
834+
835+ // If the block contains more than one node and the replaced node decomposed to more than one node replace the new nodes to.
836+ if ( selectedPartition . Count > 1 && createdNodes . Count > 1 )
837+ {
838+ newSelected . AddRange ( RecursiveReplaceNodes ( selected . Node . ParentNode , type , createdNodes . Skip ( 1 ) ) ) ;
839+ }
761840 }
762841 }
763842 }
0 commit comments