1 package jdiff; 2 3 import java.util.*; 4 5 27 class MergeChanges { 28 29 36 public static void mergeRemoveAdd(APIDiff apiDiff) { 37 Iterator iter = apiDiff.packagesChanged.iterator(); 39 while (iter.hasNext()) { 40 PackageDiff pkgDiff = (PackageDiff)(iter.next()); 41 Iterator iter2 = pkgDiff.classesChanged.iterator(); 42 while (iter2.hasNext()) { 43 ClassDiff classDiff = (ClassDiff)(iter2.next()); 44 ConstructorAPI[] ctorArr = new ConstructorAPI[classDiff.ctorsRemoved.size()]; 48 ctorArr = (ConstructorAPI[])classDiff.ctorsRemoved.toArray(ctorArr); 49 for (int ctorIdx = 0; ctorIdx < ctorArr.length; ctorIdx++) { 50 ConstructorAPI removedCtor = ctorArr[ctorIdx]; 51 mergeRemoveAddCtor(removedCtor, classDiff, pkgDiff); 52 } 53 MethodAPI[] methodArr = new MethodAPI[classDiff.methodsRemoved.size()]; 55 methodArr = (MethodAPI[])classDiff.methodsRemoved.toArray(methodArr); 56 for (int methodIdx = 0; methodIdx < methodArr.length; methodIdx++) { 57 MethodAPI removedMethod = methodArr[methodIdx]; 58 if (removedMethod.inheritedFrom_ == null) 60 mergeRemoveAddMethod(removedMethod, classDiff, pkgDiff); 61 } 62 FieldAPI[] fieldArr = new FieldAPI[classDiff.fieldsRemoved.size()]; 64 fieldArr = (FieldAPI[])classDiff.fieldsRemoved.toArray(fieldArr); 65 for (int fieldIdx = 0; fieldIdx < fieldArr.length; fieldIdx++) { 66 FieldAPI removedField = fieldArr[fieldIdx]; 67 if (removedField.inheritedFrom_ == null) 69 mergeRemoveAddField(removedField, classDiff, pkgDiff); 70 } 71 } 72 } 73 } 74 75 78 public static void mergeRemoveAddCtor(ConstructorAPI removedCtor, ClassDiff classDiff, PackageDiff pkgDiff) { 79 int startRemoved = classDiff.ctorsRemoved.indexOf(removedCtor); 81 int endRemoved = classDiff.ctorsRemoved.lastIndexOf(removedCtor); 82 int startAdded = classDiff.ctorsAdded.indexOf(removedCtor); 83 int endAdded = classDiff.ctorsAdded.lastIndexOf(removedCtor); 84 if (startRemoved != -1 && startRemoved == endRemoved && 85 startAdded != -1 && startAdded == endAdded) { 86 ConstructorAPI addedCtor = (ConstructorAPI)(classDiff.ctorsAdded.get(startAdded)); 89 MemberDiff ctorDiff = new MemberDiff(classDiff.name_); 91 ctorDiff.oldType_ = removedCtor.type_; 92 ctorDiff.newType_ = addedCtor.type_; ctorDiff.oldExceptions_ = removedCtor.exceptions_; 94 ctorDiff.newExceptions_ = addedCtor.exceptions_; 95 ctorDiff.addModifiersChange(removedCtor.modifiers_.diff(addedCtor.modifiers_)); 96 if (APIComparator.docChanged(removedCtor.doc_, addedCtor.doc_)) { 98 String type = ctorDiff.newType_; 99 if (type.compareTo("void") == 0) 100 type = ""; 101 String fqName = pkgDiff.name_ + "." + classDiff.name_; 102 String link1 = "<a HREF=\"" + fqName + HTMLReportGenerator.reportFileExt + "\" class=\"hiddenlink\">"; 103 String link2 = "<a HREF=\"" + fqName + HTMLReportGenerator.reportFileExt + "#" + fqName + ".ctor_changed(" + type + ")\" class=\"hiddenlink\">"; 104 String id = pkgDiff.name_ + "." + classDiff.name_ + ".ctor(" + HTMLReportGenerator.simpleName(type) + ")"; 105 String title = link1 + "Class <b>" + classDiff.name_ + 106 "</b></a>, " + link2 + "constructor <b>" + classDiff.name_ + "(" + HTMLReportGenerator.simpleName(type) + ")</b></a>"; 107 ctorDiff.documentationChange_ = Diff.saveDocDiffs(pkgDiff.name_, classDiff.name_, removedCtor.doc_, addedCtor.doc_, id, title); 108 } 109 classDiff.ctorsChanged.add(ctorDiff); 110 classDiff.ctorsRemoved.remove(startRemoved); 112 classDiff.ctorsAdded.remove(startAdded); 113 if (trace && ctorDiff.modifiersChange_ != null) 114 System.out.println("Merged the removal and addition of constructor into one change: " + ctorDiff.modifiersChange_); 115 } 116 } 117 118 121 public static void mergeRemoveAddMethod(MethodAPI removedMethod, 122 ClassDiff classDiff, 123 PackageDiff pkgDiff) { 124 mergeSingleMethods(removedMethod, classDiff, pkgDiff); 125 mergeMultipleMethods(removedMethod, classDiff, pkgDiff); 126 } 127 128 131 public static void mergeSingleMethods(MethodAPI removedMethod, ClassDiff classDiff, PackageDiff pkgDiff) { 132 int startRemoved = classDiff.methodsRemoved.indexOf(removedMethod); 134 int endRemoved = classDiff.methodsRemoved.lastIndexOf(removedMethod); 135 int startAdded = classDiff.methodsAdded.indexOf(removedMethod); 136 int endAdded = classDiff.methodsAdded.lastIndexOf(removedMethod); 137 if (startRemoved != -1 && startRemoved == endRemoved && 138 startAdded != -1 && startAdded == endAdded) { 139 MethodAPI addedMethod = (MethodAPI)(classDiff.methodsAdded.get(startAdded)); 142 if (addedMethod.inheritedFrom_ == null) { 143 MemberDiff methodDiff = new MemberDiff(removedMethod.name_); 145 methodDiff.oldType_ = removedMethod.returnType_; 146 methodDiff.newType_ = addedMethod.returnType_; 147 methodDiff.oldSignature_ = removedMethod.getSignature(); 148 methodDiff.newSignature_ = addedMethod.getSignature(); 149 methodDiff.oldExceptions_ = removedMethod.exceptions_; 150 methodDiff.newExceptions_ = addedMethod.exceptions_; 151 diffMethods(methodDiff, removedMethod, addedMethod); 155 methodDiff.addModifiersChange(removedMethod.modifiers_.diff(addedMethod.modifiers_)); 156 if (APIComparator.docChanged(removedMethod.doc_, addedMethod.doc_)) { 158 String sig = methodDiff.newSignature_; 159 if (sig.compareTo("void") == 0) 160 sig = ""; 161 String fqName = pkgDiff.name_ + "." + classDiff.name_; 162 String link1 = "<a HREF=\"" + fqName + HTMLReportGenerator.reportFileExt + "\" class=\"hiddenlink\">"; 163 String link2 = "<a HREF=\"" + fqName + HTMLReportGenerator.reportFileExt + "#" + fqName + "." + addedMethod.name_ + "_changed(" + sig + ")\" class=\"hiddenlink\">"; 164 String id = pkgDiff.name_ + "." + classDiff.name_ + ".dmethod." + addedMethod.name_ + "(" + HTMLReportGenerator.simpleName(sig) + ")"; 165 String title = link1 + "Class <b>" + classDiff.name_ + "</b></a>, " + 166 link2 + HTMLReportGenerator.simpleName(methodDiff.newType_) + " <b>" + addedMethod.name_ + "(" + HTMLReportGenerator.simpleName(sig) + ")</b></a>"; 167 methodDiff.documentationChange_ = Diff.saveDocDiffs(pkgDiff.name_, classDiff.name_, removedMethod.doc_, addedMethod.doc_, id, title); 168 } 169 classDiff.methodsChanged.add(methodDiff); 170 classDiff.methodsRemoved.remove(startRemoved); 172 classDiff.methodsAdded.remove(startAdded); 173 if (trace) { 174 System.out.println("Merged the removal and addition of method " + 175 removedMethod.name_ + 176 " into one change"); 177 } 178 } } 180 } 181 182 187 public static void mergeMultipleMethods(MethodAPI removedMethod, ClassDiff classDiff, PackageDiff pkgDiff) { 188 int startRemoved = classDiff.methodsRemoved.indexOf(removedMethod); 190 int endRemoved = classDiff.methodsRemoved.lastIndexOf(removedMethod); 191 int startAdded = classDiff.methodsAdded.indexOf(removedMethod); 192 int endAdded = classDiff.methodsAdded.lastIndexOf(removedMethod); 193 if (startRemoved != -1 && endRemoved != -1 && 194 startAdded != -1 && endAdded != -1) { 195 int removedIdx = -1; 197 for (int i = startRemoved; i <= endRemoved; i++) { 198 if (removedMethod.equalSignatures(classDiff.methodsRemoved.get(i))) { 199 removedIdx = i; 200 break; 201 } 202 } 203 if (removedIdx == -1) { 204 System.out.println("Error: removed method index not found"); 205 System.exit(5); 206 } 207 int addedIdx = -1; 210 for (int i = startAdded; i <= endAdded; i++) { 211 MethodAPI addedMethod2 = (MethodAPI)(classDiff.methodsAdded.get(i)); 212 if (addedMethod2.inheritedFrom_ == null && 213 removedMethod.equalSignatures(addedMethod2)) 214 addedIdx = i; 215 break; 216 } 217 if (addedIdx == -1) 218 return; 219 MethodAPI addedMethod = (MethodAPI)(classDiff.methodsAdded.get(addedIdx)); 220 MemberDiff methodDiff = new MemberDiff(removedMethod.name_); 222 methodDiff.oldType_ = removedMethod.returnType_; 223 methodDiff.newType_ = addedMethod.returnType_; 224 methodDiff.oldSignature_ = removedMethod.getSignature(); 225 methodDiff.newSignature_ = addedMethod.getSignature(); 226 methodDiff.oldExceptions_ = removedMethod.exceptions_; 227 methodDiff.newExceptions_ = addedMethod.exceptions_; 228 diffMethods(methodDiff, removedMethod, addedMethod); 232 methodDiff.addModifiersChange(removedMethod.modifiers_.diff(addedMethod.modifiers_)); 233 if (APIComparator.docChanged(removedMethod.doc_, addedMethod.doc_)) { 235 String sig = methodDiff.newSignature_; 236 if (sig.compareTo("void") == 0) 237 sig = ""; 238 String fqName = pkgDiff.name_ + "." + classDiff.name_; 239 String link1 = "<a HREF=\"" + fqName + HTMLReportGenerator.reportFileExt + "\" class=\"hiddenlink\">"; 240 String link2 = "<a HREF=\"" + fqName + HTMLReportGenerator.reportFileExt + "#" + fqName + "." + addedMethod.name_ + "_changed(" + sig + ")\" class=\"hiddenlink\">"; 241 String id = pkgDiff.name_ + "." + classDiff.name_ + ".dmethod." + addedMethod.name_ + "(" + HTMLReportGenerator.simpleName(sig) + ")"; 242 String title = link1 + "Class <b>" + classDiff.name_ + "</b></a>, " + 243 link2 + HTMLReportGenerator.simpleName(methodDiff.newType_) + " <b>" + addedMethod.name_ + "(" + HTMLReportGenerator.simpleName(sig) + ")</b></a>"; 244 methodDiff.documentationChange_ = Diff.saveDocDiffs(pkgDiff.name_, classDiff.name_, removedMethod.doc_, addedMethod.doc_, id, title); 245 } 246 classDiff.methodsChanged.add(methodDiff); 247 classDiff.methodsRemoved.remove(removedIdx); 249 classDiff.methodsAdded.remove(addedIdx); 250 if (trace) { 251 System.out.println("Merged the removal and addition of method " + 252 removedMethod.name_ + 253 " into one change. There were multiple methods of this name."); 254 } 255 } 256 } 257 258 262 public static void diffMethods(MemberDiff methodDiff, 263 MethodAPI oldMethod, 264 MethodAPI newMethod) { 265 if (oldMethod.isAbstract_ != newMethod.isAbstract_) { 267 String changeText = ""; 268 if (oldMethod.isAbstract_) 269 changeText += "Changed from abstract to non-abstract."; 270 else 271 changeText += "Changed from non-abstract to abstract."; 272 methodDiff.addModifiersChange(changeText); 273 } 274 if (Diff.showAllChanges && 276 oldMethod.isNative_ != newMethod.isNative_) { 277 String changeText = ""; 278 if (oldMethod.isNative_) 279 changeText += "Changed from native to non-native."; 280 else 281 changeText += "Changed from non-native to native."; 282 methodDiff.addModifiersChange(changeText); 283 } 284 if (Diff.showAllChanges && 286 oldMethod.isSynchronized_ != newMethod.isSynchronized_) { 287 String changeText = ""; 288 if (oldMethod.isSynchronized_) 289 changeText += "Changed from synchronized to non-synchronized."; 290 else 291 changeText += "Changed from non-synchronized to synchronized."; 292 methodDiff.addModifiersChange(changeText); 293 } 294 } 295 296 299 public static void mergeRemoveAddField(FieldAPI removedField, ClassDiff classDiff, PackageDiff pkgDiff) { 300 int startRemoved = classDiff.fieldsRemoved.indexOf(removedField); 302 int endRemoved = classDiff.fieldsRemoved.lastIndexOf(removedField); 303 int startAdded = classDiff.fieldsAdded.indexOf(removedField); 304 int endAdded = classDiff.fieldsAdded.lastIndexOf(removedField); 305 if (startRemoved != -1 && startRemoved == endRemoved && 306 startAdded != -1 && startAdded == endAdded) { 307 FieldAPI addedField = (FieldAPI)(classDiff.fieldsAdded.get(startAdded)); 310 if (addedField.inheritedFrom_ == null) { 311 MemberDiff fieldDiff = new MemberDiff(removedField.name_); 313 fieldDiff.oldType_ = removedField.type_; 314 fieldDiff.newType_ = addedField.type_; 315 fieldDiff.addModifiersChange(removedField.modifiers_.diff(addedField.modifiers_)); 316 if (APIComparator.docChanged(removedField.doc_, addedField.doc_)) { 318 String fqName = pkgDiff.name_ + "." + classDiff.name_; 319 String link1 = "<a HREF=\"" + fqName + HTMLReportGenerator.reportFileExt + "\" class=\"hiddenlink\">"; 320 String link2 = "<a HREF=\"" + fqName + HTMLReportGenerator.reportFileExt + "#" + fqName + "." + addedField.name_ + "\" class=\"hiddenlink\">"; 321 String id = pkgDiff.name_ + "." + classDiff.name_ + ".field." + addedField.name_; 322 String title = link1 + "Class <b>" + classDiff.name_ + "</b></a>, " + 323 link2 + HTMLReportGenerator.simpleName(fieldDiff.newType_) + " <b>" + addedField.name_ + "</b></a>"; 324 fieldDiff.documentationChange_ = Diff.saveDocDiffs(pkgDiff.name_, classDiff.name_, removedField.doc_, addedField.doc_, id, title); 325 } 326 classDiff.fieldsChanged.add(fieldDiff); 327 classDiff.fieldsRemoved.remove(startRemoved); 329 classDiff.fieldsAdded.remove(startAdded); 330 if (trace) { 331 System.out.println("Merged the removal and addition of field " + 332 removedField.name_ + 333 " into one change"); 334 } 335 } } 337 } 338 339 340 private static boolean trace = false; 341 342 } 343 | Popular Tags |