/// <summary> /// Compares the spacing (as represented by grouping) of using directives in /// two lists. Returns null if they are the same, and otherwise returns a /// description of the first line at which to either remove or insert space /// to bring the list closer into line with the required spacing. (This presumes /// that the order is already correct.) /// </summary> /// <param name="requiredGroups">The required order and spacing, where /// spacing is denoted by grouping.</param> /// <param name="currentGroups">The current order and spacing.</param> /// <returns>Null if the spacing matches. Otherwise, a <see cref="SpaceChange"/> /// describing where to add or remove a blank line.</returns> public static SpaceChange GetNextModification( IEnumerable<IEnumerable<UsingDirective>> requiredGroups, IEnumerable<IEnumerable<UsingDirective>> currentGroups) { var requiredByGroup = requiredGroups .SelectMany((items, groupIndex) => items.Select(item => groupIndex)); var currentByGroup = currentGroups .SelectMany((items, groupIndex) => items.Select(item => groupIndex)); var itemsByGroup = requiredByGroup.Zip(currentByGroup, (required, actual) => new { required, actual }); int index = 0; foreach (var groupIndices in itemsByGroup) { if (groupIndices.actual < groupIndices.required) { return SpaceChange.Insert(index); } if (groupIndices.actual > groupIndices.required) { return SpaceChange.Remove(index); } index += 1; } return null; }
/// <summary> /// Given a set of using directives which are already in the correct order, determines /// where to remove or add a blank line to bring them one step closer to the correct /// spacing. This method should be called repeatedly (applying each update that it /// generates between each call) until it returns null to indicate that the order /// is correct. /// </summary> /// <param name="requiredOrderByGroups">The correct order and spacing (e.g., as /// determined by a call to <see cref="FlattenImportsAndDetermineOrderAndSpacing"/>).</param> /// <param name="items">The directives as they are currently ordered and spaced.</param> /// <returns>Null if the directives are already in the correct order. Otherwise, /// a <see cref="SpaceChange"/> describing where to add or remove a blank line.</returns> public static SpaceChange GetNextSpacingModification( List <List <UsingDirective> > requiredOrderByGroups, List <UsingDirectiveOrSpace> items) { SpaceChange nextChange = null; if (requiredOrderByGroups != null) { var importsByGroup = new List <List <UsingDirective> >(); foreach (UsingDirectiveOrSpace item in items) { if (importsByGroup.Count == 0) { importsByGroup.Add(new List <UsingDirective>()); } List <UsingDirective> currentGroup = importsByGroup[importsByGroup.Count - 1]; if (item.IsBlankLine) { if (currentGroup.Count > 0) { importsByGroup.Add(new List <UsingDirective>()); } } else { currentGroup.Add(item.Directive); } } nextChange = SpacingChecker.GetNextModification( requiredOrderByGroups, importsByGroup); } return(nextChange); }