Interface MappingSetMergerHandler


  • public interface MappingSetMergerHandler

    This class is responsible for handling the individual merge conditions found in the default MappingSetMerger. It may be simpler to override the default implementation of this class to handle any particular cases you wish to modify rather than overriding MappingSetMerger.

    All methods in this class are intended to create the base-mapping only. That is to say, for a merge of 2 class mappings, the method should merge only the name of said class and return it, not process the rest of the class's members. The MappingSetMerger will handle recursively calling individual mapping methods for the members.


    Continuations and Duplicates:
    This class distinguishes between the normal merge case and a duplicate merge case. A normal merge case is when the left mapping maps A -> B and the right mapping maps B -> C. This can be thought of as a mapping chain, where the deobfuscated side of the left mapping lines up with the obfuscated side of the right mapping. This is what is referred to as a continuation, since in this case the right mapping "continues" the chain. All of the right mappings in the normal merge methods are continuations.

    There also exists the possibility that the right mapping set will duplicate the left. That means that the left mapping maps A -> B, and the right mapping maps A -> C (or A -> B too, what matters is the obfuscated sides match). In this case the obfuscated side of the left mapping matches the obfuscated side of the right mapping. This is what this class refers to as a duplicate mapping.

    The mergeDuplicate* methods in this class have 2 right mapping parameters, one called right and the other called rightContinuation. If the duplicate method is called that means a duplicate has already been detected, which is why the right mapping is never null. In this situation there is still a possibility of a continuation mapping existing in the right mapping set, however. Put another way, the left mapping set may map A -> B, and the right mapping set may map both A -> C and B -> D (or B -> C, the left side is what matters here). If this situation occurs, then the rightContinuation parameter will not be null and the handler implementation will need to handle this case. The default implementation just assumes the duplicated right mapping is the correct mapping and throws away the rightContinuation mapping. Note that attempting to keep both will always fail (in the default case) because both would eventually resolve to the same obfuscated names.

    Since:
    0.5.4
    See Also:
    MappingSetMerger
    Implementation Requirements:
    In order to properly implement this interface extra care must be taken for the addRightMethod() method. This method has a special case that no other method has in the standard merge case, which is that the obfuscated types of the method descriptor may be mapped to the deobfuscated types of the left side (which has no matching mapping in this case). In order to properly map this case you must also make a best-effort to map the obfuscated types of the descriptor to the obfuscated mappings of the left side. All handler methods have a context parameter to help with these kinds of situations.
    • Method Detail

      • create

        static MappingSetMergerHandler create()
        Create the default mapping set merger handler implementation.
        Returns:
        The newly created mapping set merger handler.
        Since:
        0.5.4
      • mergeTopLevelClassMappings

        default MergeResult<TopLevelClassMapping> mergeTopLevelClassMappings​(TopLevelClassMapping left,
                                                                             TopLevelClassMapping right,
                                                                             MappingSet target,
                                                                             MergeContext context)
        Merge 2 existing top level class mappings together, creating the result in the target and returning it. This method should only map the name of the class, not any members.
        Parameters:
        left - The left top level class mapping, never null.
        right - The right top level class mapping, never null.
        target - The mapping set to create the new class mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new top level class mapping in a merge result. Pass null to the MergeResult if the mapping wasn't merged and should be removed.
      • mergeDuplicateTopLevelClassMappings

        default MergeResult<TopLevelClassMapping> mergeDuplicateTopLevelClassMappings​(TopLevelClassMapping left,
                                                                                      TopLevelClassMapping right,
                                                                                      TopLevelClassMapping rightContinuation,
                                                                                      MappingSet target,
                                                                                      MergeContext context)
        Merge 2 existing top level class mappings together who both refer to the same obfuscated name, creating the result in the target and returning it. This method should only map the name of the class, not any members.
        Parameters:
        left - The left top level class mapping, never null.
        right - The right top level class mapping which duplicates the left mapping, never null.
        rightContinuation - The optional right top level class mapping which continues from the left mapping, can be null. For more information on continuation mappings, see the "Continuations and Duplicates" section in MappingSetMergerHandler.
        target - The mapping set to create the new class mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new top level class mapping in a merge result. Pass null to the MergeResult if the mapping wasn't merged and should be removed.
        Implementation Note:
        The default implementation views the "right" mapping as the more up-to-date method, so this situation is treated by delegating to addRightTopLevelClassMapping().
      • addLeftTopLevelClassMapping

        default MergeResult<TopLevelClassMapping> addLeftTopLevelClassMapping​(TopLevelClassMapping left,
                                                                              MappingSet target,
                                                                              MergeContext context)
        Handle the case where only the left top level class mapping exists, creating the result in the target and returning it. This method should only map the name of the class, not any members.
        Parameters:
        left - The left class mapping, never null.
        target - The mapping set to create the new class mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new top level class mapping in a merge result. Pass null to the MergeResult if the mapping wasn't merged and should be removed.
      • addRightTopLevelClassMapping

        default MergeResult<TopLevelClassMapping> addRightTopLevelClassMapping​(TopLevelClassMapping right,
                                                                               MappingSet target,
                                                                               MergeContext context)
        Handle the case where only the right top level class mapping exists, creating the result in the target and returning it. This method should only map the name of the class, not any members.
        Parameters:
        right - The right top level class mapping, never null.
        target - The mapping top level set to create the new class mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new top level class mapping in a merge result. Pass null to the MergeResult if the mapping wasn't merged and should be removed.
      • mergeInnerClassMappings

        default MergeResult<InnerClassMapping> mergeInnerClassMappings​(InnerClassMapping left,
                                                                       InnerClassMapping right,
                                                                       ClassMapping<?,​?> target,
                                                                       MergeContext context)
        Merge 2 existing inner classes together, creating the result in the target and returning it. This method should only map the name of the class, not any members.
        Parameters:
        left - The left inner class mapping, never null.
        right - The right inner class mapping, never null.
        target - The class mapping to create the new inner class mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new inner class mapping in a merge result. Pass null to the MergeResult if the mapping wasn't merged and should be removed.
      • mergeDuplicateInnerClassMappings

        default MergeResult<InnerClassMapping> mergeDuplicateInnerClassMappings​(InnerClassMapping left,
                                                                                InnerClassMapping right,
                                                                                InnerClassMapping rightContinuation,
                                                                                ClassMapping<?,​?> target,
                                                                                MergeContext context)
        Merge 2 existing inner class mappings together who both refer to the same obfuscated name, creating the result in the target and returning it. This method should only map the name of the class, not any members.
        Parameters:
        left - The left inner class mapping, never null.
        right - The right inner class mapping, never null.
        rightContinuation - The optional right inner class mapping which continues from the left mapping, can be null. For more information on continuation mappings, see the "Continuations and Duplicates" section in MappingSetMergerHandler.
        target - The class mapping to create the new inner class mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new inner class mapping in a merge result. Pass null to the MergeResult if the mapping wasn't merged and should be removed.
        Implementation Note:
        The default implementation views the "right" mapping as the more up-to-date method, so this situation is treated by delegating to addRightInnerClassMapping().
      • addLeftInnerClassMapping

        default MergeResult<InnerClassMapping> addLeftInnerClassMapping​(InnerClassMapping left,
                                                                        ClassMapping<?,​?> target,
                                                                        MergeContext context)
        Handle the case where only the left inner class mapping exists, creating the result in the target and returning it. This method should only map the name of the class, not any members.
        Parameters:
        left - The left class mapping, never null.
        target - The class mapping to create the new inner class mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new inner class mapping in a merge result. Pass null to the MergeResult if the mapping wasn't merged and should be removed.
      • addRightInnerClassMapping

        default MergeResult<InnerClassMapping> addRightInnerClassMapping​(InnerClassMapping right,
                                                                         ClassMapping<?,​?> target,
                                                                         MergeContext context)
        Handle the case where only the right inner class mapping exists, creating the result in the target and returning it. This method should only map the name of the class, not any members.
        Parameters:
        right - The right class mapping, never null.
        target - The class mapping to create the new inner class mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new inner class mapping in a merge result. Pass null to the MergeResult if the mapping wasn't merged and should be removed.
      • mergeFieldMappings

        default FieldMapping mergeFieldMappings​(FieldMapping left,
                                                FieldMapping strictRight,
                                                FieldMapping looseRight,
                                                ClassMapping<?,​?> target,
                                                MergeContext context)

        Merge 2 existing fields together, creating the result in the target and returning it.

        There are 2 possible ways a right field mapping can continue a left field mapping:

        • The right field mapping's obfuscated signature matches the left field mapping's deobfuscated signature. This also includes the field type. This is the standard case.
        • Only the right field mapping's obfuscated name matches the left method mapping's deobfuscated name, ignoring the type.

        The first case is considered most correct and, and thus is considered the strict merge and is what maps to the parameter named strictRight. The second case is found only by widening the search past a typical merge, so it's considered the FieldMergeStrategy.LOOSE merge and is what maps to the parameter named looseRight.

        Note: Both strictRight and looseRight may be present together at the same time, but at least one will always be present.

        Parameters:
        left - The left field mapping, never null.
        strictRight - The best-fit right field mapping which continues from the left mapping, can be null if not present.
        looseRight - The slightly worse-fit right field mapping which continues from the left mapping, can be null if not present. Can only be present if the field merge strategy is set to FieldMergeStrategy.LOOSE.
        target - The class mapping to create the new field mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new field mapping. Return null if the mapping wasn't merged and should be removed.
        Implementation Note:
        The looseRight parameter will only be checked for and included if the field mapping merge strategy is set to FieldMergeStrategy.LOOSE. This is set via MergeConfig. If the merge strategy is not loose then looseRight will always be null.
      • mergeDuplicateFieldMappings

        default FieldMapping mergeDuplicateFieldMappings​(FieldMapping left,
                                                         FieldMapping strictRightDuplicate,
                                                         FieldMapping looseRightDuplicate,
                                                         FieldMapping strictRightContinuation,
                                                         FieldMapping looseRightContinuation,
                                                         ClassMapping<?,​?> target,
                                                         MergeContext context)

        Merge 2 existing field mappings together who both refer to the same obfuscated name, creating the result in the target and returning it.

        There are 2 possible ways a right field mapping can duplicate a left field mapping:

        • The right field mapping's obfuscated signature matches the left field mapping's obfuscated signature. This also includes the field's type. This is the standard case.
        • Only the right field mapping's obfuscated name matches the left field mapping's obfuscated name, ignoring the type.

        The first case is considered most correct and, and thus is considered the strict duplicate and is what maps to the parameter named strictRightDuplicate. The second case is found only by widening the search past a typical duplicate, so it's considered the loose duplicate and is what maps to the parameter named looseRightDuplicate.

        There are 2 possible ways a right field mapping can continue a left field mapping:

        • The right field mapping's obfuscated signature matches the left field mapping's deobfuscated signature. This also includes the field's type. This is the standard case.
        • Only the right field mapping's obfuscated name matches the left field mapping's deobfuscated name, ignoring the type.

        The first case is considered most correct and, and thus is considered the strict continuation and is what maps to the parameter named strictRightContinuation. The second case is found only by widening the search past a typical merge, so it's considered the FieldMergeStrategy.LOOSE merge and is what maps to the parameter named looseRightContinuation.

        Note: At least one of the two parameters strictRightDuplicate or looseRightDuplicate must be present for this method to be called. They both can be present together at the same time. The 2 continuation parameters, strictRightContinuation and looseRightContinuation may also be present, either together or separate, but are not guaranteed.

        For more information on continuations, see the "Continuations and Duplicates" section in MappingSetMergerHandler

        Parameters:
        left - The left field mapping, never null.
        strictRightDuplicate - The best-fit right field mapping which duplicates the left mapping, can be null if not present.
        looseRightDuplicate - The slightly worse-fit right field mapping which duplicates teh left mapping, can be null if not present. Can only be present if the field merge strategy is set to FieldMergeStrategy.LOOSE.
        strictRightContinuation - The optional best-fit right field mapping which continues from the left mapping, can be null if not present.
        looseRightContinuation - The optional sightly worse-fit right field mapping which continues from the right mapping, can be nul if not present. Can only be present if the field merge strategy is set to FieldMergeStrategy.LOOSE.
        target - The class mapping to create the new field mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new field mapping. Return null if the mapping wasn't merged and should be removed.
        Implementation Note:

        The default implementation views the "right" mapping as the more up-to-date method, so this situation is treated by delegating to addRightFieldMapping() whichever of the 2 duplicate parameters is present, checking strictRightDuplicate first as it is the preferred of the two.


        The looseRightDuplicate and looseRightContinuation parameters will only be checked for and included if the field mapping merge strategy is set to FieldMergeStrategy.LOOSE. This is set via MergeConfig. If the merge strategy is not loose then looseRightDuplicate and looseRightContinuation will always be null.

      • addLeftFieldMapping

        default FieldMapping addLeftFieldMapping​(FieldMapping left,
                                                 ClassMapping<?,​?> target,
                                                 MergeContext context)
        Handle the case where only the left mapping exists, creating the result in the target and returning it.
        Parameters:
        left - The left field mapping, never null.
        target - The class mapping to create the new field mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new field mapping. Return null if the mapping wasn't merged and should be removed.
      • addRightFieldMapping

        default FieldMapping addRightFieldMapping​(FieldMapping right,
                                                  ClassMapping<?,​?> target,
                                                  MergeContext context)
        Handle the case where only the right mapping exists, creating the result in the target and returning it.
        Parameters:
        right - The right field mapping, never null.
        target - The class mapping to create the new field mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new field mapping. Return null if the mapping wasn't merged and should be removed.
      • mergeMethodMappings

        default MergeResult<MethodMapping> mergeMethodMappings​(MethodMapping left,
                                                               MethodMapping strictRight,
                                                               MethodMapping looseRight,
                                                               ClassMapping<?,​?> target,
                                                               MergeContext context)

        Merge 2 or 3 existing method mappings together, creating the result in the target and returning it. This method should only map the name of the method, not any parameters.


        There are 2 possible ways a right method mapping can continue a left method mapping:

        • The right method mapping's obfuscated signature matches the left method mapping's deobfuscated signature. This is the standard case.
        • The right method mapping's obfuscated name matches the left method mapping's deobfuscated name, but the right method mapping's obfuscated descriptor matches the left mapping's obfuscated descriptor.

        The first case is considered most correct and, and thus is considered the strict merge and is what maps to the parameter named strictRight. The second case is found only by widening the search past a typical merge, so it's considered the loose merge and is what maps to the parameter named looseRight.



        Note: Both strictRight and wiggleRight may be present together at the same time, but at least one will always be present.

        Parameters:
        left - The left method mapping, never null.
        strictRight - The best-fit right method mapping which continues from the left mapping, can be null if not present.
        looseRight - The slightly worse-fit right method mapping which continues from the left mapping, can be null if not present. Can only be present if the method merge strategy is set to MethodMergeStrategy.LOOSE.
        target - The class mapping to create the new method mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new method mapping in a merge result. Pass null to the MergeResult if the mapping wasn't merged and should be removed.
        See Also:
        mergeDuplicateMethodMappings(MethodMapping, MethodMapping, MethodMapping, MethodMapping, MethodMapping, ClassMapping, MergeContext)
        Implementation Note:
        The looseRight parameter will only be checked for and included if the method mapping merge strategy is set to MethodMergeStrategy.LOOSE. This is set via MergeConfig. If the merge strategy is not loose then looseRight will always be null.
      • mergeDuplicateMethodMappings

        default MergeResult<MethodMapping> mergeDuplicateMethodMappings​(MethodMapping left,
                                                                        MethodMapping strictRightDuplicate,
                                                                        MethodMapping looseRightDuplicate,
                                                                        MethodMapping strictRightContinuation,
                                                                        MethodMapping looseRightContinuation,
                                                                        ClassMapping<?,​?> target,
                                                                        MergeContext context)

        Merge 2 or more existing method mappings together who all refer to the same obfuscated signature, creating the result in the target and returning it. This method should only map the name of the method, not any parameters.

        There are 2 possible ways a right method mapping can duplicate a left method mapping:

        • The right method mapping's obfuscated signature matches the left method mapping's obfuscated signature. This is the standard case.
        • The right method mapping's obfuscated name matches the left method mapping's obfuscated name, but the right method mapping's obfuscated descriptor matches the left mapping's deobfuscated descriptor.

        The first case is considered most correct and, and thus is considered the strict duplicate and is what maps to the parameter named strictRightDuplicate. The second case is found only by widening the search past a typical duplicate, so it's considered the loose duplicate and is what maps to the parameter named looseRightDuplicate.

        There are 2 possible ways a right method mapping can continue a left method mapping:

        • The right method mapping's obfuscated signature matches the left method mapping's deobfuscated signature. This is the standard case.
        • The right method mapping's obfuscated name matches the left method mapping's deobfuscated name, but the right method mapping's obfuscated descriptor matches the left mapping's obfuscated descriptor.

        The first case is considered most correct and, and thus is considered the strict continuation and is what maps to the parameter named strictRightContinuation. The second case is found only by widening the search past a typical merge, so it's considered the loose merge and is what maps to the parameter named looseRightContinuation.

        Note: At least one of the two parameters strictRightDuplicate or looseRightDuplicate must be present for this method to be called. They both can be present together at the same time. The 2 continuation parameters, strictRightContinuation and looseRightContinuation may also be present, either together or separate, but are not guaranteed.

        For more information on continuation mappings, see the "Continuations and Duplicates" section in MappingSetMergerHandler

        Parameters:
        left - The left method mapping, never null.
        strictRightDuplicate - The best-fit right method mapping which duplicates the left mapping, can be null if not present.
        looseRightDuplicate - The slightly worse-fit right method mapping which duplicates the left mapping, can be null if not present. Can only be present if the method merge strategy is set to MethodMergeStrategy.LOOSE.
        strictRightContinuation - The optional best-fit right method mapping which continues from the left mapping, can be null if not present.
        looseRightContinuation - The optional slightly worse-fit right method mapping which continues from the left mapping, can be null if not present. Can only be present if the method merge strategy is set to MethodMergeStrategy.LOOSE.
        target - The class mapping to create the new method mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new method mapping in a merge result. Pass null to the MergeResult if the mapping wasn't merged and should be removed.
        See Also:
        mergeMethodMappings(MethodMapping, MethodMapping, MethodMapping, ClassMapping, MergeContext)
        Implementation Note:

        The default implementation views the "right" mapping as the more up-to-date method, so this situation is treated by delegating to addRightMethodMapping() whichever of the 2 duplicate parameters is present, checking strictRightDuplicate first as it is the preferred of the two.


        The looseRightDuplicate and looseRightContinuation parameters will only be checked for and included if the method mapping merge strategy is set to MethodMergeStrategy.LOOSE. This is set via MergeConfig. If the merge strategy is not loose then looseRightDuplicate and looseRightContinuation will always be null.

      • addLeftMethodMapping

        default MergeResult<MethodMapping> addLeftMethodMapping​(MethodMapping left,
                                                                ClassMapping<?,​?> target,
                                                                MergeContext context)
        Handle the case where only the left method mapping exists, creating the result in the target and returning it. This method should only map the name of the method, not any parameters
        Parameters:
        left - The left method mapping, never null.
        target - The class mapping to create the new method mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new method mapping in a merge result. Pass null to the MergeResult if the mapping wasn't merged and should be removed.
      • addRightMethodMapping

        default MergeResult<MethodMapping> addRightMethodMapping​(MethodMapping right,
                                                                 ClassMapping<?,​?> target,
                                                                 MergeContext context)
        Handle the case where only the right method mapping exists, creating the result in the target and returning it. This method should only map the name of the method, not any parameters.
        Parameters:
        right - The right method mapping, never null.
        target - The class mapping to create the new method mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new method mapping in a merge result. Pass null to the MergeResult if the mapping wasn't merged and should be removed.
      • mergeParameterMappings

        default MethodParameterMapping mergeParameterMappings​(MethodParameterMapping left,
                                                              MethodParameterMapping right,
                                                              MethodMapping target,
                                                              MergeContext context)
        Merge 2 existing parameter mappings together, creating the result in the target and returning it.
        Parameters:
        left - The left parameter mapping, never null.
        right - The right parameter mapping, never null.
        target - The method mapping to create the new parameter mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new parameter mapping. Return null if the mapping wasn't merged and should be removed.
        API Note:
        Unlike all of the other classes of mapping merge handlers in this class, method parameters don't have a distinction between merging parameter mappings and merging duplicate parameter mappings. this is because all parameters are mapped solely by their index, so any time both mapping sets have parameters mappings for the same method they are always a kind of "duplicate" - this method handles both cases, since they are identical.
      • addLeftParameterMapping

        default MethodParameterMapping addLeftParameterMapping​(MethodParameterMapping left,
                                                               MethodMapping target,
                                                               MergeContext context)
        Handle the case where only the left parameter mapping mapping exists, creating the result in the target and returning it.
        Parameters:
        left - The left parameter mapping, never null.
        target - The method mapping to create the new parameter mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new parameter mapping. Return null if the mapping wasn't merged and should be removed.
      • addRightParameterMapping

        default MethodParameterMapping addRightParameterMapping​(MethodParameterMapping right,
                                                                MethodMapping target,
                                                                MergeContext context)
        Handle the case where only the right parameter mapping mapping exists, creating the result in the target and returning it.
        Parameters:
        right - The right parameter mapping, never null.
        target - The method mapping to create the new parameter mapping in, never null.
        context - The MergeContext associated with this merge operation, never null.
        Returns:
        The new parameter mapping. Return null if the mapping wasn't merged and should be removed.