1 /* 2 * Copyright (C) 2008-2009, Johannes E. Schindelin <johannes.schindelin@gmx.de> and others 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the Eclipse Distribution License v. 1.0 which is available at 6 * https://www.eclipse.org/org/documents/edl-v10.php. 7 * 8 * SPDX-License-Identifier: BSD-3-Clause 9 */ 10 11 package org.eclipse.jgit.diff; 12 13 /** 14 * A modified region detected between two versions of roughly the same content. 15 * <p> 16 * An edit covers the modified region only. It does not cover a common region. 17 * <p> 18 * Regions should be specified using 0 based notation, so add 1 to the start and 19 * end marks for line numbers in a file. 20 * <p> 21 * An edit where {@code beginA == endA && beginB < endB} is an insert edit, that 22 * is sequence B inserted the elements in region <code>[beginB, endB)</code> at 23 * <code>beginA</code>. 24 * <p> 25 * An edit where {@code beginA < endA && beginB == endB} is a delete edit, that 26 * is sequence B has removed the elements between <code>[beginA, endA)</code>. 27 * <p> 28 * An edit where {@code beginA < endA && beginB < endB} is a replace edit, that 29 * is sequence B has replaced the range of elements between 30 * <code>[beginA, endA)</code> with those found in <code>[beginB, endB)</code>. 31 */ 32 public class Edit { 33 /** Type of edit */ 34 public enum Type { 35 /** Sequence B has inserted the region. */ 36 INSERT, 37 38 /** Sequence B has removed the region. */ 39 DELETE, 40 41 /** Sequence B has replaced the region with different content. */ 42 REPLACE, 43 44 /** Sequence A and B have zero length, describing nothing. */ 45 EMPTY; 46 } 47 48 int beginA; 49 50 int endA; 51 52 int beginB; 53 54 int endB; 55 56 /** 57 * Create a new empty edit. 58 * 59 * @param as 60 * beginA: start and end of region in sequence A; 0 based. 61 * @param bs 62 * beginB: start and end of region in sequence B; 0 based. 63 */ 64 public Edit(int as, int bs) { 65 this(as, as, bs, bs); 66 } 67 68 /** 69 * Create a new edit. 70 * 71 * @param as 72 * beginA: start of region in sequence A; 0 based. 73 * @param ae 74 * endA: end of region in sequence A; must be >= as. 75 * @param bs 76 * beginB: start of region in sequence B; 0 based. 77 * @param be 78 * endB: end of region in sequence B; must be > = bs. 79 */ 80 public Edit(int as, int ae, int bs, int be) { 81 beginA = as; 82 endA = ae; 83 84 beginB = bs; 85 endB = be; 86 } 87 88 /** 89 * Get type 90 * 91 * @return the type of this region 92 */ 93 public final Type getType() { 94 if (beginA < endA) { 95 if (beginB < endB) { 96 return Type.REPLACE; 97 } 98 return Type.DELETE; 99 100 } 101 if (beginB < endB) { 102 return Type.INSERT; 103 } 104 // beginB == endB) 105 return Type.EMPTY; 106 } 107 108 /** 109 * Whether edit is empty 110 * 111 * @return {@code true} if the edit is empty (lengths of both a and b is 112 * zero) 113 */ 114 public final boolean isEmpty() { 115 return beginA == endA && beginB == endB; 116 } 117 118 /** 119 * Get start point in sequence A 120 * 121 * @return start point in sequence A 122 */ 123 public final int getBeginA() { 124 return beginA; 125 } 126 127 /** 128 * Get end point in sequence A 129 * 130 * @return end point in sequence A 131 */ 132 public final int getEndA() { 133 return endA; 134 } 135 136 /** 137 * Get start point in sequence B 138 * 139 * @return start point in sequence B 140 */ 141 public final int getBeginB() { 142 return beginB; 143 } 144 145 /** 146 * Get end point in sequence B 147 * 148 * @return end point in sequence B 149 */ 150 public final int getEndB() { 151 return endB; 152 } 153 154 /** 155 * Get length of the region in A 156 * 157 * @return length of the region in A 158 */ 159 public final int getLengthA() { 160 return endA - beginA; 161 } 162 163 /** 164 * Get length of the region in B 165 * 166 * @return return length of the region in B 167 */ 168 public final int getLengthB() { 169 return endB - beginB; 170 } 171 172 /** 173 * Move the edit region by the specified amount. 174 * 175 * @param amount 176 * the region is shifted by this amount, and can be positive or 177 * negative. 178 * @since 4.8 179 */ 180 public final void shift(int amount) { 181 beginA += amount; 182 endA += amount; 183 beginB += amount; 184 endB += amount; 185 } 186 187 /** 188 * Construct a new edit representing the region before cut. 189 * 190 * @param cut 191 * the cut point. The beginning A and B points are used as the 192 * end points of the returned edit. 193 * @return an edit representing the slice of {@code this} edit that occurs 194 * before {@code cut} starts. 195 */ 196 public final Editref="../../../../org/eclipse/jgit/diff/Edit.html#Edit">Edit before(Edit cut) { 197 return new Edit(beginA, cut.beginA, beginB, cut.beginB); 198 } 199 200 /** 201 * Construct a new edit representing the region after cut. 202 * 203 * @param cut 204 * the cut point. The ending A and B points are used as the 205 * starting points of the returned edit. 206 * @return an edit representing the slice of {@code this} edit that occurs 207 * after {@code cut} ends. 208 */ 209 public final Edithref="../../../../org/eclipse/jgit/diff/Edit.html#Edit">Edit after(Edit cut) { 210 return new Edit(cut.endA, endA, cut.endB, endB); 211 } 212 213 /** 214 * Increase {@link #getEndA()} by 1. 215 */ 216 public void extendA() { 217 endA++; 218 } 219 220 /** 221 * Increase {@link #getEndB()} by 1. 222 */ 223 public void extendB() { 224 endB++; 225 } 226 227 /** 228 * Swap A and B, so the edit goes the other direction. 229 */ 230 public void swap() { 231 final int sBegin = beginA; 232 final int sEnd = endA; 233 234 beginA = beginB; 235 endA = endB; 236 237 beginB = sBegin; 238 endB = sEnd; 239 } 240 241 /** {@inheritDoc} */ 242 @Override 243 public int hashCode() { 244 return beginA ^ endA; 245 } 246 247 /** {@inheritDoc} */ 248 @Override 249 public boolean equals(Object o) { 250 if (o instanceof Edit) { 251 final Edit href="../../../../org/eclipse/jgit/diff/Edit.html#Edit">Edit e = (Edit) o; 252 return this.beginA == e.beginA && this.endA == e.endA 253 && this.beginB == e.beginB && this.endB == e.endB; 254 } 255 return false; 256 } 257 258 /** {@inheritDoc} */ 259 @SuppressWarnings("nls") 260 @Override 261 public String toString() { 262 final Type t = getType(); 263 return t + "(" + beginA + "-" + endA + "," + beginB + "-" + endB + ")"; 264 } 265 }