Package org.stianloader.remapper

# Class HierarchyAwareMappingDelegator<T extends MappingLookup & MappingSink>

java.lang.Object
org.stianloader.remapper.HierarchyAwareMappingDelegator<T>

Type Parameters:
  `T` - The type of `MappingLookup` to use as a the delegate (it must implement `MappingSink`, too)

All Implemented Interfaces:
  `MappingLookup`, `MappingSink`

Direct Known Subclasses:
  `SimpleHierarchyAwareMappingLookup`

public class HierarchyAwareMappingDelegator<T extends MappingLookup & MappingSink> extends Object implements MappingLookup, MappingSink
A `HierarchyAwareMappingDelegator` is an implementation of `MappingLookup` that binds mappings of class members provided by `MappingSink.remapMember(MemberRef, String)` to their top level definition. The actual storage of mappings are handled by a defined delegated `MappingLookup` (which also implements the `MappingSink` instance) of type T.

The main point in using this delegator is in ensuring that disjointed method overrides do not happen, although this `MappingLookup` still allows for name collisions to occur (unless the delegate prohibits it - read up on the behaviour of delegates)

## Thread safety and concurrency

The thread safety and concurrency guarantees are only as strong as the components of the instance of the class. If the `HierarchyAwareMappingDelegator.TopLevelMemberLookup` and the used delegate are both thread-safe, then this class is thread-safe, too. In case of doubt, don't use instances of this class in an concurrent environment.

## Nested Class Summary

Nested Classes
Modifier and Type
Class
Description
`static interface`
`HierarchyAwareMappingDelegator.TopLevelMemberLookup`
Interface for obtaining the root definition of a member.

## Constructor Summary

Constructors
Constructor
Description
`HierarchyAwareMappingDelegator(T lookupDelegate, @NotNull HierarchyAwareMappingDelegator.TopLevelMemberLookup definitionLookup)`
Creates a `HierarchyAwareMappingDelegator` with the delegate `lookupDelegate` of type T and a given `HierarchyAwareMappingDelegator.TopLevelMemberLookup`.

## Method Summary

