Merge branch 'GP-0_ryanmkurtz_PR-9595_jialfaro_monexa_issue-9594-fd3aef'

(Closes #9594, Closes #9595)
This commit is contained in:
Ryan Kurtz
2026-09-08 06:21:15 -04:00

View File

@@ -38,35 +38,35 @@ import ghidra.util.task.TaskMonitor;
/** /**
* Handles merging of function tags when they are added/removed from * Handles merging of function tags when they are added/removed from
* functions. * functions.
* * <p>
* Most merging can be done automatically; the exception being when a * Most merging can be done automatically; the exception being when a
* tag has been added to a function by one user, but deleted from the * tag has been added to a function by one user, but deleted from the
* program by another. * program by another.
* * <p
* Note that there are other tag related conflict cases, but they are * Note that there are other tag related conflict cases, but they are
* handled by the {@link FunctionTagMerger}, which handles all aspects of * handled by the {@link FunctionTagMerger}, which handles all aspects of
* creation/deletion/editing of tags independent of functions. * creation/deletion/editing of tags independent of functions.
* * <p>
* THIS CLASS ONLY DEALS WITH FUNCTION-RELATED ADDS/REMOVES. * THIS CLASS ONLY DEALS WITH FUNCTION-RELATED ADDS/REMOVES.
* * <p>
* The specific cases handled by the class are described below: * The specific cases handled by the class are described below:
* * <ul>
* - X and Y are tags * <li>X and Y are tags</li>
* - ** indicates a conflict * <li>** indicates a conflict</li>
* * </ul>
* User A | Add X Add Y Delete X Delete Y * <pre>
* | * User A | Add X Add Y Delete X Delete Y
* User B | * |
* User B |
* ------------------------------------------------------- * -------------------------------------------------------
* Add X | X X,Y ** X * Add X | X X,Y ** X
* | * |
* Add Y | X,Y Y Y ** * Add Y | X,Y Y Y **
* | * |
* Delete X | ** Y - - * Delete X | ** Y - -
* | * |
* Delete Y | X ** - - * Delete Y | X ** - -
* * </pre>
*
*/ */
public class FunctionTagListingMerger extends AbstractListingMerger { public class FunctionTagListingMerger extends AbstractListingMerger {
@@ -95,7 +95,7 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
super(listingMergeMgr); super(listingMergeMgr);
} }
/****************************************************************************** /****************************************************************************
* PUBLIC METHODS * PUBLIC METHODS
******************************************************************************/ ******************************************************************************/
@@ -204,9 +204,9 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
// Make sure we're supposed to prompt the user; if not, just use the // Make sure we're supposed to prompt the user; if not, just use the
// previous choice and merge. // previous choice and merge.
if (tagChoice != ASK_USER) { if (tagChoice != ASK_USER) {
int optionToUse = // tagChoice may have been changed by the user's "Use For All" selection
(tagChoice == ASK_USER) ? chosenConflictOption : tagChoice; // in a previous iteration; use it directly.
mergeConflictingTag(addr, optionToUse, monitor); mergeConflictingTag(addr, tagChoice, monitor);
} }
else { else {
showMergePanel(listingPanel, addr, id, monitor); showMergePanel(listingPanel, addr, id, monitor);
@@ -228,7 +228,7 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
} }
} }
/****************************************************************************** /****************************************************************************
* PRIVATE METHODS * PRIVATE METHODS
******************************************************************************/ ******************************************************************************/
@@ -238,12 +238,11 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
* *
* @param diffType from {@link ProgramDiffFilter} * @param diffType from {@link ProgramDiffFilter}
* @param monitor task monitor * @param monitor task monitor
* @throws ProgramConflictException * @throws CancelledException if the user cancelled the operation
* @throws CancelledException * @throws IOException if an IO-related error occurred
* @throws IOException
*/ */
private void autoMerge(int diffType, TaskMonitor monitor) private void autoMerge(int diffType, TaskMonitor monitor)
throws ProgramConflictException, CancelledException, IOException { throws CancelledException, IOException {
// Get the address of all changes in Latest and My. These changes are guaranteed to ONLY be // Get the address of all changes in Latest and My. These changes are guaranteed to ONLY be
// additions/removals of tags from the address; tag creations/deletions/edits will not be // additions/removals of tags from the address; tag creations/deletions/edits will not be
@@ -276,7 +275,7 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
* @param changedAddresses list of addresses to inspect * @param changedAddresses list of addresses to inspect
* @param deletedTags all tags deleted in the 'other' program * @param deletedTags all tags deleted in the 'other' program
* @param programAddedTo the program in which the adds reside * @param programAddedTo the program in which the adds reside
* @throws IOException * @throws IOException if an IO-related error occurred
*/ */
private void processChangedAddresses(AddressSetView changedAddresses, private void processChangedAddresses(AddressSetView changedAddresses,
Collection<? extends FunctionTag> deletedTags, Program programAddedTo) Collection<? extends FunctionTag> deletedTags, Program programAddedTo)
@@ -312,7 +311,7 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
* Adds the given tag/address combo to the global conflict list. * Adds the given tag/address combo to the global conflict list.
* *
* @param addr the conflicting address * @param addr the conflicting address
* @param tag the conflicting tag * @param tag the conflicting tag
*/ */
private void addToConflicts(Address addr, FunctionTag tag) { private void addToConflicts(Address addr, FunctionTag tag) {
if (conflictMap.get(addr) == null) { if (conflictMap.get(addr) == null) {
@@ -324,11 +323,10 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
} }
/** /**
* Returns all tags that were added to the function at the given address. * {@return all tags that were added to the function at the given address}
* *
* @param program the program where the function resides * @param program the program where the function resides
* @param addr the function entry point * @param addr the function entry point
* @return
*/ */
private Collection<FunctionTag> getTagsAddedToFunction(Program program, Address addr) { private Collection<FunctionTag> getTagsAddedToFunction(Program program, Address addr) {
@@ -363,7 +361,7 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
* indicate deletions. * indicate deletions.
* *
* @param program the program version * @param program the program version
* @param monitor * @param monitor A {@link TaskMonitor}
* @return database IDs from the FunctionTagAdapter table that were deleted * @return database IDs from the FunctionTagAdapter table that were deleted
*/ */
private Collection<? extends FunctionTag> getDeletedTags(Program program, TaskMonitor monitor) { private Collection<? extends FunctionTag> getDeletedTags(Program program, TaskMonitor monitor) {
@@ -391,9 +389,9 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
* resolving the conflict will appear at the bottom. * resolving the conflict will appear at the bottom.
* *
* @param listingPanel the main panel * @param listingPanel the main panel
* @param addr * @param addr The address
* @param tagID * @param tagID The tag ID
* @param changeListener * @param changeListener The {@link ChangeListener}
*/ */
private void setupConflictsPanel(ListingMergePanel listingPanel, Address addr, Long tagID, private void setupConflictsPanel(ListingMergePanel listingPanel, Address addr, Long tagID,
ChangeListener changeListener) { ChangeListener changeListener) {
@@ -438,12 +436,12 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
} }
/** /**
* Returns a string containing the tag and the program version it's associated * {@return a string containing the tag and the program version it's associated with}
* with. This is used when displaying the conflict panel. * <p>
* This is used when displaying the conflict panel.
* *
* @param version * @param version The program version
* @param tags * @param tag The associated tag
* @return
*/ */
private String[] getFunctionTagInfo(int version, String tag) { private String[] getFunctionTagInfo(int version, String tag) {
String[] info = new String[] { "Keep", "", tag }; String[] info = new String[] { "Keep", "", tag };
@@ -471,8 +469,8 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
* *
* @param addr the location of the conflict * @param addr the location of the conflict
* @param chosenConflictOption KEEP_ORIGINAL, KEEP_LATEST, KEEP_MY * @param chosenConflictOption KEEP_ORIGINAL, KEEP_LATEST, KEEP_MY
* @param monitor * @param monitor A {@link TaskMonitor}
* @throws CancelledException * @throws CancelledException if the user cancelled the operation
*/ */
private void mergeConflictingTag(Address addr, int chosenConflictOption, TaskMonitor monitor) private void mergeConflictingTag(Address addr, int chosenConflictOption, TaskMonitor monitor)
throws CancelledException { throws CancelledException {
@@ -484,7 +482,7 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
// want to throw away; the keep list is the one we want to keep. // want to throw away; the keep list is the one we want to keep.
// //
// ie: Original = "Red" // ie: Original = "Red"
// My = "Red-my" // My = "Red-my"
// Latest = "Red-latest" // Latest = "Red-latest"
// //
// If the decision is KEEP_LATEST, then "Red-my" and "Red" will be added // If the decision is KEEP_LATEST, then "Red-my" and "Red" will be added
@@ -629,7 +627,7 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
* @param id the tag ID * @param id the tag ID
* @param program the program version * @param program the program version
* @return null if tag not found for the given id * @return null if tag not found for the given id
* @throws IOException * @throws IOException if an IO-related error occurred
*/ */
private FunctionTag getTag(Long id, Program program) throws IOException { private FunctionTag getTag(Long id, Program program) throws IOException {
FunctionManagerDB functionManagerDB = (FunctionManagerDB) program.getFunctionManager(); FunctionManagerDB functionManagerDB = (FunctionManagerDB) program.getFunctionManager();