/// <summary> /// Completely populate all Region property members. Missing data /// is computed based on the values that are already present. /// </summary> /// <param name="region"></param> /// <param name="newLineIndex"></param> public static void Populate(this Region region, NewLineIndex newLineIndex) { if (region == null) { throw new ArgumentNullException(nameof(region)); } if (newLineIndex == null) { throw new ArgumentNullException(nameof(newLineIndex)); } // A call to Populate is an implicit indicator that we are working // with a text region (otherwise the offset and length would be // sufficient data to constitute the region). if (region.StartLine == 0) { OffsetInfo offsetInfo = newLineIndex.GetOffsetInfoForOffset(region.Offset); region.StartLine = offsetInfo.LineNumber; region.StartColumn = offsetInfo.ColumnNumber; offsetInfo = newLineIndex.GetOffsetInfoForOffset(region.Offset + region.Length); region.EndLine = offsetInfo.LineNumber; region.EndColumn = offsetInfo.ColumnNumber; } else { // Make endColumn and endLine explicit, if not expressed if (region.EndLine == 0) { region.EndLine = region.StartLine; } if (region.StartColumn == 0) { region.StartColumn = 1; } if (region.EndColumn == 0) { region.EndColumn = region.StartColumn; } LineInfo lineInfo = newLineIndex.GetLineInfoForLine(region.StartLine); region.Offset = lineInfo.StartOffset + (region.StartColumn - 1); lineInfo = newLineIndex.GetLineInfoForLine(region.EndLine); region.Length = lineInfo.StartOffset + (region.EndColumn - 1) - region.Offset; } }
private void PopulatePropertiesFromCharOffsetAndLength(NewLineIndex newLineIndex, Region region) { Assert(!region.IsBinaryRegion); Assert(region.StartLine == 0); Assert(region.CharLength >= 0 || region.CharOffset >= 0); int startLine, startColumn, endLine, endColumn; // Retrieve start and end line and column information from the new line index OffsetInfo offsetInfo = newLineIndex.GetOffsetInfoForOffset(region.CharOffset); startLine = offsetInfo.LineNumber; startColumn = offsetInfo.ColumnNumber; offsetInfo = newLineIndex.GetOffsetInfoForOffset(region.CharOffset + region.CharLength); endLine = offsetInfo.LineNumber; // The computation above points one past our actual region, because endColumn // is exclusive of the region. This allows for length to easily be computed // for single line regions: region.EndColumn - region.StartColumn endColumn = offsetInfo.ColumnNumber; // Only set values if they aren't already specified if (region.StartLine == 0) { region.StartLine = startLine; } if (region.StartColumn == 0) { region.StartColumn = startColumn; } if (region.EndLine == 0) { region.EndLine = endLine; } if (region.EndColumn == 0) { region.EndColumn = endColumn; } // Validate cases where new line index disagrees with explicit values Assert(region.StartLine == startLine); Assert(region.StartColumn == startColumn); Assert(region.EndLine == endLine); Assert(region.EndColumn == endColumn); }