Skip to content

Commit

Permalink
Allow merging of target methods. Closes FabricMC#19.
Browse files Browse the repository at this point in the history
  • Loading branch information
Daomephsta committed Nov 22, 2021
1 parent 9c750fa commit cbbc4e9
Showing 1 changed file with 37 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package daomephsta.unpick.impl.representations;

import java.util.*;
import java.util.Map.Entry;

import org.objectweb.asm.*;

Expand Down Expand Up @@ -110,24 +111,56 @@ public TargetMethodBuilder parameterGroup(int parameterIndex, String constantGro
{
String existingGroup = parameterConstantGroups.putIfAbsent(parameterIndex, constantGroup);
if (existingGroup != null)
throw new DuplicateMappingException("Parameter " + parameterIndex + " is already mapped to constant group " + existingGroup);
throw duplicateParameterGroup(parameterIndex, existingGroup);
return this;
}

public TargetMethodBuilder returnGroup(String constantGroup)
{
if (returnConstantGroup != null)
throw new DuplicateMappingException("Return is already mapped to constant group " + returnConstantGroup);
throw duplicateReturnGroup(constantGroup);
else
returnConstantGroup = constantGroup;
return this;
}

public Builder add()
{
parent.targetMethods.put(name + descriptor, new TargetMethod(owner, name, descriptor, parameterConstantGroups, returnConstantGroup));
parent.targetMethods.compute(name + descriptor, (key, existing) ->
{
if (existing != null)
{
// Find non-null returnConstantGroup, throw if both are non-null
// Note that exceptions always use values from the existing TargetMethod
if (returnConstantGroup == null && existing.returnConstantGroup != null)
returnConstantGroup = existing.returnConstantGroup;
else if (returnConstantGroup != null && existing.returnConstantGroup == null)
/*NO OP*/;
else if (!Objects.equals(existing.returnConstantGroup, returnConstantGroup))
throw duplicateReturnGroup(existing.returnConstantGroup);

// Merge parameterConstantGroups, throwing on duplicate keys
// Note that exceptions always use keys & values from the existing TargetMethod
for (Entry<Integer, String> entry : existing.parameterConstantGroups.entrySet())
{
if (parameterConstantGroups.putIfAbsent(entry.getKey(), entry.getValue()) != null)
throw duplicateParameterGroup(entry.getKey(), entry.getValue());
}
}
return new TargetMethod(owner, name, descriptor, parameterConstantGroups, returnConstantGroup);
});
return parent;
}

private DuplicateMappingException duplicateParameterGroup(int index, String group)
{
return new DuplicateMappingException("Parameter " + index + " is already mapped to constant group " + group);
}


private DuplicateMappingException duplicateReturnGroup(String group)
{
return new DuplicateMappingException("Return is already mapped to constant group " + group);
}
}

/**
Expand Down

0 comments on commit cbbc4e9

Please sign in to comment.