public virtual ISourceLocation GetCorrespondingSourceLocation(ISourceLocation sourceLocationInPreviousVersionOfDocument)
//^^ requires this.IsUpdatedVersionOf(sourceLocationInPreviousVersionOfDocument.SourceDocument);
{
SourceDocument/*?*/ prev = this.previousVersion.Target as SourceDocument;
Contract.Assume(prev != null); //follows from the precondition because older versions keep younger versions alive.
if (sourceLocationInPreviousVersionOfDocument.SourceDocument != prev)
sourceLocationInPreviousVersionOfDocument = prev.GetCorrespondingSourceLocation(sourceLocationInPreviousVersionOfDocument);
int startIndex = sourceLocationInPreviousVersionOfDocument.StartIndex;
int length = sourceLocationInPreviousVersionOfDocument.Length;
int delta = this.editNewLength - this.editOldLength;
if (startIndex + length < this.editStartIndex) {
//do nothing since the edit does not affect this location
} else if (startIndex > this.editStartIndex + this.editOldLength) {
//The location does not overlap the edit, but may have to move to the left or right, depending on whether the edit deleted or inserted characters
startIndex += delta;
} else if (startIndex >= this.editStartIndex) {
length += delta;
if (startIndex + length <= this.editStartIndex + this.editOldLength) {
//The location is inside the edited region.
if (delta < 0) {
//The edit deleted characters. Make length correspondingly smaller, but no smaller than 0.
if (length < 0) length = 0;
} else {
//The edit inserted characters. Make length correspondingly larger, but not do not go beyond the edit.
if (startIndex + length > this.editStartIndex + this.editNewLength)
length = (this.editStartIndex + this.editNewLength) - startIndex;
}
} else {
//The location starts inside the edit region but carries on.
if (delta < 0) {
//The edit deleted characters. Make length correspondingly smaller, but no smaller than 0.
if (length < 0) length = 0;
} else {
//The edit inserted characters. Make length correspondingly larger, but not do not go beyond the end of the document.
if (startIndex + length > this.Length)
length = this.Length - startIndex;
}
}
} else if (startIndex + length < this.editStartIndex + this.editOldLength) {
//The location starts before the edit region and ends inside it.
if (delta < 0) {
//The edit deleted characters. Make length correspondingly smaller, but no smaller than 0.
if (startIndex + length < this.editStartIndex) {
length = this.editStartIndex - startIndex;
//Contract.Assume(length >= 0);
}
}
} else {
//The location contains the edit.
length += delta;
}
Contract.Assume(length <= this.Length);
Contract.Assume(length >= 0);
return this.GetSourceLocation(startIndex, length);
}