Modifier and Type
Method
Description
`@NotNull String`
`getRemappedClassName(@NotNull String srcName)`
Obtains the name of the class in the destination namespace (or in laymen's terms the remapped name).
`@Nullable String`
`getRemappedClassNameFast(@NotNull String srcName)`
Obtains the name of the class in the destination namespace (or in laymen's terms the remapped name).
`@NotNull String`
`getRemappedFieldName(@NotNull String srcOwner, @NotNull String srcName, @NotNull String srcDesc)`
Obtains the name of a field in the destination namespace (or the mapped name).
`@NotNull String`
`getRemappedMethodName(@NotNull String srcOwner, @NotNull String srcName, @NotNull String srcDesc)`
Obtains the name of a field in the destination namespace (or the mapped name).
`@Nullable String`
`getRemappedParameterName(@NotNull String srcOwner, @NotNull String srcName, @NotNull String srcDesc, int paramIndex, boolean isStatic)`
Obtains the name of the parameter in the destination namespace (or in laymen's terms the remapped name of the parameter).
`@NotNull HierarchyAwareMappingDelegator<T>`
`remapClass(@NotNull String srcName, @NotNull String dstName)`
Remaps a specific class.
`@NotNull HierarchyAwareMappingDelegator<T>`
`remapMember(@NotNull MemberRef srcRef, @NotNull String dstName)`
Remaps a class member - that is either a field or a method.
`@NotNull MappingSink`
`remapParameter(@NotNull String srcOwner, @NotNull String srcMethodName, @NotNull String srcDesc, int paramIndex, @NotNull String destParamName)`
Remaps a method parameter.

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

## Constructor Details

### HierarchyAwareMappingDelegator

public HierarchyAwareMappingDelegator(@NotNull T lookupDelegate, @NotNull @NotNull HierarchyAwareMappingDelegator.TopLevelMemberLookup definitionLookup)
Creates a `HierarchyAwareMappingDelegator` with the delegate `lookupDelegate` of type T and a given `HierarchyAwareMappingDelegator.TopLevelMemberLookup`.

Parameters:
  `lookupDelegate` - The object to which all lookup and sink calls are delegated to.
  `definitionLookup` - The lookup that is used to acquire the top-level definition of a class member.

## Method Details

### getRemappedClassName

@NotNull public @NotNull String getRemappedClassName(@NotNull @NotNull String srcName)
Description copied from interface: `MappingLookup`
Obtains the name of the class in the destination namespace (or in laymen's terms the remapped name). If the class name in the source namespace is equal to the name in the destination namespace (e.g. because there is no mapping), then the name in the source namespace must be returned.

It is valid to have `MappingLookup.getRemappedClassNameFast(String)` and `MappingLookup.getRemappedClassName(String)` be the same implementation for as long as `MappingLookup.getRemappedClassName(String)` never returns null, however doing so might incur a slight performance reduction.

srcName and the returned value are in the same format as `Type.getInternalName()`.

Specified by:
  `getRemappedClassName` in interface `MappingLookup`
Parameters:
  `srcName` - The name of the class in the source namespace
Returns:
  The mapped name in the destination namespace, or the name in the source namespace if no mapping exists.

### getRemappedClassNameFast

@Nullable public @Nullable String getRemappedClassNameFast(@NotNull @NotNull String srcName)
Description copied from interface: `MappingLookup`
Obtains the name of the class in the destination namespace (or in laymen's terms the remapped name). If the class name in the source namespace is equal to the name in the destination namespace (e.g. because there is no mapping), then null can be returned for performance reasons.

This is especially done when some string manipulation can be skipped if the source name equals the destination name.

It is valid to have `MappingLookup.getRemappedClassNameFast(String)` and `MappingLookup.getRemappedClassName(String)` be the same implementation for as long as `MappingLookup.getRemappedClassName(String)` never returns null, however doing so might incur a slight performance reduction.

srcName and the returned value are in the same format as `Type.getInternalName()`.

Specified by:
  `getRemappedClassNameFast` in interface `MappingLookup`
Parameters:
  `srcName` - The name of the class in the source namespace
Returns:
  The name in the destination namespace, or null if the name is the same as the source namespace

### getRemappedFieldName

@NotNull public @NotNull String getRemappedFieldName(@NotNull @NotNull String srcOwner, @NotNull @NotNull String srcName, @NotNull @NotNull String srcDesc)
Description copied from interface: `MappingLookup`
Obtains the name of a field in the destination namespace (or the mapped name). If the field is not known or if no mapping exists for the field, then the name in the source namespace must be returned (that is the srcName parameter).

srcOwner is in the same format as `Type.getInternalName()`.

Implementations of this interface are encouraged to not throw if possible.

Specified by:
  `getRemappedFieldName` in interface `MappingLookup`
Parameters:
  `srcOwner` - The name of the owner of the member in the source namespace
  `srcName` - The name of the member in the source namespace
  `srcDesc` - The descriptor of the member (where as classes are all in the source namespace)
Returns:
  The mapped name in the destination namespace, or the name in the source namespace if no mapping exists.

### getRemappedMethodName

@NotNull public @NotNull String getRemappedMethodName(@NotNull @NotNull String srcOwner, @NotNull @NotNull String srcName, @NotNull @NotNull String srcDesc)
Description copied from interface: `MappingLookup`
Obtains the name of a field in the destination namespace (or the mapped name). If the field is not known or if no mapping exists for the field, then the name in the source namespace must be returned (that is the srcName parameter).

srcOwner is in the same format as `Type.getInternalName()`.

Implementations of this interface are encouraged to not throw if possible.

Specified by:
  `getRemappedMethodName` in interface `MappingLookup`
Parameters:
  `srcOwner` - The name of the owner of the member in the source namespace
  `srcName` - The name of the member in the source namespace
  `srcDesc` - The descriptor of the member (where as classes are all in the source namespace)
Returns:
  The mapped name in the destination namespace, or the name in the source namespace if no mapping exists.

### getRemappedParameterName

@Nullable public @Nullable String getRemappedParameterName(@NotNull @NotNull String srcOwner, @NotNull @NotNull String srcName, @NotNull @NotNull String srcDesc, int paramIndex, boolean isStatic)
Description copied from interface: `MappingLookup`
Obtains the name of the parameter in the destination namespace (or in laymen's terms the remapped name of the parameter). Should the name of the parameter not be known in the destination namespace, then `null` is returned. This is the default behaviour of this method.

The `paramIndex` argument is 0-indexed. It does not distinguish between computational categories. Or in other words, for both `(IZ)V` and `(JZ)V` the boolean parameter corresponds to a `paramIndex` value of 1, while the integer and long have a value of 0.

Callers may throw an `IndexOutOfBoundsException` if `paramIndex` is below 0 or above the amount of parameters as discernible by `srcDesc`. As such, this method cannot be used to remap LVT entries, even though they are quite similar in structure. This is because LVT entries can be reused. By default this method does not do any checks whether `paramIndex` is a valid value. This is done for performance reasons.

Implementations of this method are encouraged to not throw if possible, unless for reasons described above. While it theoretically makes sense to throw an exception in cases where a method is known to not exist, this is generally rarely the case.

If this `MappingLookup` instance does not support remapping parameters, then `null` should be returned unconditionally, without throwing outside of aforementioned reasons.

Specified by:
  `getRemappedParameterName` in interface `MappingLookup`
Parameters:
  `srcOwner` - The name of the owner of the member in the source namespace.
  `srcName` - The name of the member in the source namespace.
  `srcDesc` - The descriptor of the member (where as classes are all in the source namespace).
  `paramIndex` - The index of the parameter, excluding the implied `this` parameter.
  `isStatic` - Whether the method is static. Used when working with mappings formats such as Enigma, TINYv2, or TSRG.
Returns:
  The name of the parameter in the destination namespace, or `null` if not applicable.

### remapClass

@NotNull public @NotNull HierarchyAwareMappingDelegator<T> remapClass(@NotNull @NotNull String srcName, @NotNull @NotNull String dstName)
Description copied from interface: `MappingSink`
Remaps a specific class. Do note that this makes no promises on inner classes. That is using the dollar ('$') sign or a dot ('.') has no effect on the internal arrangement of inner class nodes. Inner classes are as of now not handled by the `Remapper` implementation and if implemented would be independent of this method.

Class names are defined via the `internal name` of a class - that is forward slashes ('/') are used instead of dots ('.'). Usage of dots or semicolons (';') are completely forbidden as they are not allowed in the JVMS within internal names of classes.

Implementations are not required to ensure that the class names make sense or are valid - the burden of verification falls upon the caller.

Specified by:
  `remapClass` in interface `MappingSink`
Parameters:
  `srcName` - The name of the member in the source namespace (that is the unmapped name)
  `dstName` - The name of the member in the destination namespace (that is the mapped name)
Returns:
  The current `MappingSink` instance (i.e. this), for chaining

### remapMember

@NotNull public @NotNull HierarchyAwareMappingDelegator<T> remapMember(@NotNull @NotNull MemberRef srcRef, @NotNull @NotNull String dstName)
Description copied from interface: `MappingSink`
Remaps a class member - that is either a field or a method. Whether the member is a field or a method can be easily discerned by looking at the first character of the `descriptor` of the `MemberRef`. If the first character is a '(', then it is a method - otherwise it is a field.

As no non-method descriptor can start with '(', this check suffices and reduces the work required for bridging between stianloader-remapper and other mapping formats or software.

Specified by:
  `remapMember` in interface `MappingSink`
Parameters:
  `srcRef` - The reference of the member in the source namespace (i.e. the unmapped member)
  `dstName` - The name of the member in the target namespace (i.e. the mapped member name)
Returns:
  The current `MappingSink` instance, for chaining

### remapParameter

@NotNull public @NotNull MappingSink remapParameter(@NotNull @NotNull String srcOwner, @NotNull @NotNull String srcMethodName, @NotNull @NotNull String srcDesc, int paramIndex, @NotNull @NotNull String destParamName)
Description copied from interface: `MappingSink`
Remaps a method parameter.

The `paramIndex` argument is 0-indexed. It does not distinguish between computational categories. Or in other words, for both `(IZ)V` and `(JZ)V` the boolean parameter corresponds to a `paramIndex` value of 1, while the integer and long have a value of 0.

Callers may throw an `IndexOutOfBoundsException` if `paramIndex` is below 0 or above the amount of parameters as discernible by `srcDesc`. As such, this method cannot be used to remap LVT entries, even though they are quite similar in structure. This is because LVT entries can be reused. By default this method does not do any checks whether `paramIndex` is a valid value. This is done for performance reasons.

If this `MappingSink` instance does not support remapping method parameters then an `UnsupportedOperationException` should be thrown. In cases where libraries are used that link against an older version of stianloader-remapper (namely 0.1.X and earlier), an `AbstractMethodError` may be thrown when attempting to call this method.

Specified by:
  `remapParameter` in interface `MappingSink`
Parameters:
  `srcOwner` - The name of the owner of the method in the source namespace.
  `srcMethodName` - The name of the method in the source namespace.
  `srcDesc` - The descriptor of the method in the source namespace.
  `paramIndex` - The index of the parameter, excluding the implied `this` argument on non-static methods.
  `destParamName` - The name of the parameter in the destination namespace.
Returns:
  The current `MappingSink` instance, for chaining.